aboutsummaryrefslogtreecommitdiff
path: root/gcc/config/arm/arm.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/config/arm/arm.c')
-rw-r--r--gcc/config/arm/arm.c115
1 files changed, 77 insertions, 38 deletions
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 886bcfa98b9..74b9d07a195 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -2811,16 +2811,16 @@ arm_option_check_internal (struct gcc_options *opts)
flag_pic = 0;
}
- /* We only support -mslow-flash-data on armv7-m targets. */
- if (target_slow_flash_data
- && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
- || (TARGET_THUMB1_P (flags) || flag_pic || TARGET_NEON)))
- error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
-
- /* We only support pure-code on Thumb-2 M-profile targets. */
- if (target_pure_code
- && (!arm_arch_thumb2 || arm_arch_notm || flag_pic || TARGET_NEON))
- error ("-mpure-code only supports non-pic code on armv7-m targets");
+ /* We only support -mpure-code and -mslow-flash-data on M-profile targets
+ with MOVT. */
+ if ((target_pure_code || target_slow_flash_data)
+ && (!TARGET_HAVE_MOVT || arm_arch_notm || flag_pic || TARGET_NEON))
+ {
+ const char *flag = (target_pure_code ? "-mpure-code" :
+ "-mslow-flash-data");
+ error ("%s only supports non-pic code on M-profile targets with the "
+ "MOVT instruction", flag);
+ }
}
@@ -4055,7 +4055,7 @@ const_ok_for_arm (HOST_WIDE_INT i)
|| (i & ~0xfc000003) == 0))
return TRUE;
}
- else
+ else if (TARGET_THUMB2)
{
HOST_WIDE_INT v;
@@ -4071,6 +4071,14 @@ const_ok_for_arm (HOST_WIDE_INT i)
if (i == v)
return TRUE;
}
+ else if (TARGET_HAVE_MOVT)
+ {
+ /* Thumb-1 Targets with MOVT. */
+ if (i > 0xffff)
+ return FALSE;
+ else
+ return TRUE;
+ }
return FALSE;
}
@@ -7714,6 +7722,32 @@ arm_legitimate_address_outer_p (machine_mode mode, rtx x, RTX_CODE outer,
return 0;
}
+/* Return true if we can avoid creating a constant pool entry for x. */
+static bool
+can_avoid_literal_pool_for_label_p (rtx x)
+{
+ /* Normally we can assign constant values to target registers without
+ the help of constant pool. But there are cases we have to use constant
+ pool like:
+ 1) assign a label to register.
+ 2) sign-extend a 8bit value to 32bit and then assign to register.
+
+ Constant pool access in format:
+ (set (reg r0) (mem (symbol_ref (".LC0"))))
+ will cause the use of literal pool (later in function arm_reorg).
+ So here we mark such format as an invalid format, then the compiler
+ will adjust it into:
+ (set (reg r0) (symbol_ref (".LC0")))
+ (set (reg r0) (mem (reg r0))).
+ No extra register is required, and (mem (reg r0)) won't cause the use
+ of literal pools. */
+ if (arm_disable_literal_pool && GET_CODE (x) == SYMBOL_REF
+ && CONSTANT_POOL_ADDRESS_P (x))
+ return 1;
+ return 0;
+}
+
+
/* Return nonzero if X is a valid Thumb-2 address operand. */
static int
thumb2_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
@@ -7777,23 +7811,7 @@ thumb2_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
&& thumb2_legitimate_index_p (mode, xop0, strict_p)));
}
- /* Normally we can assign constant values to target registers without
- the help of constant pool. But there are cases we have to use constant
- pool like:
- 1) assign a label to register.
- 2) sign-extend a 8bit value to 32bit and then assign to register.
-
- Constant pool access in format:
- (set (reg r0) (mem (symbol_ref (".LC0"))))
- will cause the use of literal pool (later in function arm_reorg).
- So here we mark such format as an invalid format, then the compiler
- will adjust it into:
- (set (reg r0) (symbol_ref (".LC0")))
- (set (reg r0) (mem (reg r0))).
- No extra register is required, and (mem (reg r0)) won't cause the use
- of literal pools. */
- else if (arm_disable_literal_pool && code == SYMBOL_REF
- && CONSTANT_POOL_ADDRESS_P (x))
+ else if (can_avoid_literal_pool_for_label_p (x))
return 0;
else if (GET_MODE_CLASS (mode) != MODE_FLOAT
@@ -8072,6 +8090,9 @@ thumb1_index_register_rtx_p (rtx x, int strict_p)
int
thumb1_legitimate_address_p (machine_mode mode, rtx x, int strict_p)
{
+ if (TARGET_HAVE_MOVT && can_avoid_literal_pool_for_label_p (x))
+ return 0;
+
/* ??? Not clear if this is right. Experiment. */
if (GET_MODE_SIZE (mode) < 4
&& !(reload_in_progress || reload_completed)
@@ -8693,6 +8714,7 @@ thumb_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
return (CONST_INT_P (x)
|| CONST_DOUBLE_P (x)
|| CONSTANT_ADDRESS_P (x)
+ || (TARGET_HAVE_MOVT && GET_CODE (x) == SYMBOL_REF)
|| flag_pic);
}
@@ -10684,7 +10706,7 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code,
{
if (speed_p)
*cost += extra_cost->fp[mode == DFmode].widen;
- if (!TARGET_FPU_ARMV8
+ if (!TARGET_VFP5
&& GET_MODE (XEXP (x, 0)) == HFmode)
{
/* Pre v8, widening HF->DF is a two-step process, first
@@ -10778,7 +10800,7 @@ arm_rtx_costs_internal (rtx x, enum rtx_code code, enum rtx_code outer_code,
return true;
}
else if (GET_MODE_CLASS (mode) == MODE_FLOAT
- && TARGET_FPU_ARMV8)
+ && TARGET_VFP5)
{
if (speed_p)
*cost += extra_cost->fp[mode == DFmode].roundint;
@@ -26146,6 +26168,8 @@ arm_file_start (void)
else if (strncmp (arm_active_target.core_name, "generic", 7) == 0)
asm_fprintf (asm_out_file, "\t.arch %s\n",
arm_active_target.core_name + 8);
+ else if (strcmp (arm_active_target.core_name, "cortex-m33+nodsp") == 0)
+ asm_fprintf (asm_out_file, "\t.arch armv8-m.main\n");
else
{
const char* truncated_name
@@ -28266,17 +28290,32 @@ arm_expand_compare_and_swap (rtx operands[])
gcc_unreachable ();
}
- switch (mode)
+ if (TARGET_THUMB1)
{
- case QImode: gen = gen_atomic_compare_and_swapqi_1; break;
- case HImode: gen = gen_atomic_compare_and_swaphi_1; break;
- case SImode: gen = gen_atomic_compare_and_swapsi_1; break;
- case DImode: gen = gen_atomic_compare_and_swapdi_1; break;
- default:
- gcc_unreachable ();
+ switch (mode)
+ {
+ case QImode: gen = gen_atomic_compare_and_swapt1qi_1; break;
+ case HImode: gen = gen_atomic_compare_and_swapt1hi_1; break;
+ case SImode: gen = gen_atomic_compare_and_swapt1si_1; break;
+ case DImode: gen = gen_atomic_compare_and_swapt1di_1; break;
+ default:
+ gcc_unreachable ();
+ }
+ }
+ else
+ {
+ switch (mode)
+ {
+ case QImode: gen = gen_atomic_compare_and_swap32qi_1; break;
+ case HImode: gen = gen_atomic_compare_and_swap32hi_1; break;
+ case SImode: gen = gen_atomic_compare_and_swap32si_1; break;
+ case DImode: gen = gen_atomic_compare_and_swap32di_1; break;
+ default:
+ gcc_unreachable ();
+ }
}
- bdst = TARGET_THUMB1 ? bval : gen_rtx_REG (CCmode, CC_REGNUM);
+ bdst = TARGET_THUMB1 ? bval : gen_rtx_REG (CC_Zmode, CC_REGNUM);
emit_insn (gen (bdst, rval, mem, oldval, newval, is_weak, mod_s, mod_f));
if (mode == QImode || mode == HImode)