summaryrefslogtreecommitdiff
path: root/gcc/config/arm/predicates.md
diff options
context:
space:
mode:
authorIan Bolton <ian.bolton@arm.com>2012-04-30 13:40:14 +0000
committerRichard Earnshaw <rearnsha@gcc.gnu.org>2012-04-30 13:40:14 +0000
commit5991e1568cd0d505ae3646c3178b1676cc70bc13 (patch)
treec09b78879773404236f826ecfe7361af931d230e /gcc/config/arm/predicates.md
parentd55d2c8490cf7c44a2c48a41cf253888b3a5c552 (diff)
downloadgcc-5991e1568cd0d505ae3646c3178b1676cc70bc13.tar.gz
2012-04-30 Ian Bolton <ian.bolton at arm.com> Sameera Deshpande...
2012-04-30 Ian Bolton <ian.bolton at arm.com> Sameera Deshpande <sameera.deshpande at arm.com> Greta Yorsh <greta.yorsh at arm.com> * config/arm/arm-protos.h (ldm_stm_operation_p): New declaration. * config/arm/arm.c (ldm_stm_operation_p): New function. * config/arm/predicates.md (load_multiple_operation): Update predicate. (store_multiple_operation): Likewise. Co-Authored-By: Greta Yorsh <greta.yorsh@arm.com> Co-Authored-By: Sameera Deshpande <sameera.deshpande@arm.com> From-SVN: r186980
Diffstat (limited to 'gcc/config/arm/predicates.md')
-rw-r--r--gcc/config/arm/predicates.md145
1 files changed, 2 insertions, 143 deletions
diff --git a/gcc/config/arm/predicates.md b/gcc/config/arm/predicates.md
index 9171d7377fe..20a64ec3701 100644
--- a/gcc/config/arm/predicates.md
+++ b/gcc/config/arm/predicates.md
@@ -380,154 +380,13 @@
(define_special_predicate "load_multiple_operation"
(match_code "parallel")
{
- HOST_WIDE_INT count = XVECLEN (op, 0);
- unsigned dest_regno;
- rtx src_addr;
- HOST_WIDE_INT i = 1, base = 0;
- HOST_WIDE_INT offset = 0;
- rtx elt;
- bool addr_reg_loaded = false;
- bool update = false;
-
- if (count <= 1
- || GET_CODE (XVECEXP (op, 0, 0)) != SET
- || !REG_P (SET_DEST (XVECEXP (op, 0, 0))))
- return false;
-
- /* Check to see if this might be a write-back. */
- if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
- {
- i++;
- base = 1;
- update = true;
-
- /* Now check it more carefully. */
- if (GET_CODE (SET_DEST (elt)) != REG
- || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
- || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
- || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
- return false;
- }
-
- /* Perform a quick check so we don't blow up below. */
- if (count <= i
- || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
- || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != REG
- || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != MEM)
- return false;
-
- dest_regno = REGNO (SET_DEST (XVECEXP (op, 0, i - 1)));
- src_addr = XEXP (SET_SRC (XVECEXP (op, 0, i - 1)), 0);
- if (GET_CODE (src_addr) == PLUS)
- {
- if (GET_CODE (XEXP (src_addr, 1)) != CONST_INT)
- return false;
- offset = INTVAL (XEXP (src_addr, 1));
- src_addr = XEXP (src_addr, 0);
- }
- if (!REG_P (src_addr))
- return false;
-
- for (; i < count; i++)
- {
- elt = XVECEXP (op, 0, i);
-
- if (GET_CODE (elt) != SET
- || GET_CODE (SET_DEST (elt)) != REG
- || GET_MODE (SET_DEST (elt)) != SImode
- || REGNO (SET_DEST (elt)) <= dest_regno
- || GET_CODE (SET_SRC (elt)) != MEM
- || GET_MODE (SET_SRC (elt)) != SImode
- || ((GET_CODE (XEXP (SET_SRC (elt), 0)) != PLUS
- || !rtx_equal_p (XEXP (XEXP (SET_SRC (elt), 0), 0), src_addr)
- || GET_CODE (XEXP (XEXP (SET_SRC (elt), 0), 1)) != CONST_INT
- || INTVAL (XEXP (XEXP (SET_SRC (elt), 0), 1)) != offset + (i - base) * 4)
- && (!REG_P (XEXP (SET_SRC (elt), 0))
- || offset + (i - base) * 4 != 0)))
- return false;
- dest_regno = REGNO (SET_DEST (elt));
- if (dest_regno == REGNO (src_addr))
- addr_reg_loaded = true;
- }
- /* For Thumb, we only have updating instructions. If the pattern does
- not describe an update, it must be because the address register is
- in the list of loaded registers - on the hardware, this has the effect
- of overriding the update. */
- if (update && addr_reg_loaded)
- return false;
- if (TARGET_THUMB1)
- return update || addr_reg_loaded;
- return true;
+ return ldm_stm_operation_p (op, /*load=*/true);
})
(define_special_predicate "store_multiple_operation"
(match_code "parallel")
{
- HOST_WIDE_INT count = XVECLEN (op, 0);
- unsigned src_regno;
- rtx dest_addr;
- HOST_WIDE_INT i = 1, base = 0, offset = 0;
- rtx elt;
-
- if (count <= 1
- || GET_CODE (XVECEXP (op, 0, 0)) != SET)
- return false;
-
- /* Check to see if this might be a write-back. */
- if (GET_CODE (SET_SRC (elt = XVECEXP (op, 0, 0))) == PLUS)
- {
- i++;
- base = 1;
-
- /* Now check it more carefully. */
- if (GET_CODE (SET_DEST (elt)) != REG
- || GET_CODE (XEXP (SET_SRC (elt), 0)) != REG
- || GET_CODE (XEXP (SET_SRC (elt), 1)) != CONST_INT
- || INTVAL (XEXP (SET_SRC (elt), 1)) != (count - 1) * 4)
- return false;
- }
-
- /* Perform a quick check so we don't blow up below. */
- if (count <= i
- || GET_CODE (XVECEXP (op, 0, i - 1)) != SET
- || GET_CODE (SET_DEST (XVECEXP (op, 0, i - 1))) != MEM
- || GET_CODE (SET_SRC (XVECEXP (op, 0, i - 1))) != REG)
- return false;
-
- src_regno = REGNO (SET_SRC (XVECEXP (op, 0, i - 1)));
- dest_addr = XEXP (SET_DEST (XVECEXP (op, 0, i - 1)), 0);
-
- if (GET_CODE (dest_addr) == PLUS)
- {
- if (GET_CODE (XEXP (dest_addr, 1)) != CONST_INT)
- return false;
- offset = INTVAL (XEXP (dest_addr, 1));
- dest_addr = XEXP (dest_addr, 0);
- }
- if (!REG_P (dest_addr))
- return false;
-
- for (; i < count; i++)
- {
- elt = XVECEXP (op, 0, i);
-
- if (GET_CODE (elt) != SET
- || GET_CODE (SET_SRC (elt)) != REG
- || GET_MODE (SET_SRC (elt)) != SImode
- || REGNO (SET_SRC (elt)) <= src_regno
- || GET_CODE (SET_DEST (elt)) != MEM
- || GET_MODE (SET_DEST (elt)) != SImode
- || ((GET_CODE (XEXP (SET_DEST (elt), 0)) != PLUS
- || !rtx_equal_p (XEXP (XEXP (SET_DEST (elt), 0), 0), dest_addr)
- || GET_CODE (XEXP (XEXP (SET_DEST (elt), 0), 1)) != CONST_INT
- || INTVAL (XEXP (XEXP (SET_DEST (elt), 0), 1)) != offset + (i - base) * 4)
- && (!REG_P (XEXP (SET_DEST (elt), 0))
- || offset + (i - base) * 4 != 0)))
- return false;
- src_regno = REGNO (SET_SRC (elt));
- }
-
- return true;
+ return ldm_stm_operation_p (op, /*load=*/false);
})
(define_special_predicate "multi_register_push"