Add new sparc options to control instruction availability.
authorDavid S. Miller <davem@redhat.com>
Thu, 22 Sep 2011 00:03:30 +0000 (00:03 +0000)
committerDavid S. Miller <davem@redhat.com>
Thu, 22 Sep 2011 00:03:30 +0000 (00:03 +0000)
gas/

* config/tc-sparc.c (hwcap_allowed): New.
(struct sparc_arch): New field 'hwcap_allowed' containing a bitmask
of F_FOO flags which are enabled by the particular arch setting.
Add new options that provide explicit access to new instructions.
(md_parse_option): Only bump max_architecture if the requested one
is larger, or this is the first explicit request.
(get_hwcap_name): New function.
(sparc_ip): Validate that hwcaps used by an instruction have actually
been enabled.
* doc/c-sparc.texi: Document new sparc options.

gas/ChangeLog
gas/config/tc-sparc.c
gas/doc/c-sparc.texi
gas/testsuite/ChangeLog
gas/testsuite/gas/sparc/hpcvis3.d

index 46593cbce8115034347cb9212bf9d7acfe9ee9bb..3b7b7adc58ff59d58a3b2801c513f8260e9c0c83 100644 (file)
@@ -1,3 +1,16 @@
+2011-09-21  David S. Miller  <davem@davemloft.net>
+
+       * config/tc-sparc.c (hwcap_allowed): New.
+       (struct sparc_arch): New field 'hwcap_allowed' containing a bitmask
+       of F_FOO flags which are enabled by the particular arch setting.
+       Add new options that provide explicit access to new instructions.
+       (md_parse_option): Only bump max_architecture if the requested one
+       is larger, or this is the first explicit request.
+       (get_hwcap_name): New function.
+       (sparc_ip): Validate that hwcaps used by an instruction have actually
+       been enabled.
+       * doc/c-sparc.texi: Document new sparc options.
+
 2011-09-21  David S. Miller  <davem@davemloft.net>
 
        * config/tc-sparc.c (hwcap_seen): New bitmask, defined when
index 974524b147ae54f14e90e8364be8fd52c0345531..77fda56b8a265e8f1fb7b16cdf5409f2cbb48e45 100644 (file)
@@ -84,6 +84,8 @@ static int hwcap_seen;
 #endif
 #endif
 
+static int hwcap_allowed;
+
 static int architecture_requested;
 static int warn_on_bump;
 
