Update pc-relative support.
authorMichael Meissner <meissner@linux.ibm.com>
Fri, 28 Jun 2019 20:19:54 +0000 (20:19 +0000)
committerMichael Meissner <meissner@gcc.gnu.org>
Fri, 28 Jun 2019 20:19:54 +0000 (20:19 +0000)
2019-06-28  Michael Meissner  <meissner@linux.ibm.com>

* config/rs6000/predicates.md (pcrel_address):  Use
SYMBOL_REF_LOCAL_P to determine if a label is local.
(pcrel_external_address): New predicate.
(non_prefixed_mem_operand): Delete, predicate not used.
* config/rs6000/rs6000.h (SYMBOL_FLAG_PCREL_P): Delete, we now use
SYMBOL_REF_LOCAL_P to determine if we can use pc-relative
addressing.
(SYMBOL_REF_PCREL_P): Likewise.

From-SVN: r272792

gcc/ChangeLog
gcc/config/rs6000/predicates.md
gcc/config/rs6000/rs6000.h

index 21d2977736c92032b425d5f087796b7a4ce9b176..80790ed76f54c2d0ab63aef48e52010e2e7ab5c7 100644 (file)
@@ -1,5 +1,14 @@
 2019-06-28   Michael Meissner  <meissner@linux.ibm.com>
 
+       * config/rs6000/predicates.md (pcrel_address):  Use
+       SYMBOL_REF_LOCAL_P to determine if a label is local.
+       (pcrel_external_address): New predicate.
+       (non_prefixed_mem_operand): Delete, predicate not used.
+       * config/rs6000/rs6000.h (SYMBOL_FLAG_PCREL_P): Delete, we now use
+       SYMBOL_REF_LOCAL_P to determine if we can use pc-relative
+       addressing.
+       (SYMBOL_REF_PCREL_P): Likewise.
+
        PR target/91009
        * config/rs6000/rs6000.md (floatsi<mode>2_lfiwax): Add non-VSX
        alternative.
index 8ca98299950424b54dca539d10118ea2615bbbb8..45fa40a404509fb919a3e38e659c21b80390596e 100644 (file)
 (define_predicate "pcrel_address"
   (match_code "label_ref,symbol_ref,const")
 {
-  if (!TARGET_PCREL)
+  if (!rs6000_pcrel_p (cfun))
     return false;
 
-  /* Discard any CONST's.  */
   if (GET_CODE (op) == CONST)
     op = XEXP (op, 0);
 
       op = op0;
     }
 
-  return LABEL_REF_P (op) || SYMBOL_REF_PCREL_P (op);
+  if (LABEL_REF_P (op))
+    return true;
+
+  return (SYMBOL_REF_P (op) && SYMBOL_REF_LOCAL_P (op));
+})
+
+;; Return true if the operand is an external symbol whose address can be loaded
+;; into a register using:
+;;     PLA reg,label@pcrel@got
+;;
+;; The linker will either optimize this to either a PADDI if the label is
+;; defined locally in another module or a PLD of the address if the label is
+;; defined in another module.
+
+(define_predicate "pcrel_external_address"
+  (match_code "symbol_ref,const")
+{
+  if (!rs6000_pcrel_p (cfun))
+    return false;
+
+  if (GET_CODE (op) == CONST)
+    op = XEXP (op, 0);
+
+  /* Validate offset.  */
+  if (GET_CODE (op) == PLUS)
+    {
+      rtx op0 = XEXP (op, 0);
+      rtx op1 = XEXP (op, 1);
+
+      if (!CONST_INT_P (op1) || !SIGNED_34BIT_OFFSET_P (INTVAL (op1), 0))
+       return false;
+
+      op = op0;
+    }
+
+  return (SYMBOL_REF_P (op) && !SYMBOL_REF_LOCAL_P (op));
 })
 
-;; Return 1 if op is a prefixed memory operand
+;; Return 1 if op is a prefixed memory operand.
 (define_predicate "prefixed_mem_operand"
   (match_code "mem")
 {
   return rs6000_prefixed_address (XEXP (op, 0), GET_MODE (op));
 })
 
-;; Return 1 if op is a memory operand that is not a prefixed memory
-;; operand.
-(define_predicate "non_prefixed_mem_operand"
-  (and (match_operand 0 "memory_operand")
-       (not (match_operand 0 "prefixed_mem_operand"))))
+;; Return 1 if op is a memory operand to an external variable when we
+;; support pc-relative addressing and the PCREL_OPT relocation to
+;; optimize references to it.
+(define_predicate "pcrel_external_mem_operand"
+  (match_code "mem")
+{
+  return pcrel_external_address (XEXP (op, 0), Pmode);
+})
 
 ;; Match the first insn (addis) in fusing the combination of addis and loads to
 ;; GPR registers on power8.
index 0a2c0bc341f02b2b312a7a543ed59c725b3a3b44..9193d9e8a54a8590d8e179ef7b1591e01b47d32b 100644 (file)
@@ -2539,10 +2539,3 @@ typedef struct GTY(()) machine_function
   IN_RANGE (VALUE,                                                     \
            -(HOST_WIDE_INT_1 << 33),                                   \
            (HOST_WIDE_INT_1 << 33) - 1 - (EXTRA))
-
-/* Flag to mark SYMBOL_REF objects to say they are local addresses and are used
-   in pc-relative addresses.  */
-#define SYMBOL_FLAG_PCREL      SYMBOL_FLAG_MACH_DEP
-
-#define SYMBOL_REF_PCREL_P(X)                                          \
-  (SYMBOL_REF_P (X) && SYMBOL_REF_FLAGS (X) & SYMBOL_FLAG_PCREL)