This patch updates the predicates for prefixed addressing. This patch deletes a predicate that I had originally added, but the code no longer uses.
This patch changes how local symbols for pc-relative addressing are marked. Previously, we had used a machine dependent bit in the SYMBOL_REF node. Now, I use the SYMBOL_REF_LOCAL_P bit. This patch adds a predicate for handling external addresses that will be used for future patches. I have done bootstrap builds and make check. There were no regressions. Can I check this patch into the trunk? 2019-06-27 Michael Meissner <meiss...@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. Index: gcc/config/rs6000/predicates.md =================================================================== --- gcc/config/rs6000/predicates.md (revision 272766) +++ gcc/config/rs6000/predicates.md (working copy) @@ -1645,21 +1645,57 @@ (define_predicate "pcrel_address" op = op0; } - return LABEL_REF_P (op) || SYMBOL_REF_PCREL_P (op); + if (LABEL_REF_P (op)) + return true; + + return (TARGET_CMODEL == CMODEL_MEDIUM && SYMBOL_REF_P (op) + && SYMBOL_REF_LOCAL_P (op)); }) -;; Return 1 if op is a prefixed memory operand +;; Return true if the operand is an external symbol whose address can be loaded +;; into a register either via PADDI (if the symbol is in the main program) or +;; PLD GOT address (if the symbol is defined in a shared library). + +(define_predicate "pcrel_external_address" + (match_code "symbol_ref,const") +{ + if (!TARGET_PCREL || TARGET_CMODEL != CMODEL_MEDIUM) + return false; + + /* Discard any CONST's. */ + 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))) + return false; + + op = op0; + } + + return (SYMBOL_REF_P (op) && !SYMBOL_REF_LOCAL_P (op)); +}) + +;; 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: gcc/config/rs6000/rs6000.h =================================================================== --- gcc/config/rs6000/rs6000.h (revision 272766) +++ gcc/config/rs6000/rs6000.h (working copy) @@ -2550,10 +2550,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) -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797