* ping: [PATCH, ARM] attribute target (thumb,arm) [0-6]
@ 2015-02-09 12:34 Christian Bruel
2015-02-09 12:45 ` Christian Bruel
2015-04-14 19:11 ` Ramana Radhakrishnan
0 siblings, 2 replies; 8+ messages in thread
From: Christian Bruel @ 2015-02-09 12:34 UTC (permalink / raw)
To: Ramana Radhakrishnan, richard Earnshaw; +Cc: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 983 bytes --]
Hello,
I'd like to ping with a respin of the 7 patches for
the attribute target (thumb,arm) [0-6] :
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02455.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02458.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02460.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02461.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02463.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02467.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02468.html
In order to fix the various conflicts that have happened since, please
find attached the re-based patches to trunk rev #220529 (respectively
from above p0.patch, p1.patch, p2,patch, p3.patch, p4,patch, p5,patch,
p6,patch).
I understand the difficulty of reviewing those due to the code
reorganization, but maintaining them are really a pain since a conflict
happens at almost every update in the ARM back-end :-(
Comments, questions are welcome,
Many thanks
Christian
[-- Attachment #2: p0.patch --]
[-- Type: text/x-patch, Size: 7687 bytes --]
Index: gcc/ChangeLog
===================================================================
--- gcc/ChangeLog (revision 220436)
+++ gcc/ChangeLog (working copy)
@@ -1,3 +1,11 @@
+2015-02-06 Christian Bruel <christian.bruel@st.com>
+
+ PR target/64835
+ * config/i386/i386.c (ix86_default_align): New function.
+ (ix86_override_options_after_change): Call ix86_default_align.
+ (TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE): New hook.
+ (ix86_override_options_after_change): New function.
+
2015-02-04 Jan Hubicka <hubicka@ucw.cz>
Trevor Saunders <tsaunders@mozilla.com>
Index: gcc/config/i386/i386.c
===================================================================
--- gcc/config/i386/i386.c (revision 220436)
+++ gcc/config/i386/i386.c (working copy)
@@ -3105,6 +3105,35 @@
}
+/* Default align_* from the processor table. */
+
+static void
+ix86_default_align (struct gcc_options *opts)
+{
+ if (opts->x_align_loops == 0)
+ {
+ opts->x_align_loops = processor_target_table[ix86_tune].align_loop;
+ align_loops_max_skip = processor_target_table[ix86_tune].align_loop_max_skip;
+ }
+ if (opts->x_align_jumps == 0)
+ {
+ opts->x_align_jumps = processor_target_table[ix86_tune].align_jump;
+ align_jumps_max_skip = processor_target_table[ix86_tune].align_jump_max_skip;
+ }
+ if (opts->x_align_functions == 0)
+ {
+ opts->x_align_functions = processor_target_table[ix86_tune].align_func;
+ }
+}
+
+/* Implement TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE hook. */
+
+static void
+ix86_override_options_after_change (void)
+{
+ ix86_default_align (&global_options);
+}
+
/* Override various settings based on options. If MAIN_ARGS_P, the
options are from the command line, otherwise they are from
attributes. */
@@ -3902,20 +3931,7 @@
opts->x_ix86_regparm = REGPARM_MAX;
/* Default align_* from the processor table. */
- if (opts->x_align_loops == 0)
- {
- opts->x_align_loops = processor_target_table[ix86_tune].align_loop;
- align_loops_max_skip = processor_target_table[ix86_tune].align_loop_max_skip;
- }
- if (opts->x_align_jumps == 0)
- {
- opts->x_align_jumps = processor_target_table[ix86_tune].align_jump;
- align_jumps_max_skip = processor_target_table[ix86_tune].align_jump_max_skip;
- }
- if (opts->x_align_functions == 0)
- {
- opts->x_align_functions = processor_target_table[ix86_tune].align_func;
- }
+ ix86_default_align (opts);
/* Provide default for -mbranch-cost= value. */
if (!opts_set->x_ix86_branch_cost)
@@ -51928,6 +51944,9 @@
#undef TARGET_PROMOTE_FUNCTION_MODE
#define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
+#undef TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE
+#define TARGET_OVERRIDE_OPTIONS_AFTER_CHANGE ix86_override_options_after_change
+
#undef TARGET_MEMBER_TYPE_FORCES_BLK
#define TARGET_MEMBER_TYPE_FORCES_BLK ix86_member_type_forces_blk
Index: gcc/dwarf2cfi.c
===================================================================
--- gcc/dwarf2cfi.c (revision 220436)
+++ gcc/dwarf2cfi.c (working copy)
@@ -2941,7 +2941,6 @@
dw_trace_info cie_trace;
dw_stack_pointer_regnum = DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM);
- dw_frame_pointer_regnum = DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM);
memset (&cie_trace, 0, sizeof (cie_trace));
cur_trace = &cie_trace;
@@ -2994,6 +2993,9 @@
static unsigned int
execute_dwarf2_frame (void)
{
+ /* Different HARD_FRAME_POINTER_REGNUM might coexist in the same file. */
+ dw_frame_pointer_regnum = DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM);
+
/* The first time we're called, compute the incoming frame state. */
if (cie_cfi_vec == NULL)
create_cie_data ();
Index: gcc/ipa-inline.c
===================================================================
--- gcc/ipa-inline.c (revision 220436)
+++ gcc/ipa-inline.c (working copy)
@@ -489,7 +489,7 @@
else if (opt_for_fn (callee->decl, optimize_size)
< opt_for_fn (caller->decl, optimize_size)
|| (opt_for_fn (callee->decl, optimize)
- >= opt_for_fn (caller->decl, optimize)))
+ > opt_for_fn (caller->decl, optimize)))
{
if (estimate_edge_time (e)
>= 20 + inline_edge_summary (e)->call_stmt_time)
Index: gcc/ipa-prop.c
===================================================================
--- gcc/ipa-prop.c (revision 220436)
+++ gcc/ipa-prop.c (working copy)
@@ -178,19 +178,6 @@
static alloc_pool ipa_refdesc_pool;
-/* Return true if DECL_FUNCTION_SPECIFIC_OPTIMIZATION of the decl associated
- with NODE should prevent us from analyzing it for the purposes of IPA-CP. */
-
-static bool
-ipa_func_spec_opts_forbid_analysis_p (struct cgraph_node *node)
-{
- tree fs_opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (node->decl);
-
- if (!fs_opts)
- return false;
- return !opt_for_fn (node->decl, optimize) || !opt_for_fn (node->decl, flag_ipa_cp);
-}
-
/* Return index of the formal whose tree is PTREE in function which corresponds
to INFO. */
@@ -1730,8 +1717,6 @@
if (gimple_call_internal_p (call))
return;
- if (ipa_func_spec_opts_forbid_analysis_p (cs->caller))
- return;
for (n = 0; n < arg_num; n++)
{
@@ -2389,16 +2374,6 @@
return;
info->analysis_done = 1;
- if (ipa_func_spec_opts_forbid_analysis_p (node))
- {
- for (int i = 0; i < ipa_get_param_count (info); i++)
- {
- ipa_set_param_used (info, i, true);
- ipa_set_controlled_uses (info, i, IPA_UNDESCRIBED_USE);
- }
- return;
- }
-
struct function *func = DECL_STRUCT_FUNCTION (node->decl);
push_cfun (func);
calculate_dominance_info (CDI_DOMINATORS);
Index: gcc/testsuite/ChangeLog
===================================================================
--- gcc/testsuite/ChangeLog (revision 220436)
+++ gcc/testsuite/ChangeLog (working copy)
@@ -1,3 +1,9 @@
+2015-02-06 Christian Bruel <christian.bruel@st.com>
+
+ PR target/64835
+ * gcc.dg/ipa/iinline-attr.c: New test.
+ * gcc.target/i386/iinline-attr-2.c: New test.
+
2015-02-05 Paul Thomas <pault@gcc.gnu.org>
PR fortran/64757
Index: gcc/testsuite/gcc.dg/ipa/iinline-attr.c
===================================================================
--- gcc/testsuite/gcc.dg/ipa/iinline-attr.c (revision 0)
+++ gcc/testsuite/gcc.dg/ipa/iinline-attr.c (working copy)
@@ -0,0 +1,27 @@
+/* Verify that simple indirect calls are inlined even when
+ attribute __optimize is used. */
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-ipa-inline" } */
+
+extern void non_existent(int);
+
+static void hooray ()
+{
+ non_existent (1);
+}
+
+__attribute__ ((__optimize__ ("O2")))
+static void hiphip (void (*f)())
+{
+ non_existent (2);
+ f ();
+}
+
+int test (void)
+{
+ hiphip (hooray);
+ return 0;
+}
+
+/* { dg-final { scan-ipa-dump "hooray\[^\\n\]*inline copy in test" "inline" } } */
+/* { dg-final { cleanup-ipa-dump "inline" } } */
Index: gcc/testsuite/gcc.target/i386/iinline-attr-2.c
===================================================================
--- gcc/testsuite/gcc.target/i386/iinline-attr-2.c (revision 0)
+++ gcc/testsuite/gcc.target/i386/iinline-attr-2.c (working copy)
@@ -0,0 +1,29 @@
+/* Verify that alignment flags are set when attribute __optimize is used. */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern void non_existent(int);
+
+__attribute__ ((__optimize__ ("O2")))
+static void hooray ()
+{
+ non_existent (1);
+}
+
+__attribute__ ((__optimize__ ("O2")))
+static void hiphip (void (*f)())
+{
+ non_existent (2);
+ f ();
+}
+
+__attribute__ ((__optimize__ ("O2")))
+int test (void)
+{
+ hiphip (hooray);
+ return 0;
+}
+
+/* { dg-final { scan-assembler "p2align" } } */
+
+
[-- Attachment #3: p1.patch --]
[-- Type: text/x-patch, Size: 17792 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.h (arm_option_override): Reoganized and split.
(arm_option_params_internal); New function.
(arm_option_check_internal): New function.
(arm_option_override_internal): New function.
(restrict_default): New boolean.
(thumb_code, thumb1_code): Remove.
* config/arm/arm.h (TREE_TARGET_THUMB, TREE_TARGET_THUMB1): New macros.
(TREE_TARGET_THUM2, TREE_TARGET_ARM): Likewise.
(thumb_code, thumb1_code): Remove.
* config/arm/arm.md (is_thumb, is_thumb1): Check TARGET flag.
diff -ruN '--exclude=.svn' a/gcc/gcc/config/arm/arm.c a1/gcc/gcc/config/arm/arm.c
--- a/gcc/gcc/config/arm/arm.c 2015-02-04 09:14:26.120602737 +0100
+++ a1/gcc/gcc/config/arm/arm.c 2015-02-05 09:19:32.853338616 +0100
@@ -846,12 +846,6 @@
/* Nonzero if tuning for Cortex-A9. */
int arm_tune_cortex_a9 = 0;
-/* Nonzero if generating Thumb instructions. */
-int thumb_code = 0;
-
-/* Nonzero if generating Thumb-1 instructions. */
-int thumb1_code = 0;
-
/* Nonzero if we should define __THUMB_INTERWORK__ in the
preprocessor.
XXX This is a bit of a hack, it's intended to help work around
@@ -2623,6 +2617,148 @@
return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
}
+/* Check any incompatible options that the user has specified. */
+static void
+arm_option_check_internal (struct gcc_options *opts)
+{
+ /* 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))
+ 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))
+ warning (0, "enabling backtrace support is only meaningful when compiling for the Thumb");
+
+ if (TREE_TARGET_ARM (opts) && 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)
+ && 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)
+ error ("iWMMXt unsupported under Thumb mode");
+
+ if (TARGET_HARD_TP && TREE_TARGET_THUMB1 (opts))
+ error ("can not use -mtp=cp15 with 16-bit Thumb");
+
+ if (TREE_TARGET_THUMB (opts) && TARGET_VXWORKS_RTP && flag_pic)
+ {
+ error ("RTP PIC is incompatible with Thumb");
+ 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)
+ || (TREE_TARGET_THUMB1 (opts) || flag_pic || TARGET_NEON)))
+ error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
+}
+
+/* Check any params depending on attributes that the user has specified. */
+static void
+arm_option_params_internal (struct gcc_options *opts)
+{
+ /* If we are not using the default (ARM mode) section anchor offset
+ ranges, then set the correct ranges now. */
+ if (TREE_TARGET_THUMB1 (opts))
+ {
+ /* Thumb-1 LDR instructions cannot have negative offsets.
+ Permissible positive offset ranges are 5-bit (for byte loads),
+ 6-bit (for halfword loads), or 7-bit (for word loads).
+ Empirical results suggest a 7-bit anchor range gives the best
+ overall code size. */
+ targetm.min_anchor_offset = 0;
+ targetm.max_anchor_offset = 127;
+ }
+ else if (TREE_TARGET_THUMB2 (opts))
+ {
+ /* The minimum is set such that the total size of the block
+ for a particular anchor is 248 + 1 + 4095 bytes, which is
+ divisible by eight, ensuring natural spacing of anchors. */
+ targetm.min_anchor_offset = -248;
+ targetm.max_anchor_offset = 4095;
+ }
+ else
+ {
+ targetm.min_anchor_offset = TARGET_MIN_ANCHOR_OFFSET;
+ targetm.max_anchor_offset = TARGET_MAX_ANCHOR_OFFSET;
+ }
+
+ if (optimize_size)
+ {
+ /* If optimizing for size, bump the number of instructions that we
+ are prepared to conditionally execute (even on a StrongARM). */
+ max_insns_skipped = 6;
+
+ /* For THUMB2, we limit the conditional sequence to one IT block. */
+ if (TREE_TARGET_THUMB2 (opts))
+ max_insns_skipped = opts->x_arm_restrict_it ? 1 : 4;
+ }
+}
+
+/* Reset options between modes that the user has specified. */
+static void
+arm_option_override_internal (struct gcc_options *opts,
+ struct gcc_options *opts_set)
+{
+ if (TREE_TARGET_THUMB (opts) && !(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))
+ {
+ /* warning (0, "ignoring -mapcs-frame because -mthumb was used"); */
+ opts->x_target_flags &= ~MASK_APCS_FRAME;
+ }
+
+ /* Callee super interworking implies thumb interworking. Adding
+ this to the flags here simplifies the logic elsewhere. */
+ if (TREE_TARGET_THUMB (opts) && 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))
+ opts->x_arm_restrict_it = 0;
+
+ if (TREE_TARGET_THUMB1 (opts))
+ {
+ /* Don't warn since it's on by default in -O2. */
+ opts->x_flag_schedule_insns = 0;
+ }
+
+ /* 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))
+ opts->x_flag_shrink_wrap = false;
+
+ /* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
+ - epilogue_insns - does not accurately model the corresponding insns
+ emitted in the asm file. In particular, see the comment in thumb_exit
+ 'Find out how many of the (return) argument registers we can corrupt'.
+ As a consequence, the epilogue may clobber registers without fipa-ra
+ 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))
+ 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);
+}
+
/* Fix up any incompatible options that the user has specified. */
static void
arm_option_override (void)
@@ -2769,10 +2905,9 @@
tune_flags = arm_selected_tune->flags;
current_tune = arm_selected_tune->tune;
- /* Make sure that the processor choice does not conflict with any of the
- other command line choices. */
- if (TARGET_ARM && !(insn_flags & FL_NOTM))
- error ("target CPU does not support ARM mode");
+ /* TBD: Dwarf info for apcs frame is not handled yet. */
+ if (TARGET_APCS_FRAME)
+ flag_shrink_wrap = false;
/* BPABI targets use linker tricks to allow interworking on cores
without thumb support. */
@@ -2782,31 +2917,6 @@
target_flags &= ~MASK_INTERWORK;
}
- if (TARGET_THUMB && !(insn_flags & FL_THUMB))
- {
- warning (0, "target CPU does not support THUMB instructions");
- target_flags &= ~MASK_THUMB;
- }
-
- if (TARGET_APCS_FRAME && TARGET_THUMB)
- {
- /* warning (0, "ignoring -mapcs-frame because -mthumb was used"); */
- target_flags &= ~MASK_APCS_FRAME;
- }
-
- /* Callee super interworking implies thumb interworking. Adding
- this to the flags here simplifies the logic elsewhere. */
- if (TARGET_THUMB && TARGET_CALLEE_INTERWORKING)
- target_flags |= MASK_INTERWORK;
-
- /* 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) && TARGET_ARM)
- warning (0, "enabling backtrace support is only meaningful when compiling for the Thumb");
-
- if (TARGET_ARM && TARGET_CALLEE_INTERWORKING)
- warning (0, "enabling callee interworking support is only meaningful when compiling for the Thumb");
-
if (TARGET_APCS_STACK && !TARGET_APCS_FRAME)
{
warning (0, "-mapcs-stack-check incompatible with -mno-apcs-frame");
@@ -2822,14 +2932,6 @@
if (TARGET_APCS_REENT)
warning (0, "APCS reentrant code not supported. Ignored");
- /* If this target is normally configured to use APCS frames, warn if they
- are turned off and debugging is turned on. */
- if (TARGET_ARM
- && write_symbols != NO_DEBUG
- && !TARGET_APCS_FRAME
- && (TARGET_DEFAULT & MASK_APCS_FRAME))
- warning (0, "-g with -mno-apcs-frame may not give sensible debugging");
-
if (TARGET_APCS_FLOAT)
warning (0, "passing floating point arguments in fp regs not yet supported");
@@ -2851,8 +2953,6 @@
arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
arm_tune_strongarm = (tune_flags & FL_STRONG) != 0;
- thumb_code = TARGET_ARM == 0;
- thumb1_code = TARGET_THUMB1 != 0;
arm_tune_wbuf = (tune_flags & FL_WBUF) != 0;
arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
@@ -2862,32 +2962,6 @@
arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0;
arm_arch_crc = (insn_flags & FL_CRC32) != 0;
arm_m_profile_small_mul = (insn_flags & FL_SMALLMUL) != 0;
- if (arm_restrict_it == 2)
- arm_restrict_it = arm_arch8 && TARGET_THUMB2;
-
- if (!TARGET_THUMB2)
- arm_restrict_it = 0;
-
- /* If we are not using the default (ARM mode) section anchor offset
- ranges, then set the correct ranges now. */
- if (TARGET_THUMB1)
- {
- /* Thumb-1 LDR instructions cannot have negative offsets.
- Permissible positive offset ranges are 5-bit (for byte loads),
- 6-bit (for halfword loads), or 7-bit (for word loads).
- Empirical results suggest a 7-bit anchor range gives the best
- overall code size. */
- targetm.min_anchor_offset = 0;
- targetm.max_anchor_offset = 127;
- }
- else if (TARGET_THUMB2)
- {
- /* The minimum is set such that the total size of the block
- for a particular anchor is 248 + 1 + 4095 bytes, which is
- divisible by eight, ensuring natural spacing of anchors. */
- targetm.min_anchor_offset = -248;
- targetm.max_anchor_offset = 4095;
- }
/* V5 code we generate is completely interworking capable, so we turn off
TARGET_INTERWORK here to avoid many tests later on. */
@@ -2906,6 +2980,9 @@
if (TARGET_IWMMXT_ABI && !TARGET_IWMMXT)
error ("iwmmxt abi requires an iwmmxt capable cpu");
+ if (! optimize_size)
+ max_insns_skipped = current_tune->max_insns_skipped;
+
if (!global_options_set.x_arm_fpu_index)
{
const char *target_fpu_name;
@@ -2947,10 +3024,6 @@
if (TARGET_IWMMXT && TARGET_NEON)
error ("iWMMXt and NEON are incompatible");
- /* iWMMXt unsupported under Thumb mode. */
- if (TARGET_THUMB && TARGET_IWMMXT)
- error ("iWMMXt unsupported under Thumb mode");
-
/* __fp16 support currently assumes the core has ldrh. */
if (!arm_arch4 && arm_fp16_format != ARM_FP16_FORMAT_NONE)
sorry ("__fp16 and no ldrh");
@@ -2995,9 +3068,6 @@
target_thread_pointer = TP_SOFT;
}
- if (TARGET_HARD_TP && TARGET_THUMB1)
- error ("can not use -mtp=cp15 with 16-bit Thumb");
-
/* Override the default structure alignment for AAPCS ABI. */
if (!global_options_set.x_arm_structure_size_boundary)
{
@@ -3020,12 +3090,6 @@
}
}
- if (!TARGET_ARM && TARGET_VXWORKS_RTP && flag_pic)
- {
- error ("RTP PIC is incompatible with Thumb");
- flag_pic = 0;
- }
-
/* If stack checking is disabled, we can use r10 as the PIC register,
which keeps r9 available. The EABI specifies r9 as the PIC register. */
if (flag_pic && TARGET_SINGLE_PIC_BASE)
@@ -3093,25 +3157,6 @@
unaligned_access = 0;
}
- if (TARGET_THUMB1 && flag_schedule_insns)
- {
- /* Don't warn since it's on by default in -O2. */
- flag_schedule_insns = 0;
- }
-
- if (optimize_size)
- {
- /* If optimizing for size, bump the number of instructions that we
- are prepared to conditionally execute (even on a StrongARM). */
- max_insns_skipped = 6;
-
- /* For THUMB2, we limit the conditional sequence to one IT block. */
- if (TARGET_THUMB2)
- max_insns_skipped = MAX_INSN_PER_IT_BLOCK;
- }
- else
- max_insns_skipped = current_tune->max_insns_skipped;
-
/* Hot/Cold partitioning is not currently supported, since we can't
handle literal pool placement in that case. */
if (flag_reorder_blocks_and_partition)
@@ -3189,45 +3234,19 @@
global_options.x_param_values,
global_options_set.x_param_values);
- /* Disable shrink-wrap when optimizing function for size, since it tends to
- generate additional returns. */
- if (optimize_function_for_size_p (cfun) && TARGET_THUMB2)
- flag_shrink_wrap = false;
- /* TBD: Dwarf info for apcs frame is not handled yet. */
- if (TARGET_APCS_FRAME)
- flag_shrink_wrap = false;
-
- /* We only support -mslow-flash-data on armv7-m targets. */
- if (target_slow_flash_data
- && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
- || (TARGET_THUMB1 || flag_pic || TARGET_NEON)))
- error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
-
/* Currently, for slow flash data, we just disable literal pools. */
if (target_slow_flash_data)
arm_disable_literal_pool = true;
- /* Thumb2 inline assembly code should always use unified syntax.
- This will apply to ARM and Thumb1 eventually. */
- if (TARGET_THUMB2)
- inline_asm_unified = 1;
-
/* Disable scheduling fusion by default if it's not armv7 processor
or doesn't prefer ldrd/strd. */
if (flag_schedule_fusion == 2
&& (!arm_arch7 || !current_tune->prefer_ldrd_strd))
flag_schedule_fusion = 0;
- /* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
- - epilogue_insns - does not accurately model the corresponding insns
- emitted in the asm file. In particular, see the comment in thumb_exit
- 'Find out how many of the (return) argument registers we can corrupt'.
- As a consequence, the epilogue may clobber registers without fipa-ra
- finding out about it. Therefore, disable fipa-ra in Thumb1 mode.
- TODO: Accurately model clobbers for epilogue_insns and reenable
- fipa-ra. */
- if (TARGET_THUMB1)
- flag_ipa_ra = 0;
+ arm_option_override_internal (&global_options, &global_options_set);
+ arm_option_check_internal (&global_options);
+ arm_option_params_internal (&global_options);
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
diff -ruN '--exclude=.svn' a/gcc/gcc/config/arm/arm.h a1/gcc/gcc/config/arm/arm.h
--- a/gcc/gcc/config/arm/arm.h 2015-01-20 15:58:49.230503992 +0100
+++ a1/gcc/gcc/config/arm/arm.h 2015-01-22 13:48:29.338437070 +0100
@@ -252,5 +252,12 @@
#define SUBTARGET_CPP_SPEC ""
#endif
\f
+/* 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)
/* Run-time Target Specification. */
#define TARGET_SOFT_FLOAT (arm_float_abi == ARM_FLOAT_ABI_SOFT)
/* Use hardware floating point instructions. */
@@ -525,12 +532,6 @@
/* Nonzero if this chip can benefit from load scheduling. */
extern int arm_ld_sched;
-/* Nonzero if generating Thumb code, either Thumb-1 or Thumb-2. */
-extern int thumb_code;
-
-/* Nonzero if generating Thumb-1 code. */
-extern int thumb1_code;
-
/* Nonzero if this chip is a StrongARM. */
extern int arm_tune_strongarm;
diff -ruN '--exclude=.svn' a/gcc/gcc/config/arm/arm.md a1/gcc/gcc/config/arm/arm.md
--- a/gcc/gcc/config/arm/arm.md 2015-01-26 11:04:05.937275841 +0100
+++ a1/gcc/gcc/config/arm/arm.md 2015-02-05 09:19:32.857338621 +0100
@@ -69,13 +69,17 @@
; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
; generating ARM code. This is used to control the length of some insn
; patterns that share the same RTL in both ARM and Thumb code.
-(define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
+(define_attr "is_thumb" "yes,no"
+ (const (if_then_else (symbol_ref "TARGET_THUMB")
+ (const_string "yes") (const_string "no"))))
; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
(define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
-(define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
+(define_attr "is_thumb1" "yes,no"
+ (const (if_then_else (symbol_ref "TARGET_THUMB1")
+ (const_string "yes") (const_string "no"))))
; We use this attribute to disable alternatives that can produce 32-bit
; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
[-- Attachment #4: p2.patch --]
[-- Type: text/x-patch, Size: 6666 bytes --]
Christian Bruel <christian.bruel@st.com>
* config/arm/arm-c.c (cpp_def_or_undef): New functions.
(arm_cpp_builtins): Likewise.
* config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Move mode dependant
macros to arm_cpp_builtins.
* config/arm/arm-protos.h (arm_cpp_builtins): Declare.
diff -ruN '--exclude=.svn' a1/gcc/gcc/config/arm/arm-c.c a2/gcc/gcc/config/arm/arm-c.c
--- a1/gcc/gcc/config/arm/arm-c.c 2015-01-13 12:34:38.910459998 +0100
+++ a2/gcc/gcc/config/arm/arm-c.c 2015-01-15 13:32:30.683013516 +0100
@@ -51,3 +51,73 @@
{
arm_lang_output_object_attributes_hook = arm_output_c_attributes;
}
+
+/* Define or undefine macro. */
+
+static void
+cpp_def_or_undef (struct cpp_reader *in, const char *str, bool def_p)
+{
+ if (def_p)
+ cpp_define (in, str);
+ else
+ cpp_undef (in, str);
+}
+
+/* Define or undefine macros based on the current target. If the user does
+ #pragma GCC target, we need to adjust the macros dynamically. */
+
+void
+arm_cpp_builtins (struct cpp_reader *in, bool thumb_p)
+{
+ bool target_32bit_p = !thumb_p || arm_arch_thumb2;
+ bool thumb2_p = thumb_p && arm_arch_thumb2;
+ bool have_ldrex_p = (arm_arch6 && !thumb_p) || arm_arch7;
+ bool have_ldrexbh_p = (arm_arch6k && !thumb_p) || arm_arch7;
+ bool have_ldrexd_p = ((arm_arch6k && !thumb_p) || arm_arch7)
+ && arm_arch_notm;
+
+ int arm_feature_ldrex = (have_ldrex_p ? 4 : 0)
+ | (have_ldrexbh_p ? 3 : 0) | (have_ldrexd_p ? 8 : 0);
+
+ cpp_def_or_undef (in, "__thumb__", thumb_p);
+ if (arm_arch_thumb2)
+ cpp_def_or_undef (in, "__thumb2__", thumb_p);
+ if (TARGET_BIG_END)
+ cpp_def_or_undef (in, "__THUMBEB__", thumb_p);
+ else
+ cpp_def_or_undef (in, "__THUMBEL__", thumb_p);
+
+ cpp_def_or_undef (in, "__ARM_32BIT_STATE", target_32bit_p); /* TARGET_32BIT */
+
+ if (arm_arch5e && (arm_arch_notm || arm_arch7)) /* TARGET_ARM_QBIT */
+ cpp_def_or_undef (in, "__ARM_FEATURE_QBIT", target_32bit_p);
+
+ if (arm_arch6 && (arm_arch_notm || arm_arch7)) /* TARGET_ARM_SAT */
+ cpp_def_or_undef (in, "__ARM_FEATURE_SAT", target_32bit_p);
+
+ if (arm_arch5e && (arm_arch_notm || arm_arch7em)) /* TARGET_DSP_MULTIPLY */
+ cpp_def_or_undef (in, "__ARM_FEATURE_DSP", target_32bit_p);
+
+ if (arm_arch6 && (arm_arch_notm || arm_arch7em)) /* TARGET_INT_SIMD */
+ cpp_def_or_undef (in, "__ARM_FEATURE_SIMD32", target_32bit_p);
+
+ /* TARGET_IDIV */
+ cpp_def_or_undef (in, "__ARM_ARCH_EXT_IDIV__",
+ ((!thumb_p && arm_arch_arm_hwdiv)
+ || (thumb2_p && arm_arch_thumb_hwdiv)));
+
+ cpp_def_or_undef (in, "__ARM_FEATURE_IDIV",
+ ((!thumb_p && arm_arch_arm_hwdiv)
+ || (thumb2_p && arm_arch_thumb_hwdiv)));
+
+ if (arm_feature_ldrex)
+ cpp_define_formatted (in, "__ARM_FEATURE_LDREX=%d", arm_feature_ldrex);
+ else
+ cpp_undef (in, "__ARM_FEATURE_LDREX");
+
+ cpp_def_or_undef (in, "__ARM_FEATURE_CLZ",
+ ((TARGET_ARM_ARCH >= 5 && !thumb_p) || TARGET_ARM_ARCH_ISA_THUMB >=2));
+
+ cpp_def_or_undef (in, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified);
+}
+
diff -ruN '--exclude=.svn' a1/gcc/gcc/config/arm/arm.h a2/gcc/gcc/config/arm/arm.h
--- a1/gcc/gcc/config/arm/arm.h 2015-01-22 13:48:29.338437070 +0100
+++ a2/gcc/gcc/config/arm/arm.h 2015-01-22 13:52:58.062879846 +0100
@@ -48,29 +48,12 @@
#define TARGET_CPU_CPP_BUILTINS() \
do \
{ \
- 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"); \
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) \
- 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"); \
- \
builtin_define_with_int_value ( \
"__ARM_SIZEOF_MINIMAL_ENUM", \
flag_short_enums ? 1 : 4); \
@@ -89,10 +72,6 @@
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__"); \
if (TARGET_ARM_ARCH_ISA_THUMB) \
builtin_define_with_int_value ( \
"__ARM_ARCH_ISA_THUMB", \
@@ -102,15 +81,9 @@
{ \
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) \
builtin_define ("__SOFTFP__"); \
@@ -163,13 +136,8 @@
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__");\
+ /* Remaining macros depends on TARGET_THUMB. */\
+ arm_cpp_builtins (pfile, TARGET_THUMB); \
} while (0)
#include "config/arm/arm-opts.h"
diff -ruN '--exclude=.svn' a1/gcc/gcc/config/arm/arm-protos.h a2/gcc/gcc/config/arm/arm-protos.h
--- a1/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:48:29.342437077 +0100
+++ a2/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:52:58.098879905 +0100
@@ -222,8 +222,6 @@
extern void arm_pr_no_long_calls (struct cpp_reader *);
extern void arm_pr_long_calls_off (struct cpp_reader *);
-extern void arm_lang_object_attributes_init(void);
-
extern const char *arm_mangle_type (const_tree);
extern const char *arm_mangle_builtin_type (const_tree);
@@ -323,6 +321,10 @@
/* Defined in gcc/common/config/arm-common.c. */
extern const char *arm_rewrite_selected_cpu (const char *name);
+/* Defined in gcc/common/config/arm-c.c. */
+extern void arm_lang_object_attributes_init(void);
+extern void arm_cpp_builtins (struct cpp_reader *, bool);
+
extern bool arm_is_constant_pool_ref (rtx);
/* Flags used to identify the presence of processor capabilities. */
[-- Attachment #5: p3.patch --]
[-- Type: text/x-patch, Size: 4793 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm-protos.h (arm_declare_function_name): Declare.
(is_called_in_ARM_mode): Remove.
* config/arm/arm.c (is_called_in_ARM_mode): Declare static bool.
(arm_declare_function_name): Moved from from ARM_DECLARE_FUNCTION_NAME.
* config/arm/arm.h (ARM_DECLARE_FUNCTION_NAME): Call
arm_declare_function_name.
diff -ruN '--exclude=.svn' a2/gcc/gcc/config/arm/arm.c a3/gcc/gcc/config/arm/arm.c
--- a2/gcc/gcc/config/arm/arm.c 2015-02-05 09:20:13.225397216 +0100
+++ a3/gcc/gcc/config/arm/arm.c 2015-02-05 09:20:12.653396291 +0100
@@ -23645,6 +23645,23 @@
fprintf (f, "}\n");
}
+/* Return nonzero if FUNC must be entered in ARM mode. */
+static bool
+is_called_in_ARM_mode (tree func)
+{
+ gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
+
+ /* Ignore the problem about functions whose address is taken. */
+ if (TARGET_CALLEE_INTERWORKING && TREE_PUBLIC (func))
+ return true;
+
+#ifdef ARM_PE
+ return lookup_attribute ("interfacearm", DECL_ATTRIBUTES (func)) != NULL_TREE;
+#else
+ return false;
+#endif
+}
+
/* Generate code to return from a thumb function.
If 'reg_containing_return_addr' is -1, then the return address is
actually on the stack, at the stack pointer. */
@@ -24080,22 +24097,6 @@
return 0;
}
-/* Return nonzero if FUNC must be entered in ARM mode. */
-int
-is_called_in_ARM_mode (tree func)
-{
- gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
-
- /* Ignore the problem about functions whose address is taken. */
- if (TARGET_CALLEE_INTERWORKING && TREE_PUBLIC (func))
- return TRUE;
-
-#ifdef ARM_PE
- return lookup_attribute ("interfacearm", DECL_ATTRIBUTES (func)) != NULL_TREE;
-#else
- return FALSE;
-#endif
-}
/* Given the stack offsets and register mask in OFFSETS, decide how
many additional registers to push instead of subtracting a constant
@@ -29435,6 +29436,25 @@
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
}
+void
+arm_declare_function_name (FILE *stream, const char *name, tree decl)
+{
+ if (TARGET_THUMB)
+ {
+ if (is_called_in_ARM_mode (decl)
+ || (TARGET_THUMB1 && !TARGET_THUMB1_ONLY
+ && cfun->is_thunk))
+ fprintf (stream, "\t.code 32\n");
+ else if (TARGET_THUMB1)
+ fprintf (stream, "\t.code\t16\n\t.thumb_func\n");
+ else
+ fprintf (stream, "\t.thumb\n\t.thumb_func\n");
+ }
+
+ if (TARGET_POKE_FUNCTION_NAME)
+ arm_poke_function_name (stream, (const char *) name);
+}
+
/* If MEM is in the form of [base+offset], extract the two parts
of address and set to BASE and OFFSET, otherwise return false
after clearing BASE and OFFSET. */
@@ -29555,4 +29575,5 @@
*pri = tmp;
return;
}
+
#include "gt-arm.h"
diff -ruN '--exclude=.svn' a2/gcc/gcc/config/arm/arm.h a3/gcc/gcc/config/arm/arm.h
--- a2/gcc/gcc/config/arm/arm.h 2015-01-22 13:52:58.062879846 +0100
+++ a3/gcc/gcc/config/arm/arm.h 2015-01-22 13:53:11.218901428 +0100
@@ -2185,23 +2185,7 @@
? 1 : 0)
#define ARM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
- do \
- { \
- if (TARGET_THUMB) \
- { \
- if (is_called_in_ARM_mode (DECL) \
- || (TARGET_THUMB1 && !TARGET_THUMB1_ONLY \
- && cfun->is_thunk)) \
- fprintf (STREAM, "\t.code 32\n") ; \
- else if (TARGET_THUMB1) \
- fprintf (STREAM, "\t.code\t16\n\t.thumb_func\n") ; \
- else \
- fprintf (STREAM, "\t.thumb\n\t.thumb_func\n") ; \
- } \
- if (TARGET_POKE_FUNCTION_NAME) \
- arm_poke_function_name (STREAM, (const char *) NAME); \
- } \
- while (0)
+ arm_declare_function_name ((STREAM), (NAME), (DECL));
/* For aliases of functions we use .thumb_set instead. */
#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL1, DECL2) \
diff -ruN '--exclude=.svn' a2/gcc/gcc/config/arm/arm-protos.h a3/gcc/gcc/config/arm/arm-protos.h
--- a2/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:52:58.098879905 +0100
+++ a3/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:53:11.222901435 +0100
@@ -30,6 +30,7 @@
extern int arm_volatile_func (void);
extern void arm_expand_prologue (void);
extern void arm_expand_epilogue (bool);
+extern void arm_declare_function_name (FILE *, const char *, tree);
extern void thumb2_expand_return (bool);
extern const char *arm_strip_name_encoding (const char *);
extern void arm_asm_output_labelref (FILE *, const char *);
@@ -185,9 +186,6 @@
extern void thumb1_expand_prologue (void);
extern void thumb1_expand_epilogue (void);
extern const char *thumb1_output_interwork (void);
-#ifdef TREE_CODE
-extern int is_called_in_ARM_mode (tree);
-#endif
extern int thumb_shiftable_const (unsigned HOST_WIDE_INT);
#ifdef RTX_CODE
extern enum arm_cond_code maybe_get_arm_condition_code (rtx);
[-- Attachment #6: p4.patch --]
[-- Type: text/x-patch, Size: 20754 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.opt (THUMB, arm_restrict_it, inline_asm_unified): Save.
* config/arm/arm.h (arm_valid_target_attribute_tree): Declare.
(arm_reset_previous_fndecl, arm_change_mode_p): Likewise.
(SWITCHABLE_TARGET): Define.
* config/arm/arm.c (arm_reset_previous_fndecl): New functions.
(arm_valid_target_attribute_tree, arm_change_mode_p): Likewise.
(arm_valid_target_attribute_p): Likewise.
(arm_set_current_function, arm_can_inline_p): Likewise.
(arm_valid_target_attribute_rec): Likewise.
(arm_previous_fndecl): New variable.
(TARGET_SET_CURRENT_FUNCTION, TARGET_OPTION_VALID_ATTRIBUTE_P): Define.
(TARGET_CAN_INLINE_P): Define.
(arm_asm_trampoline_template): Emit mode.
(arm_file_start): Don't set unified syntax.
(arm_declare_function_name): Set unified syntax and mode.
(arm_option_override): Init target_option_default_node.
and target_option_current_node.
* config/arm/arm.md (*call_value_symbol): Set mode when possible.
(*call_symbol): Likewise.
* doc/extend.texi: Document ARM target and pragma attribute.
* doc/invoke.texi: Likewise.
diff -ruN '--exclude=.svn' a3/gcc/gcc/config/arm/arm.c a4/gcc/gcc/config/arm/arm.c
--- a3/gcc/gcc/config/arm/arm.c 2015-02-05 09:20:12.653396291 +0100
+++ a4/gcc/gcc/config/arm/arm.c 2015-02-05 09:20:12.193395549 +0100
@@ -94,6 +94,7 @@
#include "opts.h"
#include "dumpfile.h"
#include "gimple-expr.h"
+#include "target-globals.h"
#include "builtins.h"
#include "tm-constrs.h"
#include "rtl-iter.h"
@@ -264,6 +265,9 @@
static void arm_expand_builtin_va_start (tree, rtx);
static tree arm_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
static void arm_option_override (void);
+static void arm_set_current_function (tree);
+static bool arm_can_inline_p (tree, tree);
+static bool arm_valid_target_attribute_p (tree, tree, tree, int);
static unsigned HOST_WIDE_INT arm_shift_truncation_mask (machine_mode);
static bool arm_macro_fusion_p (void);
static bool arm_cannot_copy_insn_p (rtx_insn *);
@@ -412,6 +416,9 @@
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue
+#undef TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P arm_can_inline_p
+
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE arm_option_override
@@ -430,6 +437,12 @@
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
+#undef TARGET_SET_CURRENT_FUNCTION
+#define TARGET_SET_CURRENT_FUNCTION arm_set_current_function
+
+#undef TARGET_OPTION_VALID_ATTRIBUTE_P
+#define TARGET_OPTION_VALID_ATTRIBUTE_P arm_valid_target_attribute_p
+
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER arm_sched_reorder
@@ -2704,6 +2717,9 @@
}
}
+/* Options after initial target override. */
+static GTY(()) tree init_optimize;
+
/* Reset options between modes that the user has specified. */
static void
arm_option_override_internal (struct gcc_options *opts,
@@ -2726,6 +2742,10 @@
if (TREE_TARGET_THUMB (opts) && TARGET_CALLEE_INTERWORKING)
opts->x_target_flags |= MASK_INTERWORK;
+ /* need to remember initial values so combinaisons of options like
+ -mflip-thumb -mthumb -fno-schedule-insns work for any attribute. */
+ cl_optimization *to = TREE_OPTIMIZATION (init_optimize);
+
if (! opts_set->x_arm_restrict_it)
opts->x_arm_restrict_it = arm_arch8;
@@ -2733,15 +2753,17 @@
opts->x_arm_restrict_it = 0;
if (TREE_TARGET_THUMB1 (opts))
- {
- /* Don't warn since it's on by default in -O2. */
- opts->x_flag_schedule_insns = 0;
- }
+ /* Don't warn since it's on by default in -O2. */
+ opts->x_flag_schedule_insns = 0;
+ else
+ opts->x_flag_schedule_insns = to->x_flag_schedule_insns;
/* 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))
opts->x_flag_shrink_wrap = false;
+ else
+ opts->x_flag_shrink_wrap = to->x_flag_shrink_wrap;
/* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
- epilogue_insns - does not accurately model the corresponding insns
@@ -2753,6 +2775,8 @@
fipa-ra. */
if (TREE_TARGET_THUMB1 (opts))
opts->x_flag_ipa_ra = 0;
+ else
+ opts->x_flag_ipa_ra = to->x_flag_ipa_ra;
/* Thumb2 inline assembly code should always use unified syntax.
This will apply to ARM and Thumb1 eventually. */
@@ -3244,12 +3268,20 @@
&& (!arm_arch7 || !current_tune->prefer_ldrd_strd))
flag_schedule_fusion = 0;
+ /* Need to remember initial options before they are overriden. */
+ init_optimize = build_optimization_node (&global_options);
+
arm_option_override_internal (&global_options, &global_options_set);
arm_option_check_internal (&global_options);
arm_option_params_internal (&global_options);
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
+
+ /* Save the initial options in case the user does function specific
+ options. */
+ target_option_default_node = target_option_current_node
+ = build_target_option_node (&global_options);
}
static void
@@ -3403,13 +3435,20 @@
static void
arm_asm_trampoline_template (FILE *f)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (f, "\t.syntax unified\n");
+ else
+ fprintf (f, "\t.syntax divided\n");
+
if (TARGET_ARM)
{
+ fprintf (f, "\t.arm\n");
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", STATIC_CHAIN_REGNUM, PC_REGNUM);
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", PC_REGNUM, PC_REGNUM);
}
else if (TARGET_THUMB2)
{
+ fprintf (f, "\t.thumb\n");
/* The Thumb-2 trampoline is similar to the arm implementation.
Unlike 16-bit Thumb, we enter the stub in thumb mode. */
asm_fprintf (f, "\tldr.w\t%r, [%r, #4]\n",
@@ -24097,6 +24136,23 @@
return 0;
}
+/* Check that FUNC is called with a different mode. */
+
+bool
+arm_change_mode_p (tree func)
+{
+ if (TREE_CODE (func) != FUNCTION_DECL)
+ return false;
+
+ tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (func);
+
+ if (!callee_tree)
+ callee_tree = target_option_default_node;
+
+ struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+
+ return (TREE_TARGET_THUMB (callee_opts) != TARGET_THUMB);
+}
/* Given the stack offsets and register mask in OFFSETS, decide how
many additional registers to push instead of subtracting a constant
@@ -25659,9 +25715,6 @@
{
int val;
- if (TARGET_UNIFIED_ASM)
- asm_fprintf (asm_out_file, "\t.syntax unified\n");
-
if (TARGET_BPABI)
{
const char *fpu_name;
@@ -29436,9 +29489,196 @@
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
}
+/* Remember the last target of arm_set_current_function. */
+static GTY(()) tree arm_previous_fndecl;
+
+/* Invalidate arm_previous_fndecl. */
+void
+arm_reset_previous_fndecl (void)
+{
+ arm_previous_fndecl = NULL_TREE;
+}
+
+/* Establish appropriate back-end context for processing the function
+ FNDECL. The argument might be NULL to indicate processing at top
+ level, outside of any function scope. */
+static void
+arm_set_current_function (tree fndecl)
+{
+ if (!fndecl || fndecl == arm_previous_fndecl)
+ return;
+
+ tree old_tree = (arm_previous_fndecl
+ ? DECL_FUNCTION_SPECIFIC_TARGET (arm_previous_fndecl)
+ : NULL_TREE);
+
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+ arm_previous_fndecl = fndecl;
+ if (old_tree == new_tree)
+ ;
+
+ else if (new_tree)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ else if (old_tree)
+ {
+ new_tree = target_option_current_node;
+
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ arm_option_params_internal (&global_options);
+}
+
+/* Hook to determine if one function can safely inline another. */
+
+static bool
+arm_can_inline_p (tree caller ATTRIBUTE_UNUSED, tree callee ATTRIBUTE_UNUSED)
+{
+ /* Overidde default hook: Always OK to inline between different modes.
+ Function with mode specific instructions, e.g using asm, must be explicitely
+ protected with noinline. */
+ return true;
+}
+
+/* Inner function to process the attribute((target(...))), take an argument and
+ set the current options from the argument. If we have a list, recursively
+ go over the list. */
+
+static bool
+arm_valid_target_attribute_rec (tree args, struct gcc_options *opts)
+{
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ bool ret = true;
+ for (; args; args = TREE_CHAIN (args))
+ if (TREE_VALUE (args)
+ && !arm_valid_target_attribute_rec (TREE_VALUE (args), opts))
+ ret = false;
+ return ret;
+ }
+
+ else if (TREE_CODE (args) != STRING_CST)
+ {
+ error ("attribute %<target%> argument not a string");
+ return false;
+ }
+
+ char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
+ while (argstr && *argstr != '\0')
+ {
+ while (ISSPACE (*argstr))
+ argstr++;
+
+ if (!strncmp (argstr, "thumb", 5))
+ {
+ opts->x_target_flags |= MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ if (!strncmp (argstr, "arm", 3))
+ {
+ opts->x_target_flags &= ~MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ warning (0, "attribute(target(\"%s\")) is unknown", argstr);
+ return false;
+ }
+
+ return false;
+}
+
+/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
+
+tree
+arm_valid_target_attribute_tree (tree args, struct gcc_options *opts,
+ struct gcc_options *opts_set)
+{
+ if (!arm_valid_target_attribute_rec (args, opts))
+ return NULL_TREE;
+
+ /* Do any overrides, such as global options arch=xxx. */
+ arm_option_override_internal (opts, opts_set);
+
+ return build_target_option_node (opts);
+}
+
+/* Hook to validate attribute((target("string"))). */
+
+static bool
+arm_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
+ tree args, int ARG_UNUSED (flags))
+{
+ bool ret = true;
+ struct gcc_options func_options;
+ tree cur_tree, new_optimize;
+ gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
+
+ /* Get the optimization options of the current function. */
+ tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
+
+ /* If the function changed the optimization levels as well as setting target
+ options, start with the optimizations specified. */
+ if (!func_optimize)
+ func_optimize = optimization_default_node;
+
+ /* Init func_options. */
+ memset (&func_options, 0, sizeof (func_options));
+ init_options_struct (&func_options, NULL);
+ lang_hooks.init_options_struct (&func_options);
+
+ /* Initialize func_options to the defaults. */
+ cl_optimization_restore (&func_options,
+ TREE_OPTIMIZATION (func_optimize));
+
+ cl_target_option_restore (&func_options,
+ TREE_TARGET_OPTION (target_option_default_node));
+
+ /* Set func_options flags with new target mode. */
+ cur_tree = arm_valid_target_attribute_tree (args, &func_options,
+ &global_options_set);
+
+ if (cur_tree == NULL_TREE)
+ ret = false;
+
+ new_optimize = build_optimization_node (&func_options);
+
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
+
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+
+ return ret;
+}
+
void
arm_declare_function_name (FILE *stream, const char *name, tree decl)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (stream, "\t.syntax unified\n");
+ else
+ fprintf (stream, "\t.syntax divided\n");
+
if (TARGET_THUMB)
{
if (is_called_in_ARM_mode (decl)
@@ -29450,6 +29690,8 @@
else
fprintf (stream, "\t.thumb\n\t.thumb_func\n");
}
+ else
+ fprintf (stream, "\t.arm\n");
if (TARGET_POKE_FUNCTION_NAME)
arm_poke_function_name (stream, (const char *) name);
diff -ruN '--exclude=.svn' a3/gcc/gcc/config/arm/arm.h a4/gcc/gcc/config/arm/arm.h
--- a3/gcc/gcc/config/arm/arm.h 2015-01-22 13:53:11.218901428 +0100
+++ a4/gcc/gcc/config/arm/arm.h 2015-01-22 13:56:30.235226925 +0100
@@ -2360,4 +2360,8 @@
#define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS
#define TARGET_SUPPORTS_WIDE_INT 1
+
+/* For switching between functions with different target attributes. */
+#define SWITCHABLE_TARGET 1
+
#endif /* ! GCC_ARM_H */
diff -ruN '--exclude=.svn' a3/gcc/gcc/config/arm/arm.md a4/gcc/gcc/config/arm/arm.md
--- a3/gcc/gcc/config/arm/arm.md 2015-02-05 09:20:12.657396298 +0100
+++ a4/gcc/gcc/config/arm/arm.md 2015-02-05 09:20:12.233395613 +0100
@@ -7722,6 +7722,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
"*
{
+ rtx op = operands[0];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
}"
[(set_attr "type" "call")]
@@ -7739,6 +7746,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
"*
{
+ rtx op = operands[1];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
}"
[(set_attr "type" "call")]
diff -ruN '--exclude=.svn' a3/gcc/gcc/config/arm/arm.opt a4/gcc/gcc/config/arm/arm.opt
--- a3/gcc/gcc/config/arm/arm.opt 2015-01-22 13:53:11.222901435 +0100
+++ a4/gcc/gcc/config/arm/arm.opt 2015-02-09 12:34:43.188559954 +0100
@@ -182,7 +182,7 @@
Specify the minimum bit alignment of structures
mthumb
-Target Report RejectNegative Mask(THUMB)
+Target Report RejectNegative Mask(THUMB) Save
Generate code for Thumb state
mthumb-interwork
@@ -240,7 +240,7 @@
Only generate absolute relocations on word sized values.
mrestrict-it
-Target Report Var(arm_restrict_it) Init(2)
+Target Report Var(arm_restrict_it) Init(2) Save
Generate IT blocks appropriate for ARMv8.
mold-rtx-costs
@@ -269,5 +269,5 @@
Assume loading data from flash is slower than fetching instructions.
masm-syntax-unified
-Target Report Var(inline_asm_unified) Init(0)
+Target Report Var(inline_asm_unified) Init(0) Save
Assume unified syntax for Thumb inline assembly code.
diff -ruN '--exclude=.svn' a3/gcc/gcc/config/arm/arm-protos.h a4/gcc/gcc/config/arm/arm-protos.h
--- a3/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:53:11.222901435 +0100
+++ a4/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:56:30.239226931 +0100
@@ -214,6 +214,9 @@
extern int arm_dllimport_p (tree);
extern void arm_mark_dllexport (tree);
extern void arm_mark_dllimport (tree);
+extern bool arm_change_mode_p (tree);
+extern tree arm_valid_target_attribute_tree (tree, struct gcc_options *,
+ struct gcc_options *);
#endif
extern void arm_pr_long_calls (struct cpp_reader *);
@@ -316,6 +319,8 @@
extern void arm_emit_eabi_attribute (const char *, int, int);
+extern void arm_reset_previous_fndecl (void);
+
/* Defined in gcc/common/config/arm-common.c. */
extern const char *arm_rewrite_selected_cpu (const char *name);
diff -ruN '--exclude=.svn' a3/gcc/gcc/doc/extend.texi a4/gcc/gcc/doc/extend.texi
--- a3/gcc/gcc/doc/extend.texi 2015-02-05 09:18:12.909233395 +0100
+++ a4/gcc/gcc/doc/extend.texi 2015-02-05 09:21:38.749534626 +0100
@@ -3996,10 +3996,25 @@
strings to specify multiple options, or separate the options
with a comma (@samp{,}).
-The @code{target} attribute is presently implemented for
-x86, PowerPC, and Nios II targets only.
+The @code{target} attribute is implemented for
+ARM, x86, PowerPC, and Nios II targets.
+
The options supported are specific to each target.
+for ARM, the following options are allowed:
+
+@table @samp
+@item thumb
+@cindex @code{target("thumb")} attribute
+Force Thumb1 Thumb2 code generation depending on the architecture.
+
+@item arm
+@cindex @code{target("arm")} attribute
+Force ARM code generation.
+@end table
+
+Functions from different modes can be inlined , unless the callee has asm statements.
+
On the x86, the following options are allowed:
@table @samp
@@ -17795,8 +17810,9 @@
@xref{Function Attributes}, for more information about the
@code{target} attribute and the attribute syntax.
-The @code{#pragma GCC target} pragma is presently implemented for
-x86, PowerPC, and Nios II targets only.
+The @code{#pragma GCC target} pragma is implemented for
+ARM, x86, PowerPC, and Nios II targets.
+
@end table
@table @code
diff -ruN '--exclude=.svn' a3/gcc/gcc/doc/invoke.texi a4/gcc/gcc/doc/invoke.texi
--- a3/gcc/gcc/doc/invoke.texi 2015-02-05 09:18:12.913233401 +0100
+++ a4/gcc/gcc/doc/invoke.texi 2015-02-05 09:18:24.465248626 +0100
@@ -13149,6 +13149,10 @@
configuring GCC with the @option{--with-mode=}@var{state}
configure option.
+You can also override the ARM and Thumb mode for each function
+by using the @code{target("thumb")} and @code{target("arm")} function attributes
+(@pxref{Function Attributes}) or pragmas (@pxref{Function Specific Option Pragmas}).
+
@item -mtpcs-frame
@opindex mtpcs-frame
Generate a stack frame that is compliant with the Thumb Procedure Call
diff -ruN '--exclude=.svn' a3/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c a4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c
--- a3/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 1970-01-01 01:00:00.000000000 +0100
+++ a4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 2015-01-15 13:35:12.135273352 +0100
@@ -0,0 +1,13 @@
+/* Check that attribute target arm is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".arm" } } */
+/* { dg-final { scan-assembler-not "ite" } } */
+
+int __attribute__((target("arm")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
diff -ruN '--exclude=.svn' a3/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c a4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c
--- a3/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 1970-01-01 01:00:00.000000000 +0100
+++ a4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 2015-01-15 13:35:12.139273358 +0100
@@ -0,0 +1,13 @@
+/* Check that attribute target arm is rejected for M profile. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6-m" } } */
+/* { dg-add-options arm_arch_v6m } */
+
+int __attribute__((target("arm")))
+foo(int a)
+{ /* { dg-error "does not support" } */
+ return a ? 1 : 5;
+}
+
+
diff -ruN '--exclude=.svn' a3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c a4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c
--- a3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 1970-01-01 01:00:00.000000000 +0100
+++ a4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 2015-01-15 13:35:12.139273358 +0100
@@ -0,0 +1,13 @@
+/* Check that attribute target thumb is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".thumb" } } */
+/* { dg-final { scan-assembler "ite" } } */
+
+int __attribute__((target("thumb")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
diff -ruN '--exclude=.svn' a3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c a4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c
--- a3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c 1970-01-01 01:00:00.000000000 +0100
+++ a4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c 2015-01-15 13:35:12.139273358 +0100
@@ -0,0 +1,24 @@
+/* Check that a change mode to a static function is correctly handled. */
+/* { dg-do run } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+static void
+ __attribute__((__noinline__))
+foo (void)
+{
+ __asm__ ("");
+}
+
+static void
+__attribute__((__noinline__))
+__attribute__((target("thumb")))
+bar (void)
+{
+ __asm__ ("");
+}
+
+int main()
+{
+ foo();
+ bar();
+}
[-- Attachment #7: p5.patch --]
[-- Type: text/x-patch, Size: 5746 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.h (REGISTER_TARGET_PRAGMAS):
Call arm_register_target_pragmas.
* config/arm/arm-protos.h (arm_register_target_pragmas): Declare.
* config/arm/arm-c.c (arm_register_target_pragmas): New function.
(arm_pragma_target_parse): Likewise.
diff -ruN '--exclude=.svn' a4/gcc/gcc/config/arm/arm-c.c a5/gcc/gcc/config/arm/arm-c.c
--- a4/gcc/gcc/config/arm/arm-c.c 2015-01-15 13:35:07.195265398 +0100
+++ a5/gcc/gcc/config/arm/arm-c.c 2015-01-15 13:36:28.935397056 +0100
@@ -20,7 +20,6 @@
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "tm_p.h"
#include "hash-set.h"
#include "machmode.h"
#include "vec.h"
@@ -31,7 +30,11 @@
#include "wide-int.h"
#include "inchash.h"
#include "tree.h"
+#include "tm_p.h"
#include "c-family/c-common.h"
+#include "target.h"
+#include "target-def.h"
+#include "c-family/c-pragma.h"
/* Output C specific EABI object attributes. These can not be done in
arm.c because they require information from the C frontend. */
@@ -121,3 +124,79 @@
cpp_def_or_undef (in, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified);
}
+/* Hook to validate the current #pragma GCC target and set the arch custom
+ mode state. If ARGS is NULL, then POP_TARGET is used to reset
+ the options. */
+static bool
+arm_pragma_target_parse (tree args, tree pop_target)
+{
+ tree prev_tree = build_target_option_node (&global_options);
+ tree cur_tree;
+ struct cl_target_option *prev_opt;
+ struct cl_target_option *cur_opt;
+ bool cur_mode, prev_mode;
+
+ if (! args)
+ {
+ cur_tree = ((pop_target) ? pop_target : target_option_default_node);
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (cur_tree));
+ }
+ else
+ {
+ cur_tree = arm_valid_target_attribute_tree (args, &global_options,
+ &global_options_set);
+ if (cur_tree == NULL_TREE)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (prev_tree));
+ return false;
+ }
+ }
+
+ target_option_current_node = cur_tree;
+ arm_reset_previous_fndecl ();
+
+ /* Figure out the previous mode. */
+ prev_opt = TREE_TARGET_OPTION (prev_tree);
+ cur_opt = TREE_TARGET_OPTION (cur_tree);
+
+ gcc_assert (prev_opt);
+ gcc_assert (cur_opt);
+
+ cur_mode = TARGET_THUMB_P (cur_opt->x_target_flags);
+ prev_mode = TARGET_THUMB_P (prev_opt->x_target_flags);
+
+ if (prev_mode != cur_mode)
+ {
+ /* For the definitions, ensure all newly defined macros are considered
+ as used for -Wunused-macros. There is no point warning about the
+ compiler predefined macros. */
+ cpp_options *cpp_opts = cpp_get_options (parse_in);
+ unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
+ cpp_opts->warn_unused_macros = 0;
+
+ /* Update macros. */
+ arm_cpp_builtins (parse_in, cur_mode);
+
+ cpp_opts->warn_unused_macros = saved_warn_unused_macros;
+ }
+
+ return true;
+}
+
+/* Register target pragmas. We need to add the hook for parsing #pragma GCC
+ option here rather than in arm.c since it will pull in various preprocessor
+ functions, and those are not present in languages like fortran without a
+ preprocessor. */
+
+void
+arm_register_target_pragmas (void)
+{
+ /* Update pragma hook to allow parsing #pragma GCC target. */
+ targetm.target_option.pragma_parse = arm_pragma_target_parse;
+
+#ifdef REGISTER_SUBTARGET_PRAGMAS
+ REGISTER_SUBTARGET_PRAGMAS ();
+#endif
+}
diff -ruN '--exclude=.svn' a4/gcc/gcc/config/arm/arm.h a5/gcc/gcc/config/arm/arm.h
--- a4/gcc/gcc/config/arm/arm.h 2015-01-22 13:56:30.235226925 +0100
+++ a5/gcc/gcc/config/arm/arm.h 2015-01-22 13:56:45.251251411 +0100
@@ -2098,7 +2098,8 @@
c_register_pragma (0, "long_calls", arm_pr_long_calls); \
c_register_pragma (0, "no_long_calls", arm_pr_no_long_calls); \
c_register_pragma (0, "long_calls_off", arm_pr_long_calls_off); \
- arm_lang_object_attributes_init(); \
+ arm_lang_object_attributes_init(); \
+ arm_register_target_pragmas(); \
} while (0)
/* Condition code information. */
diff -ruN '--exclude=.svn' a4/gcc/gcc/config/arm/arm-protos.h a5/gcc/gcc/config/arm/arm-protos.h
--- a4/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:56:30.239226931 +0100
+++ a5/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:56:45.255251418 +0100
@@ -326,6 +326,7 @@
/* Defined in gcc/common/config/arm-c.c. */
extern void arm_lang_object_attributes_init(void);
+extern void arm_register_target_pragmas (void);
extern void arm_cpp_builtins (struct cpp_reader *, bool);
extern bool arm_is_constant_pool_ref (rtx);
diff -ruN '--exclude=.svn' a4/gcc/gcc/testsuite/gcc.target/arm/pragma_attribute.c a5/gcc/gcc/testsuite/gcc.target/arm/pragma_attribute.c
--- a4/gcc/gcc/testsuite/gcc.target/arm/pragma_attribute.c 1970-01-01 01:00:00.000000000 +0100
+++ a5/gcc/gcc/testsuite/gcc.target/arm/pragma_attribute.c 2015-01-15 13:36:28.935397056 +0100
@@ -0,0 +1,35 @@
+/* Test for #prama target macros. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+#pragma GCC target ("thumb")
+
+#ifndef __thumb__
+#error "__thumb__ is not defined"
+#endif
+
+#ifdef __thumb2__
+#ifndef __ARM_32BIT_STATE
+#error "__ARM_32BIT_STATE is not defined"
+#endif
+#else /* thumb1 */
+#ifdef __ARM_32BIT_STATE
+#error "__ARM_32BIT_STATE is defined"
+#endif
+#endif /* thumb1 */
+
+#pragma GCC target ("arm")
+
+#ifdef __thumb__
+#error "__thumb__ is defined"
+#endif
+
+#if defined (__thumb2__) || defined (__thumb1__)
+#error "thumb is defined"
+#endif
+
+#ifndef __ARM_32BIT_STATE
+#error "__ARM_32BIT_STATE is not defined"
+#endif
+
+#pragma GCC reset_options
[-- Attachment #8: p6.patch --]
[-- Type: text/x-patch, Size: 5364 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.c (add_attribute, arm_insert_attributes): New functions
(TARGET_INSERT_ATTRIBUTES): Define.
(thumb_flipper): New var.
* config/arm/arm.opt (-mflip-thumb): New switch.
diff -ruN '--exclude=.svn' gnu_trunk.devs5/gcc/gcc/config/arm/arm.c gnu_trunk.devs6/gcc/gcc/config/arm/arm.c
--- gnu_trunk.devs5/gcc/gcc/config/arm/arm.c 2015-02-05 09:21:44.449543733 +0100
+++ gnu_trunk.devs6/gcc/gcc/config/arm/arm.c 2015-02-05 09:21:56.821563455 +0100
@@ -99,6 +99,7 @@
#include "tm-constrs.h"
#include "rtl-iter.h"
#include "sched-int.h"
+#include "tree.h"
/* Forward definitions of types. */
typedef struct minipool_node Mnode;
@@ -232,6 +233,7 @@
static void arm_file_end (void);
static void arm_file_start (void);
+static void arm_insert_attributes (tree, tree *);
static void arm_setup_incoming_varargs (cumulative_args_t, machine_mode,
tree, int *, int);
@@ -390,6 +392,9 @@
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE arm_attribute_table
+#undef TARGET_INSERT_ATTRIBUTES
+#define TARGET_INSERT_ATTRIBUTES arm_insert_attributes
+
#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START arm_file_start
#undef TARGET_ASM_FILE_END
@@ -2717,6 +2722,10 @@
}
}
+/* True if -mflip-thumb should next add an attribute for the default
+ mode, false if it should next add an attribute for the opposite mode. */
+static GTY(()) bool thumb_flipper;
+
/* Options after initial target override. */
static GTY(()) tree init_optimize;
@@ -2753,7 +2762,7 @@
opts->x_arm_restrict_it = 0;
if (TREE_TARGET_THUMB1 (opts))
- /* Don't warn since it's on by default in -O2. */
+ /* Don't warn since it's on by default in -O2. */
opts->x_flag_schedule_insns = 0;
else
opts->x_flag_schedule_insns = to->x_flag_schedule_insns;
@@ -3282,6 +3291,9 @@
options. */
target_option_default_node = target_option_current_node
= build_target_option_node (&global_options);
+
+ /* Init initial mode for testing. */
+ thumb_flipper = TARGET_THUMB;
}
static void
@@ -29624,6 +29636,52 @@
return build_target_option_node (opts);
}
+static void
+add_attribute (const char * mode, tree *attributes)
+{
+ size_t len = strlen (mode);
+ tree value = build_string (len, mode);
+
+ TREE_TYPE (value) = build_array_type (char_type_node,
+ build_index_type (size_int (len)));
+
+ *attributes = tree_cons (get_identifier ("target"),
+ build_tree_list (NULL_TREE, value),
+ *attributes);
+}
+
+/* For testing. Insert thumb or arm modes alternatively on functions. */
+
+static void
+arm_insert_attributes (tree fndecl, tree * attributes)
+{
+ const char *mode;
+
+ if (! TARGET_FLIP_THUMB)
+ return;
+
+ if (TREE_CODE (fndecl) != FUNCTION_DECL || DECL_EXTERNAL(fndecl)
+ || DECL_BUILT_IN (fndecl) || DECL_ARTIFICIAL (fndecl))
+ return;
+
+ /* Nested definitions must inherit mode. */
+ if (current_function_decl)
+ {
+ mode = TARGET_THUMB ? "thumb" : "arm";
+ add_attribute (mode, attributes);
+ return;
+ }
+
+ /* If there is already a setting don't change it. */
+ if (lookup_attribute ("target", *attributes) != NULL)
+ return;
+
+ mode = thumb_flipper ? "thumb" : "arm";
+ add_attribute (mode, attributes);
+
+ thumb_flipper = !thumb_flipper;
+}
+
/* Hook to validate attribute((target("string"))). */
static bool
@@ -29635,13 +29693,15 @@
tree cur_tree, new_optimize;
gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
+ tree old_optimize = build_optimization_node (&global_options);
+
/* Get the optimization options of the current function. */
tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
/* If the function changed the optimization levels as well as setting target
options, start with the optimizations specified. */
if (!func_optimize)
- func_optimize = optimization_default_node;
+ func_optimize = old_optimize;
/* Init func_options. */
memset (&func_options, 0, sizeof (func_options));
@@ -29659,14 +29719,17 @@
cur_tree = arm_valid_target_attribute_tree (args, &func_options,
&global_options_set);
- if (cur_tree == NULL_TREE)
- ret = false;
-
new_optimize = build_optimization_node (&func_options);
- DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
+ if (cur_tree == NULL_TREE)
+ ret = false;
+ else
+ {
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
- DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+ if (old_optimize != new_optimize)
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+ }
return ret;
}
diff -ruN '--exclude=.svn' gnu_trunk.devs5/gcc/gcc/config/arm/arm.opt gnu_trunk.devs6/gcc/gcc/config/arm/arm.opt
--- gnu_trunk.devs5/gcc/gcc/config/arm/arm.opt 2015-01-22 13:56:45.255251418 +0100
+++ gnu_trunk.devs6/gcc/gcc/config/arm/arm.opt 2015-01-21 18:18:16.166984018 +0100
@@ -122,6 +122,10 @@
EnumValue
Enum(float_abi_type) String(hard) Value(ARM_FLOAT_ABI_HARD)
+mflip-thumb
+Target Report Var(TARGET_FLIP_THUMB)
+Switch ARM/Thumb modes on alternating functions for compiler testing
+
mfp16-format=
Target RejectNegative Joined Enum(arm_fp16_format_type) Var(arm_fp16_format) Init(ARM_FP16_FORMAT_NONE)
Specify the __fp16 floating-point format
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ping: [PATCH, ARM] attribute target (thumb,arm) [0-6]
2015-02-09 12:34 ping: [PATCH, ARM] attribute target (thumb,arm) [0-6] Christian Bruel
@ 2015-02-09 12:45 ` Christian Bruel
2015-04-14 19:11 ` Ramana Radhakrishnan
1 sibling, 0 replies; 8+ messages in thread
From: Christian Bruel @ 2015-02-09 12:45 UTC (permalink / raw)
To: Ramana Radhakrishnan, richard Earnshaw; +Cc: gcc-patches
> In order to fix the various conflicts that have happened since, please
> find attached the re-based patches to trunk rev #220529 (respectively
> from above p0.patch, p1.patch, p2,patch, p3.patch, p4,patch, p5,patch,
> p6,patch).
>
oops, please don't review p0.patch here. This last one will be reviewed
separately by the i386 and middle-end maintainers. It was posted now
accidentally and is useful only for testing.
Thanks
Christian
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ping: [PATCH, ARM] attribute target (thumb,arm) [0-6]
2015-02-09 12:34 ping: [PATCH, ARM] attribute target (thumb,arm) [0-6] Christian Bruel
2015-02-09 12:45 ` Christian Bruel
@ 2015-04-14 19:11 ` Ramana Radhakrishnan
2015-04-20 8:35 ` Christian Bruel
1 sibling, 1 reply; 8+ messages in thread
From: Ramana Radhakrishnan @ 2015-04-14 19:11 UTC (permalink / raw)
To: Christian Bruel; +Cc: Ramana Radhakrishnan, richard Earnshaw, gcc-patches
On Mon, Feb 9, 2015 at 12:34 PM, Christian Bruel <christian.bruel@st.com> wrote:
> Hello,
>
> I'd like to ping with a respin of the 7 patches for
> the attribute target (thumb,arm) [0-6] :
>
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02455.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02458.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02460.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02461.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02463.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02467.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02468.html
>
> In order to fix the various conflicts that have happened since, please find
> attached the re-based patches to trunk rev #220529 (respectively from above
> p0.patch, p1.patch, p2,patch, p3.patch, p4,patch, p5,patch, p6,patch).
>
> I understand the difficulty of reviewing those due to the code
> reorganization, but maintaining them are really a pain since a conflict
> happens at almost every update in the ARM back-end :-(
>
> Comments, questions are welcome,
>
> Many thanks
>
> Christian
>
>
>
>
Can you respin this now that we are in stage1 again ?
Ramana
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ping: [PATCH, ARM] attribute target (thumb,arm) [0-6]
2015-04-14 19:11 ` Ramana Radhakrishnan
@ 2015-04-20 8:35 ` Christian Bruel
2015-04-30 8:27 ` Ramana Radhakrishnan
0 siblings, 1 reply; 8+ messages in thread
From: Christian Bruel @ 2015-04-20 8:35 UTC (permalink / raw)
To: ramrad01; +Cc: Ramana Radhakrishnan, richard Earnshaw, gcc-patches
[-- Attachment #1: Type: text/plain, Size: 598 bytes --]
Hello Ramana
>>
>
> Can you respin this now that we are in stage1 again ?
>
> Ramana
>
Attached the rebased, rechecked set of patches. Original with comments
posted in
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02455.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02458.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02460.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02461.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02463.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02467.html
https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02468.html
many thanks,
Christian
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: p1.patch --]
[-- Type: text/x-patch; name="p1.patch", Size: 18247 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.h (arm_option_override): Reoganized and split.
(arm_option_params_internal); New function.
(arm_option_check_internal): New function.
(arm_option_override_internal): New function.
(restrict_default): New boolean.
(thumb_code, thumb1_code): Remove.
* config/arm/arm.h (TREE_TARGET_THUMB, TREE_TARGET_THUMB1): New macros.
(TREE_TARGET_THUM2, TREE_TARGET_ARM): Likewise.
(thumb_code, thumb1_code): Remove.
* config/arm/arm.md (is_thumb, is_thumb1): Check TARGET flag.
diff -ruN '--exclude=.svn' a/gcc/gcc/config/arm/arm.c a1/gcc/gcc/config/arm/arm.c
--- a/gcc/gcc/config/arm/arm.c 2015-02-04 09:14:26.120602737 +0100
+++ a1/gcc/gcc/config/arm/arm.c 2015-02-05 09:19:32.853338616 +0100
@@ -846,12 +846,6 @@
/* Nonzero if tuning for Cortex-A9. */
int arm_tune_cortex_a9 = 0;
-/* Nonzero if generating Thumb instructions. */
-int thumb_code = 0;
-
-/* Nonzero if generating Thumb-1 instructions. */
-int thumb1_code = 0;
-
/* Nonzero if we should define __THUMB_INTERWORK__ in the
preprocessor.
XXX This is a bit of a hack, it's intended to help work around
@@ -2623,6 +2617,148 @@
return std_gimplify_va_arg_expr (valist, type, pre_p, post_p);
}
+/* Check any incompatible options that the user has specified. */
+static void
+arm_option_check_internal (struct gcc_options *opts)
+{
+ /* 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))
+ 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))
+ warning (0, "enabling backtrace support is only meaningful when compiling for the Thumb");
+
+ if (TREE_TARGET_ARM (opts) && 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)
+ && 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)
+ error ("iWMMXt unsupported under Thumb mode");
+
+ if (TARGET_HARD_TP && TREE_TARGET_THUMB1 (opts))
+ error ("can not use -mtp=cp15 with 16-bit Thumb");
+
+ if (TREE_TARGET_THUMB (opts) && TARGET_VXWORKS_RTP && flag_pic)
+ {
+ error ("RTP PIC is incompatible with Thumb");
+ 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)
+ || (TREE_TARGET_THUMB1 (opts) || flag_pic || TARGET_NEON)))
+ error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
+}
+
+/* Check any params depending on attributes that the user has specified. */
+static void
+arm_option_params_internal (struct gcc_options *opts)
+{
+ /* If we are not using the default (ARM mode) section anchor offset
+ ranges, then set the correct ranges now. */
+ if (TREE_TARGET_THUMB1 (opts))
+ {
+ /* Thumb-1 LDR instructions cannot have negative offsets.
+ Permissible positive offset ranges are 5-bit (for byte loads),
+ 6-bit (for halfword loads), or 7-bit (for word loads).
+ Empirical results suggest a 7-bit anchor range gives the best
+ overall code size. */
+ targetm.min_anchor_offset = 0;
+ targetm.max_anchor_offset = 127;
+ }
+ else if (TREE_TARGET_THUMB2 (opts))
+ {
+ /* The minimum is set such that the total size of the block
+ for a particular anchor is 248 + 1 + 4095 bytes, which is
+ divisible by eight, ensuring natural spacing of anchors. */
+ targetm.min_anchor_offset = -248;
+ targetm.max_anchor_offset = 4095;
+ }
+ else
+ {
+ targetm.min_anchor_offset = TARGET_MIN_ANCHOR_OFFSET;
+ targetm.max_anchor_offset = TARGET_MAX_ANCHOR_OFFSET;
+ }
+
+ if (optimize_size)
+ {
+ /* If optimizing for size, bump the number of instructions that we
+ are prepared to conditionally execute (even on a StrongARM). */
+ max_insns_skipped = 6;
+
+ /* For THUMB2, we limit the conditional sequence to one IT block. */
+ if (TREE_TARGET_THUMB2 (opts))
+ max_insns_skipped = opts->x_arm_restrict_it ? 1 : 4;
+ }
+}
+
+/* Reset options between modes that the user has specified. */
+static void
+arm_option_override_internal (struct gcc_options *opts,
+ struct gcc_options *opts_set)
+{
+ if (TREE_TARGET_THUMB (opts) && !(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))
+ {
+ /* warning (0, "ignoring -mapcs-frame because -mthumb was used"); */
+ opts->x_target_flags &= ~MASK_APCS_FRAME;
+ }
+
+ /* Callee super interworking implies thumb interworking. Adding
+ this to the flags here simplifies the logic elsewhere. */
+ if (TREE_TARGET_THUMB (opts) && 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))
+ opts->x_arm_restrict_it = 0;
+
+ if (TREE_TARGET_THUMB1 (opts))
+ {
+ /* Don't warn since it's on by default in -O2. */
+ opts->x_flag_schedule_insns = 0;
+ }
+
+ /* 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))
+ opts->x_flag_shrink_wrap = false;
+
+ /* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
+ - epilogue_insns - does not accurately model the corresponding insns
+ emitted in the asm file. In particular, see the comment in thumb_exit
+ 'Find out how many of the (return) argument registers we can corrupt'.
+ As a consequence, the epilogue may clobber registers without fipa-ra
+ 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))
+ 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);
+}
+
/* Fix up any incompatible options that the user has specified. */
static void
arm_option_override (void)
@@ -2769,10 +2905,9 @@
tune_flags = arm_selected_tune->flags;
current_tune = arm_selected_tune->tune;
- /* Make sure that the processor choice does not conflict with any of the
- other command line choices. */
- if (TARGET_ARM && !(insn_flags & FL_NOTM))
- error ("target CPU does not support ARM mode");
+ /* TBD: Dwarf info for apcs frame is not handled yet. */
+ if (TARGET_APCS_FRAME)
+ flag_shrink_wrap = false;
/* BPABI targets use linker tricks to allow interworking on cores
without thumb support. */
@@ -2782,31 +2917,6 @@
target_flags &= ~MASK_INTERWORK;
}
- if (TARGET_THUMB && !(insn_flags & FL_THUMB))
- {
- warning (0, "target CPU does not support THUMB instructions");
- target_flags &= ~MASK_THUMB;
- }
-
- if (TARGET_APCS_FRAME && TARGET_THUMB)
- {
- /* warning (0, "ignoring -mapcs-frame because -mthumb was used"); */
- target_flags &= ~MASK_APCS_FRAME;
- }
-
- /* Callee super interworking implies thumb interworking. Adding
- this to the flags here simplifies the logic elsewhere. */
- if (TARGET_THUMB && TARGET_CALLEE_INTERWORKING)
- target_flags |= MASK_INTERWORK;
-
- /* 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) && TARGET_ARM)
- warning (0, "enabling backtrace support is only meaningful when compiling for the Thumb");
-
- if (TARGET_ARM && TARGET_CALLEE_INTERWORKING)
- warning (0, "enabling callee interworking support is only meaningful when compiling for the Thumb");
-
if (TARGET_APCS_STACK && !TARGET_APCS_FRAME)
{
warning (0, "-mapcs-stack-check incompatible with -mno-apcs-frame");
@@ -2822,14 +2932,6 @@
if (TARGET_APCS_REENT)
warning (0, "APCS reentrant code not supported. Ignored");
- /* If this target is normally configured to use APCS frames, warn if they
- are turned off and debugging is turned on. */
- if (TARGET_ARM
- && write_symbols != NO_DEBUG
- && !TARGET_APCS_FRAME
- && (TARGET_DEFAULT & MASK_APCS_FRAME))
- warning (0, "-g with -mno-apcs-frame may not give sensible debugging");
-
if (TARGET_APCS_FLOAT)
warning (0, "passing floating point arguments in fp regs not yet supported");
@@ -2851,8 +2953,6 @@
arm_ld_sched = (tune_flags & FL_LDSCHED) != 0;
arm_tune_strongarm = (tune_flags & FL_STRONG) != 0;
- thumb_code = TARGET_ARM == 0;
- thumb1_code = TARGET_THUMB1 != 0;
arm_tune_wbuf = (tune_flags & FL_WBUF) != 0;
arm_tune_xscale = (tune_flags & FL_XSCALE) != 0;
arm_arch_iwmmxt = (insn_flags & FL_IWMMXT) != 0;
@@ -2862,32 +2962,6 @@
arm_tune_cortex_a9 = (arm_tune == cortexa9) != 0;
arm_arch_crc = (insn_flags & FL_CRC32) != 0;
arm_m_profile_small_mul = (insn_flags & FL_SMALLMUL) != 0;
- if (arm_restrict_it == 2)
- arm_restrict_it = arm_arch8 && TARGET_THUMB2;
-
- if (!TARGET_THUMB2)
- arm_restrict_it = 0;
-
- /* If we are not using the default (ARM mode) section anchor offset
- ranges, then set the correct ranges now. */
- if (TARGET_THUMB1)
- {
- /* Thumb-1 LDR instructions cannot have negative offsets.
- Permissible positive offset ranges are 5-bit (for byte loads),
- 6-bit (for halfword loads), or 7-bit (for word loads).
- Empirical results suggest a 7-bit anchor range gives the best
- overall code size. */
- targetm.min_anchor_offset = 0;
- targetm.max_anchor_offset = 127;
- }
- else if (TARGET_THUMB2)
- {
- /* The minimum is set such that the total size of the block
- for a particular anchor is 248 + 1 + 4095 bytes, which is
- divisible by eight, ensuring natural spacing of anchors. */
- targetm.min_anchor_offset = -248;
- targetm.max_anchor_offset = 4095;
- }
/* V5 code we generate is completely interworking capable, so we turn off
TARGET_INTERWORK here to avoid many tests later on. */
@@ -2906,6 +2980,9 @@
if (TARGET_IWMMXT_ABI && !TARGET_IWMMXT)
error ("iwmmxt abi requires an iwmmxt capable cpu");
+ if (! optimize_size)
+ max_insns_skipped = current_tune->max_insns_skipped;
+
if (!global_options_set.x_arm_fpu_index)
{
const char *target_fpu_name;
@@ -2947,10 +3024,6 @@
if (TARGET_IWMMXT && TARGET_NEON)
error ("iWMMXt and NEON are incompatible");
- /* iWMMXt unsupported under Thumb mode. */
- if (TARGET_THUMB && TARGET_IWMMXT)
- error ("iWMMXt unsupported under Thumb mode");
-
/* __fp16 support currently assumes the core has ldrh. */
if (!arm_arch4 && arm_fp16_format != ARM_FP16_FORMAT_NONE)
sorry ("__fp16 and no ldrh");
@@ -2995,9 +3068,6 @@
target_thread_pointer = TP_SOFT;
}
- if (TARGET_HARD_TP && TARGET_THUMB1)
- error ("can not use -mtp=cp15 with 16-bit Thumb");
-
/* Override the default structure alignment for AAPCS ABI. */
if (!global_options_set.x_arm_structure_size_boundary)
{
@@ -3020,12 +3090,6 @@
}
}
- if (!TARGET_ARM && TARGET_VXWORKS_RTP && flag_pic)
- {
- error ("RTP PIC is incompatible with Thumb");
- flag_pic = 0;
- }
-
/* If stack checking is disabled, we can use r10 as the PIC register,
which keeps r9 available. The EABI specifies r9 as the PIC register. */
if (flag_pic && TARGET_SINGLE_PIC_BASE)
@@ -3093,25 +3157,6 @@
unaligned_access = 0;
}
- if (TARGET_THUMB1 && flag_schedule_insns)
- {
- /* Don't warn since it's on by default in -O2. */
- flag_schedule_insns = 0;
- }
-
- if (optimize_size)
- {
- /* If optimizing for size, bump the number of instructions that we
- are prepared to conditionally execute (even on a StrongARM). */
- max_insns_skipped = 6;
-
- /* For THUMB2, we limit the conditional sequence to one IT block. */
- if (TARGET_THUMB2)
- max_insns_skipped = MAX_INSN_PER_IT_BLOCK;
- }
- else
- max_insns_skipped = current_tune->max_insns_skipped;
-
/* Hot/Cold partitioning is not currently supported, since we can't
handle literal pool placement in that case. */
if (flag_reorder_blocks_and_partition)
@@ -3189,45 +3234,19 @@
global_options.x_param_values,
global_options_set.x_param_values);
- /* Disable shrink-wrap when optimizing function for size, since it tends to
- generate additional returns. */
- if (optimize_function_for_size_p (cfun) && TARGET_THUMB2)
- flag_shrink_wrap = false;
- /* TBD: Dwarf info for apcs frame is not handled yet. */
- if (TARGET_APCS_FRAME)
- flag_shrink_wrap = false;
-
- /* We only support -mslow-flash-data on armv7-m targets. */
- if (target_slow_flash_data
- && ((!(arm_arch7 && !arm_arch_notm) && !arm_arch7em)
- || (TARGET_THUMB1 || flag_pic || TARGET_NEON)))
- error ("-mslow-flash-data only supports non-pic code on armv7-m targets");
-
/* Currently, for slow flash data, we just disable literal pools. */
if (target_slow_flash_data)
arm_disable_literal_pool = true;
- /* Thumb2 inline assembly code should always use unified syntax.
- This will apply to ARM and Thumb1 eventually. */
- if (TARGET_THUMB2)
- inline_asm_unified = 1;
-
/* Disable scheduling fusion by default if it's not armv7 processor
or doesn't prefer ldrd/strd. */
if (flag_schedule_fusion == 2
&& (!arm_arch7 || !current_tune->prefer_ldrd_strd))
flag_schedule_fusion = 0;
- /* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
- - epilogue_insns - does not accurately model the corresponding insns
- emitted in the asm file. In particular, see the comment in thumb_exit
- 'Find out how many of the (return) argument registers we can corrupt'.
- As a consequence, the epilogue may clobber registers without fipa-ra
- finding out about it. Therefore, disable fipa-ra in Thumb1 mode.
- TODO: Accurately model clobbers for epilogue_insns and reenable
- fipa-ra. */
- if (TARGET_THUMB1)
- flag_ipa_ra = 0;
+ arm_option_override_internal (&global_options, &global_options_set);
+ arm_option_check_internal (&global_options);
+ arm_option_params_internal (&global_options);
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
diff -ruN '--exclude=.svn' a/gcc/gcc/config/arm/arm.h a1/gcc/gcc/config/arm/arm.h
--- a/gcc/gcc/config/arm/arm.h 2015-01-20 15:58:49.230503992 +0100
+++ a1/gcc/gcc/config/arm/arm.h 2015-01-22 13:48:29.338437070 +0100
@@ -252,5 +252,12 @@
#define SUBTARGET_CPP_SPEC ""
#endif
\f
+/* 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)
/* Run-time Target Specification. */
#define TARGET_SOFT_FLOAT (arm_float_abi == ARM_FLOAT_ABI_SOFT)
/* Use hardware floating point instructions. */
@@ -525,12 +532,6 @@
/* Nonzero if this chip can benefit from load scheduling. */
extern int arm_ld_sched;
-/* Nonzero if generating Thumb code, either Thumb-1 or Thumb-2. */
-extern int thumb_code;
-
-/* Nonzero if generating Thumb-1 code. */
-extern int thumb1_code;
-
/* Nonzero if this chip is a StrongARM. */
extern int arm_tune_strongarm;
diff -ruN '--exclude=.svn' a/gcc/gcc/config/arm/arm.md a1/gcc/gcc/config/arm/arm.md
--- a/gcc/gcc/config/arm/arm.md 2015-01-26 11:04:05.937275841 +0100
+++ a1/gcc/gcc/config/arm/arm.md 2015-02-05 09:19:32.857338621 +0100
@@ -69,13 +69,17 @@
; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when
; generating ARM code. This is used to control the length of some insn
; patterns that share the same RTL in both ARM and Thumb code.
-(define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code")))
+(define_attr "is_thumb" "yes,no"
+ (const (if_then_else (symbol_ref "TARGET_THUMB")
+ (const_string "yes") (const_string "no"))))
; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6.
(define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6")))
; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code.
-(define_attr "is_thumb1" "no,yes" (const (symbol_ref "thumb1_code")))
+(define_attr "is_thumb1" "yes,no"
+ (const (if_then_else (symbol_ref "TARGET_THUMB1")
+ (const_string "yes") (const_string "no"))))
; We use this attribute to disable alternatives that can produce 32-bit
; instructions inside an IT-block in Thumb2 state. ARMv8 deprecates IT blocks
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #3: p2.patch --]
[-- Type: text/x-patch; name="p2.patch", Size: 6850 bytes --]
Christian Bruel <christian.bruel@st.com>
* config/arm/arm-c.c (cpp_def_or_undef): New functions.
(arm_cpp_builtins): Likewise.
* config/arm/arm.h (TARGET_CPU_CPP_BUILTINS): Move mode dependant
macros to arm_cpp_builtins.
* config/arm/arm-protos.h (arm_cpp_builtins): Declare.
diff -ruN '--exclude=.svn' a1/gcc/gcc/config/arm/arm-c.c a2/gcc/gcc/config/arm/arm-c.c
--- a1/gcc/gcc/config/arm/arm-c.c 2015-01-13 12:34:38.910459998 +0100
+++ a2/gcc/gcc/config/arm/arm-c.c 2015-01-15 13:32:30.683013516 +0100
@@ -51,3 +51,73 @@
{
arm_lang_output_object_attributes_hook = arm_output_c_attributes;
}
+
+/* Define or undefine macro. */
+
+static void
+cpp_def_or_undef (struct cpp_reader *in, const char *str, bool def_p)
+{
+ if (def_p)
+ cpp_define (in, str);
+ else
+ cpp_undef (in, str);
+}
+
+/* Define or undefine macros based on the current target. If the user does
+ #pragma GCC target, we need to adjust the macros dynamically. */
+
+void
+arm_cpp_builtins (struct cpp_reader *in, bool thumb_p)
+{
+ bool target_32bit_p = !thumb_p || arm_arch_thumb2;
+ bool thumb2_p = thumb_p && arm_arch_thumb2;
+ bool have_ldrex_p = (arm_arch6 && !thumb_p) || arm_arch7;
+ bool have_ldrexbh_p = (arm_arch6k && !thumb_p) || arm_arch7;
+ bool have_ldrexd_p = ((arm_arch6k && !thumb_p) || arm_arch7)
+ && arm_arch_notm;
+
+ int arm_feature_ldrex = (have_ldrex_p ? 4 : 0)
+ | (have_ldrexbh_p ? 3 : 0) | (have_ldrexd_p ? 8 : 0);
+
+ cpp_def_or_undef (in, "__thumb__", thumb_p);
+ if (arm_arch_thumb2)
+ cpp_def_or_undef (in, "__thumb2__", thumb_p);
+ if (TARGET_BIG_END)
+ cpp_def_or_undef (in, "__THUMBEB__", thumb_p);
+ else
+ cpp_def_or_undef (in, "__THUMBEL__", thumb_p);
+
+ cpp_def_or_undef (in, "__ARM_32BIT_STATE", target_32bit_p); /* TARGET_32BIT */
+
+ if (arm_arch5e && (arm_arch_notm || arm_arch7)) /* TARGET_ARM_QBIT */
+ cpp_def_or_undef (in, "__ARM_FEATURE_QBIT", target_32bit_p);
+
+ if (arm_arch6 && (arm_arch_notm || arm_arch7)) /* TARGET_ARM_SAT */
+ cpp_def_or_undef (in, "__ARM_FEATURE_SAT", target_32bit_p);
+
+ if (arm_arch5e && (arm_arch_notm || arm_arch7em)) /* TARGET_DSP_MULTIPLY */
+ cpp_def_or_undef (in, "__ARM_FEATURE_DSP", target_32bit_p);
+
+ if (arm_arch6 && (arm_arch_notm || arm_arch7em)) /* TARGET_INT_SIMD */
+ cpp_def_or_undef (in, "__ARM_FEATURE_SIMD32", target_32bit_p);
+
+ /* TARGET_IDIV */
+ cpp_def_or_undef (in, "__ARM_ARCH_EXT_IDIV__",
+ ((!thumb_p && arm_arch_arm_hwdiv)
+ || (thumb2_p && arm_arch_thumb_hwdiv)));
+
+ cpp_def_or_undef (in, "__ARM_FEATURE_IDIV",
+ ((!thumb_p && arm_arch_arm_hwdiv)
+ || (thumb2_p && arm_arch_thumb_hwdiv)));
+
+ if (arm_feature_ldrex)
+ cpp_define_formatted (in, "__ARM_FEATURE_LDREX=%d", arm_feature_ldrex);
+ else
+ cpp_undef (in, "__ARM_FEATURE_LDREX");
+
+ cpp_def_or_undef (in, "__ARM_FEATURE_CLZ",
+ ((TARGET_ARM_ARCH >= 5 && !thumb_p) || TARGET_ARM_ARCH_ISA_THUMB >=2));
+
+ cpp_def_or_undef (in, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified);
+}
+
diff -ruN '--exclude=.svn' a1/gcc/gcc/config/arm/arm.h a2/gcc/gcc/config/arm/arm.h
--- a1/gcc/gcc/config/arm/arm.h 2015-01-22 13:48:29.338437070 +0100
+++ a2/gcc/gcc/config/arm/arm.h 2015-01-22 13:52:58.062879846 +0100
@@ -48,29 +48,12 @@
#define TARGET_CPU_CPP_BUILTINS() \
do \
{ \
- 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"); \
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) \
- 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"); \
- \
builtin_define_with_int_value ( \
"__ARM_SIZEOF_MINIMAL_ENUM", \
flag_short_enums ? 1 : 4); \
@@ -89,10 +72,6 @@
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__"); \
if (TARGET_ARM_ARCH_ISA_THUMB) \
builtin_define_with_int_value ( \
"__ARM_ARCH_ISA_THUMB", \
@@ -102,15 +81,9 @@
{ \
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) \
builtin_define ("__SOFTFP__"); \
@@ -163,13 +136,8 @@
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__");\
+ /* Remaining macros depends on TARGET_THUMB. */\
+ arm_cpp_builtins (pfile, TARGET_THUMB); \
} while (0)
#include "config/arm/arm-opts.h"
diff -ruN '--exclude=.svn' a1/gcc/gcc/config/arm/arm-protos.h a2/gcc/gcc/config/arm/arm-protos.h
--- a1/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:48:29.342437077 +0100
+++ a2/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:52:58.098879905 +0100
@@ -222,8 +222,6 @@
extern void arm_pr_no_long_calls (struct cpp_reader *);
extern void arm_pr_long_calls_off (struct cpp_reader *);
-extern void arm_lang_object_attributes_init(void);
-
extern const char *arm_mangle_type (const_tree);
extern const char *arm_mangle_builtin_type (const_tree);
@@ -323,6 +321,10 @@
/* Defined in gcc/common/config/arm-common.c. */
extern const char *arm_rewrite_selected_cpu (const char *name);
+/* Defined in gcc/common/config/arm-c.c. */
+extern void arm_lang_object_attributes_init(void);
+extern void arm_cpp_builtins (struct cpp_reader *, bool);
+
extern bool arm_is_constant_pool_ref (rtx);
/* Flags used to identify the presence of processor capabilities. */
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #4: p3.patch --]
[-- Type: text/x-patch; name="p3.patch", Size: 4933 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm-protos.h (arm_declare_function_name): Declare.
(is_called_in_ARM_mode): Remove.
* config/arm/arm.c (is_called_in_ARM_mode): Declare static bool.
(arm_declare_function_name): Moved from from ARM_DECLARE_FUNCTION_NAME.
* config/arm/arm.h (ARM_DECLARE_FUNCTION_NAME): Call
arm_declare_function_name.
diff -ruN '--exclude=.svn' a2/gcc/gcc/config/arm/arm.c a3/gcc/gcc/config/arm/arm.c
--- a2/gcc/gcc/config/arm/arm.c 2015-02-05 09:20:13.225397216 +0100
+++ a3/gcc/gcc/config/arm/arm.c 2015-02-05 09:20:12.653396291 +0100
@@ -23645,6 +23645,23 @@
fprintf (f, "}\n");
}
+/* Return nonzero if FUNC must be entered in ARM mode. */
+static bool
+is_called_in_ARM_mode (tree func)
+{
+ gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
+
+ /* Ignore the problem about functions whose address is taken. */
+ if (TARGET_CALLEE_INTERWORKING && TREE_PUBLIC (func))
+ return true;
+
+#ifdef ARM_PE
+ return lookup_attribute ("interfacearm", DECL_ATTRIBUTES (func)) != NULL_TREE;
+#else
+ return false;
+#endif
+}
+
/* Generate code to return from a thumb function.
If 'reg_containing_return_addr' is -1, then the return address is
actually on the stack, at the stack pointer. */
@@ -24080,22 +24097,6 @@
return 0;
}
-/* Return nonzero if FUNC must be entered in ARM mode. */
-int
-is_called_in_ARM_mode (tree func)
-{
- gcc_assert (TREE_CODE (func) == FUNCTION_DECL);
-
- /* Ignore the problem about functions whose address is taken. */
- if (TARGET_CALLEE_INTERWORKING && TREE_PUBLIC (func))
- return TRUE;
-
-#ifdef ARM_PE
- return lookup_attribute ("interfacearm", DECL_ATTRIBUTES (func)) != NULL_TREE;
-#else
- return FALSE;
-#endif
-}
/* Given the stack offsets and register mask in OFFSETS, decide how
many additional registers to push instead of subtracting a constant
@@ -29435,6 +29436,25 @@
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
}
+void
+arm_declare_function_name (FILE *stream, const char *name, tree decl)
+{
+ if (TARGET_THUMB)
+ {
+ if (is_called_in_ARM_mode (decl)
+ || (TARGET_THUMB1 && !TARGET_THUMB1_ONLY
+ && cfun->is_thunk))
+ fprintf (stream, "\t.code 32\n");
+ else if (TARGET_THUMB1)
+ fprintf (stream, "\t.code\t16\n\t.thumb_func\n");
+ else
+ fprintf (stream, "\t.thumb\n\t.thumb_func\n");
+ }
+
+ if (TARGET_POKE_FUNCTION_NAME)
+ arm_poke_function_name (stream, (const char *) name);
+}
+
/* If MEM is in the form of [base+offset], extract the two parts
of address and set to BASE and OFFSET, otherwise return false
after clearing BASE and OFFSET. */
@@ -29555,4 +29575,5 @@
*pri = tmp;
return;
}
+
#include "gt-arm.h"
diff -ruN '--exclude=.svn' a2/gcc/gcc/config/arm/arm.h a3/gcc/gcc/config/arm/arm.h
--- a2/gcc/gcc/config/arm/arm.h 2015-01-22 13:52:58.062879846 +0100
+++ a3/gcc/gcc/config/arm/arm.h 2015-01-22 13:53:11.218901428 +0100
@@ -2185,23 +2185,7 @@
? 1 : 0)
#define ARM_DECLARE_FUNCTION_NAME(STREAM, NAME, DECL) \
- do \
- { \
- if (TARGET_THUMB) \
- { \
- if (is_called_in_ARM_mode (DECL) \
- || (TARGET_THUMB1 && !TARGET_THUMB1_ONLY \
- && cfun->is_thunk)) \
- fprintf (STREAM, "\t.code 32\n") ; \
- else if (TARGET_THUMB1) \
- fprintf (STREAM, "\t.code\t16\n\t.thumb_func\n") ; \
- else \
- fprintf (STREAM, "\t.thumb\n\t.thumb_func\n") ; \
- } \
- if (TARGET_POKE_FUNCTION_NAME) \
- arm_poke_function_name (STREAM, (const char *) NAME); \
- } \
- while (0)
+ arm_declare_function_name ((STREAM), (NAME), (DECL));
/* For aliases of functions we use .thumb_set instead. */
#define ASM_OUTPUT_DEF_FROM_DECLS(FILE, DECL1, DECL2) \
diff -ruN '--exclude=.svn' a2/gcc/gcc/config/arm/arm-protos.h a3/gcc/gcc/config/arm/arm-protos.h
--- a2/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:52:58.098879905 +0100
+++ a3/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:53:11.222901435 +0100
@@ -30,6 +30,7 @@
extern int arm_volatile_func (void);
extern void arm_expand_prologue (void);
extern void arm_expand_epilogue (bool);
+extern void arm_declare_function_name (FILE *, const char *, tree);
extern void thumb2_expand_return (bool);
extern const char *arm_strip_name_encoding (const char *);
extern void arm_asm_output_labelref (FILE *, const char *);
@@ -185,9 +186,6 @@
extern void thumb1_expand_prologue (void);
extern void thumb1_expand_epilogue (void);
extern const char *thumb1_output_interwork (void);
-#ifdef TREE_CODE
-extern int is_called_in_ARM_mode (tree);
-#endif
extern int thumb_shiftable_const (unsigned HOST_WIDE_INT);
#ifdef RTX_CODE
extern enum arm_cond_code maybe_get_arm_condition_code (rtx);
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #5: p4.patch --]
[-- Type: text/x-patch; name="p4.patch", Size: 21385 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.opt (THUMB, arm_restrict_it, inline_asm_unified): Save.
* config/arm/arm.h (arm_valid_target_attribute_tree): Declare.
(arm_reset_previous_fndecl, arm_change_mode_p): Likewise.
(SWITCHABLE_TARGET): Define.
* config/arm/arm.c (arm_reset_previous_fndecl): New functions.
(arm_valid_target_attribute_tree, arm_change_mode_p): Likewise.
(arm_valid_target_attribute_p): Likewise.
(arm_set_current_function, arm_can_inline_p): Likewise.
(arm_valid_target_attribute_rec): Likewise.
(arm_previous_fndecl): New variable.
(TARGET_SET_CURRENT_FUNCTION, TARGET_OPTION_VALID_ATTRIBUTE_P): Define.
(TARGET_CAN_INLINE_P): Define.
(arm_asm_trampoline_template): Emit mode.
(arm_file_start): Don't set unified syntax.
(arm_declare_function_name): Set unified syntax and mode.
(arm_option_override): Init target_option_default_node.
and target_option_current_node.
* config/arm/arm.md (*call_value_symbol): Set mode when possible.
(*call_symbol): Likewise.
* doc/extend.texi: Document ARM target and pragma attribute.
* doc/invoke.texi: Likewise.
diff -ruN '--exclude=.svn' a3/gcc/gcc/config/arm/arm.c a4/gcc/gcc/config/arm/arm.c
--- a3/gcc/gcc/config/arm/arm.c 2015-02-05 09:20:12.653396291 +0100
+++ a4/gcc/gcc/config/arm/arm.c 2015-02-05 09:20:12.193395549 +0100
@@ -94,6 +94,7 @@
#include "opts.h"
#include "dumpfile.h"
#include "gimple-expr.h"
+#include "target-globals.h"
#include "builtins.h"
#include "tm-constrs.h"
#include "rtl-iter.h"
@@ -264,6 +265,9 @@
static void arm_expand_builtin_va_start (tree, rtx);
static tree arm_gimplify_va_arg_expr (tree, tree, gimple_seq *, gimple_seq *);
static void arm_option_override (void);
+static void arm_set_current_function (tree);
+static bool arm_can_inline_p (tree, tree);
+static bool arm_valid_target_attribute_p (tree, tree, tree, int);
static unsigned HOST_WIDE_INT arm_shift_truncation_mask (machine_mode);
static bool arm_macro_fusion_p (void);
static bool arm_cannot_copy_insn_p (rtx_insn *);
@@ -412,6 +416,9 @@
#undef TARGET_ASM_FUNCTION_EPILOGUE
#define TARGET_ASM_FUNCTION_EPILOGUE arm_output_function_epilogue
+#undef TARGET_CAN_INLINE_P
+#define TARGET_CAN_INLINE_P arm_can_inline_p
+
#undef TARGET_OPTION_OVERRIDE
#define TARGET_OPTION_OVERRIDE arm_option_override
@@ -430,6 +437,12 @@
#undef TARGET_SCHED_ADJUST_COST
#define TARGET_SCHED_ADJUST_COST arm_adjust_cost
+#undef TARGET_SET_CURRENT_FUNCTION
+#define TARGET_SET_CURRENT_FUNCTION arm_set_current_function
+
+#undef TARGET_OPTION_VALID_ATTRIBUTE_P
+#define TARGET_OPTION_VALID_ATTRIBUTE_P arm_valid_target_attribute_p
+
#undef TARGET_SCHED_REORDER
#define TARGET_SCHED_REORDER arm_sched_reorder
@@ -2704,6 +2717,9 @@
}
}
+/* Options after initial target override. */
+static GTY(()) tree init_optimize;
+
/* Reset options between modes that the user has specified. */
static void
arm_option_override_internal (struct gcc_options *opts,
@@ -2726,6 +2742,10 @@
if (TREE_TARGET_THUMB (opts) && TARGET_CALLEE_INTERWORKING)
opts->x_target_flags |= MASK_INTERWORK;
+ /* need to remember initial values so combinaisons of options like
+ -mflip-thumb -mthumb -fno-schedule-insns work for any attribute. */
+ cl_optimization *to = TREE_OPTIMIZATION (init_optimize);
+
if (! opts_set->x_arm_restrict_it)
opts->x_arm_restrict_it = arm_arch8;
@@ -2733,15 +2753,17 @@
opts->x_arm_restrict_it = 0;
if (TREE_TARGET_THUMB1 (opts))
- {
- /* Don't warn since it's on by default in -O2. */
- opts->x_flag_schedule_insns = 0;
- }
+ /* Don't warn since it's on by default in -O2. */
+ opts->x_flag_schedule_insns = 0;
+ else
+ opts->x_flag_schedule_insns = to->x_flag_schedule_insns;
/* 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))
opts->x_flag_shrink_wrap = false;
+ else
+ opts->x_flag_shrink_wrap = to->x_flag_shrink_wrap;
/* In Thumb1 mode, we emit the epilogue in RTL, but the last insn
- epilogue_insns - does not accurately model the corresponding insns
@@ -2753,6 +2775,8 @@
fipa-ra. */
if (TREE_TARGET_THUMB1 (opts))
opts->x_flag_ipa_ra = 0;
+ else
+ opts->x_flag_ipa_ra = to->x_flag_ipa_ra;
/* Thumb2 inline assembly code should always use unified syntax.
This will apply to ARM and Thumb1 eventually. */
@@ -3244,12 +3268,20 @@
&& (!arm_arch7 || !current_tune->prefer_ldrd_strd))
flag_schedule_fusion = 0;
+ /* Need to remember initial options before they are overriden. */
+ init_optimize = build_optimization_node (&global_options);
+
arm_option_override_internal (&global_options, &global_options_set);
arm_option_check_internal (&global_options);
arm_option_params_internal (&global_options);
/* Register global variables with the garbage collector. */
arm_add_gc_roots ();
+
+ /* Save the initial options in case the user does function specific
+ options. */
+ target_option_default_node = target_option_current_node
+ = build_target_option_node (&global_options);
}
static void
@@ -3403,13 +3435,20 @@
static void
arm_asm_trampoline_template (FILE *f)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (f, "\t.syntax unified\n");
+ else
+ fprintf (f, "\t.syntax divided\n");
+
if (TARGET_ARM)
{
+ fprintf (f, "\t.arm\n");
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", STATIC_CHAIN_REGNUM, PC_REGNUM);
asm_fprintf (f, "\tldr\t%r, [%r, #0]\n", PC_REGNUM, PC_REGNUM);
}
else if (TARGET_THUMB2)
{
+ fprintf (f, "\t.thumb\n");
/* The Thumb-2 trampoline is similar to the arm implementation.
Unlike 16-bit Thumb, we enter the stub in thumb mode. */
asm_fprintf (f, "\tldr.w\t%r, [%r, #4]\n",
@@ -24097,6 +24136,23 @@
return 0;
}
+/* Check that FUNC is called with a different mode. */
+
+bool
+arm_change_mode_p (tree func)
+{
+ if (TREE_CODE (func) != FUNCTION_DECL)
+ return false;
+
+ tree callee_tree = DECL_FUNCTION_SPECIFIC_TARGET (func);
+
+ if (!callee_tree)
+ callee_tree = target_option_default_node;
+
+ struct cl_target_option *callee_opts = TREE_TARGET_OPTION (callee_tree);
+
+ return (TREE_TARGET_THUMB (callee_opts) != TARGET_THUMB);
+}
/* Given the stack offsets and register mask in OFFSETS, decide how
many additional registers to push instead of subtracting a constant
@@ -25659,9 +25715,6 @@
{
int val;
- if (TARGET_UNIFIED_ASM)
- asm_fprintf (asm_out_file, "\t.syntax unified\n");
-
if (TARGET_BPABI)
{
const char *fpu_name;
@@ -29436,9 +29489,196 @@
&& CONSTANT_POOL_ADDRESS_P (XEXP (x, 0)));
}
+/* Remember the last target of arm_set_current_function. */
+static GTY(()) tree arm_previous_fndecl;
+
+/* Invalidate arm_previous_fndecl. */
+void
+arm_reset_previous_fndecl (void)
+{
+ arm_previous_fndecl = NULL_TREE;
+}
+
+/* Establish appropriate back-end context for processing the function
+ FNDECL. The argument might be NULL to indicate processing at top
+ level, outside of any function scope. */
+static void
+arm_set_current_function (tree fndecl)
+{
+ if (!fndecl || fndecl == arm_previous_fndecl)
+ return;
+
+ tree old_tree = (arm_previous_fndecl
+ ? DECL_FUNCTION_SPECIFIC_TARGET (arm_previous_fndecl)
+ : NULL_TREE);
+
+ tree new_tree = DECL_FUNCTION_SPECIFIC_TARGET (fndecl);
+
+ arm_previous_fndecl = fndecl;
+ if (old_tree == new_tree)
+ ;
+
+ else if (new_tree)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ else if (old_tree)
+ {
+ new_tree = target_option_current_node;
+
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (new_tree));
+ if (TREE_TARGET_GLOBALS (new_tree))
+ restore_target_globals (TREE_TARGET_GLOBALS (new_tree));
+ else if (new_tree == target_option_default_node)
+ restore_target_globals (&default_target_globals);
+ else
+ TREE_TARGET_GLOBALS (new_tree)
+ = save_target_globals_default_opts ();
+ }
+
+ arm_option_params_internal (&global_options);
+}
+
+/* Hook to determine if one function can safely inline another. */
+
+static bool
+arm_can_inline_p (tree caller ATTRIBUTE_UNUSED, tree callee ATTRIBUTE_UNUSED)
+{
+ /* Overidde default hook: Always OK to inline between different modes.
+ Function with mode specific instructions, e.g using asm, must be explicitely
+ protected with noinline. */
+ return true;
+}
+
+/* Inner function to process the attribute((target(...))), take an argument and
+ set the current options from the argument. If we have a list, recursively
+ go over the list. */
+
+static bool
+arm_valid_target_attribute_rec (tree args, struct gcc_options *opts)
+{
+ if (TREE_CODE (args) == TREE_LIST)
+ {
+ bool ret = true;
+ for (; args; args = TREE_CHAIN (args))
+ if (TREE_VALUE (args)
+ && !arm_valid_target_attribute_rec (TREE_VALUE (args), opts))
+ ret = false;
+ return ret;
+ }
+
+ else if (TREE_CODE (args) != STRING_CST)
+ {
+ error ("attribute %<target%> argument not a string");
+ return false;
+ }
+
+ char *argstr = ASTRDUP (TREE_STRING_POINTER (args));
+ while (argstr && *argstr != '\0')
+ {
+ while (ISSPACE (*argstr))
+ argstr++;
+
+ if (!strncmp (argstr, "thumb", 5))
+ {
+ opts->x_target_flags |= MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ if (!strncmp (argstr, "arm", 3))
+ {
+ opts->x_target_flags &= ~MASK_THUMB;
+ arm_option_check_internal (opts);
+ return true;
+ }
+
+ warning (0, "attribute(target(\"%s\")) is unknown", argstr);
+ return false;
+ }
+
+ return false;
+}
+
+/* Return a TARGET_OPTION_NODE tree of the target options listed or NULL. */
+
+tree
+arm_valid_target_attribute_tree (tree args, struct gcc_options *opts,
+ struct gcc_options *opts_set)
+{
+ if (!arm_valid_target_attribute_rec (args, opts))
+ return NULL_TREE;
+
+ /* Do any overrides, such as global options arch=xxx. */
+ arm_option_override_internal (opts, opts_set);
+
+ return build_target_option_node (opts);
+}
+
+/* Hook to validate attribute((target("string"))). */
+
+static bool
+arm_valid_target_attribute_p (tree fndecl, tree ARG_UNUSED (name),
+ tree args, int ARG_UNUSED (flags))
+{
+ bool ret = true;
+ struct gcc_options func_options;
+ tree cur_tree, new_optimize;
+ gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
+
+ /* Get the optimization options of the current function. */
+ tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
+
+ /* If the function changed the optimization levels as well as setting target
+ options, start with the optimizations specified. */
+ if (!func_optimize)
+ func_optimize = optimization_default_node;
+
+ /* Init func_options. */
+ memset (&func_options, 0, sizeof (func_options));
+ init_options_struct (&func_options, NULL);
+ lang_hooks.init_options_struct (&func_options);
+
+ /* Initialize func_options to the defaults. */
+ cl_optimization_restore (&func_options,
+ TREE_OPTIMIZATION (func_optimize));
+
+ cl_target_option_restore (&func_options,
+ TREE_TARGET_OPTION (target_option_default_node));
+
+ /* Set func_options flags with new target mode. */
+ cur_tree = arm_valid_target_attribute_tree (args, &func_options,
+ &global_options_set);
+
+ if (cur_tree == NULL_TREE)
+ ret = false;
+
+ new_optimize = build_optimization_node (&func_options);
+
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
+
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+
+ return ret;
+}
+
void
arm_declare_function_name (FILE *stream, const char *name, tree decl)
{
+ if (TARGET_UNIFIED_ASM)
+ fprintf (stream, "\t.syntax unified\n");
+ else
+ fprintf (stream, "\t.syntax divided\n");
+
if (TARGET_THUMB)
{
if (is_called_in_ARM_mode (decl)
@@ -29450,6 +29690,8 @@
else
fprintf (stream, "\t.thumb\n\t.thumb_func\n");
}
+ else
+ fprintf (stream, "\t.arm\n");
if (TARGET_POKE_FUNCTION_NAME)
arm_poke_function_name (stream, (const char *) name);
diff -ruN '--exclude=.svn' a3/gcc/gcc/config/arm/arm.h a4/gcc/gcc/config/arm/arm.h
--- a3/gcc/gcc/config/arm/arm.h 2015-01-22 13:53:11.218901428 +0100
+++ a4/gcc/gcc/config/arm/arm.h 2015-01-22 13:56:30.235226925 +0100
@@ -2360,4 +2360,8 @@
#define DRIVER_SELF_SPECS MCPU_MTUNE_NATIVE_SPECS
#define TARGET_SUPPORTS_WIDE_INT 1
+
+/* For switching between functions with different target attributes. */
+#define SWITCHABLE_TARGET 1
+
#endif /* ! GCC_ARM_H */
diff -ruN '--exclude=.svn' a3/gcc/gcc/config/arm/arm.md a4/gcc/gcc/config/arm/arm.md
--- a3/gcc/gcc/config/arm/arm.md 2015-02-05 09:20:12.657396298 +0100
+++ a4/gcc/gcc/config/arm/arm.md 2015-02-05 09:20:12.233395613 +0100
@@ -7722,6 +7722,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))"
"*
{
+ rtx op = operands[0];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\";
}"
[(set_attr "type" "call")]
@@ -7739,6 +7746,13 @@
&& !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))"
"*
{
+ rtx op = operands[1];
+
+ /* Switch mode now when possible. */
+ if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op))
+ && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op)))
+ return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\";
+
return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\";
}"
[(set_attr "type" "call")]
diff -ruN '--exclude=.svn' a3/gcc/gcc/config/arm/arm.opt a4/gcc/gcc/config/arm/arm.opt
--- a3/gcc/gcc/config/arm/arm.opt 2015-01-22 13:53:11.222901435 +0100
+++ a4/gcc/gcc/config/arm/arm.opt 2015-02-09 12:34:43.188559954 +0100
@@ -182,7 +182,7 @@
Specify the minimum bit alignment of structures
mthumb
-Target Report RejectNegative Mask(THUMB)
+Target Report RejectNegative Mask(THUMB) Save
Generate code for Thumb state
mthumb-interwork
@@ -240,7 +240,7 @@
Only generate absolute relocations on word sized values.
mrestrict-it
-Target Report Var(arm_restrict_it) Init(2)
+Target Report Var(arm_restrict_it) Init(2) Save
Generate IT blocks appropriate for ARMv8.
mold-rtx-costs
@@ -269,5 +269,5 @@
Assume loading data from flash is slower than fetching instructions.
masm-syntax-unified
-Target Report Var(inline_asm_unified) Init(0)
+Target Report Var(inline_asm_unified) Init(0) Save
Assume unified syntax for Thumb inline assembly code.
diff -ruN '--exclude=.svn' a3/gcc/gcc/config/arm/arm-protos.h a4/gcc/gcc/config/arm/arm-protos.h
--- a3/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:53:11.222901435 +0100
+++ a4/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:56:30.239226931 +0100
@@ -214,6 +214,9 @@
extern int arm_dllimport_p (tree);
extern void arm_mark_dllexport (tree);
extern void arm_mark_dllimport (tree);
+extern bool arm_change_mode_p (tree);
+extern tree arm_valid_target_attribute_tree (tree, struct gcc_options *,
+ struct gcc_options *);
#endif
extern void arm_pr_long_calls (struct cpp_reader *);
@@ -316,6 +319,8 @@
extern void arm_emit_eabi_attribute (const char *, int, int);
+extern void arm_reset_previous_fndecl (void);
+
/* Defined in gcc/common/config/arm-common.c. */
extern const char *arm_rewrite_selected_cpu (const char *name);
diff -ruN '--exclude=.svn' a3/gcc/gcc/doc/extend.texi a4/gcc/gcc/doc/extend.texi
--- a3/gcc/gcc/doc/extend.texi 2015-02-05 09:18:12.909233395 +0100
+++ a4/gcc/gcc/doc/extend.texi 2015-02-05 09:21:38.749534626 +0100
@@ -3996,10 +3996,25 @@
strings to specify multiple options, or separate the options
with a comma (@samp{,}).
-The @code{target} attribute is presently implemented for
-x86, PowerPC, and Nios II targets only.
+The @code{target} attribute is implemented for
+ARM, x86, PowerPC, and Nios II targets.
+
The options supported are specific to each target.
+for ARM, the following options are allowed:
+
+@table @samp
+@item thumb
+@cindex @code{target("thumb")} attribute
+Force Thumb1 Thumb2 code generation depending on the architecture.
+
+@item arm
+@cindex @code{target("arm")} attribute
+Force ARM code generation.
+@end table
+
+Functions from different modes can be inlined , unless the callee has asm statements.
+
On the x86, the following options are allowed:
@table @samp
@@ -17795,8 +17810,9 @@
@xref{Function Attributes}, for more information about the
@code{target} attribute and the attribute syntax.
-The @code{#pragma GCC target} pragma is presently implemented for
-x86, PowerPC, and Nios II targets only.
+The @code{#pragma GCC target} pragma is implemented for
+ARM, x86, PowerPC, and Nios II targets.
+
@end table
@table @code
diff -ruN '--exclude=.svn' a3/gcc/gcc/doc/invoke.texi a4/gcc/gcc/doc/invoke.texi
--- a3/gcc/gcc/doc/invoke.texi 2015-02-05 09:18:12.913233401 +0100
+++ a4/gcc/gcc/doc/invoke.texi 2015-02-05 09:18:24.465248626 +0100
@@ -13149,6 +13149,10 @@
configuring GCC with the @option{--with-mode=}@var{state}
configure option.
+You can also override the ARM and Thumb mode for each function
+by using the @code{target("thumb")} and @code{target("arm")} function attributes
+(@pxref{Function Attributes}) or pragmas (@pxref{Function Specific Option Pragmas}).
+
@item -mtpcs-frame
@opindex mtpcs-frame
Generate a stack frame that is compliant with the Thumb Procedure Call
diff -ruN '--exclude=.svn' a3/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c a4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c
--- a3/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 1970-01-01 01:00:00.000000000 +0100
+++ a4/gcc/gcc/testsuite/gcc.target/arm/attr_arm.c 2015-01-15 13:35:12.135273352 +0100
@@ -0,0 +1,13 @@
+/* Check that attribute target arm is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".arm" } } */
+/* { dg-final { scan-assembler-not "ite" } } */
+
+int __attribute__((target("arm")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
diff -ruN '--exclude=.svn' a3/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c a4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c
--- a3/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 1970-01-01 01:00:00.000000000 +0100
+++ a4/gcc/gcc/testsuite/gcc.target/arm/attr_arm-err.c 2015-01-15 13:35:12.139273358 +0100
@@ -0,0 +1,13 @@
+/* Check that attribute target arm is rejected for M profile. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_arm_ok } */
+/* { dg-skip-if "avoid conflicting multilib options" { *-*-* } { "-march=*" } { "-march=armv6-m" } } */
+/* { dg-add-options arm_arch_v6m } */
+
+int __attribute__((target("arm")))
+foo(int a)
+{ /* { dg-error "does not support" } */
+ return a ? 1 : 5;
+}
+
+
diff -ruN '--exclude=.svn' a3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c a4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c
--- a3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 1970-01-01 01:00:00.000000000 +0100
+++ a4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb.c 2015-01-15 13:35:12.139273358 +0100
@@ -0,0 +1,13 @@
+/* Check that attribute target thumb is recogniwed. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb2_ok } */
+/* { dg-options "-O2" } */
+/* { dg-final { scan-assembler ".thumb" } } */
+/* { dg-final { scan-assembler "ite" } } */
+
+int __attribute__((target("thumb")))
+foo(int a)
+{
+ return a ? 1 : 5;
+}
+
diff -ruN '--exclude=.svn' a3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c a4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c
--- a3/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c 1970-01-01 01:00:00.000000000 +0100
+++ a4/gcc/gcc/testsuite/gcc.target/arm/attr_thumb-static.c 2015-01-15 13:35:12.139273358 +0100
@@ -0,0 +1,24 @@
+/* Check that a change mode to a static function is correctly handled. */
+/* { dg-do run } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+static void
+ __attribute__((__noinline__))
+foo (void)
+{
+ __asm__ ("");
+}
+
+static void
+__attribute__((__noinline__))
+__attribute__((target("thumb")))
+bar (void)
+{
+ __asm__ ("");
+}
+
+int main()
+{
+ foo();
+ bar();
+}
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #6: p5.patch --]
[-- Type: text/x-patch; name="p5.patch", Size: 5920 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.h (REGISTER_TARGET_PRAGMAS):
Call arm_register_target_pragmas.
* config/arm/arm-protos.h (arm_register_target_pragmas): Declare.
* config/arm/arm-c.c (arm_register_target_pragmas): New function.
(arm_pragma_target_parse): Likewise.
diff -ruN '--exclude=.svn' a4/gcc/gcc/config/arm/arm-c.c a5/gcc/gcc/config/arm/arm-c.c
--- a4/gcc/gcc/config/arm/arm-c.c 2015-01-15 13:35:07.195265398 +0100
+++ a5/gcc/gcc/config/arm/arm-c.c 2015-01-15 13:36:28.935397056 +0100
@@ -20,7 +20,6 @@
#include "system.h"
#include "coretypes.h"
#include "tm.h"
-#include "tm_p.h"
#include "hash-set.h"
#include "machmode.h"
#include "vec.h"
@@ -31,7 +30,11 @@
#include "wide-int.h"
#include "inchash.h"
#include "tree.h"
+#include "tm_p.h"
#include "c-family/c-common.h"
+#include "target.h"
+#include "target-def.h"
+#include "c-family/c-pragma.h"
/* Output C specific EABI object attributes. These can not be done in
arm.c because they require information from the C frontend. */
@@ -121,3 +124,79 @@
cpp_def_or_undef (in, "__ARM_ASM_SYNTAX_UNIFIED__", inline_asm_unified);
}
+/* Hook to validate the current #pragma GCC target and set the arch custom
+ mode state. If ARGS is NULL, then POP_TARGET is used to reset
+ the options. */
+static bool
+arm_pragma_target_parse (tree args, tree pop_target)
+{
+ tree prev_tree = build_target_option_node (&global_options);
+ tree cur_tree;
+ struct cl_target_option *prev_opt;
+ struct cl_target_option *cur_opt;
+ bool cur_mode, prev_mode;
+
+ if (! args)
+ {
+ cur_tree = ((pop_target) ? pop_target : target_option_default_node);
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (cur_tree));
+ }
+ else
+ {
+ cur_tree = arm_valid_target_attribute_tree (args, &global_options,
+ &global_options_set);
+ if (cur_tree == NULL_TREE)
+ {
+ cl_target_option_restore (&global_options,
+ TREE_TARGET_OPTION (prev_tree));
+ return false;
+ }
+ }
+
+ target_option_current_node = cur_tree;
+ arm_reset_previous_fndecl ();
+
+ /* Figure out the previous mode. */
+ prev_opt = TREE_TARGET_OPTION (prev_tree);
+ cur_opt = TREE_TARGET_OPTION (cur_tree);
+
+ gcc_assert (prev_opt);
+ gcc_assert (cur_opt);
+
+ cur_mode = TARGET_THUMB_P (cur_opt->x_target_flags);
+ prev_mode = TARGET_THUMB_P (prev_opt->x_target_flags);
+
+ if (prev_mode != cur_mode)
+ {
+ /* For the definitions, ensure all newly defined macros are considered
+ as used for -Wunused-macros. There is no point warning about the
+ compiler predefined macros. */
+ cpp_options *cpp_opts = cpp_get_options (parse_in);
+ unsigned char saved_warn_unused_macros = cpp_opts->warn_unused_macros;
+ cpp_opts->warn_unused_macros = 0;
+
+ /* Update macros. */
+ arm_cpp_builtins (parse_in, cur_mode);
+
+ cpp_opts->warn_unused_macros = saved_warn_unused_macros;
+ }
+
+ return true;
+}
+
+/* Register target pragmas. We need to add the hook for parsing #pragma GCC
+ option here rather than in arm.c since it will pull in various preprocessor
+ functions, and those are not present in languages like fortran without a
+ preprocessor. */
+
+void
+arm_register_target_pragmas (void)
+{
+ /* Update pragma hook to allow parsing #pragma GCC target. */
+ targetm.target_option.pragma_parse = arm_pragma_target_parse;
+
+#ifdef REGISTER_SUBTARGET_PRAGMAS
+ REGISTER_SUBTARGET_PRAGMAS ();
+#endif
+}
diff -ruN '--exclude=.svn' a4/gcc/gcc/config/arm/arm.h a5/gcc/gcc/config/arm/arm.h
--- a4/gcc/gcc/config/arm/arm.h 2015-01-22 13:56:30.235226925 +0100
+++ a5/gcc/gcc/config/arm/arm.h 2015-01-22 13:56:45.251251411 +0100
@@ -2098,7 +2098,8 @@
c_register_pragma (0, "long_calls", arm_pr_long_calls); \
c_register_pragma (0, "no_long_calls", arm_pr_no_long_calls); \
c_register_pragma (0, "long_calls_off", arm_pr_long_calls_off); \
- arm_lang_object_attributes_init(); \
+ arm_lang_object_attributes_init(); \
+ arm_register_target_pragmas(); \
} while (0)
/* Condition code information. */
diff -ruN '--exclude=.svn' a4/gcc/gcc/config/arm/arm-protos.h a5/gcc/gcc/config/arm/arm-protos.h
--- a4/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:56:30.239226931 +0100
+++ a5/gcc/gcc/config/arm/arm-protos.h 2015-01-22 13:56:45.255251418 +0100
@@ -326,6 +326,7 @@
/* Defined in gcc/common/config/arm-c.c. */
extern void arm_lang_object_attributes_init(void);
+extern void arm_register_target_pragmas (void);
extern void arm_cpp_builtins (struct cpp_reader *, bool);
extern bool arm_is_constant_pool_ref (rtx);
diff -ruN '--exclude=.svn' a4/gcc/gcc/testsuite/gcc.target/arm/pragma_attribute.c a5/gcc/gcc/testsuite/gcc.target/arm/pragma_attribute.c
--- a4/gcc/gcc/testsuite/gcc.target/arm/pragma_attribute.c 1970-01-01 01:00:00.000000000 +0100
+++ a5/gcc/gcc/testsuite/gcc.target/arm/pragma_attribute.c 2015-01-15 13:36:28.935397056 +0100
@@ -0,0 +1,35 @@
+/* Test for #prama target macros. */
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_thumb1_ok } */
+
+#pragma GCC target ("thumb")
+
+#ifndef __thumb__
+#error "__thumb__ is not defined"
+#endif
+
+#ifdef __thumb2__
+#ifndef __ARM_32BIT_STATE
+#error "__ARM_32BIT_STATE is not defined"
+#endif
+#else /* thumb1 */
+#ifdef __ARM_32BIT_STATE
+#error "__ARM_32BIT_STATE is defined"
+#endif
+#endif /* thumb1 */
+
+#pragma GCC target ("arm")
+
+#ifdef __thumb__
+#error "__thumb__ is defined"
+#endif
+
+#if defined (__thumb2__) || defined (__thumb1__)
+#error "thumb is defined"
+#endif
+
+#ifndef __ARM_32BIT_STATE
+#error "__ARM_32BIT_STATE is not defined"
+#endif
+
+#pragma GCC reset_options
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #7: p6.patch --]
[-- Type: text/x-patch; name="p6.patch", Size: 5214 bytes --]
2014-09-23 Christian Bruel <christian.bruel@st.com>
* config/arm/arm.c (add_attribute, arm_insert_attributes): New functions
(TARGET_INSERT_ATTRIBUTES): Define.
(thumb_flipper): New var.
* config/arm/arm.opt (-mflip-thumb): New switch.
diff -ruN '--exclude=.svn' gnu_trunk.devs5/gcc/gcc/config/arm/arm.c gnu_trunk.devs6/gcc/gcc/config/arm/arm.c
--- gnu_trunk.devs5/gcc/gcc/config/arm/arm.c 2015-02-05 09:21:44.449543733 +0100
+++ gnu_trunk.devs6/gcc/gcc/config/arm/arm.c 2015-02-05 09:21:56.821563455 +0100
@@ -99,6 +99,7 @@
#include "tm-constrs.h"
#include "rtl-iter.h"
#include "sched-int.h"
+#include "tree.h"
/* Forward definitions of types. */
typedef struct minipool_node Mnode;
@@ -232,6 +233,7 @@
static void arm_file_end (void);
static void arm_file_start (void);
+static void arm_insert_attributes (tree, tree *);
static void arm_setup_incoming_varargs (cumulative_args_t, machine_mode,
tree, int *, int);
@@ -390,6 +392,9 @@
#undef TARGET_ATTRIBUTE_TABLE
#define TARGET_ATTRIBUTE_TABLE arm_attribute_table
+#undef TARGET_INSERT_ATTRIBUTES
+#define TARGET_INSERT_ATTRIBUTES arm_insert_attributes
+
#undef TARGET_ASM_FILE_START
#define TARGET_ASM_FILE_START arm_file_start
#undef TARGET_ASM_FILE_END
@@ -2717,6 +2722,10 @@
}
}
+/* True if -mflip-thumb should next add an attribute for the default
+ mode, false if it should next add an attribute for the opposite mode. */
+static GTY(()) bool thumb_flipper;
+
/* Options after initial target override. */
static GTY(()) tree init_optimize;
@@ -3282,6 +3291,9 @@
options. */
target_option_default_node = target_option_current_node
= build_target_option_node (&global_options);
+
+ /* Init initial mode for testing. */
+ thumb_flipper = TARGET_THUMB;
}
static void
@@ -29624,6 +29636,52 @@
return build_target_option_node (opts);
}
+static void
+add_attribute (const char * mode, tree *attributes)
+{
+ size_t len = strlen (mode);
+ tree value = build_string (len, mode);
+
+ TREE_TYPE (value) = build_array_type (char_type_node,
+ build_index_type (size_int (len)));
+
+ *attributes = tree_cons (get_identifier ("target"),
+ build_tree_list (NULL_TREE, value),
+ *attributes);
+}
+
+/* For testing. Insert thumb or arm modes alternatively on functions. */
+
+static void
+arm_insert_attributes (tree fndecl, tree * attributes)
+{
+ const char *mode;
+
+ if (! TARGET_FLIP_THUMB)
+ return;
+
+ if (TREE_CODE (fndecl) != FUNCTION_DECL || DECL_EXTERNAL(fndecl)
+ || DECL_BUILT_IN (fndecl) || DECL_ARTIFICIAL (fndecl))
+ return;
+
+ /* Nested definitions must inherit mode. */
+ if (current_function_decl)
+ {
+ mode = TARGET_THUMB ? "thumb" : "arm";
+ add_attribute (mode, attributes);
+ return;
+ }
+
+ /* If there is already a setting don't change it. */
+ if (lookup_attribute ("target", *attributes) != NULL)
+ return;
+
+ mode = thumb_flipper ? "thumb" : "arm";
+ add_attribute (mode, attributes);
+
+ thumb_flipper = !thumb_flipper;
+}
+
/* Hook to validate attribute((target("string"))). */
static bool
@@ -29635,13 +29693,15 @@
tree cur_tree, new_optimize;
gcc_assert ((fndecl != NULL_TREE) && (args != NULL_TREE));
+ tree old_optimize = build_optimization_node (&global_options);
+
/* Get the optimization options of the current function. */
tree func_optimize = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl);
/* If the function changed the optimization levels as well as setting target
options, start with the optimizations specified. */
if (!func_optimize)
- func_optimize = optimization_default_node;
+ func_optimize = old_optimize;
/* Init func_options. */
memset (&func_options, 0, sizeof (func_options));
@@ -29659,14 +29719,17 @@
cur_tree = arm_valid_target_attribute_tree (args, &func_options,
&global_options_set);
- if (cur_tree == NULL_TREE)
- ret = false;
-
new_optimize = build_optimization_node (&func_options);
- DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
+ if (cur_tree == NULL_TREE)
+ ret = false;
+ else
+ {
+ DECL_FUNCTION_SPECIFIC_TARGET (fndecl) = cur_tree;
- DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+ if (old_optimize != new_optimize)
+ DECL_FUNCTION_SPECIFIC_OPTIMIZATION (fndecl) = new_optimize;
+ }
return ret;
}
diff -ruN '--exclude=.svn' gnu_trunk.devs5/gcc/gcc/config/arm/arm.opt gnu_trunk.devs6/gcc/gcc/config/arm/arm.opt
--- gnu_trunk.devs5/gcc/gcc/config/arm/arm.opt 2015-01-22 13:56:45.255251418 +0100
+++ gnu_trunk.devs6/gcc/gcc/config/arm/arm.opt 2015-01-21 18:18:16.166984018 +0100
@@ -122,6 +122,10 @@
EnumValue
Enum(float_abi_type) String(hard) Value(ARM_FLOAT_ABI_HARD)
+mflip-thumb
+Target Report Var(TARGET_FLIP_THUMB)
+Switch ARM/Thumb modes on alternating functions for compiler testing
+
mfp16-format=
Target RejectNegative Joined Enum(arm_fp16_format_type) Var(arm_fp16_format) Init(ARM_FP16_FORMAT_NONE)
Specify the __fp16 floating-point format
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ping: [PATCH, ARM] attribute target (thumb,arm) [0-6]
2015-04-20 8:35 ` Christian Bruel
@ 2015-04-30 8:27 ` Ramana Radhakrishnan
2015-04-30 8:41 ` Christian Bruel
0 siblings, 1 reply; 8+ messages in thread
From: Ramana Radhakrishnan @ 2015-04-30 8:27 UTC (permalink / raw)
To: Christian Bruel; +Cc: Ramana Radhakrishnan, richard Earnshaw, gcc-patches
On Mon, Apr 20, 2015 at 9:35 AM, Christian Bruel <christian.bruel@st.com> wrote:
> Hello Ramana
>
>>>
>>
>> Can you respin this now that we are in stage1 again ?
>>
>> Ramana
>>
>
> Attached the rebased, rechecked set of patches. Original with comments
> posted in
>
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02455.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02458.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02460.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02461.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02463.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02467.html
> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02468.html
>
> many thanks,
>
> Christian
A general note, please reply to each of the patches with a rebased
patch as a separate email. Further more all your patches appear to
have dos line endings so they don't seem to apply cleanly. Please
don't have spurious headers in your patch submission - it then makes
it hard to , please create it in a way that it is easily applied by
someone trying it out. It looks like p4 needs a respin as I got a
reject trying to apply the documentation patch to my tree while trying
to apply it.
I tried the following decoration on foo in gcc.target/arm/attr_arm.c
int __attribute__((target("arm, fpu=vfpv4")))
foo(int a)
{
return a ? 1 : 5;
}
And the compiler accepts it just fine.
Given that with LTO we are now using target attributes to decide
inlining - I'm not convinced that the inline asm case goes away. In
fact it only makes things worse so I'm almost convinced to forbid
inlining from "arm" to "thumb" or vice-versa, which is a reversal of
my earlier position. I hadn't twigged that LTO would reuse this
infrastructure and it's probably simpler to prevent inlining in those
cases.
Thoughts ?
So in essence I'm still playing with this and would like to iterate
towards a quick solution.
Ramana
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ping: [PATCH, ARM] attribute target (thumb,arm) [0-6]
2015-04-30 8:27 ` Ramana Radhakrishnan
@ 2015-04-30 8:41 ` Christian Bruel
2015-04-30 10:26 ` Ramana Radhakrishnan
0 siblings, 1 reply; 8+ messages in thread
From: Christian Bruel @ 2015-04-30 8:41 UTC (permalink / raw)
To: ramrad01; +Cc: Ramana Radhakrishnan, richard Earnshaw, gcc-patches
On 04/30/2015 09:43 AM, Ramana Radhakrishnan wrote:
> On Mon, Apr 20, 2015 at 9:35 AM, Christian Bruel <christian.bruel@st.com> wrote:
>> Hello Ramana
>>
>>>>
>>>
>>> Can you respin this now that we are in stage1 again ?
>>>
>>> Ramana
>>>
>>
>> Attached the rebased, rechecked set of patches. Original with comments
>> posted in
>>
>> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02455.html
>> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02458.html
>> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02460.html
>> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02461.html
>> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02463.html
>> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02467.html
>> https://gcc.gnu.org/ml/gcc-patches/2014-11/msg02468.html
>>
>> many thanks,
>>
>> Christian
>
>
> A general note, please reply to each of the patches with a rebased
> patch as a separate email. Further more all your patches appear to
> have dos line endings so they don't seem to apply cleanly. Please
> don't have spurious headers in your patch submission - it then makes
> it hard to , please create it in a way that it is easily applied by
> someone trying it out. It looks like p4 needs a respin as I got a
> reject trying to apply the documentation patch to my tree while trying
> to apply it.
>
OK, thanks for the suggestions and sorry for the p4 reject. The sources
are moving fast and I have hard times catching up with re-bases.
> I tried the following decoration on foo in gcc.target/arm/attr_arm.c
>
>
> int __attribute__((target("arm, fpu=vfpv4")))
> foo(int a)
> {
> return a ? 1 : 5;
> }
>
>
> And the compiler accepts it just fine.
Indeed, it's a mistake for now. attributes other the arm/thumb ones
shall be rejected (eventually with a "not yet implemented" warning for
the fpu, error for the others.) until we extend it.
>
> Given that with LTO we are now using target attributes to decide
> inlining - I'm not convinced that the inline asm case goes away. In
> fact it only makes things worse so I'm almost convinced to forbid
> inlining from "arm" to "thumb" or vice-versa, which is a reversal of
> my earlier position. I hadn't twigged that LTO would reuse this
> infrastructure and it's probably simpler to prevent inlining in those
> cases.
I can resurrect the inline check chunk. FYI, with a few small examples
arm/thumb attribute is correctly handled by LTO
>
> Thoughts ?
>
> So in essence I'm still playing with this and would like to iterate
> towards a quick solution.
>
thanks, that would be good if we could land the arm/thumb attribute and
start the fpu extensions separately. (I'm currently playing with
fpu=neon but it will take time to have something solid).
Christian
> Ramana
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ping: [PATCH, ARM] attribute target (thumb,arm) [0-6]
2015-04-30 8:41 ` Christian Bruel
@ 2015-04-30 10:26 ` Ramana Radhakrishnan
2015-05-20 13:13 ` Christian Bruel
0 siblings, 1 reply; 8+ messages in thread
From: Ramana Radhakrishnan @ 2015-04-30 10:26 UTC (permalink / raw)
To: Christian Bruel; +Cc: Richard Earnshaw, gcc-patches
>>> Christian
>>
>>
>> A general note, please reply to each of the patches with a rebased
>> patch as a separate email. Further more all your patches appear to
>> have dos line endings so they don't seem to apply cleanly. Please
>> don't have spurious headers in your patch submission - it then makes
>> it hard to , please create it in a way that it is easily applied by
>> someone trying it out. It looks like p4 needs a respin as I got a
>> reject trying to apply the documentation patch to my tree while trying
>> to apply it.
>>
>
> OK, thanks for the suggestions and sorry for the p4 reject. The sources
> are moving fast and I have hard times catching up with re-bases.
I understand.
>
>> I tried the following decoration on foo in gcc.target/arm/attr_arm.c
>>
>>
>> int __attribute__((target("arm, fpu=vfpv4")))
>> foo(int a)
>> {
>> return a ? 1 : 5;
>> }
>>
>>
>> And the compiler accepts it just fine.
>
> Indeed, it's a mistake for now. attributes other the arm/thumb ones
> shall be rejected (eventually with a "not yet implemented" warning for
> the fpu, error for the others.) until we extend it.
Yep - funnily enough if you remove "arm" and just use "fpu=vfpv4", I
think you get an error.
>
>>
>> Given that with LTO we are now using target attributes to decide
>> inlining - I'm not convinced that the inline asm case goes away. In
>> fact it only makes things worse so I'm almost convinced to forbid
>> inlining from "arm" to "thumb" or vice-versa, which is a reversal of
>> my earlier position. I hadn't twigged that LTO would reuse this
>> infrastructure and it's probably simpler to prevent inlining in those
>> cases.
>
> I can resurrect the inline check chunk. FYI, with a few small examples
> arm/thumb attribute is correctly handled by LTO
Yes it would work with normal C code as it does normally - I'm worried
about functions with inline asm. We've just increased the inlining scope
with lto and that would mean things are a bit more painful ?
>
>>
>> Thoughts ?
>>
>> So in essence I'm still playing with this and would like to iterate
>> towards a quick solution.
>>
>
> thanks, that would be good if we could land the arm/thumb attribute and
> start the fpu extensions separately. (I'm currently playing with
> fpu=neon but it will take time to have something solid).
Absolutely - I'd rather spend the time first in polishing this up.
Extending it for other options can be something you look at separately.
BTW I was pointed at a PR for this yesterday by a colleague -
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884
So, lets use that as the PR for this work.
regards
Ramana
>
> Christian
>
>> Ramana
>>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: ping: [PATCH, ARM] attribute target (thumb,arm) [0-6]
2015-04-30 10:26 ` Ramana Radhakrishnan
@ 2015-05-20 13:13 ` Christian Bruel
0 siblings, 0 replies; 8+ messages in thread
From: Christian Bruel @ 2015-05-20 13:13 UTC (permalink / raw)
To: Ramana Radhakrishnan; +Cc: gcc-patches
Hi Ramana,
>
> BTW I was pointed at a PR for this yesterday by a colleague -
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884
>
> So, lets use that as the PR for this work.
>
> regards
> Ramana
>
>
just to let you know that I've also found this old entry (2012):
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52144
I'm going to link all of those, and continue the review there
cheers
Christian
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2015-05-20 13:07 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-02-09 12:34 ping: [PATCH, ARM] attribute target (thumb,arm) [0-6] Christian Bruel
2015-02-09 12:45 ` Christian Bruel
2015-04-14 19:11 ` Ramana Radhakrishnan
2015-04-20 8:35 ` Christian Bruel
2015-04-30 8:27 ` Ramana Radhakrishnan
2015-04-30 8:41 ` Christian Bruel
2015-04-30 10:26 ` Ramana Radhakrishnan
2015-05-20 13:13 ` Christian Bruel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).