瀏覽代碼

+ arm: optimize sxth/sxtb

git-svn-id: trunk@44713 -
florian 5 年之前
父節點
當前提交
458a6000e7
共有 1 個文件被更改,包括 202 次插入0 次删除
  1. 202 0
      compiler/arm/aoptcpu.pas

+ 202 - 0
compiler/arm/aoptcpu.pas

@@ -2247,6 +2247,208 @@ Implementation
                          RemoveSuperfluousMove(p, hp1, 'UxthMov2Data') then
                       Result:=true;
                   end;
+                A_SXTB:
+                  begin
+                    {
+                      change
+                      sxtb reg2,reg1
+                      strb reg2,[...]
+                      dealloc reg2
+                      to
+                      strb reg1,[...]
+                    }
+                    if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and
+                      (taicpu(p).ops=2) and
+                      GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
+                      MatchInstruction(hp1, A_STR, [C_None], [PF_B]) and
+                      assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) and
+                      { the reference in strb might not use reg2 }
+                      not(RegInRef(taicpu(p).oper[0]^.reg,taicpu(hp1).oper[1]^.ref^)) and
+                      { reg1 might not be modified inbetween }
+                      not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
+                      begin
+                        DebugMsg('Peephole SxtbStrb2Strb done', p);
+                        taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg);
+                        GetNextInstruction(p,hp2);
+                        asml.remove(p);
+                        p.free;
+                        p:=hp2;
+                        result:=true;
+                      end
+                    {
+                      change
+                      sxtb reg2,reg1
+                      sxth reg3,reg2
+                      dealloc reg2
+                      to
+                      sxtb reg3,reg1
+                    }
+                    else if MatchInstruction(p, A_SXTB, [C_None], [PF_None]) and
+                      (taicpu(p).ops=2) and
+                      GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
+                      MatchInstruction(hp1, A_SXTH, [C_None], [PF_None]) and
+                      (taicpu(hp1).ops = 2) and
+                      MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
+                      RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
+                      { reg1 might not be modified inbetween }
+                      not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
+                      begin
+                        DebugMsg('Peephole SxtbSxth2Sxtb done', p);
+                        AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs);
+                        taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg);
+                        asml.remove(hp1);
+                        hp1.free;
+                        result:=true;
+                      end
+                    {
+                      change
+                      sxtb reg2,reg1
+                      sxtb reg3,reg2
+                      dealloc reg2
+                      to
+                      uxtb reg3,reg1
+                    }
+                    else if MatchInstruction(p, A_SXTB, [C_None], [PF_None]) and
+                      (taicpu(p).ops=2) and
+                      GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
+                      MatchInstruction(hp1, A_SXTB, [C_None], [PF_None]) and
+                      (taicpu(hp1).ops = 2) and
+                      MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
+                      RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
+                      { reg1 might not be modified inbetween }
+                      not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
+                      begin
+                        DebugMsg('Peephole SxtbSxtb2Sxtb done', p);
+                        AllocRegBetween(taicpu(hp1).oper[0]^.reg,p,hp1,UsedRegs);
+                        taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg);
+                        asml.remove(hp1);
+                        hp1.free;
+                        result:=true;
+                      end
+                    {
+                      change
+                      sxtb reg2,reg1
+                      and reg3,reg2,#0x*FF
+                      dealloc reg2
+                      to
+                      uxtb reg3,reg1
+                    }
+                    else if MatchInstruction(p, A_SXTB, [C_None], [PF_None]) and
+                      (taicpu(p).ops=2) and
+                      GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
+                      MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and
+                      (taicpu(hp1).ops=3) and
+                      (taicpu(hp1).oper[2]^.typ=top_const) and
+                      ((taicpu(hp1).oper[2]^.val and $FF)=$FF) and
+                      MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
+                      RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
+                      { reg1 might not be modified inbetween }
+                      not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
+                      begin
+                        DebugMsg('Peephole SxtbAndImm2Sxtb done', p);
+                        taicpu(hp1).opcode:=A_SXTB;
+                        taicpu(hp1).ops:=2;
+                        taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg);
+                        GetNextInstruction(p,hp2);
+                        asml.remove(p);
+                        p.free;
+                        p:=hp2;
+                        result:=true;
+                      end
+                    else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
+                         RemoveSuperfluousMove(p, hp1, 'SxtbMov2Data') then
+                      Result:=true;
+                  end;
+                A_SXTH:
+                  begin
+                    {
+                      change
+                      sxth reg2,reg1
+                      strh reg2,[...]
+                      dealloc reg2
+                      to
+                      strh reg1,[...]
+                    }
+                    if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and
+                      (taicpu(p).ops=2) and
+                      GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
+                      MatchInstruction(hp1, A_STR, [C_None], [PF_H]) and
+                      RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
+                      { the reference in strb might not use reg2 }
+                      not(RegInRef(taicpu(p).oper[0]^.reg,taicpu(hp1).oper[1]^.ref^)) and
+                      { reg1 might not be modified inbetween }
+                      not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
+                      begin
+                        DebugMsg('Peephole SXTHStrh2Strh done', p);
+                        taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg);
+                        GetNextInstruction(p, hp1);
+                        asml.remove(p);
+                        p.free;
+                        p:=hp1;
+                        result:=true;
+                      end
+                    {
+                      change
+                      sxth reg2,reg1
+                      sxth reg3,reg2
+                      dealloc reg2
+                      to
+                      sxth reg3,reg1
+                    }
+                    else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and
+                      (taicpu(p).ops=2) and
+                      GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
+                      MatchInstruction(hp1, A_SXTH, [C_None], [PF_None]) and
+                      (taicpu(hp1).ops=2) and
+                      MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
+                      RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
+                      { reg1 might not be modified inbetween }
+                      not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
+                      begin
+                        DebugMsg('Peephole SxthSxth2Sxth done', p);
+                        AllocRegBetween(taicpu(p).oper[1]^.reg,p,hp1,UsedRegs);
+                        taicpu(hp1).opcode:=A_SXTH;
+                        taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg);
+                        GetNextInstruction(p, hp1);
+                        asml.remove(p);
+                        p.free;
+                        p:=hp1;
+                        result:=true;
+                      end
+                    {
+                      change
+                      sxth reg2,reg1
+                      and reg3,reg2,#65535
+                      dealloc reg2
+                      to
+                      sxth reg3,reg1
+                    }
+                    else if MatchInstruction(p, A_SXTH, [C_None], [PF_None]) and
+                      (taicpu(p).ops=2) and
+                      GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and
+                      MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and
+                      (taicpu(hp1).ops=3) and
+                      (taicpu(hp1).oper[2]^.typ=top_const) and
+                      ((taicpu(hp1).oper[2]^.val and $FFFF)=$FFFF) and
+                      MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and
+                      RegEndofLife(taicpu(p).oper[0]^.reg,taicpu(hp1)) and
+                      { reg1 might not be modified inbetween }
+                      not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then
+                      begin
+                        DebugMsg('Peephole SxthAndImm2Sxth done', p);
+                        taicpu(hp1).opcode:=A_SXTH;
+                        taicpu(hp1).ops:=2;
+                        taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg);
+                        GetNextInstruction(p, hp1);
+                        asml.remove(p);
+                        p.free;
+                        p:=hp1;
+                        result:=true;
+                      end
+                    else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) and
+                         RemoveSuperfluousMove(p, hp1, 'SxthMov2Data') then
+                      Result:=true;
+                  end;
                 A_CMP:
                   begin
                     {