Annotate sparc objects with cpu hardware capabilities used.

bfd/

	* elfxx-sparc.c (_bfd_sparc_elf_merge_private_bfd_data): New.
	* elfxx-sparc.h: Declare it.
	* elf32-sparc.c (elf32_sparc_merge_private_bfd_data): Call it.
	* elf64-sparc.c (elf64_sparc_merge_private_bfd_data): Likewise.

binutils/

	* readelf.c (display_sparc_hwcaps): New.
	(display_sparc_gnu_attribute): New.
	(process_sparc_specific): New.
	(process_arch_specific): When EM_SPARC, EM_SPARC32PLUS,
	or EM_SPARCV9 invoke process_sparc_specific.

gas/

	* config/tc-sparc.c (hwcap_seen): New bitmask, defined when
	not TE_SOLARIS.
	(sparc_ip): When not TE_SOLARIS, accumulate hwcap bits from
	sparc_opcode->flags of instruction into hwcap_seen.
	(sparc_md_end): Create Tag_GNU_Sparc_HWCAPS attribute if
	hwcap_seen is non-zero and not TE_SOLARIS.

gas/testsuite/

	* gas/sparc/hpcvis3.s: Update for fixed fchksum16 mnemonic.
	* gas/sparc/hpcvis3.d: Likewise.

include/elf/

	* sparc.h (Tag_GNU_Sparc_HWCAPS): New object attribute.
	(ELF_SPARC_HWCAP_*): New HWCAPS bitmask values.

include/opcode/

	* sparc.h (struct sparc_opcode): Expand 'flags' to unsigned int.
	(F_MUL32, F_DIV32, F_FSMULD, F_V8PLUS, 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): New flag bits.

opcodes/

	* sparc-opc.c (sparc_opcodes): Annotate table with HWCAP flag
	bits.  Fix "fchksm16" mnemonic.
This commit is contained in:
David S. Miller
2011-09-21 20:49:16 +00:00
parent cdd30861d6
commit 9e8c70f96b
18 changed files with 516 additions and 237 deletions

View File

@@ -11096,6 +11096,88 @@ display_power_gnu_attribute (unsigned char * p, int tag)
return p;
}
static void
display_sparc_hwcaps (int mask)
{
if (mask)
{
int first = 1;
if (mask & ELF_SPARC_HWCAP_MUL32)
fputs ("mul32", stdout), first = 0;
if (mask & ELF_SPARC_HWCAP_DIV32)
printf ("%sdiv32", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_FSMULD)
printf ("%sfsmuld", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_V8PLUS)
printf ("%sv8plus", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_POPC)
printf ("%spopc", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_VIS)
printf ("%svis", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_VIS2)
printf ("%svis2", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_ASI_BLK_INIT)
printf ("%sASIBlkInit", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_FMAF)
printf ("%sfmaf", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_VIS3)
printf ("%svis3", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_HPC)
printf ("%shpc", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_RANDOM)
printf ("%srandom", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_TRANS)
printf ("%strans", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_FJFMAU)
printf ("%sfjfmau", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_IMA)
printf ("%sima", first ? "" : "|"), first = 0;
if (mask & ELF_SPARC_HWCAP_ASI_CACHE_SPARING)
printf ("%scspare", first ? "" : "|"), first = 0;
}
else
fputc('0', stdout);
fputc('\n', stdout);
}
static unsigned char *
display_sparc_gnu_attribute (unsigned char * p, int tag)
{
int type;
unsigned int len;
int val;
if (tag == Tag_GNU_Sparc_HWCAPS)
{
val = read_uleb128 (p, &len);
p += len;
printf (" Tag_GNU_Sparc_HWCAPS: ");
display_sparc_hwcaps (val);
return p;
}
if (tag & 1)
type = 1; /* String. */
else
type = 2; /* uleb128. */
printf (" Tag_unknown_%d: ", tag);
if (type == 1)
{
printf ("\"%s\"\n", p);
p += strlen ((char *) p) + 1;
}
else
{
val = read_uleb128 (p, &len);
p += len;
printf ("%d (0x%x)\n", val, val);
}
return p;
}
static unsigned char *
display_mips_gnu_attribute (unsigned char * p, int tag)
{
@@ -11544,6 +11626,13 @@ process_power_specific (FILE * file)
display_power_gnu_attribute);
}
static int
process_sparc_specific (FILE * file)
{
return process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
display_sparc_gnu_attribute);
}
static int
process_tic6x_specific (FILE * file)
{
@@ -12898,6 +12987,11 @@ process_arch_specific (FILE * file)
case EM_PPC:
return process_power_specific (file);
break;
case EM_SPARC:
case EM_SPARC32PLUS:
case EM_SPARCV9:
return process_sparc_specific (file);
break;
case EM_TI_C6000:
return process_tic6x_specific (file);
break;