+ tcgexitnode,tcgbreaknode,tcgcontinuenode: added possibility to generate specialized code for leaving unwind-protected regions.

git-svn-id: trunk@19636 -
This commit is contained in:
sergei 2011-11-14 22:47:37 +00:00
parent c12a4989d0
commit 8c9ad67682
3 changed files with 23 additions and 5 deletions

View File

@ -525,6 +525,9 @@ unit cgobj;
procedure g_maybe_got_init(list: TAsmList); virtual;
{ allocallcpuregisters, a_call_name, deallocallcpuregisters sequence }
procedure g_call(list: TAsmList; const s: string);
{ Generate code to exit an unwind-protected region. The default implementation
produces a simple jump to destination label. }
procedure g_local_unwind(list: TAsmList; l: TAsmLabel);virtual;
protected
procedure get_subsetref_load_info(const sref: tsubsetreference; out loadsize: tcgsize; out extra_load: boolean);
procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tcgsize; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); virtual;
@ -4278,6 +4281,11 @@ implementation
deallocallcpuregisters(list);
end;
procedure tcg.g_local_unwind(list: TAsmList; l: TAsmLabel);
begin
a_jmp_always(list,l);
end;
procedure tcg.a_loadmm_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister; shuffle: pmmshuffle);
begin
internalerror(200807231);

View File

@ -839,8 +839,10 @@ implementation
include(flowcontrol,fc_exit);
if assigned(left) then
secondpass(left);
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel);
if (fc_unwind in flowcontrol) then
cg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel)
else
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel);
end;
@ -858,7 +860,10 @@ implementation
{$ifdef OLDREGVARS}
load_all_regvars(current_asmdata.CurrAsmList);
{$endif OLDREGVARS}
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel)
if (fc_unwind in flowcontrol) then
cg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel)
else
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrBreakLabel)
end
else
CGMessage(cg_e_break_not_allowed);
@ -879,7 +884,10 @@ implementation
{$ifdef OLDREGVARS}
load_all_regvars(current_asmdata.CurrAsmList);
{$endif OLDREGVARS}
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel)
if (fc_unwind in flowcontrol) then
cg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel)
else
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrContinueLabel)
end
else
CGMessage(cg_e_continue_not_allowed);

View File

@ -35,6 +35,8 @@ uses
fc_continue,
fc_inflowcontrol,
fc_gotolabel,
{ in try block of try..finally }
fc_unwind,
{ the left side of an expression is already handled, so we are
not allowed to do ssl }
fc_lefthandled);
@ -199,7 +201,7 @@ implementation
if (not codegenerror) then
begin
if (p.location.loc<>p.expectloc) then
Comment(V_Warning,'Location not equal to expectloc: '+nodetype2str[p.nodetype]);
Comment(V_Warning,'Location ('+tcgloc2str[p.location.loc]+') not equal to expectloc ('+tcgloc2str[p.expectloc]+'): '+nodetype2str[p.nodetype]);
if (p.location.loc=LOC_INVALID) then
Comment(V_Warning,'Location not set in secondpass: '+nodetype2str[p.nodetype]);
end;