Browse Source

* use high level interface wrappers for powerpc64 if pic is generated as the abi does not support branches between functions located in different tocs which might happen for inter-module branches

(cherry picked from commit 12f48c230bccd49f368be1e5a2855cb6c3a60c0f)
florian 3 years ago
parent
commit
084e3e7b9a
2 changed files with 62 additions and 46 deletions
  1. 53 42
      compiler/ncgvmt.pas
  2. 9 4
      compiler/ppcgen/hlcgppc.pas

+ 53 - 42
compiler/ncgvmt.pas

@@ -1222,14 +1222,22 @@ implementation
         tmps : string;
         pd   : TProcdef;
         ImplIntf : TImplementedInterface;
-{$ifdef cpuhighleveltarget}
         wrapperpd: tprocdef;
         wrapperinfo: pskpara_interface_wrapper;
-{$else}
-       tmplist: tasmlist;
-       oldfileposinfo: tfileposinfo;
-{$endif cpuhighleveltarget}
+        tmplist: tasmlist;
+        oldfileposinfo: tfileposinfo;
+        usehighlevelwrapper: Boolean;
       begin
+{$if defined(cpuhighleveltarget)}
+        usehighlevelwrapper:=true;
+{$else defined(cpuhighleveltarget)}
+{$if defined(powerpc64)}
+        if cs_create_pic in current_settings.moduleswitches then
+          usehighlevelwrapper:=true
+        else
+{$endif defined(powerpc64)}
+          usehighlevelwrapper:=false;
+{$endif defined(cpuhighleveltarget)}
         for i:=0 to _class.ImplementedInterfaces.count-1 do
           begin
             ImplIntf:=TImplementedInterface(_class.ImplementedInterfaces[i]);
@@ -1246,43 +1254,46 @@ implementation
                        not is_objectpascal_helper(tprocdef(pd).struct) then
                       tobjectdef(tprocdef(pd).struct).register_vmt_call(tprocdef(pd).extnumber);
                     tmps:=CreateWrapperName(_Class,ImplIntf,j,pd);
-{$ifdef cpuhighleveltarget}
-                    new(wrapperinfo);
-                    wrapperinfo^.pd:=pd;
-                    wrapperinfo^.offset:=ImplIntf.ioffset;
-                    { insert the wrapper procdef in the current unit's local
-                      symbol table, but set the owning "struct" to the current
-                      class (so self will have the correct type) }
-                    wrapperpd:=create_procdef_alias(pd,tmps,tmps,
-                      current_module.localsymtable,_class,
-                      tsk_interface_wrapper,wrapperinfo);
-                    include(wrapperpd.procoptions,po_noreturn);
-{$else cpuhighleveltarget}
-                    oldfileposinfo:=current_filepos;
-                    if pd.owner.iscurrentunit then
-                      current_filepos:=pd.fileinfo
-                    else
-                      begin
-                        current_filepos.moduleindex:=current_module.unit_index;
-                        current_filepos.fileindex:=1;
-                        current_filepos.line:=1;
-                        current_filepos.column:=1;
-                      end;
-                    { create wrapper code }
-                    tmplist:=tasmlist.create;
-                    new_section(tmplist,sec_code,tmps,target_info.alignment.procalign);
-                    tmplist.Concat(tai_function_name.create(tmps));
-                    hlcg.init_register_allocators;
-                    hlcg.g_intf_wrapper(tmplist,pd,tmps,ImplIntf.ioffset);
-                    hlcg.done_register_allocators;
-                    if ((cs_debuginfo in current_settings.moduleswitches) or
-                       (cs_use_lineinfo in current_settings.globalswitches)) and
-                       (target_dbg.id<>dbg_stabx) then
-                         current_debuginfo.insertlineinfo(tmplist);
-                    list.concatlist(tmplist);
-                    tmplist.Free;
-                    current_filepos:=oldfileposinfo;
-{$endif cpuhighleveltarget}
+
+                  if usehighlevelwrapper then
+                    begin
+                      new(wrapperinfo);
+                      wrapperinfo^.pd:=pd;
+                      wrapperinfo^.offset:=ImplIntf.ioffset;
+                      { insert the wrapper procdef in the current unit's local
+                        symbol table, but set the owning "struct" to the current
+                        class (so self will have the correct type) }
+                      wrapperpd:=create_procdef_alias(pd,tmps,tmps,
+                        current_module.localsymtable,_class,
+                        tsk_interface_wrapper,wrapperinfo);
+                    end
+                  else
+                    begin
+                      oldfileposinfo:=current_filepos;
+                      if pd.owner.iscurrentunit then
+                        current_filepos:=pd.fileinfo
+                      else
+                        begin
+                          current_filepos.moduleindex:=current_module.unit_index;
+                          current_filepos.fileindex:=1;
+                          current_filepos.line:=1;
+                          current_filepos.column:=1;
+                        end;
+                      { create wrapper code }
+                      tmplist:=tasmlist.create;
+                      new_section(tmplist,sec_code,tmps,target_info.alignment.procalign);
+                      tmplist.Concat(tai_function_name.create(tmps));
+                      hlcg.init_register_allocators;
+                      hlcg.g_intf_wrapper(tmplist,pd,tmps,ImplIntf.ioffset);
+                      hlcg.done_register_allocators;
+                      if ((cs_debuginfo in current_settings.moduleswitches) or
+                         (cs_use_lineinfo in current_settings.globalswitches)) and
+                         (target_dbg.id<>dbg_stabx) then
+                           current_debuginfo.insertlineinfo(tmplist);
+                      list.concatlist(tmplist);
+                      tmplist.Free;
+                      current_filepos:=oldfileposinfo;
+                    end;
                   end;
               end;
           end;

+ 9 - 4
compiler/ppcgen/hlcgppc.pas

@@ -183,11 +183,16 @@ implementation
           system_powerpc_darwin,
           system_powerpc64_darwin:
             list.concat(taicpu.op_sym(A_B,tcgppcgen(cg).get_darwin_call_stub(procdef.mangledname,false)));
-          else if use_dotted_functions then
-            {$note ts:todo add GOT change?? - think not needed :) }
-            list.concat(taicpu.op_sym(A_B,current_asmdata.RefAsmSymbol('.' + procdef.mangledname,AT_FUNCTION)))
           else
-            list.concat(taicpu.op_sym(A_B,current_asmdata.RefAsmSymbol(procdef.mangledname,AT_FUNCTION)))
+            begin
+              if use_dotted_functions then
+                {$note ts:todo add GOT change?? - think not needed :) }
+                list.concat(taicpu.op_sym(A_B,current_asmdata.RefAsmSymbol('.' + procdef.mangledname,AT_FUNCTION)))
+              else
+                list.concat(taicpu.op_sym(A_B,current_asmdata.RefAsmSymbol(procdef.mangledname,AT_FUNCTION)));
+              if (target_info.system in ([system_powerpc64_linux]+systems_aix)) then
+                list.concat(taicpu.op_none(A_NOP));
+            end;
         end;
       List.concat(Tai_symbol_end.Createname(labelname));
     end;