trunk/gcc121/vcs_diff_compiler.patch results

File details

./trunk/gcc121/vcs_diff_compiler.patch 2026-03-07-01:54

Used binaries

   

Binaries version

> uname -a
Linux cfarm121 6.18.5+deb14-powerpc64 #1 SMP PREEMPT Debian 6.18.5-1 (2026-01-16) ppc64 GNU/Linux

Full file content

 
diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas
index 16c4a23e6a..6e58455553 100644
--- a/compiler/cgobj.pas
+++ b/compiler/cgobj.pas
@@ -415,6 +415,11 @@        tcg = class
              @param(size Number of bytes to allocate)
           }
           procedure g_stackpointer_alloc(list : TAsmList;size : longint);virtual;
+          {# Emits instruction to load TOC into ABI specific register
+
+             @param(sym: assembler symbol used for computation of specific relocation)
+          }
+          procedure g_load_toc(list: TAsmList; sym : TAsmSymbol); virtual;
           {# Emits instruction for allocating the locals in entry
              code of a routine. This is one of the first
              routine called in @var(genentrycode).
@@ -2884,6 +2889,11 @@ implementation
       end;
 
 
+    procedure tcg.g_load_toc(list: TAsmList;sym : TAsmSymbol);
+      begin
+      end;
+
+
     procedure tcg.g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: tcgint);
       var
         hsym : tsym;
diff --git a/compiler/hlcgobj.pas b/compiler/hlcgobj.pas
index df399ab0d0..13478a6073 100644
--- a/compiler/hlcgobj.pas
+++ b/compiler/hlcgobj.pas
@@ -4250,6 +4250,7 @@ implementation
           sym:=current_asmdata.DefineAsmSymbol(wrappername,AB_PRIVATE_EXTERN,AT_FUNCTION,procdef);
           list.concat(Tai_symbol.Create(sym,0));
         end;
+      cg.g_load_toc(list,sym);
       a_jmp_external_name(list,externalname);
       list.concat(Tai_symbol_end.Create(sym));
     end;
diff --git a/compiler/powerpc64/cgcpu.pas b/compiler/powerpc64/cgcpu.pas
index d3c663badd..a3890db769 100644
--- a/compiler/powerpc64/cgcpu.pas
+++ b/compiler/powerpc64/cgcpu.pas
@@ -79,6 +79,7 @@   tcgppc = class(tcgppcgen)
     procedure g_adjust_self_value(list:TAsmList;procdef: tprocdef;ioffset: aint);override;
 
     procedure g_profilecode(list: TAsmList); override;
