This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
RE: [PATCH 0/2] [PUSHED/OBV] gas/arc: Add nps400 support to .cpu directive
- From: Claudiu Zissulescu <Claudiu dot Zissulescu at synopsys dot com>
- To: Andrew Burgess <andrew dot burgess at embecosm dot com>, Nick Clifton <nickc at redhat dot com>
- Cc: "binutils at sourceware dot org" <binutils at sourceware dot org>, Cupertino Miranda <Cupertino dot Miranda at synopsys dot com>
- Date: Wed, 20 Apr 2016 12:00:58 +0000
- Subject: RE: [PATCH 0/2] [PUSHED/OBV] gas/arc: Add nps400 support to .cpu directive
- Authentication-results: sourceware.org; auth=none
- References: <57174AF9 dot 2080603 at redhat dot com> <098ECE41A0A6114BB2A07F1EC238DE89661889E2 at de02wembxa dot internal dot synopsys dot com> <20160420112356 dot GJ6589 at embecosm dot com>
> I disagree and think it's a much worse idea. My concern was never
> about memory usage, my concern is data duplication, how long until we
> have a bug where one alias is configured slightly differently to
> another alias
This is one of the reason why macros have been introduced. For example:
#define A7_CPU_TYPE(NAME) { #NAME, ARC_OPCODE_ARC700, bfd_mach_arc_arc700, E_ARC_MACH_ARC700, 0x00}
Then you just enumerate it in the structure:
A7_CPU_TYPE (ARC700),
A7_CPU_TYPE (A7),
So on, so forth...
Attached is a patch that shows this concept, though it needs to be validated:
diff --git a/gas/config/tc-arc.c b/gas/config/tc-arc.c
index 169b05c..07e78df 100644
--- a/gas/config/tc-arc.c
+++ b/gas/config/tc-arc.c
@@ -408,6 +408,16 @@ static struct hash_control *arc_reg_hash;
/* The hash table of aux register symbols. */
static struct hash_control *arc_aux_hash;
+#define A6_CPU_TYPE(NAME) \
+ { #NAME, ARC_OPCODE_ARC600, bfd_mach_arc_arc600, E_ARC_MACH_ARC600, 0x00},
+#define A7_CPU_TYPE(NAME) \
+ { #NAME, ARC_OPCODE_ARC700, bfd_mach_arc_arc700, E_ARC_MACH_ARC700, 0x00},
+#define EM_CPU_TYPE(NAME) \
+ { #NAME, ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2, EF_ARC_CPU_ARCV2EM, ARC_CD},
+#define HS_CPU_TYPE(NAME) \
+ { #NAME, ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2, EF_ARC_CPU_ARCV2HS, ARC_CD},
+
+
/* A table of CPU names and opcode sets. */
static const struct cpu_type
{
@@ -419,17 +429,18 @@ static const struct cpu_type
}
cpu_types[] =
{
- { "arc600", ARC_OPCODE_ARC600, bfd_mach_arc_arc600,
- E_ARC_MACH_ARC600, 0x00},
- { "arc700", ARC_OPCODE_ARC700, bfd_mach_arc_arc700,
- E_ARC_MACH_ARC700, 0x00},
- { "nps400", ARC_OPCODE_ARC700 | ARC_OPCODE_NPS400, bfd_mach_arc_nps400,
+ A6_CPU_TYPE(ARC600)
+ A6_CPU_TYPE(ARC601)
+ A6_CPU_TYPE(ARC6)
+ A7_CPU_TYPE(ARC700)
+ A7_CPU_TYPE(A7)
+ { "NPS400", ARC_OPCODE_ARC700 | ARC_OPCODE_NPS400, bfd_mach_arc_nps400,
E_ARC_MACH_NPS400, 0x00},
- { "arcem", ARC_OPCODE_ARCv2EM, bfd_mach_arc_arcv2,
- EF_ARC_CPU_ARCV2EM, ARC_CD},
- { "archs", ARC_OPCODE_ARCv2HS, bfd_mach_arc_arcv2,
- EF_ARC_CPU_ARCV2HS, ARC_CD},
- { 0, 0, 0, 0, 0 }
+ EM_CPU_TYPE(ARCEM)
+ EM_CPU_TYPE(EM)
+ HS_CPU_TYPE(ARCHS)
+ HS_CPU_TYPE(HS)
+ { NULL, 0, 0, 0, 0 }
};
/* Used by the arc_reloc_op table. Order is important. */
@@ -861,6 +872,27 @@ arc_lcomm (int ignore)
symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
}
+/* Take the string passed to the .cpu directive and configure the assembler
+ as though the -mcpu option was used. Raises an error if the string is
+ not a valid cpu name. */
+
+static void
+arc_handle_cpu_option_string (const char *cpu)
+{
+ int i;
+
+ for (i = 0; cpu_types[i].name != NULL; ++i)
+ {
+ if (!strcmp (cpu_types[i].name, cpu))
+ {
+ md_parse_option (OPTION_MCPU, cpu_types[i].name);
+ return;
+ }
+ }
+
+ as_fatal (_("could not find the architecture"));
+}
+
/* Select the cpu we're assembling for. */
static void
@@ -878,31 +910,7 @@ arc_option (int ignore ATTRIBUTE_UNUSED)
if (!mach_type_specified_p)
{
- if ((!strcmp ("ARC600", cpu))
- || (!strcmp ("ARC601", cpu))
- || (!strcmp ("A6", cpu)))
- {
- md_parse_option (OPTION_MCPU, "arc600");
- }
- else if ((!strcmp ("ARC700", cpu))
- || (!strcmp ("A7", cpu)))
- {
- md_parse_option (OPTION_MCPU, "arc700");
- }
- else if (!strcmp ("EM", cpu))
- {
- md_parse_option (OPTION_MCPU, "arcem");
- }
- else if (!strcmp ("HS", cpu))
- {
- md_parse_option (OPTION_MCPU, "archs");
- }
- else if (!strcmp ("NPS400", cpu))
- {
- md_parse_option (OPTION_MCPU, "nps400");
- }
- else
- as_fatal (_("could not find the architecture"));
+ arc_handle_cpu_option_string (cpu);
if (!bfd_set_arch_mach (stdoutput, bfd_arch_arc, mach))
as_fatal (_("could not set architecture and machine"));
@@ -3238,21 +3246,49 @@ md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
return 1;
}
+/* Display the list of cpu names for use in the help text. */
+static void
+arc_show_cpu_list (FILE *stream)
+{
+ int i, offset;
+ static const char *spaces = " ";
+
+ fprintf (stream, "%s", spaces);
+ offset = strlen (spaces);
+ for (i = 0; cpu_types[i].name != NULL; ++i)
+ {
+ bfd_boolean last = (cpu_types[i + 1].name == NULL);
+
+ /* If displaying the new cpu name string, and the ', ' (for all but
+ the last one) will take us past a target width of 80 characters,
+ then it's time for a new line. */
+ if (offset + strlen (cpu_types[i].name) + (last ? 0 : 2) > 80)
+ {
+ fprintf (stream, "\n%s", spaces);
+ offset = strlen (spaces);
+ }
+
+ fprintf (stream, "%s%s", cpu_types[i].name, (last ? "\n" : ", "));
+ offset += strlen (cpu_types [i].name) + (last ? 0 : 2);
+ }
+}
+
void
md_show_usage (FILE *stream)
{
fprintf (stream, _("ARC-specific assembler options:\n"));
- fprintf (stream, " -mcpu=<cpu name>\t assemble for CPU <cpu name>\n");
- fprintf (stream,
- " -mcode-density\t enable code density option for ARC EM\n");
-
+ fprintf (stream, "\
+ -mcpu=<cpu name> assemble for CPU <cpu name>, one of:\n");
+ arc_show_cpu_list (stream);
+ fprintf (stream, "\
+ -mcode-density enable code density option for ARC EM\n");
fprintf (stream, _("\
-EB assemble code for a big-endian cpu\n"));
fprintf (stream, _("\
-EL assemble code for a little-endian cpu\n"));
fprintf (stream, _("\
- -mrelax Enable relaxation\n"));
+ -mrelax enable relaxation\n"));
}