* 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:
Jonas Maebe 2015-02-27 20:52:12 +00:00
parent 1ecf8dcfa1
commit b2427d04ed

View File

@ -898,6 +898,20 @@ implementation
limit:=254;
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
curinspos,
penalty,
@ -906,7 +920,8 @@ implementation
currentsize,
extradataoffset,
curop : longint;
curtai : tai;
curtai,
inserttai : tai;
ai_label : tai_label;
curdatatai,hp,hp2 : tai;
curdata : TAsmList;
@ -1066,15 +1081,11 @@ implementation
case taicpu(hp).opcode of
A_MOV,
A_LDR,
A_ADD:
A_ADD,
A_TBH,
A_TBB:
{ approximation if we hit a case jump table }
if ((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))
then
if is_case_dispatch(taicpu(hp)) then
begin
penalty:=multiplier;
hp:=tai(hp.next);
@ -1168,12 +1179,34 @@ implementation
else
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
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 }
if GenerateThumbCode then
while assigned(tai(curtai.Next)) and (tai(curtai.Next).typ in SkipInstr+[ait_label]) do
curtai:=tai(curtai.next);
while assigned(tai(inserttai.Next)) and (tai(inserttai.Next).typ in SkipInstr+[ait_label]) do
inserttai:=tai(inserttai.next);
doinsert:=false;
current_asmdata.getjumplabel(l);
@ -1200,7 +1233,7 @@ implementation
is then equal curdata.last.previous) we could over see one
instruction }
hp:=tai(curdata.Last);
list.insertlistafter(curtai,curdata);
list.insertlistafter(inserttai,curdata);
curtai:=hp;
end
else