* synchronized with trunk

git-svn-id: branches/wasm@46681 -
This commit is contained in:
nickysn 2020-08-25 00:15:56 +00:00
commit 7bab5b6483
9 changed files with 90 additions and 60 deletions

View File

@ -600,10 +600,10 @@ implementation
result:=inherited pass_1; result:=inherited pass_1;
if assigned(result) then if assigned(result) then
exit; exit;
{ set fforcedprocname so that even virtual method calls will be { set foverrideprocnamedef so that even virtual method calls will be
name-based (instead of based on VMT entry numbers) } name-based (instead of based on VMT entry numbers) }
if procdefinition.typ=procdef then if procdefinition.typ=procdef then
fforcedprocname:=tprocdef(procdefinition).mangledname foverrideprocnamedef:=tprocdef(procdefinition)
end; end;
end; end;

View File

@ -41,6 +41,7 @@ Type
llvmver_7_0, llvmver_7_0,
llvmver_7_1, llvmver_7_1,
llvmver_8_0, llvmver_8_0,
llvmver_xc_11,
llvmver_9_0, llvmver_9_0,
llvmver_10_0 llvmver_10_0
); );
@ -63,6 +64,7 @@ Const
'7.0', '7.0',
'7.1', '7.1',
'8.0', '8.0',
'Xcode-11.0',
'9.0', '9.0',
'10.0' '10.0'
); );
@ -75,6 +77,7 @@ Const
{ llvmver_7_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid], { llvmver_7_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid],
{ llvmver_7_1 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid], { llvmver_7_1 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid],
{ llvmver_8_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid], { llvmver_8_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid],
{ llvmver_xc_11 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid],
{ llvmver_9_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext], { llvmver_9_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext],
{ llvmver_10_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp] { llvmver_10_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp]
); );

View File

