diff options
author | Jose E. Marchesi <jose.marchesi@oracle.com> | 2014-10-09 13:16:53 +0100 |
---|---|---|
committer | Nick Clifton <nickc@redhat.com> | 2014-10-09 13:16:53 +0100 |
commit | 3d68f91c0fb05b426e554004cabd3ded4c91f9c8 (patch) | |
tree | 0297b29c1d0d20a3d36868c0357e23a0db4f6efd /gas/config | |
parent | fcbdedf866d777b3598cf8703737eb0f987c2aca (diff) | |
download | gdb-3d68f91c0fb05b426e554004cabd3ded4c91f9c8.zip gdb-3d68f91c0fb05b426e554004cabd3ded4c91f9c8.tar.gz gdb-3d68f91c0fb05b426e554004cabd3ded4c91f9c8.tar.bz2 |
This is a series of patches that add support for the SPARC M7 cpu to
binutils. They were discussed and approved here:
https://sourceware.org/ml/binutils/2014-10/msg00038.html
Diffstat (limited to 'gas/config')
-rw-r--r-- | gas/config/tc-sparc.c | 150 |
1 files changed, 110 insertions, 40 deletions
diff --git a/gas/config/tc-sparc.c b/gas/config/tc-sparc.c index 7497618..1d2f945 100644 --- a/gas/config/tc-sparc.c +++ b/gas/config/tc-sparc.c @@ -77,11 +77,11 @@ static enum { MM_TSO, MM_PSO, MM_RMO } sparc_memory_model = MM_RMO; #ifndef TE_SOLARIS /* Bitmask of instruction types seen so far, used to populate the GNU attributes section with hwcap information. */ -static int hwcap_seen; +static bfd_uint64_t hwcap_seen; #endif #endif -static int hwcap_allowed; +static bfd_uint64_t hwcap_allowed; static int architecture_requested; static int warn_on_bump; @@ -221,6 +221,25 @@ 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 { char *name; char *opcode_arch; @@ -231,41 +250,50 @@ static struct sparc_arch { /* Allowable arg to -A? */ int user_option_p; int hwcap_allowed; + int hwcap2_allowed; } sparc_arch_table[] = { - { "v6", "v6", v6, 0, 1, 0 }, - { "v7", "v7", v7, 0, 1, 0 }, - { "v8", "v8", v8, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD }, - { "v8a", "v8", v8, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD }, - { "sparc", "v9", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS }, - { "sparcvis", "v9a", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS }, - { "sparcvis2", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2 }, - { "sparcfmaf", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF }, - { "sparcima", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_IMA }, - { "sparcvis3", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC }, - { "sparcvis3r", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU }, - { "sparc4", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|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 }, - { "leon", "leon", leon, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD }, - { "sparclet", "sparclet", sparclet, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD }, - { "sparclite", "sparclite", sparclite, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD }, - { "sparc86x", "sparclite", sparc86x, 32, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD }, - { "v8plus", "v9", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS }, - { "v8plusa", "v9a", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS }, - { "v8plusb", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2 }, - { "v8plusc", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT }, - { "v8plusd", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC }, - { "v8pluse", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|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 }, - { "v8plusv", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_V8PLUS|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_IMA|HWCAP_ASI_CACHE_SPARING|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 }, - { "v9", "v9", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC }, - { "v9a", "v9a", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS }, - { "v9b", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2 }, - { "v9c", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT }, - { "v9d", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC }, - { "v9e", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|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 }, - { "v9v", "v9b", v9, 0, 1, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC|HWCAP_VIS|HWCAP_VIS2|HWCAP_ASI_BLK_INIT|HWCAP_FMAF|HWCAP_VIS3|HWCAP_HPC|HWCAP_RANDOM|HWCAP_TRANS|HWCAP_FJFMAU|HWCAP_IMA|HWCAP_ASI_CACHE_SPARING|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 }, + { "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", "v9b", v9, 0, 1, HWS_VV, 0 }, + { "sparc5", "v9b", 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", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VC, 0 }, + { "v8plusd", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VD, 0 }, + { "v8pluse", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VE, 0 }, + { "v8plusv", "v9b", v9, 0, 1, HWCAP_V8PLUS|HWS_VV, 0 }, + { "v8plusm", "v9b", 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", "v9b", v9, 0, 1, HWS_VC, 0 }, + { "v9d", "v9b", v9, 0, 1, HWS_VD, 0 }, + { "v9e", "v9b", v9, 0, 1, HWS_VE, 0 }, + { "v9v", "v9b", v9, 0, 1, HWS_VV, 0 }, + { "v9m", "v9b", v9, 0, 1, HWS_VM, HWS2_VM }, + /* 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, HWCAP_MUL32|HWCAP_DIV32|HWCAP_FSMULD|HWCAP_POPC }, - { NULL, NULL, v8, 0, 0, 0 } + { "v9-64", "v9", v9, 64, 0, HWS_V9, 0 }, + { NULL, NULL, v8, 0, 0, 0, 0 } }; /* Variant of default_arch */ @@ -516,7 +544,8 @@ md_parse_option (int c, char *arg) if (!architecture_requested || opcode_arch > max_architecture) max_architecture = opcode_arch; - hwcap_allowed |= sa->hwcap_allowed; + hwcap_allowed + |= (((bfd_uint64_t) sa->hwcap2_allowed) << 32) | sa->hwcap_allowed; architecture_requested = 1; } break; @@ -810,9 +839,9 @@ struct priv_reg_entry v9a_asr_table[] = {"pause", 27}, {"pic", 17}, {"pcr", 16}, + {"mwait", 28}, {"gsr", 19}, {"dcr", 18}, - {"cps", 28}, {"cfr", 26}, {"clear_softint", 21}, {"", -1}, /* End marker. */ @@ -942,6 +971,7 @@ void sparc_md_end (void) { unsigned long mach = bfd_mach_sparc; + int hwcaps, hwcaps2; if (sparc_arch_size == 64) switch (current_architecture) @@ -965,8 +995,13 @@ sparc_md_end (void) bfd_set_arch_mach (stdoutput, bfd_arch_sparc, mach); #if defined(OBJ_ELF) && !defined(TE_SOLARIS) - if (hwcap_seen) - bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU, Tag_GNU_Sparc_HWCAPS, hwcap_seen); + hwcaps = hwcap_seen & U0xffffffff; + hwcaps2 = hwcap_seen >> 32; + + if (hwcaps) + bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU, Tag_GNU_Sparc_HWCAPS, hwcaps); + if (hwcaps2) + bfd_elf_add_obj_attr_int (stdoutput, OBJ_ATTR_GNU, Tag_GNU_Sparc_HWCAPS2, hwcaps2); #endif } @@ -1422,7 +1457,7 @@ md_assemble (char *str) } static const char * -get_hwcap_name (int mask) +get_hwcap_name (bfd_uint64_t mask) { if (mask & HWCAP_MUL32) return "mul32"; @@ -1482,6 +1517,25 @@ get_hwcap_name (int mask) return "cbcond"; if (mask & HWCAP_CRC32C) return "crc32c"; + + mask = mask >> 32; + if (mask & HWCAP2_FJATHPLUS) + return "fjathplus"; + if (mask & HWCAP2_VIS3B) + return "vis3b"; + if (mask & HWCAP2_ADP) + return "adp"; + if (mask & HWCAP2_SPARC5) + return "sparc5"; + if (mask & HWCAP2_MWAIT) + return "mwait"; + if (mask & HWCAP2_XMPMUL) + return "xmpmul"; + if (mask & HWCAP2_XMONT) + return "xmont"; + if (mask & HWCAP2_NSEC) + return "nsec"; + return "UNKNOWN"; } @@ -2306,6 +2360,7 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn) case 'g': case 'H': case 'J': + case '}': { char format; @@ -2368,6 +2423,13 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn) break; } /* if not an 'f' register. */ + if (*args == '}' && mask != RS2 (opcode)) + { + error_message + = _(": Instruction requires frs2 and frsd must be the same register"); + goto error; + } + switch (*args) { case 'v': @@ -2390,6 +2452,7 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn) case 'g': case 'H': case 'J': + case '}': opcode |= RD (mask); continue; } /* Pack it in. */ @@ -2843,6 +2906,12 @@ sparc_ip (char *str, const struct sparc_opcode **pinsn) s += 5; continue; + case '{': + if (strncmp (s, "%mcdper",7) != 0) + break; + s += 7; + continue; + case 'E': if (strncmp (s, "%ccr", 4) != 0) break; @@ -2933,7 +3002,8 @@ 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; - int hwcaps = insn->hwcaps; + bfd_uint64_t hwcaps + = (((bfd_uint64_t) insn->hwcaps2) << 32) | insn->hwcaps; #if defined(OBJ_ELF) && !defined(TE_SOLARIS) if (hwcaps) |