From 453bfcd37094c40c7baafdfe477eaa137a3eaa43 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sun, 23 Aug 2020 21:11:09 +0000 Subject: [PATCH 1/5] * emit the correct declaration for procdefs used to force a procname in LLVM o fixes lazarus startup on macOS/AArch64 when compiled with the LLVM cg git-svn-id: trunk@46675 - --- compiler/jvm/njvmcal.pas | 4 ++-- compiler/llvm/nllvmcal.pas | 26 +++++++++++++++++++++++ compiler/ncal.pas | 42 ++++++++------------------------------ compiler/ncgcal.pas | 13 ++++++++---- 4 files changed, 46 insertions(+), 39 deletions(-) diff --git a/compiler/jvm/njvmcal.pas b/compiler/jvm/njvmcal.pas index b76c0c8131..f1384b7dd8 100644 --- a/compiler/jvm/njvmcal.pas +++ b/compiler/jvm/njvmcal.pas @@ -600,10 +600,10 @@ implementation result:=inherited pass_1; if assigned(result) then 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) } if procdefinition.typ=procdef then - fforcedprocname:=tprocdef(procdefinition).mangledname + foverrideprocnamedef:=tprocdef(procdefinition) end; end; diff --git a/compiler/llvm/nllvmcal.pas b/compiler/llvm/nllvmcal.pas index d07813ed43..14a7e36aaa 100644 --- a/compiler/llvm/nllvmcal.pas +++ b/compiler/llvm/nllvmcal.pas @@ -39,6 +39,7 @@ interface function paraneedsinlinetemp(para: tcallparanode; const pushconstaddr, complexpara: boolean): boolean; override; function can_call_ref(var ref: treference): boolean; override; procedure pushparas; override; + procedure pass_generate_code; override; end; @@ -46,6 +47,7 @@ implementation uses verbose, + aasmbase,aasmdata,aasmllvm, symconst,symdef; {***************************************************************************** @@ -104,6 +106,30 @@ implementation 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 ccallnode:=tllvmcallnode; end. diff --git a/compiler/ncal.pas b/compiler/ncal.pas index 18538143d3..e29ded90ea 100644 --- a/compiler/ncal.pas +++ b/compiler/ncal.pas @@ -67,7 +67,7 @@ interface private { number of parameters passed from the source, this does not include the hidden parameters } paralength : smallint; - function getforcedprocname: TSymStr; + function getoverrideprocnamedef: tprocdef; inline; function is_simple_para_load(p:tnode; may_be_in_reg: boolean):boolean; procedure maybe_load_in_temp(var p:tnode); function gen_high_tree(var p:tnode;paradef:tdef):tnode; @@ -90,6 +90,7 @@ interface function pass1_normal:tnode; procedure register_created_object_types; function get_expect_loc: tcgloc; + protected function safe_call_self_node: 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 target for calling virtual methods, as this is name-based and not based on VMT entry locations } -{$ifdef symansistr} - fforcedprocname: TSymStr; -{$else symansistr} - fforcedprocname: pshortstring; -{$endif symansistr} - property forcedprocname: TSymStr read getforcedprocname; + foverrideprocnamedef: tprocdef; + property overrideprocnamedef: tprocdef read getoverrideprocnamedef; public { the symbol containing the definition of the procedure } { to call } @@ -1656,9 +1653,6 @@ implementation call_vmt_node.free; vmt_entry.free; spezcontext.free; -{$ifndef symansistr} - stringdispose(fforcedprocname); -{$endif symansistr} inherited destroy; end; @@ -1844,14 +1838,7 @@ implementation end else n.varargsparas:=nil; -{$ifdef symansistr} - n.fforcedprocname:=fforcedprocname; -{$else symansistr} - if assigned(fforcedprocname) then - n.fforcedprocname:=stringdup(fforcedprocname^) - else - n.fforcedprocname:=nil; -{$endif symansistr} + n.foverrideprocnamedef:=foverrideprocnamedef; result:=n; end; @@ -2084,16 +2071,9 @@ implementation end; - function tcallnode.getforcedprocname: TSymStr; + function tcallnode.getoverrideprocnamedef: tprocdef; inline; begin -{$ifdef symansistr} - result:=fforcedprocname; -{$else} - if assigned(fforcedprocname) then - result:=fforcedprocname^ - else - result:=''; -{$endif} + result:=foverrideprocnamedef; end; @@ -2670,7 +2650,7 @@ implementation vmt_def: trecorddef; begin if not assigned(right) and - (forcedprocname='') and + not assigned(overrideprocnamedef) and (po_virtualmethod in procdefinition.procoptions) and not is_objectpascal_helper(tprocdef(procdefinition).struct) and assigned(methodpointer) and @@ -2780,11 +2760,7 @@ implementation (srsym.typ<>procsym) or (tprocsym(srsym).ProcdefList.count<>1) then Message1(cg_f_unknown_compilerproc,'objc.'+msgsendname); -{$ifdef symansistr} - fforcedprocname:=tprocdef(tprocsym(srsym).ProcdefList[0]).mangledname; -{$else symansistr} - fforcedprocname:=stringdup(tprocdef(tprocsym(srsym).ProcdefList[0]).mangledname); -{$endif symansistr} + foverrideprocnamedef:=tprocdef(tprocsym(srsym).ProcdefList[0]); { B) Handle self } { 1) in case of sending a message to a superclass, self is a pointer to diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index 245e6561d5..43e80ed671 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -1067,10 +1067,10 @@ implementation end; {$endif vtentry} - name_to_call:=forcedprocname; { When methodpointer is typen we don't need (and can't) load 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 not is_objectpascal_helper(tprocdef(procdefinition).struct) and assigned(methodpointer) and @@ -1164,8 +1164,13 @@ implementation extra_interrupt_code; extra_call_code; retloc.resetiftemp; - if (name_to_call='') then - name_to_call:=tprocdef(procdefinition).mangledname; + if name_to_call='' then + 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 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 } From 3208929e176a2e6664f803ccb6db0fa03b22c246 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sun, 23 Aug 2020 21:11:13 +0000 Subject: [PATCH 2/5] * add Xcode-11.0 as LLVM target version versin git-svn-id: trunk@46676 - --- compiler/llvm/llvminfo.pas | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/llvm/llvminfo.pas b/compiler/llvm/llvminfo.pas index d9b76dc2cc..5e74d6df10 100644 --- a/compiler/llvm/llvminfo.pas +++ b/compiler/llvm/llvminfo.pas @@ -41,6 +41,7 @@ Type llvmver_7_0, llvmver_7_1, llvmver_8_0, + llvmver_xc_11, llvmver_9_0, llvmver_10_0 ); @@ -63,6 +64,7 @@ Const '7.0', '7.1', '8.0', + 'Xcode-11.0', '9.0', '10.0' ); @@ -75,6 +77,7 @@ Const { llvmver_7_0 } [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_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_10_0 } [llvmflag_memcpy_indiv_align,llvmflag_null_pointer_valid,llvmflag_constrained_fptrunc_fpext,llvmflag_constrained_fptoi_itofp] ); From beac71ed2484347e151e53231c6a127c3aaa9fbe Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Mon, 24 Aug 2020 20:21:10 +0000 Subject: [PATCH 3/5] * fix deleting the linksyms file after successful linking (mantis #37636) git-svn-id: trunk@46677 - --- compiler/systems/t_darwin.pas | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/systems/t_darwin.pas b/compiler/systems/t_darwin.pas index 61d9b90cd9..3de7f8a752 100644 --- a/compiler/systems/t_darwin.pas +++ b/compiler/systems/t_darwin.pas @@ -670,6 +670,7 @@ implementation extdbgcmdstr:=maybequoted(current_module.sharedlibfilename); end; + LinkSymsFileName:=''; if not texportlibunix(exportlib).exportedsymnames.empty then begin LinkSymsFileName:=UniqueName('linksyms')+'.fpc'; @@ -721,7 +722,7 @@ implementation DeleteFile(ordersymfile); DeleteFile(linkscript.fn); linkscript.free; - if not texportlibunix(exportlib).exportedsymnames.empty then + if LinkSymsFileName<>'' then DeleteFile(outputexedir+LinkSymsFileName); DeleteFile(outputexedir+LinkFilesFileName); end; From 03a0e6e82f4c6616fe6215e8a241b9aba7b00c23 Mon Sep 17 00:00:00 2001 From: florian Date: Mon, 24 Aug 2020 21:02:08 +0000 Subject: [PATCH 4/5] * Xtensa: fixed TCPUAddNode.second_cmpsmallset git-svn-id: trunk@46678 - --- compiler/xtensa/ncpuadd.pas | 42 ++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/compiler/xtensa/ncpuadd.pas b/compiler/xtensa/ncpuadd.pas index 57b94aa315..7163566a38 100644 --- a/compiler/xtensa/ncpuadd.pas +++ b/compiler/xtensa/ncpuadd.pas @@ -101,14 +101,19 @@ interface end; - procedure TCPUAddNode.second_cmpsmallset; + procedure TCPUAddNode.second_cmpsmallset; var tmpreg : tregister; - cond: TOpCmp; - instr: taicpu; truelab, falselab: TAsmLabel; begin 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(falselab); @@ -116,18 +121,27 @@ interface force_reg_left_right(false,false); case nodetype of - equaln: cond:=OC_EQ; - unequaln: cond:=OC_NE; - ltn: cond:=OC_LT; - lten: cond:=OC_LT; - gtn: cond:=OC_GT; - gten: cond:=OC_GTE; - else - internalerror(2020030801); + equaln: + begin + cg.a_cmp_reg_reg_label(current_asmdata.CurrAsmList,OS_INT,OC_EQ,left.location.register,right.location.register,location.truelabel); + cg.a_jmp_always(current_asmdata.CurrAsmList,location.falselabel); + end; + unequaln: + begin + 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; - - 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; From c73c98d995bb251f0d9b504eb638e6f2d7b5deb2 Mon Sep 17 00:00:00 2001 From: florian Date: Mon, 24 Aug 2020 21:02:09 +0000 Subject: [PATCH 5/5] * Xtensa FreeRTOS: unified haltproc git-svn-id: trunk@46679 - --- rtl/freertos/xtensa/esp32.pp | 15 ++++++++++----- rtl/freertos/xtensa/esp8266.pp | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/rtl/freertos/xtensa/esp32.pp b/rtl/freertos/xtensa/esp32.pp index 5217ee959d..3c60888a26 100644 --- a/rtl/freertos/xtensa/esp32.pp +++ b/rtl/freertos/xtensa/esp32.pp @@ -75,11 +75,16 @@ unit esp32; procedure _FPC_haltproc; public name '_haltproc';noreturn; begin - printpchar('_haltproc called, going to deep sleep, exit code: $'); - printdword(operatingsystem_result); - printpchar(#10); - while true do - esp_deep_sleep_start; + if operatingsystem_result <> 0 then + writeln('Runtime error ', operatingsystem_result); + + writeln('_haltproc called, exit code: ',operatingsystem_result); + 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; diff --git a/rtl/freertos/xtensa/esp8266.pp b/rtl/freertos/xtensa/esp8266.pp index 344603e3a7..2601c3fbe1 100644 --- a/rtl/freertos/xtensa/esp8266.pp +++ b/rtl/freertos/xtensa/esp8266.pp @@ -56,7 +56,7 @@ unit esp8266; if operatingsystem_result <> 0 then writeln('Runtime error ', operatingsystem_result); - writeln('_haltproc called...'); + writeln('_haltproc called, exit code: ',operatingsystem_result); flushOutput(TextRec(Output)); repeat // Allow other tasks to run