diff options
author | Aaron Sawdey <acsawdey@linux.ibm.com> | 2020-06-02 15:48:01 -0500 |
---|---|---|
committer | Aaron Sawdey <acsawdey@linux.ibm.com> | 2020-06-03 16:01:27 -0500 |
commit | c0d738a0f493a85f46d7618efe20a89bf7f7ead8 (patch) | |
tree | dbca18c6d4ef373e1abffb319c2c3b9692570da4 | |
parent | c06280ac4c34b0aff8cfa2e74ae8c7afd759d52f (diff) | |
download | gcc-c0d738a0f493a85f46d7618efe20a89bf7f7ead8.zip gcc-c0d738a0f493a85f46d7618efe20a89bf7f7ead8.tar.gz gcc-c0d738a0f493a85f46d7618efe20a89bf7f7ead8.tar.bz2 |
identify lfs prefixed case PR95347
The same problem also arises for plfs where prefixed_load_p()
doesn't recognize it so we get just lfs in the asm output
with an @pcrel address.
PR target/95347
* config/rs6000/rs6000.c (is_stfs_insn): Rename to
is_lfs_stfs_insn and make it recognize lfs as well.
(prefixed_store_p): Use is_lfs_stfs_insn().
(prefixed_load_p): Use is_lfs_stfs_insn() to recognize lfs.
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 37 |
1 files changed, 25 insertions, 12 deletions
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index ba9069e..42d517c 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -24980,14 +24980,18 @@ address_to_insn_form (rtx addr, return INSN_FORM_BAD; } -/* Helper function to see if we're potentially looking at stfs. +/* Helper function to see if we're potentially looking at lfs/stfs. - PARALLEL containing a SET and a CLOBBER - - SET is from UNSPEC_SI_FROM_SF to MEM:SI - - CLOBBER is a V4SF + - stfs: + - SET is from UNSPEC_SI_FROM_SF to MEM:SI + - CLOBBER is a V4SF + - lfs: + - SET is from UNSPEC_SF_FROM_SI to REG:SF + - CLOBBER is a DI */ static bool -is_stfs_insn (rtx_insn *insn) +is_lfs_stfs_insn (rtx_insn *insn) { rtx pattern = PATTERN (insn); if (GET_CODE (pattern) != PARALLEL) @@ -25013,16 +25017,22 @@ is_stfs_insn (rtx_insn *insn) rtx src = SET_SRC (set); rtx scratch = SET_DEST (clobber); - if (GET_CODE (src) != UNSPEC || XINT (src, 1) != UNSPEC_SI_FROM_SF) + if (GET_CODE (src) != UNSPEC) return false; - if (GET_CODE (dest) != MEM || GET_MODE (dest) != SImode) - return false; + /* stfs case. */ + if (XINT (src, 1) == UNSPEC_SI_FROM_SF + && GET_CODE (dest) == MEM && GET_MODE (dest) == SImode + && GET_CODE (scratch) == SCRATCH && GET_MODE (scratch) == V4SFmode) + return true; - if (GET_CODE (scratch) != SCRATCH || GET_MODE (scratch) != V4SFmode) - return false; + /* lfs case. */ + if (XINT (src, 1) == UNSPEC_SF_FROM_SI + && GET_CODE (dest) == REG && GET_MODE (dest) == SFmode + && GET_CODE (scratch) == SCRATCH && GET_MODE (scratch) == DImode) + return true; - return true; + return false; } /* Helper function to take a REG and a MODE and turn it into the non-prefixed @@ -25135,7 +25145,10 @@ prefixed_load_p (rtx_insn *insn) else non_prefixed = reg_to_non_prefixed (reg, mem_mode); - return address_is_prefixed (XEXP (mem, 0), mem_mode, non_prefixed); + if (non_prefixed == NON_PREFIXED_X && is_lfs_stfs_insn (insn)) + return address_is_prefixed (XEXP (mem, 0), mem_mode, NON_PREFIXED_DEFAULT); + else + return address_is_prefixed (XEXP (mem, 0), mem_mode, non_prefixed); } /* Whether a store instruction is a prefixed instruction. This is called from @@ -25170,7 +25183,7 @@ prefixed_store_p (rtx_insn *insn) /* 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)) + if (non_prefixed == NON_PREFIXED_X && is_lfs_stfs_insn (insn)) return address_is_prefixed (addr, mem_mode, NON_PREFIXED_DEFAULT); else return address_is_prefixed (addr, mem_mode, non_prefixed); |