|
@@ -8228,6 +8228,65 @@ unit aoptx86;
|
|
|
end;
|
|
|
end;
|
|
|
|
|
|
+ function AdjustInitialLoad: Boolean;
|
|
|
+ begin
|
|
|
+ Result := False;
|
|
|
+
|
|
|
+ if not p_removed then
|
|
|
+ begin
|
|
|
+ if TargetSize = MinSize then
|
|
|
+ begin
|
|
|
+ { Convert the input MOVZX to a MOV }
|
|
|
+ if (taicpu(p).oper[0]^.typ = top_reg) and
|
|
|
+ SuperRegistersEqual(taicpu(p).oper[0]^.reg, ThisReg) then
|
|
|
+ begin
|
|
|
+ { Or remove it completely! }
|
|
|
+ DebugMsg(SPeepholeOptimization + 'Movzx2Nop 1', p);
|
|
|
+ RemoveCurrentP(p);
|
|
|
+ p_removed := True;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ DebugMsg(SPeepholeOptimization + 'Movzx2Mov 1', p);
|
|
|
+ taicpu(p).opcode := A_MOV;
|
|
|
+ taicpu(p).oper[1]^.reg := ThisReg;
|
|
|
+ taicpu(p).opsize := TargetSize;
|
|
|
+ end;
|
|
|
+
|
|
|
+ Result := True;
|
|
|
+ end
|
|
|
+ else if TargetSize <> MaxSize then
|
|
|
+ begin
|
|
|
+
|
|
|
+ case MaxSize of
|
|
|
+ S_L:
|
|
|
+ if TargetSize = S_W then
|
|
|
+ begin
|
|
|
+ DebugMsg(SPeepholeOptimization + 'movzbl2movzbw', p);
|
|
|
+ taicpu(p).opsize := S_BW;
|
|
|
+ taicpu(p).oper[1]^.reg := ThisReg;
|
|
|
+ Result := True;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ InternalError(2020112341);
|
|
|
+
|
|
|
+ S_W:
|
|
|
+ if TargetSize = S_L then
|
|
|
+ begin
|
|
|
+ DebugMsg(SPeepholeOptimization + 'movzbw2movzbl', p);
|
|
|
+ taicpu(p).opsize := S_BL;
|
|
|
+ taicpu(p).oper[1]^.reg := ThisReg;
|
|
|
+ Result := True;
|
|
|
+ end
|
|
|
+ else
|
|
|
+ InternalError(2020112342);
|
|
|
+ else
|
|
|
+ ;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+
|
|
|
procedure AdjustFinalLoad;
|
|
|
begin
|
|
|
if ((TargetSize = S_L) and (taicpu(hp1).opsize in [S_L, S_BL, S_WL])) or
|
|
@@ -8453,60 +8512,7 @@ unit aoptx86;
|
|
|
else
|
|
|
AdjustFinalLoad;
|
|
|
|
|
|
- if not p_removed then
|
|
|
- begin
|
|
|
- if TargetSize = MinSize then
|
|
|
- begin
|
|
|
- { Convert the input MOVZX to a MOV }
|
|
|
- if (taicpu(p).oper[0]^.typ = top_reg) and
|
|
|
- SuperRegistersEqual(taicpu(p).oper[0]^.reg, ThisReg) then
|
|
|
- begin
|
|
|
- { Or remove it completely! }
|
|
|
- DebugMsg(SPeepholeOptimization + 'Movzx2Nop 1', p);
|
|
|
- DebugMsg(SPeepholeOptimization + tostr(InstrMax), p);
|
|
|
- RemoveCurrentP(p);
|
|
|
- p_removed := True;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- DebugMsg(SPeepholeOptimization + 'Movzx2Mov 1', p);
|
|
|
- taicpu(p).opcode := A_MOV;
|
|
|
- taicpu(p).oper[1]^.reg := ThisReg;
|
|
|
- taicpu(p).opsize := TargetSize;
|
|
|
- end;
|
|
|
-
|
|
|
- Result := True;
|
|
|
- end
|
|
|
- else if TargetSize <> MaxSize then
|
|
|
- begin
|
|
|
-
|
|
|
- case MaxSize of
|
|
|
- S_L:
|
|
|
- if TargetSize = S_W then
|
|
|
- begin
|
|
|
- DebugMsg(SPeepholeOptimization + 'movzbl2movzbw', p);
|
|
|
- taicpu(p).opsize := S_BW;
|
|
|
- taicpu(p).oper[1]^.reg := ThisReg;
|
|
|
- Result := True;
|
|
|
- end
|
|
|
- else
|
|
|
- InternalError(2020112341);
|
|
|
-
|
|
|
- S_W:
|
|
|
- if TargetSize = S_L then
|
|
|
- begin
|
|
|
- DebugMsg(SPeepholeOptimization + 'movzbw2movzbl', p);
|
|
|
- taicpu(p).opsize := S_BL;
|
|
|
- taicpu(p).oper[1]^.reg := ThisReg;
|
|
|
- Result := True;
|
|
|
- end
|
|
|
- else
|
|
|
- InternalError(2020112342);
|
|
|
- else
|
|
|
- ;
|
|
|
- end;
|
|
|
- end;
|
|
|
- end;
|
|
|
+ Result := AdjustInitialLoad or Result;
|
|
|
|
|
|
{ Now go through every instruction we found and change the
|
|
|
size. If TargetSize = MaxSize, then almost no changes are
|
|
@@ -8820,50 +8826,39 @@ unit aoptx86;
|
|
|
InternalError(2021051002);
|
|
|
end;
|
|
|
|
|
|
- { Update the register to its new size }
|
|
|
- setsubreg(ThisReg, TargetSubReg);
|
|
|
+ if TargetSize <> MaxSize then
|
|
|
+ begin
|
|
|
+ { Update the register to its new size }
|
|
|
+ setsubreg(ThisReg, TargetSubReg);
|
|
|
|
|
|
- taicpu(hp1).oper[1]^.reg := ThisReg;
|
|
|
- taicpu(hp1).opsize := MinSize;
|
|
|
+ DebugMsg(SPeepholeOptimization + 'CMP instruction resized thanks to register size optimisation (see MOV/Z assignment above)', hp1);
|
|
|
+ taicpu(hp1).oper[1]^.reg := ThisReg;
|
|
|
+ taicpu(hp1).opsize := TargetSize;
|
|
|
|
|
|
- { Convert the input MOVZX to a MOV }
|
|
|
- if (taicpu(p).oper[0]^.typ = top_reg) and
|
|
|
- SuperRegistersEqual(taicpu(p).oper[0]^.reg, ThisReg) then
|
|
|
- begin
|
|
|
- { Or remove it completely! }
|
|
|
- DebugMsg(SPeepholeOptimization + 'Movzx2Nop 1a', p);
|
|
|
- RemoveCurrentP(p);
|
|
|
- p_removed := True;
|
|
|
- end
|
|
|
- else
|
|
|
- begin
|
|
|
- DebugMsg(SPeepholeOptimization + 'Movzx2Mov 1a', p);
|
|
|
- taicpu(p).opcode := A_MOV;
|
|
|
- taicpu(p).oper[1]^.reg := ThisReg;
|
|
|
- taicpu(p).opsize := MinSize;
|
|
|
- end;
|
|
|
+ { Convert the input MOVZX to a MOV if necessary }
|
|
|
+ AdjustInitialLoad;
|
|
|
|
|
|
- if (InstrMax >= 0) then
|
|
|
- begin
|
|
|
- for Index := 0 to InstrMax do
|
|
|
+ if (InstrMax >= 0) then
|
|
|
begin
|
|
|
+ for Index := 0 to InstrMax do
|
|
|
+ begin
|
|
|
|
|
|
- { If p_removed is true, then the original MOV/Z was removed
|
|
|
- and removing the AND instruction may not be safe if it
|
|
|
- appears first }
|
|
|
- if (InstrList[Index].oper[InstrList[Index].ops - 1]^.typ <> top_reg) then
|
|
|
- InternalError(2020112311);
|
|
|
+ { If p_removed is true, then the original MOV/Z was removed
|
|
|
+ and removing the AND instruction may not be safe if it
|
|
|
+ appears first }
|
|
|
+ if (InstrList[Index].oper[InstrList[Index].ops - 1]^.typ <> top_reg) then
|
|
|
+ InternalError(2020112311);
|
|
|
|
|
|
- if InstrList[Index].oper[0]^.typ = top_reg then
|
|
|
- InstrList[Index].oper[0]^.reg := ThisReg;
|
|
|
+ if InstrList[Index].oper[0]^.typ = top_reg then
|
|
|
+ InstrList[Index].oper[0]^.reg := ThisReg;
|
|
|
|
|
|
- InstrList[Index].oper[InstrList[Index].ops - 1]^.reg := ThisReg;
|
|
|
- InstrList[Index].opsize := MinSize;
|
|
|
+ InstrList[Index].oper[InstrList[Index].ops - 1]^.reg := ThisReg;
|
|
|
+ InstrList[Index].opsize := MinSize;
|
|
|
+ end;
|
|
|
end;
|
|
|
|
|
|
+ Result := True;
|
|
|
end;
|
|
|
-
|
|
|
- Result := True;
|
|
|
Exit;
|
|
|
end;
|
|
|
end;
|