[committed,hppa] Fix loading of PIC labels

Message ID d812a651-ad14-4d5b-cc35-225797ebcb99@bell.net
State New
Headers show
Series
  • [committed,hppa] Fix loading of PIC labels
Related show

Commit Message

John David Anglin Feb. 14, 2018, 9:28 p.m.
The attached patch fixes the compilation of pr81687-2.c in the libgomp 
testsuite.

Typically, when labels are "close" on hppa, it is best to load the 
address of the label in
PIC code using a pc-relative sequence.  The code generated for 
pr81687-2.c is an example
where the label and the referencing code are in different spaces.  A 
pc-relative sequence
doesn't work in this case, and we are forced to load the address from 
the linkage table.

Tested on hppa64-hp-hpux11.11, hppa2.0w-hp-hpux11.11 and 
hppa-unknown-linux-gnu
with no observed regressions.

Committed to trunk.

Dave

-- 
John David Anglin  dave.anglin@bell.net
2018-02-14  John David Anglin  <danglin@gcc.gnu.org>

	PR target/83984
	* config/pa/pa.md: Load address of PIC label using the linkage table
	if the label is nonlocal.

Patch

Index: config/pa/pa.md
===================================================================
--- config/pa/pa.md	(revision 257505)
+++ config/pa/pa.md	(working copy)
@@ -2536,24 +2536,40 @@ 
 
   xoperands[0] = operands[0];
   xoperands[1] = operands[1];
-  xoperands[2] = gen_label_rtx ();
 
-  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
-				     CODE_LABEL_NUMBER (xoperands[2]));
-  output_asm_insn (\"mfia %0\", xoperands);
+  if (GET_CODE (operands[1]) == LABEL_REF
+      && !LABEL_REF_NONLOCAL_P (operands[1]))
+    {
+      xoperands[2] = gen_label_rtx ();
+      (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
+					 CODE_LABEL_NUMBER (xoperands[2]));
+      output_asm_insn (\"mfia %0\", xoperands);
 
-  /* If we're trying to load the address of a label that happens to be
-     close, then we can use a shorter sequence.  */
-  if (GET_CODE (operands[1]) == LABEL_REF
-      && !LABEL_REF_NONLOCAL_P (operands[1])
-      && INSN_ADDRESSES_SET_P ()
-      && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
-	        - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
-    output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
+      /* If we're trying to load the address of a label that happens to be
+	 close, then we can use a shorter sequence.  */
+      if (INSN_ADDRESSES_SET_P ()
+	  && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
+		  - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
+	output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
+      else
+	{
+	  output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
+	  output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
+	}
+    }
   else
     {
-      output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
-      output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
+      /* Load using linkage table.  */
+      if (TARGET_64BIT)
+	{
+	  output_asm_insn (\"addil LT%%%1,%%r27\", xoperands);
+	  output_asm_insn (\"ldd RT%%%1(%0),%0\", xoperands);
+	}
+      else
+	{
+	  output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
+	  output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
+	}
     }
   return \"\";
 }"
@@ -2570,25 +2586,33 @@ 
 
   xoperands[0] = operands[0];
   xoperands[1] = operands[1];
-  xoperands[2] = gen_label_rtx ();
 
-  output_asm_insn (\"bl .+8,%0\", xoperands);
-  output_asm_insn (\"depi 0,31,2,%0\", xoperands);
-  (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
-				     CODE_LABEL_NUMBER (xoperands[2]));
+  if (GET_CODE (operands[1]) == LABEL_REF
+      && !LABEL_REF_NONLOCAL_P (operands[1]))
+    {
+      xoperands[2] = gen_label_rtx ();
+      output_asm_insn (\"bl .+8,%0\", xoperands);
+      output_asm_insn (\"depi 0,31,2,%0\", xoperands);
+      (*targetm.asm_out.internal_label) (asm_out_file, \"L\",
+					 CODE_LABEL_NUMBER (xoperands[2]));
 
-  /* If we're trying to load the address of a label that happens to be
-     close, then we can use a shorter sequence.  */
-  if (GET_CODE (operands[1]) == LABEL_REF
-      && !LABEL_REF_NONLOCAL_P (operands[1])
-      && INSN_ADDRESSES_SET_P ()
-      && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
-	        - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
-    output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
+      /* If we're trying to load the address of a label that happens to be
+	 close, then we can use a shorter sequence.  */
+      if (INSN_ADDRESSES_SET_P ()
+	  && abs (INSN_ADDRESSES (INSN_UID (XEXP (operands[1], 0)))
+		  - INSN_ADDRESSES (INSN_UID (insn))) < 8100)
+	output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
+      else
+	{
+	  output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
+	  output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
+	}
+    }
   else
     {
-      output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
-      output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
+      /* Load using linkage table.  */
+      output_asm_insn (\"addil LT%%%1,%%r19\", xoperands);
+      output_asm_insn (\"ldw RT%%%1(%0),%0\", xoperands);
     }
   return \"\";
 }"