Bläddra i källkod

+ make use of sbi/cbi

git-svn-id: trunk@30964 -
florian 10 år sedan
förälder
incheckning
9216e561e2
1 ändrade filer med 63 tillägg och 0 borttagningar
  1. 63 0
      compiler/avr/aoptcpu.pas

+ 63 - 0
compiler/avr/aoptcpu.pas

@@ -43,6 +43,7 @@ Type
 Implementation
 
   uses
+    cutils,
     cpuinfo,
     aasmbase,aasmcpu,
     globals,globtype,
@@ -89,6 +90,14 @@ Implementation
     end;
 
 
+  function MatchInstruction(const instr: tai; const op: TAsmOp): boolean;
+    begin
+      result :=
+        (instr.typ = ait_instruction) and
+        (taicpu(instr).opcode = op);
+    end;
+
+
   function TCpuAsmOptimizer.RegInInstruction(Reg: TRegister; p1: tai): Boolean;
     begin
       If (p1.typ = ait_instruction) and (taicpu(p1).opcode in [A_MUL,A_MULS,A_FMUL,A_FMULS,A_FMULSU]) and
@@ -189,6 +198,60 @@ Implementation
                     taicpu(p).opcode:=A_IN;
                     taicpu(p).loadconst(1,taicpu(p).oper[1]^.ref^.offset-32);
                   end;
+              A_IN:
+                  if GetNextInstruction(p,hp1) then
+                    begin
+                      {
+                        in rX,Y
+                        ori rX,n
+                        out Y,rX
+
+                        into
+                        sbi rX,lg(n)
+                      }
+                      if MatchInstruction(hp1,A_ORI) and
+                        (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) and
+                        (PopCnt(byte(taicpu(hp1).oper[1]^.val))=1) and
+                        GetNextInstruction(hp1,hp2) and
+                        MatchInstruction(hp2,A_OUT) and
+                        MatchOperand(taicpu(hp2).oper[1]^,taicpu(p).oper[0]^) and
+                        MatchOperand(taicpu(hp2).oper[0]^,taicpu(p).oper[1]^) then
+                        begin
+                          taicpu(p).opcode:=A_SBI;
+                          taicpu(p).loadconst(0,taicpu(p).oper[1]^.val);
+                          taicpu(p).loadconst(1,BsrByte(taicpu(hp1).oper[1]^.val)-1);
+                          asml.Remove(hp1);
+                          hp1.Free;
+                          asml.Remove(hp2);
+                          hp2.Free;
+                          result:=true;
+                        end
+                       {
+                        in rX,Y
+                        andi rX,not(n)
+                        out Y,rX
+
+                        into
+                        cbi rX,lg(n)
+                      }
+                      else if MatchInstruction(hp1,A_ANDI) and
+                         (taicpu(hp1).oper[0]^.reg=taicpu(p).oper[0]^.reg) and
+                         (PopCnt(byte(not(taicpu(hp1).oper[1]^.val)))=1) and
+                         GetNextInstruction(hp1,hp2) and
+                         MatchInstruction(hp2,A_OUT) and
+                         MatchOperand(taicpu(hp2).oper[1]^,taicpu(p).oper[0]^) and
+                         MatchOperand(taicpu(hp2).oper[0]^,taicpu(p).oper[1]^) then
+                        begin
+                          taicpu(p).opcode:=A_CBI;
+                          taicpu(p).loadconst(0,taicpu(p).oper[1]^.val);
+                          taicpu(p).loadconst(1,BsrByte(not(taicpu(hp1).oper[1]^.val))-1);
+                          asml.Remove(hp1);
+                          hp1.Free;
+                          asml.Remove(hp2);
+                          hp2.Free;
+                          result:=true;
+                        end;
+                    end;
               A_CLR:
                 begin
                   { turn the common