Przeglądaj źródła

Make r12 one of the first registers to be allocated since it's volatile.
Add some extra optimizations for LDREX and STREX opcodes, and fix some of the spilling information.

git-svn-id: branches/laksen/intrinsics@32155 -

Jeppe Johansen 10 lat temu
rodzic
commit
009f40dfe3
3 zmienionych plików z 65 dodań i 6 usunięć
  1. 1 3
      compiler/arm/aasmcpu.pas
  2. 62 1
      compiler/arm/aoptcpu.pas
  3. 2 2
      compiler/arm/cgcpu.pas

+ 1 - 3
compiler/arm/aasmcpu.pas

@@ -815,13 +815,11 @@ implementation
               result:=operand_readwrite
             else
               result:=operand_read;
-          A_LDREX:
+          A_LDREX,A_STREX:
             if opnr in [0] then
               result:=operand_write
             else
               result:=operand_read;
-          A_STREX:
-            result:=operand_write;
           else
             internalerror(200403151);
         end;

+ 62 - 1
compiler/arm/aoptcpu.pas

@@ -702,6 +702,18 @@ Implementation
                       end;
                     Result:=LookForPostindexedPattern(taicpu(p)) or Result;
                   end;
+                A_LDREX,A_LDREXB,A_LDREXH:
+                  begin
+                    if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
+                       RemoveSuperfluousMove(p, hp1, 'LdrMov2Ldr') then
+                      Result:=true;
+                  end;
+                A_STREX,A_STREXB,A_STREXH:
+                  begin
+                    if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
+                       RemoveSuperfluousMove(p, hp1, 'StrMov2Str') then
+                      Result:=true;
+                  end;
                 A_LDR:
                   begin
                     { change
@@ -1245,7 +1257,7 @@ Implementation
                        (taicpu(p).oper[1]^.typ = top_reg) and
                        (taicpu(p).oppostfix = PF_NONE) and
                        GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
-                       MatchInstruction(hp1, [A_LDR, A_STR], [taicpu(p).condition], []) and
+                       MatchInstruction(hp1, [A_LDR, A_STR, A_LDREX,A_LDREXB,A_LDREXH], [taicpu(p).condition], []) and
                        (taicpu(hp1).oper[1]^.typ = top_ref) and
                        { We can change the base register only when the instruction uses AM_OFFSET }
                        ((taicpu(hp1).oper[1]^.ref^.index = taicpu(p).oper[0]^.reg) or
@@ -1282,6 +1294,55 @@ Implementation
                         p:=hp1;
                         result:=true;
                       end;
+                    { Fold
+                        mov  regA, regB
+                        strex* regA, regC, [regA]
+                      to
+                        strex* regA, regC, [regB]
+                      CAUTION! If this one is successful p might not be a mov instruction anymore!
+                    }
+                    if (taicpu(p).opcode = A_MOV) and
+                       (taicpu(p).ops = 2) and
+                       (taicpu(p).oper[1]^.typ = top_reg) and
+                       (taicpu(p).oppostfix = PF_NONE) and
+                       GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
+                       MatchInstruction(hp1, [A_STREX, A_STREXB, A_STREXH], [taicpu(p).condition], []) and
+                       (taicpu(hp1).oper[2]^.typ = top_ref) and
+                       { We can change the base register only when the instruction uses AM_OFFSET }
+                       ((taicpu(hp1).oper[2]^.ref^.index = taicpu(p).oper[0]^.reg) or
+                         ((taicpu(hp1).oper[2]^.ref^.addressmode = AM_OFFSET) and
+                          (taicpu(hp1).oper[2]^.ref^.base = taicpu(p).oper[0]^.reg))
+                       ) and
+                       not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) and
+
+                       // Make sure that Thumb code doesn't propagate a high register into a reference
+                       ((GenerateThumbCode and
+                         (getsupreg(taicpu(p).oper[1]^.reg) < RS_R8)) or
+                        (not GenerateThumbCode)) and
+
+                       RegEndOfLife(taicpu(p).oper[0]^.reg, taicpu(hp1)) then
+                      begin
+                        DebugMsg('Peephole MovStrex2Strex done', hp1);
+                        if (taicpu(hp1).oper[2]^.ref^.addressmode = AM_OFFSET) and
+                           (taicpu(hp1).oper[2]^.ref^.base = taicpu(p).oper[0]^.reg) then
+                          taicpu(hp1).oper[2]^.ref^.base := taicpu(p).oper[1]^.reg;
+
+                        if taicpu(hp1).oper[2]^.ref^.index = taicpu(p).oper[0]^.reg then
+                          taicpu(hp1).oper[2]^.ref^.index := taicpu(p).oper[1]^.reg;
+
+                        dealloc:=FindRegDeAlloc(taicpu(p).oper[1]^.reg, taicpu(p.Next));
+                        if Assigned(dealloc) then
+                          begin
+                            asml.remove(dealloc);
+                            asml.InsertAfter(dealloc,hp1);
+                          end;
+
+                        GetNextInstruction(p, hp1);
+                        asml.remove(p);
+                        p.free;
+                        p:=hp1;
+                        result:=true;
+                      end;
 
                     { This folds shifterops into following instructions
                       mov r0, r1, lsl #8

+ 2 - 2
compiler/arm/cgcpu.pas

@@ -4126,8 +4126,8 @@ unit cgcpu;
         { currently, we save R14 always, so we can use it }
         if (target_info.system<>system_arm_darwin) then
           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,RS_R8,
-               RS_R9,RS_R10,RS_R12,RS_R14],first_int_imreg,[])
+              [RS_R0,RS_R1,RS_R2,RS_R3,RS_R12,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,
+               RS_R9,RS_R10,RS_R14],first_int_imreg,[])
         else
           { r9 is not available on Darwin according to the llvm code generator }
           rg[R_INTREGISTER]:=trgintcputhumb2.create(R_INTREGISTER,R_SUBWHOLE,