From: Luis Silva <[email protected]>

For ARC EM CPUs that enable code density by default, the driver adds
-mcode-density to the assembler command line.  When the user passes
-mno-code-density, the compiler disables the extension, but the driver
still passes -mcode-density to the assembler for those CPUs.

For example, with -mcpu=em4_dmips the driver invokes the assembler as:

        gcc ... -mcpu=em4_dmips -c test.c
        -> as ... -mcpu=arcem -mcode-density ...

With -mno-code-density, it used to make no difference:

        gcc ... -mcpu=em4_dmips -mno-code-density -c test.c
        -> as ... -mcpu=arcem -mcode-density ...

and now correctly omits -mcode-density:

        gcc ... -mcpu=em4_dmips -mno-code-density -c test.c
        -> as ... -mcpu=arcem ...

Assembling the same test program shows different instruction encodings
in the object file, for example:

        $ gcc -c test.c -mcpu=em4_dmips
        $ objdump -d test.o
           4:   4104                    ld_s    r1,[r0,0]
          10:   4004                    ld_s    r0,[r0,0]

versus:

        $ gcc -c test.c -mcpu=em4_dmips -mno-code-density
        $ objdump -d test.o
           4:   8020                    ld_s    r1,[r0,0]
          10:   8000                    ld_s    r0,[r0,0]

gcc/ChangeLog:

        * config/arc/arc.h (arc_cd_to_as): Declare.
        (EXTRA_SPEC_FUNCTIONS): Register cd_to_as.
        (ASM_SPEC): Call cd_to_as with the CPU name and code-density
        markers from -mcode-density/-mno-code-density.
        * config/arc/driver-arc.cc (arc_lookup_cpu): New helper.
        (arc_cpu_to_as): Drop code-density handling.
        (arc_cd_to_as): New spec function; add -mcode-density only when
        appropriate, and omit it for -mno-code-density.

Signed-off-by: Luis Silva <[email protected]>
---
 gcc/config/arc/arc.h         |  9 +++--
 gcc/config/arc/driver-arc.cc | 66 +++++++++++++++++++++++++-----------
 2 files changed, 53 insertions(+), 22 deletions(-)

diff --git a/gcc/config/arc/arc.h b/gcc/config/arc/arc.h
index f2a4f0de701..934ac6f89f4 100644
--- a/gcc/config/arc/arc.h
+++ b/gcc/config/arc/arc.h
@@ -70,9 +70,11 @@ along with GCC; see the file COPYING3.  If not see
 %{G*}                                                          \
 "
 extern const char *arc_cpu_to_as (int argc, const char **argv);
+extern const char *arc_cd_to_as (int argc, const char **argv);
 
 #define EXTRA_SPEC_FUNCTIONS                   \
-  { "cpu_to_as", arc_cpu_to_as },
+  { "cpu_to_as", arc_cpu_to_as },              \
+  { "cd_to_as", arc_cd_to_as },
 
 /* This macro defines names of additional specifications to put in the specs
    that can be used in various specifications like CC1_SPEC.  Its definition
@@ -97,8 +99,9 @@ extern const char *arc_cpu_to_as (int argc, const char 
**argv);
 
 #undef ASM_SPEC
 #define ASM_SPEC  "%{mbig-endian|EB:-EB} %{EL} "                       \
-  "%:cpu_to_as(%{mcpu=*:%*}) %{mspfp*} %{mdpfp*} "                      \
-  "%{mfpu=fpuda*:-mfpuda} %{mcode-density}"
+  "%:cpu_to_as(%{mcpu=*:%*}) "                                         \
+  "%:cd_to_as(%{mcpu=*:%*} %{mno-code-density:no-cd;mcode-density:cd}) " \
+  "%{mspfp*} %{mdpfp*} %{mfpu=fpuda*:-mfpuda}"
 
 /* Support for a compile-time default CPU and FPU.  The rules are:
    --with-cpu is ignored if -mcpu, mARC*, marc*, mA7, mA6 are specified.
diff --git a/gcc/config/arc/driver-arc.cc b/gcc/config/arc/driver-arc.cc
index b70b21cf231..b3efe87c67e 100644
--- a/gcc/config/arc/driver-arc.cc
+++ b/gcc/config/arc/driver-arc.cc
@@ -25,6 +25,25 @@
 #include "coretypes.h"
 #include "tm.h"
 
+/* Look up the CPU given by NAME, or the default CPU if NAME is NULL.  */
+
+static const arc_cpu_t *
+arc_lookup_cpu (const char *name)
+{
+  if (name == NULL)
+    return &arc_cpu_types[(int) TARGET_CPU_DEFAULT];
+
+  for (const arc_cpu_t *arc_selected_cpu = arc_cpu_types;
+       arc_selected_cpu->name;
+       arc_selected_cpu++)
+    {
+      if (strcmp (arc_selected_cpu->name, name) == 0)
+       return arc_selected_cpu;
+    }
+
+  gcc_unreachable ();
+}
+
 /* Returns command line parameters to pass to as.  */
 
 const char*
@@ -33,29 +52,12 @@ arc_cpu_to_as (int argc, const char **argv)
   const char *name = NULL;
   const arc_cpu_t *arc_selected_cpu;
 
-  /* No argument, check what is the default cpu.  */
-  if (argc == 0)
-    {
-      arc_selected_cpu = &arc_cpu_types[(int) TARGET_CPU_DEFAULT];
-    }
-  else
-    {
-      name = argv[0];
-      for (arc_selected_cpu = arc_cpu_types; arc_selected_cpu->name;
-          arc_selected_cpu++)
-       {
-         if (strcmp (arc_selected_cpu->name, name) == 0)
-           break;
-       }
-    }
+  arc_selected_cpu = arc_lookup_cpu (argc == 0 ? NULL : argv[0]);
 
   switch (arc_selected_cpu->arch_info->arch_id)
     {
     case BASE_ARCH_em:
-      if (arc_selected_cpu->flags & FL_CD)
-       name = "-mcode-density";
-      else
-       name = "";
+      name = "";
       if (arc_selected_cpu->flags & FL_FPUDA)
        name = concat ("-mfpuda ", name, NULL);
       if (arc_selected_cpu->flags & FL_SPFP)
@@ -81,3 +83,29 @@ arc_cpu_to_as (int argc, const char **argv)
     }
   return NULL;
 }
+
+/* Returns code density parameters to pass to as.  */
+
+const char *
+arc_cd_to_as (int argc, const char **argv)
+{
+  const char *name = NULL;
+  const arc_cpu_t *arc_selected_cpu;
+
+  for (int i = 0; i < argc; i++)
+    {
+      if (strcmp (argv[i], "no-cd") == 0)
+       return "";
+      else if (strcmp (argv[i], "cd") == 0)
+       return "-mcode-density";
+      else
+       name = argv[i];
+    }
+
+  arc_selected_cpu = arc_lookup_cpu (name);
+  if (arc_selected_cpu->arch_info->arch_id == BASE_ARCH_em
+      && (arc_selected_cpu->flags & FL_CD))
+    return "-mcode-density";
+
+  return "";
+}
-- 
2.47.3

Reply via email to