aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/config/rs6000/predicates.md55
-rw-r--r--gcc/config/rs6000/rs6000.h7
3 files changed, 55 insertions, 16 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 21d2977..80790ed 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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.
diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md
index 8ca9829..45fa40a 100644
--- a/gcc/config/rs6000/predicates.md
+++ b/gcc/config/rs6000/predicates.md
@@ -1626,10 +1626,9 @@
(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);
@@ -1645,21 +1644,59 @@
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.
diff --git a/gcc/config/rs6000/rs6000.h b/gcc/config/rs6000/rs6000.h
index 0a2c0bc..9193d9e 100644
--- a/gcc/config/rs6000/rs6000.h
+++ b/gcc/config/rs6000/rs6000.h
@@ -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)