mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-09 16:48:10 +02:00
* getfinaldestination works completely again (a lot of functionality
got lost in the conversion resulting from the removal of ait_labeled_instruction)
This commit is contained in:
parent
52340aa35a
commit
621cecced4
@ -34,6 +34,9 @@ Implementation
|
|||||||
Uses
|
Uses
|
||||||
globtype,systems,
|
globtype,systems,
|
||||||
globals,verbose,hcodegen,
|
globals,verbose,hcodegen,
|
||||||
|
{$ifdef finaldestdebug}
|
||||||
|
cobjects,
|
||||||
|
{$endif finaldestdebug}
|
||||||
cpubase,cpuasm,DAOpt386;
|
cpubase,cpuasm,DAOpt386;
|
||||||
|
|
||||||
Function RegUsedAfterInstruction(Reg: TRegister; p: Pai; Var UsedRegs: TRegSet): Boolean;
|
Function RegUsedAfterInstruction(Reg: TRegister; p: Pai; Var UsedRegs: TRegSet): Boolean;
|
||||||
@ -57,7 +60,25 @@ Var
|
|||||||
|
|
||||||
UsedRegs, TmpUsedRegs: TRegSet;
|
UsedRegs, TmpUsedRegs: TRegSet;
|
||||||
|
|
||||||
Procedure GetFinalDestination(hp: paicpu);
|
Function SkipLabels(hp: Pai; var hp2: pai): boolean;
|
||||||
|
{skips all labels and returns the next "real" instruction}
|
||||||
|
Begin
|
||||||
|
While assigned(hp^.next) and
|
||||||
|
(pai(hp^.next)^.typ In SkipInstr + [ait_label,ait_align]) Do
|
||||||
|
hp := pai(hp^.next);
|
||||||
|
If assigned(hp^.next) Then
|
||||||
|
Begin
|
||||||
|
SkipLabels := True;
|
||||||
|
hp2 := pai(hp^.next)
|
||||||
|
End
|
||||||
|
Else
|
||||||
|
Begin
|
||||||
|
hp2 := hp;
|
||||||
|
SkipLabels := False
|
||||||
|
End;
|
||||||
|
End;
|
||||||
|
|
||||||
|
Procedure GetFinalDestination(AsmL: PAAsmOutput; hp: paicpu);
|
||||||
{traces sucessive jumps to their final destination and sets it, e.g.
|
{traces sucessive jumps to their final destination and sets it, e.g.
|
||||||
je l1 je l3
|
je l1 je l3
|
||||||
<code> <code>
|
<code> <code>
|
||||||
@ -67,18 +88,21 @@ Var
|
|||||||
l2: l2:
|
l2: l2:
|
||||||
jmp l3 jmp l3}
|
jmp l3 jmp l3}
|
||||||
|
|
||||||
Var p1: pai;
|
Var p1, p2: pai;
|
||||||
|
l: pasmlabel;
|
||||||
|
|
||||||
Function SkipLabels(hp: Pai): Pai;
|
Function FindAnyLabel(hp: pai; var l: pasmlabel): Boolean;
|
||||||
{skips all labels and returns the next "real" instruction; it is
|
|
||||||
assumed that hp is of the type ait_label}
|
|
||||||
Begin
|
Begin
|
||||||
|
FindAnyLabel := false;
|
||||||
While assigned(hp^.next) and
|
While assigned(hp^.next) and
|
||||||
(pai(hp^.next)^.typ In SkipInstr + [ait_label]) Do
|
(pai(hp^.next)^.typ In (SkipInstr+[ait_align])) Do
|
||||||
hp := pai(hp^.next);
|
hp := pai(hp^.next);
|
||||||
If assigned(hp^.next)
|
If assigned(hp^.next) and
|
||||||
Then SkipLabels := pai(hp^.next)
|
(pai(hp^.next)^.typ = ait_label) Then
|
||||||
Else SkipLabels := hp;
|
Begin
|
||||||
|
FindAnyLabel := true;
|
||||||
|
l := pai_label(hp^.next)^.l;
|
||||||
|
End
|
||||||
End;
|
End;
|
||||||
|
|
||||||
Begin
|
Begin
|
||||||
@ -87,16 +111,57 @@ Var
|
|||||||
Assigned(LTable^[pasmlabel(hp^.oper[0].sym)^.labelnr-LoLab].PaiObj) Then
|
Assigned(LTable^[pasmlabel(hp^.oper[0].sym)^.labelnr-LoLab].PaiObj) Then
|
||||||
Begin
|
Begin
|
||||||
p1 := LTable^[pasmlabel(hp^.oper[0].sym)^.labelnr-LoLab].PaiObj; {the jump's destination}
|
p1 := LTable^[pasmlabel(hp^.oper[0].sym)^.labelnr-LoLab].PaiObj; {the jump's destination}
|
||||||
p1 := SkipLabels(p1);
|
SkipLabels(p1,p1);
|
||||||
If (pai(p1)^.typ = ait_instruction) and
|
If (pai(p1)^.typ = ait_instruction) and
|
||||||
(paicpu(p1)^.is_jmp) and
|
(paicpu(p1)^.is_jmp) Then
|
||||||
(paicpu(p1)^.condition = hp^.condition) Then
|
If { the next instruction after the label where the jump hp arrives}
|
||||||
|
{ is unconditional or of the same type as hp, so continue }
|
||||||
|
(paicpu(p1)^.condition in [C_None,hp^.condition]) or
|
||||||
|
{ the next instruction after the label where the jump hp arrives}
|
||||||
|
{ is the opposite of hp (so this one is never taken), but after }
|
||||||
|
{ that one there is a branch that will be taken, so perform a }
|
||||||
|
{ little hack: set p1 equal to this instruction (that's what the}
|
||||||
|
{ last SkipLabels is for, only works with short bool evaluation)}
|
||||||
|
((paicpu(p1)^.condition = inverse_cond[hp^.condition]) and
|
||||||
|
SkipLabels(p1,p2) and
|
||||||
|
(p2^.typ = ait_instruction) and
|
||||||
|
(paicpu(p2)^.is_jmp) and
|
||||||
|
(paicpu(p2)^.condition in [C_None,hp^.condition]) and
|
||||||
|
SkipLabels(p1,p1)) Then
|
||||||
Begin
|
Begin
|
||||||
GetFinalDestination(paicpu(p1));
|
GetFinalDestination(asml, paicpu(p1));
|
||||||
Dec(pasmlabel(hp^.oper[0].sym)^.refs);
|
Dec(pasmlabel(hp^.oper[0].sym)^.refs);
|
||||||
hp^.oper[0].sym:=paicpu(p1)^.oper[0].sym;
|
hp^.oper[0].sym:=paicpu(p1)^.oper[0].sym;
|
||||||
inc(pasmlabel(hp^.oper[0].sym)^.refs);
|
inc(pasmlabel(hp^.oper[0].sym)^.refs);
|
||||||
End;
|
End
|
||||||
|
Else
|
||||||
|
If (paicpu(p1)^.condition = inverse_cond[hp^.condition]) then
|
||||||
|
if not FindAnyLabel(p1,l) then
|
||||||
|
begin
|
||||||
|
{$ifdef finaldestdebug}
|
||||||
|
insertllitem(asml,p1,p1^.next,new(pai_asm_comment,init(
|
||||||
|
strpnew('previous label inserted'))));
|
||||||
|
{$endif finaldestdebug}
|
||||||
|
getlabel(l);
|
||||||
|
insertllitem(asml,p1,p1^.next,new(pai_label,init(l)));
|
||||||
|
dec(pasmlabel(paicpu(hp)^.oper[0].sym)^.refs);
|
||||||
|
hp^.oper[0].sym := l;
|
||||||
|
inc(l^.refs);
|
||||||
|
{ this won't work, since the new label isn't in the labeltable }
|
||||||
|
{ so it will fail the rangecheck. Labeltable should become a }
|
||||||
|
{ hashtable to support this: }
|
||||||
|
{ GetFinalDestination(asml, hp); }
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
{$ifdef finaldestdebug}
|
||||||
|
insertllitem(asml,p1,p1^.next,new(pai_asm_comment,init(
|
||||||
|
strpnew('next label reused'))));
|
||||||
|
{$endif finaldestdebug}
|
||||||
|
inc(l^.refs);
|
||||||
|
hp^.oper[0].sym := l;
|
||||||
|
GetFinalDestination(asml, hp);
|
||||||
|
end;
|
||||||
End;
|
End;
|
||||||
End;
|
End;
|
||||||
|
|
||||||
@ -173,6 +238,18 @@ Begin
|
|||||||
End;
|
End;
|
||||||
If GetNextInstruction(p, hp1) then
|
If GetNextInstruction(p, hp1) then
|
||||||
Begin
|
Begin
|
||||||
|
if FindLabel(pasmlabel(paicpu(p)^.oper[0].sym), hp1) then
|
||||||
|
Begin
|
||||||
|
hp2:=pai(hp1^.next);
|
||||||
|
asml^.remove(p);
|
||||||
|
dispose(p,done);
|
||||||
|
p:=hp2;
|
||||||
|
continue;
|
||||||
|
end
|
||||||
|
Else
|
||||||
|
Begin
|
||||||
|
if hp1^.typ = ait_label then
|
||||||
|
SkipLabels(hp1,hp1);
|
||||||
If (pai(hp1)^.typ=ait_instruction) and
|
If (pai(hp1)^.typ=ait_instruction) and
|
||||||
(paicpu(hp1)^.opcode=A_JMP) and
|
(paicpu(hp1)^.opcode=A_JMP) and
|
||||||
GetNextInstruction(hp1, hp2) And
|
GetNextInstruction(hp1, hp2) And
|
||||||
@ -184,7 +261,7 @@ Begin
|
|||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
If (LabDif <> 0) Then
|
If (LabDif <> 0) Then
|
||||||
GetFinalDestination(paicpu(p));
|
GetFinalDestination(asml, paicpu(p));
|
||||||
p:=pai(p^.next);
|
p:=pai(p^.next);
|
||||||
continue;
|
continue;
|
||||||
end;
|
end;
|
||||||
@ -194,20 +271,12 @@ Begin
|
|||||||
asml^.remove(hp1);
|
asml^.remove(hp1);
|
||||||
dispose(hp1,done);
|
dispose(hp1,done);
|
||||||
If (LabDif <> 0) Then
|
If (LabDif <> 0) Then
|
||||||
GetFinalDestination(paicpu(p));
|
GetFinalDestination(asml, paicpu(p));
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if FindLabel(pasmlabel(paicpu(p)^.oper[0].sym), hp1) then
|
|
||||||
Begin
|
|
||||||
hp2:=pai(hp1^.next);
|
|
||||||
asml^.remove(p);
|
|
||||||
dispose(p,done);
|
|
||||||
p:=hp2;
|
|
||||||
continue;
|
|
||||||
end
|
|
||||||
Else
|
|
||||||
If (LabDif <> 0) Then
|
If (LabDif <> 0) Then
|
||||||
GetFinalDestination(paicpu(p));
|
GetFinalDestination(asml, paicpu(p));
|
||||||
|
end;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -1603,7 +1672,12 @@ End.
|
|||||||
|
|
||||||
{
|
{
|
||||||
$Log$
|
$Log$
|
||||||
Revision 1.67 1999-11-06 14:34:23 peter
|
Revision 1.68 1999-11-06 16:24:00 jonas
|
||||||
|
* getfinaldestination works completely again (a lot of functionality
|
||||||
|
got lost in the conversion resulting from the removal of
|
||||||
|
ait_labeled_instruction)
|
||||||
|
|
||||||
|
Revision 1.67 1999/11/06 14:34:23 peter
|
||||||
* truncated log to 20 revs
|
* truncated log to 20 revs
|
||||||
|
|
||||||
Revision 1.66 1999/09/27 23:44:55 peter
|
Revision 1.66 1999/09/27 23:44:55 peter
|
||||||
|
Loading…
Reference in New Issue
Block a user