mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-15 21:09:27 +02:00
+ tcgexitnode,tcgbreaknode,tcgcontinuenode: added possibility to generate specialized code for leaving unwind-protected regions.
git-svn-id: trunk@19636 -
This commit is contained in:
parent
c12a4989d0
commit
8c9ad67682
@ -525,6 +525,9 @@ unit cgobj;
|
|||||||
procedure g_maybe_got_init(list: TAsmList); virtual;
|
procedure g_maybe_got_init(list: TAsmList); virtual;
|
||||||
{ allocallcpuregisters, a_call_name, deallocallcpuregisters sequence }
|
{ allocallcpuregisters, a_call_name, deallocallcpuregisters sequence }
|
||||||
procedure g_call(list: TAsmList; const s: string);
|
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
|
protected
|
||||||
procedure get_subsetref_load_info(const sref: tsubsetreference; out loadsize: tcgsize; out extra_load: boolean);
|
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;
|
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);
|
deallocallcpuregisters(list);
|
||||||
end;
|
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);
|
procedure tcg.a_loadmm_reg_reg(list: TAsmList; fromsize, tosize: tcgsize; reg1, reg2: tregister; shuffle: pmmshuffle);
|
||||||
begin
|
begin
|
||||||
internalerror(200807231);
|
internalerror(200807231);
|
||||||
|
@ -839,8 +839,10 @@ implementation
|
|||||||
include(flowcontrol,fc_exit);
|
include(flowcontrol,fc_exit);
|
||||||
if assigned(left) then
|
if assigned(left) then
|
||||||
secondpass(left);
|
secondpass(left);
|
||||||
|
if (fc_unwind in flowcontrol) then
|
||||||
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel);
|
cg.g_local_unwind(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel)
|
||||||
|
else
|
||||||
|
cg.a_jmp_always(current_asmdata.CurrAsmList,current_procinfo.CurrExitLabel);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
@ -858,7 +860,10 @@ implementation
|
|||||||
{$ifdef OLDREGVARS}
|
{$ifdef OLDREGVARS}
|
||||||
load_all_regvars(current_asmdata.CurrAsmList);
|
load_all_regvars(current_asmdata.CurrAsmList);
|
||||||
{$endif OLDREGVARS}
|
{$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
|
end
|
||||||
else
|
else
|
||||||
CGMessage(cg_e_break_not_allowed);
|
CGMessage(cg_e_break_not_allowed);
|
||||||
@ -879,7 +884,10 @@ implementation
|
|||||||
{$ifdef OLDREGVARS}
|
{$ifdef OLDREGVARS}
|
||||||
load_all_regvars(current_asmdata.CurrAsmList);
|
load_all_regvars(current_asmdata.CurrAsmList);
|
||||||
{$endif OLDREGVARS}
|
{$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
|
end
|
||||||
else
|
else
|
||||||
CGMessage(cg_e_continue_not_allowed);
|
CGMessage(cg_e_continue_not_allowed);
|
||||||
|
@ -35,6 +35,8 @@ uses
|
|||||||
fc_continue,
|
fc_continue,
|
||||||
fc_inflowcontrol,
|
fc_inflowcontrol,
|
||||||
fc_gotolabel,
|
fc_gotolabel,
|
||||||
|
{ in try block of try..finally }
|
||||||
|
fc_unwind,
|
||||||
{ the left side of an expression is already handled, so we are
|
{ the left side of an expression is already handled, so we are
|
||||||
not allowed to do ssl }
|
not allowed to do ssl }
|
||||||
fc_lefthandled);
|
fc_lefthandled);
|
||||||
@ -199,7 +201,7 @@ implementation
|
|||||||
if (not codegenerror) then
|
if (not codegenerror) then
|
||||||
begin
|
begin
|
||||||
if (p.location.loc<>p.expectloc) then
|
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
|
if (p.location.loc=LOC_INVALID) then
|
||||||
Comment(V_Warning,'Location not set in secondpass: '+nodetype2str[p.nodetype]);
|
Comment(V_Warning,'Location not set in secondpass: '+nodetype2str[p.nodetype]);
|
||||||
end;
|
end;
|
||||||
|
Loading…
Reference in New Issue
Block a user