[ARC] Fix and extend features of .cpu directive.
authorClaudiu Zissulescu <claziss@synopsys.com>
Thu, 17 Nov 2016 12:26:54 +0000 (13:26 +0100)
committerClaudiu Zissulescu <claziss@synopsys.com>
Fri, 18 Nov 2016 13:29:48 +0000 (14:29 +0100)
gas/
2016-11-18  Claudiu Zissulescu  <claziss@synopsys.com>

* testsuite/gas/arc/cl-warn.s: New file.
* testsuite/gas/arc/cpu-pseudop-1.d: Likewise.
* testsuite/gas/arc/cpu-pseudop-1.s: Likewise.
* testsuite/gas/arc/cpu-pseudop-2.d: Likewise.
* testsuite/gas/arc/cpu-pseudop-2.s: Likewise.
* testsuite/gas/arc/cpu-warn2.s: Likewise.
* config/tc-arc.c (selected_cpu): Initialize.
(feature_type): New struct.
(feature_list): New variable.
(arc_check_feature): New function.
(arc_select_cpu): Check for .cpu duplicates. Don't overwrite the
current cpu features. Check if a feature is available for a given
cpu.
(md_parse_option): Test if features are available for a given cpu.

gas/ChangeLog
gas/config/tc-arc.c
gas/testsuite/gas/arc/cl-warn.s [new file with mode: 0644]
gas/testsuite/gas/arc/cpu-pseudop-1.d [new file with mode: 0644]
gas/testsuite/gas/arc/cpu-pseudop-1.s [new file with mode: 0644]
gas/testsuite/gas/arc/cpu-pseudop-2.d [new file with mode: 0644]
gas/testsuite/gas/arc/cpu-pseudop-2.s [new file with mode: 0644]
gas/testsuite/gas/arc/cpu-warn2.s [new file with mode: 0644]

index 2ade09ce4135008079e564994f065da1bc771f8f..c95decc6bf9c5c5bf68a606080b8ecde19f96531 100644 (file)
@@ -1,3 +1,20 @@
+2016-11-18  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * testsuite/gas/arc/cl-warn.s: New file.
+       * testsuite/gas/arc/cpu-pseudop-1.d: Likewise.
+       * testsuite/gas/arc/cpu-pseudop-1.s: Likewise.
+       * testsuite/gas/arc/cpu-pseudop-2.d: Likewise.
+       * testsuite/gas/arc/cpu-pseudop-2.s: Likewise.
+       * testsuite/gas/arc/cpu-warn2.s: Likewise.
+       * config/tc-arc.c (selected_cpu): Initialize.
+       (feature_type): New struct.
+       (feature_list): New variable.
+       (arc_check_feature): New function.
+       (arc_select_cpu): Check for .cpu duplicates. Don't overwrite the
+       current cpu features. Check if a feature is available for a given
+       cpu.
+       (md_parse_option): Test if features are available for a given cpu.
+
 2016-11-18  Szabolcs Nagy  <szabolcs.nagy@arm.com>
 
        * config/tc-aarch64.c (parse_operands): Handle AARCH64_OPND_IMM_ROT*.
index 06aee48900c8875231bc1df44289bbe9d1c53cdd..376ac4332f59dfee9dce8fc5a25c44d1b738926e 100644 (file)
@@ -451,7 +451,23 @@ static const struct cpu_type
 };
 
 /* Information about the cpu/variant we're assembling for.  */
-static struct cpu_type selected_cpu;
+static struct cpu_type selected_cpu = { 0, 0, 0, 0, 0 };
+
+/* A table with options.  */
+static const struct feature_type
+{
+  unsigned feature;
+  unsigned cpus;
+  const char *name;
+}
+  feature_list[] =
+{
+  { ARC_CD, ARC_OPCODE_ARCV2, "code-density" },
+  { ARC_NPS400, ARC_OPCODE_ARC700, "nps400" },
+  { ARC_SPFP, ARC_OPCODE_ARCFPX, "single-precision FPX" },
+  { ARC_DPFP, ARC_OPCODE_ARCFPX, "double-precision FPX" },
+  { ARC_FPUDA, ARC_OPCODE_ARCv2EM, "double assist FP" }
+};
 
 /* Used by the arc_reloc_op table.  Order is important.  */
 #define O_gotoff  O_md1     /* @gotoff relocation.  */
