diff options
author | John David Anglin <danglin@gcc.gnu.org> | 2024-08-31 12:20:14 -0400 |
---|---|---|
committer | John David Anglin <danglin@gcc.gnu.org> | 2024-08-31 12:20:14 -0400 |
commit | b7e9f361088055c49cee8225a6cc0f4288458211 (patch) | |
tree | 6b7448221c33a7ef03a108fc383267950066a275 /gcc | |
parent | ceda727dafba6e05b510b5f8f4ccacfb507dc023 (diff) | |
download | gcc-b7e9f361088055c49cee8225a6cc0f4288458211.zip gcc-b7e9f361088055c49cee8225a6cc0f4288458211.tar.gz gcc-b7e9f361088055c49cee8225a6cc0f4288458211.tar.bz2 |
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 <danglin@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.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/config/pa/pa.cc | 13 | ||||
-rw-r--r-- | gcc/config/pa/pa.md | 12 | ||||
-rw-r--r-- | gcc/config/pa/predicates.md | 27 |
3 files changed, 25 insertions, 27 deletions
diff --git a/gcc/config/pa/pa.cc b/gcc/config/pa/pa.cc index 297ec3a..631f18a 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 9e410f4..1e781ef 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 50dffa1..0c6e41b 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. |