aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/aarch64/aarch64.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/aarch64/aarch64.c')
-rw-r--r--gcc/config/aarch64/aarch64.c67
1 files changed, 61 insertions, 6 deletions
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index 3e663eb5f13..6078b163548 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -712,7 +712,7 @@ static const struct tune_params thunderx_tunings =
0, /* max_case_values. */
0, /* cache_line_size. */
tune_params::AUTOPREFETCHER_OFF, /* autoprefetcher_model. */
- (AARCH64_EXTRA_TUNE_NONE) /* tune_flags. */
+ (AARCH64_EXTRA_TUNE_SLOW_UNALIGNED_LDPW) /* tune_flags. */
};
static const struct tune_params xgene1_tunings =
@@ -4191,6 +4191,24 @@ aarch64_legitimate_address_p (machine_mode mode, rtx x,
return aarch64_classify_address (&addr, x, mode, outer_code, strict_p);
}
+/* Split an out-of-range address displacement into a base and offset.
+ Use 4KB range for 1- and 2-byte accesses and a 16KB range otherwise
+ to increase opportunities for sharing the base address of different sizes.
+ For TI/TFmode and unaligned accesses use a 256-byte range. */
+static bool
+aarch64_legitimize_address_displacement (rtx *disp, rtx *off, machine_mode mode)
+{
+ HOST_WIDE_INT mask = GET_MODE_SIZE (mode) < 4 ? 0xfff : 0x3fff;
+
+ if (mode == TImode || mode == TFmode ||
+ (INTVAL (*disp) & (GET_MODE_SIZE (mode) - 1)) != 0)
+ mask = 0xff;
+
+ *off = GEN_INT (INTVAL (*disp) & ~mask);
+ *disp = GEN_INT (INTVAL (*disp) & mask);
+ return true;
+}
+
/* Return TRUE if rtx X is immediate constant 0.0 */
bool
aarch64_float_const_zero_rtx_p (rtx x)
@@ -4264,6 +4282,14 @@ aarch64_select_cc_mode (RTX_CODE code, rtx x, rtx y)
&& (GET_MODE (x) == HImode || GET_MODE (x) == QImode))
return CC_NZmode;
+ /* Similarly, comparisons of zero_extends from shorter modes can
+ be performed using an ANDS with an immediate mask. */
+ if (y == const0_rtx && GET_CODE (x) == ZERO_EXTEND
+ && (GET_MODE (x) == SImode || GET_MODE (x) == DImode)
+ && (GET_MODE (XEXP (x, 0)) == HImode || GET_MODE (XEXP (x, 0)) == QImode)
+ && (code == EQ || code == NE))
+ return CC_NZmode;
+
if ((GET_MODE (x) == SImode || GET_MODE (x) == DImode)
&& y == const0_rtx
&& (code == EQ || code == NE || code == LT || code == GE)
@@ -5056,9 +5082,19 @@ aarch64_legitimize_address (rtx x, rtx /* orig_x */, machine_mode mode)
/* For offsets aren't a multiple of the access size, the limit is
-256...255. */
else if (offset & (GET_MODE_SIZE (mode) - 1))
- base_offset = (offset + 0x100) & ~0x1ff;
+ {
+ base_offset = (offset + 0x100) & ~0x1ff;
+
+ /* BLKmode typically uses LDP of X-registers. */
+ if (mode == BLKmode)
+ base_offset = (offset + 512) & ~0x3ff;
+ }
+ /* Small negative offsets are supported. */
+ else if (IN_RANGE (offset, -256, 0))
+ base_offset = 0;
+ /* Use 12-bit offset by access size. */
else
- base_offset = offset & ~0xfff;
+ base_offset = offset & (~0xfff * GET_MODE_SIZE (mode));
if (base_offset != 0)
{
@@ -13593,6 +13629,15 @@ aarch64_operands_ok_for_ldpstp (rtx *operands, bool load,
if (MEM_VOLATILE_P (mem_1) || MEM_VOLATILE_P (mem_2))
return false;
+ /* If we have SImode and slow unaligned ldp,
+ check the alignment to be at least 8 byte. */
+ if (mode == SImode
+ && (aarch64_tune_params.extra_tuning_flags
+ & AARCH64_EXTRA_TUNE_SLOW_UNALIGNED_LDPW)
+ && !optimize_size
+ && MEM_ALIGN (mem_1) < 8 * BITS_PER_UNIT)
+ return false;
+
/* Check if the addresses are in the form of [base+offset]. */
extract_base_offset_in_addr (mem_1, &base_1, &offset_1);
if (base_1 == NULL_RTX || offset_1 == NULL_RTX)
@@ -13752,6 +13797,15 @@ aarch64_operands_adjust_ok_for_ldpstp (rtx *operands, bool load,
return false;
}
+ /* If we have SImode and slow unaligned ldp,
+ check the alignment to be at least 8 byte. */
+ if (mode == SImode
+ && (aarch64_tune_params.extra_tuning_flags
+ & AARCH64_EXTRA_TUNE_SLOW_UNALIGNED_LDPW)
+ && !optimize_size
+ && MEM_ALIGN (mem_1) < 8 * BITS_PER_UNIT)
+ return false;
+
if (REG_P (reg_1) && FP_REGNUM_P (REGNO (reg_1)))
rclass_1 = FP_REGS;
else
@@ -14127,12 +14181,13 @@ aarch64_optab_supported_p (int op, machine_mode mode1, machine_mode,
#undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P aarch64_legitimate_constant_p
+#undef TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT
+#define TARGET_LEGITIMIZE_ADDRESS_DISPLACEMENT \
+ aarch64_legitimize_address_displacement
+
#undef TARGET_LIBGCC_CMP_RETURN_MODE
#define TARGET_LIBGCC_CMP_RETURN_MODE aarch64_libgcc_cmp_return_mode
-#undef TARGET_LRA_P
-#define TARGET_LRA_P hook_bool_void_true
-
#undef TARGET_MANGLE_TYPE
#define TARGET_MANGLE_TYPE aarch64_mangle_type