@ -39,6 +39,7 @@ interface
function paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean; override; function paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean; override;
function can_call_ref(var ref: treference): boolean; override; function can_call_ref(var ref: treference): boolean; override;
procedure pushparas; override; procedure pushparas; override;
procedure pass_generate_code; override;
end; end;
@ -46,6 +47,7 @@ implementation
uses uses
verbose, verbose,
aasmbase,aasmdata,aasmllvm,
symconst,symdef; symconst,symdef;
{***************************************************************************** {*****************************************************************************
@ -104,6 +106,30 @@ implementation
end; end;
end; end;
procedure tllvmcallnode.pass_generate_code;
var
asmsym: tasmsymbol;
begin
inherited;
if assigned(overrideprocnamedef) and
not overrideprocnamedef.in_currentunit then
begin
{ insert an llvm declaration for this def if it's not defined in
the current unit, because otherwise we will define it in the
LLVM IR using the def for which this procdef's name is used
first, which may be something completely different from the original
def. LLVM can take the original def into account to load certain
registers, so if we use a wrong def this can result in wrong code
generation. }
asmsym:=current_asmdata.RefAsmSymbol(overrideprocnamedef.mangledname,AT_FUNCTION);
if not asmsym.declared then
begin
current_asmdata.AsmLists[al_imports].Concat(taillvmdecl.createdecl(asmsym,overrideprocnamedef,nil,sec_code,overrideprocnamedef.alignment));
end;
end;
end;
begin begin
ccallnode:=tllvmcallnode; ccallnode:=tllvmcallnode;
end. end.

View File

@ -67,7 +67,7 @@ interface
private private
{ number of parameters passed from the source, this does not include the hidden parameters } { number of parameters passed from the source, this does not include the hidden parameters }
paralength : smallint; paralength : smallint;
function getforcedprocname: TSymStr; function getoverrideprocnamedef: tprocdef; inline;
function is_simple_para_load(p:tnode; may_be_in_reg: boolean):boolean; function is_simple_para_load(p:tnode; may_be_in_reg: boolean):boolean;
procedure maybe_load_in_temp(var p:tnode); procedure maybe_load_in_temp(var p:tnode);
function gen_high_tree(var p:tnode;paradef:tdef):tnode; function gen_high_tree(var p:tnode;paradef:tdef):tnode;
@ -90,6 +90,7 @@ interface
function pass1_normal:tnode; function pass1_normal:tnode;
procedure register_created_object_types; procedure register_created_object_types;
function get_expect_loc: tcgloc; function get_expect_loc: tcgloc;
protected protected
function safe_call_self_node: tnode; function safe_call_self_node: tnode;
procedure load_in_temp(var p:tnode); procedure load_in_temp(var p:tnode);
@ -124,12 +125,8 @@ interface
to ppu, is set while processing the node). Also used on the JVM to ppu, is set while processing the node). Also used on the JVM
target for calling virtual methods, as this is name-based and not target for calling virtual methods, as this is name-based and not
based on VMT entry locations } based on VMT entry locations }
{$ifdef symansistr} foverrideprocnamedef: tprocdef;
fforcedprocname: TSymStr; property overrideprocnamedef: tprocdef read getoverrideprocnamedef;
{$else symansistr}
fforcedprocname: pshortstring;
{$endif symansistr}
property forcedprocname: TSymStr read getforcedprocname;
public public
{ the symbol containing the definition of the procedure } { the symbol containing the definition of the procedure }
{ to call } { to call }
@ -1656,9 +1653,6 @@ implementation
call_vmt_node.free; call_vmt_node.free;
vmt_entry.free; vmt_entry.free;
spezcontext.free; spezcontext.free;
{$ifndef symansistr}
stringdispose(fforcedprocname);
{$endif symansistr}
inherited destroy; inherited destroy;
end; end;
@ -1844,14 +1838,7 @@ implementation
end end
else else
n.varargsparas:=nil; n.varargsparas:=nil;
{$ifdef symansistr} n.foverrideprocnamedef:=foverrideprocnamedef;
n.fforcedprocname:=fforcedprocname;
{$else symansistr}
if assigned(fforcedprocname) then
n.fforcedprocname:=stringdup(fforcedprocname^)
else
n.fforcedprocname:=nil;
{$endif symansistr}
result:=n; result:=n;
end; end;
@ -2084,16 +2071,9 @@ implementation
end; end;
function tcallnode.getforcedprocname: TSymStr; function tcallnode.getoverrideprocnamedef: tprocdef; inline;
begin begin
{$ifdef symansistr} result:=foverrideprocnamedef;
result:=fforcedprocname;
{$else}
if assigned(fforcedprocname) then
result:=fforcedprocname^
else
result:='';
{$endif}
end; end;
@ -2670,7 +2650,7 @@ implementation
vmt_def: trecorddef; vmt_def: trecorddef;
begin begin
if not assigned(right) and if not assigned(right) and
(forcedprocname='') and not assigned(overrideprocnamedef) and
(po_virtualmethod in procdefinition.procoptions) and (po_virtualmethod in procdefinition.procoptions) and
not is_objectpascal_helper(tprocdef(procdefinition).struct) and not is_objectpascal_helper(tprocdef(procdefinition).struct) and
assigned(methodpointer) and assigned(methodpointer) and
@ -2780,11 +2760,7 @@ implementation
(srsym.typ<>procsym) or (srsym.typ<>procsym) or
(tprocsym(srsym).ProcdefList.count<>1) then (tprocsym(srsym).ProcdefList.count<>1) then
Message1(cg_f_unknown_compilerproc,'objc.'+msgsendname); Message1(cg_f_unknown_compilerproc,'objc.'+msgsendname);
{$ifdef symansistr} foverrideprocnamedef:=tprocdef(tprocsym(srsym).ProcdefList[0]);
fforcedprocname:=tprocdef(tprocsym(srsym).ProcdefList[0]).mangledname;
{$else symansistr}
fforcedprocname:=stringdup(tprocdef(tprocsym(srsym).ProcdefList[0]).mangledname);
{$endif symansistr}
{ B) Handle self } { B) Handle self }
{ 1) in case of sending a message to a superclass, self is a pointer to { 1) in case of sending a message to a superclass, self is a pointer to

View File

@ -1067,10 +1067,10 @@ implementation
end; end;
{$endif vtentry} {$endif vtentry}
name_to_call:=forcedprocname;
{ When methodpointer is typen we don't need (and can't) load { When methodpointer is typen we don't need (and can't) load
a pointer. We can directly call the correct procdef (PFV) } a pointer. We can directly call the correct procdef (PFV) }
if (name_to_call='') and name_to_call:='';
if not assigned(overrideprocnamedef) and
(po_virtualmethod in procdefinition.procoptions) and (po_virtualmethod in procdefinition.procoptions) and
not is_objectpascal_helper(tprocdef(procdefinition).struct) and not is_objectpascal_helper(tprocdef(procdefinition).struct) and
assigned(methodpointer) and assigned(methodpointer) and
@ -1164,8 +1164,13 @@ implementation
extra_interrupt_code; extra_interrupt_code;
extra_call_code; extra_call_code;
retloc.resetiftemp; retloc.resetiftemp;
if (name_to_call='') then if name_to_call='' then
name_to_call:=tprocdef(procdefinition).mangledname; begin
if not assigned(overrideprocnamedef) then
name_to_call:=tprocdef(procdefinition).mangledname
else
name_to_call:=overrideprocnamedef.mangledname;
end;
if cnf_inherited in callnodeflags then if cnf_inherited in callnodeflags then
retloc:=hlcg.a_call_name_inherited(current_asmdata.CurrAsmList,tprocdef(procdefinition),name_to_call,paralocs) retloc:=hlcg.a_call_name_inherited(current_asmdata.CurrAsmList,tprocdef(procdefinition),name_to_call,paralocs)
{ under certain conditions, a static call (i.e. without PIC) can be generated } { under certain conditions, a static call (i.e. without PIC) can be generated }

