@@ -247,5 +247,5 @@ extern int vfp3_const_double_for_fract_bits (rtx);
extern void arm_expand_vec_perm (rtx target, rtx op0, rtx op1, rtx sel);
extern bool arm_expand_vec_perm_const (rtx target, rtx op0, rtx op1, rtx sel);
-
+extern bool arm_autoinc_modes_ok_p (enum machine_mode, int);
#endif /* ! GCC_ARM_PROTOS_H */
@@ -25652,5 +25652,40 @@ arm_vectorize_vec_perm_const_ok (enum machine_mode vmode,
return ret;
}
+bool
+arm_autoinc_modes_ok_p (enum machine_mode mode, int code)
+{
+ if (TARGET_SOFT_FLOAT)
+ return true;
+
+ switch (code)
+ {
+ case ARM_POST_INC:
+ case ARM_PRE_DEC:
+ if (VECTOR_MODE_P (mode))
+ {
+ if (code != PRE_DEC)
+ return true;
+ else
+ return false;
+ }
+
+ return true;
+
+ case ARM_POST_DEC:
+ case ARM_PRE_INC:
+ if (FLOAT_MODE_P (mode) || VECTOR_MODE_P (mode))
+ return false;
+ else
+ return true;
+
+ default:
+ return false;
+
+ }
+
+ return false;
+}
+
#include "gt-arm.h"
@@ -1623,6 +1623,27 @@ typedef struct
#define HAVE_PRE_MODIFY_REG TARGET_32BIT
#define HAVE_POST_MODIFY_REG TARGET_32BIT
+#define ARM_POST_INC 0
+#define ARM_PRE_INC 1
+#define ARM_POST_DEC 2
+#define ARM_PRE_DEC 3
+
+#define ARM_AUTOINC_VALID_FOR_MODE_P(mode, code) \
+ (TARGET_32BIT && arm_autoinc_modes_ok_p (mode, code))
+#define USE_LOAD_POST_INCREMENT(mode) \
+ ARM_AUTOINC_VALID_FOR_MODE_P(mode, ARM_POST_INC)
+#define USE_LOAD_PRE_INCREMENT(mode) \
+ ARM_AUTOINC_VALID_FOR_MODE_P(mode, ARM_PRE_INC)
+#define USE_LOAD_POST_DECREMENT(mode) \
+ ARM_AUTOINC_VALID_FOR_MODE_P(mode, ARM_POST_DEC)
+#define USE_LOAD_PRE_DECREMENT(mode) \
+ ARM_AUTOINC_VALID_FOR_MODE_P(mode, ARM_PRE_DEC)
+
+#define USE_STORE_PRE_DECREMENT(mode) USE_LOAD_PRE_DECREMENT(mode)
+#define USE_STORE_PRE_INCREMENT(mode) USE_LOAD_PRE_INCREMENT(mode)
+#define USE_STORE_POST_DECREMENT(mode) USE_LOAD_POST_DECREMENT(mode)
+#define USE_STORE_POST_INCREMENT(mode) USE_LOAD_POST_INCREMENT(mode)
+
/* Macros to check register numbers against specific register classes. */
/* These assume that REGNO is a hard or pseudo reg number.
@@ -2361,8 +2361,12 @@ add_autoinc_candidates (struct ivopts_data *data, tree base, tree step,
cstepi = int_cst_value (step);
mem_mode = TYPE_MODE (TREE_TYPE (*use->op_p));
- if ((HAVE_PRE_INCREMENT && GET_MODE_SIZE (mem_mode) == cstepi)
- || (HAVE_PRE_DECREMENT && GET_MODE_SIZE (mem_mode) == -cstepi))
+ if (((USE_LOAD_PRE_INCREMENT (mem_mode)
+ || USE_STORE_PRE_INCREMENT (mem_mode))
+ && GET_MODE_SIZE (mem_mode) == cstepi)
+ || ((USE_LOAD_PRE_DECREMENT (mem_mode)
+ || USE_STORE_PRE_DECREMENT (mem_mode))
+ && GET_MODE_SIZE (mem_mode) == -cstepi))
{
enum tree_code code = MINUS_EXPR;
tree new_base;
@@ -2379,8 +2383,12 @@ add_autoinc_candidates (struct ivopts_data *data, tree base, tree step,
add_candidate_1 (data, new_base, step, important, IP_BEFORE_USE, use,
use->stmt);
}
- if ((HAVE_POST_INCREMENT && GET_MODE_SIZE (mem_mode) == cstepi)
- || (HAVE_POST_DECREMENT && GET_MODE_SIZE (mem_mode) == -cstepi))
+ if (((USE_LOAD_POST_INCREMENT (mem_mode)
+ || USE_STORE_POST_INCREMENT (mem_mode))
+ && GET_MODE_SIZE (mem_mode) == cstepi)
+ || ((USE_LOAD_POST_DECREMENT (mem_mode)
+ || USE_STORE_POST_DECREMENT (mem_mode))
+ && GET_MODE_SIZE (mem_mode) == -cstepi))
{
add_candidate_1 (data, base, step, important, IP_AFTER_USE, use,
use->stmt);
@@ -3314,25 +3322,29 @@ get_address_cost (bool symbol_present, bool var_present,
reg0 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 1);
reg1 = gen_raw_REG (address_mode, LAST_VIRTUAL_REGISTER + 2);
- if (HAVE_PRE_DECREMENT)
+ if (USE_LOAD_PRE_DECREMENT (mem_mode)
+ || USE_STORE_PRE_DECREMENT (mem_mode))
{
addr = gen_rtx_PRE_DEC (address_mode, reg0);
has_predec[mem_mode]
= memory_address_addr_space_p (mem_mode, addr, as);
}
- if (HAVE_POST_DECREMENT)
+ if (USE_LOAD_POST_DECREMENT (mem_mode)
+ || USE_STORE_POST_DECREMENT (mem_mode))
{
addr = gen_rtx_POST_DEC (address_mode, reg0);
has_postdec[mem_mode]
= memory_address_addr_space_p (mem_mode, addr, as);
}
- if (HAVE_PRE_INCREMENT)
+ if (USE_LOAD_PRE_INCREMENT (mem_mode)
+ || USE_STORE_PRE_DECREMENT (mem_mode))
{
addr = gen_rtx_PRE_INC (address_mode, reg0);
has_preinc[mem_mode]
= memory_address_addr_space_p (mem_mode, addr, as);
}
- if (HAVE_POST_INCREMENT)
+ if (USE_LOAD_POST_INCREMENT (mem_mode)
+ || USE_STORE_POST_INCREMENT (mem_mode))
{
addr = gen_rtx_POST_INC (address_mode, reg0);
has_postinc[mem_mode]