From 08793a386ad3f3365bd891dc793eedc59f8c5ee5 Mon Sep 17 00:00:00 2001 From: Christian Bruel Date: Tue, 26 May 2015 16:06:17 +0200 Subject: [PATCH] re PR target/52144 (ARM should support arm/thumb function attribute to permit different instruction sets in the same source) 2015-05-13 Christian Bruel PR target/52144 * config/arm/arm.c (arm_option_check_internal) (arm_option_params_internal): Check opts->target_flags to set macros. (TREE_TARGET_ARM, TREE_TARGET_THUMB) (TREE_TARGET_THUMB1, TREE_TARGET_THUMB2) Replace with... (TARGET_ARM_P, TARGET_THUMB_P, TARGET_THUMB1_P, TARGET_THUMB2_P) (builtin_define): Replaced with def_or_undef_macro. * config/arm/arm.h (TREE_TARGET_ARM, TREE_TARGET_THUMB) TREE_TARGET_THUMB1, TREE_TARGET_THUMB2) Redefine with... (TARGET_ARM_P, TARGET_THUMB_P, TARGET_THUMB1_P, TARGET_THUMB2_P) (TARGET_32BIT_P, TARGET_ARM_QBIT_P, TARGET_ARM_SAT_P, TARGET_IDIV_P) (TARGET_HAVE_LDREX_P, TARGET_HAVE_LDREXBH_P, TARGET_HAVE_LDREXD_P) (TARGET_ARM_FEATURE_LDREX_P) (TARGET_DSP_MULTIPLY_P, TARGET_INT_SIMD_P): New macros. (def_or_undef_macro): New function. From-SVN: r223699 --- gcc/ChangeLog | 18 ++++++++++ gcc/config/arm/arm-c.c | 78 ++++++++++++++++++++++++++---------------- gcc/config/arm/arm.c | 43 +++++++++++++---------- gcc/config/arm/arm.h | 58 ++++++++++++++++++++----------- 4 files changed, 128 insertions(+), 69 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 70a8f0ef96d..a9bdd6c24c5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,21 @@ + 2015-05-13 Christian Bruel + + PR target/52144 + * config/arm/arm.c (arm_option_check_internal) + (arm_option_params_internal): Check opts->target_flags to set macros. + (TREE_TARGET_ARM, TREE_TARGET_THUMB) + (TREE_TARGET_THUMB1, TREE_TARGET_THUMB2) Replace with... + (TARGET_ARM_P, TARGET_THUMB_P, TARGET_THUMB1_P, TARGET_THUMB2_P) + (builtin_define): Replaced with def_or_undef_macro. + * config/arm/arm.h (TREE_TARGET_ARM, TREE_TARGET_THUMB) + TREE_TARGET_THUMB1, TREE_TARGET_THUMB2) Redefine with... + (TARGET_ARM_P, TARGET_THUMB_P, TARGET_THUMB1_P, TARGET_THUMB2_P) + (TARGET_32BIT_P, TARGET_ARM_QBIT_P, TARGET_ARM_SAT_P, TARGET_IDIV_P) + (TARGET_HAVE_LDREX_P, TARGET_HAVE_LDREXBH_P, TARGET_HAVE_LDREXD_P) + (TARGET_ARM_FEATURE_LDREX_P) + (TARGET_DSP_MULTIPLY_P, TARGET_INT_SIMD_P): New macros. + (def_or_undef_macro): New function. + 2015-05-26 Christian Bruel * c-common.h (builtin_define_with_int_value) diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c index 8dfbd78f46c..8f9a867a989 100644 --- a/gcc/config/arm/arm-c.c +++ b/gcc/config/arm/arm-c.c @@ -55,31 +55,49 @@ arm_lang_object_attributes_init (void) #define builtin_define(TXT) cpp_define (pfile, TXT) #define builtin_assert(TXT) cpp_assert (pfile, TXT) +/* Define or undefine macros based on the current target. If the user does + #pragma GCC target, we need to adjust the macros dynamically. */ + +static void +def_or_undef_macro(struct cpp_reader* pfile, const char *name, bool def_p) +{ + if (def_p) + cpp_define (pfile, name); + else + cpp_undef (pfile, name); +} + void arm_cpu_cpp_builtins (struct cpp_reader * pfile) { - if (TARGET_DSP_MULTIPLY) - builtin_define ("__ARM_FEATURE_DSP"); - if (TARGET_ARM_QBIT) - builtin_define ("__ARM_FEATURE_QBIT"); - if (TARGET_ARM_SAT) - builtin_define ("__ARM_FEATURE_SAT"); + int flags = target_flags; + + def_or_undef_macro (pfile, "__ARM_FEATURE_DSP", + TARGET_DSP_MULTIPLY_P (flags)); + def_or_undef_macro (pfile, "__ARM_FEATURE_QBIT", + TARGET_ARM_QBIT_P (flags)); + def_or_undef_macro (pfile, "__ARM_FEATURE_SAT", + TARGET_ARM_SAT_P (flags)); if (TARGET_CRYPTO) builtin_define ("__ARM_FEATURE_CRYPTO"); if (unaligned_access) builtin_define ("__ARM_FEATURE_UNALIGNED"); if (TARGET_CRC32) builtin_define ("__ARM_FEATURE_CRC32"); - if (TARGET_32BIT) - builtin_define ("__ARM_32BIT_STATE"); - if (TARGET_ARM_FEATURE_LDREX) + + def_or_undef_macro (pfile, "__ARM_32BIT_STATE", TARGET_32BIT_P (flags)); + + if (TARGET_ARM_FEATURE_LDREX_P (flags)) builtin_define_with_int_value ("__ARM_FEATURE_LDREX", - TARGET_ARM_FEATURE_LDREX); - if ((TARGET_ARM_ARCH >= 5 && !TARGET_THUMB) - || TARGET_ARM_ARCH_ISA_THUMB >=2) - builtin_define ("__ARM_FEATURE_CLZ"); - if (TARGET_INT_SIMD) - builtin_define ("__ARM_FEATURE_SIMD32"); + TARGET_ARM_FEATURE_LDREX_P (flags)); + else + cpp_undef (pfile, "__ARM_FEATURE_LDREX"); + + def_or_undef_macro (pfile, "__ARM_FEATURE_CLZ", + ((TARGET_ARM_ARCH >= 5 && !TARGET_THUMB_P (flags)) + || TARGET_ARM_ARCH_ISA_THUMB >=2)); + + def_or_undef_macro (pfile, "__ARM_FEATURE_SIMD32", TARGET_INT_SIMD_P (flags)); builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM", flag_short_enums ? 1 : 4); @@ -96,10 +114,14 @@ arm_cpu_cpp_builtins (struct cpp_reader * pfile) if (arm_arch_notm) builtin_define ("__ARM_ARCH_ISA_ARM"); builtin_define ("__APCS_32__"); - if (TARGET_THUMB) - builtin_define ("__thumb__"); - if (TARGET_THUMB2) - builtin_define ("__thumb2__"); + + def_or_undef_macro (pfile, "__thumb__", TARGET_THUMB_P (flags)); + def_or_undef_macro (pfile, "__thumb2__", TARGET_THUMB2_P (flags)); + if (TARGET_BIG_END) + def_or_undef_macro (pfile, "__THUMBEB__", TARGET_THUMB_P (flags)); + else + def_or_undef_macro (pfile, "__THUMBEL__", TARGET_THUMB_P (flags)); + if (TARGET_ARM_ARCH_ISA_THUMB) builtin_define_with_int_value ("__ARM_ARCH_ISA_THUMB", TARGET_ARM_ARCH_ISA_THUMB); @@ -108,14 +130,10 @@ arm_cpu_cpp_builtins (struct cpp_reader * pfile) { builtin_define ("__ARMEB__"); builtin_define ("__ARM_BIG_ENDIAN"); - if (TARGET_THUMB) - builtin_define ("__THUMBEB__"); } else { builtin_define ("__ARMEL__"); - if (TARGET_THUMB) - builtin_define ("__THUMBEL__"); } if (TARGET_SOFT_FLOAT) @@ -166,11 +184,11 @@ arm_cpu_cpp_builtins (struct cpp_reader * pfile) builtin_define ("__ARM_PCS"); builtin_define ("__ARM_EABI__"); } - if (TARGET_IDIV) - { - builtin_define ("__ARM_ARCH_EXT_IDIV__"); - builtin_define ("__ARM_FEATURE_IDIV"); - } - if (inline_asm_unified) - builtin_define ("__ARM_ASM_SYNTAX_UNIFIED__"); + + + + def_or_undef_macro (pfile, "__ARM_ARCH_EXT_IDIV__", TARGET_IDIV_P (flags)); + def_or_undef_macro (pfile, "__ARM_FEATURE_IDIV", TARGET_IDIV_P (flags)); + + def_or_undef_macro (pfile, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified); } diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index fa9543138bc..888813b9c43 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2702,35 +2702,37 @@ arm_gimplify_va_arg_expr (tree valist, tree type, gimple_seq *pre_p, static void arm_option_check_internal (struct gcc_options *opts) { + int flags = opts->x_target_flags; + /* Make sure that the processor choice does not conflict with any of the other command line choices. */ - if (TREE_TARGET_ARM (opts) && !(insn_flags & FL_NOTM)) + if (TARGET_ARM_P (flags) && !(insn_flags & FL_NOTM)) error ("target CPU does not support ARM mode"); /* TARGET_BACKTRACE calls leaf_function_p, which causes a crash if done from here where no function is being compiled currently. */ - if ((TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME) && TREE_TARGET_ARM (opts)) + if ((TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME) && TARGET_ARM_P (flags)) warning (0, "enabling backtrace support is only meaningful when compiling for the Thumb"); - if (TREE_TARGET_ARM (opts) && TARGET_CALLEE_INTERWORKING) + if (TARGET_ARM_P (flags) && TARGET_CALLEE_INTERWORKING) warning (0, "enabling callee interworking support is only meaningful when compiling for the Thumb"); /* If this target is normally configured to use APCS frames, warn if they are turned off and debugging is turned on. */ - if (TREE_TARGET_ARM (opts) + if (TARGET_ARM_P (flags) && write_symbols != NO_DEBUG && !TARGET_APCS_FRAME && (TARGET_DEFAULT & MASK_APCS_FRAME)) warning (0, "-g with -mno-apcs-frame may not give sensible debugging"); /* iWMMXt unsupported under Thumb mode. */ - if (TREE_TARGET_THUMB (opts) && TARGET_IWMMXT) + if (TARGET_THUMB_P (flags) && TARGET_IWMMXT) error ("iWMMXt unsupported under Thumb mode"); - if (TARGET_HARD_TP && TREE_TARGET_THUMB1 (opts)) + if (TARGET_HARD_TP && TARGET_THUMB1_P (flags)) error ("can not use -mtp=cp15 with 16-bit Thumb"); - if (TREE_TARGET_THUMB (opts) && TARGET_VXWORKS_RTP && flag_pic) + if (TARGET_THUMB_P (flags) && TARGET_VXWORKS_RTP && flag_pic) { error ("RTP PIC is incompatible with Thumb"); flag_pic = 0; @@ -2739,7 +2741,7 @@ arm_option_check_internal (struct gcc_options *opts) /* We only support -mslow-flash-data on armv7-m targets. */ if (target_slow_flash_data && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em) - || (TREE_TARGET_THUMB1 (opts) || flag_pic || TARGET_NEON))) + || (TARGET_THUMB1_P (flags) || flag_pic || TARGET_NEON))) error ("-mslow-flash-data only supports non-pic code on armv7-m targets"); } @@ -2747,9 +2749,11 @@ arm_option_check_internal (struct gcc_options *opts) static void arm_option_params_internal (struct gcc_options *opts) { + int flags = opts->x_target_flags; + /* If we are not using the default (ARM mode) section anchor offset ranges, then set the correct ranges now. */ - if (TREE_TARGET_THUMB1 (opts)) + if (TARGET_THUMB1_P (flags)) { /* Thumb-1 LDR instructions cannot have negative offsets. Permissible positive offset ranges are 5-bit (for byte loads), @@ -2759,7 +2763,7 @@ arm_option_params_internal (struct gcc_options *opts) targetm.min_anchor_offset = 0; targetm.max_anchor_offset = 127; } - else if (TREE_TARGET_THUMB2 (opts)) + else if (TARGET_THUMB2_P (flags)) { /* The minimum is set such that the total size of the block for a particular anchor is 248 + 1 + 4095 bytes, which is @@ -2780,7 +2784,7 @@ arm_option_params_internal (struct gcc_options *opts) max_insns_skipped = 6; /* For THUMB2, we limit the conditional sequence to one IT block. */ - if (TREE_TARGET_THUMB2 (opts)) + if (TARGET_THUMB2_P (flags)) max_insns_skipped = opts->x_arm_restrict_it ? 1 : 4; } else @@ -2792,13 +2796,13 @@ static void arm_option_override_internal (struct gcc_options *opts, struct gcc_options *opts_set) { - if (TREE_TARGET_THUMB (opts) && !(insn_flags & FL_THUMB)) + if (TARGET_THUMB_P (opts->x_target_flags) && !(insn_flags & FL_THUMB)) { warning (0, "target CPU does not support THUMB instructions"); opts->x_target_flags &= ~MASK_THUMB; } - if (TARGET_APCS_FRAME && TREE_TARGET_THUMB (opts)) + if (TARGET_APCS_FRAME && TARGET_THUMB_P (opts->x_target_flags)) { /* warning (0, "ignoring -mapcs-frame because -mthumb was used"); */ opts->x_target_flags &= ~MASK_APCS_FRAME; @@ -2806,16 +2810,16 @@ arm_option_override_internal (struct gcc_options *opts, /* Callee super interworking implies thumb interworking. Adding this to the flags here simplifies the logic elsewhere. */ - if (TREE_TARGET_THUMB (opts) && TARGET_CALLEE_INTERWORKING) + if (TARGET_THUMB_P (opts->x_target_flags) && TARGET_CALLEE_INTERWORKING) opts->x_target_flags |= MASK_INTERWORK; if (! opts_set->x_arm_restrict_it) opts->x_arm_restrict_it = arm_arch8; - if (!TREE_TARGET_THUMB2 (opts)) + if (!TARGET_THUMB2_P (opts->x_target_flags)) opts->x_arm_restrict_it = 0; - if (TREE_TARGET_THUMB1 (opts)) + if (TARGET_THUMB1_P (opts->x_target_flags)) { /* Don't warn since it's on by default in -O2. */ opts->x_flag_schedule_insns = 0; @@ -2823,7 +2827,8 @@ arm_option_override_internal (struct gcc_options *opts, /* Disable shrink-wrap when optimizing function for size, since it tends to generate additional returns. */ - if (optimize_function_for_size_p (cfun) && TREE_TARGET_THUMB2 (opts)) + if (optimize_function_for_size_p (cfun) + && TARGET_THUMB2_P (opts->x_target_flags)) opts->x_flag_shrink_wrap = false; /* In Thumb1 mode, we emit the epilogue in RTL, but the last insn @@ -2834,12 +2839,12 @@ arm_option_override_internal (struct gcc_options *opts, finding out about it. Therefore, disable fipa-ra in Thumb1 mode. TODO: Accurately model clobbers for epilogue_insns and reenable fipa-ra. */ - if (TREE_TARGET_THUMB1 (opts)) + if (TARGET_THUMB1_P (opts->x_target_flags)) opts->x_flag_ipa_ra = 0; /* Thumb2 inline assembly code should always use unified syntax. This will apply to ARM and Thumb1 eventually. */ - opts->x_inline_asm_unified = TREE_TARGET_THUMB2 (opts); + opts->x_inline_asm_unified = TARGET_THUMB2_P (opts->x_target_flags); } /* Fix up any incompatible options that the user has specified. */ diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 4cdd60d69b4..df0aeb4a825 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -128,12 +128,10 @@ extern void (*arm_lang_output_object_attributes_hook)(void); #endif /* Tree Target Specification. */ -#define TREE_TARGET_THUMB(opts) (TARGET_THUMB_P (opts->x_target_flags)) -#define TREE_TARGET_ARM(opts) (!TARGET_THUMB_P (opts->x_target_flags)) -#define TREE_TARGET_THUMB1(opts) (TARGET_THUMB_P (opts->x_target_flags) \ - && !arm_arch_thumb2) -#define TREE_TARGET_THUMB2(opts) (TARGET_THUMB_P (opts->x_target_flags) \ - && arm_arch_thumb2) +#define TARGET_ARM_P(flags) (!TARGET_THUMB_P (flags)) +#define TARGET_THUMB1_P(flags) (TARGET_THUMB_P (flags) && !arm_arch_thumb2) +#define TARGET_THUMB2_P(flags) (TARGET_THUMB_P (flags) && arm_arch_thumb2) + /* Run-time Target Specification. */ #define TARGET_SOFT_FLOAT (arm_float_abi == ARM_FLOAT_ABI_SOFT) /* Use hardware floating point instructions. */ @@ -162,6 +160,8 @@ extern void (*arm_lang_output_object_attributes_hook)(void); #define TARGET_THUMB1 (TARGET_THUMB && !arm_arch_thumb2) /* Arm or Thumb-2 32-bit code. */ #define TARGET_32BIT (TARGET_ARM || arm_arch_thumb2) +#define TARGET_32BIT_P(flags) (TARGET_ARM_P (flags) \ + || arm_arch_thumb2) /* 32-bit Thumb-2 code. */ #define TARGET_THUMB2 (TARGET_THUMB && arm_arch_thumb2) /* Thumb-1 only. */ @@ -216,17 +216,21 @@ extern void (*arm_lang_output_object_attributes_hook)(void); && TARGET_VFP && arm_fpu_desc->neon) /* Q-bit is present. */ -#define TARGET_ARM_QBIT \ - (TARGET_32BIT && arm_arch5e && (arm_arch_notm || arm_arch7)) +#define TARGET_ARM_QBIT_P(flags) \ + (TARGET_32BIT_P (flags) && arm_arch5e && (arm_arch_notm || arm_arch7)) +#define TARGET_ARM_QBIT TARGET_ARM_QBIT_P(target_flags) /* Saturation operation, e.g. SSAT. */ -#define TARGET_ARM_SAT \ - (TARGET_32BIT && arm_arch6 && (arm_arch_notm || arm_arch7)) +#define TARGET_ARM_SAT_P(flags) \ + (TARGET_32BIT_P (flags) && arm_arch6 && (arm_arch_notm || arm_arch7)) +#define TARGET_ARM_SAT TARGET_ARM_SAT_P(target_flags) /* "DSP" multiply instructions, eg. SMULxy. */ -#define TARGET_DSP_MULTIPLY \ - (TARGET_32BIT && arm_arch5e && (arm_arch_notm || arm_arch7em)) +#define TARGET_DSP_MULTIPLY_P(flags) \ + (TARGET_32BIT_P (flags) && arm_arch5e && (arm_arch_notm || arm_arch7em)) +#define TARGET_DSP_MULTIPLY TARGET_DSP_MULTIPLY_P(target_flags) /* Integer SIMD instructions, and extend-accumulate instructions. */ -#define TARGET_INT_SIMD \ - (TARGET_32BIT && arm_arch6 && (arm_arch_notm || arm_arch7em)) +#define TARGET_INT_SIMD_P(flags) \ + (TARGET_32BIT_P (flags) && arm_arch6 && (arm_arch_notm || arm_arch7em)) +#define TARGET_INT_SIMD TARGET_INT_SIMD_P(target_flags) /* Should MOVW/MOVT be used in preference to a constant pool. */ #define TARGET_USE_MOVT \ @@ -249,21 +253,30 @@ extern void (*arm_lang_output_object_attributes_hook)(void); #define TARGET_HAVE_MEMORY_BARRIER (TARGET_HAVE_DMB || TARGET_HAVE_DMB_MCR) /* Nonzero if this chip supports ldrex and strex */ -#define TARGET_HAVE_LDREX ((arm_arch6 && TARGET_ARM) || arm_arch7) +#define TARGET_HAVE_LDREX_P(flags) ((arm_arch6 && TARGET_ARM_P (flags)) \ + || arm_arch7) +#define TARGET_HAVE_LDREX TARGET_HAVE_LDREX_P (target_flags) /* Nonzero if this chip supports ldrex{bh} and strex{bh}. */ -#define TARGET_HAVE_LDREXBH ((arm_arch6k && TARGET_ARM) || arm_arch7) +#define TARGET_HAVE_LDREXBH_P(flags) ((arm_arch6k && TARGET_ARM_P (flags)) \ + || arm_arch7) +#define TARGET_HAVE_LDREXBH TARGET_HAVE_LDREXBH_P (target_flags) /* Nonzero if this chip supports ldrexd and strexd. */ -#define TARGET_HAVE_LDREXD (((arm_arch6k && TARGET_ARM) || arm_arch7) \ - && arm_arch_notm) +#define TARGET_HAVE_LDREXD_P(flags) (((arm_arch6k && TARGET_ARM_P (flags)) \ + || arm_arch7) && arm_arch_notm) +#define TARGET_HAVE_LDREXD TARGET_HAVE_LDREXD_P (target_flags) + /* Nonzero if this chip supports load-acquire and store-release. */ #define TARGET_HAVE_LDACQ (TARGET_ARM_ARCH >= 8) /* Nonzero if integer division instructions supported. */ -#define TARGET_IDIV ((TARGET_ARM && arm_arch_arm_hwdiv) \ - || (TARGET_THUMB2 && arm_arch_thumb_hwdiv)) +#define TARGET_IDIV_P(flags) ((TARGET_ARM_P (flags) && arm_arch_arm_hwdiv) \ + || (TARGET_THUMB2_P (flags) \ + && arm_arch_thumb_hwdiv)) +#define TARGET_IDIV TARGET_IDIV_P (target_flags) + /* Nonzero if disallow volatile memory access in IT block. */ #define TARGET_NO_VOLATILE_CE (arm_arch_no_volatile_ce) @@ -2189,6 +2202,11 @@ extern int making_const_table; | (TARGET_HAVE_LDREXBH ? 3 : 0) \ | (TARGET_HAVE_LDREXD ? 8 : 0)) +#define TARGET_ARM_FEATURE_LDREX_P(flags) \ + ((TARGET_HAVE_LDREX_P (flags) ? 4 : 0) \ + | (TARGET_HAVE_LDREXBH_P (flags) ? 3 : 0) \ + | (TARGET_HAVE_LDREXD_P (flags) ? 8 : 0)) + /* Set as a bit mask indicating the available widths of hardware floating point types. Where bit 1 indicates 16-bit support, bit 2 indicates 32-bit support, bit 3 indicates 64-bit support. */ -- 2.30.2