|
@@ -4155,8 +4155,8 @@ unit aoptx86;
|
|
|
movq x(ref),%reg64
|
|
|
shrq y,%reg64
|
|
|
To:
|
|
|
- movq x+4(ref),%reg32
|
|
|
- shrq y-32,%reg32 (Remove if y = 32)
|
|
|
+ movl x+4(ref),%reg32
|
|
|
+ shrl y-32,%reg32 (Remove if y = 32)
|
|
|
}
|
|
|
if (taicpu(p).opsize = S_Q) and
|
|
|
(taicpu(p).oper[0]^.typ = top_ref) and { Second operand will be a register }
|
|
@@ -4198,6 +4198,55 @@ unit aoptx86;
|
|
|
Exit;
|
|
|
end;
|
|
|
{$endif x86_64}
|
|
|
+
|
|
|
+ { Backward optimisation. If we have:
|
|
|
+ func. %reg1,%reg2
|
|
|
+ mov %reg2,%reg3
|
|
|
+ (dealloc %reg2)
|
|
|
+
|
|
|
+ Change to:
|
|
|
+ func. %reg1,%reg3 (see comment below for what a valid func. is)
|
|
|
+ }
|
|
|
+ if MatchOpType(taicpu(p), top_reg, top_reg) then
|
|
|
+ begin
|
|
|
+ CurrentReg := taicpu(p).oper[0]^.reg;
|
|
|
+ ActiveReg := taicpu(p).oper[1]^.reg;
|
|
|
+ TransferUsedRegs(TmpUsedRegs);
|
|
|
+ if not RegUsedAfterInstruction(CurrentReg, p, TmpUsedRegs) and
|
|
|
+ GetLastInstruction(p, hp2) and
|
|
|
+ (hp2.typ = ait_instruction) and
|
|
|
+ { Have to make sure it's an instruction that only reads from
|
|
|
+ operand 1 and only writes (not reads or modifies) from operand 2;
|
|
|
+ in essence, a one-operand pure function such as BSR or POPCNT }
|
|
|
+ (taicpu(hp2).ops = 2) and
|
|
|
+ (insprop[taicpu(hp2).opcode].Ch * [Ch_Rop1, Ch_Wop2] = [Ch_Rop1, Ch_Wop2]) and
|
|
|
+ (taicpu(hp2).oper[1]^.typ = top_reg) and
|
|
|
+ (taicpu(hp2).oper[1]^.reg = CurrentReg) then
|
|
|
+ begin
|
|
|
+ case taicpu(hp2).opcode of
|
|
|
+ A_FSTSW, A_FNSTSW,
|
|
|
+ A_IN, A_INS, A_OUT, A_OUTS,
|
|
|
+ A_CMPS, A_LODS, A_MOVS, A_SCAS, A_STOS,
|
|
|
+ { These routines have explicit operands, but they are restricted in
|
|
|
+ what they can be (e.g. IN and OUT can only read from AL, AX or
|
|
|
+ EAX. }
|
|
|
+ A_CMOVcc:
|
|
|
+ { CMOV is not valid either because then CurrentReg will depend
|
|
|
+ on an unknown value if the condition is False and hence is
|
|
|
+ not a pure write }
|
|
|
+ ;
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ DebugMsg(SPeepholeOptimization + 'Removed MOV and changed destination on previous instruction to optimise register usage (FuncMov2Func)', p);
|
|
|
+ taicpu(hp2).oper[1]^.reg := ActiveReg;
|
|
|
+ AllocRegBetween(ActiveReg, hp2, p, TmpUsedRegs);
|
|
|
+ RemoveCurrentp(p, hp1);
|
|
|
+ Result := True;
|
|
|
+ Exit;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
|