+    procedure g_load_toc(list: TAsmList; sym : TAsmSymbol); override;
     procedure g_proc_entry(list: TAsmList; localsize: longint; nostackframe:
       boolean); override;
     procedure g_proc_exit(list: TAsmList; parasize: longint; nostackframe:
@@ -1095,6 +1096,38 @@ procedure tcgppc.g_profilecode(list: TAsmList);
   current_procinfo.procdef.paras.ForEachCall(TObjectListCallback(@profilecode_restorepara), list);
 end;
 
+{ Default does nothing }
+procedure tcgppc.g_load_toc(list: TAsmList; sym: TAsmSymbol);
+var
+  href: treference;
+  lab: tasmlabel;
+begin
+  { In ELFv2 the function is required to initialise the TOC register itself
+    if necessary. Additionally, it has to mark the end of this TOC
+    initialisation code with a .localfunc directive, which will be used as
+    local entry code by the linker (when it knows the TOC value is the same
+    for the caller and callee). It must load the TOC in a PIC-way, which it
+    can do easily because R12 is guaranteed to hold the address of this function
+    on entry. }
+  if (target_info.abi=abi_powerpc_elfv2) then
+    begin
+      current_asmdata.getlabel(lab,alt_addr);
+      if assigned(current_procinfo) then
+        begin
+          getcpuregister(list,NR_R12);
+          getcpuregister(list,NR_R2);
+        end;
+      cg.a_label(list,lab);
+      reference_reset_symbol(href,current_asmdata.RefAsmSymbol('.TOC.',AT_DATA),0,sizeof(PInt),[]);
+      href.relsymbol:=lab;
+      href.refaddr:=addr_higha;
+      list.concat(taicpu.op_reg_reg_ref(a_addis,NR_R2,NR_R12,href));
+      href.refaddr:=addr_low;
+      list.concat(taicpu.op_reg_reg_ref(a_addi,NR_R2,NR_R2,href));
+      list.concat(tai_symbolpair.create(spk_localentry,sym.name,sym.name));
+    end;
+end;
+
 { Generates the entry code of a procedure/function.
 
  This procedure may be called before, as well as after g_return_from_proc
@@ -1175,33 +1208,11 @@ procedure tcgppc.g_proc_entry(list: TAsmList; localsize: longint;
 
 var
   href: treference;
-  lab: tasmlabel;
-  procmangledname: TSymStr;
+  sym: TAsmSymbol;
 begin
-  { In ELFv2 the function is required to initialise the TOC register itself
-    if necessary. Additionally, it has to mark the end of this TOC
-    initialisation code with a .localfunc directive, which will be used as
-    local entry code by the linker (when it knows the TOC value is the same
-    for the caller and callee). It must load the TOC in a PIC-way, which it
-    can do easily because R12 is guaranteed to hold the address of this function
-    on entry. }
-  if (target_info.abi=abi_powerpc_elfv2) and
-     (pi_needs_got in current_procinfo.flags) and
-     not nostackframe then
-    begin
-      current_asmdata.getlabel(lab,alt_addr);
-      getcpuregister(list,NR_R12);
-      getcpuregister(list,NR_R2);
-      cg.a_label(list,lab);
-      reference_reset_symbol(href,current_asmdata.RefAsmSymbol('.TOC.',AT_DATA),0,sizeof(PInt),[]);
-      href.relsymbol:=lab;
-      href.refaddr:=addr_higha;
-      list.concat(taicpu.op_reg_reg_ref(a_addis,NR_R2,NR_R12,href));
-      href.refaddr:=addr_low;
-      list.concat(taicpu.op_reg_reg_ref(a_addi,NR_R2,NR_R2,href));
-      procmangledname:=current_procinfo.procdef.mangledname;
-      list.concat(tai_symbolpair.create(spk_localentry,procmangledname,procmangledname));
-    end;
+  sym:=current_asmdata.RefAsmSymbol(current_procinfo.procdef.mangledname,AT_FUNCTION);
+  if (pi_needs_got in current_procinfo.flags) and not nostackframe then
+    g_load_toc(list,sym);
   calcFirstUsedFPR(firstregfpu, fprcount);
   calcFirstUsedGPR(firstreggpr, gprcount);
 
diff --git a/compiler/ppcgen/cgppc.pas b/compiler/ppcgen/cgppc.pas
index c09c961b76..d2777898a9 100644
--- a/compiler/ppcgen/cgppc.pas
+++ b/compiler/ppcgen/cgppc.pas
@@ -67,6 +67,10 @@       tcgppcgen = class(tcg)
         procedure g_load_check_simple(list: TAsmList; const ref: treference; size: aint);
         procedure g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister); override;
 
+        function get_rtoc_offset: longint;
+
+        function load_got_symbol(list : TAsmList; const symbol : string; const flags: tindsymflags) : tregister;
+
         { returns true if the offset of the given reference can not be  }
         { represented by a 16 bit immediate as required by some PowerPC }
         { instructions                                                  }
@@ -89,11 +93,7 @@       tcgppcgen = class(tcg)
         procedure a_jmp(list: TAsmList; op: tasmop;
                         c: tasmcondflag; crval: longint; l: tasmlabel);
 
-        function get_rtoc_offset: longint;
-
         function save_lr_in_prologue: boolean;
-
-        function load_got_symbol(list : TAsmList; const symbol : string; const flags: tindsymflags) : tregister;
      end;
 
 
diff --git a/compiler/ppcgen/hlcgppc.pas b/compiler/ppcgen/hlcgppc.pas
index 1e7c84a6ec..3622099198 100644
--- a/compiler/ppcgen/hlcgppc.pas
+++ b/compiler/ppcgen/hlcgppc.pas
@@ -30,7 +30,7 @@ interface
 uses
   globtype,globals,
   aasmdata,
-  symtype,symdef,
+  symtype,symdef,parabase,
   cgbase,cgutils,hlcgobj,hlcg2ll;
 
 type
@@ -39,6 +39,7 @@   thlcgppcgen = class(thlcg2ll)
     procedure a_load_subsetref_regs_noindex(list: TAsmList; subsetsize: tdef; loadbitsize: byte; const sref: tsubsetreference; valuereg, extra_value_reg: tregister); override;
    public
     procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
+    function a_call_name(list: TAsmList; pd: tprocdef; const s: TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara; override;
     procedure a_jmp_external_name(list: TAsmList; const externalname: TSymStr); override;
     procedure gen_load_para_value(list: TAsmList); override;
   end;
@@ -197,6 +198,31 @@ implementation
       List.concat(Tai_symbol_end.Createname(labelname));
     end;
 
+  function thlcgppcgen.a_call_name(list: TAsmList; pd: tprocdef; const s: TSymStr; const paras: array of pcgpara; forceresdef: tdef; weak: boolean): tcgpara;
+    var
+      href : treference;
+      tmpreg : tregister;
+      sym : TAsmSymbol;
+    begin
+      { For external functions, we need to use R12 on ELFv2 ABI }
+      if (target_info.abi = abi_powerpc_elfv2) and ([po_external,po_has_importname]*pd.procoptions<>[]) then
+        begin
+          include(current_procinfo.flags,pi_needs_got);
+          sym:=current_asmdata.refasmsymbol(pd.mangledname,AT_FUNCTION);
+          tmpreg := tcgppcgen(cg).load_got_symbol(list, sym.name, asmsym2indsymflags(sym));
+          cg.a_load_reg_reg(list,OS_ADDR,OS_ADDR,tmpreg,NR_R12);
+          { move actual function pointer to CTR register }
+          list.concat(taicpu.op_reg(A_MTCTR, NR_R12));
+          { call function }
+          list.concat(taicpu.op_none(A_BCTR));
+          { we need to load the old RTOC from stackframe it might have changed }
+          reference_reset_base(href, voidpointertype, NR_STACK_POINTER_REG, tcgppcgen(cg).get_rtoc_offset, ctempposinvalid, sizeof(pint), []);
+          cg.a_load_ref_reg(list, OS_ADDR, OS_ADDR, href, NR_RTOC);
+          result:=get_call_result_cgpara(pd,forceresdef);
+        end
+      else
+        result:=inherited a_call_name(list,pd,s,paras,forceresdef,weak);
+    end;
 
   procedure thlcgppcgen.a_jmp_external_name(list: TAsmList; const externalname: TSymStr);
     var