소스 검색

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 년 전
부모
커밋
009f40dfe3
3개의 변경된 파일65개의 추가작업 그리고 6개의 파일을 삭제
  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,