@@ -231,23 +233,38 @@ static struct sparc_arch {
   int default_arch_size;
   /* Allowable arg to -A?  */
   int user_option_p;
+  int hwcap_allowed;
 } sparc_arch_table[] = {
-  { "v6", "v6", v6, 0, 1 },
-  { "v7", "v7", v7, 0, 1 },
-  { "v8", "v8", v8, 32, 1 },
-  { "sparclet", "sparclet", sparclet, 32, 1 },
-  { "sparclite", "sparclite", sparclite, 32, 1 },
-  { "sparc86x", "sparclite", sparc86x, 32, 1 },
-  { "v8plus", "v9", v9, 0, 1 },
-  { "v8plusa", "v9a", v9, 0, 1 },
-  { "v8plusb", "v9b", v9, 0, 1 },
-  { "v9", "v9", v9, 0, 1 },
-  { "v9a", "v9a", v9, 0, 1 },
-  { "v9b", "v9b", v9, 0, 1 },
+  { "v6", "v6", v6, 0, 1, 0 },
+  { "v7", "v7", v7, 0, 1, 0 },
+  { "v8", "v8", v8, 32, 1, F_MUL32|F_DIV32|F_FSMULD },
+  { "v8a", "v8", v8, 32, 1, F_MUL32|F_DIV32|F_FSMULD },
+  { "sparc", "v9", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_V8PLUS },
+  { "sparcvis", "v9a", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS },
+  { "sparcvis2", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS|F_VIS2 },
+  { "sparcfmaf", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS|F_VIS2|F_FMAF },
+  { "sparcima", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS|F_VIS2|F_FMAF|F_IMA },
+  { "sparcvis3", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS|F_VIS2|F_FMAF|F_VIS3|F_HPC },
+  { "sparcvis3r", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS|F_VIS2|F_FMAF|F_VIS3|F_HPC|F_RANDOM|F_TRANS|F_FJFMAU },
+  { "sparclet", "sparclet", sparclet, 32, 1, F_MUL32|F_DIV32|F_FSMULD },
+  { "sparclite", "sparclite", sparclite, 32, 1, F_MUL32|F_DIV32|F_FSMULD },
+  { "sparc86x", "sparclite", sparc86x, 32, 1, F_MUL32|F_DIV32|F_FSMULD },
+  { "v8plus", "v9", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_V8PLUS },
+  { "v8plusa", "v9a", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_V8PLUS|F_VIS },
+  { "v8plusb", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_V8PLUS|F_VIS|F_VIS2 },
+  { "v8plusc", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_V8PLUS|F_VIS|F_VIS2|F_ASI_BLK_INIT },
+  { "v8plusd", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_V8PLUS|F_VIS|F_VIS2|F_ASI_BLK_INIT|F_FMAF|F_VIS3|F_HPC },
+  { "v8plusv", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_V8PLUS|F_VIS|F_VIS2|F_ASI_BLK_INIT|F_FMAF|F_VIS3|F_HPC|F_RANDOM|F_TRANS|F_FJFMAU|F_IMA|F_ASI_CACHE_SPARING },
+  { "v9", "v9", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC },
+  { "v9a", "v9a", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS },
+  { "v9b", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS|F_VIS2 },
+  { "v9c", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS|F_VIS2|F_ASI_BLK_INIT },
+  { "v9d", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS|F_VIS2|F_ASI_BLK_INIT|F_FMAF|F_VIS3|F_HPC },
+  { "v9v", "v9b", v9, 0, 1, F_MUL32|F_DIV32|F_FSMULD|F_POPC|F_VIS|F_VIS2|F_ASI_BLK_INIT|F_FMAF|F_VIS3|F_HPC|F_RANDOM|F_TRANS|F_FJFMAU|F_IMA|F_ASI_CACHE_SPARING },
   /* This exists to allow configure.in/Makefile.in to pass one
      value to specify both the default machine and default word size.  */
-  { "v9-64", "v9", v9, 64, 0 },
-  { NULL, NULL, v8, 0, 0 }
+  { "v9-64", "v9", v9, 64, 0, F_MUL32|F_DIV32|F_FSMULD|F_POPC },
+  { NULL, NULL, v8, 0, 0, 0 }
 };
 
 /* Variant of default_arch */
@@ -487,7 +504,10 @@ md_parse_option (int c, char *arg)
        if (opcode_arch == SPARC_OPCODE_ARCH_BAD)
          as_fatal (_("Bad opcode table, broken assembler."));
 
-       max_architecture = opcode_arch;
+       if (!architecture_requested
+           || opcode_arch > max_architecture)
+         max_architecture = opcode_arch;
+       hwcap_allowed |= sa->hwcap_allowed;
        architecture_requested = 1;
       }
       break;
@@ -1417,6 +1437,44 @@ md_assemble (char *str)
     }
 }
 
+static const char *
+get_hwcap_name (int mask)
+{
+  if (mask & F_MUL32)
+    return "mul32";
+  if (mask & F_DIV32)
+    return "div32";
+  if (mask & F_FSMULD)
+    return "fsmuld";
+  if (mask & F_V8PLUS)
+    return "v8plus";
+  if (mask & F_POPC)
+    return "popc";
+  if (mask & F_VIS)
+    return "vis";
+  if (mask & F_VIS2)
+    return "vis2";
+  if (mask & F_ASI_BLK_INIT)
+    return "ASIBlkInit";
+  if (mask & F_FMAF)
+    return "fmaf";
+  if (mask & F_VIS3)
+    return "vis3";
+  if (mask & F_HPC)
+    return "hpc";
+  if (mask & F_RANDOM)
+    return "random";
+  if (mask & F_TRANS)
+    return "trans";
+  if (mask & F_FJFMAU)
+    return "fjfmau";
+  if (mask & F_IMA)
+    return "ima";
+  if (mask & F_ASI_CACHE_SPARING)
+    return "cspare";
+  return "UNKNOWN";
+}
+
 /* Subroutine of md_assemble to do the actual parsing.  */
 
 static int
