diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2015-05-31 21:11:53 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2015-05-31 21:11:53 +0000 |
commit | fd038aac8be795e98521da2e0cc01e4bd2def57a (patch) | |
tree | e49884645ff651237ffea9fbd41eeaef834f4ba6 /compiler/avr/aoptcpu.pas | |
parent | e180b834826486ec7386dbb8ae4076a095c22b14 (diff) | |
download | fpc-fd038aac8be795e98521da2e0cc01e4bd2def57a.tar.gz |
+ make use of sbi/cbi
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@30964 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/avr/aoptcpu.pas')
-rw-r--r-- | compiler/avr/aoptcpu.pas | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/compiler/avr/aoptcpu.pas b/compiler/avr/aoptcpu.pas index d5bb018b70..badabf4aa7 100644 --- a/compiler/avr/aoptcpu.pas +++ b/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 |