From: David S. Miller Date: Thu, 22 Sep 2011 00:03:30 +0000 (+0000) Subject: Add new sparc options to control instruction availability. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=4bafe00ecf3e7b63d3b2b23f5406637261c6b391;p=binutils-gdb.git Add new sparc options to control instruction availability. 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. --- diff --git a/gas/ChangeLog b/gas/ChangeLog index 46593cbce81..3b7b7adc58f 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,16 @@ +2011-09-21 David S. Miller + + * 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 * config/tc-sparc.c (hwcap_seen): New bitmask, defined when diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index 974524b147a..77fda56b8a2 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -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; diff --git a/gas/doc/c-sparc.texi b/gas/doc/c-sparc.texi index 3f758adb42c..099c031d2a9 100644 --- a/gas/doc/c-sparc.texi +++ b/gas/doc/c-sparc.texi @@ -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. diff --git a/gas/testsuite/ChangeLog b/gas/testsuite/ChangeLog index ca8f38d0e3f..03463adb5f0 100644 --- a/gas/testsuite/ChangeLog +++ b/gas/testsuite/ChangeLog @@ -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 * gas/sparc/imm-plus-rreg.[sd]: New test. diff --git a/gas/testsuite/gas/sparc/hpcvis3.d b/gas/testsuite/gas/sparc/hpcvis3.d index d44b13b0fed..faa3137c9d2 100644 --- a/gas/testsuite/gas/sparc/hpcvis3.d +++ b/gas/testsuite/gas/sparc/hpcvis3.d @@ -1,4 +1,4 @@ -#as: -Av9b +#as: -Av9v #objdump: -dr #name: sparc HPC+VIS3