@@ -2441,6 +2441,10 @@ aarch64_regno_ok_for_index_p (int regno,
{
if (!strict_p)
return true;
+
+ if (!reg_renumber)
+ return false;
+
regno = reg_renumber[regno];
}
return GP_REGNUM_P (regno);
@@ -2456,6 +2460,10 @@ aarch64_regno_ok_for_base_p (int regno,
{
if (!strict_p)
return true;
+
+ if (!reg_renumber)
+ return false;
+
regno = reg_renumber[regno];
}
@@ -2639,6 +2647,29 @@ aarch64_classify_index (struct aarch64_a
return false;
}
+static inline bool
+offset_7bit_signed_scaled_p (enum machine_mode mode, HOST_WIDE_INT offset)
+{
+ return (offset >= -64 * GET_MODE_SIZE (mode)
+ && offset < 64 * GET_MODE_SIZE (mode)
+ && offset % GET_MODE_SIZE (mode) == 0);
+}
+
+static inline bool
+offset_9bit_signed_unscaled_p (enum machine_mode mode ATTRIBUTE_UNUSED,
+ HOST_WIDE_INT offset)
+{
+ return offset >= -256 && offset < 256;
+}
+
+static inline bool
+offset_12bit_unsigned_scaled_p (enum machine_mode mode, HOST_WIDE_INT offset)
+{
+ return (offset >= 0
+ && offset < 4096 * GET_MODE_SIZE (mode)
+ && offset % GET_MODE_SIZE (mode) == 0);
+}
+
/* Return true if X is a valid address for machine mode MODE. If it is,
fill in INFO appropriately. STRICT_P is true if REG_OK_STRICT is in
effect. OUTER_CODE is PARALLEL for a load/store pair. */
@@ -2650,7 +2681,8 @@ aarch64_classify_address (struct aarch64
{
enum rtx_code code = GET_CODE (x);
rtx op0, op1;
- bool pair_p = (outer_code == PARALLEL || mode == TImode);
+ bool allow_reg_index_p =
+ outer_code != PARALLEL && GET_MODE_SIZE(mode) != 16;
/* Don't support anything other than POST_INC or REG addressing for
AdvSIMD. */
@@ -2679,25 +2711,27 @@ aarch64_classify_address (struct aarch64
info->type = ADDRESS_REG_IMM;
info->base = op0;
info->offset = op1;
+
+ /* TImode and TFmode values are allowed in both pairs of X
+ registers and individual Q registers. The available
+ address modes are:
+ X,X: 7-bit signed scaled offset
+ Q: 9-bit signed offset
+ We conservatively require an offset representable in either mode.
+ */
+ if (mode == TImode || mode == TFmode)
+ return (offset_7bit_signed_scaled_p (mode, offset)
+ && offset_9bit_signed_unscaled_p (mode, offset));
+
if (outer_code == PARALLEL)
- /* load/store pair: 7-bit signed, scaled offset. */
return ((GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
- && offset >= -64 * GET_MODE_SIZE (mode)
- && offset < 64 * GET_MODE_SIZE (mode)
- && offset % GET_MODE_SIZE (mode) == 0);
- else if (mode == TImode)
- /* load/store pair of dwords: 7-bit signed, scaled offset. */
- return offset >= -512 && offset < 512 && offset % 8 == 0;
+ && offset_7bit_signed_scaled_p (mode, offset));
else
- /* load/store single: 9-bit signed, unscaled offset. */
- /* load/store single: 12-bit unsigned, scaled offset. */
- return ((offset >= -256 && offset < 256)
- || (offset >= 0
- && offset < 4096 * GET_MODE_SIZE (mode)
- && offset % GET_MODE_SIZE (mode) == 0));
+ return (offset_9bit_signed_unscaled_p (mode, offset)
+ || offset_12bit_unsigned_scaled_p (mode, offset));
}
- if (!pair_p)
+ if (allow_reg_index_p)
{
/* Look for base + (scaled/extended) index register. */
if (aarch64_base_register_rtx_p (op0, strict_p)
@@ -2737,18 +2771,23 @@ aarch64_classify_address (struct aarch64
HOST_WIDE_INT offset;
info->offset = XEXP (XEXP (x, 1), 1);
offset = INTVAL (info->offset);
+
+ /* TImode and TFmode values are allowed in both pairs of X
+ registers and individual Q registers. The available
+ address modes are:
+ X,X: 7-bit signed scaled offset
+ Q: 9-bit signed offset
+ We conservatively require an offset representable in either mode.
+ */
+ if (mode == TImode || mode == TFmode)
+ return (offset_7bit_signed_scaled_p (mode, offset)
+ && offset_9bit_signed_unscaled_p (mode, offset));
+
if (outer_code == PARALLEL)
- /* load/store pair: 7-bit signed, scaled offset. */
return ((GET_MODE_SIZE (mode) == 4 || GET_MODE_SIZE (mode) == 8)
- && offset >= -64 * GET_MODE_SIZE (mode)
- && offset < 64 * GET_MODE_SIZE (mode)
- && offset % GET_MODE_SIZE (mode) == 0);
- else if (mode == TImode)
- /* load/store pair of dwords: 7-bit signed, scaled offset. */
- return offset >= -512 && offset < 512 && offset % 8 == 0;
+ && offset_7bit_signed_scaled_p (mode, offset));
else
- /* load/store single: 9-bit signed, unscaled offset. */
- return offset >= -256 && offset < 256;
+ return offset_9bit_signed_unscaled_p (mode, offset);
}
return false;
@@ -2759,10 +2798,10 @@ aarch64_classify_address (struct aarch64
info->type = ADDRESS_SYMBOLIC;
if (outer_code != PARALLEL
&& (GET_MODE_SIZE (mode) == 4
- || GET_MODE_SIZE (mode) == 8
- || mode == TFmode))
+ || GET_MODE_SIZE (mode) == 8))
{
rtx sym, addend;
+
split_const (x, &sym, &addend);
return (GET_CODE (sym) == LABEL_REF
|| (GET_CODE (sym) == SYMBOL_REF
@@ -2774,7 +2813,7 @@ aarch64_classify_address (struct aarch64
info->type = ADDRESS_LO_SUM;
info->base = XEXP (x, 0);
info->offset = XEXP (x, 1);
- if (!pair_p
+ if (allow_reg_index_p
&& aarch64_base_register_rtx_p (info->base, strict_p))
{
rtx sym, offs;
@@ -987,8 +987,10 @@ (define_expand "movti"
)
(define_insn "*movti_aarch64"
- [(set (match_operand:TI 0 "nonimmediate_operand" "=r, *w,r,*w,r,m,m,*w, m")
- (match_operand:TI 1 "aarch64_movti_operand" " rn,r,*w,*w,m,r,Z, m,*w"))]
+ [(set (match_operand:TI 0
+ "nonimmediate_operand" "=r, *w,r ,*w,r ,Ump,Ump,*w,m")
+ (match_operand:TI 1
+ "aarch64_movti_operand" " rn,r ,*w,*w,Ump,r ,Z , m,*w"))]
"(register_operand (operands[0], TImode)
|| aarch64_reg_or_zero (operands[1], TImode))"
"@
@@ -1002,7 +1004,7 @@ (define_insn "*movti_aarch64"
ldr\\t%q0, %1
str\\t%q1, %0"
[(set_attr "v8type" "move2,fmovi2f,fmovf2i,*, \
- load2,store2,store2,fpsimd_load,fpsimd_store")
+ load2,store2,store2,fpsimd_load,fpsimd_store")
(set_attr "simd_type" "*,*,*,simd_move,*,*,*,*,*")
(set_attr "mode" "DI,DI,DI,TI,DI,DI,DI,TI,TI")
(set_attr "length" "8,8,8,4,4,4,4,4,4")
@@ -1091,8 +1093,10 @@ (define_expand "movtf"
)
(define_insn "*movtf_aarch64"
- [(set (match_operand:TF 0 "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Utf")
- (match_operand:TF 1 "general_operand" " w,?r,?r,w ,Y,Y ,m,w,Utf,?rY"))]
+ [(set (match_operand:TF 0
+ "nonimmediate_operand" "=w,?&r,w ,?r,w,?w,w,m,?r ,Ump")
+ (match_operand:TF 1
+ "general_operand" " w,?r, ?r,w ,Y,Y ,m,w,Ump,?rY"))]
"TARGET_FLOAT && (register_operand (operands[0], TFmode)
|| register_operand (operands[1], TFmode))"
"@
@@ -121,14 +121,7 @@ (define_memory_constraint "Ump"
A memory address suitable for a load/store pair operation."
(and (match_code "mem")
(match_test "aarch64_legitimate_address_p (GET_MODE (op), XEXP (op, 0),
- PARALLEL, 0)")))
-
-(define_memory_constraint "Utf"
- "@internal
- A memory address suitable for a load/store pair operation."
- (and (match_code "mem")
- (match_test "aarch64_legitimate_address_p (TImode, XEXP (op, 0),
- UNKNOWN, 0)")))
+ PARALLEL, 1)")))
(define_constraint "Dn"
"@internal