@@ -2792,9 +2850,9 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
        {
          /* We have a match.  Now see if the architecture is OK.  */
          int needed_arch_mask = insn->architecture;
-#if defined(OBJ_ELF) && !defined(TE_SOLARIS)
          int hwcaps = insn->flags & F_HWCAP_MASK;
 
+#if defined(OBJ_ELF) && !defined(TE_SOLARIS)
          if (hwcaps)
                  hwcap_seen |= hwcaps;
 #endif
@@ -2865,6 +2923,17 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn)
                         sparc_opcode_archs[max_architecture].name);
              return special_case;
            }
+
+         /* Make sure the the hwcaps used by the instruction are
+            currently enabled.  */
+         if (hwcaps & ~hwcap_allowed)
+           {
+             const char *hwcap_name = get_hwcap_name(hwcaps & ~hwcap_allowed);
+
+             as_bad (_("Hardware capability \"%s\" not enabled for \"%s\"."),
+                     hwcap_name, str);
+             return special_case;
+           }
        } /* If no match.  */
 
       break;
index 3f758adb42c5a46cd5f7ef097ef8ab01389df215..099c031d2a929cbe726a7438ffe8d1a77174476d 100644 (file)
@@ -52,31 +52,91 @@ is explicitly requested.  SPARC v9 is always incompatible with sparclite.
 
 @table @code
 @kindex -Av6
-@kindex Av7
+@kindex -Av7
 @kindex -Av8
 @kindex -Asparclet
 @kindex -Asparclite
 @kindex -Av9
 @kindex -Av9a
+@kindex -Av9b
+@kindex -Av9c
+@kindex -Av9d
+@kindex -Av9v
+@kindex -Asparc
+@kindex -Asparcvis
+@kindex -Asparcvis2
+@kindex -Asparcfmaf
+@kindex -Asparcima
+@kindex -Asparcvis3
+@kindex -Asparcvis3r
 @item -Av6 | -Av7 | -Av8 | -Asparclet | -Asparclite
-@itemx -Av8plus | -Av8plusa | -Av9 | -Av9a
+@itemx -Av8plus | -Av8plusa | -Av8plusb | -Av8plusc | -Av8plusd | -Av8plusv
+@itemx -Av9 | -Av9a | -Av9b | -Av9c | -Av9d | -Av9v
+@itemx -Asparc | -Asparcvis | -Asparcvis2 | -Asparcfmaf | -Asparcima
+@itemx -Asparcvis3 | -Asparcvis3r
 Use one of the @samp{-A} options to select one of the SPARC
 architectures explicitly.  If you select an architecture explicitly,
 @code{@value{AS}} reports a fatal error if it encounters an instruction
 or feature requiring an incompatible or higher level.
 
-@samp{-Av8plus} and @samp{-Av8plusa} select a 32 bit environment.
+@samp{-Av8plus}, @samp{-Av8plusa}, @samp{-Av8plusb}, @samp{-Av8plusc},
+@samp{-Av8plusd}, and @samp{-Av8plusv} select a 32 bit environment.
 
-@samp{-Av9} and @samp{-Av9a} select a 64 bit environment and are not
-available unless GAS is explicitly configured with 64 bit environment
-support.
+@samp{-Av9}, @samp{-Av9a}, @samp{-Av9b}, @samp{-Av9c}, @samp{-Av9d}, and
+@samp{-Av9v} select a 64 bit environment and are not available unless GAS
+is explicitly configured with 64 bit environment support.
 
 @samp{-Av8plusa} and @samp{-Av9a} enable the SPARC V9 instruction set with
-UltraSPARC extensions.
+UltraSPARC VIS 1.0 extensions.
 
