From 59e6276b64b1a3b248d851e5a3f5acd63e346399 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Wed, 16 Jun 2010 00:36:04 +0000 Subject: bfd: * elf-bfd.h (LEAST_KNOWN_OBJ_ATTRIBUTE): Decrease to 2. * elf32-tic6x.c (elf32_tic6x_obj_attrs_arg_type, elf32_tic6x_merge_arch_attributes, elf32_tic6x_merge_attributes, elf32_tic6x_merge_private_bfd_data): New. (bfd_elf32_bfd_merge_private_bfd_data, elf_backend_obj_attrs_arg_type, elf_backend_obj_attrs_section, elf_backend_obj_attrs_section_type, elf_backend_obj_attrs_vendor): Define. * elf32-tic6x.h (elf32_tic6x_merge_arch_attributes): Declare. binutils: * readelf.c (display_tic6x_attribute, process_tic6x_specific): New. (process_arch_specific): Call process_tic6x_specific for EM_TI_C6000. gas: * config/tc-tic6x.c: Include elf/tic6x.h. (tic6x_arch_attribute, tic6x_seen_insns): New. (tic6x_arch_table, tic6x_arches): Add attribute values. (tic6x_use_arch): Handle attribute settings. (tic6x_attributes_set_explicitly, s_tic6x_c6xabi_attribute, tic6x_attribute_table, tic6x_attributes, tic6x_convert_symbolic_attribute): New. (md_pseudo_table): Add c6xabi_attribute. (md_assemble): Set tic6x_seen_insns and tic6x_arch_attribute. (tic6x_set_attribute_int, tic6x_set_attributes): New. (tic6x_end): Call tic6x_set_attributes. * config/tc-tic6x.h (CONVERT_SYMBOLIC_ATTRIBUTE): Define. (tic6x_convert_symbolic_attribute): Declare. gas/testsuite: * gas/elf/elf.exp: Set target_machine for tic6x-*-*. * gas/elf/section2.e-tic6x, gas/tic6x/attr-arch-directive-1.d, gas/tic6x/attr-arch-directive-1.s, gas/tic6x/attr-arch-directive-2.d, gas/tic6x/attr-arch-directive-2.s, gas/tic6x/attr-arch-directive-3.d, gas/tic6x/attr-arch-directive-3.s, gas/tic6x/attr-arch-directive-4.d, gas/tic6x/attr-arch-directive-4.s, gas/tic6x/attr-arch-directive-5.d, gas/tic6x/attr-arch-directive-5.s, gas/tic6x/attr-arch-opts-c62x.d, gas/tic6x/attr-arch-opts-c64x+.d, gas/tic6x/attr-arch-opts-c64x.d, gas/tic6x/attr-arch-opts-c674x.d, gas/tic6x/attr-arch-opts-c67x+.d, gas/tic6x/attr-arch-opts-c67x.d, gas/tic6x/attr-arch-opts-none-1.d, gas/tic6x/attr-arch-opts-none-2.d, gas/tic6x/attr-arch-opts-override-1.d, gas/tic6x/attr-arch-opts-override-2.d, gas/tic6x/empty.s: New. include/elf: * tic6x-attrs.h: New. * tic6x.h: Include elf/tic6x-attrs.h for attribute table. (C6XABI_Tag_CPU_arch_none, C6XABI_Tag_CPU_arch_C62X, C6XABI_Tag_CPU_arch_C67X, C6XABI_Tag_CPU_arch_C67XP, C6XABI_Tag_CPU_arch_C64X, C6XABI_Tag_CPU_arch_C64XP, C6XABI_Tag_CPU_arch_C674X): Define. ld: * emulparams/elf32_tic6x_le.sh (ATTRS_SECTIONS): Define. ld/testsuite: * ld-elf/orphan3.d: Allow section names starting '_'. * ld-tic6x/attr-arch-c62x-c62x.d, ld-tic6x/attr-arch-c62x-c64x+.d, ld-tic6x/attr-arch-c62x-c64x.d, ld-tic6x/attr-arch-c62x-c674x.d, ld-tic6x/attr-arch-c62x-c67x+.d, ld-tic6x/attr-arch-c62x-c67x.d, ld-tic6x/attr-arch-c62x.s, ld-tic6x/attr-arch-c64x+-c62x.d, ld-tic6x/attr-arch-c64x+-c64x+.d, ld-tic6x/attr-arch-c64x+-c64x.d, ld-tic6x/attr-arch-c64x+-c674x.d, ld-tic6x/attr-arch-c64x+-c67x+.d, ld-tic6x/attr-arch-c64x+-c67x.d, ld-tic6x/attr-arch-c64x+.s, ld-tic6x/attr-arch-c64x-c62x.d, ld-tic6x/attr-arch-c64x-c64x+.d, ld-tic6x/attr-arch-c64x-c64x.d, ld-tic6x/attr-arch-c64x-c674x.d, ld-tic6x/attr-arch-c64x-c67x+.d, ld-tic6x/attr-arch-c64x-c67x.d, ld-tic6x/attr-arch-c64x.s, ld-tic6x/attr-arch-c674x-c62x.d, ld-tic6x/attr-arch-c674x-c64x+.d, ld-tic6x/attr-arch-c674x-c64x.d, ld-tic6x/attr-arch-c674x-c674x.d, ld-tic6x/attr-arch-c674x-c67x+.d, ld-tic6x/attr-arch-c674x-c67x.d, ld-tic6x/attr-arch-c674x.s, ld-tic6x/attr-arch-c67x+-c62x.d, ld-tic6x/attr-arch-c67x+-c64x+.d, ld-tic6x/attr-arch-c67x+-c64x.d, ld-tic6x/attr-arch-c67x+-c674x.d, ld-tic6x/attr-arch-c67x+-c67x+.d, ld-tic6x/attr-arch-c67x+-c67x.d, ld-tic6x/attr-arch-c67x+.s, ld-tic6x/attr-arch-c67x-c62x.d, ld-tic6x/attr-arch-c67x-c64x+.d, ld-tic6x/attr-arch-c67x-c64x.d, ld-tic6x/attr-arch-c67x-c674x.d, ld-tic6x/attr-arch-c67x-c67x+.d, ld-tic6x/attr-arch-c67x-c67x.d, ld-tic6x/attr-arch-c67x.s: New. --- gas/config/tc-tic6x.c | 122 +++++++++++++++++++++++++++++++++++++++++++++----- gas/config/tc-tic6x.h | 4 ++ 2 files changed, 115 insertions(+), 11 deletions(-) (limited to 'gas/config') diff --git a/gas/config/tc-tic6x.c b/gas/config/tc-tic6x.c index 5e63c8bd2b6..9c40c15a3e9 100644 --- a/gas/config/tc-tic6x.c +++ b/gas/config/tc-tic6x.c @@ -24,6 +24,7 @@ #include "safe-ctype.h" #include "subsegs.h" #include "opcode/tic6x.h" +#include "elf/tic6x.h" #include "elf32-tic6x.h" /* Truncate and sign-extend at 32 bits, so that building on a 64-bit @@ -81,6 +82,15 @@ static unsigned short tic6x_arch_enable = (TIC6X_INSN_C62X (architecture, as modified by other options). */ static unsigned short tic6x_features; +/* The architecture attribute value, or C6XABI_Tag_CPU_arch_none if + not yet set. */ +static int tic6x_arch_attribute = C6XABI_Tag_CPU_arch_none; + +/* Whether any instructions at all have been seen. Once any + instructions have been seen, architecture attributes merge into the + previous attribute value rather than replacing it. */ +static bfd_boolean tic6x_seen_insns = FALSE; + /* The number of registers in each register file supported by the current architecture. */ static unsigned int tic6x_num_registers; @@ -105,21 +115,26 @@ static bfd_boolean tic6x_generate_rela = TRUE; typedef struct { const char *arch; + int attr; unsigned short features; } tic6x_arch_table; static const tic6x_arch_table tic6x_arches[] = { - { "c62x", TIC6X_INSN_C62X }, - { "c64x", TIC6X_INSN_C62X | TIC6X_INSN_C64X }, - { "c64x+", TIC6X_INSN_C62X | TIC6X_INSN_C64X | TIC6X_INSN_C64XP }, - { "c67x", TIC6X_INSN_C62X | TIC6X_INSN_C67X }, - { "c67x+", TIC6X_INSN_C62X | TIC6X_INSN_C67X | TIC6X_INSN_C67XP }, - { "c674x", (TIC6X_INSN_C62X - | TIC6X_INSN_C64X - | TIC6X_INSN_C64XP - | TIC6X_INSN_C67X - | TIC6X_INSN_C67XP - | TIC6X_INSN_C674X) } + { "c62x", C6XABI_Tag_CPU_arch_C62X, TIC6X_INSN_C62X }, + { "c64x", C6XABI_Tag_CPU_arch_C64X, TIC6X_INSN_C62X | TIC6X_INSN_C64X }, + { "c64x+", C6XABI_Tag_CPU_arch_C64XP, (TIC6X_INSN_C62X + | TIC6X_INSN_C64X + | TIC6X_INSN_C64XP) }, + { "c67x", C6XABI_Tag_CPU_arch_C67X, TIC6X_INSN_C62X | TIC6X_INSN_C67X }, + { "c67x+", C6XABI_Tag_CPU_arch_C67XP, (TIC6X_INSN_C62X + | TIC6X_INSN_C67X + | TIC6X_INSN_C67XP) }, + { "c674x", C6XABI_Tag_CPU_arch_C674X, (TIC6X_INSN_C62X + | TIC6X_INSN_C64X + | TIC6X_INSN_C64XP + | TIC6X_INSN_C67X + | TIC6X_INSN_C67XP + | TIC6X_INSN_C674X) } }; /* Update the selected architecture based on ARCH, giving an error if @@ -135,6 +150,12 @@ tic6x_use_arch (const char *arch) if (strcmp (arch, tic6x_arches[i].arch) == 0) { tic6x_arch_enable = tic6x_arches[i].features; + if (tic6x_seen_insns) + tic6x_arch_attribute + = elf32_tic6x_merge_arch_attributes (tic6x_arch_attribute, + tic6x_arches[i].attr); + else + tic6x_arch_attribute = tic6x_arches[i].attr; return; } @@ -295,10 +316,53 @@ s_tic6x_nocmp (int ignored ATTRIBUTE_UNUSED) demand_empty_rest_of_line (); } +/* Track for each attribute whether it has been set explicitly (and so + should not have a default value set by the assembler). */ +static bfd_boolean tic6x_attributes_set_explicitly[NUM_KNOWN_OBJ_ATTRIBUTES]; + +/* Parse a .c6xabi_attribute directive. */ + +static void +s_tic6x_c6xabi_attribute (int ignored ATTRIBUTE_UNUSED) +{ + int tag = s_vendor_attribute (OBJ_ATTR_PROC); + + if (tag < NUM_KNOWN_OBJ_ATTRIBUTES) + tic6x_attributes_set_explicitly[tag] = TRUE; +} + +typedef struct +{ + const char *name; + int tag; +} tic6x_attribute_table; + +static const tic6x_attribute_table tic6x_attributes[] = + { +#define TAG(tag, value) { #tag, tag } +#include "elf/tic6x-attrs.h" +#undef TAG + }; + +/* Convert an attribute name to a number. */ + +int +tic6x_convert_symbolic_attribute (const char *name) +{ + unsigned int i; + + for (i = 0; i < ARRAY_SIZE (tic6x_attributes); i++) + if (strcmp (name, tic6x_attributes[i].name) == 0) + return tic6x_attributes[i].tag; + + return -1; +} + const pseudo_typeS md_pseudo_table[] = { { "arch", s_tic6x_arch, 0 }, { "atomic", s_tic6x_atomic, 0 }, + { "c6xabi_attribute", s_tic6x_c6xabi_attribute, 0 }, { "noatomic", s_tic6x_noatomic, 0 }, { "nocmp", s_tic6x_nocmp, 0 }, { "word", cons, 4 }, @@ -2587,6 +2651,16 @@ md_assemble (char *str) if (p == str) abort (); + /* Now an instruction has been seen, architecture attributes from + .arch directives merge with rather than overriding the previous + value. */ + tic6x_seen_insns = TRUE; + /* If no .arch directives or -march options have been seen, we are + assessing instruction validity based on the C674X default, so set + the attribute accordingly. */ + if (tic6x_arch_attribute == C6XABI_Tag_CPU_arch_none) + tic6x_arch_attribute = C6XABI_Tag_CPU_arch_C674X; + /* Reset global settings for parallel bars and predicates now to avoid extra errors if there are problems with this opcode. */ this_line_parallel = tic6x_line_parallel; @@ -3760,6 +3834,29 @@ tic6x_frag_init (fragS *fragp) fragp->tc_frag_data.can_cross_fp_boundary = FALSE; } +/* Set an attribute if it has not already been set by the user. */ + +static void +tic6x_set_attribute_int (int tag, int value) +{ + if (tag < 1 + || tag >= NUM_KNOWN_OBJ_ATTRIBUTES) + abort (); + if (!tic6x_attributes_set_explicitly[tag]) + bfd_elf_add_proc_attr_int (stdoutput, tag, value); +} + +/* Set object attributes deduced from the input file and command line + rather than given explicitly. */ +static void +tic6x_set_attributes (void) +{ + if (tic6x_arch_attribute == C6XABI_Tag_CPU_arch_none) + tic6x_arch_attribute = C6XABI_Tag_CPU_arch_C674X; + + tic6x_set_attribute_int (Tag_C6XABI_Tag_CPU_arch, tic6x_arch_attribute); +} + /* Do machine-dependent manipulations of the frag chains after all input has been read and before the machine-independent sizing and relaxing. */ @@ -3767,6 +3864,9 @@ tic6x_frag_init (fragS *fragp) void tic6x_end (void) { + /* Set object attributes at this point if not explicitly set. */ + tic6x_set_attributes (); + /* Meeting alignment requirements may require inserting NOPs in parallel in execute packets earlier in the segment. Future 16-bit instruction generation involves whole-segment optimization diff --git a/gas/config/tc-tic6x.h b/gas/config/tc-tic6x.h index 0285db4baf9..c9df520b4b6 100644 --- a/gas/config/tc-tic6x.h +++ b/gas/config/tc-tic6x.h @@ -119,6 +119,10 @@ extern void tic6x_cons_align (int n); } while (0) extern bfd_boolean tic6x_do_align (int n, char *fill, int len, int max); +#define CONVERT_SYMBOLIC_ATTRIBUTE(name) \ + tic6x_convert_symbolic_attribute (name) +extern int tic6x_convert_symbolic_attribute (const char *); + #define md_end() tic6x_end (); extern void tic6x_end (void); -- cgit v1.2.1