mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-03 11:30:25 +02:00
* patch by J. Gareth Moreton: CMOV extensions: frame/stack pointer relative references are always valid, resolves #36675
git-svn-id: trunk@44141 -
This commit is contained in:
parent
d750582581
commit
12d015a935
@ -61,6 +61,15 @@ unit aoptx86;
|
||||
except where the register is being written }
|
||||
function ReplaceRegisterInInstruction(const p: taicpu; const AOldReg, ANewReg: TRegister): Boolean;
|
||||
|
||||
{ Returns true if the reference only refers to ESP or EBP (or their 64-bit equivalents),
|
||||
or writes to a global symbol }
|
||||
class function IsRefSafe(const ref: PReference): Boolean; static; inline;
|
||||
|
||||
|
||||
{ Returns true if the given MOV instruction can be safely converted to CMOV }
|
||||
class function CanBeCMOV(p : tai) : boolean; static;
|
||||
|
||||
|
||||
function DeepMOVOpt(const p_mov: taicpu; const hp: taicpu): Boolean;
|
||||
|
||||
procedure DebugMsg(const s : string; p : tai);inline;
|
||||
@ -1627,6 +1636,23 @@ unit aoptx86;
|
||||
end;
|
||||
|
||||
|
||||
class function TX86AsmOptimizer.IsRefSafe(const ref: PReference): Boolean; inline;
|
||||
begin
|
||||
Result :=
|
||||
(ref^.index = NR_NO) and
|
||||
(
|
||||
{$ifdef x86_64}
|
||||
(
|
||||
(ref^.base = NR_RIP) and
|
||||
(ref^.refaddr in [addr_pic, addr_pic_no_got])
|
||||
) or
|
||||
{$endif x86_64}
|
||||
(ref^.base = NR_STACK_POINTER_REG) or
|
||||
(ref^.base = current_procinfo.framepointer)
|
||||
);
|
||||
end;
|
||||
|
||||
|
||||
function TX86AsmOptimizer.DeepMOVOpt(const p_mov: taicpu; const hp: taicpu): Boolean;
|
||||
var
|
||||
CurrentReg, ReplaceReg: TRegister;
|
||||
@ -4638,7 +4664,7 @@ unit aoptx86;
|
||||
end;
|
||||
|
||||
|
||||
function CanBeCMOV(p : tai) : boolean;
|
||||
class function TX86AsmOptimizer.CanBeCMOV(p : tai) : boolean;
|
||||
begin
|
||||
CanBeCMOV:=assigned(p) and
|
||||
MatchInstruction(p,A_MOV,[S_W,S_L,S_Q]) and
|
||||
@ -4648,16 +4674,15 @@ unit aoptx86;
|
||||
or ((taicpu(p).oper[0]^.typ = top_ref) and
|
||||
(taicpu(p).oper[0]^.ref^.refaddr = addr_no))
|
||||
}
|
||||
(MatchOpType(taicpu(p),top_reg,top_reg) or
|
||||
{ allow references, but only pure symbols or got rel. addressing with RIP as based,
|
||||
it is not expected that this can cause a seg. violation }
|
||||
(MatchOpType(taicpu(p),top_ref,top_reg) and
|
||||
(((taicpu(p).oper[0]^.ref^.base=NR_NO) and (taicpu(p).oper[0]^.ref^.refaddr=addr_no)){$ifdef x86_64} or
|
||||
((taicpu(p).oper[0]^.ref^.base=NR_RIP) and (taicpu(p).oper[0]^.ref^.refaddr=addr_pic)){$endif x86_64}
|
||||
) and
|
||||
(taicpu(p).oper[0]^.ref^.index=NR_NO) and
|
||||
(taicpu(p).oper[0]^.ref^.offset=0)
|
||||
)
|
||||
(taicpu(p).oper[1]^.typ = top_reg) and
|
||||
(
|
||||
(taicpu(p).oper[0]^.typ = top_reg) or
|
||||
{ allow references, but only pure symbols or got rel. addressing with RIP as based,
|
||||
it is not expected that this can cause a seg. violation }
|
||||
(
|
||||
(taicpu(p).oper[0]^.typ = top_ref) and
|
||||
IsRefSafe(taicpu(p).oper[0]^.ref)
|
||||
)
|
||||
);
|
||||
end;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user