diff options
-rw-r--r-- | bfd/ChangeLog | 4 | ||||
-rw-r--r-- | bfd/elf32-xtensa.c | 1852 | ||||
-rw-r--r-- | gas/ChangeLog | 8 | ||||
-rw-r--r-- | gas/config/tc-xtensa.c | 3621 | ||||
-rw-r--r-- | gas/config/tc-xtensa.h | 70 | ||||
-rw-r--r-- | gas/config/xtensa-istack.h | 18 | ||||
-rw-r--r-- | gas/config/xtensa-relax.c | 474 | ||||
-rw-r--r-- | gas/config/xtensa-relax.h | 8 | ||||
-rw-r--r-- | ld/ChangeLog | 4 | ||||
-rw-r--r-- | ld/emultempl/xtensaelf.em | 49 | ||||
-rw-r--r-- | opcodes/ChangeLog | 4 | ||||
-rw-r--r-- | opcodes/xtensa-dis.c | 26 |
12 files changed, 2335 insertions, 3803 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4dc9458..c0b4e3a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,7 @@ +2004-10-12 Bob Wilson <bob.wilson@acm.org> + + * elf32-xtensa.c: Use ISO C90 formatting. + 2004-10-12 Paul Brook <paul@codesourcery.com> * elf32-arm.h (elf32_arm_merge_private_bfd_data): Rephrase error diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 09ef0e1..56f317f 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -37,233 +37,105 @@ #define XTENSA_NO_NOP_REMOVAL 0 -/* Main interface functions. */ -static void elf_xtensa_info_to_howto_rela - PARAMS ((bfd *, arelent *, Elf_Internal_Rela *)); -static reloc_howto_type *elf_xtensa_reloc_type_lookup - PARAMS ((bfd *abfd, bfd_reloc_code_real_type code)); -extern int xtensa_read_table_entries - PARAMS ((bfd *, asection *, property_table_entry **, const char *, - bfd_boolean)); -static bfd_boolean elf_xtensa_check_relocs - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static void elf_xtensa_hide_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean)); -static asection *elf_xtensa_gc_mark_hook - PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *)); -static bfd_boolean elf_xtensa_gc_sweep_hook - PARAMS ((bfd *, struct bfd_link_info *, asection *, - const Elf_Internal_Rela *)); -static bfd_boolean elf_xtensa_create_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean elf_xtensa_adjust_dynamic_symbol - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static bfd_boolean elf_xtensa_size_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean elf_xtensa_modify_segment_map - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean elf_xtensa_relocate_section - PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); -static bfd_boolean elf_xtensa_relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *again)); -static bfd_boolean elf_xtensa_finish_dynamic_symbol - PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *, - Elf_Internal_Sym *)); -static bfd_boolean elf_xtensa_finish_dynamic_sections - PARAMS ((bfd *, struct bfd_link_info *)); -static bfd_boolean elf_xtensa_merge_private_bfd_data - PARAMS ((bfd *, bfd *)); -static bfd_boolean elf_xtensa_set_private_flags - PARAMS ((bfd *, flagword)); -extern flagword elf_xtensa_get_private_bfd_flags - PARAMS ((bfd *)); -static bfd_boolean elf_xtensa_print_private_bfd_data - PARAMS ((bfd *, PTR)); -static bfd_boolean elf_xtensa_object_p - PARAMS ((bfd *)); -static void elf_xtensa_final_write_processing - PARAMS ((bfd *, bfd_boolean)); -static enum elf_reloc_type_class elf_xtensa_reloc_type_class - PARAMS ((const Elf_Internal_Rela *)); -static bfd_boolean elf_xtensa_discard_info - PARAMS ((bfd *, struct elf_reloc_cookie *, struct bfd_link_info *)); -static bfd_boolean elf_xtensa_ignore_discarded_relocs - PARAMS ((asection *)); -static bfd_boolean elf_xtensa_grok_prstatus - PARAMS ((bfd *, Elf_Internal_Note *)); -static bfd_boolean elf_xtensa_grok_psinfo - PARAMS ((bfd *, Elf_Internal_Note *)); -static bfd_boolean elf_xtensa_new_section_hook - PARAMS ((bfd *, asection *)); - +extern flagword elf_xtensa_get_private_bfd_flags (bfd *); /* Local helper functions. */ -static bfd_boolean xtensa_elf_dynamic_symbol_p - PARAMS ((struct elf_link_hash_entry *, struct bfd_link_info *)); -static int property_table_compare - PARAMS ((const PTR, const PTR)); -static int property_table_matches - PARAMS ((const PTR, const PTR)); -static property_table_entry *elf_xtensa_find_property_entry - PARAMS ((property_table_entry *, int, bfd_vma)); -static bfd_boolean elf_xtensa_in_literal_pool - PARAMS ((property_table_entry *, int, bfd_vma)); -static void elf_xtensa_make_sym_local - PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); -static bfd_boolean add_extra_plt_sections - PARAMS ((bfd *, int)); -static bfd_boolean elf_xtensa_fix_refcounts - PARAMS ((struct elf_link_hash_entry *, PTR)); -static bfd_boolean elf_xtensa_allocate_plt_size - PARAMS ((struct elf_link_hash_entry *, PTR)); -static bfd_boolean elf_xtensa_allocate_got_size - PARAMS ((struct elf_link_hash_entry *, PTR)); -static void elf_xtensa_allocate_local_got_size - PARAMS ((struct bfd_link_info *, asection *)); -static bfd_reloc_status_type elf_xtensa_do_reloc - PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_vma, bfd_byte *, - bfd_vma, bfd_boolean, char **)); -static char * vsprint_msg - VPARAMS ((const char *, const char *, int, ...)); -static char *build_encoding_error_message - PARAMS ((xtensa_opcode, bfd_vma)); +static bfd_boolean add_extra_plt_sections (bfd *, int); +static char *build_encoding_error_message (xtensa_opcode, bfd_vma); static bfd_reloc_status_type bfd_elf_xtensa_reloc - PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **)); + (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **); static bfd_boolean do_fix_for_relocatable_link - PARAMS ((Elf_Internal_Rela *, bfd *, asection *, bfd_byte *)); + (Elf_Internal_Rela *, bfd *, asection *, bfd_byte *); static void do_fix_for_final_link - PARAMS ((Elf_Internal_Rela *, bfd *, asection *, bfd_byte *, bfd_vma *)); -static bfd_vma elf_xtensa_create_plt_entry - PARAMS ((bfd *, bfd *, unsigned)); -static int elf_xtensa_combine_prop_entries - PARAMS ((bfd *, asection *, asection *)); -static bfd_boolean elf_xtensa_discard_info_for_section - PARAMS ((bfd *, struct elf_reloc_cookie *, struct bfd_link_info *, - asection *)); + (Elf_Internal_Rela *, bfd *, asection *, bfd_byte *, bfd_vma *); /* Local functions to handle Xtensa configurability. */ -static void init_call_opcodes - PARAMS ((void)); -static bfd_boolean is_indirect_call_opcode - PARAMS ((xtensa_opcode)); -static bfd_boolean is_direct_call_opcode - PARAMS ((xtensa_opcode)); -static bfd_boolean is_windowed_call_opcode - PARAMS ((xtensa_opcode)); -static xtensa_opcode get_const16_opcode - PARAMS ((void)); -static xtensa_opcode get_l32r_opcode - PARAMS ((void)); -static bfd_vma l32r_offset - PARAMS ((bfd_vma, bfd_vma)); -static int get_relocation_opnd - PARAMS ((xtensa_opcode, int)); -static int get_relocation_slot - PARAMS ((int)); +static bfd_boolean is_indirect_call_opcode (xtensa_opcode); +static bfd_boolean is_direct_call_opcode (xtensa_opcode); +static bfd_boolean is_windowed_call_opcode (xtensa_opcode); +static xtensa_opcode get_const16_opcode (void); +static xtensa_opcode get_l32r_opcode (void); +static bfd_vma l32r_offset (bfd_vma, bfd_vma); +static int get_relocation_opnd (xtensa_opcode, int); +static int get_relocation_slot (int); static xtensa_opcode get_relocation_opcode - PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *)); + (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *); static bfd_boolean is_l32r_relocation - PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *)); -static bfd_boolean is_alt_relocation - PARAMS ((int)); -static bfd_boolean is_operand_relocation - PARAMS ((int)); + (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *); +static bfd_boolean is_alt_relocation (int); +static bfd_boolean is_operand_relocation (int); static bfd_size_type insn_decode_len - PARAMS ((bfd_byte *, bfd_size_type, bfd_size_type)); + (bfd_byte *, bfd_size_type, bfd_size_type); static xtensa_opcode insn_decode_opcode - PARAMS ((bfd_byte *, bfd_size_type, bfd_size_type, int)); + (bfd_byte *, bfd_size_type, bfd_size_type, int); static bfd_boolean check_branch_target_aligned - PARAMS ((bfd_byte *, bfd_size_type, bfd_vma, bfd_vma)); + (bfd_byte *, bfd_size_type, bfd_vma, bfd_vma); static bfd_boolean check_loop_aligned - PARAMS ((bfd_byte *, bfd_size_type, bfd_vma, bfd_vma)); -static bfd_boolean check_branch_target_aligned_address - PARAMS ((bfd_vma, int)); + (bfd_byte *, bfd_size_type, bfd_vma, bfd_vma); +static bfd_boolean check_branch_target_aligned_address (bfd_vma, int); static bfd_size_type get_asm_simplify_size - PARAMS ((bfd_byte *, bfd_size_type, bfd_size_type)); + (bfd_byte *, bfd_size_type, bfd_size_type); /* Functions for link-time code simplifications. */ static bfd_reloc_status_type elf_xtensa_do_asm_simplify - PARAMS ((bfd_byte *, bfd_vma, bfd_vma, char **)); + (bfd_byte *, bfd_vma, bfd_vma, char **); static bfd_reloc_status_type contract_asm_expansion - PARAMS ((bfd_byte *, bfd_vma, Elf_Internal_Rela *, char **)); -static xtensa_opcode swap_callx_for_call_opcode - PARAMS ((xtensa_opcode)); -static xtensa_opcode get_expanded_call_opcode - PARAMS ((bfd_byte *, int, bfd_boolean *)); + (bfd_byte *, bfd_vma, Elf_Internal_Rela *, char **); +static xtensa_opcode swap_callx_for_call_opcode (xtensa_opcode); +static xtensa_opcode get_expanded_call_opcode (bfd_byte *, int, bfd_boolean *); /* Access to internal relocations, section contents and symbols. */ static Elf_Internal_Rela *retrieve_internal_relocs - PARAMS ((bfd *, asection *, bfd_boolean)); -static void pin_internal_relocs - PARAMS ((asection *, Elf_Internal_Rela *)); -static void release_internal_relocs - PARAMS ((asection *, Elf_Internal_Rela *)); -static bfd_byte *retrieve_contents - PARAMS ((bfd *, asection *, bfd_boolean)); -static void pin_contents - PARAMS ((asection *, bfd_byte *)); -static void release_contents - PARAMS ((asection *, bfd_byte *)); -static Elf_Internal_Sym *retrieve_local_syms - PARAMS ((bfd *)); + (bfd *, asection *, bfd_boolean); +static void pin_internal_relocs (asection *, Elf_Internal_Rela *); +static void release_internal_relocs (asection *, Elf_Internal_Rela *); +static bfd_byte *retrieve_contents (bfd *, asection *, bfd_boolean); +static void pin_contents (asection *, bfd_byte *); +static void release_contents (asection *, bfd_byte *); +static Elf_Internal_Sym *retrieve_local_syms (bfd *); /* Miscellaneous utility functions. */ -static asection *elf_xtensa_get_plt_section - PARAMS ((bfd *, int)); -static asection *elf_xtensa_get_gotplt_section - PARAMS ((bfd *, int)); -static asection *get_elf_r_symndx_section - PARAMS ((bfd *, unsigned long)); +static asection *elf_xtensa_get_plt_section (bfd *, int); +static asection *elf_xtensa_get_gotplt_section (bfd *, int); +static asection *get_elf_r_symndx_section (bfd *, unsigned long); static struct elf_link_hash_entry *get_elf_r_symndx_hash_entry - PARAMS ((bfd *, unsigned long)); -static bfd_vma get_elf_r_symndx_offset - PARAMS ((bfd *, unsigned long)); -static bfd_boolean is_reloc_sym_weak - PARAMS ((bfd *, Elf_Internal_Rela *)); -static bfd_boolean pcrel_reloc_fits - PARAMS ((xtensa_opcode, int, bfd_vma, bfd_vma)); -static bfd_boolean xtensa_is_property_section - PARAMS ((asection *)); -static bfd_boolean xtensa_is_littable_section - PARAMS ((asection *)); -static int internal_reloc_compare - PARAMS ((const PTR, const PTR)); -static int internal_reloc_matches - PARAMS ((const PTR, const PTR)); -extern char *xtensa_get_property_section_name - PARAMS ((asection *, const char *)); -static flagword xtensa_get_property_predef_flags - PARAMS ((asection *)); + (bfd *, unsigned long); +static bfd_vma get_elf_r_symndx_offset (bfd *, unsigned long); +static bfd_boolean is_reloc_sym_weak (bfd *, Elf_Internal_Rela *); +static bfd_boolean pcrel_reloc_fits (xtensa_opcode, int, bfd_vma, bfd_vma); +static bfd_boolean xtensa_is_property_section (asection *); +static bfd_boolean xtensa_is_littable_section (asection *); +static int internal_reloc_compare (const void *, const void *); +static int internal_reloc_matches (const void *, const void *); +extern char *xtensa_get_property_section_name (asection *, const char *); +static flagword xtensa_get_property_predef_flags (asection *); /* Other functions called directly by the linker. */ typedef void (*deps_callback_t) - PARAMS ((asection *, bfd_vma, asection *, bfd_vma, PTR)); + (asection *, bfd_vma, asection *, bfd_vma, void *); extern bfd_boolean xtensa_callback_required_dependence - PARAMS ((bfd *, asection *, struct bfd_link_info *, - deps_callback_t, PTR)); + (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *); /* Globally visible flag for choosing size optimization of NOP removal instead of branch-target-aware minimization for NOP removal. When nonzero, narrow all instructions and remove all NOPs possible around longcall expansions. */ + int elf32xtensa_size_opt; /* The "new_section_hook" is used to set up a per-section "xtensa_relax_info" data structure with additional information used during relaxation. */ -typedef struct xtensa_relax_info_struct xtensa_relax_info; +typedef struct xtensa_relax_info_struct xtensa_relax_info; /* Total count of PLT relocations seen during check_relocs. @@ -467,9 +339,8 @@ static reloc_howto_type elf_howto_table[] = #endif static reloc_howto_type * -elf_xtensa_reloc_type_lookup (abfd, code) - bfd *abfd ATTRIBUTE_UNUSED; - bfd_reloc_code_real_type code; +elf_xtensa_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) { switch (code) { @@ -570,10 +441,9 @@ elf_xtensa_reloc_type_lookup (abfd, code) it in the BFD internal arelent representation of the relocation. */ static void -elf_xtensa_info_to_howto_rela (abfd, cache_ptr, dst) - bfd *abfd ATTRIBUTE_UNUSED; - arelent *cache_ptr; - Elf_Internal_Rela *dst; +elf_xtensa_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) { unsigned int r_type = ELF32_R_TYPE (dst->r_info); @@ -634,9 +504,8 @@ static const bfd_byte elf_xtensa_le_plt_entry[PLT_ENTRY_SIZE] = static inline bfd_boolean -xtensa_elf_dynamic_symbol_p (h, info) - struct elf_link_hash_entry *h; - struct bfd_link_info *info; +xtensa_elf_dynamic_symbol_p (struct elf_link_hash_entry *h, + struct bfd_link_info *info) { /* Check if we should do dynamic things to this symbol. The "ignore_protected" argument need not be set, because Xtensa code @@ -649,9 +518,7 @@ xtensa_elf_dynamic_symbol_p (h, info) static int -property_table_compare (ap, bp) - const PTR ap; - const PTR bp; +property_table_compare (const void *ap, const void *bp) { const property_table_entry *a = (const property_table_entry *) ap; const property_table_entry *b = (const property_table_entry *) bp; @@ -690,9 +557,7 @@ property_table_compare (ap, bp) static int -property_table_matches (ap, bp) - const PTR ap; - const PTR bp; +property_table_matches (const void *ap, const void *bp) { const property_table_entry *a = (const property_table_entry *) ap; const property_table_entry *b = (const property_table_entry *) bp; @@ -710,13 +575,12 @@ property_table_matches (ap, bp) section. Sets TABLE_P and returns the number of entries. On error, returns a negative value. */ -int -xtensa_read_table_entries (abfd, section, table_p, sec_name, output_addr) - bfd *abfd; - asection *section; - property_table_entry **table_p; - const char *sec_name; - bfd_boolean output_addr; +static int +xtensa_read_table_entries (bfd *abfd, + asection *section, + property_table_entry **table_p, + const char *sec_name, + bfd_boolean output_addr) { asection *table_section; char *table_section_name; @@ -845,11 +709,10 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name, output_addr) } -property_table_entry * -elf_xtensa_find_property_entry (property_table, property_table_size, addr) - property_table_entry *property_table; - int property_table_size; - bfd_vma addr; +static property_table_entry * +elf_xtensa_find_property_entry (property_table_entry *property_table, + int property_table_size, + bfd_vma addr) { property_table_entry entry; property_table_entry *rv; @@ -868,10 +731,9 @@ elf_xtensa_find_property_entry (property_table, property_table_size, addr) static bfd_boolean -elf_xtensa_in_literal_pool (lit_table, lit_table_size, addr) - property_table_entry *lit_table; - int lit_table_size; - bfd_vma addr; +elf_xtensa_in_literal_pool (property_table_entry *lit_table, + int lit_table_size, + bfd_vma addr) { if (elf_xtensa_find_property_entry (lit_table, lit_table_size, addr)) return TRUE; @@ -884,11 +746,10 @@ elf_xtensa_in_literal_pool (lit_table, lit_table_size, addr) calculate needed space in the dynamic reloc sections. */ static bfd_boolean -elf_xtensa_check_relocs (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info; - asection *sec; - const Elf_Internal_Rela *relocs; +elf_xtensa_check_relocs (bfd *abfd, + struct bfd_link_info *info, + asection *sec, + const Elf_Internal_Rela *relocs) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -1061,10 +922,33 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs) static void -elf_xtensa_hide_symbol (info, h, force_local) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; - bfd_boolean force_local; +elf_xtensa_make_sym_local (struct bfd_link_info *info, + struct elf_link_hash_entry *h) +{ + if (info->shared) + { + if (h->plt.refcount > 0) + { + /* Will use RELATIVE relocs instead of JMP_SLOT relocs. */ + if (h->got.refcount < 0) + h->got.refcount = 0; + h->got.refcount += h->plt.refcount; + h->plt.refcount = 0; + } + } + else + { + /* Don't need any dynamic relocations at all. */ + h->plt.refcount = 0; + h->got.refcount = 0; + } +} + + +static void +elf_xtensa_hide_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h, + bfd_boolean force_local) { /* For a shared link, move the plt refcount to the got refcount to leave space for RELATIVE relocs. */ @@ -1078,14 +962,13 @@ elf_xtensa_hide_symbol (info, h, force_local) relocation. */ static asection * -elf_xtensa_gc_mark_hook (sec, info, rel, h, sym) - asection *sec; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +elf_xtensa_gc_mark_hook (asection *sec, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { - if (h != NULL) + if (h) { switch (ELF32_R_TYPE (rel->r_info)) { @@ -1114,15 +997,15 @@ elf_xtensa_gc_mark_hook (sec, info, rel, h, sym) return NULL; } + /* Update the GOT & PLT entry reference counts for the section being removed. */ static bfd_boolean -elf_xtensa_gc_sweep_hook (abfd, info, sec, relocs) - bfd *abfd; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - asection *sec; - const Elf_Internal_Rela *relocs; +elf_xtensa_gc_sweep_hook (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sec, + const Elf_Internal_Rela *relocs) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -1181,9 +1064,7 @@ elf_xtensa_gc_sweep_hook (abfd, info, sec, relocs) /* Create all the dynamic sections. */ static bfd_boolean -elf_xtensa_create_dynamic_sections (dynobj, info) - bfd *dynobj; - struct bfd_link_info *info; +elf_xtensa_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info) { flagword flags, noalloc_flags; asection *s; @@ -1233,9 +1114,7 @@ elf_xtensa_create_dynamic_sections (dynobj, info) static bfd_boolean -add_extra_plt_sections (dynobj, count) - bfd *dynobj; - int count; +add_extra_plt_sections (bfd *dynobj, int count) { int chunk; @@ -1282,14 +1161,13 @@ add_extra_plt_sections (dynobj, count) understand. */ static bfd_boolean -elf_xtensa_adjust_dynamic_symbol (info, h) - struct bfd_link_info *info ATTRIBUTE_UNUSED; - struct elf_link_hash_entry *h; +elf_xtensa_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED, + struct elf_link_hash_entry *h) { /* If this is a weak symbol, and there is a real definition, the processor independent code will have arranged for us to see the real definition first, and we can just use the same value. */ - if (h->u.weakdef != NULL) + if (h->u.weakdef) { BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined || h->u.weakdef->root.type == bfd_link_hash_defweak); @@ -1306,35 +1184,8 @@ elf_xtensa_adjust_dynamic_symbol (info, h) } -static void -elf_xtensa_make_sym_local (info, h) - struct bfd_link_info *info; - struct elf_link_hash_entry *h; -{ - if (info->shared) - { - if (h->plt.refcount > 0) - { - /* Will use RELATIVE relocs instead of JMP_SLOT relocs. */ - if (h->got.refcount < 0) - h->got.refcount = 0; - h->got.refcount += h->plt.refcount; - h->plt.refcount = 0; - } - } - else - { - /* Don't need any dynamic relocations at all. */ - h->plt.refcount = 0; - h->got.refcount = 0; - } -} - - static bfd_boolean -elf_xtensa_fix_refcounts (h, arg) - struct elf_link_hash_entry *h; - PTR arg; +elf_xtensa_fix_refcounts (struct elf_link_hash_entry *h, void *arg) { struct bfd_link_info *info = (struct bfd_link_info *) arg; @@ -1349,9 +1200,7 @@ elf_xtensa_fix_refcounts (h, arg) static bfd_boolean -elf_xtensa_allocate_plt_size (h, arg) - struct elf_link_hash_entry *h; - PTR arg; +elf_xtensa_allocate_plt_size (struct elf_link_hash_entry *h, void *arg) { asection *srelplt = (asection *) arg; @@ -1366,9 +1215,7 @@ elf_xtensa_allocate_plt_size (h, arg) static bfd_boolean -elf_xtensa_allocate_got_size (h, arg) - struct elf_link_hash_entry *h; - PTR arg; +elf_xtensa_allocate_got_size (struct elf_link_hash_entry *h, void *arg) { asection *srelgot = (asection *) arg; @@ -1383,9 +1230,8 @@ elf_xtensa_allocate_got_size (h, arg) static void -elf_xtensa_allocate_local_got_size (info, srelgot) - struct bfd_link_info *info; - asection *srelgot; +elf_xtensa_allocate_local_got_size (struct bfd_link_info *info, + asection *srelgot) { bfd *i; @@ -1415,9 +1261,8 @@ elf_xtensa_allocate_local_got_size (info, srelgot) /* Set the sizes of the dynamic sections. */ static bfd_boolean -elf_xtensa_size_dynamic_sections (output_bfd, info) - bfd *output_bfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info; +elf_xtensa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info) { bfd *dynobj, *abfd; asection *s, *srelplt, *splt, *sgotplt, *srelgot, *spltlittbl, *sgotloc; @@ -1453,7 +1298,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info) /* Adjust refcounts for symbols that we now know are not "dynamic". */ elf_link_hash_traverse (elf_hash_table (info), elf_xtensa_fix_refcounts, - (PTR) info); + (void *) info); /* Allocate space in ".rela.got" for literals that reference global symbols. */ @@ -1462,7 +1307,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info) abort (); elf_link_hash_traverse (elf_hash_table (info), elf_xtensa_allocate_got_size, - (PTR) srelgot); + (void *) srelgot); /* If we are generating a shared object, we also need space in ".rela.got" for R_XTENSA_RELATIVE relocs for literals that @@ -1476,7 +1321,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info) abort (); elf_link_hash_traverse (elf_hash_table (info), elf_xtensa_allocate_plt_size, - (PTR) srelplt); + (void *) srelplt); /* Allocate space in ".plt" to match the size of ".rela.plt". For each PLT entry, we need the PLT code plus a 4-byte literal. @@ -1684,14 +1529,13 @@ elf_xtensa_size_dynamic_sections (output_bfd, info) this and it probably ought to be moved into elf.c as well. */ static bfd_boolean -elf_xtensa_modify_segment_map (abfd, info) - bfd *abfd; - struct bfd_link_info *info ATTRIBUTE_UNUSED; +elf_xtensa_modify_segment_map (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED) { struct elf_segment_map **m_p; m_p = &elf_tdata (abfd)->segment_map; - while (*m_p != NULL) + while (*m_p) { if ((*m_p)->p_type == PT_LOAD && (*m_p)->count == 0) *m_p = (*m_p)->next; @@ -1708,19 +1552,17 @@ elf_xtensa_modify_segment_map (abfd, info) howto. */ #define CALL_SEGMENT_BITS (30) -#define CALL_SEGMENT_SIZE (1<<CALL_SEGMENT_BITS) +#define CALL_SEGMENT_SIZE (1 << CALL_SEGMENT_BITS) static bfd_reloc_status_type -elf_xtensa_do_reloc (howto, abfd, input_section, relocation, - contents, address, is_weak_undef, error_message) - reloc_howto_type *howto; - bfd *abfd; - asection *input_section; - bfd_vma relocation; - bfd_byte *contents; - bfd_vma address; - bfd_boolean is_weak_undef; - char **error_message; +elf_xtensa_do_reloc (reloc_howto_type *howto, + bfd *abfd, + asection *input_section, + bfd_vma relocation, + bfd_byte *contents, + bfd_vma address, + bfd_boolean is_weak_undef, + char **error_message) { xtensa_format fmt; xtensa_opcode opcode; @@ -1921,7 +1763,7 @@ elf_xtensa_do_reloc (howto, abfd, input_section, relocation, static char * -vsprint_msg VPARAMS ((const char *origmsg, const char *fmt, int arglen, ...)) +vsprint_msg (const char *origmsg, const char *fmt, int arglen, ...) { /* To reduce the size of the memory leak, we only use a single message buffer. */ @@ -1951,9 +1793,7 @@ vsprint_msg VPARAMS ((const char *origmsg, const char *fmt, int arglen, ...)) static char * -build_encoding_error_message (opcode, target_address) - xtensa_opcode opcode; - bfd_vma target_address; +build_encoding_error_message (xtensa_opcode opcode, bfd_vma target_address) { const char *opname = xtensa_opcode_name (xtensa_default_isa, opcode); const char *msg; @@ -1986,15 +1826,13 @@ build_encoding_error_message (opcode, target_address) stripped-down version of bfd_perform_relocation. */ static bfd_reloc_status_type -bfd_elf_xtensa_reloc (abfd, reloc_entry, symbol, data, input_section, - output_bfd, error_message) - bfd *abfd; - arelent *reloc_entry; - asymbol *symbol; - PTR data; - asection *input_section; - bfd *output_bfd; - char **error_message; +bfd_elf_xtensa_reloc (bfd *abfd, + arelent *reloc_entry, + asymbol *symbol, + void *data, + asection *input_section, + bfd *output_bfd, + char **error_message) { bfd_vma relocation; bfd_reloc_status_type flag; @@ -2015,8 +1853,7 @@ bfd_elf_xtensa_reloc (abfd, reloc_entry, symbol, data, input_section, relocs to begin with, but that's a long story and there's little we can do about it now....) */ - if (output_bfd != (bfd *) NULL - && (symbol->flags & BSF_SECTION_SYM) == 0) + if (output_bfd && (symbol->flags & BSF_SECTION_SYM) == 0) { reloc_entry->address += input_section->output_offset; return bfd_reloc_ok; @@ -2095,10 +1932,9 @@ bfd_elf_xtensa_reloc (abfd, reloc_entry, symbol, data, input_section, /* Set up an entry in the procedure linkage table. */ static bfd_vma -elf_xtensa_create_plt_entry (dynobj, output_bfd, reloc_index) - bfd *dynobj; - bfd *output_bfd; - unsigned reloc_index; +elf_xtensa_create_plt_entry (bfd *dynobj, + bfd *output_bfd, + unsigned reloc_index) { asection *splt, *sgotplt; bfd_vma plt_base, got_base; @@ -2145,17 +1981,14 @@ elf_xtensa_create_plt_entry (dynobj, output_bfd, reloc_index) both relocatable and final links. */ static bfd_boolean -elf_xtensa_relocate_section (output_bfd, info, input_bfd, - input_section, contents, relocs, - local_syms, local_sections) - bfd *output_bfd; - struct bfd_link_info *info; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - Elf_Internal_Rela *relocs; - Elf_Internal_Sym *local_syms; - asection **local_sections; +elf_xtensa_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) { Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Rela *rel; @@ -2177,7 +2010,7 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, srelgot = NULL; srelplt = NULL; - if (dynobj != NULL) + if (dynobj) { srelgot = bfd_get_section_by_name (dynobj, ".rela.got");; srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); @@ -2487,9 +2320,9 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, const char *name; BFD_ASSERT (r == bfd_reloc_dangerous || r == bfd_reloc_other); - BFD_ASSERT (error_message != (char *) NULL); + BFD_ASSERT (error_message != NULL); - if (h != NULL) + if (h) name = h->root.root.string; else { @@ -2529,11 +2362,10 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd, the PLT and GOT entries are all set up by relocate_section. */ static bfd_boolean -elf_xtensa_finish_dynamic_symbol (output_bfd, info, h, sym) - bfd *output_bfd ATTRIBUTE_UNUSED; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +elf_xtensa_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) { if (h->needs_plt && !h->def_regular) @@ -2561,10 +2393,9 @@ elf_xtensa_finish_dynamic_symbol (output_bfd, info, h, sym) on error. */ static int -elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc) - bfd *output_bfd; - asection *sxtlit; - asection *sgotloc; +elf_xtensa_combine_prop_entries (bfd *output_bfd, + asection *sxtlit, + asection *sgotloc) { bfd_byte *contents; property_table_entry *table; @@ -2669,9 +2500,8 @@ elf_xtensa_combine_prop_entries (output_bfd, sxtlit, sgotloc) /* Finish up the dynamic sections. */ static bfd_boolean -elf_xtensa_finish_dynamic_sections (output_bfd, info) - bfd *output_bfd; - struct bfd_link_info *info; +elf_xtensa_finish_dynamic_sections (bfd *output_bfd, + struct bfd_link_info *info) { bfd *dynobj; asection *sdyn, *srelplt, *sgot, *sxtlit, *sgotloc; @@ -2692,7 +2522,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info) { BFD_ASSERT (sgot->size == 4); if (sdyn == NULL) - bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents); + bfd_put_32 (output_bfd, 0, sgot->contents); else bfd_put_32 (output_bfd, sdyn->output_section->vma + sdyn->output_offset, @@ -2700,7 +2530,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info) } srelplt = bfd_get_section_by_name (dynobj, ".rela.plt"); - if (srelplt != NULL && srelplt->size != 0) + if (srelplt && srelplt->size != 0) { asection *sgotplt, *srelgot, *spltlittbl; int chunk, plt_chunks, plt_entries; @@ -2873,9 +2703,7 @@ elf_xtensa_finish_dynamic_sections (output_bfd, info) object file when linking. */ static bfd_boolean -elf_xtensa_merge_private_bfd_data (ibfd, obfd) - bfd *ibfd; - bfd *obfd; +elf_xtensa_merge_private_bfd_data (bfd *ibfd, bfd *obfd) { unsigned out_mach, in_mach; flagword out_flag, in_flag; @@ -2927,9 +2755,7 @@ elf_xtensa_merge_private_bfd_data (ibfd, obfd) static bfd_boolean -elf_xtensa_set_private_flags (abfd, flags) - bfd *abfd; - flagword flags; +elf_xtensa_set_private_flags (bfd *abfd, flagword flags) { BFD_ASSERT (!elf_flags_init (abfd) || elf_elfheader (abfd)->e_flags == flags); @@ -2942,17 +2768,14 @@ elf_xtensa_set_private_flags (abfd, flags) extern flagword -elf_xtensa_get_private_bfd_flags (abfd) - bfd *abfd; +elf_xtensa_get_private_bfd_flags (bfd *abfd) { return elf_elfheader (abfd)->e_flags; } static bfd_boolean -elf_xtensa_print_private_bfd_data (abfd, farg) - bfd *abfd; - PTR farg; +elf_xtensa_print_private_bfd_data (bfd *abfd, void *farg) { FILE *f = (FILE *) farg; flagword e_flags = elf_elfheader (abfd)->e_flags; @@ -2976,8 +2799,7 @@ elf_xtensa_print_private_bfd_data (abfd, farg) /* Set the right machine number for an Xtensa ELF file. */ static bfd_boolean -elf_xtensa_object_p (abfd) - bfd *abfd; +elf_xtensa_object_p (bfd *abfd) { int mach; unsigned long arch = elf_elfheader (abfd)->e_flags & EF_XTENSA_MACH; @@ -3001,9 +2823,8 @@ elf_xtensa_object_p (abfd) number. */ static void -elf_xtensa_final_write_processing (abfd, linker) - bfd *abfd; - bfd_boolean linker ATTRIBUTE_UNUSED; +elf_xtensa_final_write_processing (bfd *abfd, + bfd_boolean linker ATTRIBUTE_UNUSED) { int mach; unsigned long val; @@ -3023,8 +2844,7 @@ elf_xtensa_final_write_processing (abfd, linker) static enum elf_reloc_type_class -elf_xtensa_reloc_type_class (rela) - const Elf_Internal_Rela *rela; +elf_xtensa_reloc_type_class (const Elf_Internal_Rela *rela) { switch ((int) ELF32_R_TYPE (rela->r_info)) { @@ -3039,11 +2859,10 @@ elf_xtensa_reloc_type_class (rela) static bfd_boolean -elf_xtensa_discard_info_for_section (abfd, cookie, info, sec) - bfd *abfd; - struct elf_reloc_cookie *cookie; - struct bfd_link_info *info; - asection *sec; +elf_xtensa_discard_info_for_section (bfd *abfd, + struct elf_reloc_cookie *cookie, + struct bfd_link_info *info, + asection *sec) { bfd_byte *contents; bfd_vma section_size; @@ -3164,10 +2983,9 @@ elf_xtensa_discard_info_for_section (abfd, cookie, info, sec) static bfd_boolean -elf_xtensa_discard_info (abfd, cookie, info) - bfd *abfd; - struct elf_reloc_cookie *cookie; - struct bfd_link_info *info; +elf_xtensa_discard_info (bfd *abfd, + struct elf_reloc_cookie *cookie, + struct bfd_link_info *info) { asection *sec; bfd_boolean changed = FALSE; @@ -3186,8 +3004,7 @@ elf_xtensa_discard_info (abfd, cookie, info) static bfd_boolean -elf_xtensa_ignore_discarded_relocs (sec) - asection *sec; +elf_xtensa_ignore_discarded_relocs (asection *sec) { return xtensa_is_property_section (sec); } @@ -3196,9 +3013,7 @@ elf_xtensa_ignore_discarded_relocs (sec) /* Support for core dump NOTE sections. */ static bfd_boolean -elf_xtensa_grok_prstatus (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +elf_xtensa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note) { int offset; unsigned int size; @@ -3223,9 +3038,7 @@ elf_xtensa_grok_prstatus (abfd, note) static bfd_boolean -elf_xtensa_grok_psinfo (abfd, note) - bfd *abfd; - Elf_Internal_Note *note; +elf_xtensa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note) { switch (note->descsz) { @@ -3267,7 +3080,7 @@ static xtensa_opcode call8_op = XTENSA_UNDEFINED; static xtensa_opcode call12_op = XTENSA_UNDEFINED; static void -init_call_opcodes () +init_call_opcodes (void) { if (callx0_op == XTENSA_UNDEFINED) { @@ -3284,8 +3097,7 @@ init_call_opcodes () static bfd_boolean -is_indirect_call_opcode (opcode) - xtensa_opcode opcode; +is_indirect_call_opcode (xtensa_opcode opcode) { init_call_opcodes (); return (opcode == callx0_op @@ -3296,8 +3108,7 @@ is_indirect_call_opcode (opcode) static bfd_boolean -is_direct_call_opcode (opcode) - xtensa_opcode opcode; +is_direct_call_opcode (xtensa_opcode opcode) { init_call_opcodes (); return (opcode == call0_op @@ -3308,8 +3119,7 @@ is_direct_call_opcode (opcode) static bfd_boolean -is_windowed_call_opcode (opcode) - xtensa_opcode opcode; +is_windowed_call_opcode (xtensa_opcode opcode) { init_call_opcodes (); return (opcode == call4_op @@ -3351,9 +3161,7 @@ get_l32r_opcode (void) static bfd_vma -l32r_offset (addr, pc) - bfd_vma addr; - bfd_vma pc; +l32r_offset (bfd_vma addr, bfd_vma pc) { bfd_vma offset; @@ -3366,9 +3174,7 @@ l32r_offset (addr, pc) static int -get_relocation_opnd (opcode, r_type) - xtensa_opcode opcode; - int r_type; +get_relocation_opnd (xtensa_opcode opcode, int r_type) { xtensa_isa isa = xtensa_default_isa; int last_immed, last_opnd, opi; @@ -3411,8 +3217,7 @@ get_relocation_opnd (opcode, r_type) int -get_relocation_slot (r_type) - int r_type; +get_relocation_slot (int r_type) { switch (r_type) { @@ -3436,11 +3241,10 @@ get_relocation_slot (r_type) /* Get the opcode for a relocation. */ static xtensa_opcode -get_relocation_opcode (abfd, sec, contents, irel) - bfd *abfd; - asection *sec; - bfd_byte *contents; - Elf_Internal_Rela *irel; +get_relocation_opcode (bfd *abfd, + asection *sec, + bfd_byte *contents, + Elf_Internal_Rela *irel) { static xtensa_insnbuf ibuff = NULL; static xtensa_insnbuf sbuff = NULL; @@ -3473,11 +3277,10 @@ get_relocation_opcode (abfd, sec, contents, irel) bfd_boolean -is_l32r_relocation (abfd, sec, contents, irel) - bfd *abfd; - asection *sec; - bfd_byte *contents; - Elf_Internal_Rela *irel; +is_l32r_relocation (bfd *abfd, + asection *sec, + bfd_byte *contents, + Elf_Internal_Rela *irel) { xtensa_opcode opcode; if (!is_operand_relocation (ELF32_R_TYPE (irel->r_info))) @@ -3488,10 +3291,9 @@ is_l32r_relocation (abfd, sec, contents, irel) static bfd_size_type -get_asm_simplify_size (contents, content_len, offset) - bfd_byte *contents; - bfd_size_type content_len; - bfd_size_type offset; +get_asm_simplify_size (bfd_byte *contents, + bfd_size_type content_len, + bfd_size_type offset) { bfd_size_type insnlen, size = 0; @@ -3512,8 +3314,7 @@ get_asm_simplify_size (contents, content_len, offset) bfd_boolean -is_alt_relocation (r_type) - int r_type; +is_alt_relocation (int r_type) { return (r_type >= R_XTENSA_SLOT0_ALT && r_type <= R_XTENSA_SLOT14_ALT); @@ -3521,8 +3322,7 @@ is_alt_relocation (r_type) bfd_boolean -is_operand_relocation (r_type) - int r_type; +is_operand_relocation (int r_type) { switch (r_type) { @@ -3548,10 +3348,9 @@ is_operand_relocation (r_type) /* Return 0 if it fails to decode. */ bfd_size_type -insn_decode_len (contents, content_len, offset) - bfd_byte *contents; - bfd_size_type content_len; - bfd_size_type offset; +insn_decode_len (bfd_byte *contents, + bfd_size_type content_len, + bfd_size_type offset) { int insn_len; xtensa_isa isa = xtensa_default_isa; @@ -3579,11 +3378,10 @@ insn_decode_len (contents, content_len, offset) Return 0 if it fails to decode or the instruction is multi-slot. */ xtensa_opcode -insn_decode_opcode (contents, content_len, offset, slot) - bfd_byte *contents; - bfd_size_type content_len; - bfd_size_type offset; - int slot; +insn_decode_opcode (bfd_byte *contents, + bfd_size_type content_len, + bfd_size_type offset, + int slot) { xtensa_isa isa = xtensa_default_isa; xtensa_format fmt; @@ -3617,11 +3415,10 @@ insn_decode_opcode (contents, content_len, offset, slot) The address is the address of that offset. */ static bfd_boolean -check_branch_target_aligned (contents, content_length, offset, address) - bfd_byte *contents; - bfd_size_type content_length; - bfd_vma offset; - bfd_vma address; +check_branch_target_aligned (bfd_byte *contents, + bfd_size_type content_length, + bfd_vma offset, + bfd_vma address) { bfd_size_type insn_len = insn_decode_len (contents, content_length, offset); if (insn_len == 0) @@ -3631,11 +3428,10 @@ check_branch_target_aligned (contents, content_length, offset, address) static bfd_boolean -check_loop_aligned (contents, content_length, offset, address) - bfd_byte *contents; - bfd_size_type content_length; - bfd_vma offset; - bfd_vma address; +check_loop_aligned (bfd_byte *contents, + bfd_size_type content_length, + bfd_vma offset, + bfd_vma address) { bfd_size_type loop_len, insn_len; xtensa_opcode opcode = @@ -3662,9 +3458,7 @@ check_loop_aligned (contents, content_length, offset, address) static bfd_boolean -check_branch_target_aligned_address (addr, len) - bfd_vma addr; - int len; +check_branch_target_aligned_address (bfd_vma addr, int len) { if (len == 8) return (addr % 8 == 0); @@ -3674,21 +3468,58 @@ check_branch_target_aligned_address (addr, len) /* Instruction widening and narrowing. */ -static bfd_boolean narrow_instruction - PARAMS ((bfd_byte *, bfd_size_type, bfd_size_type, bfd_boolean)); -static bfd_boolean widen_instruction - PARAMS ((bfd_byte *, bfd_size_type, bfd_size_type, bfd_boolean)); -static xtensa_format get_single_format - PARAMS ((xtensa_opcode)); -static void init_op_single_format_table - PARAMS ((void)); +/* When FLIX is available we need to access certain instructions only + when they are 16-bit or 24-bit instructions. This table caches + information about such instructions by walking through all the + opcodes and finding the smallest single-slot format into which each + can be encoded. */ + +static xtensa_format *op_single_fmt_table = NULL; -struct string_pair +static void +init_op_single_format_table (void) { - const char *wide; - const char *narrow; -}; + xtensa_isa isa = xtensa_default_isa; + xtensa_insnbuf ibuf; + xtensa_opcode opcode; + xtensa_format fmt; + int num_opcodes; + + if (op_single_fmt_table) + return; + + ibuf = xtensa_insnbuf_alloc (isa); + num_opcodes = xtensa_isa_num_opcodes (isa); + + op_single_fmt_table = (xtensa_format *) + bfd_malloc (sizeof (xtensa_format) * num_opcodes); + for (opcode = 0; opcode < num_opcodes; opcode++) + { + op_single_fmt_table[opcode] = XTENSA_UNDEFINED; + for (fmt = 0; fmt < xtensa_isa_num_formats (isa); fmt++) + { + if (xtensa_format_num_slots (isa, fmt) == 1 + && xtensa_opcode_encode (isa, fmt, 0, ibuf, opcode) == 0) + { + xtensa_opcode old_fmt = op_single_fmt_table[opcode]; + int fmt_length = xtensa_format_length (isa, fmt); + if (old_fmt == XTENSA_UNDEFINED + || fmt_length < xtensa_format_length (isa, old_fmt)) + op_single_fmt_table[opcode] = fmt; + } + } + } + xtensa_insnbuf_free (isa, ibuf); +} + + +static xtensa_format +get_single_format (xtensa_opcode opcode) +{ + init_op_single_format_table (); + return op_single_fmt_table[opcode]; +} /* For the set of narrowable instructions we do NOT include the @@ -3697,6 +3528,12 @@ struct string_pair re-expand in some conditions. Also, the narrowing "or" -> mov.n requires special case code to ensure it only works when op1 == op2. */ +struct string_pair +{ + const char *wide; + const char *narrow; +}; + struct string_pair narrowable[] = { { "add", "add.n" }, @@ -3733,11 +3570,10 @@ struct string_pair widenable[] = but require some special case operand checks in some cases. */ static bfd_boolean -narrow_instruction (contents, content_length, offset, do_it) - bfd_byte *contents; - bfd_size_type content_length; - bfd_size_type offset; - bfd_boolean do_it; +narrow_instruction (bfd_byte *contents, + bfd_size_type content_length, + bfd_size_type offset, + bfd_boolean do_it) { xtensa_opcode opcode; bfd_size_type insn_len, opi; @@ -3880,11 +3716,10 @@ narrow_instruction (contents, content_length, offset, do_it) cases. */ static bfd_boolean -widen_instruction (contents, content_length, offset, do_it) - bfd_byte *contents; - bfd_size_type content_length; - bfd_size_type offset; - bfd_boolean do_it; +widen_instruction (bfd_byte *contents, + bfd_size_type content_length, + bfd_size_type offset, + bfd_boolean do_it) { xtensa_opcode opcode; bfd_size_type insn_len, opi; @@ -4019,70 +3854,14 @@ widen_instruction (contents, content_length, offset, do_it) return FALSE; } - -/* When FLIX is available we need to access certain instructions only - when they are 16-bit or 24-bit instructions. This table caches - information about such instructions by walking through all the - opcodes and finding the smallest single-slot format into which each - can be encoded. */ - -static xtensa_format *op_single_fmt_table = NULL; - - -static xtensa_format -get_single_format (opcode) - xtensa_opcode opcode; -{ - init_op_single_format_table (); - return op_single_fmt_table[opcode]; -} - - -static void -init_op_single_format_table () -{ - xtensa_isa isa = xtensa_default_isa; - xtensa_insnbuf ibuf; - xtensa_opcode opcode; - xtensa_format fmt; - int num_opcodes; - - if (op_single_fmt_table != NULL) - return; - - ibuf = xtensa_insnbuf_alloc (isa); - num_opcodes = xtensa_isa_num_opcodes (isa); - - op_single_fmt_table = (xtensa_format *) - bfd_malloc (sizeof (xtensa_format) * num_opcodes); - for (opcode = 0; opcode < num_opcodes; opcode++) - { - op_single_fmt_table[opcode] = XTENSA_UNDEFINED; - for (fmt = 0; fmt < xtensa_isa_num_formats (isa); fmt++) - { - if (xtensa_format_num_slots (isa, fmt) == 1 - && xtensa_opcode_encode (isa, fmt, 0, ibuf, opcode) == 0) - { - xtensa_opcode old_fmt = op_single_fmt_table[opcode]; - int fmt_length = xtensa_format_length (isa, fmt); - if (old_fmt == XTENSA_UNDEFINED - || fmt_length < xtensa_format_length (isa, old_fmt)) - op_single_fmt_table[opcode] = fmt; - } - } - } - xtensa_insnbuf_free (isa, ibuf); -} - /* Code for transforming CALLs at link-time. */ static bfd_reloc_status_type -elf_xtensa_do_asm_simplify (contents, address, content_length, error_message) - bfd_byte *contents; - bfd_vma address; - bfd_vma content_length; - char **error_message; +elf_xtensa_do_asm_simplify (bfd_byte *contents, + bfd_vma address, + bfd_vma content_length, + char **error_message) { static xtensa_insnbuf insnbuf = NULL; static xtensa_insnbuf slotbuf = NULL; @@ -4142,11 +3921,10 @@ elf_xtensa_do_asm_simplify (contents, address, content_length, error_message) static bfd_reloc_status_type -contract_asm_expansion (contents, content_length, irel, error_message) - bfd_byte *contents; - bfd_vma content_length; - Elf_Internal_Rela *irel; - char **error_message; +contract_asm_expansion (bfd_byte *contents, + bfd_vma content_length, + Elf_Internal_Rela *irel, + char **error_message) { bfd_reloc_status_type retval = elf_xtensa_do_asm_simplify (contents, irel->r_offset, content_length, @@ -4164,8 +3942,7 @@ contract_asm_expansion (contents, content_length, irel, error_message) static xtensa_opcode -swap_callx_for_call_opcode (opcode) - xtensa_opcode opcode; +swap_callx_for_call_opcode (xtensa_opcode opcode) { init_call_opcodes (); @@ -4188,10 +3965,7 @@ swap_callx_for_call_opcode (opcode) #define CALLN_SOURCE_OPERAND 0 static xtensa_opcode -get_expanded_call_opcode (buf, bufsize, p_uses_l32r) - bfd_byte *buf; - int bufsize; - bfd_boolean *p_uses_l32r; +get_expanded_call_opcode (bfd_byte *buf, int bufsize, bfd_boolean *p_uses_l32r) { static xtensa_insnbuf insnbuf = NULL; static xtensa_insnbuf slotbuf = NULL; @@ -4312,23 +4086,6 @@ struct r_reloc_struct bfd_vma virtual_offset; }; -static bfd_boolean r_reloc_is_const - PARAMS ((const r_reloc *)); -static void r_reloc_init - PARAMS ((r_reloc *, bfd *, Elf_Internal_Rela *, bfd_byte *, bfd_size_type)); -static bfd_vma r_reloc_get_target_offset - PARAMS ((const r_reloc *)); -static asection *r_reloc_get_section - PARAMS ((const r_reloc *)); -static bfd_boolean r_reloc_is_defined - PARAMS ((const r_reloc *)); -static struct elf_link_hash_entry *r_reloc_get_hash_entry - PARAMS ((const r_reloc *)); -#if DEBUG -static void print_r_reloc - PARAMS ((FILE *fp, const r_reloc *r)); -#endif /* DEBUG */ - /* The r_reloc structure is included by value in literal_value, but not every literal_value has an associated relocation -- some are simple @@ -4337,49 +4094,14 @@ static void print_r_reloc detect this case. */ static bfd_boolean -r_reloc_is_const (r_rel) - const r_reloc *r_rel; +r_reloc_is_const (const r_reloc *r_rel) { return (r_rel->abfd == NULL); } -static void -r_reloc_init (r_rel, abfd, irel, contents, content_length) - r_reloc *r_rel; - bfd *abfd; - Elf_Internal_Rela *irel; - bfd_byte *contents; - bfd_size_type content_length; -{ - int r_type; - reloc_howto_type *howto; - - if (irel != NULL) - { - r_rel->rela = *irel; - r_rel->abfd = abfd; - r_rel->target_offset = r_reloc_get_target_offset (r_rel); - r_rel->virtual_offset = 0; - r_type = ELF32_R_TYPE (r_rel->rela.r_info); - howto = &elf_howto_table[r_type]; - if (howto->partial_inplace) - { - bfd_vma inplace_val; - BFD_ASSERT (r_rel->rela.r_offset < content_length); - - inplace_val = bfd_get_32 (abfd, &contents[r_rel->rela.r_offset]); - r_rel->target_offset += inplace_val; - } - } - else - memset (r_rel, 0, sizeof (r_reloc)); -} - - static bfd_vma -r_reloc_get_target_offset (r_rel) - const r_reloc *r_rel; +r_reloc_get_target_offset (const r_reloc *r_rel) { bfd_vma target_offset; unsigned long r_symndx; @@ -4392,8 +4114,7 @@ r_reloc_get_target_offset (r_rel) static struct elf_link_hash_entry * -r_reloc_get_hash_entry (r_rel) - const r_reloc *r_rel; +r_reloc_get_hash_entry (const r_reloc *r_rel) { unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info); return get_elf_r_symndx_hash_entry (r_rel->abfd, r_symndx); @@ -4401,8 +4122,7 @@ r_reloc_get_hash_entry (r_rel) static asection * -r_reloc_get_section (r_rel) - const r_reloc *r_rel; +r_reloc_get_section (const r_reloc *r_rel) { unsigned long r_symndx = ELF32_R_SYM (r_rel->rela.r_info); return get_elf_r_symndx_section (r_rel->abfd, r_symndx); @@ -4410,8 +4130,7 @@ r_reloc_get_section (r_rel) static bfd_boolean -r_reloc_is_defined (r_rel) - const r_reloc *r_rel; +r_reloc_is_defined (const r_reloc *r_rel) { asection *sec; if (r_rel == NULL) @@ -4426,12 +4145,42 @@ r_reloc_is_defined (r_rel) } +static void +r_reloc_init (r_reloc *r_rel, + bfd *abfd, + Elf_Internal_Rela *irel, + bfd_byte *contents, + bfd_size_type content_length) +{ + int r_type; + reloc_howto_type *howto; + + if (irel) + { + r_rel->rela = *irel; + r_rel->abfd = abfd; + r_rel->target_offset = r_reloc_get_target_offset (r_rel); + r_rel->virtual_offset = 0; + r_type = ELF32_R_TYPE (r_rel->rela.r_info); + howto = &elf_howto_table[r_type]; + if (howto->partial_inplace) + { + bfd_vma inplace_val; + BFD_ASSERT (r_rel->rela.r_offset < content_length); + + inplace_val = bfd_get_32 (abfd, &contents[r_rel->rela.r_offset]); + r_rel->target_offset += inplace_val; + } + } + else + memset (r_rel, 0, sizeof (r_reloc)); +} + + #if DEBUG static void -print_r_reloc (fp, r_rel) - FILE *fp; - const r_reloc *r_rel; +print_r_reloc (FILE *fp, const r_reloc *r_rel) { if (r_reloc_is_defined (r_rel)) { @@ -4486,23 +4235,13 @@ struct source_reloc_struct }; -static void init_source_reloc - PARAMS ((source_reloc *, asection *, const r_reloc *, - xtensa_opcode, int, bfd_boolean)); -static source_reloc *find_source_reloc - PARAMS ((source_reloc *, int, asection *, Elf_Internal_Rela *)); -static int source_reloc_compare - PARAMS ((const PTR, const PTR)); - - static void -init_source_reloc (reloc, source_sec, r_rel, opcode, opnd, is_abs_literal) - source_reloc *reloc; - asection *source_sec; - const r_reloc *r_rel; - xtensa_opcode opcode; - int opnd; - bfd_boolean is_abs_literal; +init_source_reloc (source_reloc *reloc, + asection *source_sec, + const r_reloc *r_rel, + xtensa_opcode opcode, + int opnd, + bfd_boolean is_abs_literal) { reloc->source_sec = source_sec; reloc->r_rel = *r_rel; @@ -4518,11 +4257,10 @@ init_source_reloc (reloc, source_sec, r_rel, opcode, opnd, is_abs_literal) just a linear search. */ static source_reloc * -find_source_reloc (src_relocs, src_count, sec, irel) - source_reloc *src_relocs; - int src_count; - asection *sec; - Elf_Internal_Rela *irel; +find_source_reloc (source_reloc *src_relocs, + int src_count, + asection *sec, + Elf_Internal_Rela *irel) { int i; @@ -4540,9 +4278,7 @@ find_source_reloc (src_relocs, src_count, sec, irel) static int -source_reloc_compare (ap, bp) - const PTR ap; - const PTR bp; +source_reloc_compare (const void *ap, const void *bp) { const source_reloc *a = (const source_reloc *) ap; const source_reloc *b = (const source_reloc *) bp; @@ -4604,31 +4340,11 @@ struct value_map_hash_table_struct }; -static void init_literal_value - PARAMS ((literal_value *, const r_reloc *, unsigned long, bfd_boolean)); -static bfd_boolean literal_value_equal - PARAMS ((const literal_value *, const literal_value *, bfd_boolean)); -static value_map_hash_table *value_map_hash_table_init - PARAMS ((void)); -static void value_map_hash_table_delete - PARAMS ((value_map_hash_table *)); -static unsigned literal_value_hash - PARAMS ((const literal_value *)); -static unsigned hash_bfd_vma - PARAMS ((bfd_vma)); -static value_map *value_map_get_cached_value - PARAMS ((value_map_hash_table *, const literal_value *, bfd_boolean)); -static value_map *add_value_map - PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *, - bfd_boolean)); - - static void -init_literal_value (lit, r_rel, value, is_abs_literal) - literal_value *lit; - const r_reloc *r_rel; - unsigned long value; - bfd_boolean is_abs_literal; +init_literal_value (literal_value *lit, + const r_reloc *r_rel, + unsigned long value, + bfd_boolean is_abs_literal) { lit->r_rel = *r_rel; lit->value = value; @@ -4637,10 +4353,9 @@ init_literal_value (lit, r_rel, value, is_abs_literal) static bfd_boolean -literal_value_equal (src1, src2, final_static_link) - const literal_value *src1; - const literal_value *src2; - bfd_boolean final_static_link; +literal_value_equal (const literal_value *src1, + const literal_value *src2, + bfd_boolean final_static_link) { struct elf_link_hash_entry *h1, *h2; @@ -4694,7 +4409,7 @@ literal_value_equal (src1, src2, final_static_link) #define INITIAL_HASH_RELOC_BUCKET_COUNT 1024 static value_map_hash_table * -value_map_hash_table_init () +value_map_hash_table_init (void) { value_map_hash_table *values; @@ -4716,8 +4431,7 @@ value_map_hash_table_init () static void -value_map_hash_table_delete (table) - value_map_hash_table *table; +value_map_hash_table_delete (value_map_hash_table *table) { free (table->buckets); free (table); @@ -4725,16 +4439,14 @@ value_map_hash_table_delete (table) static unsigned -hash_bfd_vma (val) - bfd_vma val; +hash_bfd_vma (bfd_vma val) { return (val >> 2) + (val >> 10); } static unsigned -literal_value_hash (src) - const literal_value *src; +literal_value_hash (const literal_value *src) { unsigned hash_val; @@ -4761,10 +4473,9 @@ literal_value_hash (src) /* Check if the specified literal_value has been seen before. */ static value_map * -value_map_get_cached_value (map, val, final_static_link) - value_map_hash_table *map; - const literal_value *val; - bfd_boolean final_static_link; +value_map_get_cached_value (value_map_hash_table *map, + const literal_value *val, + bfd_boolean final_static_link) { value_map *map_e; value_map *bucket; @@ -4786,11 +4497,10 @@ value_map_get_cached_value (map, val, final_static_link) already has an entry here. */ static value_map * -add_value_map (map, val, loc, final_static_link) - value_map_hash_table *map; - const literal_value *val; - const r_reloc *loc; - bfd_boolean final_static_link; +add_value_map (value_map_hash_table *map, + const literal_value *val, + const r_reloc *loc, + bfd_boolean final_static_link) { value_map **bucket_p; unsigned idx; @@ -4885,34 +4595,8 @@ struct text_action_list_struct }; -static text_action *find_fill_action - PARAMS ((text_action_list *, asection *, bfd_vma)); -static int compute_removed_action_diff - PARAMS ((const text_action *, asection *, bfd_vma, int, int)); -static void adjust_fill_action - PARAMS ((text_action *, int)); -static void text_action_add - PARAMS ((text_action_list *, text_action_t, asection *, bfd_vma, int)); -static void text_action_add_literal - PARAMS ((text_action_list *, text_action_t, const r_reloc *, - const literal_value *, int)); -static bfd_vma offset_with_removed_text - PARAMS ((text_action_list *, bfd_vma)); -static bfd_vma offset_with_removed_text_before_fill - PARAMS ((text_action_list *, bfd_vma)); -static text_action *find_insn_action - PARAMS ((text_action_list *, bfd_vma)); -#if DEBUG -static void print_action_list - PARAMS ((FILE *, text_action_list *)); -#endif - - -text_action * -find_fill_action (l, sec, offset) - text_action_list *l; - asection *sec; - bfd_vma offset; +static text_action * +find_fill_action (text_action_list *l, asection *sec, bfd_vma offset) { text_action **m_p; @@ -4920,9 +4604,7 @@ find_fill_action (l, sec, offset) if (sec->size == offset) return NULL; - for (m_p = &l->head; - *m_p != NULL && (*m_p)->offset <= offset; - m_p = &(*m_p)->next) + for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next) { text_action *t = *m_p; /* When the action is another fill at the same address, @@ -4935,17 +4617,16 @@ find_fill_action (l, sec, offset) static int -compute_removed_action_diff (ta, sec, offset, removed, removable_space) - const text_action *ta; - asection *sec; - bfd_vma offset; - int removed; - int removable_space; +compute_removed_action_diff (const text_action *ta, + asection *sec, + bfd_vma offset, + int removed, + int removable_space) { int new_removed; int current_removed = 0; - if (ta != NULL) + if (ta) current_removed = ta->removed_bytes; BFD_ASSERT (ta == NULL || ta->offset == offset); @@ -4971,10 +4652,8 @@ compute_removed_action_diff (ta, sec, offset, removed, removable_space) } -void -adjust_fill_action (ta, fill_diff) - text_action *ta; - int fill_diff; +static void +adjust_fill_action (text_action *ta, int fill_diff) { ta->removed_bytes += fill_diff; } @@ -4986,12 +4665,11 @@ adjust_fill_action (ta, fill_diff) negative removed value is a fill. */ static void -text_action_add (l, action, sec, offset, removed) - text_action_list *l; - text_action_t action; - asection *sec; - bfd_vma offset; - int removed; +text_action_add (text_action_list *l, + text_action_t action, + asection *sec, + bfd_vma offset, + int removed) { text_action **m_p; text_action *ta; @@ -5004,9 +4682,7 @@ text_action_add (l, action, sec, offset, removed) if (action == ta_fill && removed == 0) return; - for (m_p = &l->head; - *m_p != NULL && (*m_p)->offset <= offset; - m_p = &(*m_p)->next) + for (m_p = &l->head; *m_p && (*m_p)->offset <= offset; m_p = &(*m_p)->next) { text_action *t = *m_p; /* When the action is another fill at the same address, @@ -5030,12 +4706,11 @@ text_action_add (l, action, sec, offset, removed) static void -text_action_add_literal (l, action, loc, value, removed) - text_action_list *l; - text_action_t action; - const r_reloc *loc; - const literal_value *value; - int removed; +text_action_add_literal (text_action_list *l, + text_action_t action, + const r_reloc *loc, + const literal_value *value, + int removed) { text_action **m_p; text_action *ta; @@ -5066,10 +4741,8 @@ text_action_add_literal (l, action, loc, value, removed) } -bfd_vma -offset_with_removed_text (action_list, offset) - text_action_list *action_list; - bfd_vma offset; +static bfd_vma +offset_with_removed_text (text_action_list *action_list, bfd_vma offset) { text_action *r; int removed = 0; @@ -5085,10 +4758,9 @@ offset_with_removed_text (action_list, offset) } -bfd_vma -offset_with_removed_text_before_fill (action_list, offset) - text_action_list *action_list; - bfd_vma offset; +static bfd_vma +offset_with_removed_text_before_fill (text_action_list *action_list, + bfd_vma offset) { text_action *r; int removed = 0; @@ -5102,10 +4774,8 @@ offset_with_removed_text_before_fill (action_list, offset) /* The find_insn_action routine will only find non-fill actions. */ -text_action * -find_insn_action (action_list, offset) - text_action_list *action_list; - bfd_vma offset; +static text_action * +find_insn_action (text_action_list *action_list, bfd_vma offset) { text_action *t; for (t = action_list->head; t; t = t->next) @@ -5137,9 +4807,7 @@ find_insn_action (action_list, offset) #if DEBUG static void -print_action_list (fp, action_list) - FILE *fp; - text_action_list *action_list; +print_action_list (FILE *fp, text_action_list *action_list) { text_action *r; @@ -5203,24 +4871,13 @@ struct removed_literal_list_struct }; -static void add_removed_literal - PARAMS ((removed_literal_list *, const r_reloc *, const r_reloc *)); -static removed_literal *find_removed_literal - PARAMS ((removed_literal_list *, bfd_vma)); -#if DEBUG -static void print_removed_literals - PARAMS ((FILE *, removed_literal_list *)); -#endif /* DEBUG */ - - /* Record that the literal at "from" is being removed. If "to" is not NULL, the "from" literal is being coalesced with the "to" literal. */ static void -add_removed_literal (removed_list, from, to) - removed_literal_list *removed_list; - const r_reloc *from; - const r_reloc *to; +add_removed_literal (removed_literal_list *removed_list, + const r_reloc *from, + const r_reloc *to) { removed_literal *r, *new_r, *next_r; @@ -5247,8 +4904,7 @@ add_removed_literal (removed_list, from, to) } else { - while (r->from.target_offset < from->target_offset - && r->next != NULL) + while (r->from.target_offset < from->target_offset && r->next) { r = r->next; } @@ -5265,9 +4921,7 @@ add_removed_literal (removed_list, from, to) given address. Return the entry if found. */ static removed_literal * -find_removed_literal (removed_list, addr) - removed_literal_list *removed_list; - bfd_vma addr; +find_removed_literal (removed_literal_list *removed_list, bfd_vma addr) { removed_literal *r = removed_list->head; while (r && r->from.target_offset < addr) @@ -5281,9 +4935,7 @@ find_removed_literal (removed_list, addr) #if DEBUG static void -print_removed_literals (fp, removed_list) - FILE *fp; - removed_literal_list *removed_list; +print_removed_literals (FILE *fp, removed_literal_list *removed_list) { removed_literal *r; r = removed_list->head; @@ -5341,16 +4993,9 @@ struct elf_xtensa_section_data xtensa_relax_info relax_info; }; -static void init_xtensa_relax_info - PARAMS ((asection *)); -static xtensa_relax_info *get_xtensa_relax_info - PARAMS ((asection *)); - static bfd_boolean -elf_xtensa_new_section_hook (abfd, sec) - bfd *abfd; - asection *sec; +elf_xtensa_new_section_hook (bfd *abfd, asection *sec) { struct elf_xtensa_section_data *sdata; bfd_size_type amt = sizeof (*sdata); @@ -5358,15 +5003,28 @@ elf_xtensa_new_section_hook (abfd, sec) sdata = (struct elf_xtensa_section_data *) bfd_zalloc (abfd, amt); if (sdata == NULL) return FALSE; - sec->used_by_bfd = (PTR) sdata; + sec->used_by_bfd = (void *) sdata; return _bfd_elf_new_section_hook (abfd, sec); } +static xtensa_relax_info * +get_xtensa_relax_info (asection *sec) +{ + struct elf_xtensa_section_data *section_data; + + /* No info available if no section or if it is an output section. */ + if (!sec || sec == sec->output_section) + return NULL; + + section_data = (struct elf_xtensa_section_data *) elf_section_data (sec); + return §ion_data->relax_info; +} + + static void -init_xtensa_relax_info (sec) - asection *sec; +init_xtensa_relax_info (asection *sec) { xtensa_relax_info *relax_info = get_xtensa_relax_info (sec); @@ -5392,21 +5050,6 @@ init_xtensa_relax_info (sec) relax_info->allocated_relocs_count = 0; } - -static xtensa_relax_info * -get_xtensa_relax_info (sec) - asection *sec; -{ - struct elf_xtensa_section_data *section_data; - - /* No info available if no section or if it is an output section. */ - if (!sec || sec == sec->output_section) - return NULL; - - section_data = (struct elf_xtensa_section_data *) elf_section_data (sec); - return §ion_data->relax_info; -} - /* Coalescing literals may require a relocation to refer to a section in a different input file, but the standard relocation information @@ -5432,29 +5075,14 @@ struct reloc_bfd_fix_struct }; -static reloc_bfd_fix *reloc_bfd_fix_init - PARAMS ((asection *, bfd_vma, unsigned, bfd *, asection *, bfd_vma, - bfd_boolean)); -static void add_fix - PARAMS ((asection *, reloc_bfd_fix *)); -static int fix_compare - PARAMS ((const PTR, const PTR)); -static void cache_fix_array - PARAMS ((asection *)); -static reloc_bfd_fix *get_bfd_fix - PARAMS ((asection *, bfd_vma, unsigned)); - - static reloc_bfd_fix * -reloc_bfd_fix_init (src_sec, src_offset, src_type, - target_abfd, target_sec, target_offset, translated) - asection *src_sec; - bfd_vma src_offset; - unsigned src_type; - bfd *target_abfd; - asection *target_sec; - bfd_vma target_offset; - bfd_boolean translated; +reloc_bfd_fix_init (asection *src_sec, + bfd_vma src_offset, + unsigned src_type, + bfd *target_abfd, + asection *target_sec, + bfd_vma target_offset, + bfd_boolean translated) { reloc_bfd_fix *fix; @@ -5472,9 +5100,7 @@ reloc_bfd_fix_init (src_sec, src_offset, src_type, static void -add_fix (src_sec, fix) - asection *src_sec; - reloc_bfd_fix *fix; +add_fix (asection *src_sec, reloc_bfd_fix *fix) { xtensa_relax_info *relax_info; @@ -5485,9 +5111,7 @@ add_fix (src_sec, fix) static int -fix_compare (ap, bp) - const PTR ap; - const PTR bp; +fix_compare (const void *ap, const void *bp) { const reloc_bfd_fix *a = (const reloc_bfd_fix *) ap; const reloc_bfd_fix *b = (const reloc_bfd_fix *) bp; @@ -5499,8 +5123,7 @@ fix_compare (ap, bp) static void -cache_fix_array (sec) - asection *sec; +cache_fix_array (asection *sec) { unsigned i, count = 0; reloc_bfd_fix *r; @@ -5531,10 +5154,7 @@ cache_fix_array (sec) static reloc_bfd_fix * -get_bfd_fix (sec, offset, type) - asection *sec; - bfd_vma offset; - unsigned type; +get_bfd_fix (asection *sec, bfd_vma offset, unsigned type) { xtensa_relax_info *relax_info = get_xtensa_relax_info (sec); reloc_bfd_fix *rv; @@ -5575,27 +5195,31 @@ struct section_cache_struct }; -static void init_section_cache - PARAMS ((section_cache_t *)); -static bfd_boolean section_cache_section - PARAMS ((section_cache_t *, asection *, struct bfd_link_info *)); -static void clear_section_cache - PARAMS ((section_cache_t *)); +static void +init_section_cache (section_cache_t *sec_cache) +{ + memset (sec_cache, 0, sizeof (*sec_cache)); +} static void -init_section_cache (sec_cache) - section_cache_t *sec_cache; +clear_section_cache (section_cache_t *sec_cache) { - memset (sec_cache, 0, sizeof (*sec_cache)); + if (sec_cache->sec) + { + release_contents (sec_cache->sec, sec_cache->contents); + release_internal_relocs (sec_cache->sec, sec_cache->relocs); + if (sec_cache->ptbl) + free (sec_cache->ptbl); + memset (sec_cache, 0, sizeof (sec_cache)); + } } static bfd_boolean -section_cache_section (sec_cache, sec, link_info) - section_cache_t *sec_cache; - asection *sec; - struct bfd_link_info *link_info; +section_cache_section (section_cache_t *sec_cache, + asection *sec, + struct bfd_link_info *link_info) { bfd *abfd; property_table_entry *prop_table = NULL; @@ -5649,21 +5273,6 @@ section_cache_section (sec_cache, sec, link_info) return FALSE; } - -static void -clear_section_cache (sec_cache) - section_cache_t *sec_cache; -{ - if (sec_cache->sec) - { - release_contents (sec_cache->sec, sec_cache->contents); - release_internal_relocs (sec_cache->sec, sec_cache->relocs); - if (sec_cache->ptbl) - free (sec_cache->ptbl); - memset (sec_cache, 0, sizeof (sec_cache)); - } -} - /* Extended basic blocks. */ @@ -5769,56 +5378,30 @@ struct ebb_constraint_struct }; -static void init_ebb_constraint - PARAMS ((ebb_constraint *)); -static void free_ebb_constraint - PARAMS ((ebb_constraint *)); -static void init_ebb - PARAMS ((ebb_t *, asection *, bfd_byte *, bfd_size_type, - property_table_entry *, unsigned, Elf_Internal_Rela *, unsigned)); -static bfd_boolean extend_ebb_bounds - PARAMS ((ebb_t *)); -static bfd_boolean extend_ebb_bounds_forward - PARAMS ((ebb_t *)); -static bfd_boolean extend_ebb_bounds_backward - PARAMS ((ebb_t *)); -static bfd_size_type insn_block_decodable_len - PARAMS ((bfd_byte *, bfd_size_type, bfd_vma, bfd_size_type)); -static void ebb_propose_action - PARAMS ((ebb_constraint *, enum ebb_target_enum, bfd_vma, text_action_t, - bfd_vma, int, bfd_boolean)); -static void ebb_add_proposed_action - PARAMS ((ebb_constraint *, proposed_action *)); - - static void -init_ebb_constraint (c) - ebb_constraint *c; +init_ebb_constraint (ebb_constraint *c) { memset (c, 0, sizeof (ebb_constraint)); } static void -free_ebb_constraint (c) - ebb_constraint *c; +free_ebb_constraint (ebb_constraint *c) { - if (c->actions != NULL) + if (c->actions) free (c->actions); } static void -init_ebb (ebb, sec, contents, content_length, prop_table, ptblsize, - internal_relocs, reloc_count) - ebb_t *ebb; - asection *sec; - bfd_byte *contents; - bfd_size_type content_length; - property_table_entry *prop_table; - unsigned ptblsize; - Elf_Internal_Rela *internal_relocs; - unsigned reloc_count; +init_ebb (ebb_t *ebb, + asection *sec, + bfd_byte *contents, + bfd_size_type content_length, + property_table_entry *prop_table, + unsigned ptblsize, + Elf_Internal_Rela *internal_relocs, + unsigned reloc_count) { memset (ebb, 0, sizeof (ebb_t)); ebb->sec = sec; @@ -5843,9 +5426,13 @@ init_ebb (ebb, sec, contents, content_length, prop_table, ptblsize, a block that cannot be transformed. Then we push it backwards searching for similar conditions. */ +static bfd_boolean extend_ebb_bounds_forward (ebb_t *); +static bfd_boolean extend_ebb_bounds_backward (ebb_t *); +static bfd_size_type insn_block_decodable_len + (bfd_byte *, bfd_size_type, bfd_vma, bfd_size_type); + static bfd_boolean -extend_ebb_bounds (ebb) - ebb_t *ebb; +extend_ebb_bounds (ebb_t *ebb) { if (!extend_ebb_bounds_forward (ebb)) return FALSE; @@ -5856,8 +5443,7 @@ extend_ebb_bounds (ebb) static bfd_boolean -extend_ebb_bounds_forward (ebb) - ebb_t *ebb; +extend_ebb_bounds_forward (ebb_t *ebb) { property_table_entry *the_entry, *new_entry; @@ -5933,8 +5519,7 @@ extend_ebb_bounds_forward (ebb) static bfd_boolean -extend_ebb_bounds_backward (ebb) - ebb_t *ebb; +extend_ebb_bounds_backward (ebb_t *ebb) { property_table_entry *the_entry, *new_entry; @@ -5990,11 +5575,10 @@ extend_ebb_bounds_backward (ebb) static bfd_size_type -insn_block_decodable_len (contents, content_len, block_offset, block_len) - bfd_byte *contents; - bfd_size_type content_len; - bfd_vma block_offset; - bfd_size_type block_len; +insn_block_decodable_len (bfd_byte *contents, + bfd_size_type content_len, + bfd_vma block_offset, + bfd_size_type block_len) { bfd_vma offset = block_offset; @@ -6011,16 +5595,16 @@ insn_block_decodable_len (contents, content_len, block_offset, block_len) } +static void ebb_add_proposed_action (ebb_constraint *, proposed_action *); + static void -ebb_propose_action (c, align_type, alignment_pow, action, offset, - removed_bytes, do_action) - ebb_constraint *c; - bfd_vma alignment_pow; - enum ebb_target_enum align_type; - text_action_t action; - bfd_vma offset; - int removed_bytes; - bfd_boolean do_action; +ebb_propose_action (ebb_constraint *c, + bfd_vma alignment_pow, + enum ebb_target_enum align_type, + text_action_t action, + bfd_vma offset, + int removed_bytes, + bfd_boolean do_action) { proposed_action paction; paction.align_type = align_type; @@ -6034,9 +5618,7 @@ ebb_propose_action (c, align_type, alignment_pow, action, offset, static void -ebb_add_proposed_action (c, action) - ebb_constraint *c; - proposed_action *action; +ebb_add_proposed_action (ebb_constraint *c, proposed_action *action) { unsigned i; if (c->action_allocated <= c->action_count) @@ -6047,7 +5629,7 @@ ebb_add_proposed_action (c, action) for (i = 0; i < c->action_count; i++) new_actions[i] = c->actions[i]; - if (c->actions != NULL) + if (c->actions) free (c->actions); c->actions = new_actions; c->action_allocated = new_allocated; @@ -6067,10 +5649,7 @@ ebb_add_proposed_action (c, action) standard BFD functions to take care of this for us. */ static Elf_Internal_Rela * -retrieve_internal_relocs (abfd, sec, keep_memory) - bfd *abfd; - asection *sec; - bfd_boolean keep_memory; +retrieve_internal_relocs (bfd *abfd, asection *sec, bfd_boolean keep_memory) { Elf_Internal_Rela *internal_relocs; @@ -6080,25 +5659,20 @@ retrieve_internal_relocs (abfd, sec, keep_memory) internal_relocs = elf_section_data (sec)->relocs; if (internal_relocs == NULL) internal_relocs = (_bfd_elf_link_read_relocs - (abfd, sec, (PTR) NULL, (Elf_Internal_Rela *) NULL, - keep_memory)); + (abfd, sec, NULL, NULL, keep_memory)); return internal_relocs; } static void -pin_internal_relocs (sec, internal_relocs) - asection *sec; - Elf_Internal_Rela *internal_relocs; +pin_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs) { elf_section_data (sec)->relocs = internal_relocs; } static void -release_internal_relocs (sec, internal_relocs) - asection *sec; - Elf_Internal_Rela *internal_relocs; +release_internal_relocs (asection *sec, Elf_Internal_Rela *internal_relocs) { if (internal_relocs && elf_section_data (sec)->relocs != internal_relocs) @@ -6107,10 +5681,7 @@ release_internal_relocs (sec, internal_relocs) static bfd_byte * -retrieve_contents (abfd, sec, keep_memory) - bfd *abfd; - asection *sec; - bfd_boolean keep_memory; +retrieve_contents (bfd *abfd, asection *sec, bfd_boolean keep_memory) { bfd_byte *contents; bfd_size_type sec_size; @@ -6122,7 +5693,7 @@ retrieve_contents (abfd, sec, keep_memory) { if (!bfd_malloc_and_get_section (abfd, sec, &contents)) { - if (contents != NULL) + if (contents) free (contents); return NULL; } @@ -6134,18 +5705,14 @@ retrieve_contents (abfd, sec, keep_memory) static void -pin_contents (sec, contents) - asection *sec; - bfd_byte *contents; +pin_contents (asection *sec, bfd_byte *contents) { elf_section_data (sec)->this_hdr.contents = contents; } static void -release_contents (sec, contents) - asection *sec; - bfd_byte *contents; +release_contents (asection *sec, bfd_byte *contents) { if (contents && elf_section_data (sec)->this_hdr.contents != contents) free (contents); @@ -6153,8 +5720,7 @@ release_contents (sec, contents) static Elf_Internal_Sym * -retrieve_local_syms (input_bfd) - bfd *input_bfd; +retrieve_local_syms (bfd *input_bfd) { Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Sym *isymbuf; @@ -6179,87 +5745,71 @@ retrieve_local_syms (input_bfd) /* Code for link-time relaxation. */ /* Initialization for relaxation: */ -static bfd_boolean analyze_relocations - PARAMS ((struct bfd_link_info *)); +static bfd_boolean analyze_relocations (struct bfd_link_info *); static bfd_boolean find_relaxable_sections - PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *)); + (bfd *, asection *, struct bfd_link_info *, bfd_boolean *); static bfd_boolean collect_source_relocs - PARAMS ((bfd *, asection *, struct bfd_link_info *)); + (bfd *, asection *, struct bfd_link_info *); static bfd_boolean is_resolvable_asm_expansion - PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, - struct bfd_link_info *, bfd_boolean *)); + (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, struct bfd_link_info *, + bfd_boolean *); static Elf_Internal_Rela *find_associated_l32r_irel - PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, - Elf_Internal_Rela *)); + (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Rela *); static bfd_boolean compute_text_actions - PARAMS ((bfd *, asection *, struct bfd_link_info *)); -static bfd_boolean compute_ebb_proposed_actions - PARAMS ((ebb_constraint *)); -static bfd_boolean compute_ebb_actions - PARAMS ((ebb_constraint *)); + (bfd *, asection *, struct bfd_link_info *); +static bfd_boolean compute_ebb_proposed_actions (ebb_constraint *); +static bfd_boolean compute_ebb_actions (ebb_constraint *); static bfd_boolean check_section_ebb_pcrels_fit - PARAMS ((bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, - const ebb_constraint *)); -static bfd_boolean check_section_ebb_reduces - PARAMS ((const ebb_constraint *)); + (bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, const ebb_constraint *); +static bfd_boolean check_section_ebb_reduces (const ebb_constraint *); static void text_action_add_proposed - PARAMS ((text_action_list *, const ebb_constraint *, asection *)); -static int compute_fill_extra_space - PARAMS ((property_table_entry *)); + (text_action_list *, const ebb_constraint *, asection *); +static int compute_fill_extra_space (property_table_entry *); /* First pass: */ static bfd_boolean compute_removed_literals - PARAMS ((bfd *, asection *, struct bfd_link_info *, value_map_hash_table *)); + (bfd *, asection *, struct bfd_link_info *, value_map_hash_table *); static Elf_Internal_Rela *get_irel_at_offset - PARAMS ((asection *, Elf_Internal_Rela *, bfd_vma)); + (asection *, Elf_Internal_Rela *, bfd_vma); static bfd_boolean is_removable_literal - PARAMS ((const source_reloc *, int, const source_reloc *, int)); + (const source_reloc *, int, const source_reloc *, int); static bfd_boolean remove_dead_literal - PARAMS ((bfd *, asection *, struct bfd_link_info *, Elf_Internal_Rela *, - Elf_Internal_Rela *, source_reloc *, property_table_entry *, int)); -static bfd_boolean identify_literal_placement - PARAMS ((bfd *, asection *, bfd_byte *, struct bfd_link_info *, - value_map_hash_table *, bfd_boolean *, Elf_Internal_Rela *, int, - source_reloc *, property_table_entry *, int, section_cache_t *, - bfd_boolean)); -static bfd_boolean relocations_reach - PARAMS ((source_reloc *, int, const r_reloc *)); + (bfd *, asection *, struct bfd_link_info *, Elf_Internal_Rela *, + Elf_Internal_Rela *, source_reloc *, property_table_entry *, int); +static bfd_boolean identify_literal_placement + (bfd *, asection *, bfd_byte *, struct bfd_link_info *, + value_map_hash_table *, bfd_boolean *, Elf_Internal_Rela *, int, + source_reloc *, property_table_entry *, int, section_cache_t *, + bfd_boolean); +static bfd_boolean relocations_reach (source_reloc *, int, const r_reloc *); static bfd_boolean coalesce_shared_literal - PARAMS ((asection *, source_reloc *, property_table_entry *, int, - value_map *)); + (asection *, source_reloc *, property_table_entry *, int, value_map *); static bfd_boolean move_shared_literal - PARAMS ((asection *, struct bfd_link_info *, source_reloc *, - property_table_entry *, int, const r_reloc *, - const literal_value *, section_cache_t *)); + (asection *, struct bfd_link_info *, source_reloc *, property_table_entry *, + int, const r_reloc *, const literal_value *, section_cache_t *); /* Second pass: */ -static bfd_boolean relax_section - PARAMS ((bfd *, asection *, struct bfd_link_info *)); -static bfd_boolean translate_section_fixes - PARAMS ((asection *)); -static bfd_boolean translate_reloc_bfd_fix - PARAMS ((reloc_bfd_fix *)); -static void translate_reloc - PARAMS ((const r_reloc *, r_reloc *)); +static bfd_boolean relax_section (bfd *, asection *, struct bfd_link_info *); +static bfd_boolean translate_section_fixes (asection *); +static bfd_boolean translate_reloc_bfd_fix (reloc_bfd_fix *); +static void translate_reloc (const r_reloc *, r_reloc *); static void shrink_dynamic_reloc_sections - PARAMS ((struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *)); + (struct bfd_link_info *, bfd *, asection *, Elf_Internal_Rela *); static bfd_boolean move_literal - PARAMS ((bfd *, struct bfd_link_info *, asection *, bfd_vma, bfd_byte *, - xtensa_relax_info *, Elf_Internal_Rela **, const literal_value *)); + (bfd *, struct bfd_link_info *, asection *, bfd_vma, bfd_byte *, + xtensa_relax_info *, Elf_Internal_Rela **, const literal_value *); static bfd_boolean relax_property_section - PARAMS ((bfd *, asection *, struct bfd_link_info *)); + (bfd *, asection *, struct bfd_link_info *); /* Third pass: */ -static bfd_boolean relax_section_symbols - PARAMS ((bfd *, asection *)); +static bfd_boolean relax_section_symbols (bfd *, asection *); static bfd_boolean -elf_xtensa_relax_section (abfd, sec, link_info, again) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - bfd_boolean *again; +elf_xtensa_relax_section (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info, + bfd_boolean *again) { static value_map_hash_table *values = NULL; static bfd_boolean relocations_analyzed = FALSE; @@ -6331,8 +5881,7 @@ elf_xtensa_relax_section (abfd, sec, link_info, again) branch target alignments. */ static bfd_boolean -analyze_relocations (link_info) - struct bfd_link_info *link_info; +analyze_relocations (struct bfd_link_info *link_info) { bfd *abfd; asection *sec; @@ -6403,11 +5952,10 @@ analyze_relocations (link_info) relaxable literal section. */ static bfd_boolean -find_relaxable_sections (abfd, sec, link_info, is_relaxable_p) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - bfd_boolean *is_relaxable_p; +find_relaxable_sections (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info, + bfd_boolean *is_relaxable_p) { Elf_Internal_Rela *internal_relocs; bfd_byte *contents; @@ -6490,10 +6038,9 @@ find_relaxable_sections (abfd, sec, link_info, is_relaxable_p) ASM_SIMPLIFY or by removing them. */ static bfd_boolean -collect_source_relocs (abfd, sec, link_info) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; +collect_source_relocs (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info) { Elf_Internal_Rela *internal_relocs; bfd_byte *contents; @@ -6650,14 +6197,12 @@ collect_source_relocs (abfd, sec, link_info) for this section and the target section. */ bfd_boolean -is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info, - is_reachable_p) - bfd *abfd; - asection *sec; - bfd_byte *contents; - Elf_Internal_Rela *irel; - struct bfd_link_info *link_info; - bfd_boolean *is_reachable_p; +is_resolvable_asm_expansion (bfd *abfd, + asection *sec, + bfd_byte *contents, + Elf_Internal_Rela *irel, + struct bfd_link_info *link_info, + bfd_boolean *is_reachable_p) { asection *target_sec; bfd_vma target_offset; @@ -6727,12 +6272,11 @@ is_resolvable_asm_expansion (abfd, sec, contents, irel, link_info, static Elf_Internal_Rela * -find_associated_l32r_irel (abfd, sec, contents, other_irel, internal_relocs) - bfd *abfd; - asection *sec; - bfd_byte *contents; - Elf_Internal_Rela *other_irel; - Elf_Internal_Rela *internal_relocs; +find_associated_l32r_irel (bfd *abfd, + asection *sec, + bfd_byte *contents, + Elf_Internal_Rela *other_irel, + Elf_Internal_Rela *internal_relocs) { unsigned i; @@ -6764,10 +6308,9 @@ find_associated_l32r_irel (abfd, sec, contents, other_irel, internal_relocs) pass. */ bfd_boolean -compute_text_actions (abfd, sec, link_info) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; +compute_text_actions (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info) { xtensa_relax_info *relax_info; bfd_byte *contents; @@ -6901,7 +6444,7 @@ compute_text_actions (abfd, sec, link_info) } #if DEBUG - if (relax_info->action_list.head != NULL) + if (relax_info->action_list.head) print_action_list (stderr, &relax_info->action_list); #endif @@ -6918,8 +6461,7 @@ error_return: /* Find all of the possible actions for an extended basic block. */ bfd_boolean -compute_ebb_proposed_actions (ebb_table) - ebb_constraint *ebb_table; +compute_ebb_proposed_actions (ebb_constraint *ebb_table) { const ebb_t *ebb = &ebb_table->ebb; unsigned rel_idx = ebb->start_reloc_idx; @@ -7080,8 +6622,7 @@ compute_ebb_proposed_actions (ebb_table) of the EBB prevents it. */ bfd_boolean -compute_ebb_actions (ebb_table) - ebb_constraint *ebb_table; +compute_ebb_actions (ebb_constraint *ebb_table) { unsigned i = 0; unsigned j; @@ -7321,12 +6862,11 @@ compute_ebb_actions (ebb_table) are performed. */ static bfd_boolean -check_section_ebb_pcrels_fit (abfd, sec, contents, internal_relocs, constraint) - bfd *abfd; - asection *sec; - bfd_byte *contents; - Elf_Internal_Rela *internal_relocs; - const ebb_constraint *constraint; +check_section_ebb_pcrels_fit (bfd *abfd, + asection *sec, + bfd_byte *contents, + Elf_Internal_Rela *internal_relocs, + const ebb_constraint *constraint) { unsigned i, j; Elf_Internal_Rela *irel; @@ -7424,8 +6964,7 @@ check_section_ebb_pcrels_fit (abfd, sec, contents, internal_relocs, constraint) static bfd_boolean -check_section_ebb_reduces (constraint) - const ebb_constraint *constraint; +check_section_ebb_reduces (const ebb_constraint *constraint) { int removed = 0; unsigned i; @@ -7444,10 +6983,9 @@ check_section_ebb_reduces (constraint) void -text_action_add_proposed (l, ebb_table, sec) - text_action_list *l; - const ebb_constraint *ebb_table; - asection *sec; +text_action_add_proposed (text_action_list *l, + const ebb_constraint *ebb_table, + asection *sec) { unsigned i; @@ -7480,8 +7018,7 @@ text_action_add_proposed (l, ebb_table, sec) int -compute_fill_extra_space (entry) - property_table_entry *entry; +compute_fill_extra_space (property_table_entry *entry) { int fill_extra_space; @@ -7515,11 +7052,10 @@ compute_fill_extra_space (entry) actual changes are deferred until the next pass. */ static bfd_boolean -compute_removed_literals (abfd, sec, link_info, values) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - value_map_hash_table *values; +compute_removed_literals (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info, + value_map_hash_table *values) { xtensa_relax_info *relax_info; bfd_byte *contents; @@ -7642,10 +7178,9 @@ error_return: static Elf_Internal_Rela * -get_irel_at_offset (sec, internal_relocs, offset) - asection *sec; - Elf_Internal_Rela *internal_relocs; - bfd_vma offset; +get_irel_at_offset (asection *sec, + Elf_Internal_Rela *internal_relocs, + bfd_vma offset) { unsigned i; Elf_Internal_Rela *irel; @@ -7683,11 +7218,10 @@ get_irel_at_offset (sec, internal_relocs, offset) bfd_boolean -is_removable_literal (rel, i, src_relocs, src_count) - const source_reloc *rel; - int i; - const source_reloc *src_relocs; - int src_count; +is_removable_literal (const source_reloc *rel, + int i, + const source_reloc *src_relocs, + int src_count) { const source_reloc *curr_rel; if (!rel->is_null) @@ -7710,16 +7244,14 @@ is_removable_literal (rel, i, src_relocs, src_count) bfd_boolean -remove_dead_literal (abfd, sec, link_info, internal_relocs, - irel, rel, prop_table, ptblsize) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - Elf_Internal_Rela *internal_relocs; - Elf_Internal_Rela *irel; - source_reloc *rel; - property_table_entry *prop_table; - int ptblsize; +remove_dead_literal (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info, + Elf_Internal_Rela *internal_relocs, + Elf_Internal_Rela *irel, + source_reloc *rel, + property_table_entry *prop_table, + int ptblsize) { property_table_entry *entry; xtensa_relax_info *relax_info; @@ -7783,23 +7315,19 @@ remove_dead_literal (abfd, sec, link_info, internal_relocs, bfd_boolean -identify_literal_placement (abfd, sec, contents, link_info, values, - last_loc_is_prev_p, irel, remaining_src_rels, - rel, prop_table, ptblsize, target_sec_cache, - is_abs_literal) - bfd *abfd; - asection *sec; - bfd_byte *contents; - struct bfd_link_info *link_info; - value_map_hash_table *values; - bfd_boolean *last_loc_is_prev_p; - Elf_Internal_Rela *irel; - int remaining_src_rels; - source_reloc *rel; - property_table_entry *prop_table; - int ptblsize; - section_cache_t *target_sec_cache; - bfd_boolean is_abs_literal; +identify_literal_placement (bfd *abfd, + asection *sec, + bfd_byte *contents, + struct bfd_link_info *link_info, + value_map_hash_table *values, + bfd_boolean *last_loc_is_prev_p, + Elf_Internal_Rela *irel, + int remaining_src_rels, + source_reloc *rel, + property_table_entry *prop_table, + int ptblsize, + section_cache_t *target_sec_cache, + bfd_boolean is_abs_literal) { literal_value val; value_map *val_map; @@ -7911,10 +7439,9 @@ identify_literal_placement (abfd, sec, contents, link_info, values, literal will be contiguous. */ static bfd_boolean -relocations_reach (reloc, remaining_relocs, r_rel) - source_reloc *reloc; - int remaining_relocs; - const r_reloc *r_rel; +relocations_reach (source_reloc *reloc, + int remaining_relocs, + const r_reloc *r_rel) { bfd_vma from_offset, source_address, dest_address; asection *sec; @@ -7966,12 +7493,11 @@ relocations_reach (reloc, remaining_relocs, r_rel) the same as the other literal value. */ static bfd_boolean -coalesce_shared_literal (sec, rel, prop_table, ptblsize, val_map) - asection *sec; - source_reloc *rel; - property_table_entry *prop_table; - int ptblsize; - value_map *val_map; +coalesce_shared_literal (asection *sec, + source_reloc *rel, + property_table_entry *prop_table, + int ptblsize, + value_map *val_map) { property_table_entry *entry; text_action *fa; @@ -8032,16 +7558,14 @@ coalesce_shared_literal (sec, rel, prop_table, ptblsize, val_map) this carefully. Also, it may make a branch go out of range. */ static bfd_boolean -move_shared_literal (sec, link_info, rel, prop_table, ptblsize, - target_loc, lit_value, target_sec_cache) - asection *sec; - struct bfd_link_info *link_info; - source_reloc *rel; - property_table_entry *prop_table; - int ptblsize; - const r_reloc *target_loc; - const literal_value *lit_value; - section_cache_t *target_sec_cache; +move_shared_literal (asection *sec, + struct bfd_link_info *link_info, + source_reloc *rel, + property_table_entry *prop_table, + int ptblsize, + const r_reloc *target_loc, + const literal_value *lit_value, + section_cache_t *target_sec_cache) { property_table_entry *the_add_entry, *src_entry, *target_entry = NULL; text_action *fa, *target_fa; @@ -8188,10 +7712,7 @@ move_shared_literal (sec, link_info, rel, prop_table, ptblsize, section size. */ bfd_boolean -relax_section (abfd, sec, link_info) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; +relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) { Elf_Internal_Rela *internal_relocs; xtensa_relax_info *relax_info; @@ -8625,8 +8146,7 @@ relax_section (abfd, sec, link_info) static bfd_boolean -translate_section_fixes (sec) - asection *sec; +translate_section_fixes (asection *sec) { xtensa_relax_info *relax_info; reloc_bfd_fix *r; @@ -8647,8 +8167,7 @@ translate_section_fixes (sec) section. If it has already been translated, no work is required. */ static bfd_boolean -translate_reloc_bfd_fix (fix) - reloc_bfd_fix *fix; +translate_reloc_bfd_fix (reloc_bfd_fix *fix) { reloc_bfd_fix new_fix; asection *sec; @@ -8738,9 +8257,7 @@ translate_reloc_bfd_fix (fix) /* Fix up a relocation to take account of removed literals. */ static void -translate_reloc (orig_rel, new_rel) - const r_reloc *orig_rel; - r_reloc *new_rel; +translate_reloc (const r_reloc *orig_rel, r_reloc *new_rel) { asection *sec; xtensa_relax_info *relax_info; @@ -8815,11 +8332,10 @@ translate_reloc (orig_rel, new_rel) nothing else that needs to be done. */ static void -shrink_dynamic_reloc_sections (info, abfd, input_section, rel) - struct bfd_link_info *info; - bfd *abfd; - asection *input_section; - Elf_Internal_Rela *rel; +shrink_dynamic_reloc_sections (struct bfd_link_info *info, + bfd *abfd, + asection *input_section, + Elf_Internal_Rela *rel) { Elf_Internal_Shdr *symtab_hdr; struct elf_link_hash_entry **sym_hashes; @@ -8919,16 +8435,14 @@ shrink_dynamic_reloc_sections (info, abfd, input_section, rel) section must be pinned after calling this routine. */ static bfd_boolean -move_literal (abfd, link_info, sec, offset, contents, relax_info, - internal_relocs_p, lit) - bfd *abfd; - struct bfd_link_info *link_info; - asection *sec; - bfd_vma offset; - bfd_byte *contents; - xtensa_relax_info *relax_info; - Elf_Internal_Rela **internal_relocs_p; - const literal_value *lit; +move_literal (bfd *abfd, + struct bfd_link_info *link_info, + asection *sec, + bfd_vma offset, + bfd_byte *contents, + xtensa_relax_info *relax_info, + Elf_Internal_Rela **internal_relocs_p, + const literal_value *lit) { Elf_Internal_Rela *new_relocs = NULL; size_t new_relocs_count = 0; @@ -9054,10 +8568,9 @@ move_literal (abfd, link_info, sec, offset, contents, relax_info, property sections. */ static bfd_boolean -relax_property_section (abfd, sec, link_info) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; +relax_property_section (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info) { Elf_Internal_Rela *internal_relocs; bfd_byte *contents; @@ -9405,9 +8918,7 @@ relax_property_section (abfd, sec, link_info) /* Change symbol values to account for removed literals. */ bfd_boolean -relax_section_symbols (abfd, sec) - bfd *abfd; - asection *sec; +relax_section_symbols (bfd *abfd, asection *sec) { xtensa_relax_info *relax_info; unsigned int sec_shndx; @@ -9491,11 +9002,10 @@ relax_section_symbols (abfd, sec) /* "Fix" handling functions, called while performing relocations. */ static bfd_boolean -do_fix_for_relocatable_link (rel, input_bfd, input_section, contents) - Elf_Internal_Rela *rel; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; +do_fix_for_relocatable_link (Elf_Internal_Rela *rel, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents) { r_reloc r_rel; asection *sec, *old_sec; @@ -9538,12 +9048,11 @@ do_fix_for_relocatable_link (rel, input_bfd, input_section, contents) static void -do_fix_for_final_link (rel, input_bfd, input_section, contents, relocationp) - Elf_Internal_Rela *rel; - bfd *input_bfd; - asection *input_section; - bfd_byte *contents; - bfd_vma *relocationp; +do_fix_for_final_link (Elf_Internal_Rela *rel, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + bfd_vma *relocationp) { asection *sec; int r_type = ELF32_R_TYPE (rel->r_info); @@ -9578,9 +9087,7 @@ do_fix_for_final_link (rel, input_bfd, input_section, contents, relocationp) /* Miscellaneous utility functions.... */ static asection * -elf_xtensa_get_plt_section (dynobj, chunk) - bfd *dynobj; - int chunk; +elf_xtensa_get_plt_section (bfd *dynobj, int chunk) { char plt_name[10]; @@ -9593,9 +9100,7 @@ elf_xtensa_get_plt_section (dynobj, chunk) static asection * -elf_xtensa_get_gotplt_section (dynobj, chunk) - bfd *dynobj; - int chunk; +elf_xtensa_get_gotplt_section (bfd *dynobj, int chunk) { char got_name[14]; @@ -9616,9 +9121,7 @@ elf_xtensa_get_gotplt_section (dynobj, chunk) . an absolute value, return the absolute section. */ static asection * -get_elf_r_symndx_section (abfd, r_symndx) - bfd *abfd; - unsigned long r_symndx; +get_elf_r_symndx_section (bfd *abfd, unsigned long r_symndx) { Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr; asection *target_sec = NULL; @@ -9674,9 +9177,7 @@ get_elf_r_symndx_section (abfd, r_symndx) static struct elf_link_hash_entry * -get_elf_r_symndx_hash_entry (abfd, r_symndx) - bfd *abfd; - unsigned long r_symndx; +get_elf_r_symndx_hash_entry (bfd *abfd, unsigned long r_symndx) { unsigned long indx; struct elf_link_hash_entry *h; @@ -9697,9 +9198,7 @@ get_elf_r_symndx_hash_entry (abfd, r_symndx) /* Get the section-relative offset for a symbol number. */ static bfd_vma -get_elf_r_symndx_offset (abfd, r_symndx) - bfd *abfd; - unsigned long r_symndx; +get_elf_r_symndx_offset (bfd *abfd, unsigned long r_symndx) { Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr; bfd_vma offset = 0; @@ -9728,9 +9227,7 @@ get_elf_r_symndx_offset (abfd, r_symndx) static bfd_boolean -is_reloc_sym_weak (abfd, rel) - bfd *abfd; - Elf_Internal_Rela *rel; +is_reloc_sym_weak (bfd *abfd, Elf_Internal_Rela *rel) { unsigned long r_symndx = ELF32_R_SYM (rel->r_info); struct elf_link_hash_entry *h; @@ -9743,11 +9240,10 @@ is_reloc_sym_weak (abfd, rel) static bfd_boolean -pcrel_reloc_fits (opc, opnd, self_address, dest_address) - xtensa_opcode opc; - int opnd; - bfd_vma self_address; - bfd_vma dest_address; +pcrel_reloc_fits (xtensa_opcode opc, + int opnd, + bfd_vma self_address, + bfd_vma dest_address) { xtensa_isa isa = xtensa_default_isa; uint32 valp = dest_address; @@ -9765,8 +9261,7 @@ static int prop_sec_len = sizeof (XTENSA_PROP_SEC_NAME) - 1; static bfd_boolean -xtensa_is_property_section (sec) - asection *sec; +xtensa_is_property_section (asection *sec) { if (strncmp (XTENSA_INSN_SEC_NAME, sec->name, insn_sec_len) == 0 || strncmp (XTENSA_LIT_SEC_NAME, sec->name, lit_sec_len) == 0 @@ -9784,8 +9279,7 @@ xtensa_is_property_section (sec) static bfd_boolean -xtensa_is_littable_section (sec) - asection *sec; +xtensa_is_littable_section (asection *sec) { if (strncmp (XTENSA_LIT_SEC_NAME, sec->name, lit_sec_len) == 0) return TRUE; @@ -9800,9 +9294,7 @@ xtensa_is_littable_section (sec) static int -internal_reloc_compare (ap, bp) - const PTR ap; - const PTR bp; +internal_reloc_compare (const void *ap, const void *bp) { const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap; const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp; @@ -9825,9 +9317,7 @@ internal_reloc_compare (ap, bp) static int -internal_reloc_matches (ap, bp) - const PTR ap; - const PTR bp; +internal_reloc_matches (const void *ap, const void *bp) { const Elf_Internal_Rela *a = (const Elf_Internal_Rela *) ap; const Elf_Internal_Rela *b = (const Elf_Internal_Rela *) bp; @@ -9839,9 +9329,7 @@ internal_reloc_matches (ap, bp) char * -xtensa_get_property_section_name (sec, base_name) - asection *sec; - const char *base_name; +xtensa_get_property_section_name (asection *sec, const char *base_name) { if (strncmp (sec->name, ".gnu.linkonce.", linkonce_len) == 0) { @@ -9878,8 +9366,7 @@ xtensa_get_property_section_name (sec, base_name) flagword -xtensa_get_property_predef_flags (sec) - asection *sec; +xtensa_get_property_predef_flags (asection *sec) { if (strcmp (sec->name, XTENSA_INSN_SEC_NAME) == 0 || strncmp (sec->name, ".gnu.linkonce.x.", @@ -9900,12 +9387,11 @@ xtensa_get_property_predef_flags (sec) /* Other functions called directly by the linker. */ bfd_boolean -xtensa_callback_required_dependence (abfd, sec, link_info, callback, closure) - bfd *abfd; - asection *sec; - struct bfd_link_info *link_info; - deps_callback_t callback; - PTR closure; +xtensa_callback_required_dependence (bfd *abfd, + asection *sec, + struct bfd_link_info *link_info, + deps_callback_t callback, + void *closure) { Elf_Internal_Rela *internal_relocs; bfd_byte *contents; diff --git a/gas/ChangeLog b/gas/ChangeLog index 1c954b8..043fb05 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,11 @@ +2004-10-12 Bob Wilson <bob.wilson@acm.org> + + * config/tc-xtensa.c: Use ISO C90 formatting. + * config/tc-xtensa.h: Likewise. + * config/xtensa-istack.h: Likewise. + * config/xtensa-relax.c: Likewise. + * config/xtensa-relax.h: Likewise. + 2004-10-12 Paul Brook <paul@codesourcery.com> * config/tc-arm.c (md_begin): Change EF_ARM_EABI_VER3 to diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.c index ab626a4..faac466 100644 --- a/gas/config/tc-xtensa.c +++ b/gas/config/tc-xtensa.c @@ -74,7 +74,6 @@ bfd_boolean absolute_literals_supported = XSHAL_USE_ABSOLUTE_LITERALS; /* Maximum width we would pad an unreachable frag to get alignment. */ #define UNREACHABLE_MAX_WIDTH 8 -static void error_reset_cur_vinsn PARAMS ((void)); static vliw_insn cur_vinsn; size_t xtensa_fetch_width = XCHAL_INST_FETCH_WIDTH; @@ -441,543 +440,115 @@ bfd_boolean directive_state[] = #endif }; -typedef bfd_boolean (*frag_predicate) (const fragS *); -typedef void (*frag_flags_fn) (const fragS *, frag_flags *); - -/* Command-line option functions. */ -static void xtensa_setup_hw_workarounds PARAMS ((int, int)); /* Directive functions. */ -static bfd_boolean use_transform - PARAMS ((void)); -static bfd_boolean use_longcalls - PARAMS ((void)); -static bfd_boolean do_align_targets - PARAMS ((void)); -static void directive_push - PARAMS ((directiveE, bfd_boolean, const void *)); -static void directive_pop - PARAMS ((directiveE *, bfd_boolean *, const char **, - unsigned int *, const void **)); -static void directive_balance - PARAMS ((void)); -static bfd_boolean inside_directive - PARAMS ((directiveE)); -static void get_directive - PARAMS ((directiveE *, bfd_boolean *)); -static void xtensa_begin_directive - PARAMS ((int)); -static void xtensa_end_directive - PARAMS ((int)); -static void xtensa_dwarf2_directive_loc - PARAMS ((int)); -static void xtensa_dwarf2_emit_insn - PARAMS ((int, struct dwarf2_line_info *)); -static void xtensa_literal_prefix - PARAMS ((char const *, int)); -static void xtensa_literal_position - PARAMS ((int)); -static void xtensa_literal_pseudo - PARAMS ((int)); -static void xtensa_frequency_pseudo - PARAMS ((int)); -static void xtensa_elf_cons - PARAMS ((int)); -static bfd_reloc_code_real_type xtensa_elf_suffix - PARAMS ((char **, expressionS *)); - -/* Parsing and Idiom Translation Functions. */ - -static const char *expression_end - PARAMS ((const char *)); -static unsigned tc_get_register - PARAMS ((const char *)); -static void expression_maybe_register - PARAMS ((xtensa_opcode, int, expressionS *)); -static int tokenize_arguments - PARAMS ((char **, char *)); -static bfd_boolean parse_arguments - PARAMS ((TInsn *, int, char **)); -static int get_invisible_operands - PARAMS ((TInsn *)); -static int xg_translate_idioms - PARAMS ((char **, int *, char **)); -static int xg_translate_sysreg_op - PARAMS ((char **, int *, char **)); -static int xtensa_translate_old_userreg_ops - PARAMS ((char **)); -static int xtensa_translate_zero_immed - PARAMS ((char *, char *, char **, int *, char **)); -static void xg_reverse_shift_count - PARAMS ((char **)); -static int xg_arg_is_constant - PARAMS ((char *, offsetT *)); -static void xg_replace_opname - PARAMS ((char **, char *)); -static int xg_check_num_args - PARAMS ((int *, int, char *, char **)); +static void xtensa_begin_directive (int); +static void xtensa_end_directive (int); +static void xtensa_dwarf2_directive_loc (int); +static void xtensa_literal_prefix (char const *, int); +static void xtensa_literal_position (int); +static void xtensa_literal_pseudo (int); +static void xtensa_frequency_pseudo (int); +static void xtensa_elf_cons (int); -/* Functions for dealing with the Xtensa ISA. */ +/* Parsing and Idiom Translation. */ -static int get_relaxable_immed - PARAMS ((xtensa_opcode)); -static xtensa_opcode get_opcode_from_buf - PARAMS ((const char *, int)); -#ifdef TENSILICA_DEBUG -static void xtensa_print_insn_table - PARAMS ((void)); -static void print_vliw_insn - PARAMS ((xtensa_insnbuf)); -#endif -static bfd_boolean is_direct_call_opcode - PARAMS ((xtensa_opcode)); -static bfd_boolean is_entry_opcode - PARAMS ((xtensa_opcode)); -static bfd_boolean is_movi_opcode - PARAMS ((xtensa_opcode)); -static bfd_boolean is_the_loop_opcode - PARAMS ((xtensa_opcode)); -static bfd_boolean is_jx_opcode - PARAMS ((xtensa_opcode)); -static bfd_boolean is_windowed_return_opcode - PARAMS ((xtensa_opcode)); -static int decode_reloc - PARAMS ((bfd_reloc_code_real_type, int *, bfd_boolean *)); -static bfd_reloc_code_real_type encode_reloc - PARAMS ((int)); -static bfd_reloc_code_real_type encode_alt_reloc - PARAMS ((int)); -static void xtensa_insnbuf_set_operand - PARAMS ((xtensa_insnbuf, xtensa_format, int, xtensa_opcode, int, uint32, - const char *, unsigned int)); -static uint32 xtensa_insnbuf_get_operand - PARAMS ((xtensa_insnbuf, xtensa_format, int, xtensa_opcode, int)); +static bfd_reloc_code_real_type xtensa_elf_suffix (char **, expressionS *); /* Various Other Internal Functions. */ -static bfd_boolean is_unique_insn_expansion - PARAMS ((TransitionRule *)); -static int xg_get_build_instr_size - PARAMS ((BuildInstr *)); -static bfd_boolean xg_is_narrow_insn - PARAMS ((TInsn *)); -static bfd_boolean xg_is_single_relaxable_insn - PARAMS ((TInsn *)); -static int xg_get_max_insn_widen_size - PARAMS ((xtensa_opcode)); -static int xg_get_max_insn_widen_literal_size - PARAMS ((xtensa_opcode)); -static bfd_boolean xg_is_relaxable_insn - PARAMS ((TInsn *, int)); -static symbolS *get_special_literal_symbol - PARAMS ((void)); -static symbolS *get_special_label_symbol - PARAMS ((void)); -static bfd_boolean xg_build_to_insn - PARAMS ((TInsn *, TInsn *, BuildInstr *)); -static bfd_boolean xg_build_to_stack - PARAMS ((IStack *, TInsn *, BuildInstr *)); -static bfd_boolean xg_expand_to_stack - PARAMS ((IStack *, TInsn *, int)); -static bfd_boolean xg_expand_narrow - PARAMS ((TInsn *, TInsn *)); -static bfd_boolean xg_immeds_fit - PARAMS ((const TInsn *)); -static bfd_boolean xg_symbolic_immeds_fit - PARAMS ((const TInsn *, segT, fragS *, offsetT, long)); -static bfd_boolean xg_check_operand - PARAMS ((int32, xtensa_opcode, int)); -static int xg_assembly_relax - PARAMS ((IStack *, TInsn *, segT, fragS *, offsetT, int, long)); -static void xg_force_frag_space - PARAMS ((int)); -static void xg_finish_frag - PARAMS ((char *, enum xtensa_relax_statesE, enum xtensa_relax_statesE, - int, bfd_boolean)); -static bfd_boolean is_branch_jmp_to_next - PARAMS ((TInsn *, fragS *)); -static void xg_add_branch_and_loop_targets - PARAMS ((TInsn *)); -static bfd_boolean xg_instruction_matches_options - PARAMS ((TInsn *, const ReqOption *)); -static bfd_boolean xg_instruction_matches_or_options - PARAMS ((TInsn *, const ReqOrOptionList *)); -static bfd_boolean xg_instruction_matches_option_term - PARAMS ((TInsn *, const ReqOrOption *)); -static bfd_boolean xg_instruction_matches_rule - PARAMS ((TInsn *, TransitionRule *)); -static TransitionRule *xg_instruction_match - PARAMS ((TInsn *)); -static int transition_rule_cmp - PARAMS ((const TransitionRule *, const TransitionRule *)); -static bfd_boolean xg_build_token_insn - PARAMS ((BuildInstr *, TInsn *, TInsn *)); -static bfd_boolean xg_simplify_insn - PARAMS ((TInsn *, TInsn *)); -static bfd_boolean xg_expand_assembly_insn - PARAMS ((IStack *, TInsn *)); -static symbolS *xg_assemble_literal - PARAMS ((TInsn *)); -static bfd_boolean xg_valid_literal_expression - PARAMS ((const expressionS *)); -static void xg_assemble_literal_space - PARAMS ((int, int)); -static symbolS *xtensa_create_literal_symbol - PARAMS ((segT, fragS *)); -static void xtensa_add_literal_sym - PARAMS ((symbolS *)); -static void xtensa_add_insn_label - PARAMS ((symbolS *)); -static void xtensa_clear_insn_labels - PARAMS ((void)); -static bfd_boolean get_is_linkonce_section - PARAMS ((bfd *, segT)); -static bfd_boolean xg_emit_insn_to_buf - PARAMS ((TInsn *, xtensa_format, char *, fragS *, offsetT, bfd_boolean)); -static bfd_boolean xg_add_opcode_fix - PARAMS ((TInsn *, int, xtensa_format, int, expressionS *, fragS *, offsetT)); -static void xg_resolve_literals - PARAMS ((TInsn *, symbolS *)); -static void xg_resolve_labels - PARAMS ((TInsn *, symbolS *)); -static bfd_boolean is_register_writer - PARAMS ((const TInsn *, const char *, int)); -static bfd_boolean is_bad_loopend_opcode - PARAMS ((const TInsn *)); -static bfd_boolean is_unaligned_label - PARAMS ((symbolS *)); -static fragS *next_non_empty_frag - PARAMS ((const fragS *)); -static bfd_boolean next_frag_opcode_is_loop - PARAMS ((const fragS *, xtensa_opcode *)); -static int next_frag_format_size - PARAMS ((const fragS *)); -static int frag_format_size - PARAMS ((const fragS *)); -static void update_next_frag_state - PARAMS ((fragS *, bfd_boolean)); -static bfd_boolean next_frag_is_branch_target - PARAMS ((const fragS *)); -static bfd_boolean next_frag_is_loop_target - PARAMS ((const fragS *)); -static addressT next_frag_pre_opcode_bytes - PARAMS ((const fragS *)); -static bfd_boolean is_next_frag_target - PARAMS ((const fragS *, const fragS *)); -static void xtensa_mark_literal_pool_location - PARAMS ((void)); -static void xtensa_move_labels - PARAMS ((fragS *, valueT, bfd_boolean)); -static void assemble_nop - PARAMS ((size_t, char *)); -static void build_nop - PARAMS ((TInsn *, int)); -static addressT get_expanded_loop_offset - PARAMS ((xtensa_opcode)); -static fragS *get_literal_pool_location - PARAMS ((segT)); -static void set_literal_pool_location - PARAMS ((segT, fragS *)); -static void xtensa_set_frag_assembly_state - PARAMS ((fragS *)); -static bfd_boolean relaxable_section - PARAMS ((asection *)); -static void xtensa_find_unmarked_state_frags - PARAMS ((void)); -static void xtensa_find_unaligned_branch_targets - PARAMS ((bfd *, asection *, PTR)); -static void xtensa_find_unaligned_loops - PARAMS ((bfd *, asection *, PTR)); -static void xg_apply_tentative_value - PARAMS ((fixS *, valueT)); -static void finish_vinsn - PARAMS ((vliw_insn *)); -static bfd_boolean find_vinsn_conflicts - PARAMS ((vliw_insn *)); -static char check_t1_t2_reads_and_writes - PARAMS ((TInsn *, TInsn *)); -static bfd_boolean resources_conflict - PARAMS ((vliw_insn *)); -static xtensa_format xg_find_narrowest_format - PARAMS ((vliw_insn *)); -static int relaxation_requirements - PARAMS ((vliw_insn *)); -static void bundle_single_op - PARAMS ((TInsn *)); -static bfd_boolean emit_single_op - PARAMS ((TInsn *)); -static void xg_assemble_vliw_tokens - PARAMS ((vliw_insn *)); - -/* Helpers for xtensa_end(). */ - -static void xtensa_cleanup_align_frags - PARAMS ((void)); -static void xtensa_fix_target_frags - PARAMS ((void)); -static bfd_boolean frag_can_negate_branch - PARAMS ((fragS *)); -static void xtensa_mark_narrow_branches - PARAMS ((void)); -static bfd_boolean is_narrow_branch_guaranteed_in_range - PARAMS ((fragS *, TInsn *)); -static void xtensa_mark_zcl_first_insns - PARAMS ((void)); -static void xtensa_fix_a0_b_retw_frags - PARAMS ((void)); -static bfd_boolean next_instrs_are_b_retw - PARAMS ((fragS *)); -static void xtensa_fix_b_j_loop_end_frags - PARAMS ((void)); -static bfd_boolean next_instr_is_loop_end - PARAMS ((fragS *)); -static void xtensa_fix_close_loop_end_frags - PARAMS ((void)); -static size_t min_bytes_to_other_loop_end - PARAMS ((fragS *, fragS *, offsetT, size_t)); -static size_t unrelaxed_frag_min_size - PARAMS ((fragS *)); -static size_t unrelaxed_frag_max_size - PARAMS ((fragS *)); -static void xtensa_fix_short_loop_frags - PARAMS ((void)); -static size_t count_insns_to_loop_end - PARAMS ((fragS *, bfd_boolean, size_t)); -static size_t unrelaxed_frag_min_insn_count - PARAMS ((fragS *)); -static bfd_boolean branch_before_loop_end - PARAMS ((fragS *)); -static bfd_boolean unrelaxed_frag_has_b_j - PARAMS ((fragS *)); -static void xtensa_sanity_check - PARAMS ((void)); -static bfd_boolean is_empty_loop - PARAMS ((const TInsn *, fragS *)); -static bfd_boolean is_local_forward_loop - PARAMS ((const TInsn *, fragS *)); +static void xtensa_mark_literal_pool_location (void); +static addressT get_expanded_loop_offset (xtensa_opcode); +static fragS *get_literal_pool_location (segT); +static void set_literal_pool_location (segT, fragS *); +static void xtensa_set_frag_assembly_state (fragS *); +static void finish_vinsn (vliw_insn *); +static bfd_boolean emit_single_op (TInsn *); /* Alignment Functions. */ -static size_t get_text_align_power - PARAMS ((int)); -static addressT get_text_align_max_fill_size - PARAMS ((int, bfd_boolean, bfd_boolean)); -static addressT get_text_align_fill_size - PARAMS ((addressT, int, int, bfd_boolean, bfd_boolean)); -static size_t get_text_align_nop_count - PARAMS ((size_t, bfd_boolean)); -static size_t get_text_align_nth_nop_size - PARAMS ((size_t, size_t, bfd_boolean)); -static addressT get_noop_aligned_address - PARAMS ((fragS *, addressT)); -static addressT get_aligned_diff - PARAMS ((fragS *, addressT, addressT *)); +static size_t get_text_align_power (int); +static addressT get_text_align_max_fill_size (int, bfd_boolean, bfd_boolean); /* Helpers for xtensa_relax_frag(). */ -static long relax_frag_loop_align - PARAMS ((fragS *, long)); -static long relax_frag_add_nop - PARAMS ((fragS *)); -static long relax_frag_for_align - PARAMS ((fragS *, long)); -static long future_alignment_required - PARAMS ((fragS *, long)); -static addressT find_address_of_next_align_frag - PARAMS ((fragS **, int *, int *, int *, bfd_boolean *)); -static long bytes_to_stretch - PARAMS ((fragS *, int, int, int, int)); -static long relax_frag_immed - PARAMS ((segT, fragS *, long, int, xtensa_format, int, int *, bfd_boolean)); - -/* Helpers for md_convert_frag(). */ - -static void convert_frag_align_next_opcode - PARAMS ((fragS *)); -static void convert_frag_narrow - PARAMS ((segT, fragS *, xtensa_format, int)); -static void convert_frag_fill_nop - PARAMS ((fragS *)); -static void convert_frag_immed - PARAMS ((segT, fragS *, int, xtensa_format, int)); -static fixS *fix_new_exp_in_seg - PARAMS ((segT, subsegT, fragS *, int, int, expressionS *, int, - bfd_reloc_code_real_type)); -static void convert_frag_immed_finish_loop - PARAMS ((segT, fragS *, TInsn *)); -static offsetT get_expression_value - PARAMS ((segT, expressionS *)); +static long relax_frag_add_nop (fragS *); /* Flags for the Last Instruction in Each Subsegment. */ -static unsigned get_last_insn_flags - PARAMS ((segT, subsegT)); -static void set_last_insn_flags - PARAMS ((segT, subsegT, unsigned, bfd_boolean)); +static subseg_map *get_subseg_info (segT, subsegT); +static unsigned get_last_insn_flags (segT, subsegT); +static void set_last_insn_flags (segT, subsegT, unsigned, bfd_boolean); /* Segment list functions. */ -static void xtensa_remove_section - PARAMS ((segT)); -static void xtensa_insert_section - PARAMS ((segT, segT)); -static void xtensa_move_seg_list_to_beginning - PARAMS ((seg_list *)); -static subseg_map *get_subseg_info - PARAMS ((segT, subsegT)); -static void xtensa_move_literals - PARAMS ((void)); -static void mark_literal_frags - PARAMS ((seg_list *)); -static void xtensa_reorder_seg_list - PARAMS ((seg_list *, segT)); -static void xtensa_reorder_segments - PARAMS ((void)); -static segT get_last_sec - PARAMS ((void)); -static void xtensa_switch_to_literal_fragment - PARAMS ((emit_state *)); -static void xtensa_switch_to_non_abs_literal_fragment - PARAMS ((emit_state *)); -static void xtensa_switch_section_emit_state - PARAMS ((emit_state *, segT, subsegT)); -static void xtensa_restore_emit_state - PARAMS ((emit_state *)); +static void xtensa_move_literals (void); +static void xtensa_reorder_segments (void); +static void xtensa_switch_to_literal_fragment (emit_state *); +static void xtensa_switch_to_non_abs_literal_fragment (emit_state *); +static void xtensa_switch_section_emit_state (emit_state *, segT, subsegT); +static void xtensa_restore_emit_state (emit_state *); static void cache_literal_section - PARAMS ((seg_list *, const char *, segT *, bfd_boolean)); -static segT retrieve_literal_seg - PARAMS ((seg_list *, const char *, bfd_boolean)); -static segT seg_present - PARAMS ((const char *)); -static void add_seg_list - PARAMS ((seg_list *, segT)); + (seg_list *, const char *, segT *, bfd_boolean); /* Property flags on fragments and conversion to object file flags. */ -static bfd_boolean get_frag_is_literal - PARAMS ((const fragS *)); -static bfd_boolean get_frag_is_insn - PARAMS ((const fragS *)); -static bfd_boolean get_frag_is_no_transform - PARAMS ((fragS *)); -static void set_frag_is_specific_opcode - PARAMS ((fragS *, bfd_boolean)); -static void set_frag_is_no_transform - PARAMS ((fragS *, bfd_boolean)); -static void xtensa_create_property_segments - PARAMS ((frag_predicate, frag_predicate, const char *, xt_section_type)); -static void xtensa_create_xproperty_segments - PARAMS ((frag_flags_fn, const char *, xt_section_type)); -static segment_info_type *retrieve_segment_info - PARAMS ((segT)); -static segT retrieve_xtensa_section - PARAMS ((char *)); -static bfd_boolean section_has_property - PARAMS ((segT, frag_predicate)); -static bfd_boolean section_has_xproperty - PARAMS ((segT, frag_flags_fn)); -static void add_xt_block_frags - PARAMS ((segT, segT, xtensa_block_info **, frag_predicate, frag_predicate)); -static bfd_boolean xtensa_frag_flags_is_empty - PARAMS ((const frag_flags *)); -static void xtensa_frag_flags_init - PARAMS ((frag_flags *)); -static void get_frag_property_flags - PARAMS ((const fragS *, frag_flags *)); -static bfd_vma frag_flags_to_number - PARAMS ((const frag_flags *)); -static bfd_boolean xtensa_frag_flags_combinable - PARAMS ((const frag_flags *, const frag_flags *)); -static bfd_vma xt_block_aligned_size - PARAMS ((const xtensa_block_info *)); -static bfd_boolean xtensa_xt_block_combine - PARAMS ((xtensa_block_info *, const xtensa_block_info *)); -static void add_xt_prop_frags - PARAMS ((segT, segT, xtensa_block_info **, frag_flags_fn)); +static bfd_boolean get_frag_is_literal (const fragS *); +static bfd_boolean get_frag_is_insn (const fragS *); +static bfd_boolean get_frag_is_no_transform (fragS *); +static void set_frag_is_specific_opcode (fragS *, bfd_boolean); +static void set_frag_is_no_transform (fragS *, bfd_boolean); /* Import from elf32-xtensa.c in BFD library. */ -extern char *xtensa_get_property_section_name - PARAMS ((asection *, const char *)); +extern char *xtensa_get_property_section_name (asection *, const char *); /* op_placement_info functions. */ -static void init_op_placement_info_table - PARAMS ((void)); -extern bfd_boolean opcode_fits_format_slot - PARAMS ((xtensa_opcode, xtensa_format, int)); -static int xg_get_single_size - PARAMS ((xtensa_opcode)); -static xtensa_format xg_get_single_format - PARAMS ((xtensa_opcode)); +static void init_op_placement_info_table (void); +extern bfd_boolean opcode_fits_format_slot (xtensa_opcode, xtensa_format, int); +static int xg_get_single_size (xtensa_opcode); +static xtensa_format xg_get_single_format (xtensa_opcode); /* TInsn and IStack functions. */ -static bfd_boolean tinsn_has_symbolic_operands - PARAMS ((const TInsn *)); -static bfd_boolean tinsn_has_invalid_symbolic_operands - PARAMS ((const TInsn *)); -static bfd_boolean tinsn_has_complex_operands - PARAMS ((const TInsn *)); -static bfd_boolean tinsn_to_insnbuf - PARAMS ((TInsn *, xtensa_insnbuf)); -static bfd_boolean tinsn_to_slotbuf - PARAMS ((xtensa_format, int, TInsn *, xtensa_insnbuf)); -static bfd_boolean tinsn_check_arguments - PARAMS ((const TInsn *)); -static void tinsn_from_chars - PARAMS ((TInsn *, char *, int)); -static void tinsn_from_insnbuf - PARAMS ((TInsn *, xtensa_insnbuf, xtensa_format, int)); -static void tinsn_immed_from_frag - PARAMS ((TInsn *, fragS *, int)); -static int get_num_stack_text_bytes - PARAMS ((IStack *)); -static int get_num_stack_literal_bytes - PARAMS ((IStack *)); +static bfd_boolean tinsn_has_symbolic_operands (const TInsn *); +static bfd_boolean tinsn_has_invalid_symbolic_operands (const TInsn *); +static bfd_boolean tinsn_has_complex_operands (const TInsn *); +static bfd_boolean tinsn_to_insnbuf (TInsn *, xtensa_insnbuf); +static bfd_boolean tinsn_check_arguments (const TInsn *); +static void tinsn_from_chars (TInsn *, char *, int); +static void tinsn_immed_from_frag (TInsn *, fragS *, int); +static int get_num_stack_text_bytes (IStack *); +static int get_num_stack_literal_bytes (IStack *); /* vliw_insn functions. */ -static void xg_init_vinsn - PARAMS ((vliw_insn *)); -static void xg_clear_vinsn - PARAMS ((vliw_insn *)); -static bfd_boolean vinsn_has_specific_opcodes - PARAMS ((vliw_insn *)); -static void xg_free_vinsn - PARAMS ((vliw_insn *)); +static void xg_init_vinsn (vliw_insn *); +static void xg_clear_vinsn (vliw_insn *); +static bfd_boolean vinsn_has_specific_opcodes (vliw_insn *); +static void xg_free_vinsn (vliw_insn *); static bfd_boolean vinsn_to_insnbuf - PARAMS ((vliw_insn *, char *, fragS *, bfd_boolean)); -static void vinsn_from_chars - PARAMS ((vliw_insn *, char *)); + (vliw_insn *, char *, fragS *, bfd_boolean); +static void vinsn_from_chars (vliw_insn *, char *); /* Expression Utilities. */ -bfd_boolean expr_is_const - PARAMS ((const expressionS *)); -offsetT get_expr_const - PARAMS ((const expressionS *)); -void set_expr_const - PARAMS ((expressionS *, offsetT)); -bfd_boolean expr_is_register - PARAMS ((const expressionS *)); -offsetT get_expr_register - PARAMS ((const expressionS *)); -void set_expr_symbol_offset - PARAMS ((expressionS *, symbolS *, offsetT)); +bfd_boolean expr_is_const (const expressionS *); +offsetT get_expr_const (const expressionS *); +void set_expr_const (expressionS *, offsetT); +bfd_boolean expr_is_register (const expressionS *); +offsetT get_expr_register (const expressionS *); +void set_expr_symbol_offset (expressionS *, symbolS *, offsetT); static void set_expr_symbol_offset_diff - PARAMS ((expressionS *, symbolS *, symbolS *, offsetT)); -bfd_boolean expr_is_equal - PARAMS ((expressionS *, expressionS *)); -static void copy_expr - PARAMS ((expressionS *, const expressionS *)); + (expressionS *, symbolS *, symbolS *, offsetT); +bfd_boolean expr_is_equal (expressionS *, expressionS *); +static void copy_expr (expressionS *, const expressionS *); #ifdef XTENSA_SECTION_RENAME -static void build_section_rename - PARAMS ((const char *)); -static void add_section_rename - PARAMS ((char *, char *)); +static void build_section_rename (const char *); +static void add_section_rename (char *, char *); #endif @@ -1038,6 +609,25 @@ static bfd_boolean maybe_has_close_loop_end = FALSE; static bfd_boolean workaround_all_short_loops = FALSE; + +static void +xtensa_setup_hw_workarounds (int earliest, int latest) +{ + if (earliest > latest) + as_fatal (_("illegal range of target hardware versions")); + + /* Enable all workarounds for pre-T1050.0 hardware. */ + if (earliest < 105000 || latest < 105000) + { + workaround_a0_b_retw |= TRUE; + workaround_b_j_loop_end |= TRUE; + workaround_short_loop |= TRUE; + workaround_close_loop_end |= TRUE; + workaround_all_short_loops |= TRUE; + } +} + + enum { option_density = OPTION_MD_BASE, @@ -1120,9 +710,9 @@ struct option md_longopts[] = /* This option was changed from -align-target to -target-align because it conflicted with the "-al" option. */ { "target-align", no_argument, NULL, option_align_targets }, - { "no-target-align", no_argument, NULL, - option_no_align_targets }, - { "warn-unaligned-targets", no_argument, NULL, option_warn_unaligned_targets }, + { "no-target-align", no_argument, NULL, option_no_align_targets }, + { "warn-unaligned-targets", no_argument, NULL, + option_warn_unaligned_targets }, { "longcalls", no_argument, NULL, option_longcalls }, { "no-longcalls", no_argument, NULL, option_no_longcalls }, @@ -1137,7 +727,8 @@ struct option md_longopts[] = { "no-workaround-short-loops", no_argument, NULL, option_no_workaround_short_loop }, - { "workaround-short-loops", no_argument, NULL, option_workaround_short_loop }, + { "workaround-short-loops", no_argument, NULL, + option_workaround_short_loop }, { "no-workaround-all-short-loops", no_argument, NULL, option_no_workaround_all_short_loops }, @@ -1155,8 +746,7 @@ struct option md_longopts[] = option_workaround_close_loop_end }, #ifdef XTENSA_SECTION_RENAME - { "rename-section", required_argument, NULL, - option_rename_section_name }, + { "rename-section", required_argument, NULL, option_rename_section_name }, #endif /* XTENSA_SECTION_RENAME */ { "link-relax", no_argument, NULL, option_link_relax }, @@ -1171,9 +761,7 @@ size_t md_longopts_size = sizeof md_longopts; int -md_parse_option (c, arg) - int c; - char *arg; +md_parse_option (int c, char *arg) { switch (c) { @@ -1346,8 +934,7 @@ md_parse_option (c, arg) void -md_show_usage (stream) - FILE *stream; +md_show_usage (FILE *stream) { fputs ("\n\ Xtensa options:\n\ @@ -1365,23 +952,77 @@ Xtensa options:\n\ , stream); } + +/* Functions related to the list of current label symbols. */ static void -xtensa_setup_hw_workarounds (earliest, latest) - int earliest; - int latest; +xtensa_add_insn_label (symbolS *sym) { - if (earliest > latest) - as_fatal (_("illegal range of target hardware versions")); + sym_list *l; - /* Enable all workarounds for pre-T1050.0 hardware. */ - if (earliest < 105000 || latest < 105000) + if (!free_insn_labels) + l = (sym_list *) xmalloc (sizeof (sym_list)); + else { - workaround_a0_b_retw |= TRUE; - workaround_b_j_loop_end |= TRUE; - workaround_short_loop |= TRUE; - workaround_close_loop_end |= TRUE; - workaround_all_short_loops |= TRUE; + l = free_insn_labels; + free_insn_labels = l->next; + } + + l->sym = sym; + l->next = insn_labels; + insn_labels = l; +} + + +static void +xtensa_clear_insn_labels (void) +{ + sym_list **pl; + + for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next) + ; + *pl = insn_labels; + insn_labels = NULL; +} + + +/* The "loops_ok" argument is provided to allow ignoring labels that + define loop ends. This fixes a bug where the NOPs to align a + loop opcode were included in a previous zero-cost loop: + + loop a0, loopend + <loop1 body> + loopend: + + loop a2, loopend2 + <loop2 body> + + would become: + + loop a0, loopend + <loop1 body> + nop.n <===== bad! + loopend: + + loop a2, loopend2 + <loop2 body> + + This argument is used to prevent moving the NOP to before the + loop-end label, which is what you want in this special case. */ + +static void +xtensa_move_labels (fragS *new_frag, valueT new_offset, bfd_boolean loops_ok) +{ + sym_list *lit; + + for (lit = insn_labels; lit; lit = lit->next) + { + symbolS *lit_sym = lit->sym; + if (loops_ok || ! symbol_get_tc (lit_sym)->is_loop_target) + { + S_SET_VALUE (lit_sym, new_offset); + symbol_set_frag (lit_sym, new_frag); + } } } @@ -1418,8 +1059,8 @@ const pseudo_typeS md_pseudo_table[] = }; -bfd_boolean -use_transform () +static bfd_boolean +use_transform (void) { /* After md_end, you should be checking frag by frag, rather than state directives. */ @@ -1428,8 +1069,8 @@ use_transform () } -bfd_boolean -use_longcalls () +static bfd_boolean +use_longcalls (void) { /* After md_end, you should be checking frag by frag, rather than state directives. */ @@ -1438,8 +1079,8 @@ use_longcalls () } -bfd_boolean -do_align_targets () +static bfd_boolean +do_align_targets (void) { /* After md_end, you should be checking frag by frag, rather than state directives. */ @@ -1449,10 +1090,7 @@ do_align_targets () static void -directive_push (directive, negated, datum) - directiveE directive; - bfd_boolean negated; - const void *datum; +directive_push (directiveE directive, bfd_boolean negated, const void *datum) { char *file; unsigned int line; @@ -1472,13 +1110,13 @@ directive_push (directive, negated, datum) directive_state[directive] = !negated; } + static void -directive_pop (directive, negated, file, line, datum) - directiveE *directive; - bfd_boolean *negated; - const char **file; - unsigned int *line; - const void **datum; +directive_pop (directiveE *directive, + bfd_boolean *negated, + const char **file, + unsigned int *line, + const void **datum) { state_stackS *top = directive_state_stack; @@ -1501,7 +1139,7 @@ directive_pop (directive, negated, file, line, datum) static void -directive_balance () +directive_balance (void) { while (directive_state_stack) { @@ -1519,8 +1157,7 @@ directive_balance () static bfd_boolean -inside_directive (dir) - directiveE dir; +inside_directive (directiveE dir) { state_stackS *top = directive_state_stack; @@ -1532,9 +1169,7 @@ inside_directive (dir) static void -get_directive (directive, negated) - directiveE *directive; - bfd_boolean *negated; +get_directive (directiveE *directive, bfd_boolean *negated) { int len; unsigned i; @@ -1587,8 +1222,7 @@ get_directive (directive, negated) static void -xtensa_begin_directive (ignore) - int ignore ATTRIBUTE_UNUSED; +xtensa_begin_directive (int ignore ATTRIBUTE_UNUSED) { directiveE directive; bfd_boolean negated; @@ -1699,8 +1333,7 @@ xtensa_begin_directive (ignore) static void -xtensa_end_directive (ignore) - int ignore ATTRIBUTE_UNUSED; +xtensa_end_directive (int ignore ATTRIBUTE_UNUSED) { directiveE begin_directive, end_directive; bfd_boolean begin_negated, end_negated; @@ -1802,8 +1435,7 @@ xtensa_end_directive (ignore) static bfd_boolean xtensa_loc_directive_seen = FALSE; static void -xtensa_dwarf2_directive_loc (x) - int x; +xtensa_dwarf2_directive_loc (int x) { xtensa_loc_directive_seen = TRUE; dwarf2_directive_loc (x); @@ -1811,9 +1443,7 @@ xtensa_dwarf2_directive_loc (x) static void -xtensa_dwarf2_emit_insn (size, loc) - int size; - struct dwarf2_line_info *loc; +xtensa_dwarf2_emit_insn (int size, struct dwarf2_line_info *loc) { if (debug_type != DEBUG_DWARF2 && ! xtensa_loc_directive_seen) return; @@ -1825,8 +1455,7 @@ xtensa_dwarf2_emit_insn (size, loc) /* Place an aligned literal fragment at the current location. */ static void -xtensa_literal_position (ignore) - int ignore ATTRIBUTE_UNUSED; +xtensa_literal_position (int ignore ATTRIBUTE_UNUSED) { md_flush_pending_output (); @@ -1842,8 +1471,7 @@ xtensa_literal_position (ignore) /* Support .literal label, expr, ... */ static void -xtensa_literal_pseudo (ignored) - int ignored ATTRIBUTE_UNUSED; +xtensa_literal_pseudo (int ignored ATTRIBUTE_UNUSED) { emit_state state; char *p, *base_name; @@ -1912,9 +1540,7 @@ xtensa_literal_pseudo (ignored) static void -xtensa_literal_prefix (start, len) - char const *start; - int len; +xtensa_literal_prefix (char const *start, int len) { char *name, *linkonce_suffix; char *newname, *newname4; @@ -1976,8 +1602,7 @@ xtensa_literal_prefix (start, len) /* Support ".frequency branch_target_frequency fall_through_frequency". */ static void -xtensa_frequency_pseudo (ignored) - int ignored ATTRIBUTE_UNUSED; +xtensa_frequency_pseudo (int ignored ATTRIBUTE_UNUSED) { float fall_through_f, target_f; subseg_map *seginfo; @@ -2010,8 +1635,7 @@ xtensa_frequency_pseudo (ignored) Clobbers input_line_pointer, checks end-of-line. */ static void -xtensa_elf_cons (nbytes) - int nbytes; +xtensa_elf_cons (int nbytes) { expressionS exp; bfd_reloc_code_real_type reloc; @@ -2066,12 +1690,12 @@ xtensa_elf_cons (nbytes) demand_empty_rest_of_line (); } + +/* Parsing and Idiom Translation. */ /* Parse @plt, etc. and return the desired relocation. */ static bfd_reloc_code_real_type -xtensa_elf_suffix (str_p, exp_p) - char **str_p; - expressionS *exp_p; +xtensa_elf_suffix (char **str_p, expressionS *exp_p) { struct map_bfd { @@ -2142,12 +1766,9 @@ xtensa_elf_suffix (str_p, exp_p) return BFD_RELOC_UNUSED; } - -/* Parsing and Idiom Translation. */ static const char * -expression_end (name) - const char *name; +expression_end (const char *name) { while (1) { @@ -2173,8 +1794,7 @@ expression_end (name) #define ERROR_REG_NUM ((unsigned) -1) static unsigned -tc_get_register (prefix) - const char *prefix; +tc_get_register (const char *prefix) { unsigned reg; const char *next_expr; @@ -2229,10 +1849,7 @@ tc_get_register (prefix) static void -expression_maybe_register (opc, opnd, tok) - xtensa_opcode opc; - int opnd; - expressionS *tok; +expression_maybe_register (xtensa_opcode opc, int opnd, expressionS *tok) { xtensa_isa isa = xtensa_default_isa; @@ -2302,9 +1919,7 @@ expression_maybe_register (opc, opnd, tok) /* Split up the arguments for an opcode or pseudo-op. */ static int -tokenize_arguments (args, str) - char **args; - char *str; +tokenize_arguments (char **args, char *str) { char *old_input_line_pointer; bfd_boolean saw_comma = FALSE; @@ -2390,10 +2005,7 @@ err: /* Parse the arguments to an opcode. Return TRUE on error. */ static bfd_boolean -parse_arguments (insn, num_args, arg_strings) - TInsn *insn; - int num_args; - char **arg_strings; +parse_arguments (TInsn *insn, int num_args, char **arg_strings) { expressionS *tok, *last_tok; xtensa_opcode opcode = insn->opcode; @@ -2491,8 +2103,7 @@ parse_arguments (insn, num_args, arg_strings) static int -get_invisible_operands (insn) - TInsn *insn; +get_invisible_operands (TInsn *insn) { xtensa_isa isa = xtensa_default_isa; static xtensa_insnbuf slotbuf = NULL; @@ -2560,8 +2171,7 @@ get_invisible_operands (insn) static void -xg_reverse_shift_count (cnt_argp) - char **cnt_argp; +xg_reverse_shift_count (char **cnt_argp) { char *cnt_arg, *new_arg; cnt_arg = *cnt_argp; @@ -2579,9 +2189,7 @@ xg_reverse_shift_count (cnt_argp) in *valp. */ static int -xg_arg_is_constant (arg, valp) - char *arg; - offsetT *valp; +xg_arg_is_constant (char *arg, offsetT *valp) { expressionS exp; char *save_ptr = input_line_pointer; @@ -2601,9 +2209,7 @@ xg_arg_is_constant (arg, valp) static void -xg_replace_opname (popname, newop) - char **popname; - char *newop; +xg_replace_opname (char **popname, char *newop) { free (*popname); *popname = (char *) xmalloc (strlen (newop) + 1); @@ -2612,11 +2218,10 @@ xg_replace_opname (popname, newop) static int -xg_check_num_args (pnum_args, expected_num, opname, arg_strings) - int *pnum_args; - int expected_num; - char *opname; - char **arg_strings; +xg_check_num_args (int *pnum_args, + int expected_num, + char *opname, + char **arg_strings) { int num_args = *pnum_args; @@ -2648,10 +2253,7 @@ xg_check_num_args (pnum_args, expected_num, opname, arg_strings) then get it from the operand and move it to the opcode. */ static int -xg_translate_sysreg_op (popname, pnum_args, arg_strings) - char **popname; - int *pnum_args; - char **arg_strings; +xg_translate_sysreg_op (char **popname, int *pnum_args, char **arg_strings) { xtensa_isa isa = xtensa_default_isa; xtensa_sysreg sr; @@ -2721,8 +2323,7 @@ xg_translate_sysreg_op (popname, pnum_args, arg_strings) static int -xtensa_translate_old_userreg_ops (popname) - char **popname; +xtensa_translate_old_userreg_ops (char **popname) { xtensa_isa isa = xtensa_default_isa; xtensa_sysreg sr; @@ -2783,12 +2384,11 @@ xtensa_translate_old_userreg_ops (popname) static int -xtensa_translate_zero_immed (old_op, new_op, popname, pnum_args, arg_strings) - char *old_op; - char *new_op; - char **popname; - int *pnum_args; - char **arg_strings; +xtensa_translate_zero_immed (char *old_op, + char *new_op, + char **popname, + int *pnum_args, + char **arg_strings) { char *opname; offsetT val; @@ -2818,10 +2418,7 @@ xtensa_translate_zero_immed (old_op, new_op, popname, pnum_args, arg_strings) Returns non-zero if an error was found. */ static int -xg_translate_idioms (popname, pnum_args, arg_strings) - char **popname; - int *pnum_args; - char **arg_strings; +xg_translate_idioms (char **popname, int *pnum_args, char **arg_strings) { char *opname = *popname; bfd_boolean has_underbar = FALSE; @@ -2940,9 +2537,8 @@ xg_translate_idioms (popname, pnum_args, arg_strings) last immediate operand, and if there are none of those, we fail and return -1. */ -int -get_relaxable_immed (opcode) - xtensa_opcode opcode; +static int +get_relaxable_immed (xtensa_opcode opcode) { int last_immed = -1; int noperands, opi; @@ -2966,9 +2562,7 @@ get_relaxable_immed (opcode) static xtensa_opcode -get_opcode_from_buf (buf, slot) - const char *buf; - int slot; +get_opcode_from_buf (const char *buf, int slot) { static xtensa_insnbuf insnbuf = NULL; static xtensa_insnbuf slotbuf = NULL; @@ -2998,8 +2592,8 @@ get_opcode_from_buf (buf, slot) /* For debugging, print out the mapping of opcode numbers to opcodes. */ -void -xtensa_print_insn_table () +static void +xtensa_print_insn_table (void) { int num_opcodes, num_operands; xtensa_opcode opcode; @@ -3032,8 +2626,7 @@ xtensa_print_insn_table () static void -print_vliw_insn (vbuf) - xtensa_insnbuf vbuf; +print_vliw_insn (xtensa_insnbuf vbuf) { xtensa_isa isa = xtensa_default_isa; xtensa_format f = xtensa_format_decode (isa, vbuf); @@ -3074,8 +2667,7 @@ print_vliw_insn (vbuf) static bfd_boolean -is_direct_call_opcode (opcode) - xtensa_opcode opcode; +is_direct_call_opcode (xtensa_opcode opcode) { xtensa_isa isa = xtensa_default_isa; int n, num_operands; @@ -3099,8 +2691,7 @@ is_direct_call_opcode (opcode) has an extra check for an operand value. */ static bfd_boolean -is_entry_opcode (opcode) - xtensa_opcode opcode; +is_entry_opcode (xtensa_opcode opcode) { if (opcode == XTENSA_UNDEFINED) return FALSE; @@ -3113,8 +2704,7 @@ is_entry_opcode (opcode) so we can relax "movi aX, foo" in the front end. */ static bfd_boolean -is_movi_opcode (opcode) - xtensa_opcode opcode; +is_movi_opcode (xtensa_opcode opcode) { if (opcode == XTENSA_UNDEFINED) return FALSE; @@ -3125,8 +2715,7 @@ is_movi_opcode (opcode) static bfd_boolean -is_the_loop_opcode (opcode) - xtensa_opcode opcode; +is_the_loop_opcode (xtensa_opcode opcode) { if (opcode == XTENSA_UNDEFINED) return FALSE; @@ -3136,8 +2725,7 @@ is_the_loop_opcode (opcode) static bfd_boolean -is_jx_opcode (opcode) - xtensa_opcode opcode; +is_jx_opcode (xtensa_opcode opcode) { if (opcode == XTENSA_UNDEFINED) return FALSE; @@ -3150,8 +2738,7 @@ is_jx_opcode (opcode) Needed to add nops to avoid a hardware interlock issue. */ static bfd_boolean -is_windowed_return_opcode (opcode) - xtensa_opcode opcode; +is_windowed_return_opcode (xtensa_opcode opcode) { if (opcode == XTENSA_UNDEFINED) return FALSE; @@ -3164,10 +2751,7 @@ is_windowed_return_opcode (opcode) Returns non-zero on failure. */ static int -decode_reloc (reloc, slot, is_alt) - bfd_reloc_code_real_type reloc; - int *slot; - bfd_boolean *is_alt; +decode_reloc (bfd_reloc_code_real_type reloc, int *slot, bfd_boolean *is_alt) { if (reloc >= BFD_RELOC_XTENSA_SLOT0_OP && reloc <= BFD_RELOC_XTENSA_SLOT14_OP) @@ -3193,8 +2777,7 @@ decode_reloc (reloc, slot, is_alt) failure. */ static bfd_reloc_code_real_type -encode_reloc (slot) - int slot; +encode_reloc (int slot) { if (slot < 0 || slot > 14) return BFD_RELOC_NONE; @@ -3207,8 +2790,7 @@ encode_reloc (slot) "alternate" relocations. Return BFD_RELOC_NONE on failure. */ static bfd_reloc_code_real_type -encode_alt_reloc (slot) - int slot; +encode_alt_reloc (int slot) { if (slot < 0 || slot > 14) return BFD_RELOC_NONE; @@ -3218,16 +2800,14 @@ encode_alt_reloc (slot) static void -xtensa_insnbuf_set_operand (slotbuf, fmt, slot, opcode, operand, value, - file, line) - xtensa_insnbuf slotbuf; - xtensa_format fmt; - int slot; - xtensa_opcode opcode; - int operand; - uint32 value; - const char *file; - unsigned int line; +xtensa_insnbuf_set_operand (xtensa_insnbuf slotbuf, + xtensa_format fmt, + int slot, + xtensa_opcode opcode, + int operand, + uint32 value, + const char *file, + unsigned int line) { uint32 valbuf = value; @@ -3251,12 +2831,11 @@ xtensa_insnbuf_set_operand (slotbuf, fmt, slot, opcode, operand, value, static uint32 -xtensa_insnbuf_get_operand (slotbuf, fmt, slot, opcode, opnum) - xtensa_insnbuf slotbuf; - xtensa_format fmt; - int slot; - xtensa_opcode opcode; - int opnum; +xtensa_insnbuf_get_operand (xtensa_insnbuf slotbuf, + xtensa_format fmt, + int slot, + xtensa_opcode opcode, + int opnum) { uint32 val = 0; (void) xtensa_operand_get_field (xtensa_default_isa, opcode, opnum, @@ -3266,11 +2845,247 @@ xtensa_insnbuf_get_operand (slotbuf, fmt, slot, opcode, opnum) } +/* Checks for rules from xtensa-relax tables. */ + +/* The routine xg_instruction_matches_option_term must return TRUE + when a given option term is true. The meaning of all of the option + terms is given interpretation by this function. This is needed when + an option depends on the state of a directive, but there are no such + options in use right now. */ + +static bfd_boolean +xg_instruction_matches_option_term (TInsn *insn ATTRIBUTE_UNUSED, + const ReqOrOption *option) +{ + if (strcmp (option->option_name, "realnop") == 0 + || strncmp (option->option_name, "IsaUse", 6) == 0) + { + /* These conditions were evaluated statically when building the + relaxation table. There's no need to reevaluate them now. */ + return TRUE; + } + else + { + as_fatal (_("internal error: unknown option name '%s'"), + option->option_name); + } +} + + +static bfd_boolean +xg_instruction_matches_or_options (TInsn *insn, + const ReqOrOptionList *or_option) +{ + const ReqOrOption *option; + /* Must match each of the AND terms. */ + for (option = or_option; option != NULL; option = option->next) + { + if (xg_instruction_matches_option_term (insn, option)) + return TRUE; + } + return FALSE; +} + + +static bfd_boolean +xg_instruction_matches_options (TInsn *insn, const ReqOptionList *options) +{ + const ReqOption *req_options; + /* Must match each of the AND terms. */ + for (req_options = options; + req_options != NULL; + req_options = req_options->next) + { + /* Must match one of the OR clauses. */ + if (!xg_instruction_matches_or_options (insn, + req_options->or_option_terms)) + return FALSE; + } + return TRUE; +} + + +/* Return the transition rule that matches or NULL if none matches. */ + +static bfd_boolean +xg_instruction_matches_rule (TInsn *insn, TransitionRule *rule) +{ + PreconditionList *condition_l; + + if (rule->opcode != insn->opcode) + return FALSE; + + for (condition_l = rule->conditions; + condition_l != NULL; + condition_l = condition_l->next) + { + expressionS *exp1; + expressionS *exp2; + Precondition *cond = condition_l->precond; + + switch (cond->typ) + { + case OP_CONSTANT: + /* The expression must be the constant. */ + assert (cond->op_num < insn->ntok); + exp1 = &insn->tok[cond->op_num]; + if (expr_is_const (exp1)) + { + switch (cond->cmp) + { + case OP_EQUAL: + if (get_expr_const (exp1) != cond->op_data) + return FALSE; + break; + case OP_NOTEQUAL: + if (get_expr_const (exp1) == cond->op_data) + return FALSE; + break; + default: + return FALSE; + } + } + else if (expr_is_register (exp1)) + { + switch (cond->cmp) + { + case OP_EQUAL: + if (get_expr_register (exp1) != cond->op_data) + return FALSE; + break; + case OP_NOTEQUAL: + if (get_expr_register (exp1) == cond->op_data) + return FALSE; + break; + default: + return FALSE; + } + } + else + return FALSE; + break; + + case OP_OPERAND: + assert (cond->op_num < insn->ntok); + assert (cond->op_data < insn->ntok); + exp1 = &insn->tok[cond->op_num]; + exp2 = &insn->tok[cond->op_data]; + + switch (cond->cmp) + { + case OP_EQUAL: + if (!expr_is_equal (exp1, exp2)) + return FALSE; + break; + case OP_NOTEQUAL: + if (expr_is_equal (exp1, exp2)) + return FALSE; + break; + } + break; + + case OP_LITERAL: + case OP_LABEL: + default: + return FALSE; + } + } + if (!xg_instruction_matches_options (insn, rule->options)) + return FALSE; + + return TRUE; +} + + +static int +transition_rule_cmp (const TransitionRule *a, const TransitionRule *b) +{ + bfd_boolean a_greater = FALSE; + bfd_boolean b_greater = FALSE; + + ReqOptionList *l_a = a->options; + ReqOptionList *l_b = b->options; + + /* We only care if they both are the same except for + a const16 vs. an l32r. */ + + while (l_a && l_b && ((l_a->next == NULL) == (l_b->next == NULL))) + { + ReqOrOptionList *l_or_a = l_a->or_option_terms; + ReqOrOptionList *l_or_b = l_b->or_option_terms; + while (l_or_a && l_or_b && ((l_a->next == NULL) == (l_b->next == NULL))) + { + if (l_or_a->is_true != l_or_b->is_true) + return 0; + if (strcmp (l_or_a->option_name, l_or_b->option_name) != 0) + { + /* This is the case we care about. */ + if (strcmp (l_or_a->option_name, "IsaUseConst16") == 0 + && strcmp (l_or_b->option_name, "IsaUseL32R") == 0) + { + if (prefer_const16) + a_greater = TRUE; + else + b_greater = TRUE; + } + else if (strcmp (l_or_a->option_name, "IsaUseL32R") == 0 + && strcmp (l_or_b->option_name, "IsaUseConst16") == 0) + { + if (prefer_const16) + b_greater = TRUE; + else + a_greater = TRUE; + } + else + return 0; + } + l_or_a = l_or_a->next; + l_or_b = l_or_b->next; + } + if (l_or_a || l_or_b) + return 0; + + l_a = l_a->next; + l_b = l_b->next; + } + if (l_a || l_b) + return 0; + + /* Incomparable if the substitution was used differently in two cases. */ + if (a_greater && b_greater) + return 0; + + if (b_greater) + return 1; + if (a_greater) + return -1; + + return 0; +} + + +static TransitionRule * +xg_instruction_match (TInsn *insn) +{ + TransitionTable *table = xg_build_simplify_table (&transition_rule_cmp); + TransitionList *l; + assert (insn->opcode < table->num_opcodes); + + /* Walk through all of the possible transitions. */ + for (l = table->table[insn->opcode]; l != NULL; l = l->next) + { + TransitionRule *rule = l->rule; + if (xg_instruction_matches_rule (insn, rule)) + return rule; + } + return NULL; +} + + /* Various Other Internal Functions. */ static bfd_boolean -is_unique_insn_expansion (r) - TransitionRule *r; +is_unique_insn_expansion (TransitionRule *r) { if (!r->to_instr || r->to_instr->next != NULL) return FALSE; @@ -3281,17 +3096,15 @@ is_unique_insn_expansion (r) static int -xg_get_build_instr_size (insn) - BuildInstr *insn; +xg_get_build_instr_size (BuildInstr *insn) { assert (insn->typ == INSTR_INSTR); return xg_get_single_size (insn->opcode); } -bfd_boolean -xg_is_narrow_insn (insn) - TInsn *insn; +static bfd_boolean +xg_is_narrow_insn (TInsn *insn) { TransitionTable *table = xg_build_widen_table (&transition_rule_cmp); TransitionList *l; @@ -3322,9 +3135,8 @@ xg_is_narrow_insn (insn) } -bfd_boolean -xg_is_single_relaxable_insn (insn) - TInsn *insn; +static bfd_boolean +xg_is_single_relaxable_insn (TInsn *insn) { TransitionTable *table = xg_build_widen_table (&transition_rule_cmp); TransitionList *l; @@ -3357,9 +3169,8 @@ xg_is_single_relaxable_insn (insn) /* Return the maximum number of bytes this opcode can expand to. */ -int -xg_get_max_insn_widen_size (opcode) - xtensa_opcode opcode; +static int +xg_get_max_insn_widen_size (xtensa_opcode opcode) { TransitionTable *table = xg_build_widen_table (&transition_rule_cmp); TransitionList *l; @@ -3404,9 +3215,8 @@ xg_get_max_insn_widen_size (opcode) /* Return the maximum number of literal bytes this opcode can generate. */ -int -xg_get_max_insn_widen_literal_size (opcode) - xtensa_opcode opcode; +static int +xg_get_max_insn_widen_literal_size (xtensa_opcode opcode) { TransitionTable *table = xg_build_widen_table (&transition_rule_cmp); TransitionList *l; @@ -3450,10 +3260,8 @@ xg_get_max_insn_widen_literal_size (opcode) } -bfd_boolean -xg_is_relaxable_insn (insn, lateral_steps) - TInsn *insn; - int lateral_steps; +static bfd_boolean +xg_is_relaxable_insn (TInsn *insn, int lateral_steps) { int steps_taken = 0; TransitionTable *table = xg_build_widen_table (&transition_rule_cmp); @@ -3478,7 +3286,7 @@ xg_is_relaxable_insn (insn, lateral_steps) static symbolS * -get_special_literal_symbol () +get_special_literal_symbol (void) { static symbolS *sym = NULL; @@ -3489,7 +3297,7 @@ get_special_literal_symbol () static symbolS * -get_special_label_symbol () +get_special_label_symbol (void) { static symbolS *sym = NULL; @@ -3499,13 +3307,170 @@ get_special_label_symbol () } +static bfd_boolean +xg_valid_literal_expression (const expressionS *exp) +{ + switch (exp->X_op) + { + case O_constant: + case O_symbol: + case O_big: + case O_uminus: + case O_subtract: + case O_pltrel: + return TRUE; + default: + return FALSE; + } +} + + +/* This will check to see if the value can be converted into the + operand type. It will return TRUE if it does not fit. */ + +static bfd_boolean +xg_check_operand (int32 value, xtensa_opcode opcode, int operand) +{ + uint32 valbuf = value; + if (xtensa_operand_encode (xtensa_default_isa, opcode, operand, &valbuf)) + return TRUE; + return FALSE; +} + + +/* Assumes: All immeds are constants. Check that all constants fit + into their immeds; return FALSE if not. */ + +static bfd_boolean +xg_immeds_fit (const TInsn *insn) +{ + xtensa_isa isa = xtensa_default_isa; + int i; + + int n = insn->ntok; + assert (insn->insn_type == ITYPE_INSN); + for (i = 0; i < n; ++i) + { + const expressionS *expr = &insn->tok[i]; + if (xtensa_operand_is_register (isa, insn->opcode, i) == 1) + continue; + + switch (expr->X_op) + { + case O_register: + case O_constant: + if (xg_check_operand (expr->X_add_number, insn->opcode, i)) + return FALSE; + break; + + default: + /* The symbol should have a fixup associated with it. */ + assert (FALSE); + break; + } + } + return TRUE; +} + + +/* This should only be called after we have an initial + estimate of the addresses. */ + +static bfd_boolean +xg_symbolic_immeds_fit (const TInsn *insn, + segT pc_seg, + fragS *pc_frag, + offsetT pc_offset, + long stretch) +{ + xtensa_isa isa = xtensa_default_isa; + symbolS *symbolP; + fragS *sym_frag; + offsetT target, pc; + uint32 new_offset; + int i; + int n = insn->ntok; + + assert (insn->insn_type == ITYPE_INSN); + + for (i = 0; i < n; ++i) + { + const expressionS *expr = &insn->tok[i]; + if (xtensa_operand_is_register (isa, insn->opcode, i) == 1) + continue; + + switch (expr->X_op) + { + case O_register: + case O_constant: + if (xg_check_operand (expr->X_add_number, insn->opcode, i)) + return FALSE; + break; + + case O_lo16: + case O_hi16: + /* Check for the worst case. */ + if (xg_check_operand (0xffff, insn->opcode, i)) + return FALSE; + break; + + case O_symbol: + /* We only allow symbols for pc-relative stuff. + If pc_frag == 0, then we don't have frag locations yet. */ + if (pc_frag == 0) + return FALSE; + + /* If it is PC-relative and the symbol is not in the same + segment as the PC.... */ + if (xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 0 + || S_GET_SEGMENT (expr->X_add_symbol) != pc_seg) + return FALSE; + + /* If it is a weak symbol, then assume it won't reach. This will + only affect calls when longcalls are enabled, because if + longcalls are disabled, then the call is marked as a specific + opcode. */ + if (S_IS_WEAK (expr->X_add_symbol)) + return FALSE; + + symbolP = expr->X_add_symbol; + sym_frag = symbol_get_frag (symbolP); + target = S_GET_VALUE (symbolP) + expr->X_add_number; + pc = pc_frag->fr_address + pc_offset; + + /* If frag has yet to be reached on this pass, assume it + will move by STRETCH just as we did. If this is not so, + it will be because some frag between grows, and that will + force another pass. Beware zero-length frags. There + should be a faster way to do this. */ + + if (stretch != 0 + && sym_frag->relax_marker != pc_frag->relax_marker + && S_GET_SEGMENT (symbolP) == pc_seg) + { + target += stretch; + } + + new_offset = target; + xtensa_operand_do_reloc (isa, insn->opcode, i, &new_offset, pc); + if (xg_check_operand (new_offset, insn->opcode, i)) + return FALSE; + break; + + default: + /* The symbol should have a fixup associated with it. */ + return FALSE; + } + } + + return TRUE; +} + + /* Return TRUE on success. */ -bfd_boolean -xg_build_to_insn (targ, insn, bi) - TInsn *targ; - TInsn *insn; - BuildInstr *bi; +static bfd_boolean +xg_build_to_insn (TInsn *targ, TInsn *insn, BuildInstr *bi) { BuildOp *op; symbolS *sym; @@ -3658,11 +3623,8 @@ xg_build_to_insn (targ, insn, bi) /* Return TRUE on success. */ -bfd_boolean -xg_build_to_stack (istack, insn, bi) - IStack *istack; - TInsn *insn; - BuildInstr *bi; +static bfd_boolean +xg_build_to_stack (IStack *istack, TInsn *insn, BuildInstr *bi) { for (; bi != NULL; bi = bi->next) { @@ -3677,11 +3639,8 @@ xg_build_to_stack (istack, insn, bi) /* Return TRUE on valid expansion. */ -bfd_boolean -xg_expand_to_stack (istack, insn, lateral_steps) - IStack *istack; - TInsn *insn; - int lateral_steps; +static bfd_boolean +xg_expand_to_stack (IStack *istack, TInsn *insn, int lateral_steps) { int stack_size = istack->ninsn; int steps_taken = 0; @@ -3727,10 +3686,8 @@ xg_expand_to_stack (istack, insn, lateral_steps) } -bfd_boolean -xg_expand_narrow (targ, insn) - TInsn *targ; - TInsn *insn; +static bfd_boolean +xg_expand_narrow (TInsn *targ, TInsn *insn) { TransitionTable *table = xg_build_widen_table (&transition_rule_cmp); TransitionList *l; @@ -3756,168 +3713,18 @@ xg_expand_narrow (targ, insn) return TRUE; } - -/* Assumes: All immeds are constants. Check that all constants fit - into their immeds; return FALSE if not. */ - -static bfd_boolean -xg_immeds_fit (insn) - const TInsn *insn; -{ - xtensa_isa isa = xtensa_default_isa; - int i; - - int n = insn->ntok; - assert (insn->insn_type == ITYPE_INSN); - for (i = 0; i < n; ++i) - { - const expressionS *expr = &insn->tok[i]; - if (xtensa_operand_is_register (isa, insn->opcode, i) == 1) - continue; - - switch (expr->X_op) - { - case O_register: - case O_constant: - if (xg_check_operand (expr->X_add_number, insn->opcode, i)) - return FALSE; - break; - - default: - /* The symbol should have a fixup associated with it. */ - assert (FALSE); - break; - } - } - return TRUE; -} - - -/* This should only be called after we have an initial - estimate of the addresses. */ - -static bfd_boolean -xg_symbolic_immeds_fit (insn, pc_seg, pc_frag, pc_offset, stretch) - const TInsn *insn; - segT pc_seg; - fragS *pc_frag; - offsetT pc_offset; - long stretch; -{ - xtensa_isa isa = xtensa_default_isa; - symbolS *symbolP; - fragS *sym_frag; - offsetT target, pc; - uint32 new_offset; - int i; - int n = insn->ntok; - - assert (insn->insn_type == ITYPE_INSN); - - for (i = 0; i < n; ++i) - { - const expressionS *expr = &insn->tok[i]; - if (xtensa_operand_is_register (isa, insn->opcode, i) == 1) - continue; - - switch (expr->X_op) - { - case O_register: - case O_constant: - if (xg_check_operand (expr->X_add_number, insn->opcode, i)) - return FALSE; - break; - - case O_lo16: - case O_hi16: - /* Check for the worst case. */ - if (xg_check_operand (0xffff, insn->opcode, i)) - return FALSE; - break; - - case O_symbol: - /* We only allow symbols for pc-relative stuff. - If pc_frag == 0, then we don't have frag locations yet. */ - if (pc_frag == 0) - return FALSE; - - /* If it is PC-relative and the symbol is not in the same - segment as the PC.... */ - if (xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 0 - || S_GET_SEGMENT (expr->X_add_symbol) != pc_seg) - return FALSE; - - /* If it is a weak symbol, then assume it won't reach. This will - only affect calls when longcalls are enabled, because if - longcalls are disabled, then the call is marked as a specific - opcode. */ - if (S_IS_WEAK (expr->X_add_symbol)) - return FALSE; - - symbolP = expr->X_add_symbol; - sym_frag = symbol_get_frag (symbolP); - target = S_GET_VALUE (symbolP) + expr->X_add_number; - pc = pc_frag->fr_address + pc_offset; - - /* If frag has yet to be reached on this pass, assume it - will move by STRETCH just as we did. If this is not so, - it will be because some frag between grows, and that will - force another pass. Beware zero-length frags. There - should be a faster way to do this. */ - - if (stretch != 0 - && sym_frag->relax_marker != pc_frag->relax_marker - && S_GET_SEGMENT (symbolP) == pc_seg) - { - target += stretch; - } - - new_offset = target; - xtensa_operand_do_reloc (isa, insn->opcode, i, &new_offset, pc); - if (xg_check_operand (new_offset, insn->opcode, i)) - return FALSE; - break; - - default: - /* The symbol should have a fixup associated with it. */ - return FALSE; - } - } - - return TRUE; -} - - -/* This will check to see if the value can be converted into the - operand type. It will return TRUE if it does not fit. */ - -static bfd_boolean -xg_check_operand (value, opcode, operand) - int32 value; - xtensa_opcode opcode; - int operand; -{ - uint32 valbuf = value; - if (xtensa_operand_encode (xtensa_default_isa, opcode, operand, &valbuf)) - return TRUE; - return FALSE; -} - - /* Relax the assembly instruction at least "min_steps". Return the number of steps taken. */ -int -xg_assembly_relax (istack, insn, pc_seg, pc_frag, pc_offset, min_steps, - stretch) - IStack *istack; - TInsn *insn; - segT pc_seg; - fragS *pc_frag; /* if pc_frag == 0, then no pc-relative */ - offsetT pc_offset; /* offset in fragment */ - int min_steps; /* minimum number of conversion steps */ - long stretch; /* number of bytes stretched so far */ +static int +xg_assembly_relax (IStack *istack, + TInsn *insn, + segT pc_seg, + fragS *pc_frag, /* if pc_frag == 0, not pc-relative */ + offsetT pc_offset, /* offset in fragment */ + int min_steps, /* minimum conversion steps */ + long stretch) /* number of bytes stretched so far */ { int steps_taken = 0; @@ -3990,8 +3797,7 @@ xg_assembly_relax (istack, insn, pc_seg, pc_frag, pc_offset, min_steps, static void -xg_force_frag_space (size) - int size; +xg_force_frag_space (int size) { /* This may have the side effect of creating a new fragment for the space to go into. I just do not like the name of the "frag" @@ -4000,13 +3806,12 @@ xg_force_frag_space (size) } -void -xg_finish_frag (last_insn, frag_state, slot0_state, max_growth, is_insn) - char *last_insn; - enum xtensa_relax_statesE frag_state; - enum xtensa_relax_statesE slot0_state; - int max_growth; - bfd_boolean is_insn; +static void +xg_finish_frag (char *last_insn, + enum xtensa_relax_statesE frag_state, + enum xtensa_relax_statesE slot0_state, + int max_growth, + bfd_boolean is_insn) { /* Finish off this fragment so that it has at LEAST the desired max_growth. If it doesn't fit in this fragment, close this one @@ -4034,10 +3839,34 @@ xg_finish_frag (last_insn, frag_state, slot0_state, max_growth, is_insn) } +/* Return TRUE if the target frag is one of the next non-empty frags. */ + +static bfd_boolean +is_next_frag_target (const fragS *fragP, const fragS *target) +{ + if (fragP == NULL) + return FALSE; + + for (; fragP; fragP = fragP->fr_next) + { + if (fragP == target) + return TRUE; + if (fragP->fr_fix != 0) + return FALSE; + if (fragP->fr_type == rs_fill && fragP->fr_offset != 0) + return FALSE; + if ((fragP->fr_type == rs_align || fragP->fr_type == rs_align_code) + && ((fragP->fr_address % (1 << fragP->fr_offset)) != 0)) + return FALSE; + if (fragP->fr_type == rs_space) + return FALSE; + } + return FALSE; +} + + static bfd_boolean -is_branch_jmp_to_next (insn, fragP) - TInsn *insn; - fragS *fragP; +is_branch_jmp_to_next (TInsn *insn, fragS *fragP) { xtensa_isa isa = xtensa_default_isa; int i; @@ -4087,8 +3916,7 @@ is_branch_jmp_to_next (insn, fragP) static void -xg_add_branch_and_loop_targets (insn) - TInsn *insn; +xg_add_branch_and_loop_targets (TInsn *insn) { xtensa_isa isa = xtensa_default_isa; int num_ops = xtensa_opcode_num_operands (isa, insn->opcode); @@ -4122,257 +3950,10 @@ xg_add_branch_and_loop_targets (insn) } -/* The routine xg_instruction_matches_option_term must return TRUE - when a given option term is true. The meaning of all of the option - terms is given interpretation by this function. This is needed when - an option depends on the state of a directive, but there are no such - options in use right now. */ - -bfd_boolean -xg_instruction_matches_option_term (insn, option) - TInsn *insn ATTRIBUTE_UNUSED; - const ReqOrOption *option; -{ - if (strcmp (option->option_name, "realnop") == 0 - || strncmp (option->option_name, "IsaUse", 6) == 0) - { - /* These conditions were evaluated statically when building the - relaxation table. There's no need to reevaluate them now. */ - return TRUE; - } - else - { - as_fatal (_("internal error: unknown option name '%s'"), - option->option_name); - } -} - - -bfd_boolean -xg_instruction_matches_or_options (insn, or_option) - TInsn *insn; - const ReqOrOptionList *or_option; -{ - const ReqOrOption *option; - /* Must match each of the AND terms. */ - for (option = or_option; option != NULL; option = option->next) - { - if (xg_instruction_matches_option_term (insn, option)) - return TRUE; - } - return FALSE; -} - - -bfd_boolean -xg_instruction_matches_options (insn, options) - TInsn *insn; - const ReqOptionList *options; -{ - const ReqOption *req_options; - /* Must match each of the AND terms. */ - for (req_options = options; - req_options != NULL; - req_options = req_options->next) - { - /* Must match one of the OR clauses. */ - if (!xg_instruction_matches_or_options (insn, - req_options->or_option_terms)) - return FALSE; - } - return TRUE; -} - - -/* Return the transition rule that matches or NULL if none matches. */ - -bfd_boolean -xg_instruction_matches_rule (insn, rule) - TInsn *insn; - TransitionRule *rule; -{ - PreconditionList *condition_l; - - if (rule->opcode != insn->opcode) - return FALSE; - - for (condition_l = rule->conditions; - condition_l != NULL; - condition_l = condition_l->next) - { - expressionS *exp1; - expressionS *exp2; - Precondition *cond = condition_l->precond; - - switch (cond->typ) - { - case OP_CONSTANT: - /* The expression must be the constant. */ - assert (cond->op_num < insn->ntok); - exp1 = &insn->tok[cond->op_num]; - if (expr_is_const (exp1)) - { - switch (cond->cmp) - { - case OP_EQUAL: - if (get_expr_const (exp1) != cond->op_data) - return FALSE; - break; - case OP_NOTEQUAL: - if (get_expr_const (exp1) == cond->op_data) - return FALSE; - break; - default: - return FALSE; - } - } - else if (expr_is_register (exp1)) - { - switch (cond->cmp) - { - case OP_EQUAL: - if (get_expr_register (exp1) != cond->op_data) - return FALSE; - break; - case OP_NOTEQUAL: - if (get_expr_register (exp1) == cond->op_data) - return FALSE; - break; - default: - return FALSE; - } - } - else - return FALSE; - break; - - case OP_OPERAND: - assert (cond->op_num < insn->ntok); - assert (cond->op_data < insn->ntok); - exp1 = &insn->tok[cond->op_num]; - exp2 = &insn->tok[cond->op_data]; - - switch (cond->cmp) - { - case OP_EQUAL: - if (!expr_is_equal (exp1, exp2)) - return FALSE; - break; - case OP_NOTEQUAL: - if (expr_is_equal (exp1, exp2)) - return FALSE; - break; - } - break; - - case OP_LITERAL: - case OP_LABEL: - default: - return FALSE; - } - } - if (!xg_instruction_matches_options (insn, rule->options)) - return FALSE; - - return TRUE; -} - - -static int -transition_rule_cmp (a, b) - const TransitionRule *a; - const TransitionRule *b; -{ - bfd_boolean a_greater = FALSE; - bfd_boolean b_greater = FALSE; - - ReqOptionList *l_a = a->options; - ReqOptionList *l_b = b->options; - - /* We only care if they both are the same except for - a const16 vs. an l32r. */ - - while (l_a && l_b && ((l_a->next == NULL) == (l_b->next == NULL))) - { - ReqOrOptionList *l_or_a = l_a->or_option_terms; - ReqOrOptionList *l_or_b = l_b->or_option_terms; - while (l_or_a && l_or_b && ((l_a->next == NULL) == (l_b->next == NULL))) - { - if (l_or_a->is_true != l_or_b->is_true) - return 0; - if (strcmp (l_or_a->option_name, l_or_b->option_name) != 0) - { - /* This is the case we care about. */ - if (strcmp (l_or_a->option_name, "IsaUseConst16") == 0 - && strcmp (l_or_b->option_name, "IsaUseL32R") == 0) - { - if (prefer_const16) - a_greater = TRUE; - else - b_greater = TRUE; - } - else if (strcmp (l_or_a->option_name, "IsaUseL32R") == 0 - && strcmp (l_or_b->option_name, "IsaUseConst16") == 0) - { - if (prefer_const16) - b_greater = TRUE; - else - a_greater = TRUE; - } - else - return 0; - } - l_or_a = l_or_a->next; - l_or_b = l_or_b->next; - } - if (l_or_a || l_or_b) - return 0; - - l_a = l_a->next; - l_b = l_b->next; - } - if (l_a || l_b) - return 0; - - /* Incomparable if the substitution was used differently in two cases. */ - if (a_greater && b_greater) - return 0; - - if (b_greater) - return 1; - if (a_greater) - return -1; - - return 0; -} - - -TransitionRule * -xg_instruction_match (insn) - TInsn *insn; -{ - TransitionTable *table = xg_build_simplify_table (&transition_rule_cmp); - TransitionList *l; - assert (insn->opcode < table->num_opcodes); - - /* Walk through all of the possible transitions. */ - for (l = table->table[insn->opcode]; l != NULL; l = l->next) - { - TransitionRule *rule = l->rule; - if (xg_instruction_matches_rule (insn, rule)) - return rule; - } - return NULL; -} - - /* Return FALSE if no error. */ -bfd_boolean -xg_build_token_insn (instr_spec, old_insn, new_insn) - BuildInstr *instr_spec; - TInsn *old_insn; - TInsn *new_insn; +static bfd_boolean +xg_build_token_insn (BuildInstr *instr_spec, TInsn *old_insn, TInsn *new_insn) { int num_ops = 0; BuildOp *b_op; @@ -4437,10 +4018,8 @@ xg_build_token_insn (instr_spec, old_insn, new_insn) /* Return TRUE if it was simplified. */ -bfd_boolean -xg_simplify_insn (old_insn, new_insn) - TInsn *old_insn; - TInsn *new_insn; +static bfd_boolean +xg_simplify_insn (TInsn *old_insn, TInsn *new_insn) { TransitionRule *rule; BuildInstr *insn_spec; @@ -4472,9 +4051,7 @@ xg_simplify_insn (old_insn, new_insn) error. */ static bfd_boolean -xg_expand_assembly_insn (istack, orig_insn) - IStack *istack; - TInsn *orig_insn; +xg_expand_assembly_insn (IStack *istack, TInsn *orig_insn) { int noperands; TInsn new_insn; @@ -4552,11 +4129,74 @@ xg_expand_assembly_insn (istack, orig_insn) } +/* Return TRUE if the section flags are marked linkonce + or the name is .gnu.linkonce*. */ + +static bfd_boolean +get_is_linkonce_section (bfd *abfd ATTRIBUTE_UNUSED, segT sec) +{ + flagword flags, link_once_flags; + + flags = bfd_get_section_flags (abfd, sec); + link_once_flags = (flags & SEC_LINK_ONCE); + + /* Flags might not be set yet. */ + if (!link_once_flags) + { + static size_t len = sizeof ".gnu.linkonce.t."; + + if (strncmp (segment_name (sec), ".gnu.linkonce.t.", len - 1) == 0) + link_once_flags = SEC_LINK_ONCE; + } + return (link_once_flags != 0); +} + + +static void +xtensa_add_literal_sym (symbolS *sym) +{ + sym_list *l; + + l = (sym_list *) xmalloc (sizeof (sym_list)); + l->sym = sym; + l->next = literal_syms; + literal_syms = l; +} + + +static symbolS * +xtensa_create_literal_symbol (segT sec, fragS *frag) +{ + static int lit_num = 0; + static char name[256]; + symbolS *symbolP; + + sprintf (name, ".L_lit_sym%d", lit_num); + + /* Create a local symbol. If it is in a linkonce section, we have to + be careful to make sure that if it is used in a relocation that the + symbol will be in the output file. */ + if (get_is_linkonce_section (stdoutput, sec)) + { + symbolP = symbol_new (name, sec, 0, frag); + S_CLEAR_EXTERNAL (symbolP); + /* symbolP->local = 1; */ + } + else + symbolP = symbol_new (name, sec, 0, frag); + + xtensa_add_literal_sym (symbolP); + + frag->tc_frag_data.is_literal = TRUE; + lit_num++; + return symbolP; +} + + /* Currently all literals that are generated here are 32-bit L32R targets. */ -symbolS * -xg_assemble_literal (insn) - /* const */ TInsn *insn; +static symbolS * +xg_assemble_literal (/* const */ TInsn *insn) { emit_state state; symbolS *lit_sym = NULL; @@ -4621,29 +4261,8 @@ xg_assemble_literal (insn) } -bfd_boolean -xg_valid_literal_expression (exp) - const expressionS *exp; -{ - switch (exp->X_op) - { - case O_constant: - case O_symbol: - case O_big: - case O_uminus: - case O_subtract: - case O_pltrel: - return TRUE; - default: - return FALSE; - } -} - - static void -xg_assemble_literal_space (size, slot) - /* const */ int size; - int slot; +xg_assemble_literal_space (/* const */ int size, int slot) { emit_state state; /* We might have to do something about this alignment. It only @@ -4673,150 +4292,17 @@ xg_assemble_literal_space (size, slot) } -symbolS * -xtensa_create_literal_symbol (sec, frag) - segT sec; - fragS *frag; -{ - static int lit_num = 0; - static char name[256]; - symbolS *symbolP; - - sprintf (name, ".L_lit_sym%d", lit_num); - - /* Create a local symbol. If it is in a linkonce section, we have to - be careful to make sure that if it is used in a relocation that the - symbol will be in the output file. */ - if (get_is_linkonce_section (stdoutput, sec)) - { - symbolP = symbol_new (name, sec, 0, frag); - S_CLEAR_EXTERNAL (symbolP); - /* symbolP->local = 1; */ - } - else - symbolP = symbol_new (name, sec, 0, frag); - - xtensa_add_literal_sym (symbolP); - - frag->tc_frag_data.is_literal = TRUE; - lit_num++; - return symbolP; -} - - -static void -xtensa_add_literal_sym (sym) - symbolS *sym; -{ - sym_list *l; - - l = (sym_list *) xmalloc (sizeof (sym_list)); - l->sym = sym; - l->next = literal_syms; - literal_syms = l; -} - - -static void -xtensa_add_insn_label (sym) - symbolS *sym; -{ - sym_list *l; - - if (!free_insn_labels) - l = (sym_list *) xmalloc (sizeof (sym_list)); - else - { - l = free_insn_labels; - free_insn_labels = l->next; - } - - l->sym = sym; - l->next = insn_labels; - insn_labels = l; -} - - -static void -xtensa_clear_insn_labels (void) -{ - sym_list **pl; - - for (pl = &free_insn_labels; *pl != NULL; pl = &(*pl)->next) - ; - *pl = insn_labels; - insn_labels = NULL; -} - - -/* Return TRUE if the section flags are marked linkonce - or the name is .gnu.linkonce*. */ - -bfd_boolean -get_is_linkonce_section (abfd, sec) - bfd *abfd ATTRIBUTE_UNUSED; - segT sec; -{ - flagword flags, link_once_flags; - - flags = bfd_get_section_flags (abfd, sec); - link_once_flags = (flags & SEC_LINK_ONCE); - - /* Flags might not be set yet. */ - if (!link_once_flags) - { - static size_t len = sizeof ".gnu.linkonce.t."; - - if (strncmp (segment_name (sec), ".gnu.linkonce.t.", len - 1) == 0) - link_once_flags = SEC_LINK_ONCE; - } - return (link_once_flags != 0); -} - - -static bfd_boolean -xg_emit_insn_to_buf (tinsn, fmt, buf, fragP, offset, build_fix) - TInsn *tinsn; - xtensa_format fmt; - char *buf; - fragS *fragP; - offsetT offset; - bfd_boolean build_fix; -{ - static xtensa_insnbuf insnbuf = NULL; - bfd_boolean has_symbolic_immed = FALSE; - bfd_boolean ok = TRUE; - if (!insnbuf) - insnbuf = xtensa_insnbuf_alloc (xtensa_default_isa); - - has_symbolic_immed = tinsn_to_insnbuf (tinsn, insnbuf); - if (has_symbolic_immed && build_fix) - { - /* Add a fixup. */ - int opnum = get_relaxable_immed (tinsn->opcode); - expressionS *exp = &tinsn->tok[opnum]; - - if (!xg_add_opcode_fix (tinsn, opnum, fmt, 0, exp, fragP, offset)) - ok = FALSE; - } - fragP->tc_frag_data.is_insn = TRUE; - xtensa_insnbuf_to_chars (xtensa_default_isa, insnbuf, buf, 0); - return ok; -} - - /* Put in a fixup record based on the opcode. Return TRUE on success. */ -bfd_boolean -xg_add_opcode_fix (tinsn, opnum, fmt, slot, expr, fragP, offset) - TInsn *tinsn; - int opnum; - xtensa_format fmt; - int slot; - expressionS *expr; - fragS *fragP; - offsetT offset; +static bfd_boolean +xg_add_opcode_fix (TInsn *tinsn, + int opnum, + xtensa_format fmt, + int slot, + expressionS *expr, + fragS *fragP, + offsetT offset) { xtensa_opcode opcode = tinsn->opcode; bfd_reloc_code_real_type reloc; @@ -4897,10 +4383,38 @@ xg_add_opcode_fix (tinsn, opnum, fmt, slot, expr, fragP, offset) } -void -xg_resolve_literals (insn, lit_sym) - TInsn *insn; - symbolS *lit_sym; +static bfd_boolean +xg_emit_insn_to_buf (TInsn *tinsn, + xtensa_format fmt, + char *buf, + fragS *fragP, + offsetT offset, + bfd_boolean build_fix) +{ + static xtensa_insnbuf insnbuf = NULL; + bfd_boolean has_symbolic_immed = FALSE; + bfd_boolean ok = TRUE; + if (!insnbuf) + insnbuf = xtensa_insnbuf_alloc (xtensa_default_isa); + + has_symbolic_immed = tinsn_to_insnbuf (tinsn, insnbuf); + if (has_symbolic_immed && build_fix) + { + /* Add a fixup. */ + int opnum = get_relaxable_immed (tinsn->opcode); + expressionS *exp = &tinsn->tok[opnum]; + + if (!xg_add_opcode_fix (tinsn, opnum, fmt, 0, exp, fragP, offset)) + ok = FALSE; + } + fragP->tc_frag_data.is_insn = TRUE; + xtensa_insnbuf_to_chars (xtensa_default_isa, insnbuf, buf, 0); + return ok; +} + + +static void +xg_resolve_literals (TInsn *insn, symbolS *lit_sym) { symbolS *sym = get_special_literal_symbol (); int i; @@ -4914,10 +4428,8 @@ xg_resolve_literals (insn, lit_sym) } -void -xg_resolve_labels (insn, label_sym) - TInsn *insn; - symbolS *label_sym; +static void +xg_resolve_labels (TInsn *insn, symbolS *label_sym) { symbolS *sym = get_special_label_symbol (); int i; @@ -4933,10 +4445,7 @@ xg_resolve_labels (insn, label_sym) integer register. */ static bfd_boolean -is_register_writer (insn, regset, regnum) - const TInsn *insn; - const char *regset; - int regnum; +is_register_writer (const TInsn *insn, const char *regset, int regnum) { int i; int num_ops; @@ -4966,8 +4475,7 @@ is_register_writer (insn, regset, regnum) static bfd_boolean -is_bad_loopend_opcode (tinsn) - const TInsn * tinsn; +is_bad_loopend_opcode (const TInsn *tinsn) { xtensa_opcode opcode = tinsn->opcode; @@ -5000,9 +4508,8 @@ is_bad_loopend_opcode (tinsn) Also, the assembler generates stabs labels that need not be aligned: FAKE_LABEL_NAME . {"F", "L", "endfunc"}. */ -bfd_boolean -is_unaligned_label (sym) - symbolS *sym; +static bfd_boolean +is_unaligned_label (symbolS *sym) { const char *name = S_GET_NAME (sym); static size_t fake_size = 0; @@ -5028,9 +4535,8 @@ is_unaligned_label (sym) } -fragS * -next_non_empty_frag (fragP) - const fragS *fragP; +static fragS * +next_non_empty_frag (const fragS *fragP) { fragS *next_fragP = fragP->fr_next; @@ -5047,9 +4553,7 @@ next_non_empty_frag (fragP) static bfd_boolean -next_frag_opcode_is_loop (fragP, opcode) - const fragS *fragP; - xtensa_opcode *opcode; +next_frag_opcode_is_loop (const fragS *fragP, xtensa_opcode *opcode) { xtensa_opcode out_opcode; const fragS *next_fragP = next_non_empty_frag (fragP); @@ -5068,17 +4572,7 @@ next_frag_opcode_is_loop (fragP, opcode) static int -next_frag_format_size (fragP) - const fragS *fragP; -{ - const fragS *next_fragP = next_non_empty_frag (fragP); - return frag_format_size (next_fragP); -} - - -static int -frag_format_size (fragP) - const fragS * fragP; +frag_format_size (const fragS *fragP) { static xtensa_insnbuf insnbuf = NULL; xtensa_isa isa = xtensa_default_isa; @@ -5132,31 +4626,11 @@ frag_format_size (fragP) } -/* Return TRUE if the target frag is one of the next non-empty frags. */ - -bfd_boolean -is_next_frag_target (fragP, target) - const fragS *fragP; - const fragS *target; +static int +next_frag_format_size (const fragS *fragP) { - if (fragP == NULL) - return FALSE; - - for (; fragP; fragP = fragP->fr_next) - { - if (fragP == target) - return TRUE; - if (fragP->fr_fix != 0) - return FALSE; - if (fragP->fr_type == rs_fill && fragP->fr_offset != 0) - return FALSE; - if ((fragP->fr_type == rs_align || fragP->fr_type == rs_align_code) - && ((fragP->fr_address % (1 << fragP->fr_offset)) != 0)) - return FALSE; - if (fragP->fr_type == rs_space) - return FALSE; - } - return FALSE; + const fragS *next_fragP = next_non_empty_frag (fragP); + return frag_format_size (next_fragP); } @@ -5164,9 +4638,7 @@ is_next_frag_target (fragP, target) switch its state so it will instantiate a NOP. */ static void -update_next_frag_state (fragP, unreachable) - fragS *fragP; - bfd_boolean unreachable; +update_next_frag_state (fragS *fragP, bfd_boolean unreachable) { fragS *next_fragP = fragP->fr_next; fragS *new_target = NULL; @@ -5229,8 +4701,7 @@ update_next_frag_state (fragP, unreachable) static bfd_boolean -next_frag_is_branch_target (fragP) - const fragS *fragP; +next_frag_is_branch_target (const fragS *fragP) { /* Sometimes an empty will end up here due to storage allocation issues, so we have to skip until we find something legit. */ @@ -5246,8 +4717,7 @@ next_frag_is_branch_target (fragP) static bfd_boolean -next_frag_is_loop_target (fragP) - const fragS *fragP; +next_frag_is_loop_target (const fragS *fragP) { /* Sometimes an empty will end up here due storage allocation issues. So we have to skip until we find something legit. */ @@ -5263,8 +4733,7 @@ next_frag_is_loop_target (fragP) static addressT -next_frag_pre_opcode_bytes (fragp) - const fragS *fragp; +next_frag_pre_opcode_bytes (const fragS *fragp) { const fragS *next_fragp = fragp->fr_next; xtensa_opcode next_opcode; @@ -5296,7 +4765,7 @@ next_frag_pre_opcode_bytes (fragp) placed nearest to their use. */ static void -xtensa_mark_literal_pool_location () +xtensa_mark_literal_pool_location (void) { /* Any labels pointing to the current location need to be adjusted to after the literal pool. */ @@ -5337,56 +4806,10 @@ xtensa_mark_literal_pool_location () } -/* The "loops_ok" argument is provided to allow ignoring labels that - define loop ends. This fixes a bug where the NOPs to align a - loop opcode were included in a previous zero-cost loop: - - loop a0, loopend - <loop1 body> - loopend: - - loop a2, loopend2 - <loop2 body> - - would become: - - loop a0, loopend - <loop1 body> - nop.n <===== bad! - loopend: - - loop a2, loopend2 - <loop2 body> - - This argument is used to prevent moving the NOP to before the - loop-end label, which is what you want in this special case. */ - -static void -xtensa_move_labels (new_frag, new_offset, loops_ok) - fragS *new_frag; - valueT new_offset; - bfd_boolean loops_ok; -{ - sym_list *lit; - - for (lit = insn_labels; lit; lit = lit->next) - { - symbolS *lit_sym = lit->sym; - if (loops_ok || ! symbol_get_tc (lit_sym)->is_loop_target) - { - S_SET_VALUE (lit_sym, new_offset); - symbol_set_frag (lit_sym, new_frag); - } - } -} - - /* Build a nop of the correct size into tinsn. */ static void -build_nop (tinsn, size) - TInsn *tinsn; - int size; +build_nop (TInsn *tinsn, int size) { tinsn_init (tinsn); switch (size) @@ -5418,10 +4841,8 @@ build_nop (tinsn, size) /* Assemble a NOP of the requested size in the buffer. User must have allocated "buf" with at least "size" bytes. */ -void -assemble_nop (size, buf) - size_t size; - char *buf; +static void +assemble_nop (size_t size, char *buf) { static xtensa_insnbuf insnbuf = NULL; TInsn tinsn; @@ -5444,8 +4865,7 @@ assemble_nop (size, buf) opcode. */ static addressT -get_expanded_loop_offset (opcode) - xtensa_opcode opcode; +get_expanded_loop_offset (xtensa_opcode opcode) { /* This is the OFFSET of the loop instruction in the expanded loop. This MUST correspond directly to the specification of the loop @@ -5462,18 +4882,15 @@ get_expanded_loop_offset (opcode) } -fragS * -get_literal_pool_location (seg) - segT seg; +static fragS * +get_literal_pool_location (segT seg) { return seg_info (seg)->tc_segment_info_data.literal_pool_loc; } static void -set_literal_pool_location (seg, literal_pool_loc) - segT seg; - fragS *literal_pool_loc; +set_literal_pool_location (segT seg, fragS *literal_pool_loc) { seg_info (seg)->tc_segment_info_data.literal_pool_loc = literal_pool_loc; } @@ -5482,9 +4899,8 @@ set_literal_pool_location (seg, literal_pool_loc) /* Set frag assembly state should be called when a new frag is opened and after a frag has been closed. */ -void -xtensa_set_frag_assembly_state (fragP) - fragS *fragP; +static void +xtensa_set_frag_assembly_state (fragS *fragP) { if (!density_supported) fragP->tc_frag_data.is_no_density = TRUE; @@ -5500,16 +4916,15 @@ xtensa_set_frag_assembly_state (fragP) } -bfd_boolean -relaxable_section (sec) - asection *sec; +static bfd_boolean +relaxable_section (asection *sec) { return (sec->flags & SEC_DEBUGGING) == 0; } static void -xtensa_find_unmarked_state_frags () +xtensa_find_unmarked_state_frags (void) { segT *seclist; @@ -5566,10 +4981,9 @@ xtensa_find_unmarked_state_frags () static void -xtensa_find_unaligned_branch_targets (abfd, sec, unused) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - PTR unused ATTRIBUTE_UNUSED; +xtensa_find_unaligned_branch_targets (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + void *unused ATTRIBUTE_UNUSED) { flagword flags = bfd_get_section_flags (abfd, sec); segment_info_type *seginfo = seg_info (sec); @@ -5604,10 +5018,9 @@ xtensa_find_unaligned_branch_targets (abfd, sec, unused) static void -xtensa_find_unaligned_loops (abfd, sec, unused) - bfd *abfd ATTRIBUTE_UNUSED; - asection *sec; - PTR unused ATTRIBUTE_UNUSED; +xtensa_find_unaligned_loops (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + void *unused ATTRIBUTE_UNUSED) { flagword flags = bfd_get_section_flags (abfd, sec); segment_info_type *seginfo = seg_info (sec); @@ -5642,10 +5055,8 @@ xtensa_find_unaligned_loops (abfd, sec, unused) } -void -xg_apply_tentative_value (fixP, val) - fixS *fixP; - valueT val; +static void +xg_apply_tentative_value (fixS *fixP, valueT val) { xtensa_isa isa = xtensa_default_isa; static xtensa_insnbuf insnbuf = NULL; @@ -5695,25 +5106,21 @@ xg_apply_tentative_value (fixP, val) /* External Functions and Other GAS Hooks. */ const char * -xtensa_target_format () +xtensa_target_format (void) { return (target_big_endian ? "elf32-xtensa-be" : "elf32-xtensa-le"); } void -xtensa_file_arch_init (abfd) - bfd *abfd; +xtensa_file_arch_init (bfd *abfd) { bfd_set_private_flags (abfd, 0x100 | 0x200); } void -md_number_to_chars (buf, val, n) - char *buf; - valueT val; - int n; +md_number_to_chars (char *buf, valueT val, int n) { if (target_big_endian) number_to_chars_bigendian (buf, val, n); @@ -5727,7 +5134,7 @@ md_number_to_chars (buf, val, n) need. */ void -md_begin () +md_begin (void) { segT current_section = now_seg; int current_subsec = now_subseg; @@ -5790,8 +5197,7 @@ md_begin () /* TC_INIT_FIX_DATA hook */ void -xtensa_init_fix_data (x) - fixS *x; +xtensa_init_fix_data (fixS *x) { x->tc_fix_data.slot = 0; x->tc_fix_data.X_add_symbol = NULL; @@ -5802,8 +5208,7 @@ xtensa_init_fix_data (x) /* tc_frob_label hook */ void -xtensa_frob_label (sym) - symbolS *sym; +xtensa_frob_label (symbolS *sym) { /* Since the label was already attached to a frag associated with the previous basic block, it now needs to be reset to the current frag. */ @@ -5869,8 +5274,7 @@ xtensa_frob_label (sym) /* tc_unrecognized_line hook */ int -xtensa_unrecognized_line (ch) - int ch; +xtensa_unrecognized_line (int ch) { switch (ch) { @@ -5915,7 +5319,7 @@ xtensa_unrecognized_line (ch) /* md_flush_pending_output hook */ void -xtensa_flush_pending_output () +xtensa_flush_pending_output (void) { if (cur_vinsn.inside_bundle) as_bad (_("missing closing brace")); @@ -5940,7 +5344,7 @@ xtensa_flush_pending_output () and bad things happen. */ static void -error_reset_cur_vinsn () +error_reset_cur_vinsn (void) { if (cur_vinsn.inside_bundle) { @@ -5953,8 +5357,7 @@ error_reset_cur_vinsn () void -md_assemble (str) - char *str; +md_assemble (char *str) { xtensa_isa isa = xtensa_default_isa; char *opname; @@ -6105,8 +5508,7 @@ md_assemble (str) property section corresponding to this section. */ void -xtensa_handle_align (fragP) - fragS *fragP; +xtensa_handle_align (fragS *fragP) { if (linkrelax && !get_frag_is_literal (fragP) @@ -6134,16 +5536,14 @@ xtensa_handle_align (fragP) /* TC_FRAG_INIT hook */ void -xtensa_frag_init (frag) - fragS *frag; +xtensa_frag_init (fragS *frag) { xtensa_set_frag_assembly_state (frag); } symbolS * -md_undefined_symbol (name) - char *name ATTRIBUTE_UNUSED; +md_undefined_symbol (char *name ATTRIBUTE_UNUSED) { return NULL; } @@ -6152,17 +5552,14 @@ md_undefined_symbol (name) /* Round up a section size to the appropriate boundary. */ valueT -md_section_align (segment, size) - segT segment ATTRIBUTE_UNUSED; - valueT size; +md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size) { return size; /* Byte alignment is fine. */ } long -md_pcrel_from (fixP) - fixS *fixP; +md_pcrel_from (fixS *fixP) { char *insn_p; static xtensa_insnbuf insnbuf = NULL; @@ -6229,8 +5626,7 @@ md_pcrel_from (fixP) /* TC_FORCE_RELOCATION hook */ int -xtensa_force_relocation (fix) - fixS *fix; +xtensa_force_relocation (fixS *fix) { switch (fix->fx_r_type) { @@ -6271,7 +5667,7 @@ xtensa_force_relocation (fix) seems wrong. */ bfd_boolean -xtensa_check_inside_bundle () +xtensa_check_inside_bundle (void) { if (cur_vinsn.inside_bundle && input_line_pointer[-1] == '.') as_bad (_("directives are not valid inside bundles")); @@ -6285,7 +5681,7 @@ xtensa_check_inside_bundle () /* md_elf_section_change_hook */ void -xtensa_elf_section_change_hook () +xtensa_elf_section_change_hook (void) { /* Set up the assembly state. */ if (!frag_now->tc_frag_data.is_assembly_state_set) @@ -6296,8 +5692,7 @@ xtensa_elf_section_change_hook () /* tc_fix_adjustable hook */ bfd_boolean -xtensa_fix_adjustable (fixP) - fixS *fixP; +xtensa_fix_adjustable (fixS *fixP) { /* An offset is not allowed in combination with the difference of two symbols, but that cannot be easily detected after a local symbol @@ -6331,10 +5726,7 @@ xtensa_fix_adjustable (fixP) void -md_apply_fix3 (fixP, valP, seg) - fixS *fixP; - valueT *valP; - segT seg ATTRIBUTE_UNUSED; +md_apply_fix3 (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) { if (fixP->fx_pcrel == 0 && fixP->fx_addsy == 0) { @@ -6373,10 +5765,7 @@ md_apply_fix3 (fixP, valP, seg) char * -md_atof (type, litP, sizeP) - int type; - char *litP; - int *sizeP; +md_atof (int type, char *litP, int *sizeP) { int prec; LITTLENUM_TYPE words[4]; @@ -6419,9 +5808,7 @@ md_atof (type, litP, sizeP) int -md_estimate_size_before_relax (fragP, seg) - fragS *fragP; - segT seg ATTRIBUTE_UNUSED; +md_estimate_size_before_relax (fragS *fragP, segT seg ATTRIBUTE_UNUSED) { return fragP->tc_frag_data.text_expansion[0]; } @@ -6431,9 +5818,7 @@ md_estimate_size_before_relax (fragP, seg) format. */ arelent * -tc_gen_reloc (section, fixp) - asection *section; - fixS *fixp; +tc_gen_reloc (asection *section, fixS *fixp) { arelent *reloc; bfd_boolean apply_tentative_value = FALSE; @@ -6606,42 +5991,199 @@ tc_gen_reloc (section, fixp) return reloc; } + +/* Checks for resource conflicts between instructions. */ -/* md_post_relax_hook */ +/* The func unit stuff could be implemented as bit-vectors rather + than the iterative approach here. If it ends up being too + slow, we will switch it. */ -#define XTENSA_INSN_SEC_NAME ".xt.insn" -#define XTENSA_LIT_SEC_NAME ".xt.lit" -#define XTENSA_PROP_SEC_NAME ".xt.prop" +resource_table * +new_resource_table (void *data, + int cycles, + int nu, + unit_num_copies_func uncf, + opcode_num_units_func onuf, + opcode_funcUnit_use_unit_func ouuf, + opcode_funcUnit_use_stage_func ousf) +{ + int i; + resource_table *rt = (resource_table *) xmalloc (sizeof (resource_table)); + rt->data = data; + rt->cycles = cycles; + rt->allocated_cycles = cycles; + rt->num_units = nu; + rt->unit_num_copies = uncf; + rt->opcode_num_units = onuf; + rt->opcode_unit_use = ouuf; + rt->opcode_unit_stage = ousf; -void -xtensa_post_relax_hook () + rt->units = (char **) xcalloc (cycles, sizeof (char *)); + for (i = 0; i < cycles; i++) + rt->units[i] = (char *) xcalloc (nu, sizeof (char)); + + return rt; +} + + +void +clear_resource_table (resource_table *rt) { - xtensa_move_seg_list_to_beginning (literal_head); - xtensa_move_seg_list_to_beginning (init_literal_head); - xtensa_move_seg_list_to_beginning (fini_literal_head); + int i, j; + for (i = 0; i < rt->allocated_cycles; i++) + for (j = 0; j < rt->num_units; j++) + rt->units[i][j] = 0; +} - xtensa_find_unmarked_state_frags (); - if (use_literal_section) - xtensa_create_property_segments (get_frag_is_literal, - NULL, - XTENSA_LIT_SEC_NAME, - xt_literal_sec); - xtensa_create_xproperty_segments (get_frag_property_flags, - XTENSA_PROP_SEC_NAME, - xt_prop_sec); +/* We never shrink it, just fake it into thinking so. */ - if (warn_unaligned_branch_targets) - bfd_map_over_sections (stdoutput, xtensa_find_unaligned_branch_targets, 0); - bfd_map_over_sections (stdoutput, xtensa_find_unaligned_loops, 0); +void +resize_resource_table (resource_table *rt, int cycles) +{ + int i, old_cycles; + + rt->cycles = cycles; + if (cycles <= rt->allocated_cycles) + return; + + old_cycles = rt->allocated_cycles; + rt->allocated_cycles = cycles; + + rt->units = xrealloc (rt->units, sizeof (char *) * rt->allocated_cycles); + for (i = 0; i < old_cycles; i++) + rt->units[i] = xrealloc (rt->units[i], sizeof (char) * rt->num_units); + for (i = old_cycles; i < cycles; i++) + rt->units[i] = xcalloc (rt->num_units, sizeof (char)); +} + + +bfd_boolean +resources_available (resource_table *rt, xtensa_opcode opcode, int cycle) +{ + int i; + int uses = (rt->opcode_num_units) (rt->data, opcode); + + for (i = 0; i < uses; i++) + { + xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i); + int stage = (rt->opcode_unit_stage) (rt->data, opcode, i); + int copies_in_use = rt->units[stage + cycle][unit]; + int copies = (rt->unit_num_copies) (rt->data, unit); + if (copies_in_use >= copies) + return FALSE; + } + return TRUE; +} + + +void +reserve_resources (resource_table *rt, xtensa_opcode opcode, int cycle) +{ + int i; + int uses = (rt->opcode_num_units) (rt->data, opcode); + + for (i = 0; i < uses; i++) + { + xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i); + int stage = (rt->opcode_unit_stage) (rt->data, opcode, i); + /* Note that this allows resources to be oversubscribed. That's + essential to the way the optional scheduler works. + resources_available reports when a resource is over-subscribed, + so it's easy to tell. */ + rt->units[stage + cycle][unit]++; + } } +void +release_resources (resource_table *rt, xtensa_opcode opcode, int cycle) +{ + int i; + int uses = (rt->opcode_num_units) (rt->data, opcode); + + for (i = 0; i < uses; i++) + { + xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i); + int stage = (rt->opcode_unit_stage) (rt->data, opcode, i); + rt->units[stage + cycle][unit]--; + assert (rt->units[stage + cycle][unit] >= 0); + } +} + + +/* Wrapper functions make parameterized resource reservation + more convenient. */ + +int +opcode_funcUnit_use_unit (void *data, xtensa_opcode opcode, int idx) +{ + xtensa_funcUnit_use *use = xtensa_opcode_funcUnit_use (data, opcode, idx); + return use->unit; +} + + +int +opcode_funcUnit_use_stage (void *data, xtensa_opcode opcode, int idx) +{ + xtensa_funcUnit_use *use = xtensa_opcode_funcUnit_use (data, opcode, idx); + return use->stage; +} + + +/* Note that this function does not check issue constraints, but + solely whether the hardware is available to execute the given + instructions together. It also doesn't check if the tinsns + write the same state, or access the same tieports. That is + checked by check_t1_t2_read_write. */ + +static bfd_boolean +resources_conflict (vliw_insn *vinsn) +{ + int i; + static resource_table *rt = NULL; + + /* This is the most common case by far. Optimize it. */ + if (vinsn->num_slots == 1) + return FALSE; + + if (rt == NULL) + { + xtensa_isa isa = xtensa_default_isa; + rt = new_resource_table + (isa, xtensa_isa_num_pipe_stages (isa), + xtensa_isa_num_funcUnits (isa), + (unit_num_copies_func) xtensa_funcUnit_num_copies, + (opcode_num_units_func) xtensa_opcode_num_funcUnit_uses, + opcode_funcUnit_use_unit, + opcode_funcUnit_use_stage); + } + + clear_resource_table (rt); + + for (i = 0; i < vinsn->num_slots; i++) + { + if (!resources_available (rt, vinsn->slots[i].opcode, 0)) + return TRUE; + reserve_resources (rt, vinsn->slots[i].opcode, 0); + } + + return FALSE; +} + + +/* finish_vinsn, emit_single_op and helper functions. */ + +static bfd_boolean find_vinsn_conflicts (vliw_insn *); +static xtensa_format xg_find_narrowest_format (vliw_insn *); +static void bundle_single_op (TInsn *); +static void xg_assemble_vliw_tokens (vliw_insn *); + + /* We have reached the end of a bundle; emit into the frag. */ static void -finish_vinsn (vinsn) - vliw_insn *vinsn; +finish_vinsn (vliw_insn *vinsn) { IStack slotstack; int i; @@ -6831,9 +6373,10 @@ finish_vinsn (vinsn) because the value of a0 is trashed before the second add can read it. */ +static char check_t1_t2_reads_and_writes (TInsn *, TInsn *); + static bfd_boolean -find_vinsn_conflicts (vinsn) - vliw_insn *vinsn; +find_vinsn_conflicts (vliw_insn *vinsn) { int i, j; int branches = 0; @@ -6919,9 +6462,7 @@ find_vinsn_conflicts (vinsn) */ static char -check_t1_t2_reads_and_writes (t1, t2) - TInsn *t1; - TInsn *t2; +check_t1_t2_reads_and_writes (TInsn *t1, TInsn *t2) { xtensa_isa isa = xtensa_default_isa; xtensa_regfile t1_regfile, t2_regfile; @@ -7080,207 +6621,8 @@ check_t1_t2_reads_and_writes (t1, t2) } -/* The func unit stuff could be implemented as bit-vectors rather - than the iterative approach here. If it ends up being too - slow, we will switch it. */ - -resource_table * -new_resource_table (data, cycles, nu, uncf, onuf, ouuf, ousf) - void *data; - int cycles; - int nu; - unit_num_copies_func uncf; - opcode_num_units_func onuf; - opcode_funcUnit_use_unit_func ouuf; - opcode_funcUnit_use_stage_func ousf; -{ - int i; - resource_table *rt = (resource_table *) xmalloc (sizeof (resource_table)); - rt->data = data; - rt->cycles = cycles; - rt->allocated_cycles = cycles; - rt->num_units = nu; - rt->unit_num_copies = uncf; - rt->opcode_num_units = onuf; - rt->opcode_unit_use = ouuf; - rt->opcode_unit_stage = ousf; - - rt->units = (char **) xcalloc (cycles, sizeof (char *)); - for (i = 0; i < cycles; i++) - rt->units[i] = (char *) xcalloc (nu, sizeof (char)); - - return rt; -} - - -void -clear_resource_table (rt) - resource_table *rt; -{ - int i, j; - for (i = 0; i < rt->allocated_cycles; i++) - for (j = 0; j < rt->num_units; j++) - rt->units[i][j] = 0; -} - - -/* We never shrink it, just fake it into thinking so. */ - -void -resize_resource_table (rt, cycles) - resource_table *rt; - int cycles; -{ - int i, old_cycles; - - rt->cycles = cycles; - if (cycles <= rt->allocated_cycles) - return; - - old_cycles = rt->allocated_cycles; - rt->allocated_cycles = cycles; - - rt->units = xrealloc (rt->units, sizeof (char *) * rt->allocated_cycles); - for (i = 0; i < old_cycles; i++) - rt->units[i] = xrealloc (rt->units[i], sizeof (char) * rt->num_units); - for (i = old_cycles; i < cycles; i++) - rt->units[i] = xcalloc (rt->num_units, sizeof (char)); -} - - -bfd_boolean -resources_available (rt, opcode, cycle) - resource_table *rt; - xtensa_opcode opcode; - int cycle; -{ - int i; - int uses = (rt->opcode_num_units) (rt->data, opcode); - - for (i = 0; i < uses; i++) - { - xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i); - int stage = (rt->opcode_unit_stage) (rt->data, opcode, i); - int copies_in_use = rt->units[stage + cycle][unit]; - int copies = (rt->unit_num_copies) (rt->data, unit); - if (copies_in_use >= copies) - return FALSE; - } - return TRUE; -} - - -void -reserve_resources (rt, opcode, cycle) - resource_table *rt; - xtensa_opcode opcode; - int cycle; -{ - int i; - int uses = (rt->opcode_num_units) (rt->data, opcode); - - for (i = 0; i < uses; i++) - { - xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i); - int stage = (rt->opcode_unit_stage) (rt->data, opcode, i); - /* Note that this allows resources to be oversubscribed. That's - essential to the way the optional scheduler works. - resources_available reports when a resource is over-subscribed, - so it's easy to tell. */ - rt->units[stage + cycle][unit]++; - } -} - - -void -release_resources (rt, opcode, cycle) - resource_table *rt; - xtensa_opcode opcode; - int cycle; -{ - int i; - int uses = (rt->opcode_num_units) (rt->data, opcode); - - for (i = 0; i < uses; i++) - { - xtensa_funcUnit unit = (rt->opcode_unit_use) (rt->data, opcode, i); - int stage = (rt->opcode_unit_stage) (rt->data, opcode, i); - rt->units[stage + cycle][unit]--; - assert (rt->units[stage + cycle][unit] >= 0); - } -} - - -/* Wrapper functions make parameterized resource reservation - more convenient. */ - -int -opcode_funcUnit_use_unit (data, opcode, idx) - void *data; - xtensa_opcode opcode; - int idx; -{ - xtensa_funcUnit_use *use = xtensa_opcode_funcUnit_use (data, opcode, idx); - return use->unit; -} - - -int -opcode_funcUnit_use_stage (data, opcode, idx) - void *data; - xtensa_opcode opcode; - int idx; -{ - xtensa_funcUnit_use *use = xtensa_opcode_funcUnit_use (data, opcode, idx); - return use->stage; -} - - -/* Note that this function does not check issue constraints, but - solely whether the hardware is available to execute the given - instructions together. It also doesn't check if the tinsns - write the same state, or access the same tieports. That is - checked by check_t1_t2_read_write. */ - -static bfd_boolean -resources_conflict (vinsn) - vliw_insn *vinsn; -{ - int i; - static resource_table *rt = NULL; - - /* This is the most common case by far. Optimize it. */ - if (vinsn->num_slots == 1) - return FALSE; - - if (rt == NULL) - { - xtensa_isa isa = xtensa_default_isa; - rt = new_resource_table - (isa, xtensa_isa_num_pipe_stages (isa), - xtensa_isa_num_funcUnits (isa), - (unit_num_copies_func) xtensa_funcUnit_num_copies, - (opcode_num_units_func) xtensa_opcode_num_funcUnit_uses, - opcode_funcUnit_use_unit, - opcode_funcUnit_use_stage); - } - - clear_resource_table (rt); - - for (i = 0; i < vinsn->num_slots; i++) - { - if (!resources_available (rt, vinsn->slots[i].opcode, 0)) - return TRUE; - reserve_resources (rt, vinsn->slots[i].opcode, 0); - } - - return FALSE; -} - - static xtensa_format -xg_find_narrowest_format (vinsn) - vliw_insn *vinsn; +xg_find_narrowest_format (vliw_insn *vinsn) { /* Right now we assume that the ops within the vinsn are properly ordered for the slots that the programmer wanted them in. In @@ -7311,33 +6653,30 @@ xg_find_narrowest_format (vinsn) if (opcode_fits_format_slot (v_copy.slots[slot].opcode, format, slot)) fit++; - else + else if (v_copy.num_slots > 1) { - if (v_copy.num_slots > 1) + TInsn widened; + /* Try the widened version. */ + if (!v_copy.slots[slot].keep_wide + && !v_copy.slots[slot].is_specific_opcode + && xg_is_narrow_insn (&v_copy.slots[slot]) + && !xg_expand_narrow (&widened, &v_copy.slots[slot]) + && opcode_fits_format_slot (widened.opcode, + format, slot)) { - TInsn widened; - /* Try the widened version. */ - if (!v_copy.slots[slot].keep_wide - && !v_copy.slots[slot].is_specific_opcode - && xg_is_narrow_insn (&v_copy.slots[slot]) - && !xg_expand_narrow (&widened, &v_copy.slots[slot]) - && opcode_fits_format_slot (widened.opcode, - format, slot)) - { - /* The xg_is_narrow clause requires some explanation: + /* The xg_is_narrow clause requires some explanation: - addi can be "widened" to an addmi, which is then - expanded to an addmi/addi pair if the immediate - requires it, but here we must have a single widen - only. + addi can be "widened" to an addmi, which is then + expanded to an addmi/addi pair if the immediate + requires it, but here we must have a single widen + only. - xg_is_narrow tells us that addi isn't really - narrow. The widen_spec_list says that there are - other cases. */ + xg_is_narrow tells us that addi isn't really + narrow. The widen_spec_list says that there are + other cases. */ - v_copy.slots[slot] = widened; - fit++; - } + v_copy.slots[slot] = widened; + fit++; } } } @@ -7364,8 +6703,7 @@ xg_find_narrowest_format (vinsn) each tinsn in the vinsn. */ static int -relaxation_requirements (vinsn) - vliw_insn *vinsn; +relaxation_requirements (vliw_insn *vinsn) { int extra_space = 0; int slot; @@ -7429,8 +6767,7 @@ relaxation_requirements (vinsn) static void -bundle_single_op (orig_insn) - TInsn *orig_insn; +bundle_single_op (TInsn *orig_insn) { xtensa_isa isa = xtensa_default_isa; vliw_insn v; @@ -7468,8 +6805,7 @@ bundle_single_op (orig_insn) static bfd_boolean -emit_single_op (orig_insn) - TInsn *orig_insn; +emit_single_op (TInsn *orig_insn) { int i; IStack istack; /* put instructions into here */ @@ -7529,9 +6865,8 @@ emit_single_op (orig_insn) /* Emit a vliw instruction to the current fragment. */ -void -xg_assemble_vliw_tokens (vinsn) - vliw_insn *vinsn; +static void +xg_assemble_vliw_tokens (vliw_insn *vinsn) { bfd_boolean finish_frag = FALSE; bfd_boolean is_jump = FALSE; @@ -7790,8 +7125,20 @@ xg_assemble_vliw_tokens (vinsn) } +/* xtensa_end and helper functions. */ + +static void xtensa_cleanup_align_frags (void); +static void xtensa_fix_target_frags (void); +static void xtensa_mark_narrow_branches (void); +static void xtensa_mark_zcl_first_insns (void); +static void xtensa_fix_a0_b_retw_frags (void); +static void xtensa_fix_b_j_loop_end_frags (void); +static void xtensa_fix_close_loop_end_frags (void); +static void xtensa_fix_short_loop_frags (void); +static void xtensa_sanity_check (void); + void -xtensa_end () +xtensa_end (void) { directive_balance (); xtensa_flush_pending_output (); @@ -7822,7 +7169,7 @@ xtensa_end () static void -xtensa_cleanup_align_frags () +xtensa_cleanup_align_frags (void) { frchainS *frchP; @@ -7873,8 +7220,10 @@ xtensa_cleanup_align_frags () fragment can be expanded to negate the branch, convert this to a RELAX_LOOP_END. Otherwise, convert to a .fill 0. */ +static bfd_boolean frag_can_negate_branch (fragS *); + static void -xtensa_fix_target_frags () +xtensa_fix_target_frags (void) { frchainS *frchP; @@ -7923,8 +7272,7 @@ xtensa_fix_target_frags () static bfd_boolean -frag_can_negate_branch (fragP) - fragS *fragP; +frag_can_negate_branch (fragS *fragP) { xtensa_isa isa = xtensa_default_isa; vliw_insn vinsn; @@ -7947,8 +7295,10 @@ frag_can_negate_branch (fragP) } +static bfd_boolean is_narrow_branch_guaranteed_in_range (fragS *, TInsn *); + static void -xtensa_mark_narrow_branches () +xtensa_mark_narrow_branches (void) { frchainS *frchP; @@ -8001,10 +7351,10 @@ xtensa_mark_narrow_branches () /* the range in bytes of a bnez.n and beqz.n */ #define MAX_IMMED6 68 +static size_t unrelaxed_frag_max_size (fragS *); + static bfd_boolean -is_narrow_branch_guaranteed_in_range (fragP, tinsn) - fragS *fragP; - TInsn *tinsn; +is_narrow_branch_guaranteed_in_range (fragS *fragP, TInsn *tinsn) { const expressionS *expr = &tinsn->tok[1]; symbolS *symbolP = expr->X_add_symbol; @@ -8029,7 +7379,7 @@ is_narrow_branch_guaranteed_in_range (fragP, tinsn) static void -xtensa_mark_zcl_first_insns () +xtensa_mark_zcl_first_insns (void) { frchainS *frchP; @@ -8067,8 +7417,10 @@ xtensa_mark_zcl_first_insns () conditional branch or a retw/retw.n, convert this frag to one that will generate a NOP. In any case close it off with a .fill 0. */ +static bfd_boolean next_instrs_are_b_retw (fragS *); + static void -xtensa_fix_a0_b_retw_frags () +xtensa_fix_a0_b_retw_frags (void) { frchainS *frchP; @@ -8098,9 +7450,8 @@ xtensa_fix_a0_b_retw_frags () } -bfd_boolean -next_instrs_are_b_retw (fragP) - fragS *fragP; +static bfd_boolean +next_instrs_are_b_retw (fragS *fragP) { xtensa_opcode opcode; xtensa_format fmt; @@ -8174,8 +7525,10 @@ next_instrs_are_b_retw (fragP) loop end label, convert this frag to one that will generate a NOP. In any case close it off with a .fill 0. */ +static bfd_boolean next_instr_is_loop_end (fragS *); + static void -xtensa_fix_b_j_loop_end_frags () +xtensa_fix_b_j_loop_end_frags (void) { frchainS *frchP; @@ -8205,9 +7558,8 @@ xtensa_fix_b_j_loop_end_frags () } -bfd_boolean -next_instr_is_loop_end (fragP) - fragS * fragP; +static bfd_boolean +next_instr_is_loop_end (fragS *fragP) { const fragS *next_fragP; @@ -8236,8 +7588,10 @@ next_instr_is_loop_end (fragP) make it at least 12 bytes away. In any case close it off with a .fill 0. */ +static size_t min_bytes_to_other_loop_end (fragS *, fragS *, offsetT, size_t); + static void -xtensa_fix_close_loop_end_frags () +xtensa_fix_close_loop_end_frags (void) { frchainS *frchP; @@ -8322,12 +7676,13 @@ xtensa_fix_close_loop_end_frags () } +static size_t unrelaxed_frag_min_size (fragS *); + static size_t -min_bytes_to_other_loop_end (fragP, current_target, current_offset, max_size) - fragS *fragP; - fragS *current_target; - offsetT current_offset; - size_t max_size; +min_bytes_to_other_loop_end (fragS *fragP, + fragS *current_target, + offsetT current_offset, + size_t max_size) { size_t offset = 0; fragS *current_fragP; @@ -8350,8 +7705,7 @@ min_bytes_to_other_loop_end (fragP, current_target, current_offset, max_size) static size_t -unrelaxed_frag_min_size (fragP) - fragS *fragP; +unrelaxed_frag_min_size (fragS *fragP) { size_t size = fragP->fr_fix; @@ -8364,8 +7718,7 @@ unrelaxed_frag_min_size (fragP) static size_t -unrelaxed_frag_max_size (fragP) - fragS *fragP; +unrelaxed_frag_max_size (fragS *fragP) { size_t size = fragP->fr_fix; switch (fragP->fr_type) @@ -8417,8 +7770,11 @@ unrelaxed_frag_max_size (fragP) then convert this frag (and maybe the next one) to generate a NOP. In any case close it off with a .fill 0. */ +static size_t count_insns_to_loop_end (fragS *, bfd_boolean, size_t); +static bfd_boolean branch_before_loop_end (fragS *); + static void -xtensa_fix_short_loop_frags () +xtensa_fix_short_loop_frags (void) { frchainS *frchP; @@ -8482,11 +7838,12 @@ xtensa_fix_short_loop_frags () } +static size_t unrelaxed_frag_min_insn_count (fragS *); + static size_t -count_insns_to_loop_end (base_fragP, count_relax_add, max_count) - fragS *base_fragP; - bfd_boolean count_relax_add; - size_t max_count; +count_insns_to_loop_end (fragS *base_fragP, + bfd_boolean count_relax_add, + size_t max_count) { fragS *fragP = NULL; size_t insn_count = 0; @@ -8518,8 +7875,7 @@ count_insns_to_loop_end (base_fragP, count_relax_add, max_count) static size_t -unrelaxed_frag_min_insn_count (fragP) - fragS *fragP; +unrelaxed_frag_min_insn_count (fragS *fragP) { xtensa_isa isa = xtensa_default_isa; static xtensa_insnbuf insnbuf = NULL; @@ -8553,9 +7909,10 @@ unrelaxed_frag_min_insn_count (fragP) } +static bfd_boolean unrelaxed_frag_has_b_j (fragS *); + static bfd_boolean -branch_before_loop_end (base_fragP) - fragS *base_fragP; +branch_before_loop_end (fragS *base_fragP) { fragS *fragP; @@ -8571,8 +7928,7 @@ branch_before_loop_end (base_fragP) static bfd_boolean -unrelaxed_frag_has_b_j (fragP) - fragS *fragP; +unrelaxed_frag_has_b_j (fragS *fragP) { static xtensa_insnbuf insnbuf = NULL; xtensa_isa isa = xtensa_default_isa; @@ -8611,8 +7967,11 @@ unrelaxed_frag_has_b_j (fragP) /* Checks to be made after initial assembly but before relaxation. */ +static bfd_boolean is_empty_loop (const TInsn *, fragS *); +static bfd_boolean is_local_forward_loop (const TInsn *, fragS *); + static void -xtensa_sanity_check () +xtensa_sanity_check (void) { char *file_name; int line; @@ -8668,10 +8027,8 @@ xtensa_sanity_check () /* Return TRUE if the loop target is the next non-zero fragment. */ -bfd_boolean -is_empty_loop (insn, fragP) - const TInsn *insn; - fragS *fragP; +static bfd_boolean +is_empty_loop (const TInsn *insn, fragS *fragP) { const expressionS *expr; symbolS *symbolP; @@ -8717,10 +8074,8 @@ is_empty_loop (insn, fragP) } -bfd_boolean -is_local_forward_loop (insn, fragP) - const TInsn *insn; - fragS *fragP; +static bfd_boolean +is_local_forward_loop (const TInsn *insn, fragS *fragP) { const expressionS *expr; symbolS *symbolP; @@ -8765,8 +8120,7 @@ is_local_forward_loop (insn, fragP) /* Alignment Functions. */ static size_t -get_text_align_power (target_size) - int target_size; +get_text_align_power (int target_size) { size_t i = 0; for (i = 0; i < sizeof (size_t); i++) @@ -8780,10 +8134,9 @@ get_text_align_power (target_size) static addressT -get_text_align_max_fill_size (align_pow, use_nops, use_no_density) - int align_pow; - bfd_boolean use_nops; - bfd_boolean use_no_density; +get_text_align_max_fill_size (int align_pow, + bfd_boolean use_nops, + bfd_boolean use_no_density) { if (!use_nops) return (1 << align_pow); @@ -8818,13 +8171,11 @@ get_text_align_max_fill_size (align_pow, use_nops, use_no_density) use_no_density = 0. */ static addressT -get_text_align_fill_size (address, align_pow, target_size, - use_nops, use_no_density) - addressT address; - int align_pow; - int target_size; - bfd_boolean use_nops; - bfd_boolean use_no_density; +get_text_align_fill_size (addressT address, + int align_pow, + int target_size, + bfd_boolean use_nops, + bfd_boolean use_no_density) { /* Input arguments: @@ -8904,10 +8255,8 @@ get_text_align_fill_size (address, align_pow, target_size, /* This will assert if it is not possible. */ -size_t -get_text_align_nop_count (fill_size, use_no_density) - size_t fill_size; - bfd_boolean use_no_density; +static size_t +get_text_align_nop_count (size_t fill_size, bfd_boolean use_no_density) { size_t count = 0; if (use_no_density) @@ -8931,11 +8280,10 @@ get_text_align_nop_count (fill_size, use_no_density) } -size_t -get_text_align_nth_nop_size (fill_size, n, use_no_density) - size_t fill_size; - size_t n; - bfd_boolean use_no_density; +static size_t +get_text_align_nth_nop_size (size_t fill_size, + size_t n, + bfd_boolean use_no_density) { size_t count = 0; @@ -8963,9 +8311,7 @@ get_text_align_nth_nop_size (fill_size, n, use_no_density) for it to begin at if we are using NOPs to align it. */ static addressT -get_noop_aligned_address (fragP, address) - fragS *fragP; - addressT address; +get_noop_aligned_address (fragS *fragP, addressT address) { /* The rule is: get next fragment's FIRST instruction. Find the smallest number of bytes that need to be added to @@ -9051,10 +8397,7 @@ get_noop_aligned_address (fragP, address) widening - widen previous instructions. */ static addressT -get_aligned_diff (fragP, address, max_diff) - fragS *fragP; - addressT address; - addressT *max_diff; +get_aligned_diff (fragS *fragP, addressT address, addressT *max_diff) { addressT target_address, loop_insn_offset; int target_size; @@ -9120,14 +8463,17 @@ get_aligned_diff (fragP, address, max_diff) /* md_relax_frag Hook and Helper Functions. */ +static long relax_frag_loop_align (fragS *, long); +static long relax_frag_for_align (fragS *, long); +static long relax_frag_immed + (segT, fragS *, long, int, xtensa_format, int, int *, bfd_boolean); + + /* Return the number of bytes added to this fragment, given that the input has been stretched already by "stretch". */ long -xtensa_relax_frag (fragP, stretch, stretched_p) - fragS *fragP; - long stretch; - int *stretched_p; +xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p) { xtensa_isa isa = xtensa_default_isa; int unreported = fragP->tc_frag_data.unreported_expansion; @@ -9244,9 +8590,7 @@ xtensa_relax_frag (fragP, stretch, stretched_p) static long -relax_frag_loop_align (fragP, stretch) - fragS *fragP; - long stretch; +relax_frag_loop_align (fragS *fragP, long stretch) { addressT old_address, old_next_address, old_size; addressT new_address, new_next_address, new_size; @@ -9279,8 +8623,7 @@ relax_frag_loop_align (fragP, stretch) /* Add a NOP instruction. */ static long -relax_frag_add_nop (fragP) - fragS *fragP; +relax_frag_add_nop (fragS *fragP) { char *nop_buf = fragP->fr_literal + fragP->fr_fix; int length = fragP->tc_frag_data.is_no_density ? 3 : 2; @@ -9299,10 +8642,10 @@ relax_frag_add_nop (fragP) } +static long future_alignment_required (fragS *, long); + static long -relax_frag_for_align (fragP, stretch) - fragS *fragP; - long stretch; +relax_frag_for_align (fragS *fragP, long stretch) { /* Overview of the relaxation procedure for alignment: We can widen with NOPs or by widening instructions or by filling @@ -9356,13 +8699,11 @@ relax_frag_for_align (fragP, stretch) aligned. */ static addressT -find_address_of_next_align_frag (fragPP, wide_nops, narrow_nops, - widens, paddable) - fragS **fragPP; - int *wide_nops; - int *narrow_nops; - int *widens; - bfd_boolean *paddable; +find_address_of_next_align_frag (fragS **fragPP, + int *wide_nops, + int *narrow_nops, + int *widens, + bfd_boolean *paddable) { fragS *fragP = *fragPP; addressT address = fragP->fr_address; @@ -9439,15 +8780,15 @@ find_address_of_next_align_frag (fragPP, wide_nops, narrow_nops, } +static long bytes_to_stretch (fragS *, int, int, int, int); + /* Undefine LOOKAHEAD_ALIGNER to get the older behavior. I'll leave this in until I am more confident this works. */ #define LOOKAHEAD_ALIGNER 1 static long -future_alignment_required (fragP, stretch) - fragS *fragP; - long stretch ATTRIBUTE_UNUSED; +future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED) { fragS *this_frag = fragP; long address; @@ -9462,9 +8803,8 @@ future_alignment_required (fragP, stretch) int local_stretch_amount; int global_stretch_amount; - address - = find_address_of_next_align_frag (&fragP, &wide_nops, &narrow_nops, - &num_widens, &paddable); + address = find_address_of_next_align_frag + (&fragP, &wide_nops, &narrow_nops, &num_widens, &paddable); if (address) { @@ -9487,9 +8827,8 @@ future_alignment_required (fragP, stretch) int dnn = 0; int dw = 0; bfd_boolean glob_pad = 0; - address = - find_address_of_next_align_frag (&fragP, &glob_widens, - &dnn, &dw, &glob_pad); + address = find_address_of_next_align_frag + (&fragP, &glob_widens, &dnn, &dw, &glob_pad); /* If there is a padable portion, then skip. */ if (glob_pad || (glob_widens >= xtensa_fetch_width)) break; @@ -9607,12 +8946,11 @@ future_alignment_required (fragP, stretch) */ static long -bytes_to_stretch (this_frag, wide_nops, narrow_nops, num_widens, desired_diff) - fragS *this_frag; - int wide_nops; - int narrow_nops; - int num_widens; - int desired_diff; +bytes_to_stretch (fragS *this_frag, + int wide_nops, + int narrow_nops, + int num_widens, + int desired_diff) { int bytes_short = desired_diff - num_widens; @@ -9742,16 +9080,14 @@ bytes_to_stretch (this_frag, wide_nops, narrow_nops, num_widens, desired_diff) static long -relax_frag_immed (segP, fragP, stretch, min_steps, fmt, slot, stretched_p, - estimate_only) - segT segP; - fragS *fragP; - long stretch; - int min_steps; - xtensa_format fmt; - int slot; - int *stretched_p; - bfd_boolean estimate_only; +relax_frag_immed (segT segP, + fragS *fragP, + long stretch, + int min_steps, + xtensa_format fmt, + int slot, + int *stretched_p, + bfd_boolean estimate_only) { TInsn tinsn; vliw_insn orig_vinsn; @@ -9881,11 +9217,13 @@ relax_frag_immed (segP, fragP, stretch, min_steps, fmt, slot, stretched_p, /* md_convert_frag Hook and Helper Functions. */ +static void convert_frag_align_next_opcode (fragS *); +static void convert_frag_narrow (segT, fragS *, xtensa_format, int); +static void convert_frag_fill_nop (fragS *); +static void convert_frag_immed (segT, fragS *, int, xtensa_format, int); + void -md_convert_frag (abfd, sec, fragp) - bfd *abfd ATTRIBUTE_UNUSED; - segT sec; - fragS *fragp; +md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragp) { static xtensa_insnbuf vbuf = NULL; xtensa_isa isa = xtensa_default_isa; @@ -9998,9 +9336,8 @@ md_convert_frag (abfd, sec, fragp) } -void -convert_frag_align_next_opcode (fragp) - fragS *fragp; +static void +convert_frag_align_next_opcode (fragS *fragp) { char *nop_buf; /* Location for Writing. */ size_t i; @@ -10030,11 +9367,7 @@ convert_frag_align_next_opcode (fragp) static void -convert_frag_narrow (segP, fragP, fmt, slot) - segT segP; - fragS *fragP; - xtensa_format fmt; - int slot; +convert_frag_narrow (segT segP, fragS *fragP, xtensa_format fmt, int slot) { TInsn tinsn, single_target; xtensa_format single_fmt; @@ -10098,8 +9431,7 @@ convert_frag_narrow (segP, fragP, fmt, slot) static void -convert_frag_fill_nop (fragP) - fragS *fragP; +convert_frag_fill_nop (fragS *fragP) { char *loc = &fragP->fr_literal[fragP->fr_fix]; int size = fragP->tc_frag_data.text_expansion[0]; @@ -10119,13 +9451,17 @@ convert_frag_fill_nop (fragP) } +static fixS *fix_new_exp_in_seg + (segT, subsegT, fragS *, int, int, expressionS *, int, + bfd_reloc_code_real_type); +static void convert_frag_immed_finish_loop (segT, fragS *, TInsn *); + static void -convert_frag_immed (segP, fragP, min_steps, fmt, slot) - segT segP; - fragS *fragP; - int min_steps; - xtensa_format fmt; - int slot; +convert_frag_immed (segT segP, + fragS *fragP, + int min_steps, + xtensa_format fmt, + int slot) { char *immed_instr = fragP->fr_opcode; TInsn orig_tinsn; @@ -10421,16 +9757,14 @@ convert_frag_immed (segP, fragP, min_steps, fmt, slot) switch to that segment to do this. */ static fixS * -fix_new_exp_in_seg (new_seg, new_subseg, - frag, where, size, exp, pcrel, r_type) - segT new_seg; - subsegT new_subseg; - fragS *frag; - int where; - int size; - expressionS *exp; - int pcrel; - bfd_reloc_code_real_type r_type; +fix_new_exp_in_seg (segT new_seg, + subsegT new_subseg, + fragS *frag, + int where, + int size, + expressionS *exp, + int pcrel, + bfd_reloc_code_real_type r_type) { fixS *new_fix; segT seg = now_seg; @@ -10462,11 +9796,10 @@ fix_new_exp_in_seg (new_seg, new_subseg, label: */ +static offsetT get_expression_value (segT, expressionS *); + static void -convert_frag_immed_finish_loop (segP, fragP, tinsn) - segT segP; - fragS *fragP; - TInsn *tinsn; +convert_frag_immed_finish_loop (segT segP, fragS *fragP, TInsn *tinsn) { TInsn loop_insn; TInsn addi_insn; @@ -10555,9 +9888,7 @@ convert_frag_immed_finish_loop (segP, fragP, tinsn) static offsetT -get_expression_value (segP, exp) - segT segP; - expressionS *exp; +get_expression_value (segT segP, expressionS *exp) { if (exp->X_op == O_constant) return exp->X_add_number; @@ -10578,21 +9909,8 @@ get_expression_value (segP, exp) static subseg_map *sseg_map = NULL; - -static unsigned -get_last_insn_flags (seg, subseg) - segT seg; - subsegT subseg; -{ - subseg_map *subseg_e = get_subseg_info (seg, subseg); - return subseg_e->flags; -} - - static subseg_map * -get_subseg_info (seg, subseg) - segT seg; - subsegT subseg; +get_subseg_info (segT seg, subsegT subseg) { subseg_map *subseg_e; @@ -10616,12 +9934,20 @@ get_subseg_info (seg, subseg) return subseg_e; } + +static unsigned +get_last_insn_flags (segT seg, subsegT subseg) +{ + subseg_map *subseg_e = get_subseg_info (seg, subseg); + return subseg_e->flags; +} + + static void -set_last_insn_flags (seg, subseg, fl, val) - segT seg; - subsegT subseg; - unsigned fl; - bfd_boolean val; +set_last_insn_flags (segT seg, + subsegT subseg, + unsigned fl, + bfd_boolean val) { subseg_map *subseg_e = get_subseg_info (seg, subseg); if (val) @@ -10636,8 +9962,7 @@ set_last_insn_flags (seg, subseg, fl, val) /* Remove the segment from the global sections list. */ static void -xtensa_remove_section (sec) - segT sec; +xtensa_remove_section (segT sec) { /* Handle brain-dead bfd_section_list_remove macro, which expect the address of the prior section's "next" field, not @@ -10654,9 +9979,7 @@ xtensa_remove_section (sec) static void -xtensa_insert_section (after_sec, sec) - segT after_sec; - segT sec; +xtensa_insert_section (segT after_sec, segT sec) { segT *after_sec_next; if (after_sec == NULL) @@ -10669,8 +9992,7 @@ xtensa_insert_section (after_sec, sec) static void -xtensa_move_seg_list_to_beginning (head) - seg_list *head; +xtensa_move_seg_list_to_beginning (seg_list *head) { head = head->next; while (head) @@ -10687,8 +10009,10 @@ xtensa_move_seg_list_to_beginning (head) } -void -xtensa_move_literals () +static void mark_literal_frags (seg_list *); + +static void +xtensa_move_literals (void) { seg_list *segment; frchainS *frchain_from, *frchain_to; @@ -10813,8 +10137,7 @@ xtensa_move_literals () and frag_variant to get called in all situations. */ static void -mark_literal_frags (segment) - seg_list *segment; +mark_literal_frags (seg_list *segment) { frchainS *frchain_from; fragS *search_frag; @@ -10834,9 +10157,7 @@ mark_literal_frags (segment) static void -xtensa_reorder_seg_list (head, after) - seg_list *head; - segT after; +xtensa_reorder_seg_list (seg_list *head, segT after) { /* Move all of the sections in the section list to come after "after" in the gnu segment list. */ @@ -10861,8 +10182,10 @@ xtensa_reorder_seg_list (head, after) /* Push all the literal segments to the end of the gnu list. */ -void -xtensa_reorder_segments () +static segT get_last_sec (void); + +static void +xtensa_reorder_segments (void) { segT sec; segT last_sec; @@ -10886,8 +10209,8 @@ xtensa_reorder_segments () } -segT -get_last_sec () +static segT +get_last_sec (void) { segT last_sec = stdoutput->sections; while (last_sec->next != NULL) @@ -10901,9 +10224,8 @@ get_last_sec () correct location. Return a emit_state which can be passed to xtensa_restore_emit_state to return to current fragment. */ -void -xtensa_switch_to_literal_fragment (result) - emit_state *result; +static void +xtensa_switch_to_literal_fragment (emit_state *result) { if (directive_state[directive_absolute_literals]) { @@ -10921,9 +10243,8 @@ xtensa_switch_to_literal_fragment (result) } -void -xtensa_switch_to_non_abs_literal_fragment (result) - emit_state *result; +static void +xtensa_switch_to_non_abs_literal_fragment (emit_state *result) { /* When we mark a literal pool location, we want to put a frag in the literal pool that points to it. But to do that, we want to @@ -10997,11 +10318,10 @@ xtensa_switch_to_non_abs_literal_fragment (result) This is a helper function for xtensa_switch_to_literal_fragment. This is similar to a .section new_now_seg subseg. */ -void -xtensa_switch_section_emit_state (state, new_now_seg, new_now_subseg) - emit_state *state; - segT new_now_seg; - subsegT new_now_subseg; +static void +xtensa_switch_section_emit_state (emit_state *state, + segT new_now_seg, + subsegT new_now_subseg) { state->name = now_seg->name; state->now_seg = now_seg; @@ -11014,9 +10334,8 @@ xtensa_switch_section_emit_state (state, new_now_seg, new_now_subseg) /* Use to restore the emitting into the normal place. */ -void -xtensa_restore_emit_state (state) - emit_state *state; +static void +xtensa_restore_emit_state (emit_state *state) { generating_literals = state->generating_literals; subseg_new (state->name, state->now_subseg); @@ -11026,12 +10345,13 @@ xtensa_restore_emit_state (state) /* Get a segment of a given name. If the segment is already present, return it; otherwise, create a new one. */ +static segT retrieve_literal_seg (seg_list *, const char *, bfd_boolean); + static void -cache_literal_section (head, name, seg, is_code) - seg_list *head; - const char *name; - segT *seg; - bfd_boolean is_code; +cache_literal_section (seg_list *head, + const char *name, + segT *seg, + bfd_boolean is_code) { segT current_section = now_seg; int current_subsec = now_subseg; @@ -11046,11 +10366,11 @@ cache_literal_section (head, name, seg, is_code) /* Get a segment of a given name. If the segment is already present, return it; otherwise, create a new one. */ +static segT seg_present (const char *); +static void add_seg_list (seg_list *, segT); + static segT -retrieve_literal_seg (head, name, is_code) - seg_list *head; - const char *name; - bfd_boolean is_code; +retrieve_literal_seg (seg_list *head, const char *name, bfd_boolean is_code) { segT ret = 0; @@ -11073,8 +10393,7 @@ retrieve_literal_seg (head, name, is_code) /* Return a segment of a given name if it is present. */ static segT -seg_present (name) - const char *name; +seg_present (const char *name) { segT seg; seg = stdoutput->sections; @@ -11093,9 +10412,7 @@ seg_present (name) /* Add a segment to a segment list. */ static void -add_seg_list (head, seg) - seg_list *head; - segT seg; +add_seg_list (seg_list *head, segT seg) { seg_list *n; n = (seg_list *) xmalloc (sizeof (seg_list)); @@ -11109,11 +10426,60 @@ add_seg_list (head, seg) /* Property Tables Stuff. */ +#define XTENSA_INSN_SEC_NAME ".xt.insn" +#define XTENSA_LIT_SEC_NAME ".xt.lit" +#define XTENSA_PROP_SEC_NAME ".xt.prop" + +typedef bfd_boolean (*frag_predicate) (const fragS *); +typedef void (*frag_flags_fn) (const fragS *, frag_flags *); + +static void xtensa_create_property_segments + (frag_predicate, frag_predicate, const char *, xt_section_type); +static void xtensa_create_xproperty_segments + (frag_flags_fn, const char *, xt_section_type); +static segment_info_type *retrieve_segment_info (segT); +static segT retrieve_xtensa_section (char *); +static bfd_boolean section_has_property (segT, frag_predicate); +static bfd_boolean section_has_xproperty (segT, frag_flags_fn); +static void add_xt_block_frags + (segT, segT, xtensa_block_info **, frag_predicate, frag_predicate); +static bfd_boolean xtensa_frag_flags_is_empty (const frag_flags *); +static void xtensa_frag_flags_init (frag_flags *); +static void get_frag_property_flags (const fragS *, frag_flags *); +static bfd_vma frag_flags_to_number (const frag_flags *); +static void add_xt_prop_frags + (segT, segT, xtensa_block_info **, frag_flags_fn); + +/* Set up property tables after relaxation. */ + +void +xtensa_post_relax_hook (void) +{ + xtensa_move_seg_list_to_beginning (literal_head); + xtensa_move_seg_list_to_beginning (init_literal_head); + xtensa_move_seg_list_to_beginning (fini_literal_head); + + xtensa_find_unmarked_state_frags (); + + if (use_literal_section) + xtensa_create_property_segments (get_frag_is_literal, + NULL, + XTENSA_LIT_SEC_NAME, + xt_literal_sec); + xtensa_create_xproperty_segments (get_frag_property_flags, + XTENSA_PROP_SEC_NAME, + xt_prop_sec); + + if (warn_unaligned_branch_targets) + bfd_map_over_sections (stdoutput, xtensa_find_unaligned_branch_targets, 0); + bfd_map_over_sections (stdoutput, xtensa_find_unaligned_loops, 0); +} + + /* This function is only meaningful after xtensa_move_literals. */ static bfd_boolean -get_frag_is_literal (fragP) - const fragS *fragP; +get_frag_is_literal (const fragS *fragP) { assert (fragP != NULL); return fragP->tc_frag_data.is_literal; @@ -11121,47 +10487,39 @@ get_frag_is_literal (fragP) static bfd_boolean -get_frag_is_insn (fragP) - const fragS *fragP; +get_frag_is_insn (const fragS *fragP) { assert (fragP != NULL); return fragP->tc_frag_data.is_insn; } -bfd_boolean -get_frag_is_no_transform (fragP) - fragS *fragP; +static bfd_boolean +get_frag_is_no_transform (fragS *fragP) { return fragP->tc_frag_data.is_no_transform; } -void -set_frag_is_specific_opcode (fragP, is_specific_opcode) - fragS *fragP; - bfd_boolean is_specific_opcode; +static void +set_frag_is_specific_opcode (fragS *fragP, bfd_boolean is_specific_opcode) { fragP->tc_frag_data.is_specific_opcode = is_specific_opcode; } -void -set_frag_is_no_transform (fragP, is_no_transform) - fragS *fragP; - bfd_boolean is_no_transform; +static void +set_frag_is_no_transform (fragS *fragP, bfd_boolean is_no_transform) { fragP->tc_frag_data.is_no_transform = is_no_transform; } static void -xtensa_create_property_segments (property_function, end_property_function, - section_name_base, sec_type) - frag_predicate property_function; - frag_predicate end_property_function; - const char *section_name_base; - xt_section_type sec_type; +xtensa_create_property_segments (frag_predicate property_function, + frag_predicate end_property_function, + const char *section_name_base, + xt_section_type sec_type) { segT *seclist; @@ -11291,11 +10649,10 @@ xtensa_create_property_segments (property_function, end_property_function, } -void -xtensa_create_xproperty_segments (flag_fn, section_name_base, sec_type) - frag_flags_fn flag_fn; - const char *section_name_base; - xt_section_type sec_type; +static void +xtensa_create_xproperty_segments (frag_flags_fn flag_fn, + const char *section_name_base, + xt_section_type sec_type) { segT *seclist; @@ -11428,9 +10785,8 @@ xtensa_create_xproperty_segments (flag_fn, section_name_base, sec_type) } -segment_info_type * -retrieve_segment_info (seg) - segT seg; +static segment_info_type * +retrieve_segment_info (segT seg) { segment_info_type *seginfo; seginfo = (segment_info_type *) bfd_get_section_userdata (stdoutput, seg); @@ -11439,7 +10795,7 @@ retrieve_segment_info (seg) frchainS *frchainP; seginfo = (segment_info_type *) xmalloc (sizeof (*seginfo)); - memset ((PTR) seginfo, 0, sizeof (*seginfo)); + memset ((void *) seginfo, 0, sizeof (*seginfo)); seginfo->fix_root = NULL; seginfo->fix_tail = NULL; seginfo->bfd_section = seg; @@ -11452,7 +10808,7 @@ retrieve_segment_info (seg) und_seg_info = seginfo; else #endif - bfd_set_section_userdata (stdoutput, seg, (PTR) seginfo); + bfd_set_section_userdata (stdoutput, seg, (void *) seginfo); #if 0 seg_fix_rootP = &segment_info[seg].fix_root; seg_fix_tailP = &segment_info[seg].fix_tail; @@ -11478,9 +10834,8 @@ retrieve_segment_info (seg) } -segT -retrieve_xtensa_section (sec_name) - char *sec_name; +static segT +retrieve_xtensa_section (char *sec_name) { bfd *abfd = stdoutput; flagword flags, out_flags, link_once_flags; @@ -11502,10 +10857,8 @@ retrieve_xtensa_section (sec_name) } -bfd_boolean -section_has_property (sec, property_function) - segT sec; - frag_predicate property_function; +static bfd_boolean +section_has_property (segT sec, frag_predicate property_function) { segment_info_type *seginfo = seg_info (sec); fragS *fragP; @@ -11523,10 +10876,8 @@ section_has_property (sec, property_function) } -bfd_boolean -section_has_xproperty (sec, property_function) - segT sec; - frag_flags_fn property_function; +static bfd_boolean +section_has_xproperty (segT sec, frag_flags_fn property_function) { segment_info_type *seginfo = seg_info (sec); fragS *fragP; @@ -11547,14 +10898,12 @@ section_has_xproperty (sec, property_function) /* Two types of block sections exist right now: literal and insns. */ -void -add_xt_block_frags (sec, xt_block_sec, xt_block, property_function, - end_property_function) - segT sec; - segT xt_block_sec; - xtensa_block_info **xt_block; - frag_predicate property_function; - frag_predicate end_property_function; +static void +add_xt_block_frags (segT sec, + segT xt_block_sec, + xtensa_block_info **xt_block, + frag_predicate property_function, + frag_predicate end_property_function) { segment_info_type *seg_info; segment_info_type *xt_seg_info; @@ -11613,9 +10962,8 @@ add_xt_block_frags (sec, xt_block_sec, xt_block, property_function, /* Break the encapsulation of add_xt_prop_frags here. */ -bfd_boolean -xtensa_frag_flags_is_empty (prop_flags) - const frag_flags *prop_flags; +static bfd_boolean +xtensa_frag_flags_is_empty (const frag_flags *prop_flags) { if (prop_flags->is_literal || prop_flags->is_insn @@ -11626,26 +10974,21 @@ xtensa_frag_flags_is_empty (prop_flags) } -void -xtensa_frag_flags_init (prop_flags) - frag_flags *prop_flags; +static void +xtensa_frag_flags_init (frag_flags *prop_flags) { memset (prop_flags, 0, sizeof (frag_flags)); } -void -get_frag_property_flags (fragP, prop_flags) - const fragS *fragP; - frag_flags *prop_flags; +static void +get_frag_property_flags (const fragS *fragP, frag_flags *prop_flags) { xtensa_frag_flags_init (prop_flags); if (fragP->tc_frag_data.is_literal) prop_flags->is_literal = TRUE; if (fragP->tc_frag_data.is_unreachable) - { - prop_flags->is_unreachable = TRUE; - } + prop_flags->is_unreachable = TRUE; else if (fragP->tc_frag_data.is_insn) { prop_flags->is_insn = TRUE; @@ -11671,9 +11014,8 @@ get_frag_property_flags (fragP, prop_flags) } -bfd_vma -frag_flags_to_number (prop_flags) - const frag_flags *prop_flags; +static bfd_vma +frag_flags_to_number (const frag_flags *prop_flags) { bfd_vma num = 0; if (prop_flags->is_literal) @@ -11712,9 +11054,8 @@ frag_flags_to_number (prop_flags) static bfd_boolean -xtensa_frag_flags_combinable (prop_flags_1, prop_flags_2) - const frag_flags *prop_flags_1; - const frag_flags *prop_flags_2; +xtensa_frag_flags_combinable (const frag_flags *prop_flags_1, + const frag_flags *prop_flags_2) { /* Cannot combine with an end marker. */ @@ -11753,9 +11094,8 @@ xtensa_frag_flags_combinable (prop_flags_1, prop_flags_2) } -bfd_vma -xt_block_aligned_size (xt_block) - const xtensa_block_info *xt_block; +static bfd_vma +xt_block_aligned_size (const xtensa_block_info *xt_block) { bfd_vma end_addr; size_t align_bits; @@ -11771,9 +11111,8 @@ xt_block_aligned_size (xt_block) static bfd_boolean -xtensa_xt_block_combine (xt_block, xt_block_2) - xtensa_block_info *xt_block; - const xtensa_block_info *xt_block_2; +xtensa_xt_block_combine (xtensa_block_info *xt_block, + const xtensa_block_info *xt_block_2) { if (xt_block->sec != xt_block_2->sec) return FALSE; @@ -11819,12 +11158,11 @@ xtensa_xt_block_combine (xt_block, xt_block_2) } -void -add_xt_prop_frags (sec, xt_block_sec, xt_block, property_function) - segT sec; - segT xt_block_sec; - xtensa_block_info **xt_block; - frag_flags_fn property_function; +static void +add_xt_prop_frags (segT sec, + segT xt_block_sec, + xtensa_block_info **xt_block, + frag_flags_fn property_function) { segment_info_type *seg_info; segment_info_type *xt_seg_info; @@ -11881,7 +11219,7 @@ add_xt_prop_frags (sec, xt_block_sec, xt_block, property_function) ops can go in which slots. */ static void -init_op_placement_info_table () +init_op_placement_info_table (void) { xtensa_isa isa = xtensa_default_isa; xtensa_insnbuf ibuf = xtensa_insnbuf_alloc (isa); @@ -11951,10 +11289,7 @@ init_op_placement_info_table () bfd_boolean -opcode_fits_format_slot (opcode, fmt, slot) - xtensa_opcode opcode; - xtensa_format fmt; - int slot; +opcode_fits_format_slot (xtensa_opcode opcode, xtensa_format fmt, int slot) { return bit_is_set (slot, op_placement_table[opcode].slots[fmt]); } @@ -11962,18 +11297,16 @@ opcode_fits_format_slot (opcode, fmt, slot) /* If the opcode is available in a single slot format, return its size. */ -int -xg_get_single_size (opcode) - xtensa_opcode opcode; +static int +xg_get_single_size (xtensa_opcode opcode) { assert (op_placement_table[opcode].single != XTENSA_UNDEFINED); return op_placement_table[opcode].single_size; } -xtensa_format -xg_get_single_format (opcode) - xtensa_opcode opcode; +static xtensa_format +xg_get_single_format (xtensa_opcode opcode) { return op_placement_table[opcode].single; } @@ -11982,8 +11315,7 @@ xg_get_single_format (opcode) /* Instruction Stack Functions (from "xtensa-istack.h"). */ void -istack_init (stack) - IStack *stack; +istack_init (IStack *stack) { memset (stack, 0, sizeof (IStack)); stack->ninsn = 0; @@ -11991,16 +11323,14 @@ istack_init (stack) bfd_boolean -istack_empty (stack) - IStack *stack; +istack_empty (IStack *stack) { return (stack->ninsn == 0); } bfd_boolean -istack_full (stack) - IStack *stack; +istack_full (IStack *stack) { return (stack->ninsn == MAX_ISTACK); } @@ -12010,8 +11340,7 @@ istack_full (stack) It is an error to call this if istack_empty () is TRUE. */ TInsn * -istack_top (stack) - IStack *stack; +istack_top (IStack *stack) { int rec = stack->ninsn - 1; assert (!istack_empty (stack)); @@ -12023,9 +11352,7 @@ istack_top (stack) It is an error to call this if istack_full () is TRUE. */ void -istack_push (stack, insn) - IStack *stack; - TInsn *insn; +istack_push (IStack *stack, TInsn *insn) { int rec = stack->ninsn; assert (!istack_full (stack)); @@ -12038,8 +11365,7 @@ istack_push (stack, insn) to it. It is an error to call this if istack_full () is TRUE. */ TInsn * -istack_push_space (stack) - IStack *stack; +istack_push_space (IStack *stack) { int rec = stack->ninsn; TInsn *insn; @@ -12055,8 +11381,7 @@ istack_push_space (stack) istack_empty () returns TRUE. */ void -istack_pop (stack) - IStack *stack; +istack_pop (IStack *stack) { int rec = stack->ninsn - 1; assert (!istack_empty (stack)); @@ -12068,8 +11393,7 @@ istack_pop (stack) /* TInsn functions. */ void -tinsn_init (dst) - TInsn *dst; +tinsn_init (TInsn *dst) { memset (dst, 0, sizeof (TInsn)); } @@ -12079,9 +11403,7 @@ tinsn_init (dst) It is illegal to call this if num > insn->ntoks. */ expressionS * -tinsn_get_tok (insn, num) - TInsn *insn; - int num; +tinsn_get_tok (TInsn *insn, int num) { assert (num < insn->ntok); return &insn->tok[num]; @@ -12091,8 +11413,7 @@ tinsn_get_tok (insn, num) /* Return TRUE if ANY of the operands in the insn are symbolic. */ static bfd_boolean -tinsn_has_symbolic_operands (insn) - const TInsn *insn; +tinsn_has_symbolic_operands (const TInsn *insn) { int i; int n = insn->ntok; @@ -12115,8 +11436,7 @@ tinsn_has_symbolic_operands (insn) bfd_boolean -tinsn_has_invalid_symbolic_operands (insn) - const TInsn *insn; +tinsn_has_invalid_symbolic_operands (const TInsn *insn) { xtensa_isa isa = xtensa_default_isa; int i; @@ -12168,8 +11488,7 @@ tinsn_has_invalid_symbolic_operands (insn) boil down to SYMBOL + OFFSET. */ static bfd_boolean -tinsn_has_complex_operands (insn) - const TInsn *insn; +tinsn_has_complex_operands (const TInsn *insn) { int i; int n = insn->ntok; @@ -12203,9 +11522,7 @@ tinsn_has_complex_operands (insn) The return value tells whether there are any remaining O_symbols. */ static bfd_boolean -tinsn_to_insnbuf (tinsn, insnbuf) - TInsn *tinsn; - xtensa_insnbuf insnbuf; +tinsn_to_insnbuf (TInsn *tinsn, xtensa_insnbuf insnbuf) { static xtensa_insnbuf slotbuf = 0; xtensa_isa isa = xtensa_default_isa; @@ -12282,11 +11599,10 @@ tinsn_to_insnbuf (tinsn, insnbuf) The return value tells whether there are any remaining O_symbols. */ static bfd_boolean -tinsn_to_slotbuf (fmt, slot, tinsn, slotbuf) - xtensa_format fmt; - int slot; - TInsn *tinsn; - xtensa_insnbuf slotbuf; +tinsn_to_slotbuf (xtensa_format fmt, + int slot, + TInsn *tinsn, + xtensa_insnbuf slotbuf) { xtensa_isa isa = xtensa_default_isa; xtensa_opcode opcode = tinsn->opcode; @@ -12351,9 +11667,8 @@ tinsn_to_slotbuf (fmt, slot, tinsn, slotbuf) /* Check the instruction arguments. Return TRUE on failure. */ -bfd_boolean -tinsn_check_arguments (insn) - const TInsn *insn; +static bfd_boolean +tinsn_check_arguments (const TInsn *insn) { xtensa_isa isa = xtensa_default_isa; xtensa_opcode opcode = insn->opcode; @@ -12382,10 +11697,7 @@ tinsn_check_arguments (insn) /* Load an instruction from its encoded form. */ static void -tinsn_from_chars (tinsn, f, slot) - TInsn *tinsn; - char *f; - int slot; +tinsn_from_chars (TInsn *tinsn, char *f, int slot) { vliw_insn vinsn; @@ -12398,11 +11710,10 @@ tinsn_from_chars (tinsn, f, slot) static void -tinsn_from_insnbuf (tinsn, slotbuf, fmt, slot) - TInsn *tinsn; - xtensa_insnbuf slotbuf; - xtensa_format fmt; - int slot; +tinsn_from_insnbuf (TInsn *tinsn, + xtensa_insnbuf slotbuf, + xtensa_format fmt, + int slot) { int i; xtensa_isa isa = xtensa_default_isa; @@ -12425,10 +11736,7 @@ tinsn_from_insnbuf (tinsn, slotbuf, fmt, slot) /* Read the value of the relaxable immed from the fr_symbol and fr_offset. */ static void -tinsn_immed_from_frag (tinsn, fragP, slot) - TInsn *tinsn; - fragS *fragP; - int slot; +tinsn_immed_from_frag (TInsn *tinsn, fragS *fragP, int slot) { xtensa_opcode opcode = tinsn->opcode; int opnum; @@ -12457,8 +11765,7 @@ tinsn_immed_from_frag (tinsn, fragP, slot) static int -get_num_stack_text_bytes (istack) - IStack *istack; +get_num_stack_text_bytes (IStack *istack) { int i; int text_bytes = 0; @@ -12474,8 +11781,7 @@ get_num_stack_text_bytes (istack) static int -get_num_stack_literal_bytes (istack) - IStack *istack; +get_num_stack_literal_bytes (IStack *istack) { int i; int lit_bytes = 0; @@ -12492,9 +11798,8 @@ get_num_stack_literal_bytes (istack) /* vliw_insn functions. */ -void -xg_init_vinsn (v) - vliw_insn *v; +static void +xg_init_vinsn (vliw_insn *v) { int i; xtensa_isa isa = xtensa_default_isa; @@ -12516,9 +11821,8 @@ xg_init_vinsn (v) } -void -xg_clear_vinsn (v) - vliw_insn *v; +static void +xg_clear_vinsn (vliw_insn *v) { int i; v->format = XTENSA_UNDEFINED; @@ -12536,9 +11840,8 @@ xg_clear_vinsn (v) } -bfd_boolean -vinsn_has_specific_opcodes (v) - vliw_insn *v; +static bfd_boolean +vinsn_has_specific_opcodes (vliw_insn *v) { int i; @@ -12551,9 +11854,8 @@ vinsn_has_specific_opcodes (v) } -void -xg_free_vinsn (v) - vliw_insn *v; +static void +xg_free_vinsn (vliw_insn *v) { int i; xtensa_insnbuf_free (xtensa_default_isa, v->insnbuf); @@ -12575,11 +11877,10 @@ xg_free_vinsn (v) The return value tells whether there are any remaining O_symbols. */ static bfd_boolean -vinsn_to_insnbuf (vinsn, frag_offset, fragP, record_fixup) - vliw_insn *vinsn; - char *frag_offset; - fragS *fragP; - bfd_boolean record_fixup; +vinsn_to_insnbuf (vliw_insn *vinsn, + char *frag_offset, + fragS *fragP, + bfd_boolean record_fixup) { xtensa_isa isa = xtensa_default_isa; xtensa_format fmt = vinsn->format; @@ -12675,9 +11976,7 @@ vinsn_to_insnbuf (vinsn, frag_offset, fragP, record_fixup) static void -vinsn_from_chars (vinsn, f) - vliw_insn *vinsn; - char *f; +vinsn_from_chars (vliw_insn *vinsn, char *f) { static xtensa_insnbuf insnbuf = NULL; static xtensa_insnbuf slotbuf = NULL; @@ -12712,8 +12011,7 @@ vinsn_from_chars (vinsn, f) /* Return TRUE if the expression is an integer constant. */ bfd_boolean -expr_is_const (s) - const expressionS *s; +expr_is_const (const expressionS *s) { return (s->X_op == O_constant); } @@ -12723,8 +12021,7 @@ expr_is_const (s) Calling this is illegal if expr_is_const () returns TRUE. */ offsetT -get_expr_const (s) - const expressionS *s; +get_expr_const (const expressionS *s) { assert (expr_is_const (s)); return s->X_add_number; @@ -12734,9 +12031,7 @@ get_expr_const (s) /* Set the expression to a constant value. */ void -set_expr_const (s, val) - expressionS *s; - offsetT val; +set_expr_const (expressionS *s, offsetT val) { s->X_op = O_constant; s->X_add_number = val; @@ -12746,8 +12041,7 @@ set_expr_const (s, val) bfd_boolean -expr_is_register (s) - const expressionS *s; +expr_is_register (const expressionS *s) { return (s->X_op == O_register); } @@ -12757,8 +12051,7 @@ expr_is_register (s) Calling this is illegal if expr_is_const () returns TRUE. */ offsetT -get_expr_register (s) - const expressionS *s; +get_expr_register (const expressionS *s) { assert (expr_is_register (s)); return s->X_add_number; @@ -12768,10 +12061,7 @@ get_expr_register (s) /* Set the expression to a symbol + constant offset. */ void -set_expr_symbol_offset (s, sym, offset) - expressionS *s; - symbolS *sym; - offsetT offset; +set_expr_symbol_offset (expressionS *s, symbolS *sym, offsetT offset) { s->X_op = O_symbol; s->X_add_symbol = sym; @@ -12782,12 +12072,11 @@ set_expr_symbol_offset (s, sym, offset) /* Set the expression to symbol - minus_sym + offset. */ -void -set_expr_symbol_offset_diff (s, sym, minus_sym, offset) - expressionS *s; - symbolS *sym; - symbolS *minus_sym; - offsetT offset; +static void +set_expr_symbol_offset_diff (expressionS *s, + symbolS *sym, + symbolS *minus_sym, + offsetT offset) { s->X_op = O_subtract; s->X_add_symbol = sym; @@ -12799,9 +12088,7 @@ set_expr_symbol_offset_diff (s, sym, minus_sym, offset) /* Return TRUE if the two expressions are equal. */ bfd_boolean -expr_is_equal (s1, s2) - expressionS *s1; - expressionS *s2; +expr_is_equal (expressionS *s1, expressionS *s2) { if (s1->X_op != s2->X_op) return FALSE; @@ -12816,9 +12103,7 @@ expr_is_equal (s1, s2) static void -copy_expr (dst, src) - expressionS *dst; - const expressionS *src; +copy_expr (expressionS *dst, const expressionS *src) { memcpy (dst, src, sizeof (expressionS)); } @@ -12841,9 +12126,8 @@ static struct rename_section_struct *section_rename; /* Parse the string oldname=new_name:oldname2=new_name2 and call add_section_rename. */ -void -build_section_rename (arg) - const char *arg; +static void +build_section_rename (const char *arg) { char *this_arg = NULL; char *next_arg = NULL; @@ -12883,9 +12167,7 @@ build_section_rename (arg) static void -add_section_rename (old_name, new_name) - char *old_name; - char *new_name; +add_section_rename (char *old_name, char *new_name) { struct rename_section_struct *r = section_rename; @@ -12910,8 +12192,7 @@ add_section_rename (old_name, new_name) const char * -xtensa_section_rename (name) - const char *name; +xtensa_section_rename (const char *name) { struct rename_section_struct *r = section_rename; diff --git a/gas/config/tc-xtensa.h b/gas/config/tc-xtensa.h index 3be75c7..0bd19a3 100644 --- a/gas/config/tc-xtensa.h +++ b/gas/config/tc-xtensa.h @@ -289,46 +289,29 @@ typedef struct xtensa_segment_info_struct /* Section renaming is only supported in Tensilica's version of GAS. */ #ifdef XTENSA_SECTION_RENAME -extern const char *xtensa_section_rename - PARAMS ((const char *)); +extern const char *xtensa_section_rename (const char *); #else /* Tensilica's section renaming feature is not included here. */ #define xtensa_section_rename(name) (name) #endif /* XTENSA_SECTION_RENAME */ -extern const char *xtensa_target_format - PARAMS ((void)); -extern void xtensa_init_fix_data - PARAMS ((struct fix *)); -extern void xtensa_frag_init - PARAMS ((fragS *)); -extern int xtensa_force_relocation - PARAMS ((struct fix *)); -extern void xtensa_frob_label - PARAMS ((struct symbol *)); -extern void xtensa_end - PARAMS ((void)); -extern void xtensa_post_relax_hook - PARAMS ((void)); -extern void xtensa_file_arch_init - PARAMS ((bfd *)); -extern void xtensa_flush_pending_output - PARAMS ((void)); -extern bfd_boolean xtensa_fix_adjustable - PARAMS ((struct fix *)); -extern void xtensa_symbol_new_hook - PARAMS ((symbolS *)); -extern long xtensa_relax_frag - PARAMS ((fragS *, long, int *)); -extern void xtensa_elf_section_change_hook - PARAMS ((void)); -extern int xtensa_unrecognized_line - PARAMS ((int)); -extern bfd_boolean xtensa_check_inside_bundle - PARAMS ((void)); -extern void xtensa_handle_align - PARAMS ((fragS *)); +extern const char *xtensa_target_format (void); +extern void xtensa_init_fix_data (struct fix *); +extern void xtensa_frag_init (fragS *); +extern int xtensa_force_relocation (struct fix *); +extern void xtensa_frob_label (struct symbol *); +extern void xtensa_end (void); +extern void xtensa_post_relax_hook (void); +extern void xtensa_file_arch_init (bfd *); +extern void xtensa_flush_pending_output (void); +extern bfd_boolean xtensa_fix_adjustable (struct fix *); +extern void xtensa_symbol_new_hook (symbolS *); +extern long xtensa_relax_frag (fragS *, long, int *); +extern void xtensa_elf_section_change_hook (void); +extern int xtensa_unrecognized_line (int); +extern bfd_boolean xtensa_check_inside_bundle (void); +extern void xtensa_handle_align (fragS *); #define TARGET_FORMAT xtensa_target_format () #define TARGET_ARCH bfd_arch_xtensa @@ -421,8 +404,8 @@ typedef int (*opcode_funcUnit_use_stage_func) (void *, xtensa_opcode, int); Of course the optional scheduler has its own reservation table and functions. */ -int opcode_funcUnit_use_unit PARAMS ((void *, xtensa_opcode, int)); -int opcode_funcUnit_use_stage PARAMS ((void *, xtensa_opcode, int)); +int opcode_funcUnit_use_unit (void *, xtensa_opcode, int); +int opcode_funcUnit_use_stage (void *, xtensa_opcode, int); typedef struct { @@ -438,13 +421,12 @@ typedef struct } resource_table; resource_table *new_resource_table - PARAMS ((void *, int, int, unit_num_copies_func, opcode_num_units_func, - opcode_funcUnit_use_unit_func, opcode_funcUnit_use_stage_func)); -void resize_resource_table PARAMS ((resource_table *, int)); -void clear_resource_table PARAMS ((resource_table *)); -bfd_boolean resources_available - PARAMS ((resource_table *, xtensa_opcode, int)); -void reserve_resources PARAMS ((resource_table *, xtensa_opcode, int)); -void release_resources PARAMS ((resource_table *, xtensa_opcode, int)); + (void *, int, int, unit_num_copies_func, opcode_num_units_func, + opcode_funcUnit_use_unit_func, opcode_funcUnit_use_stage_func); +void resize_resource_table (resource_table *, int); +void clear_resource_table (resource_table *); +bfd_boolean resources_available (resource_table *, xtensa_opcode, int); +void reserve_resources (resource_table *, xtensa_opcode, int); +void release_resources (resource_table *, xtensa_opcode, int); #endif /* TC_XTENSA */ diff --git a/gas/config/xtensa-istack.h b/gas/config/xtensa-istack.h index bb9f989..47082a9 100644 --- a/gas/config/xtensa-istack.h +++ b/gas/config/xtensa-istack.h @@ -72,17 +72,17 @@ typedef struct tinsn_stack } IStack; -void istack_init PARAMS ((IStack *)); -bfd_boolean istack_empty PARAMS ((IStack *)); -bfd_boolean istack_full PARAMS ((IStack *)); -TInsn *istack_top PARAMS ((IStack *)); -void istack_push PARAMS ((IStack *, TInsn *)); -TInsn *istack_push_space PARAMS ((IStack *)); -void istack_pop PARAMS ((IStack *)); +void istack_init (IStack *); +bfd_boolean istack_empty (IStack *); +bfd_boolean istack_full (IStack *); +TInsn *istack_top (IStack *); +void istack_push (IStack *, TInsn *); +TInsn *istack_push_space (IStack *); +void istack_pop (IStack *); /* TInsn utilities. */ -void tinsn_init PARAMS ((TInsn *)); -expressionS *tinsn_get_tok PARAMS ((TInsn *, int)); +void tinsn_init (TInsn *); +expressionS *tinsn_get_tok (TInsn *, int); /* vliw_insn: bundles of TInsns. */ diff --git a/gas/config/xtensa-relax.c b/gas/config/xtensa-relax.c index 4d2d01a..d54a55c 100644 --- a/gas/config/xtensa-relax.c +++ b/gas/config/xtensa-relax.c @@ -442,148 +442,17 @@ string_pattern_pair simplify_spec_list[] = (sizeof (simplify_spec_list) / sizeof (string_pattern_pair)) -/* Transition generation helpers. */ - -static void append_transition - PARAMS ((TransitionTable *, xtensa_opcode, TransitionRule *, - transition_cmp_fn)); -static void append_condition - PARAMS ((TransitionRule *, Precondition *)); -static void append_value_condition - PARAMS ((TransitionRule *, CmpOp, unsigned, unsigned)); -static void append_constant_value_condition - PARAMS ((TransitionRule *, CmpOp, unsigned, unsigned)); -static void append_build_insn - PARAMS ((TransitionRule *, BuildInstr *)); -static void append_op - PARAMS ((BuildInstr *, BuildOp *)); -static void append_literal_op - PARAMS ((BuildInstr *, unsigned, unsigned)); -static void append_label_op - PARAMS ((BuildInstr *, unsigned, unsigned)); -static void append_constant_op - PARAMS ((BuildInstr *, unsigned, unsigned)); -static void append_field_op - PARAMS ((BuildInstr *, unsigned, unsigned)); -static void append_user_fn_field_op - PARAMS ((BuildInstr *, unsigned, OpType, unsigned)); -static long operand_function_HI24S - PARAMS ((long)); -static long operand_function_F32MINUS - PARAMS ((long)); -static long operand_function_LOW8 - PARAMS ((long)); -static long operand_function_LOW16U - PARAMS ((long)); -static long operand_function_HI16U - PARAMS ((long)); - /* Externally visible functions. */ -extern bfd_boolean xg_has_userdef_op_fn - PARAMS ((OpType)); -extern long xg_apply_userdef_op_fn - PARAMS ((OpType, long)); - -/* Parsing helpers. */ - -static const char *enter_opname_n - PARAMS ((const char *, int)); -static const char *enter_opname - PARAMS ((const char *)); - -/* Construction and destruction. */ - -static void init_opname_map - PARAMS ((opname_map *)); -static void clear_opname_map - PARAMS ((opname_map *)); -static void init_precond_list - PARAMS ((precond_list *)); -static void clear_precond_list - PARAMS ((precond_list *)); -static void init_insn_templ - PARAMS ((insn_templ *)); -static void clear_insn_templ - PARAMS ((insn_templ *)); -static void init_insn_pattern - PARAMS ((insn_pattern *)); -static void clear_insn_pattern - PARAMS ((insn_pattern *)); -static void init_insn_repl - PARAMS ((insn_repl *)); -static void clear_insn_repl - PARAMS ((insn_repl *)); -static void init_split_rec - PARAMS ((split_rec *)); -static void clear_split_rec - PARAMS ((split_rec *)); -static void clear_req_or_option_list - PARAMS ((ReqOrOption **)); -static void clear_req_option_list - PARAMS ((ReqOption **)); -static ReqOrOption *clone_req_or_option_list - PARAMS ((ReqOrOption *)); -static ReqOption *clone_req_option_list - PARAMS ((ReqOption *)); - -/* Operand and insn_templ helpers. */ - -static bfd_boolean same_operand_name - PARAMS ((const opname_map_e *, const opname_map_e *)); -static opname_map_e *get_opmatch - PARAMS ((opname_map *, const char *)); -static bfd_boolean op_is_constant - PARAMS ((const opname_map_e *)); -static unsigned op_get_constant - PARAMS ((const opname_map_e *)); -static int insn_templ_operand_count - PARAMS ((const insn_templ *)); - -/* Parsing helpers. */ - -static const char *skip_white - PARAMS ((const char *)); -static void trim_whitespace - PARAMS ((char *)); -static void split_string - PARAMS ((split_rec *, const char *, char, bfd_boolean)); - -/* Language parsing. */ - -static bfd_boolean parse_insn_pattern - PARAMS ((const char *, insn_pattern *)); -static bfd_boolean parse_insn_repl - PARAMS ((const char *, insn_repl *)); -static bfd_boolean parse_insn_templ - PARAMS ((const char *, insn_templ *)); -static bfd_boolean parse_special_fn - PARAMS ((const char *, const char **, const char **)); -static bfd_boolean parse_precond - PARAMS ((const char *, precond_e *)); -static bfd_boolean parse_constant - PARAMS ((const char *, unsigned *)); -static bfd_boolean parse_id_constant - PARAMS ((const char *, const char *, unsigned *)); -static bfd_boolean parse_option_cond - PARAMS ((const char *, ReqOption *)); - -/* Transition table building code. */ - -static bfd_boolean transition_applies - PARAMS ((insn_pattern *, const char *, const char *)); -static TransitionRule *build_transition - PARAMS ((insn_pattern *, insn_repl *, const char *, const char *)); -static TransitionTable *build_transition_table - PARAMS ((const string_pattern_pair *, int, transition_cmp_fn)); +extern bfd_boolean xg_has_userdef_op_fn (OpType); +extern long xg_apply_userdef_op_fn (OpType, long); - -void -append_transition (tt, opcode, t, cmp) - TransitionTable *tt; - xtensa_opcode opcode; - TransitionRule *t; - transition_cmp_fn cmp; + +static void +append_transition (TransitionTable *tt, + xtensa_opcode opcode, + TransitionRule *t, + transition_cmp_fn cmp) { TransitionList *tl = (TransitionList *) xmalloc (sizeof (TransitionList)); TransitionList *prev; @@ -614,10 +483,8 @@ append_transition (tt, opcode, t, cmp) } -void -append_condition (tr, cond) - TransitionRule *tr; - Precondition *cond; +static void +append_condition (TransitionRule *tr, Precondition *cond) { PreconditionList *pl = (PreconditionList *) xmalloc (sizeof (PreconditionList)); @@ -641,12 +508,11 @@ append_condition (tr, cond) } -void -append_value_condition (tr, cmp, op1, op2) - TransitionRule *tr; - CmpOp cmp; - unsigned op1; - unsigned op2; +static void +append_value_condition (TransitionRule *tr, + CmpOp cmp, + unsigned op1, + unsigned op2) { Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition)); @@ -658,12 +524,11 @@ append_value_condition (tr, cmp, op1, op2) } -void -append_constant_value_condition (tr, cmp, op1, cnst) - TransitionRule *tr; - CmpOp cmp; - unsigned op1; - unsigned cnst; +static void +append_constant_value_condition (TransitionRule *tr, + CmpOp cmp, + unsigned op1, + unsigned cnst) { Precondition *cond = (Precondition *) xmalloc (sizeof (Precondition)); @@ -675,10 +540,8 @@ append_constant_value_condition (tr, cmp, op1, cnst) } -void -append_build_insn (tr, bi) - TransitionRule *tr; - BuildInstr *bi; +static void +append_build_insn (TransitionRule *tr, BuildInstr *bi) { BuildInstr *prev = tr->to_instr; BuildInstr *nxt; @@ -699,10 +562,8 @@ append_build_insn (tr, bi) } -void -append_op (bi, b_op) - BuildInstr *bi; - BuildOp *b_op; +static void +append_op (BuildInstr *bi, BuildOp *b_op) { BuildOp *prev = bi->ops; BuildOp *nxt; @@ -722,11 +583,8 @@ append_op (bi, b_op) } -void -append_literal_op (bi, op1, litnum) - BuildInstr *bi; - unsigned op1; - unsigned litnum; +static void +append_literal_op (BuildInstr *bi, unsigned op1, unsigned litnum) { BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp)); @@ -738,11 +596,8 @@ append_literal_op (bi, op1, litnum) } -void -append_label_op (bi, op1, labnum) - BuildInstr *bi; - unsigned op1; - unsigned labnum; +static void +append_label_op (BuildInstr *bi, unsigned op1, unsigned labnum) { BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp)); @@ -754,11 +609,8 @@ append_label_op (bi, op1, labnum) } -void -append_constant_op (bi, op1, cnst) - BuildInstr *bi; - unsigned op1; - unsigned cnst; +static void +append_constant_op (BuildInstr *bi, unsigned op1, unsigned cnst) { BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp)); @@ -770,11 +622,8 @@ append_constant_op (bi, op1, cnst) } -void -append_field_op (bi, op1, src_op) - BuildInstr *bi; - unsigned op1; - unsigned src_op; +static void +append_field_op (BuildInstr *bi, unsigned op1, unsigned src_op) { BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp)); @@ -788,12 +637,11 @@ append_field_op (bi, op1, src_op) /* These could be generated but are not currently. */ -void -append_user_fn_field_op (bi, op1, typ, src_op) - BuildInstr *bi; - unsigned op1; - OpType typ; - unsigned src_op; +static void +append_user_fn_field_op (BuildInstr *bi, + unsigned op1, + OpType typ, + unsigned src_op) { BuildOp *b_op = (BuildOp *) xmalloc (sizeof (BuildOp)); @@ -808,9 +656,8 @@ append_user_fn_field_op (bi, op1, typ, src_op) /* These operand functions are the semantics of user-defined operand functions. */ -long -operand_function_HI24S (a) - long a; +static long +operand_function_HI24S (long a) { if (a & 0x80) return (a & (~0xff)) + 0x100; @@ -819,17 +666,15 @@ operand_function_HI24S (a) } -long -operand_function_F32MINUS (a) - long a; +static long +operand_function_F32MINUS (long a) { return (32 - a); } -long -operand_function_LOW8 (a) - long a; +static long +operand_function_LOW8 (long a) { if (a & 0x80) return (a & 0xff) | ~0xff; @@ -838,17 +683,15 @@ operand_function_LOW8 (a) } -long -operand_function_LOW16U (a) - long a; +static long +operand_function_LOW16U (long a) { return (a & 0xffff); } -long -operand_function_HI16U (a) - long a; +static long +operand_function_HI16U (long a) { unsigned long b = a & 0xffff0000; return (long) (b >> 16); @@ -856,8 +699,7 @@ operand_function_HI16U (a) bfd_boolean -xg_has_userdef_op_fn (op) - OpType op; +xg_has_userdef_op_fn (OpType op) { switch (op) { @@ -875,9 +717,7 @@ xg_has_userdef_op_fn (op) long -xg_apply_userdef_op_fn (op, a) - OpType op; - long a; +xg_apply_userdef_op_fn (OpType op, long a) { switch (op) { @@ -900,10 +740,8 @@ xg_apply_userdef_op_fn (op, a) /* Generate a transition table. */ -const char * -enter_opname_n (name, len) - const char *name; - int len; +static const char * +enter_opname_n (const char *name, int len) { opname_e *op; @@ -922,8 +760,7 @@ enter_opname_n (name, len) static const char * -enter_opname (name) - const char *name; +enter_opname (const char *name) { opname_e *op; @@ -938,18 +775,16 @@ enter_opname (name) } -void -init_opname_map (m) - opname_map *m; +static void +init_opname_map (opname_map *m) { m->head = NULL; m->tail = &m->head; } -void -clear_opname_map (m) - opname_map *m; +static void +clear_opname_map (opname_map *m) { opname_map_e *e; @@ -964,9 +799,7 @@ clear_opname_map (m) static bfd_boolean -same_operand_name (m1, m2) - const opname_map_e *m1; - const opname_map_e *m2; +same_operand_name (const opname_map_e *m1, const opname_map_e *m2) { if (m1->operand_name == NULL || m1->operand_name == NULL) return FALSE; @@ -974,10 +807,8 @@ same_operand_name (m1, m2) } -opname_map_e * -get_opmatch (map, operand_name) - opname_map *map; - const char *operand_name; +static opname_map_e * +get_opmatch (opname_map *map, const char *operand_name) { opname_map_e *m; @@ -990,35 +821,31 @@ get_opmatch (map, operand_name) } -bfd_boolean -op_is_constant (m1) - const opname_map_e *m1; +static bfd_boolean +op_is_constant (const opname_map_e *m1) { return (m1->operand_name == NULL); } static unsigned -op_get_constant (m1) - const opname_map_e *m1; +op_get_constant (const opname_map_e *m1) { assert (m1->operand_name == NULL); return m1->constant_value; } -void -init_precond_list (l) - precond_list *l; +static void +init_precond_list (precond_list *l) { l->head = NULL; l->tail = &l->head; } -void -clear_precond_list (l) - precond_list *l; +static void +clear_precond_list (precond_list *l) { precond_e *e; @@ -1032,26 +859,23 @@ clear_precond_list (l) } -void -init_insn_templ (t) - insn_templ *t; +static void +init_insn_templ (insn_templ *t) { t->opcode_name = NULL; init_opname_map (&t->operand_map); } -void -clear_insn_templ (t) - insn_templ *t; +static void +clear_insn_templ (insn_templ *t) { clear_opname_map (&t->operand_map); } -void -init_insn_pattern (p) - insn_pattern *p; +static void +init_insn_pattern (insn_pattern *p) { init_insn_templ (&p->t); init_precond_list (&p->preconds); @@ -1059,27 +883,24 @@ init_insn_pattern (p) } -void -clear_insn_pattern (p) - insn_pattern *p; +static void +clear_insn_pattern (insn_pattern *p) { clear_insn_templ (&p->t); clear_precond_list (&p->preconds); } -void -init_insn_repl (r) - insn_repl *r; +static void +init_insn_repl (insn_repl *r) { r->head = NULL; r->tail = &r->head; } -void -clear_insn_repl (r) - insn_repl *r; +static void +clear_insn_repl (insn_repl *r) { insn_repl_e *e; @@ -1094,8 +915,7 @@ clear_insn_repl (r) static int -insn_templ_operand_count (t) - const insn_templ *t; +insn_templ_operand_count (const insn_templ *t) { int i = 0; const opname_map_e *op; @@ -1108,10 +928,8 @@ insn_templ_operand_count (t) /* Convert a string to a number. E.G.: parse_constant("10", &num) */ -bfd_boolean -parse_constant (in, val_p) - const char *in; - unsigned *val_p; +static bfd_boolean +parse_constant (const char *in, unsigned *val_p) { unsigned val = 0; const char *p; @@ -1137,11 +955,8 @@ parse_constant (in, val_p) parse_id_constant("foo1", "foo", &num). This may also be used to just match a number. */ -bfd_boolean -parse_id_constant (in, name, val_p) - const char *in; - const char *name; - unsigned *val_p; +static bfd_boolean +parse_id_constant (const char *in, const char *name, unsigned *val_p) { unsigned namelen = 0; const char *p; @@ -1161,10 +976,9 @@ parse_id_constant (in, name, val_p) static bfd_boolean -parse_special_fn (name, fn_name_p, arg_name_p) - const char *name; - const char **fn_name_p; - const char **arg_name_p; +parse_special_fn (const char *name, + const char **fn_name_p, + const char **arg_name_p) { char *p_start; const char *p_end; @@ -1187,9 +1001,8 @@ parse_special_fn (name, fn_name_p, arg_name_p) } -const char * -skip_white (p) - const char *p; +static const char * +skip_white (const char *p) { if (p == NULL) return p; @@ -1199,9 +1012,8 @@ skip_white (p) } -void -trim_whitespace (in) - char *in; +static void +trim_whitespace (char *in) { char *last_white = NULL; char *p = in; @@ -1228,12 +1040,11 @@ trim_whitespace (in) /* Split a string into component strings where "c" is the delimiter. Place the result in the split_rec. */ -void -split_string (rec, in, c, elide_whitespace) - split_rec *rec; - const char *in; - char c; - bfd_boolean elide_whitespace; +static void +split_string (split_rec *rec, + const char *in, + char c, + bfd_boolean elide_whitespace) { int cnt = 0; int i; @@ -1284,9 +1095,8 @@ split_string (rec, in, c, elide_whitespace) } -void -clear_split_rec (rec) - split_rec *rec; +static void +clear_split_rec (split_rec *rec) { int i; @@ -1301,9 +1111,8 @@ clear_split_rec (rec) /* Initialize a split record. The split record must be initialized before split_string is called. */ -void -init_split_rec (rec) - split_rec *rec; +static void +init_split_rec (split_rec *rec) { rec->vec = NULL; rec->count = 0; @@ -1312,10 +1121,8 @@ init_split_rec (rec) /* Parse an instruction template like "insn op1, op2, op3". */ -bfd_boolean -parse_insn_templ (s, t) - const char *s; - insn_templ *t; +static bfd_boolean +parse_insn_templ (const char *s, insn_templ *t) { const char *p = s; int insn_name_len; @@ -1374,10 +1181,8 @@ parse_insn_templ (s, t) } -bfd_boolean -parse_precond (s, precond) - const char *s; - precond_e *precond; +static bfd_boolean +parse_precond (const char *s, precond_e *precond) { /* All preconditions are currently of the form: a == b or a != b or a == k (where k is a constant). @@ -1430,9 +1235,8 @@ parse_precond (s, precond) } -void -clear_req_or_option_list (r_p) - ReqOrOption **r_p; +static void +clear_req_or_option_list (ReqOrOption **r_p) { if (*r_p == NULL) return; @@ -1443,9 +1247,8 @@ clear_req_or_option_list (r_p) } -void -clear_req_option_list (r_p) - ReqOption **r_p; +static void +clear_req_option_list (ReqOption **r_p) { if (*r_p == NULL) return; @@ -1456,9 +1259,8 @@ clear_req_option_list (r_p) } -ReqOrOption * -clone_req_or_option_list (req_or_option) - ReqOrOption *req_or_option; +static ReqOrOption * +clone_req_or_option_list (ReqOrOption *req_or_option) { ReqOrOption *new_req_or_option; @@ -1474,9 +1276,8 @@ clone_req_or_option_list (req_or_option) } -ReqOption * -clone_req_option_list (req_option) - ReqOption *req_option; +static ReqOption * +clone_req_option_list (ReqOption *req_option) { ReqOption *new_req_option; @@ -1493,10 +1294,8 @@ clone_req_option_list (req_option) } -bfd_boolean -parse_option_cond (s, option) - const char *s; - ReqOption *option; +static bfd_boolean +parse_option_cond (const char *s, ReqOption *option) { int i; split_rec option_term_rec; @@ -1560,10 +1359,8 @@ parse_option_cond (s, option) split_string, it requires that '|' and '?' are only used as delimiters for predicates and required options. */ -bfd_boolean -parse_insn_pattern (in, insn) - const char *in; - insn_pattern *insn; +static bfd_boolean +parse_insn_pattern (const char *in, insn_pattern *insn) { split_rec rec; split_rec optionrec; @@ -1644,10 +1441,8 @@ parse_insn_pattern (in, insn) } -bfd_boolean -parse_insn_repl (in, r_p) - const char *in; - insn_repl *r_p; +static bfd_boolean +parse_insn_repl (const char *in, insn_repl *r_p) { /* This is a list of instruction templates separated by ';'. */ split_rec rec; @@ -1674,11 +1469,10 @@ parse_insn_repl (in, r_p) } -bfd_boolean -transition_applies (initial_insn, from_string, to_string) - insn_pattern *initial_insn; - const char *from_string ATTRIBUTE_UNUSED; - const char *to_string ATTRIBUTE_UNUSED; +static bfd_boolean +transition_applies (insn_pattern *initial_insn, + const char *from_string ATTRIBUTE_UNUSED, + const char *to_string ATTRIBUTE_UNUSED) { ReqOption *req_option; @@ -1727,12 +1521,11 @@ transition_applies (initial_insn, from_string, to_string) } -TransitionRule * -build_transition (initial_insn, replace_insns, from_string, to_string) - insn_pattern *initial_insn; - insn_repl *replace_insns; - const char *from_string; - const char *to_string; +static TransitionRule * +build_transition (insn_pattern *initial_insn, + insn_repl *replace_insns, + const char *from_string, + const char *to_string) { TransitionRule *tr = NULL; xtensa_opcode opcode; @@ -2019,11 +1812,10 @@ build_transition (initial_insn, replace_insns, from_string, to_string) } -TransitionTable * -build_transition_table (transitions, transition_count, cmp) - const string_pattern_pair *transitions; - int transition_count; - transition_cmp_fn cmp; +static TransitionTable * +build_transition_table (const string_pattern_pair *transitions, + int transition_count, + transition_cmp_fn cmp) { TransitionTable *table = NULL; int num_opcodes = xtensa_isa_num_opcodes (xtensa_default_isa); @@ -2090,8 +1882,7 @@ build_transition_table (transitions, transition_count, cmp) extern TransitionTable * -xg_build_widen_table (cmp) - transition_cmp_fn cmp; +xg_build_widen_table (transition_cmp_fn cmp) { static TransitionTable *table = NULL; if (table == NULL) @@ -2101,8 +1892,7 @@ xg_build_widen_table (cmp) extern TransitionTable * -xg_build_simplify_table (cmp) - transition_cmp_fn cmp; +xg_build_simplify_table (transition_cmp_fn cmp) { static TransitionTable *table = NULL; if (table == NULL) diff --git a/gas/config/xtensa-relax.h b/gas/config/xtensa-relax.h index 2a228bc..31fa8b0 100644 --- a/gas/config/xtensa-relax.h +++ b/gas/config/xtensa-relax.h @@ -173,10 +173,10 @@ struct transition_rule typedef int (*transition_cmp_fn) (const TransitionRule *, const TransitionRule *); -extern TransitionTable *xg_build_simplify_table PARAMS ((transition_cmp_fn)); -extern TransitionTable *xg_build_widen_table PARAMS ((transition_cmp_fn)); +extern TransitionTable *xg_build_simplify_table (transition_cmp_fn); +extern TransitionTable *xg_build_widen_table (transition_cmp_fn); -extern bfd_boolean xg_has_userdef_op_fn PARAMS ((OpType)); -extern long xg_apply_userdef_op_fn PARAMS ((OpType, long)); +extern bfd_boolean xg_has_userdef_op_fn (OpType); +extern long xg_apply_userdef_op_fn (OpType, long); #endif /* !XTENSA_RELAX_H */ diff --git a/ld/ChangeLog b/ld/ChangeLog index 1058f03..d6b409d 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,7 @@ +2004-10-12 Bob Wilson <bob.wilson@acm.org> + + * emultempl/xtensaelf.em: Use ISO C90 formatting. + 2004-10-11 Jakub Jelinek <jakub@redhat.com> * emultempl/elf32.em (gld${EMULATION_NAME}_parse_ld_so_conf): Avoid diff --git a/ld/emultempl/xtensaelf.em b/ld/emultempl/xtensaelf.em index 386bf8a..b29ec49 100644 --- a/ld/emultempl/xtensaelf.em +++ b/ld/emultempl/xtensaelf.em @@ -32,10 +32,6 @@ cat >>e${EMULATION_NAME}.c <<EOF static void xtensa_wild_group_interleave (lang_statement_union_type *); static void xtensa_colocate_output_literals (lang_statement_union_type *); -static void remove_section (bfd *, asection *); -static bfd_boolean replace_insn_sec_with_prop_sec (bfd *, const char *, - const char *, char **); -static void replace_instruction_table_sections (bfd *, asection *); /* Flag for the emulation-specific "--no-relax" option. */ @@ -82,10 +78,8 @@ elf_xtensa_before_parse (void) } -void -remove_section (abfd, os) - bfd *abfd; - asection *os; +static void +remove_section (bfd *abfd, asection *os) { asection **spp; for (spp = &abfd->sections; *spp; spp = &(*spp)->next) @@ -98,13 +92,11 @@ remove_section (abfd, os) } -bfd_boolean -replace_insn_sec_with_prop_sec (abfd, insn_sec_name, prop_sec_name, - error_message) - bfd *abfd; - const char *insn_sec_name; - const char *prop_sec_name; - char **error_message; +static bfd_boolean +replace_insn_sec_with_prop_sec (bfd *abfd, + const char *insn_sec_name, + const char *prop_sec_name, + char **error_message) { asection *insn_sec; asection *prop_sec; @@ -269,10 +261,8 @@ replace_insn_sec_with_prop_sec (abfd, insn_sec_name, prop_sec_name, #define LINKONCE_SEC_OLD_TEXT_BASE_NAME ".gnu.linkonce.x." -void -replace_instruction_table_sections (abfd, sec) - bfd *abfd; - asection *sec; +static void +replace_instruction_table_sections (bfd *abfd, asection *sec) { char *message = ""; const char *insn_sec_name = NULL; @@ -445,8 +435,7 @@ typedef void (*deps_callback_t) (asection *, /* src_sec */ extern bfd_boolean xtensa_callback_required_dependence (bfd *, asection *, struct bfd_link_info *, deps_callback_t, void *); -static void xtensa_ldlang_clear_addresses - (lang_statement_union_type *); +static void xtensa_ldlang_clear_addresses (lang_statement_union_type *); static bfd_boolean ld_local_file_relocations_fit (lang_statement_union_type *, const reloc_deps_graph *); static bfd_vma ld_assign_relative_paged_dot @@ -455,8 +444,7 @@ static bfd_vma ld_assign_relative_paged_dot static bfd_vma ld_xtensa_insert_page_offsets (bfd_vma, lang_statement_union_type *, reloc_deps_graph *, bfd_boolean); #if EXTRA_VALIDATION -static size_t ld_count_children - (lang_statement_union_type *); +static size_t ld_count_children (lang_statement_union_type *); #endif extern lang_statement_list_type constructor_list; @@ -634,6 +622,7 @@ section_is_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, return sec_deps && sec_deps->preds != NULL; } + static bfd_boolean section_is_source_or_target (const reloc_deps_graph *deps ATTRIBUTE_UNUSED, lang_statement_union_type *s) @@ -860,8 +849,7 @@ iter_stack_create (xtensa_ld_iter_stack **stack_p, static void -iter_stack_copy_current (xtensa_ld_iter_stack **stack_p, - xtensa_ld_iter *front) +iter_stack_copy_current (xtensa_ld_iter_stack **stack_p, xtensa_ld_iter *front) { *front = (*stack_p)->iterloc; } @@ -1027,9 +1015,7 @@ xtensa_move_dependencies_to_front (reloc_deps_graph *deps, static bfd_boolean -deps_has_sec_edge (const reloc_deps_graph *deps, - asection *src, - asection *tgt) +deps_has_sec_edge (const reloc_deps_graph *deps, asection *src, asection *tgt) { const reloc_deps_section *sec_deps; const reloc_deps_e *sec_deps_e; @@ -1071,9 +1057,7 @@ deps_has_edge (const reloc_deps_graph *deps, static void -add_deps_edge (reloc_deps_graph *deps, - asection *src_sec, - asection *tgt_sec) +add_deps_edge (reloc_deps_graph *deps, asection *src_sec, asection *tgt_sec) { reloc_deps_section *src_sec_deps; reloc_deps_section *tgt_sec_deps; @@ -1295,8 +1279,7 @@ xtensa_wild_group_interleave (lang_statement_union_type *s) static void -xtensa_layout_wild (const reloc_deps_graph *deps, - lang_wild_statement_type *w) +xtensa_layout_wild (const reloc_deps_graph *deps, lang_wild_statement_type *w) { /* If it does not fit initially, we need to do this step. Move all of the wild literal sections to a new list, then move each of diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 3b5f4fa..ad47507 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,7 @@ +2004-10-12 Bob Wilson <bob.wilson@acm.org> + + * xtensa-dis.c: Use ISO C90 formatting. + 2004-10-09 Alan Modra <amodra@bigpond.net.au> * ppc-opc.c: Revert 2004-09-09 change. diff --git a/opcodes/xtensa-dis.c b/opcodes/xtensa-dis.c index d7554a7..16fc4a9 100644 --- a/opcodes/xtensa-dis.c +++ b/opcodes/xtensa-dis.c @@ -39,11 +39,6 @@ extern xtensa_isa xtensa_default_isa; int show_raw_fields; -static int fetch_data - PARAMS ((struct disassemble_info *, bfd_vma)); -static void print_xtensa_operand - PARAMS ((bfd_vma, struct disassemble_info *, xtensa_opcode, int, unsigned)); - struct dis_private { bfd_byte *byte_buf; @@ -52,9 +47,7 @@ struct dis_private static int -fetch_data (info, memaddr) - struct disassemble_info *info; - bfd_vma memaddr; +fetch_data (struct disassemble_info *info, bfd_vma memaddr) { int length, status = 0; struct dis_private *priv = (struct dis_private *) info->private_data; @@ -79,12 +72,11 @@ fetch_data (info, memaddr) static void -print_xtensa_operand (memaddr, info, opc, opnd, operand_val) - bfd_vma memaddr; - struct disassemble_info *info; - xtensa_opcode opc; - int opnd; - unsigned operand_val; +print_xtensa_operand (bfd_vma memaddr, + struct disassemble_info *info, + xtensa_opcode opc, + int opnd, + unsigned operand_val) { xtensa_isa isa = xtensa_default_isa; int signed_operand_val; @@ -141,9 +133,7 @@ print_xtensa_operand (memaddr, info, opc, opnd, operand_val) Returns length of the instruction in bytes. */ int -print_insn_xtensa (memaddr, info) - bfd_vma memaddr; - struct disassemble_info *info; +print_insn_xtensa (bfd_vma memaddr, struct disassemble_info *info) { unsigned operand_val; int bytes_fetched, size, maxsize, i, n, noperands, nslots; @@ -184,7 +174,7 @@ print_insn_xtensa (memaddr, info) priv.byte_buf = byte_buf; - info->private_data = (PTR) &priv; + info->private_data = (void *) &priv; if (setjmp (priv.bailout) != 0) /* Error return. */ return -1; |