mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-12-07 02:27:11 +01:00
* when inserting pc relative data blocks on arm thumb, avoid negative pc offsets, if needed, the data is copied
a short test with the rtl shows that this happens exactly once in the rtl, so it is feasible to do so git-svn-id: trunk@24413 -
This commit is contained in:
parent
1f8192b6da
commit
cec28ef512
@ -488,6 +488,9 @@ interface
|
|||||||
{ set to true when the label has been moved by insertpcrelativedata to the correct location
|
{ set to true when the label has been moved by insertpcrelativedata to the correct location
|
||||||
so one label can be used multiple times }
|
so one label can be used multiple times }
|
||||||
moved : boolean;
|
moved : boolean;
|
||||||
|
{ true, if a label has been already inserted, this is important for arm thumb where no negative
|
||||||
|
pc relative offsets are allowed }
|
||||||
|
inserted : boolean;
|
||||||
{$endif arm}
|
{$endif arm}
|
||||||
constructor Create(_labsym : tasmlabel);
|
constructor Create(_labsym : tasmlabel);
|
||||||
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
|
constructor ppuload(t:taitype;ppufile:tcompilerppufile);override;
|
||||||
@ -1945,7 +1948,7 @@ implementation
|
|||||||
TAI_LABEL
|
TAI_LABEL
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
|
|
||||||
constructor tai_label.create(_labsym : tasmlabel);
|
constructor tai_label.Create(_labsym : tasmlabel);
|
||||||
begin
|
begin
|
||||||
inherited Create;
|
inherited Create;
|
||||||
typ:=ait_label;
|
typ:=ait_label;
|
||||||
@ -1976,7 +1979,6 @@ implementation
|
|||||||
labsym.is_set:=true;
|
labsym.is_set:=true;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
{****************************************************************************
|
{****************************************************************************
|
||||||
tai_comment comment to be inserted in the assembler file
|
tai_comment comment to be inserted in the assembler file
|
||||||
****************************************************************************}
|
****************************************************************************}
|
||||||
|
|||||||
@ -873,6 +873,7 @@ implementation
|
|||||||
limit: longint;
|
limit: longint;
|
||||||
curop : longint;
|
curop : longint;
|
||||||
curtai : tai;
|
curtai : tai;
|
||||||
|
ai_label : tai_label;
|
||||||
curdatatai,hp,hp2 : tai;
|
curdatatai,hp,hp2 : tai;
|
||||||
curdata : TAsmList;
|
curdata : TAsmList;
|
||||||
l : tasmlabel;
|
l : tasmlabel;
|
||||||
@ -910,67 +911,88 @@ implementation
|
|||||||
begin
|
begin
|
||||||
{ pc relative symbol? }
|
{ pc relative symbol? }
|
||||||
curdatatai:=tai(taicpu(curtai).oper[curop]^.ref^.symboldata);
|
curdatatai:=tai(taicpu(curtai).oper[curop]^.ref^.symboldata);
|
||||||
if assigned(curdatatai) and
|
if assigned(curdatatai) then
|
||||||
{ move only if we're at the first reference of a label }
|
|
||||||
not(tai_label(curdatatai).moved) then
|
|
||||||
begin
|
begin
|
||||||
tai_label(curdatatai).moved:=true;
|
{ create a new copy of a data entry on arm thumb if the entry has been inserted already
|
||||||
{ check if symbol already used. }
|
before because arm thumb does not allow pc relative negative offsets }
|
||||||
{ if yes, reuse the symbol }
|
if (current_settings.cputype in cpu_thumb) and
|
||||||
hp:=tai(curdatatai.next);
|
tai_label(curdatatai).inserted then
|
||||||
removeref:=false;
|
|
||||||
if assigned(hp) then
|
|
||||||
begin
|
begin
|
||||||
case hp.typ of
|
current_asmdata.getjumplabel(l);
|
||||||
ait_const:
|
hp:=tai_label.create(l);
|
||||||
begin
|
listtoinsert.Concat(hp);
|
||||||
if (tai_const(hp).consttype=aitconst_64bit) then
|
hp2:=tai(curdatatai.Next.GetCopy);
|
||||||
inc(extradataoffset,multiplier);
|
hp2.Next:=nil;
|
||||||
end;
|
hp2.Previous:=nil;
|
||||||
ait_comp_64bit,
|
listtoinsert.Concat(hp2);
|
||||||
ait_real_64bit:
|
taicpu(curtai).oper[curop]^.ref^.symboldata:=hp;
|
||||||
begin
|
taicpu(curtai).oper[curop]^.ref^.symbol:=l;
|
||||||
inc(extradataoffset,multiplier);
|
curdatatai:=hp;
|
||||||
end;
|
end;
|
||||||
ait_real_80bit:
|
|
||||||
begin
|
{ move only if we're at the first reference of a label }
|
||||||
inc(extradataoffset,2*multiplier);
|
if not(tai_label(curdatatai).moved) then
|
||||||
end;
|
begin
|
||||||
end;
|
tai_label(curdatatai).moved:=true;
|
||||||
if (hp.typ=ait_const) then
|
{ check if symbol already used. }
|
||||||
|
|
||||||
|
{ if yes, reuse the symbol }
|
||||||
|
hp:=tai(curdatatai.next);
|
||||||
|
removeref:=false;
|
||||||
|
if assigned(hp) then
|
||||||
begin
|
begin
|
||||||
hp2:=tai(curdata.first);
|
case hp.typ of
|
||||||
while assigned(hp2) do
|
ait_const:
|
||||||
|
begin
|
||||||
|
if (tai_const(hp).consttype=aitconst_64bit) then
|
||||||
|
inc(extradataoffset,multiplier);
|
||||||
|
end;
|
||||||
|
ait_comp_64bit,
|
||||||
|
ait_real_64bit:
|
||||||
|
begin
|
||||||
|
inc(extradataoffset,multiplier);
|
||||||
|
end;
|
||||||
|
ait_real_80bit:
|
||||||
|
begin
|
||||||
|
inc(extradataoffset,2*multiplier);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
{ check if the same constant has been already inserted into the currently handled list,
|
||||||
|
if yes, reuse it }
|
||||||
|
if (hp.typ=ait_const) then
|
||||||
begin
|
begin
|
||||||
{ if armconstequal(hp2,hp) then }
|
hp2:=tai(curdata.first);
|
||||||
if (hp2.typ=ait_const) and (tai_const(hp2).sym=tai_const(hp).sym)
|
while assigned(hp2) do
|
||||||
and (tai_const(hp2).value=tai_const(hp).value) and (tai(hp2.previous).typ=ait_label)
|
|
||||||
then
|
|
||||||
begin
|
begin
|
||||||
with taicpu(curtai).oper[curop]^.ref^ do
|
if (hp2.typ=ait_const) and (tai_const(hp2).sym=tai_const(hp).sym)
|
||||||
|
and (tai_const(hp2).value=tai_const(hp).value) and (tai(hp2.previous).typ=ait_label)
|
||||||
|
then
|
||||||
begin
|
begin
|
||||||
symboldata:=hp2.previous;
|
with taicpu(curtai).oper[curop]^.ref^ do
|
||||||
symbol:=tai_label(hp2.previous).labsym;
|
begin
|
||||||
|
symboldata:=hp2.previous;
|
||||||
|
symbol:=tai_label(hp2.previous).labsym;
|
||||||
|
end;
|
||||||
|
removeref:=true;
|
||||||
|
break;
|
||||||
end;
|
end;
|
||||||
removeref:=true;
|
hp2:=tai(hp2.next);
|
||||||
break;
|
|
||||||
end;
|
end;
|
||||||
hp2:=tai(hp2.next);
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
{ move or remove symbol reference }
|
||||||
|
repeat
|
||||||
|
hp:=tai(curdatatai.next);
|
||||||
|
listtoinsert.remove(curdatatai);
|
||||||
|
if removeref then
|
||||||
|
curdatatai.free
|
||||||
|
else
|
||||||
|
curdata.concat(curdatatai);
|
||||||
|
curdatatai:=hp;
|
||||||
|
until (curdatatai=nil) or (curdatatai.typ=ait_label);
|
||||||
|
if lastinspos=-1 then
|
||||||
|
lastinspos:=curinspos;
|
||||||
end;
|
end;
|
||||||
{ move or remove symbol reference }
|
|
||||||
repeat
|
|
||||||
hp:=tai(curdatatai.next);
|
|
||||||
listtoinsert.remove(curdatatai);
|
|
||||||
if removeref then
|
|
||||||
curdatatai.free
|
|
||||||
else
|
|
||||||
curdata.concat(curdatatai);
|
|
||||||
curdatatai:=hp;
|
|
||||||
until (curdatatai=nil) or (curdatatai.typ=ait_label);
|
|
||||||
if lastinspos=-1 then
|
|
||||||
lastinspos:=curinspos;
|
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
@ -1065,6 +1087,18 @@ implementation
|
|||||||
curdata.Insert(tai_align.Create(4));
|
curdata.Insert(tai_align.Create(4));
|
||||||
curdata.insert(taicpu.op_sym(A_B,l));
|
curdata.insert(taicpu.op_sym(A_B,l));
|
||||||
curdata.concat(tai_label.create(l));
|
curdata.concat(tai_label.create(l));
|
||||||
|
|
||||||
|
{ mark all labels as inserted, arm thumb
|
||||||
|
needs this, so data referencing an already inserted label can be
|
||||||
|
duplicated because arm thumb does not allow negative pc relative offset }
|
||||||
|
hp2:=tai(curdata.first);
|
||||||
|
while assigned(hp2) do
|
||||||
|
begin
|
||||||
|
if hp2.typ=ait_label then
|
||||||
|
tai_label(hp2).inserted:=true;
|
||||||
|
hp2:=tai(hp2.next);
|
||||||
|
end;
|
||||||
|
|
||||||
list.insertlistafter(curtai,curdata);
|
list.insertlistafter(curtai,curdata);
|
||||||
curtai:=hp;
|
curtai:=hp;
|
||||||
end
|
end
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user