Tested on hppa-unknown-linux-gnu.  Committed to trunk.

Dave
---

hppa: Improve handling of REG+D addresses when generating PA 2.0 code

In looking at PR 112415, it became clear that improvements could be
made in the handling of loads and stores using REG+D addresses.  A
change in 2002 conflated two issues:

1) We can't generate insns with 14-bit displacements before reload
completes when generating PA 1.x code since floating-point loads and
stores only support 5-bit offsets in PA 1.x.

2) The GNU ELF 32-bit linker lacks relocation support for PA 2.0
floating point instructions with 14-bit displacements.  These
relocations affect instructions with symbolic references.

The result of the change was to block creation of PA 2.0 instructions
with 14-bit REG_D displacements for SImode, DImode, SFmode and DFmode
on the GNU linux target before reload.  This was unnecessary as these
instructions don't need relocation.

This change revise the INT14_OK_STRICT define to allow creation
of instructions with 14-bit REG+D addresses before reload when
generating PA 2.0 code.

2024-03-17  John David Anglin  <dang...@gcc.gnu.org>

gcc/ChangeLog:

        PR rtl-optimization/112415
        * config/pa/pa.cc (pa_emit_move_sequence): Revise condition
        for symbolic memory operands.
        (pa_legitimate_address_p): Revise LO_SUM condition.
        * config/pa/pa.h (INT14_OK_STRICT): Revise define.  Move
        comment about GNU linker to predicates.md.
        * config/pa/predicates.md (floating_point_store_memory_operand):
        Revise condition for symbolic memory operands.  Update
        comment.

diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc
index 129289f8e62..d7666103de8 100644
--- a/gcc/config/pa/pa.cc
+++ b/gcc/config/pa/pa.cc
@@ -2039,7 +2039,8 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, 
rtx scratch_reg)
              op1 = replace_equiv_address (op1, scratch_reg);
            }
        }
-      else if ((!INT14_OK_STRICT && symbolic_memory_operand (op1, VOIDmode))
+      else if (((TARGET_ELF32 || !TARGET_PA_20)
+               && symbolic_memory_operand (op1, VOIDmode))
               || IS_LO_SUM_DLT_ADDR_P (XEXP (op1, 0))
               || IS_INDEX_ADDR_P (XEXP (op1, 0)))
        {
@@ -2088,7 +2089,8 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, 
rtx scratch_reg)
              op0 = replace_equiv_address (op0, scratch_reg);
            }
        }
-      else if ((!INT14_OK_STRICT && symbolic_memory_operand (op0, VOIDmode))
+      else if (((TARGET_ELF32 || !TARGET_PA_20)
+               && symbolic_memory_operand (op0, VOIDmode))
               || IS_LO_SUM_DLT_ADDR_P (XEXP (op0, 0))
               || IS_INDEX_ADDR_P (XEXP (op0, 0)))
        {
@@ -11032,18 +11040,22 @@ pa_legitimate_address_p (machine_mode mode, rtx x, 
bool strict, code_helper)
          && (strict ? STRICT_REG_OK_FOR_BASE_P (y)
                     : REG_OK_FOR_BASE_P (y)))
        {
+         y = XEXP (x, 1);
+
          /* Needed for -fPIC */
          if (mode == Pmode
-             && GET_CODE (XEXP (x, 1)) == UNSPEC)
+             && GET_CODE (y) == UNSPEC)
            return true;
 
-         if (!INT14_OK_STRICT
-             && (strict || !(reload_in_progress || reload_completed))
+         /* Before reload, we need support for 14-bit floating
+            point loads and stores, and associated relocations.  */
+         if ((TARGET_ELF32 || !INT14_OK_STRICT)
+             && !reload_completed
              && mode != QImode
              && mode != HImode)
            return false;
 
-         if (CONSTANT_P (XEXP (x, 1)))
+         if (CONSTANT_P (y))
            return true;
        }
       return false;
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
index 7abaeae269e..403f16c5cb5 100644
--- a/gcc/config/pa/pa.h
+++ b/gcc/config/pa/pa.h
@@ -828,19 +828,8 @@ extern int may_call_alloca;
 
 /* Nonzero if 14-bit offsets can be used for all loads and stores.
    This is not possible when generating PA 1.x code as floating point
-   accesses only support 5-bit offsets.  Note that we do not forbid
-   the use of 14-bit offsets prior to reload.  Instead, we use secondary
-   reloads to fix REG+D memory addresses for floating-point accesses.
-
-   FIXME: the GNU ELF linker clobbers the LSB of the FP register number
-   in PA 2.0 floating-point insns with long displacements.  This is
-   because R_PARISC_DPREL14WR and other relocations like it are not
-   yet supported by GNU ld.  For now, we reject long displacements
-   on this target.  */
-
-#define INT14_OK_STRICT \
-  (TARGET_SOFT_FLOAT                                                   \
-   || (TARGET_PA_20 && !TARGET_ELF32 && !TARGET_ELF64))
+   accesses only support 5-bit offsets.  */
+#define INT14_OK_STRICT (TARGET_SOFT_FLOAT || TARGET_PA_20)
 
 /* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
    and check its validity for a certain class.
diff --git a/gcc/config/pa/predicates.md b/gcc/config/pa/predicates.md
index 3bd3a7c212f..50dffa1138c 100644
--- a/gcc/config/pa/predicates.md
+++ b/gcc/config/pa/predicates.md
@@ -331,12 +331,16 @@
          && !IS_INDEX_ADDR_P (XEXP (op, 0)));
 })
 
-;; True iff the operand OP can be used as the destination operand of
-;; a floating point store.  This also implies the operand could be used as
+;; True iff the operand OP can be used as the destination operand of a
+;; floating point store.  This also implies the operand could be used as
 ;; the source operand of a floating point load.  LO_SUM DLT and indexed
-;; memory operands are not allowed.  Symbolic operands are accepted if
-;; INT14_OK_STRICT is true.  We accept reloading pseudos and other memory
-;; operands.
+;; memory operands are not allowed.  Symbolic operands are accepted for
+;; PA 2.0 when TARGET_ELF32 is not true.  We accept reloading pseudos
+;; and other memory; operands.
+
+;; FIXME: The GNU ELF32 linker clobbers the LSB of the FP register number
+;; in PA 2.0 {fldw,fstw} insns with long displacements.  This is because
+;; R_PARISC_DPREL14WR and other relocations like it are not supported.
 
 (define_predicate "floating_point_store_memory_operand"
   (match_code "reg,mem")
@@ -362,7 +366,8 @@
     return false;
 
   return ((reload_in_progress || memory_address_p (mode, XEXP (op, 0)))
-         && (INT14_OK_STRICT || !symbolic_memory_operand (op, VOIDmode))
+         && !((TARGET_ELF32 || !TARGET_PA_20)
+              && symbolic_memory_operand (op, VOIDmode))
          && !IS_LO_SUM_DLT_ADDR_P (XEXP (op, 0))
          && !IS_INDEX_ADDR_P (XEXP (op, 0)));
 })

Attachment: signature.asc
Description: PGP signature

Reply via email to