View File

@ -670,6 +670,7 @@ implementation
extdbgcmdstr:=maybequoted(current_module.sharedlibfilename); extdbgcmdstr:=maybequoted(current_module.sharedlibfilename);
end; end;
LinkSymsFileName:='';
if not texportlibunix(exportlib).exportedsymnames.empty then if not texportlibunix(exportlib).exportedsymnames.empty then
begin begin
LinkSymsFileName:=UniqueName('linksyms')+'.fpc'; LinkSymsFileName:=UniqueName('linksyms')+'.fpc';
@ -721,7 +722,7 @@ implementation
DeleteFile(ordersymfile); DeleteFile(ordersymfile);
DeleteFile(linkscript.fn); DeleteFile(linkscript.fn);
linkscript.free; linkscript.free;
if not texportlibunix(exportlib).exportedsymnames.empty then if LinkSymsFileName<>'' then
DeleteFile(outputexedir+LinkSymsFileName); DeleteFile(outputexedir+LinkSymsFileName);
DeleteFile(outputexedir+LinkFilesFileName); DeleteFile(outputexedir+LinkFilesFileName);
end; end;

View File

@ -101,14 +101,19 @@ interface
end; end;
procedure TCPUAddNode.second_cmpsmallset; procedure TCPUAddNode.second_cmpsmallset;
var var
tmpreg : tregister; tmpreg : tregister;
cond: TOpCmp;
instr: taicpu;
truelab, falselab: TAsmLabel; truelab, falselab: TAsmLabel;
begin begin
pass_left_right; pass_left_right;
if (not(nf_swapped in flags) and
(nodetype = lten)) or
((nf_swapped in flags) and
(nodetype = gten)) then
swapleftright;
current_asmdata.getjumplabel(truelab); current_asmdata.getjumplabel(truelab);
current_asmdata.getjumplabel(falselab); current_asmdata.getjumplabel(falselab);
@ -116,18 +121,27 @@ interface
force_reg_left_right(false,false); force_reg_left_right(false,false);
case nodetype of case nodetype of
equaln: cond:=OC_EQ; equaln:
unequaln: cond:=OC_NE; begin
ltn: cond:=OC_LT; cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_EQ,left.location.register,right.location.register,location.truelabel);
lten: cond:=OC_LT; cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);
gtn: cond:=OC_GT; end;
gten: cond:=OC_GTE; unequaln:
else begin
internalerror(2020030801); cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_NE,left.location.register,right.location.register,location.truelabel);
cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);
end;
lten,
gten:
begin
tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_AND,OS_32,left.location.register,right.location.register,tmpreg);
cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_EQ,tmpreg,right.location.register,location.truelabel);
cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);
end;
else
internalerror(2020082401);
end; end;
cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,cond,left.location.register,right.location.register,location.truelabel);
cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel);
end; end;

View File

@ -75,11 +75,16 @@ unit esp32;
procedure _FPC_haltproc; public name '_haltproc';noreturn; procedure _FPC_haltproc; public name '_haltproc';noreturn;
begin begin
printpchar('_haltproc called, going to deep sleep, exit code: $'); if operatingsystem_result <> 0 then
printdword(operatingsystem_result); writeln('Runtime error ', operatingsystem_result);
printpchar(#10);
while true do writeln('_haltproc called, exit code: ',operatingsystem_result);
esp_deep_sleep_start; flushOutput(TextRec(Output));
repeat
// Allow other tasks to run
// Do not enter deep sleep, can lead to problems with flashing
vTaskDelay(1000);
until false;
end; end;

View File

@ -56,7 +56,7 @@ unit esp8266;
if operatingsystem_result <> 0 then if operatingsystem_result <> 0 then
writeln('Runtime error ', operatingsystem_result); writeln('Runtime error ', operatingsystem_result);
writeln('_haltproc called...'); writeln('_haltproc called, exit code: ',operatingsystem_result);
flushOutput(TextRec(Output)); flushOutput(TextRec(Output));
repeat repeat
// Allow other tasks to run // Allow other tasks to run