summaryrefslogtreecommitdiff
path: root/compiler/avr/aoptcpu.pas
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-05-31 21:11:53 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2015-05-31 21:11:53 +0000
commitfd038aac8be795e98521da2e0cc01e4bd2def57a (patch)
treee49884645ff651237ffea9fbd41eeaef834f4ba6 /compiler/avr/aoptcpu.pas
parente180b834826486ec7386dbb8ae4076a095c22b14 (diff)
downloadfpc-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.pas63
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