* 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:
Jonas Maebe 1999-11-06 16:24:00 +00:00
parent 52340aa35a
commit 621cecced4

View File

@ -34,6 +34,9 @@ Implementation
Uses
globtype,systems,
globals,verbose,hcodegen,
{$ifdef finaldestdebug}
cobjects,
{$endif finaldestdebug}
cpubase,cpuasm,DAOpt386;
Function RegUsedAfterInstruction(Reg: TRegister; p: Pai; Var UsedRegs: TRegSet): Boolean;
@ -57,7 +60,25 @@ Var
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.
je l1 je l3
<code> <code>
@ -67,18 +88,21 @@ Var
l2: l2:
jmp l3 jmp l3}
Var p1: pai;
Var p1, p2: pai;
l: pasmlabel;
Function SkipLabels(hp: Pai): Pai;
{skips all labels and returns the next "real" instruction; it is
assumed that hp is of the type ait_label}
Function FindAnyLabel(hp: pai; var l: pasmlabel): Boolean;
Begin
FindAnyLabel := false;
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);
If assigned(hp^.next)
Then SkipLabels := pai(hp^.next)
Else SkipLabels := hp;
If assigned(hp^.next) and
(pai(hp^.next)^.typ = ait_label) Then
Begin
FindAnyLabel := true;
l := pai_label(hp^.next)^.l;
End
End;
Begin
@ -87,16 +111,57 @@ Var
Assigned(LTable^[pasmlabel(hp^.oper[0].sym)^.labelnr-LoLab].PaiObj) Then
Begin
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
(paicpu(p1)^.is_jmp) and
(paicpu(p1)^.condition = hp^.condition) Then
Begin
GetFinalDestination(paicpu(p1));
Dec(pasmlabel(hp^.oper[0].sym)^.refs);
hp^.oper[0].sym:=paicpu(p1)^.oper[0].sym;
inc(pasmlabel(hp^.oper[0].sym)^.refs);
End;
(paicpu(p1)^.is_jmp) 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
GetFinalDestination(asml, paicpu(p1));
Dec(pasmlabel(hp^.oper[0].sym)^.refs);
hp^.oper[0].sym:=paicpu(p1)^.oper[0].sym;
inc(pasmlabel(hp^.oper[0].sym)^.refs);
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;
@ -173,41 +238,45 @@ Begin
End;
If GetNextInstruction(p, hp1) then
Begin
If (pai(hp1)^.typ=ait_instruction) and
(paicpu(hp1)^.opcode=A_JMP) and
GetNextInstruction(hp1, hp2) And
FindLabel(PAsmLabel(paicpu(p)^.oper[0].sym), hp2)
Then
Begin
if paicpu(p)^.opcode=A_Jcc then
paicpu(p)^.condition:=inverse_cond[paicpu(p)^.condition]
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
(paicpu(hp1)^.opcode=A_JMP) and
GetNextInstruction(hp1, hp2) And
FindLabel(PAsmLabel(paicpu(p)^.oper[0].sym), hp2)
Then
Begin
if paicpu(p)^.opcode=A_Jcc then
paicpu(p)^.condition:=inverse_cond[paicpu(p)^.condition]
else
begin
If (LabDif <> 0) Then
GetFinalDestination(asml, paicpu(p));
p:=pai(p^.next);
continue;
end;
Dec(pai_label(hp2)^.l^.refs);
paicpu(p)^.oper[0].sym:=paicpu(hp1)^.oper[0].sym;
Inc(paicpu(p)^.oper[0].sym^.refs);
asml^.remove(hp1);
dispose(hp1,done);
If (LabDif <> 0) Then
GetFinalDestination(asml, paicpu(p));
end
else
begin
If (LabDif <> 0) Then
GetFinalDestination(paicpu(p));
p:=pai(p^.next);
continue;
end;
Dec(pai_label(hp2)^.l^.refs);
paicpu(p)^.oper[0].sym:=paicpu(hp1)^.oper[0].sym;
Inc(paicpu(p)^.oper[0].sym^.refs);
asml^.remove(hp1);
dispose(hp1,done);
If (LabDif <> 0) Then
GetFinalDestination(paicpu(p));
end
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
GetFinalDestination(paicpu(p));
If (LabDif <> 0) Then
GetFinalDestination(asml, paicpu(p));
end;
end
end
else
@ -1603,7 +1672,12 @@ End.
{
$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
Revision 1.66 1999/09/27 23:44:55 peter