-@item -xarch=v8plus | -xarch=v8plusa
+@samp{-Av8plusb} and @samp{-Av9b} enable the UltraSPARC VIS 2.0 instructions,
+as well as the instructions enabled by @samp{-Av8plusa} and @samp{-Av9a}.
+
+@samp{-Av8plusc} and @samp{-Av9c} enable the UltraSPARC Niagara instructions,
+as well as the instructions enabled by @samp{-Av8plusb} and @samp{-Av9b}.
+
+@samp{-Av8plusd} and @samp{-Av9d} enable the floating point fused
+multiply-add, VIS 3.0, and HPC extension instructions, as well as the
+instructions enabled by @samp{-Av8plusc} and @samp{-Av9c}.
+
+@samp{-Av8plusv} and @samp{-Av9v} enable the 'random', transactional
+memory, floating point unfused multiply-add, integer multiply-add, and
+cache sparing store instructions, as well as the instructions enabled
+by @samp{-Av8plusd} and @samp{-Av9d}.
+
+@samp{-Asparc} specifies a v9 environment.  It is equivalent to
+@samp{-Av9} if the word size is 64-bit, and @samp{-Av8plus} otherwise.
+
+@samp{-Asparcvis} specifies a v9a environment.  It is equivalent to
+@samp{-Av9a} if the word size is 64-bit, and @samp{-Av8plusa} otherwise.
+
+@samp{-Asparcvis2} specifies a v9b environment.  It is equivalent to
+@samp{-Av9b} if the word size is 64-bit, and @samp{-Av8plusb} otherwise.
+
+@samp{-Asparcfmaf} specifies a v9b environment with the floating point
+fused multiply-add instructions enabled.
+
+@samp{-Asparcima} specifies a v9b environment with the integer
+multiply-add instructions enabled.
+
+@samp{-Asparcvis3} specifies a v9b environment with the VIS 3.0,
+HPC , and floating point fused multiply-add instructions enabled.
+
+@samp{-Asparcvis3r} specifies a v9b environment with the VIS 3.0,
+HPC, transactional memory, random, and floating point unfused multiply-add
+instructions enabled.
+
+@item -xarch=v8plus | -xarch=v8plusa | -xarch=v8plusb | -xarch=v8plusc
+@itemx -xarch=v8plusd | -xarch=v8plusv | -xarch=v9 | -xarch=v9a
+@itemx -xarch=v9b | -xarch=v9c | -xarch=v9d | -xarch=v9v
+@itemx -xarch=sparc | -xarch=sparcvis | -xarch=sparcvis2
+@itemx -xarch=sparcfmaf | -xarch=sparcima | -xarch=sparcvis3
+@itemx -xarch=sparcvis3r
 For compatibility with the SunOS v9 assembler.  These options are
-equivalent to -Av8plus and -Av8plusa, respectively.
+equivalent to -Av8plus, -Av8plusa, -Av8plusb, -Av8plusc, -Av8plusd,
+-Av8plusv, -Av9, -Av9a, -Av9b, -Av9c, -Av9d, -Av9v, -Asparc, -Asparcvis,
+-Asparcvis2, -Asparcfmaf, -Asparcima, -Asparcvis3, and -Asparcvis3r,
+respectively.
 
 @item -bump
 Warn whenever it is necessary to switch to another level.
index ca8f38d0e3f5b868cf4a08c40ad1ed631805390b..03463adb5f02ab5449cb66b55c45ce0ab22445d1 100644 (file)
@@ -8,6 +8,8 @@
        * gas/sparc/ticc-imm-reg.d: Likewise, add -32 to options.
        * gas/sparc/v8-movwr-imm.d: Likewise.
 
+       * gas/sparc/hpcvis3.d: Pass '-Av9v'.
+
 2011-09-08  Mark Fortescue <mark@mtfhpc.demon.co.uk>
 
        * gas/sparc/imm-plus-rreg.[sd]: New test.
index d44b13b0fed8de99a027c354197410e6ace201ee..faa3137c9d2e79c0b6f69ec381e8e45e8bff6268 100644 (file)
@@ -1,4 +1,4 @@
-#as: -Av9b
+#as: -Av9v
 #objdump: -dr
 #name: sparc HPC+VIS3