#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;
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;
/* 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 */
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;
{"pause", 27},
{"pic", 17},
{"pcr", 16},
+ {"mwait", 28},
{"gsr", 19},
{"dcr", 18},
- {"cps", 28},
{"cfr", 26},
{"clear_softint", 21},
{"", -1}, /* End marker. */
sparc_md_end (void)
{
unsigned long mach = bfd_mach_sparc;
+ int hwcaps, hwcaps2;
if (sparc_arch_size == 64)
switch (current_architecture)
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
}
\f
}
static const char *
-get_hwcap_name (int mask)
+get_hwcap_name (bfd_uint64_t mask)
{
if (mask & HWCAP_MUL32)
return "mul32";
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";
}
case 'g':
case 'H':
case 'J':
+ case '}':
{
char format;
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':
case 'g':
case 'H':
case 'J':
+ case '}':
opcode |= RD (mask);
continue;
} /* Pack it in. */
s += 5;
continue;
+ case '{':
+ if (strncmp (s, "%mcdper",7) != 0)
+ break;
+ s += 7;
+ continue;
+
case 'E':
if (strncmp (s, "%ccr", 4) != 0)
break;
{
/* 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)