diff options
author | Jose E. Marchesi <jose.marchesi@oracle.com> | 2016-11-22 04:40:37 -0800 |
---|---|---|
committer | Jose E. Marchesi <jose.marchesi@oracle.com> | 2016-11-22 04:40:37 -0800 |
commit | 6884417a0ff3555b192d4aceeacc5e7232cad207 (patch) | |
tree | a13845af3304184f587a5d9341184a1e3373b74a /gas/config | |
parent | c4b943d7aed5edbfc31aa1e9dc9e7bcf108d76a0 (diff) | |
download | gdb-6884417a0ff3555b192d4aceeacc5e7232cad207.zip gdb-6884417a0ff3555b192d4aceeacc5e7232cad207.tar.gz gdb-6884417a0ff3555b192d4aceeacc5e7232cad207.tar.bz2 |
gas,opcodes: fix hardware capabilities bumping in the sparc assembler.
When the assembler finds an instruction which is part of a higher
opcode architecture it bumps the current opcode architecture. For
example:
$ echo "mwait" | as -bump
{standard input}: Assembler messages:
{standard input}:1: Warning: architecture bumped from "v6" to "v9m" on "mwait"
However, when two instructions pertaining to the same opcode
architecture but associated to different SPARC hardware capabilities
are found in the input stream, and no GAS architecture is specified in
the command line, the assembler bangs:
$ echo "mwait; wr %g0,%g1,%mcdper" | as -bump
{standard input}: Assembler messages:
{standard input}:1: Warning: architecture bumped from "v6" to "v9m" on "mwait"
{standard input}:1: Error: Hardware capability "sparc5" not enabled for "wr".
... and it should'nt, as WRMCDPER pertains to the same architecture
level than MWAIT.
This patch fixes this by extending the definition of sparc opcode
architectures to contain a set of hardware capabilities and making the
assembler to take these capabilities into account when updating the
set of allowed hwcaps when an architecture bump is triggered by some
instruction.
This way, hwcaps associated to architecture levels are maintained in
opcodes, while the assembler keeps the flexibiity of defining GAS
architectures including additional hwcaps (like -Asparcfmaf or the
v8plus* variants).
A test covering this failure case is included.
gas/ChangeLog:
2016-11-22 Jose E. Marchesi <jose.marchesi@oracle.com>
* config/tc-sparc.c: Move HWS_* and HWS2_* definitions to
opcodes/sparc-opc.c.
(sparc_arch): Clarify the new role of the hwcap_allowed and
hwcap2_allowed fields.
(sparc_arch_table): Remove HWS_* and HWS2_* instances from
hwcap_allowed and hwcap2_allowed respectively.
(md_parse_option): Include the opcode arch hwcaps when processing
-A.
(sparc_ip): Use the current opcode arch hwcaps to update
hwcap_allowed, as well of the hwcaps of the instruction triggering
the bump.
* testsuite/gas/sparc/hwcaps-bump.s: New file.
* testsuite/gas/sparc/hwcaps-bump.l: Likewise.
* testsuite/gas/sparc/sparc.exp (gas_64_check): Run tests in
hwcaps-bump.
include/ChangeLog:
2016-11-22 Jose E. Marchesi <jose.marchesi@oracle.com>
* opcode/sparc.h (sparc_opcode_arch): New fields hwcaps and
hwcaps2.
opcodes/ChangeLog:
2016-11-22 Jose E. Marchesi <jose.marchesi@oracle.com>
* sparc-opc.c (HWS_V8): Definition moved from
gas/config/tc-sparc.c.
(HWS_V9): Likewise.
(HWS_VA): Likewise.
(HWS_VB): Likewise.
(HWS_VC): Likewise.
(HWS_VD): Likewise.
(HWS_VE): Likewise.
(HWS_VV): Likewise.
(HWS_VM): Likewise.
(HWS2_VM): Likewise.
(sparc_opcode_archs): Initialize hwcaps and hwcaps2 fields of
existing entries.
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-sparc.c | 112 |
1 files changed, 54 insertions, 58 deletions
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index d7b9a98..edece05 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -226,25 +226,6 @@ static void output_insn (const struct sparc_opcode *, struct sparc_it *); enum sparc_arch_types {v6, v7, v8, leon, sparclet, sparclite, sparc86x, v8plus, v8plusa, v9, v9a, v9b, v9_64}; -/* Hardware capability sets, used to keep sparc_arch_table easy to - read. */ -#define HWS_V8 HWCAP_MUL32 | HWCAP_DIV32 | HWCAP_FSMULD -#define HWS_V9 HWS_V8 | HWCAP_POPC -#define HWS_VA HWS_V9 | HWCAP_VIS -#define HWS_VB HWS_VA | HWCAP_VIS2 -#define HWS_VC HWS_VB | HWCAP_ASI_BLK_INIT -#define HWS_VD HWS_VC | HWCAP_FMAF | HWCAP_VIS3 | HWCAP_HPC -#define HWS_VE HWS_VD \ - | HWCAP_AES | HWCAP_DES | HWCAP_KASUMI | HWCAP_CAMELLIA \ - | HWCAP_MD5 | HWCAP_SHA1 | HWCAP_SHA256 |HWCAP_SHA512 | HWCAP_MPMUL \ - | HWCAP_MONT | HWCAP_CRC32C | HWCAP_CBCOND | HWCAP_PAUSE -#define HWS_VV HWS_VE | HWCAP_FJFMAU | HWCAP_IMA -#define HWS_VM HWS_VV - -#define HWS2_VM \ - HWCAP2_VIS3B | HWCAP2_ADP | HWCAP2_SPARC5 | HWCAP2_MWAIT \ - | HWCAP2_XMPMUL | HWCAP2_XMONT - static struct sparc_arch { const char *name; const char *opcode_arch; @@ -254,50 +235,53 @@ static struct sparc_arch { int default_arch_size; /* Allowable arg to -A? */ int user_option_p; + /* Extra hardware capabilities allowed. These are added to the + hardware capabilities associated with the opcode + architecture. */ int hwcap_allowed; int hwcap2_allowed; } sparc_arch_table[] = { { "v6", "v6", v6, 0, 1, 0, 0 }, { "v7", "v7", v7, 0, 1, 0, 0 }, - { "v8", "v8", v8, 32, 1, HWS_V8, 0 }, - { "v8a", "v8", v8, 32, 1, HWS_V8, 0 }, - { "sparc", "v9", v9, 0, 1, HWCAP_V8PLUS|HWS_V9, 0 }, - { "sparcvis", "v9a", v9, 0, 1, HWS_VA, 0 }, - { "sparcvis2", "v9b", v9, 0, 1, HWS_VB, 0 }, - { "sparcfmaf", "v9b", v9, 0, 1, HWS_VB|HWCAP_FMAF, 0 }, - { "sparcima", "v9b", v9, 0, 1, HWS_VB|HWCAP_FMAF|HWCAP_IMA, 0 }, - { "sparcvis3", "v9b", v9, 0, 1, HWS_VB|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC, 0 }, - { "sparcvis3r", "v9b", v9, 0, 1, HWS_VB|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_FJFMAU, 0 }, - - { "sparc4", "v9v", v9, 0, 1, HWS_VV, 0 }, - { "sparc5", "v9m", v9, 0, 1, HWS_VM, HWS2_VM }, - - { "leon", "leon", leon, 32, 1, HWS_V8, 0 }, - { "sparclet", "sparclet", sparclet, 32, 1, HWS_V8, 0 }, - { "sparclite", "sparclite", sparclite, 32, 1, HWS_V8, 0 }, - { "sparc86x", "sparclite", sparc86x, 32, 1, HWS_V8, 0 }, - - { "v8plus", "v9", v9, 0, 1, HWCAP_V8PLUS|HWS_V9, 0 }, - { "v8plusa", "v9a", v9, 0, 1, HWCAP_V8PLUS|HWS_VA, 0 }, - { "v8plusb", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VB, 0 }, - { "v8plusc", "v9c", v9, 0, 1, HWCAP_V8PLUS|HWS_VC, 0 }, - { "v8plusd", "v9d", v9, 0, 1, HWCAP_V8PLUS|HWS_VD, 0 }, - { "v8pluse", "v9e", v9, 0, 1, HWCAP_V8PLUS|HWS_VE, 0 }, - { "v8plusv", "v9v", v9, 0, 1, HWCAP_V8PLUS|HWS_VV, 0 }, - { "v8plusm", "v9m", v9, 0, 1, HWCAP_V8PLUS|HWS_VM, 0 }, - - { "v9", "v9", v9, 0, 1, HWS_V9, 0 }, - { "v9a", "v9a", v9, 0, 1, HWS_VA, 0 }, - { "v9b", "v9b", v9, 0, 1, HWS_VB, 0 }, - { "v9c", "v9c", v9, 0, 1, HWS_VC, 0 }, - { "v9d", "v9d", v9, 0, 1, HWS_VD, 0 }, - { "v9e", "v9e", v9, 0, 1, HWS_VE, 0 }, - { "v9v", "v9v", v9, 0, 1, HWS_VV, 0 }, - { "v9m", "v9m", v9, 0, 1, HWS_VM, HWS2_VM }, + { "v8", "v8", v8, 32, 1, 0, 0 }, + { "v8a", "v8", v8, 32, 1, 0, 0 }, + { "sparc", "v9", v9, 0, 1, HWCAP_V8PLUS, 0 }, + { "sparcvis", "v9a", v9, 0, 1, 0, 0 }, + { "sparcvis2", "v9b", v9, 0, 1, 0, 0 }, + { "sparcfmaf", "v9b", v9, 0, 1, HWCAP_FMAF, 0 }, + { "sparcima", "v9b", v9, 0, 1, HWCAP_FMAF|HWCAP_IMA, 0 }, + { "sparcvis3", "v9b", v9, 0, 1, HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC, 0 }, + { "sparcvis3r", "v9b", v9, 0, 1, HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_FJFMAU, 0 }, + + { "sparc4", "v9v", v9, 0, 1, 0, 0 }, + { "sparc5", "v9m", v9, 0, 1, 0, 0 }, + + { "leon", "leon", leon, 32, 1, 0, 0 }, + { "sparclet", "sparclet", sparclet, 32, 1, 0, 0 }, + { "sparclite", "sparclite", sparclite, 32, 1, 0, 0 }, + { "sparc86x", "sparclite", sparc86x, 32, 1, 0, 0 }, + + { "v8plus", "v9", v9, 0, 1, HWCAP_V8PLUS, 0 }, + { "v8plusa", "v9a", v9, 0, 1, HWCAP_V8PLUS, 0 }, + { "v8plusb", "v9b", v9, 0, 1, HWCAP_V8PLUS, 0 }, + { "v8plusc", "v9c", v9, 0, 1, HWCAP_V8PLUS, 0 }, + { "v8plusd", "v9d", v9, 0, 1, HWCAP_V8PLUS, 0 }, + { "v8pluse", "v9e", v9, 0, 1, HWCAP_V8PLUS, 0 }, + { "v8plusv", "v9v", v9, 0, 1, HWCAP_V8PLUS, 0 }, + { "v8plusm", "v9m", v9, 0, 1, HWCAP_V8PLUS, 0 }, + + { "v9", "v9", v9, 0, 1, 0, 0 }, + { "v9a", "v9a", v9, 0, 1, 0, 0 }, + { "v9b", "v9b", v9, 0, 1, 0, 0 }, + { "v9c", "v9c", v9, 0, 1, 0, 0 }, + { "v9d", "v9d", v9, 0, 1, 0, 0 }, + { "v9e", "v9e", v9, 0, 1, 0, 0 }, + { "v9v", "v9v", v9, 0, 1, 0, 0 }, + { "v9m", "v9m", v9, 0, 1, 0, 0 }, /* This exists to allow configure.tgt to pass one value to specify both the default machine and default word size. */ - { "v9-64", "v9", v9, 64, 0, HWS_V9, 0 }, + { "v9-64", "v9", v9, 64, 0, 0, 0 }, { NULL, NULL, v8, 0, 0, 0, 0 } }; @@ -551,8 +535,16 @@ md_parse_option (int c, const char *arg) if (!architecture_requested || opcode_arch > max_architecture) max_architecture = opcode_arch; - hwcap_allowed - |= (((bfd_uint64_t) sa->hwcap2_allowed) << 32) | sa->hwcap_allowed; + + /* The allowed hardware capabilities are the implied by the + opcodes arch plus any extra capabilities defined in the GAS + arch. */ + hwcap_allowed + = (hwcap_allowed + | (((bfd_uint64_t) sparc_opcode_archs[opcode_arch].hwcaps2) << 32) + | (((bfd_uint64_t) sa->hwcap2_allowed) << 32) + | sparc_opcode_archs[opcode_arch].hwcaps + | sa->hwcap_allowed); architecture_requested = 1; } break; @@ -3194,7 +3186,11 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn) warn_after_architecture = needed_architecture; } current_architecture = needed_architecture; - hwcap_allowed |= hwcaps; + hwcap_allowed + = (hwcap_allowed + | hwcaps + | (((bfd_uint64_t) sparc_opcode_archs[current_architecture].hwcaps2) << 32) + | sparc_opcode_archs[current_architecture].hwcaps); } /* Conflict. */ /* ??? This seems to be a bit fragile. What if the next entry in |