diff options
Diffstat (limited to 'gcc/config/arm/arm.c')
-rw-r--r-- | gcc/config/arm/arm.c | 115 |
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) |