mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-13 11:39:24 +02:00
+ added label resolution via state machine
This commit is contained in:
parent
fc9719f5f9
commit
f9ecc12e5b
@ -63,7 +63,7 @@ implementation
|
|||||||
uses
|
uses
|
||||||
systems,verbose,globals,tgcpu,cgexcept,
|
systems,verbose,globals,tgcpu,cgexcept,
|
||||||
tgobj,paramgr,symconst,symdef,symtable,symcpu,cgutils,pass_2,parabase,
|
tgobj,paramgr,symconst,symdef,symtable,symcpu,cgutils,pass_2,parabase,
|
||||||
fmodule,hlcgobj,hlcgcpu,defutil;
|
fmodule,hlcgobj,hlcgcpu,defutil,itcpugas;
|
||||||
|
|
||||||
{*****************************************************************************
|
{*****************************************************************************
|
||||||
twasmexceptionstatehandler_noexceptions
|
twasmexceptionstatehandler_noexceptions
|
||||||
@ -670,6 +670,104 @@ implementation
|
|||||||
result:=resolve_labels_pass2(asmlist);
|
result:=resolve_labels_pass2(asmlist);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure resolve_labels_via_state_machine(asmlist: TAsmList);
|
||||||
|
var
|
||||||
|
blocks: TFPHashObjectList;
|
||||||
|
curr_block, tmplist: TAsmList;
|
||||||
|
hp, hpnext: tai;
|
||||||
|
block_nr, machine_state, target_block_index: Integer;
|
||||||
|
state_machine_loop_start_label, state_machine_exit: TAsmLabel;
|
||||||
|
begin
|
||||||
|
blocks:=TFPHashObjectList.Create;
|
||||||
|
curr_block:=TAsmList.Create;
|
||||||
|
blocks.Add('.start',curr_block);
|
||||||
|
repeat
|
||||||
|
hp:=tai(asmlist.First);
|
||||||
|
if assigned(hp) then
|
||||||
|
begin
|
||||||
|
asmlist.Remove(hp);
|
||||||
|
if hp.typ=ait_label then
|
||||||
|
begin
|
||||||
|
curr_block:=TAsmList.Create;
|
||||||
|
blocks.Add(tai_label(hp).labsym.Name,curr_block);
|
||||||
|
end;
|
||||||
|
curr_block.Concat(hp);
|
||||||
|
end;
|
||||||
|
until not assigned(hp);
|
||||||
|
{ asmlist is now empty }
|
||||||
|
asmlist.Concat(tai_comment.Create(strpnew('labels resolved via state machine')));
|
||||||
|
machine_state:=AllocWasmLocal(wbt_i32);
|
||||||
|
asmlist.Concat(tai_comment.Create(strpnew('machine state is in local '+tostr(machine_state))));
|
||||||
|
asmlist.Concat(taicpu.op_const(a_i32_const,0));
|
||||||
|
asmlist.Concat(taicpu.op_const(a_local_set,machine_state));
|
||||||
|
asmlist.Concat(taicpu.op_none(a_block));
|
||||||
|
asmlist.Concat(taicpu.op_none(a_loop));
|
||||||
|
current_asmdata.getjumplabel(state_machine_loop_start_label);
|
||||||
|
asmlist.concat(tai_label.create(state_machine_loop_start_label));
|
||||||
|
current_asmdata.getjumplabel(state_machine_exit);
|
||||||
|
for block_nr:=0 to blocks.Count-1 do
|
||||||
|
asmlist.Concat(taicpu.op_none(a_block));
|
||||||
|
for block_nr:=0 to blocks.Count-1 do
|
||||||
|
begin
|
||||||
|
{ TODO: this sequence can be replaced with a single br_table instruction }
|
||||||
|
asmlist.Concat(taicpu.op_const(a_local_get,machine_state));
|
||||||
|
asmlist.Concat(taicpu.op_const(a_i32_const,block_nr));
|
||||||
|
asmlist.Concat(taicpu.op_none(a_i32_eq));
|
||||||
|
asmlist.Concat(taicpu.op_const(a_br_if,blocks.Count-block_nr-1));
|
||||||
|
end;
|
||||||
|
asmlist.Concat(taicpu.op_none(a_unreachable));
|
||||||
|
tmplist:=TAsmList.Create;
|
||||||
|
for block_nr:=0 to blocks.Count-1 do
|
||||||
|
begin
|
||||||
|
asmlist.Concat(taicpu.op_none(a_end_block));
|
||||||
|
asmlist.Concat(tai_comment.Create(strpnew('block '+tostr(block_nr)+' for label '+blocks.NameOfIndex(block_nr))));
|
||||||
|
curr_block:=TAsmList(blocks[block_nr]);
|
||||||
|
hp:=tai(curr_block.First);
|
||||||
|
while assigned(hp) do
|
||||||
|
begin
|
||||||
|
hpnext:=tai(hp.next);
|
||||||
|
if (hp.typ=ait_instruction) and (taicpu(hp).opcode in [a_br,a_br_if]) and
|
||||||
|
(taicpu(hp).ops=1) and
|
||||||
|
(taicpu(hp).oper[0]^.typ=top_ref) and
|
||||||
|
assigned(taicpu(hp).oper[0]^.ref^.symbol) then
|
||||||
|
begin
|
||||||
|
target_block_index:=blocks.FindIndexOf(taicpu(hp).oper[0]^.ref^.symbol.Name);
|
||||||
|
curr_block.InsertBefore(tai_comment.Create(strpnew(
|
||||||
|
'branch '+gas_op2str[taicpu(hp).opcode]+
|
||||||
|
' '+taicpu(hp).oper[0]^.ref^.symbol.Name+
|
||||||
|
' target_block_index='+tostr(target_block_index))),hp);
|
||||||
|
if target_block_index<>-1 then
|
||||||
|
begin
|
||||||
|
tmplist.Clear;
|
||||||
|
if taicpu(hp).opcode=a_br_if then
|
||||||
|
tmplist.Concat(taicpu.op_none(a_if));
|
||||||
|
tmplist.Concat(taicpu.op_const(a_i32_const,target_block_index));
|
||||||
|
tmplist.Concat(taicpu.op_const(a_local_set,machine_state));
|
||||||
|
tmplist.Concat(taicpu.op_sym(a_br,state_machine_loop_start_label));
|
||||||
|
if taicpu(hp).opcode=a_br_if then
|
||||||
|
tmplist.Concat(taicpu.op_none(a_end_if));
|
||||||
|
curr_block.insertListAfter(hp,tmplist);
|
||||||
|
curr_block.Remove(hp);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
hp:=hpnext;
|
||||||
|
end;
|
||||||
|
if block_nr<(blocks.Count-1) then
|
||||||
|
begin
|
||||||
|
curr_block.Concat(taicpu.op_const(a_i32_const,block_nr+1));
|
||||||
|
curr_block.Concat(taicpu.op_const(a_local_set,machine_state));
|
||||||
|
curr_block.Concat(taicpu.op_sym(a_br,state_machine_loop_start_label));
|
||||||
|
end
|
||||||
|
else
|
||||||
|
curr_block.Concat(taicpu.op_sym(a_br,state_machine_exit));
|
||||||
|
asmlist.concatList(curr_block);
|
||||||
|
end;
|
||||||
|
tmplist.Free;
|
||||||
|
asmlist.Concat(taicpu.op_none(a_end_loop));
|
||||||
|
asmlist.Concat(taicpu.op_none(a_end_block));
|
||||||
|
asmlist.concat(tai_label.create(state_machine_exit));
|
||||||
|
end;
|
||||||
|
|
||||||
procedure resolve_labels_complex(var asmlist: TAsmList);
|
procedure resolve_labels_complex(var asmlist: TAsmList);
|
||||||
var
|
var
|
||||||
l2: TAsmList;
|
l2: TAsmList;
|
||||||
@ -689,6 +787,7 @@ implementation
|
|||||||
asmlist:=l2;
|
asmlist:=l2;
|
||||||
|
|
||||||
map_structured_asmlist(asmlist,@StripBlockInstructions);
|
map_structured_asmlist(asmlist,@StripBlockInstructions);
|
||||||
|
resolve_labels_via_state_machine(asmlist);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function prepare_locals: TAsmList;
|
function prepare_locals: TAsmList;
|
||||||
|
Loading…
Reference in New Issue
Block a user