diff --git a/compiler/mips/aoptcpu.pas b/compiler/mips/aoptcpu.pas index cb656af36e..866089f41e 100644 --- a/compiler/mips/aoptcpu.pas +++ b/compiler/mips/aoptcpu.pas @@ -28,14 +28,179 @@ unit aoptcpu; Interface uses - cpubase, aoptobj, aoptcpub, aopt; + cgbase, cpubase, aoptobj, aoptcpub, aopt, aasmtai; Type TCpuAsmOptimizer = class(TAsmOptimizer) + function TryRemoveMov(var p: tai): boolean; + function PeepHoleOptPass1Cpu(var p: tai): boolean; override; End; Implementation + uses + aasmcpu; + + + function MatchInstruction(const instr: tai; const op: TAsmOp): boolean; + begin + result := + (instr.typ = ait_instruction) and + (taicpu(instr).opcode = op); + end; + + + function MatchOperand(const oper: TOper; reg: TRegister): boolean; + begin + result:=(oper.typ=top_reg) and (oper.reg=reg); + end; + + + function IsSameReg(this,next: taicpu): boolean; + begin + result:=(next.oper[0]^.typ=top_reg) and + (next.oper[1]^.typ=top_reg) and + (next.oper[0]^.reg=next.oper[1]^.reg) and + (next.oper[0]^.reg=this.oper[0]^.reg); + end; + + + function TCpuAsmOptimizer.TryRemoveMov(var p: tai): boolean; + var + next,hp1: tai; + alloc,dealloc: tai_regalloc; + begin + { Fold + op $reg1,... + move $reg2,$reg1 + dealloc $reg1 + into + op $reg2,... + } + result:=false; + if GetNextInstruction(p,next) and + MatchInstruction(next,A_MOVE) and + MatchOperand(taicpu(next).oper[1]^,taicpu(p).oper[0]^.reg) then + begin + dealloc:=FindRegDealloc(taicpu(p).oper[0]^.reg,tai(next.Next)); + if assigned(dealloc) then + begin + { taicpu(p).oper[0]^.reg is not used anymore, try to find its allocation + and remove it if possible } + GetLastInstruction(p,hp1); + + asml.Remove(dealloc); + alloc:=FindRegAlloc(taicpu(p).oper[0]^.reg,tai(hp1.Next)); + if assigned(alloc) then + begin + asml.Remove(alloc); + alloc.free; + dealloc.free; + end + else + asml.InsertAfter(dealloc,p); + + { try to move the allocation of the target register } + GetLastInstruction(next,hp1); + alloc:=FindRegAlloc(taicpu(next).oper[0]^.reg,tai(hp1.Next)); + if assigned(alloc) then + begin + asml.Remove(alloc); + asml.InsertBefore(alloc,p); + { adjust used regs } + IncludeRegInUsedRegs(taicpu(next).oper[0]^.reg,UsedRegs); + end; + + { finally get rid of the mov } + taicpu(p).loadreg(0,taicpu(next).oper[0]^.reg); + asml.remove(next); + next.free; + end; + end; + end; + + + function TCpuAsmOptimizer.PeepHoleOptPass1Cpu(var p: tai): boolean; + var + next,next2: tai; + begin + result:=false; + case p.typ of + ait_instruction: + begin + case taicpu(p).opcode of + A_SRL: + begin + { Remove 'andi' in sequences + srl Rx,Ry,16 + andi Rx,Rx,65535 + + srl Rx,Ry,24 + andi Rx,Rx,255 + since 'srl' clears all relevant upper bits } + if (taicpu(p).oper[2]^.typ=top_const) and + GetNextInstruction(p,next) and + MatchInstruction(next,A_ANDI) and + IsSameReg(taicpu(p),taicpu(next)) and + (taicpu(next).oper[2]^.typ=top_const) and + (( + (taicpu(p).oper[2]^.val>=16) and + (taicpu(next).oper[2]^.val=65535) + ) or ( + (taicpu(p).oper[2]^.val>=24) and + (taicpu(next).oper[2]^.val=255) + )) then + begin + asml.remove(next); + next.free; + end + else + TryRemoveMov(p); + end; + + A_ANDI: + begin + { Remove sign extension after 'andi' if bit 7/15 of const operand is clear } + if (taicpu(p).oper[2]^.typ=top_const) and + GetNextInstruction(p,next) and + MatchInstruction(next,A_SLL) and + GetNextInstruction(next,next2) and + MatchInstruction(next2,A_SRA) and + IsSameReg(taicpu(p),taicpu(next)) and + IsSameReg(taicpu(p),taicpu(next2)) and + (taicpu(next).oper[2]^.typ=top_const) and + (taicpu(next2).oper[2]^.typ=top_const) and + (taicpu(next).oper[2]^.val=taicpu(next2).oper[2]^.val) and + (( + (taicpu(p).oper[2]^.val<=$7fff) and + (taicpu(next).oper[2]^.val=16) + ) or ( + (taicpu(p).oper[2]^.val<=$7f) and + (taicpu(next).oper[2]^.val=24) + )) then + begin + asml.remove(next); + asml.remove(next2); + next.free; + next2.free; + end + else + TryRemoveMov(p); + end; + + A_ADD,A_ADDU, + A_ADDI,A_ADDIU, + A_SUB,A_SUBU, + A_SRA,A_SRAV, + A_SRLV, + A_SLL,A_SLLV, + A_AND,A_OR,A_XOR,A_ORI,A_XORI: + TryRemoveMov(p); + end; + end; + end; + end; + begin casmoptimizer:=TCpuAsmOptimizer; end.