mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-14 09:09:19 +02:00
* synchronized with trunk
git-svn-id: branches/wasm@46681 -
This commit is contained in:
commit
7bab5b6483
@ -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;
|
||||||
|
|
||||||
|
@ -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]
|
||||||
);
|
);
|
||||||
|
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -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 }
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user