aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Sawdey <acsawdey@linux.ibm.com>2020-05-29 16:19:10 -0500
committerAaron Sawdey <acsawdey@linux.ibm.com>2020-06-02 11:27:46 -0500
commit85bce484d37fdda9c7eadb9bdcdb1ded891462bb (patch)
tree5c3fb388953bf3016ad91e4ea9885e38a1dc95f0
parent34e5efa10a7b514238ed9a914b802898d2d8cb36 (diff)
downloadgcc-85bce484d37fdda9c7eadb9bdcdb1ded891462bb.zip
gcc-85bce484d37fdda9c7eadb9bdcdb1ded891462bb.tar.gz
gcc-85bce484d37fdda9c7eadb9bdcdb1ded891462bb.tar.bz2
Correctly identify stfs if prefixed
Because reg_to_non_prefixed() only looks at the register being used, it doesn't get the right answer for stfs, which leads to us not seeing that it has a PCREL symbol ref. This patch works around this by introducing a helper function that inspects the insn to see if it is in fact a stfs. Then if we use NON_PREFIXED_DEFAULT, address_to_insn_form() can see that it has the PCREL symbol ref. gcc/ChangeLog: PR target/95347 * config/rs6000/rs6000.c (prefixed_store_p): Add special case for stfs. (is_stfs_insn): New helper function.
-rw-r--r--gcc/config/rs6000/rs6000.c55
1 files changed, 54 insertions, 1 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index 8435bc1..ba9069e 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -24980,6 +24980,51 @@ address_to_insn_form (rtx addr,
return INSN_FORM_BAD;
}
+/* Helper function to see if we're potentially looking at stfs.
+ - PARALLEL containing a SET and a CLOBBER
+ - SET is from UNSPEC_SI_FROM_SF to MEM:SI
+ - CLOBBER is a V4SF
+ */
+
+static bool
+is_stfs_insn (rtx_insn *insn)
+{
+ rtx pattern = PATTERN (insn);
+ if (GET_CODE (pattern) != PARALLEL)
+ return false;
+
+ /* This should be a parallel with exactly one set and one clobber. */
+ if (XVECLEN (pattern, 0) != 2)
+ return false;
+
+ rtx set = XVECEXP (pattern, 0, 0);
+ if (GET_CODE (set) != SET)
+ return false;
+
+ rtx clobber = XVECEXP (pattern, 0, 1);
+ if (GET_CODE (clobber) != CLOBBER)
+ return false;
+
+ /* All we care is that the destination of the SET is a mem:SI,
+ the source should be an UNSPEC_SI_FROM_SF, and the clobber
+ should be a scratch:V4SF. */
+
+ rtx dest = SET_DEST (set);
+ rtx src = SET_SRC (set);
+ rtx scratch = SET_DEST (clobber);
+
+ if (GET_CODE (src) != UNSPEC || XINT (src, 1) != UNSPEC_SI_FROM_SF)
+ return false;
+
+ if (GET_CODE (dest) != MEM || GET_MODE (dest) != SImode)
+ return false;
+
+ if (GET_CODE (scratch) != SCRATCH || GET_MODE (scratch) != V4SFmode)
+ return false;
+
+ return true;
+}
+
/* Helper function to take a REG and a MODE and turn it into the non-prefixed
instruction format (D/DS/DQ) used for offset memory. */
@@ -25119,8 +25164,16 @@ prefixed_store_p (rtx_insn *insn)
return false;
machine_mode mem_mode = GET_MODE (mem);
+ rtx addr = XEXP (mem, 0);
enum non_prefixed_form non_prefixed = reg_to_non_prefixed (reg, mem_mode);
- return address_is_prefixed (XEXP (mem, 0), mem_mode, non_prefixed);
+
+ /* Need to make sure we aren't looking at a stfs which doesn't look
+ like the other things reg_to_non_prefixed/address_is_prefixed
+ looks for. */
+ if (non_prefixed == NON_PREFIXED_X && is_stfs_insn (insn))
+ return address_is_prefixed (addr, mem_mode, NON_PREFIXED_DEFAULT);
+ else
+ return address_is_prefixed (addr, mem_mode, non_prefixed);
}
/* Whether a load immediate or add instruction is a prefixed instruction. This