Tested on hppa-unknown-linux-gnu and hppa64-hp-hpux11.11. Committed to trunk.
Dave --- hppa: Enable PA 2.0 symbolic operands on ELF32 targets The GNU ELF32 linker has been fixed and it can now handle PA 2.0 symbolic relocations. This only affects non-pic code generation. 2024-08-31 John David Anglin <dang...@gcc.gnu.org> gcc/ChangeLog: * config/pa/pa.cc (pa_emit_move_sequence): Remove symbolic memory work arounds for TARGET_ELF32. (pa_legitimate_address_p): Likewise. Allow symbolic operands. Adjust comment. * config/pa/pa.md: Replace reg_or_0_or_nonsymb_mem_operand with reg_or_0_or_mem_operand predicate in various unnamed move insns. * config/pa/predicates.md (floating_point_store_memory_operand): Update comment. Remove symbolic memory work arounds for TARGET_ELF32. (nonsymb_mem_operand): Rename to mem_operand. Allow symbolic memory operands. (reg_or_0_or_nonsymb_mem_operand): Rename to reg_or_0_or_mem_operand. Allow symbolic memory operands. diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc index 297ec3a6f69..631f18a0ef5 100644 --- a/gcc/config/pa/pa.cc +++ b/gcc/config/pa/pa.cc @@ -2043,8 +2043,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg) op1 = replace_equiv_address (op1, scratch_reg); } } - else if (((TARGET_ELF32 || !TARGET_PA_20) - && symbolic_memory_operand (op1, VOIDmode)) + else if ((!INT14_OK_STRICT && symbolic_memory_operand (op1, VOIDmode)) || IS_LO_SUM_DLT_ADDR_P (XEXP (op1, 0)) || IS_INDEX_ADDR_P (XEXP (op1, 0))) { @@ -2093,8 +2092,7 @@ pa_emit_move_sequence (rtx *operands, machine_mode mode, rtx scratch_reg) op0 = replace_equiv_address (op0, scratch_reg); } } - else if (((TARGET_ELF32 || !TARGET_PA_20) - && symbolic_memory_operand (op0, VOIDmode)) + else if ((!INT14_OK_STRICT && symbolic_memory_operand (op0, VOIDmode)) || IS_LO_SUM_DLT_ADDR_P (XEXP (op0, 0)) || IS_INDEX_ADDR_P (XEXP (op0, 0))) { @@ -11059,20 +11057,21 @@ pa_legitimate_address_p (machine_mode mode, rtx x, bool strict, code_helper) { y = XEXP (x, 1); - /* Needed for -fPIC */ + /* UNSPEC_DLTIND14R is always okay. Needed for -fPIC */ if (mode == Pmode && GET_CODE (y) == UNSPEC) return true; /* Before reload, we need support for 14-bit floating point loads and stores, and associated relocations. */ - if ((TARGET_ELF32 || !INT14_OK_STRICT) + if (!INT14_OK_STRICT && !reload_completed && mode != QImode && mode != HImode) return false; - if (CONSTANT_P (y)) + if (CONSTANT_P (y) + || (!flag_pic && symbolic_operand (y, mode))) return true; } return false; diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md index 9e410f43052..1e781efb66b 100644 --- a/gcc/config/pa/pa.md +++ b/gcc/config/pa/pa.md @@ -3866,7 +3866,7 @@ (define_insn "" [(set (match_operand:DF 0 "move_dest_operand" "=f,*r,T,?o,?Q,f,*r,*r,?*r,?f") - (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" + (match_operand:DF 1 "reg_or_0_or_mem_operand" "fG,*rG,f,*r,*r,RT,o,RQ,f,*r"))] "(register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode)) @@ -4040,7 +4040,7 @@ (define_insn "" [(set (match_operand:DF 0 "move_dest_operand" "=r,?o,?Q,r,r") - (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand" + (match_operand:DF 1 "reg_or_0_or_mem_operand" "rG,r,r,o,RQ"))] "(register_operand (operands[0], DFmode) || reg_or_0_operand (operands[1], DFmode)) @@ -4440,7 +4440,7 @@ (define_insn "" [(set (match_operand:SF 0 "move_dest_operand" "=f,!*r,f,*r,T,Q,?*r,?f") - (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" + (match_operand:SF 1 "reg_or_0_or_mem_operand" "fG,!*rG,RT,RQ,f,*rG,f,*r"))] "(register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode)) @@ -4462,7 +4462,7 @@ (define_insn "" [(set (match_operand:SF 0 "move_dest_operand" "=f,!*r,f,*r,T,Q") - (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" + (match_operand:SF 1 "reg_or_0_or_mem_operand" "fG,!*rG,RT,RQ,f,*rG"))] "(register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode)) @@ -4482,7 +4482,7 @@ (define_insn "" [(set (match_operand:SF 0 "move_dest_operand" "=!*r,*r,Q") - (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" + (match_operand:SF 1 "reg_or_0_or_mem_operand" "!*rG,RQ,*rG"))] "(register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode)) @@ -4615,7 +4615,7 @@ (define_insn "" [(set (match_operand:SF 0 "move_dest_operand" "=r,r,Q") - (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand" + (match_operand:SF 1 "reg_or_0_or_mem_operand" "rG,RQ,rG"))] "(register_operand (operands[0], SFmode) || reg_or_0_operand (operands[1], SFmode)) diff --git a/gcc/config/pa/predicates.md b/gcc/config/pa/predicates.md index 50dffa1138c..0c6e41be31f 100644 --- a/gcc/config/pa/predicates.md +++ b/gcc/config/pa/predicates.md @@ -335,12 +335,13 @@ ;; 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 for -;; PA 2.0 when TARGET_ELF32 is not true. We accept reloading pseudos -;; and other memory; operands. +;; PA 2.0. 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. +;; NOTE: The GNU ELF32 linker clobbered the least significant bit of +;; the target floating-point register in PA 2.0 floating-point loads +;; and stores with long displacements in ld versions prior to 2.42. +;; The global pointer also was not double-word aligned. This broke +;; various DPREL relocations. (define_predicate "floating_point_store_memory_operand" (match_code "reg,mem") @@ -366,8 +367,7 @@ return false; return ((reload_in_progress || memory_address_p (mode, XEXP (op, 0))) - && !((TARGET_ELF32 || !TARGET_PA_20) - && symbolic_memory_operand (op, VOIDmode)) + && (INT14_OK_STRICT || !symbolic_memory_operand (op, VOIDmode)) && !IS_LO_SUM_DLT_ADDR_P (XEXP (op, 0)) && !IS_INDEX_ADDR_P (XEXP (op, 0))); }) @@ -467,9 +467,9 @@ return memory_address_p (mode, XEXP (op, 0)); }) -;; True iff OP is not a symbolic memory operand. +;; True iff OP is a valid memory operand. -(define_predicate "nonsymb_mem_operand" +(define_predicate "mem_operand" (match_code "subreg,mem") { if (GET_CODE (op) == SUBREG) @@ -488,8 +488,7 @@ && REG_P (XEXP (XEXP (op, 0), 1))) return false; - return (!symbolic_memory_operand (op, mode) - && memory_address_p (mode, XEXP (op, 0))); + return (memory_address_p (mode, XEXP (op, 0))); }) ;; True iff OP is anything other than a hard register. @@ -576,11 +575,11 @@ (ior (match_operand 0 "register_operand") (match_operand 0 "const_0_operand"))) -;; True iff OP is either a register, zero, or a non-symbolic memory operand. +;; True iff OP is either a register, zero, or a memory operand. -(define_predicate "reg_or_0_or_nonsymb_mem_operand" +(define_predicate "reg_or_0_or_mem_operand" (ior (match_operand 0 "reg_or_0_operand") - (match_operand 0 "nonsymb_mem_operand"))) + (match_operand 0 "mem_operand"))) ;; Accept REG and any CONST_INT that can be moved in one instruction ;; into a general register.
signature.asc
Description: PGP signature