This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[Patch] Add options to Xtensa to prevent certain branch relaxations
- From: Sterling Augustine <sterling at tensilica dot com>
- To: binutils at sourceware dot org
- Date: Wed, 07 Jan 2009 09:40:00 -0800
- Subject: [Patch] Add options to Xtensa to prevent certain branch relaxations
Under certain circumstances, it is undesirable for the Xtensa port of
gas to relax branches into flix-style branches. The attached patch adds
options to control this behavior.
Tested under xtensa-unknown-elf
2009-01-07 Sterling Augustine <sterling@tensilica.com>
* config/tc-xtensa.c (produce_flix): New.
(option_flix, optoin_no_generate_flix, option_no_flix) Define.
(md_longopts): Add support for them.
(md_parse_option): Likewise.
(md_show_usage): Add help message.
(finish_vinsn): Don't allow multi-slot flix when produce_flix
option is set to FLIX_NONE.
* config/xtensa-relax.c (transition_applies): Only relax to
flix branches when produce_flix equals FLIX_ALL.
* config/xtensa-relax.h (flix_level, FLIX_ALL, FLIX_NO_GENERATE
FLIX_NONE): New.
(produce_flix): Declare.
Index: config/tc-xtensa.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-xtensa.c,v
retrieving revision 1.107
diff -u -p -r1.107 tc-xtensa.c
--- config/tc-xtensa.c 21 Nov 2008 22:13:31 -0000 1.107
+++ config/tc-xtensa.c 7 Jan 2009 01:06:32 -0000
@@ -591,6 +591,7 @@ static xtensa_opcode xtensa_waiti_opcode
/* Command-line Options. */
bfd_boolean use_literal_section = TRUE;
+enum flix_level produce_flix = FLIX_ALL;
static bfd_boolean align_targets = TRUE;
static bfd_boolean warn_unaligned_branch_targets = FALSE;
static bfd_boolean has_a0_b_retw = FALSE;
@@ -635,6 +636,10 @@ enum
option_density = OPTION_MD_BASE,
option_no_density,
+ option_flix,
+ option_no_generate_flix,
+ option_no_flix,
+
option_relax,
option_no_relax,
@@ -693,6 +698,10 @@ struct option md_longopts[] =
{ "density", no_argument, NULL, option_density },
{ "no-density", no_argument, NULL, option_no_density },
+ { "flix", no_argument, NULL, option_flix },
+ { "no-generate-flix", no_argument, NULL, option_no_generate_flix },
+ { "no-allow-flix", no_argument, NULL, option_no_flix },
+
/* Both "relax" and "generics" are deprecated and treated as equivalent
to the "transform" option. */
{ "relax", no_argument, NULL, option_relax },
@@ -775,6 +784,15 @@ md_parse_option (int c, char *arg)
case option_no_link_relax:
linkrelax = 0;
return 1;
+ case option_flix:
+ produce_flix = FLIX_ALL;
+ return 1;
+ case option_no_generate_flix:
+ produce_flix = FLIX_NO_GENERATE;
+ return 1;
+ case option_no_flix:
+ produce_flix = FLIX_NONE;
+ return 1;
case option_generics:
as_warn (_("--generics is deprecated; use --transform instead"));
return md_parse_option (option_transform, arg);
@@ -941,6 +959,16 @@ Xtensa options:\n\
--[no-]target-align [Do not] try to align branch targets\n\
--[no-]longcalls [Do not] emit 32-bit call sequences\n\
--[no-]transform [Do not] transform instructions\n\
+ --flix both allow hand-written and generate flix bundles\n\
+ --no-generate-flix allow hand-written but do not generate\n\
+ flix bundles\n\
+ --no-allow-flix neither allow hand-written nor generate\n\
+ flix bundles\n\
--rename-section old=new Rename section 'old' to 'new'\n", stream);
}
@@ -6180,6 +6208,14 @@ finish_vinsn (vliw_insn *vinsn)
if (vinsn->format == XTENSA_UNDEFINED)
vinsn->format = xg_find_narrowest_format (vinsn);
+ if (xtensa_format_num_slots (xtensa_default_isa, vinsn->format) > 1
+ && produce_flix == FLIX_NONE)
+ {
+ as_bad (_("The option \"--no-allow-flix\" prohibits multi-slot flix."));
+ xg_clear_vinsn (vinsn);
+ return;
+ }
+
if (vinsn->format == XTENSA_UNDEFINED)
{
as_where (&file_name, &line);
Index: config/xtensa-relax.c
===================================================================
RCS file: /cvs/src/src/gas/config/xtensa-relax.c,v
retrieving revision 1.18
diff -u -p -r1.18 xtensa-relax.c
--- config/xtensa-relax.c 4 Nov 2008 23:11:02 -0000 1.18
+++ config/xtensa-relax.c 7 Jan 2009 01:06:32 -0000
@@ -1543,9 +1543,12 @@ transition_applies (insn_pattern *initia
else if (!strcmp (option_name, "Loops"))
option_available = (XCHAL_HAVE_LOOPS == 1);
else if (!strcmp (option_name, "WideBranches"))
- option_available = (XCHAL_HAVE_WIDE_BRANCHES == 1);
+ option_available
+ = (XCHAL_HAVE_WIDE_BRANCHES == 1 && produce_flix == FLIX_ALL);
else if (!strcmp (option_name, "PredictedBranches"))
- option_available = (XCHAL_HAVE_PREDICTED_BRANCHES == 1);
+ option_available
+ = (XCHAL_HAVE_PREDICTED_BRANCHES == 1
+ && produce_flix == FLIX_ALL);
else if (!strcmp (option_name, "Booleans"))
option_available = (XCHAL_HAVE_BOOLEANS == 1);
else
Index: config/xtensa-relax.h
===================================================================
RCS file: /cvs/src/src/gas/config/xtensa-relax.h,v
retrieving revision 1.9
diff -u -p -r1.9 xtensa-relax.h
--- config/xtensa-relax.h 4 Nov 2008 23:11:02 -0000 1.9
+++ config/xtensa-relax.h 7 Jan 2009 01:06:32 -0000
@@ -177,4 +177,13 @@ extern TransitionTable *xg_build_widen_t
extern bfd_boolean xg_has_userdef_op_fn (OpType);
extern long xg_apply_userdef_op_fn (OpType, long);
+enum flix_level
+{
+ FLIX_ALL,
+ FLIX_NO_GENERATE,
+ FLIX_NONE
+};
+
+extern enum flix_level produce_flix;
+
#endif /* !XTENSA_RELAX_H */