I was asked to split V4 patch #4.2 into smaller chuncks.  This patch is one of
8 patches that were broken out from 4.2.  Another patch from 4.2 to use
SIGNED_16BIT_OFFSET_EXTRA_P has already been committed.

This patch adds some new predicates that will be used in future patches.  It
also updates the lwa_operand predicate used in extendsidi2 to know that if we
support prefixed memory addresses, we can use odd offsets.

2019-10-03  Michael Meissner  <meiss...@linux.ibm.com>

        * config/rs6000/predicates.md (lwa_operand): Add support for
        prefixed instructions.
        (non_prefixed_memory): New predicate.
        (non_pcrel_memory): New predicate.
        (reg_or_non_pcrel_memory): New predicate.

Index: gcc/config/rs6000/predicates.md
===================================================================
--- gcc/config/rs6000/predicates.md     (revision 276534)
+++ gcc/config/rs6000/predicates.md     (working copy)
@@ -932,6 +932,13 @@ (define_predicate "lwa_operand"
     return false;
 
   addr = XEXP (inner, 0);
+
+  /* The LWA instruction uses the DS-form format where the bottom two bits of
+     the offset must be 0.  The prefixed PLWA does not have this
+     restriction.  */
+  if (address_is_prefixed (addr, DImode, NON_PREFIXED_DS))
+    return true;
+
   if (GET_CODE (addr) == PRE_INC
       || GET_CODE (addr) == PRE_DEC
       || (GET_CODE (addr) == PRE_MODIFY
@@ -1807,3 +1814,30 @@ (define_predicate "pcrel_external_addres
 (define_predicate "pcrel_local_or_external_address"
   (ior (match_operand 0 "pcrel_local_address")
        (match_operand 0 "pcrel_external_address")))
+
+;; Return 1 if op is a memory operand that is not prefixed.
+(define_predicate "non_prefixed_memory"
+  (match_code "mem")
+{
+  if (!memory_operand (op, mode))
+    return false;
+
+  return !address_is_prefixed (XEXP (op, 0), mode, NON_PREFIXED_DEFAULT);
+})
+
+(define_predicate "non_pcrel_memory"
+  (match_code "mem")
+{
+  if (!memory_operand (op, mode))
+    return false;
+
+  return !pcrel_local_or_external_address (XEXP (op, 0), Pmode);
+})
+
+;; Return 1 if op is either a register operand or a memory operand that does
+;; not use a PC-relative address.
+(define_predicate "reg_or_non_pcrel_memory"
+  (match_code "reg,subreg,mem")
+{
+  return (gpc_reg_operand (op, mode) || non_pcrel_memory (op, mode));
+})

-- 
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

Reply via email to