diff --git a/compiler/x86/aoptx86.pas b/compiler/x86/aoptx86.pas index 55ae9ee3d1..98d0188a55 100644 --- a/compiler/x86/aoptx86.pas +++ b/compiler/x86/aoptx86.pas @@ -10640,7 +10640,41 @@ unit aoptx86; function TX86AsmOptimizer.PostPeepholeOptADDSUB(var p : tai) : boolean; var hp1, hp2: tai; + Opposite: TAsmOp; begin + Result := False; + + { Change: + add/sub 128,(dest) + + To: + sub/add -128,(dest) + + This generaally takes fewer bytes to encode because -128 can be stored + in a signed byte, whereas +128 cannot. + } + if (taicpu(p).opsize <> S_B) and MatchOperand(taicpu(p).oper[0]^, 128) then + begin + if taicpu(p).opcode = A_ADD then + Opposite := A_SUB + else + Opposite := A_ADD; + + DebugMsg(SPeepholeOptimization + debug_op2str(taicpu(p).opcode) + ' 128,' + debug_operstr(taicpu(p).oper[1]^) + ' changed to ' + + debug_op2str(opposite) + ' -128,' + debug_operstr(taicpu(p).oper[1]^) + ' to reduce instruction size', p); + + taicpu(p).opcode := Opposite; + taicpu(p).oper[0]^.val := -128; + + { No further optimisations can be made on this instruction, so move + onto the next one to save time } + p := tai(p.Next); + UpdateUsedRegs(p); + + Result := True; + Exit; + end; + { Detect: add/sub %reg2,(dest) add/sub x, (dest) @@ -10651,8 +10685,6 @@ unit aoptx86; "Add swap" and "Sub swap" optimisations done in pass 1 if no new optimisations could be made. } - - Result := False; if (taicpu(p).oper[0]^.typ = top_reg) and not RegInOp(taicpu(p).oper[0]^.reg, taicpu(p).oper[1]^) and (