@@ -775,6 +791,27 @@ md_number_to_chars_midend (char *buf, unsigned long long val, int n)
     }
 }
 
+/* Check if a feature is allowed for a specific CPU.  */
+
+static void
+arc_check_feature (void)
+{
+  unsigned i;
+
+  if (!selected_cpu.features
+      || !selected_cpu.name)
+    return;
+  for (i = 0; (i < ARRAY_SIZE (feature_list)); i++)
+    {
+      if ((selected_cpu.features & feature_list[i].feature)
+         && !(selected_cpu.flags & feature_list[i].cpus))
+       {
+         as_bad (_("invalid %s option for %s cpu"), feature_list[i].name,
+                 selected_cpu.name);
+       }
+    }
+}
+
 /* Select an appropriate entry from CPU_TYPES based on ARG and initialise
    the relevant static global variables.  Parameter SEL describes where
    this selection originated from.  */
@@ -790,6 +827,10 @@ arc_select_cpu (const char *arg, enum mach_selection_type sel)
   gas_assert (sel != MACH_SELECTION_FROM_DEFAULT
               || mach_selection_mode == MACH_SELECTION_NONE);
 
+  if ((mach_selection_mode == MACH_SELECTION_FROM_CPU_DIRECTIVE)
+      && (sel == MACH_SELECTION_FROM_CPU_DIRECTIVE))
+    as_bad (_("Multiple .cpu directives found"));
+
   /* Look for a matching entry in CPU_TYPES array.  */
   for (i = 0; cpu_types[i].name; ++i)
     {
@@ -807,22 +848,25 @@ arc_select_cpu (const char *arg, enum mach_selection_type sel)
                   && selected_cpu.mach != cpu_types[i].mach)
                 {
                   as_warn (_("Command-line value overrides \".cpu\" directive"));
-                  return;
                 }
+             return;
             }
 
-          /* Initialise static global data about selected machine type.  */
-          selected_cpu.flags = cpu_types[i].flags;
-          selected_cpu.name = cpu_types[i].name;
-          selected_cpu.features = cpu_types[i].features;
-          selected_cpu.mach = cpu_types[i].mach;
-          cpu_flags = cpu_types[i].eflags;
+         /* Initialise static global data about selected machine type.  */
+         selected_cpu.flags = cpu_types[i].flags;
+         selected_cpu.name = cpu_types[i].name;
+         selected_cpu.features |= cpu_types[i].features;
+         selected_cpu.mach = cpu_types[i].mach;
+         cpu_flags = cpu_types[i].eflags;
           break;
         }
     }
 
   if (!cpu_types[i].name)
     as_fatal (_("unknown architecture: %s\n"), arg);
+
+  /* Check if set features are compatible with the chosen CPU.  */
+  arc_check_feature ();
   gas_assert (cpu_flags != 0);
   selected_cpu.eflags = (arc_initial_eflag & ~EF_ARC_MACH_MSK) | cpu_flags;
   mach_selection_mode = sel;
@@ -3304,11 +3348,8 @@ md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
       break;
 
     case OPTION_CD:
-      /* This option has an effect only on ARC EM.  */
-      if (selected_cpu.flags & ARC_OPCODE_ARCv2EM)
-       selected_cpu.features |= ARC_CD;
-      else
-       as_warn (_("Code density option invalid for selected CPU"));
+      selected_cpu.features |= ARC_CD;
+      arc_check_feature ();
       break;
 
     case OPTION_RELAX:
@@ -3317,22 +3358,22 @@ md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
 
     case OPTION_NPS400:
       selected_cpu.features |= ARC_NPS400;
