mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-11 09:26:15 +02:00
* ensure that data pools are not inserted right after add/tbb/tbh-based
jumptable dispatches git-svn-id: trunk@30027 -
This commit is contained in:
parent
1ecf8dcfa1
commit
b2427d04ed
@ -898,6 +898,20 @@ implementation
|
|||||||
limit:=254;
|
limit:=254;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function is_case_dispatch(hp: taicpu): boolean;
|
||||||
|
begin
|
||||||
|
result:=
|
||||||
|
((taicpu(hp).opcode in [A_ADD,A_LDR]) and
|
||||||
|
not(GenerateThumbCode or GenerateThumb2Code) and
|
||||||
|
(taicpu(hp).oper[0]^.typ=top_reg) and
|
||||||
|
(taicpu(hp).oper[0]^.reg=NR_PC)) or
|
||||||
|
((taicpu(hp).opcode=A_MOV) and (GenerateThumbCode) and
|
||||||
|
(taicpu(hp).oper[0]^.typ=top_reg) and
|
||||||
|
(taicpu(hp).oper[0]^.reg=NR_PC)) or
|
||||||
|
(taicpu(hp).opcode=A_TBH) or
|
||||||
|
(taicpu(hp).opcode=A_TBB);
|
||||||
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
curinspos,
|
curinspos,
|
||||||
penalty,
|
penalty,
|
||||||
@ -906,7 +920,8 @@ implementation
|
|||||||
currentsize,
|
currentsize,
|
||||||
extradataoffset,
|
extradataoffset,
|
||||||
curop : longint;
|
curop : longint;
|
||||||
curtai : tai;
|
curtai,
|
||||||
|
inserttai : tai;
|
||||||
ai_label : tai_label;
|
ai_label : tai_label;
|
||||||
curdatatai,hp,hp2 : tai;
|
curdatatai,hp,hp2 : tai;
|
||||||
curdata : TAsmList;
|
curdata : TAsmList;
|
||||||
@ -1066,15 +1081,11 @@ implementation
|
|||||||
case taicpu(hp).opcode of
|
case taicpu(hp).opcode of
|
||||||
A_MOV,
|
A_MOV,
|
||||||
A_LDR,
|
A_LDR,
|
||||||
A_ADD:
|
A_ADD,
|
||||||
|
A_TBH,
|
||||||
|
A_TBB:
|
||||||
{ approximation if we hit a case jump table }
|
{ approximation if we hit a case jump table }
|
||||||
if ((taicpu(hp).opcode in [A_ADD,A_LDR]) and not(GenerateThumbCode or GenerateThumb2Code) and
|
if is_case_dispatch(taicpu(hp)) then
|
||||||
(taicpu(hp).oper[0]^.typ=top_reg) and
|
|
||||||
(taicpu(hp).oper[0]^.reg=NR_PC)) or
|
|
||||||
((taicpu(hp).opcode=A_MOV) and (GenerateThumbCode) and
|
|
||||||
(taicpu(hp).oper[0]^.typ=top_reg) and
|
|
||||||
(taicpu(hp).oper[0]^.reg=NR_PC))
|
|
||||||
then
|
|
||||||
begin
|
begin
|
||||||
penalty:=multiplier;
|
penalty:=multiplier;
|
||||||
hp:=tai(hp.next);
|
hp:=tai(hp.next);
|
||||||
@ -1168,12 +1179,34 @@ implementation
|
|||||||
else
|
else
|
||||||
limit:=1016;
|
limit:=1016;
|
||||||
|
|
||||||
|
{ if this is an add/tbh/tbb-based jumptable, go back to the
|
||||||
|
previous instruction, because inserting data between the
|
||||||
|
dispatch instruction and the table would mess up the
|
||||||
|
addresses }
|
||||||
|
inserttai:=curtai;
|
||||||
|
if is_case_dispatch(taicpu(inserttai)) and
|
||||||
|
((taicpu(inserttai).opcode=A_ADD) or
|
||||||
|
(taicpu(inserttai).opcode=A_TBH) or
|
||||||
|
(taicpu(inserttai).opcode=A_TBB)) then
|
||||||
|
begin
|
||||||
|
repeat
|
||||||
|
inserttai:=tai(inserttai.previous);
|
||||||
|
until inserttai.typ=ait_instruction;
|
||||||
|
{ if it's an add-based jump table, then also skip the
|
||||||
|
pc-relative load }
|
||||||
|
if taicpu(curtai).opcode=A_ADD then
|
||||||
|
repeat
|
||||||
|
inserttai:=tai(inserttai.previous);
|
||||||
|
until inserttai.typ=ait_instruction;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
|
||||||
{ on arm thumb, insert the data always after all labels etc. following an instruction so it
|
{ on arm thumb, insert the data always after all labels etc. following an instruction so it
|
||||||
is prevent that a bxx yyy; bl xxx; yyyy: sequence gets separated ( we never insert on arm thumb after
|
is prevent that a bxx yyy; bl xxx; yyyy: sequence gets separated ( we never insert on arm thumb after
|
||||||
bxx) and the distance of bxx gets too long }
|
bxx) and the distance of bxx gets too long }
|
||||||
if GenerateThumbCode then
|
if GenerateThumbCode then
|
||||||
while assigned(tai(curtai.Next)) and (tai(curtai.Next).typ in SkipInstr+[ait_label]) do
|
while assigned(tai(inserttai.Next)) and (tai(inserttai.Next).typ in SkipInstr+[ait_label]) do
|
||||||
curtai:=tai(curtai.next);
|
inserttai:=tai(inserttai.next);
|
||||||
|
|
||||||
doinsert:=false;
|
doinsert:=false;
|
||||||
current_asmdata.getjumplabel(l);
|
current_asmdata.getjumplabel(l);
|
||||||
@ -1200,7 +1233,7 @@ implementation
|
|||||||
is then equal curdata.last.previous) we could over see one
|
is then equal curdata.last.previous) we could over see one
|
||||||
instruction }
|
instruction }
|
||||||
hp:=tai(curdata.Last);
|
hp:=tai(curdata.Last);
|
||||||
list.insertlistafter(curtai,curdata);
|
list.insertlistafter(inserttai,curdata);
|
||||||
curtai:=hp;
|
curtai:=hp;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user