+      arc_check_feature ();
       break;
 
     case OPTION_SPFP:
       selected_cpu.features |= ARC_SPFP;
+      arc_check_feature ();
       break;
 
     case OPTION_DPFP:
       selected_cpu.features |= ARC_DPFP;
+      arc_check_feature ();
       break;
 
     case OPTION_FPUDA:
-      /* This option has an effect only on ARC EM.  */
-      if (selected_cpu.flags & ARC_OPCODE_ARCv2EM)
-       selected_cpu.features |= ARC_FPUDA;
-      else
-       as_warn (_("FPUDA invalid for selected CPU"));
+      selected_cpu.features |= ARC_FPUDA;
+      arc_check_feature ();
       break;
 
     /* Dummy options are accepted but have no effect.  */
diff --git a/gas/testsuite/gas/arc/cl-warn.s b/gas/testsuite/gas/arc/cl-warn.s
new file mode 100644 (file)
index 0000000..63199cf
--- /dev/null
@@ -0,0 +1,5 @@
+; Test command line option compatibility checking.
+; { dg-do assemble }
+; { dg-options "--mcpu=archs -mdpfp" }
+; { dg-error ".* invalid double-precision FPX option for archs cpu" "" { target arc*-*-* } 0 }
+       nop
diff --git a/gas/testsuite/gas/arc/cpu-pseudop-1.d b/gas/testsuite/gas/arc/cpu-pseudop-1.d
new file mode 100644 (file)
index 0000000..09c47c9
--- /dev/null
@@ -0,0 +1,12 @@
+#as: -mcpu=arcem -mcode-density -mdpfp
+#objdump: -dp -M dpfp
+
+.*: +file format .*arc.*
+private flags = 0x305: -mcpu=ARCv2EM .*
+
+
+Disassembly of section .text:
+
+00000000 <.text>:
+   0:  4af7                    sub_s   r15,r2,r15
+   2:  3211 00c1               dsubh12 r1,r2,r3
diff --git a/gas/testsuite/gas/arc/cpu-pseudop-1.s b/gas/testsuite/gas/arc/cpu-pseudop-1.s
new file mode 100644 (file)
index 0000000..40217aa
--- /dev/null
@@ -0,0 +1,6 @@
+;;; Check if user can use additional command line options.
+       .cpu EM
+       .section        .text
+
+       sub_s r15,r2,r15        ;code density instruction
+       dsubh12 r1,r2,r3        ;double-precision instruction
diff --git a/gas/testsuite/gas/arc/cpu-pseudop-2.d b/gas/testsuite/gas/arc/cpu-pseudop-2.d
new file mode 100644 (file)
index 0000000..3bde329
--- /dev/null
@@ -0,0 +1,11 @@
+#as: -mcpu=archs
+#objdump: -dp
+
+.*: +file format .*arc.*
+private flags = 0x306: -mcpu=ARCv2HS .*
+
+
+Disassembly of section .text:
+
+00000000 <.text>:
+   0:  4af7                    sub_s   r15,r2,r15
diff --git a/gas/testsuite/gas/arc/cpu-pseudop-2.s b/gas/testsuite/gas/arc/cpu-pseudop-2.s
new file mode 100644 (file)
index 0000000..def89d6
--- /dev/null
@@ -0,0 +1,5 @@
+;;; Check if user can use additional command line options.
+       .cpu EM
+       .section        .text
+
+       sub_s r15,r2,r15        ;code density instruction
diff --git a/gas/testsuite/gas/arc/cpu-warn2.s b/gas/testsuite/gas/arc/cpu-warn2.s
new file mode 100644 (file)
index 0000000..e9ee338
--- /dev/null
@@ -0,0 +1,4 @@
+; Test warnings when multiple .cpu pseudo-ops are defined.
+; { dg-do assemble }
+       .cpu EM
+       .cpu HS                 ;{ dg-error "Error: Multiple .cpu directives found" }