#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.
#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)
{
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);
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
\f
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;
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;
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;
}
-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;
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;
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;
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. */
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))
{
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;
/* 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;
static bfd_boolean
-add_extra_plt_sections (dynobj, count)
- bfd *dynobj;
- int count;
+add_extra_plt_sections (bfd *dynobj, int count)
{
int chunk;
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);
}
-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;
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;
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;
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;
/* 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;
/* 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. */
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
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.
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;
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;
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. */
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;
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;
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;
/* 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;
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;
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");
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
{
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)
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;
/* 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;
{
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,
}
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;
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;
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);
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;
/* 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;
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;
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))
{
\f
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;
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;
static bfd_boolean
-elf_xtensa_ignore_discarded_relocs (sec)
- asection *sec;
+elf_xtensa_ignore_discarded_relocs (asection *sec)
{
return xtensa_is_property_section (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;
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)
{
static xtensa_opcode call12_op = XTENSA_UNDEFINED;
static void
-init_call_opcodes ()
+init_call_opcodes (void)
{
if (callx0_op == XTENSA_UNDEFINED)
{
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
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
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
static bfd_vma
-l32r_offset (addr, pc)
- bfd_vma addr;
- bfd_vma pc;
+l32r_offset (bfd_vma addr, bfd_vma pc)
{
bfd_vma offset;
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;
int
-get_relocation_slot (r_type)
- int r_type;
+get_relocation_slot (int r_type)
{
switch (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;
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)))
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;
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);
bfd_boolean
-is_operand_relocation (r_type)
- int r_type;
+is_operand_relocation (int r_type)
{
switch (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;
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;
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)
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 =
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);
\f
/* 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
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" },
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;
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;
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);
-}
-
\f
/* 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;
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,
static xtensa_opcode
-swap_callx_for_call_opcode (opcode)
- xtensa_opcode opcode;
+swap_callx_for_call_opcode (xtensa_opcode opcode)
{
init_call_opcodes ();
#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;
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
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;
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);
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);
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)
}
+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))
{
};
-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;
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;
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;
};
-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;
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;
#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;
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);
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;
/* 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;
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;
};
-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;
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,
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);
}
-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;
}
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;
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,
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;
}
-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;
}
-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;
/* 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)
#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;
};
-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;
}
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;
}
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)
#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;
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);
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);
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;
-}
-
\f
/* Coalescing literals may require a relocation to refer to a section in
a different input file, but the standard relocation information
};
-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;
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;
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;
static void
-cache_fix_array (sec)
- asection *sec;
+cache_fix_array (asection *sec)
{
unsigned i, count = 0;
reloc_bfd_fix *r;
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;
};
-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;
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));
- }
-}
-
\f
/* Extended basic blocks. */
};
-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;
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;
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;
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;
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;
}
+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;
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)
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;
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;
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)
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;
{
if (!bfd_malloc_and_get_section (abfd, sec, &contents))
{
- if (contents != NULL)
+ if (contents)
free (contents);
return NULL;
}
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);
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;
/* 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;
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;
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;
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;
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;
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;
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;
}
#if DEBUG
- if (relax_info->action_list.head != NULL)
+ if (relax_info->action_list.head)
print_action_list (stderr, &relax_info->action_list);
#endif
/* 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;
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;
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;
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;
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;
int
-compute_fill_extra_space (entry)
- property_table_entry *entry;
+compute_fill_extra_space (property_table_entry *entry)
{
int fill_extra_space;
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;
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;
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)
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;
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;
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;
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;
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;
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;
static bfd_boolean
-translate_section_fixes (sec)
- asection *sec;
+translate_section_fixes (asection *sec)
{
xtensa_relax_info *relax_info;
reloc_bfd_fix *r;
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;
/* 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;
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;
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;
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;
/* 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;
/* "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;
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);
/* 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];
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];
. 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;
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;
/* 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;
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;
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;
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
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;
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;
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;
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)
{
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.",
/* 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;
/* 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;
#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
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,
/* 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 },
{ "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 },
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 },
int
-md_parse_option (c, arg)
- int c;
- char *arg;
+md_parse_option (int c, char *arg)
{
switch (c)
{
void
-md_show_usage (stream)
- FILE *stream;
+md_show_usage (FILE *stream)
{
fputs ("\n\
Xtensa options:\n\
, stream);
}
+\f
+/* 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);
+ }
}
}
};
-bfd_boolean
-use_transform ()
+static bfd_boolean
+use_transform (void)
{
/* After md_end, you should be checking frag by frag, rather
than state directives. */
}
-bfd_boolean
-use_longcalls ()
+static bfd_boolean
+use_longcalls (void)
{
/* After md_end, you should be checking frag by frag, rather
than state directives. */
}
-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. */
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;
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;
static void
-directive_balance ()
+directive_balance (void)
{
while (directive_state_stack)
{
static bfd_boolean
-inside_directive (dir)
- directiveE dir;
+inside_directive (directiveE dir)
{
state_stackS *top = directive_state_stack;
static void
-get_directive (directive, negated)
- directiveE *directive;
- bfd_boolean *negated;
+get_directive (directiveE *directive, bfd_boolean *negated)
{
int len;
unsigned i;
static void
-xtensa_begin_directive (ignore)
- int ignore ATTRIBUTE_UNUSED;
+xtensa_begin_directive (int ignore ATTRIBUTE_UNUSED)
{
directiveE directive;
bfd_boolean negated;
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;
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);
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;
/* 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 ();
/* 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;
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;
/* 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;
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;
demand_empty_rest_of_line ();
}
+\f
+/* 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
{
return BFD_RELOC_UNUSED;
}
-\f
-/* Parsing and Idiom Translation. */
static const char *
-expression_end (name)
- const char *name;
+expression_end (const char *name)
{
while (1)
{
#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;
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;
/* 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;
/* 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;
static int
-get_invisible_operands (insn)
- TInsn *insn;
+get_invisible_operands (TInsn *insn)
{
xtensa_isa isa = xtensa_default_isa;
static xtensa_insnbuf slotbuf = NULL;
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;
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;
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);
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;
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;
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;
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;
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;
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;
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;
/* 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;
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);
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;
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;
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;
static bfd_boolean
-is_the_loop_opcode (opcode)
- xtensa_opcode opcode;
+is_the_loop_opcode (xtensa_opcode opcode)
{
if (opcode == XTENSA_UNDEFINED)
return FALSE;
static bfd_boolean
-is_jx_opcode (opcode)
- xtensa_opcode opcode;
+is_jx_opcode (xtensa_opcode opcode)
{
if (opcode == XTENSA_UNDEFINED)
return FALSE;
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;
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)
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;
"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;
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;
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,
}
\f
-/* Various Other Internal Functions. */
-
-static bfd_boolean
-is_unique_insn_expansion (r)
- TransitionRule *r;
-{
- if (!r->to_instr || r->to_instr->next != NULL)
- return FALSE;
- if (r->to_instr->typ != INSTR_INSTR)
- return FALSE;
- return TRUE;
-}
+/* 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 int
-xg_get_build_instr_size (insn)
- BuildInstr *insn;
+static bfd_boolean
+xg_instruction_matches_option_term (TInsn *insn ATTRIBUTE_UNUSED,
+ const ReqOrOption *option)
{
- assert (insn->typ == INSTR_INSTR);
- return xg_get_single_size (insn->opcode);
+ 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_is_narrow_insn (insn)
- TInsn *insn;
+static bfd_boolean
+xg_instruction_matches_or_options (TInsn *insn,
+ const ReqOrOptionList *or_option)
{
- TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
- TransitionList *l;
- int num_match = 0;
- assert (insn->insn_type == ITYPE_INSN);
- assert (insn->opcode < table->num_opcodes);
-
- for (l = table->table[insn->opcode]; l != NULL; l = l->next)
+ const ReqOrOption *option;
+ /* Must match each of the AND terms. */
+ for (option = or_option; option != NULL; option = option->next)
{
- TransitionRule *rule = l->rule;
-
- if (xg_instruction_matches_rule (insn, rule)
- && is_unique_insn_expansion (rule))
- {
- /* It only generates one instruction... */
- assert (insn->insn_type == ITYPE_INSN);
- /* ...and it is a larger instruction. */
- if (xg_get_single_size (insn->opcode)
- < xg_get_build_instr_size (rule->to_instr))
- {
- num_match++;
- if (num_match > 1)
- return FALSE;
- }
- }
+ if (xg_instruction_matches_option_term (insn, option))
+ return TRUE;
}
- return (num_match == 1);
+ return FALSE;
}
-bfd_boolean
-xg_is_single_relaxable_insn (insn)
- TInsn *insn;
+static bfd_boolean
+xg_instruction_matches_options (TInsn *insn, const ReqOptionList *options)
{
- TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
- TransitionList *l;
- int num_match = 0;
- assert (insn->insn_type == ITYPE_INSN);
- assert (insn->opcode < table->num_opcodes);
-
- for (l = table->table[insn->opcode]; l != NULL; l = l->next)
+ const ReqOption *req_options;
+ /* Must match each of the AND terms. */
+ for (req_options = options;
+ req_options != NULL;
+ req_options = req_options->next)
{
- TransitionRule *rule = l->rule;
-
- if (xg_instruction_matches_rule (insn, rule)
- && is_unique_insn_expansion (rule))
- {
- /* It only generates one instruction... */
- assert (insn->insn_type == ITYPE_INSN);
- /* ... and it is a larger instruction. */
- if (xg_get_single_size (insn->opcode)
- <= xg_get_build_instr_size (rule->to_instr))
- {
- num_match++;
- if (num_match > 1)
- return FALSE;
- }
- }
+ /* Must match one of the OR clauses. */
+ if (!xg_instruction_matches_or_options (insn,
+ req_options->or_option_terms))
+ return FALSE;
}
- return (num_match == 1);
+ return TRUE;
}
-/* Return the maximum number of bytes this opcode can expand to. */
+/* Return the transition rule that matches or NULL if none matches. */
-int
-xg_get_max_insn_widen_size (opcode)
- xtensa_opcode opcode;
+static bfd_boolean
+xg_instruction_matches_rule (TInsn *insn, TransitionRule *rule)
{
- TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
- TransitionList *l;
- int max_size = xg_get_single_size (opcode);
+ PreconditionList *condition_l;
- assert (opcode < table->num_opcodes);
+ if (rule->opcode != insn->opcode)
+ return FALSE;
- for (l = table->table[opcode]; l != NULL; l = l->next)
+ for (condition_l = rule->conditions;
+ condition_l != NULL;
+ condition_l = condition_l->next)
{
- TransitionRule *rule = l->rule;
- BuildInstr *build_list;
- int this_size = 0;
+ expressionS *exp1;
+ expressionS *exp2;
+ Precondition *cond = condition_l->precond;
- if (!rule)
- continue;
- build_list = rule->to_instr;
- if (is_unique_insn_expansion (rule))
+ switch (cond->typ)
{
- assert (build_list->typ == INSTR_INSTR);
- this_size = xg_get_max_insn_widen_size (build_list->opcode);
- }
- else
- for (; build_list != NULL; build_list = build_list->next)
- {
- switch (build_list->typ)
- {
- case INSTR_INSTR:
- this_size += xg_get_single_size (build_list->opcode);
- break;
- case INSTR_LITERAL_DEF:
- case INSTR_LABEL_DEF:
+ 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;
+}
+
+\f
+/* Various Other Internal Functions. */
+
+static bfd_boolean
+is_unique_insn_expansion (TransitionRule *r)
+{
+ if (!r->to_instr || r->to_instr->next != NULL)
+ return FALSE;
+ if (r->to_instr->typ != INSTR_INSTR)
+ return FALSE;
+ return TRUE;
+}
+
+
+static int
+xg_get_build_instr_size (BuildInstr *insn)
+{
+ assert (insn->typ == INSTR_INSTR);
+ return xg_get_single_size (insn->opcode);
+}
+
+
+static bfd_boolean
+xg_is_narrow_insn (TInsn *insn)
+{
+ TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
+ TransitionList *l;
+ int num_match = 0;
+ assert (insn->insn_type == ITYPE_INSN);
+ assert (insn->opcode < table->num_opcodes);
+
+ for (l = table->table[insn->opcode]; l != NULL; l = l->next)
+ {
+ TransitionRule *rule = l->rule;
+
+ if (xg_instruction_matches_rule (insn, rule)
+ && is_unique_insn_expansion (rule))
+ {
+ /* It only generates one instruction... */
+ assert (insn->insn_type == ITYPE_INSN);
+ /* ...and it is a larger instruction. */
+ if (xg_get_single_size (insn->opcode)
+ < xg_get_build_instr_size (rule->to_instr))
+ {
+ num_match++;
+ if (num_match > 1)
+ return FALSE;
+ }
+ }
+ }
+ return (num_match == 1);
+}
+
+
+static bfd_boolean
+xg_is_single_relaxable_insn (TInsn *insn)
+{
+ TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
+ TransitionList *l;
+ int num_match = 0;
+ assert (insn->insn_type == ITYPE_INSN);
+ assert (insn->opcode < table->num_opcodes);
+
+ for (l = table->table[insn->opcode]; l != NULL; l = l->next)
+ {
+ TransitionRule *rule = l->rule;
+
+ if (xg_instruction_matches_rule (insn, rule)
+ && is_unique_insn_expansion (rule))
+ {
+ /* It only generates one instruction... */
+ assert (insn->insn_type == ITYPE_INSN);
+ /* ... and it is a larger instruction. */
+ if (xg_get_single_size (insn->opcode)
+ <= xg_get_build_instr_size (rule->to_instr))
+ {
+ num_match++;
+ if (num_match > 1)
+ return FALSE;
+ }
+ }
+ }
+ return (num_match == 1);
+}
+
+
+/* Return the maximum number of bytes this opcode can expand to. */
+
+static int
+xg_get_max_insn_widen_size (xtensa_opcode opcode)
+{
+ TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
+ TransitionList *l;
+ int max_size = xg_get_single_size (opcode);
+
+ assert (opcode < table->num_opcodes);
+
+ for (l = table->table[opcode]; l != NULL; l = l->next)
+ {
+ TransitionRule *rule = l->rule;
+ BuildInstr *build_list;
+ int this_size = 0;
+
+ if (!rule)
+ continue;
+ build_list = rule->to_instr;
+ if (is_unique_insn_expansion (rule))
+ {
+ assert (build_list->typ == INSTR_INSTR);
+ this_size = xg_get_max_insn_widen_size (build_list->opcode);
+ }
+ else
+ for (; build_list != NULL; build_list = build_list->next)
+ {
+ switch (build_list->typ)
+ {
+ case INSTR_INSTR:
+ this_size += xg_get_single_size (build_list->opcode);
+ break;
+ case INSTR_LITERAL_DEF:
+ case INSTR_LABEL_DEF:
default:
break;
}
/* 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;
}
-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);
+ TransitionList *l;
+
+ assert (insn->insn_type == ITYPE_INSN);
+ assert (insn->opcode < table->num_opcodes);
+
+ for (l = table->table[insn->opcode]; l != NULL; l = l->next)
+ {
+ TransitionRule *rule = l->rule;
+
+ if (xg_instruction_matches_rule (insn, rule))
+ {
+ if (steps_taken == lateral_steps)
+ return TRUE;
+ steps_taken++;
+ }
+ }
+ return FALSE;
+}
+
+
+static symbolS *
+get_special_literal_symbol (void)
+{
+ static symbolS *sym = NULL;
+
+ if (sym == NULL)
+ sym = symbol_find_or_make ("SPECIAL_LITERAL0\001");
+ return sym;
+}
+
+
+static symbolS *
+get_special_label_symbol (void)
+{
+ static symbolS *sym = NULL;
+
+ if (sym == NULL)
+ sym = symbol_find_or_make ("SPECIAL_LABEL0\001");
+ return sym;
+}
+
+
+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)
{
- int steps_taken = 0;
- TransitionTable *table = xg_build_widen_table (&transition_rule_cmp);
- TransitionList *l;
+ 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);
- assert (insn->opcode < table->num_opcodes);
- for (l = table->table[insn->opcode]; l != NULL; l = l->next)
+ for (i = 0; i < n; ++i)
{
- TransitionRule *rule = l->rule;
+ const expressionS *expr = &insn->tok[i];
+ if (xtensa_operand_is_register (isa, insn->opcode, i) == 1)
+ continue;
- if (xg_instruction_matches_rule (insn, rule))
+ switch (expr->X_op)
{
- if (steps_taken == lateral_steps)
- return TRUE;
- steps_taken++;
- }
- }
- return FALSE;
-}
+ 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;
-static symbolS *
-get_special_literal_symbol ()
-{
- static symbolS *sym = NULL;
+ 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 (sym == NULL)
- sym = symbol_find_or_make ("SPECIAL_LITERAL0\001");
- return sym;
-}
+ /* 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;
-static symbolS *
-get_special_label_symbol ()
-{
- static symbolS *sym = NULL;
+ 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 (sym == NULL)
- sym = symbol_find_or_make ("SPECIAL_LABEL0\001");
- return sym;
+ /* 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;
/* 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)
{
/* 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;
}
-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;
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;
-}
-
\f
-
/* 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;
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"
}
-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
}
+/* 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;
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);
-
- if (xtensa_opcode_is_loop (isa, insn->opcode) == 1)
- {
- int i = 1;
- if (xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 1
- && insn->tok[i].X_op == O_symbol)
- symbol_get_tc (insn->tok[i].X_add_symbol)->is_loop_target = TRUE;
- return;
- }
-
- if (xtensa_opcode_is_branch (isa, insn->opcode) == 1
- || xtensa_opcode_is_loop (isa, insn->opcode) == 1)
- {
- int i;
-
- for (i = 0; i < insn->ntok && i < num_ops; i++)
- {
- if (xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 1
- && insn->tok[i].X_op == O_symbol)
- {
- symbolS *sym = insn->tok[i].X_add_symbol;
- symbol_get_tc (sym)->is_branch_target = TRUE;
- if (S_IS_DEFINED (sym))
- symbol_get_frag (sym)->tc_frag_data.is_branch_target = TRUE;
- }
- }
- }
-}
-
-
-/* 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;
-}
-
+ int num_ops = xtensa_opcode_num_operands (isa, insn->opcode);
-TransitionRule *
-xg_instruction_match (insn)
- TInsn *insn;
-{
- TransitionTable *table = xg_build_simplify_table (&transition_rule_cmp);
- TransitionList *l;
- assert (insn->opcode < table->num_opcodes);
+ if (xtensa_opcode_is_loop (isa, insn->opcode) == 1)
+ {
+ int i = 1;
+ if (xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 1
+ && insn->tok[i].X_op == O_symbol)
+ symbol_get_tc (insn->tok[i].X_add_symbol)->is_loop_target = TRUE;
+ return;
+ }
- /* Walk through all of the possible transitions. */
- for (l = table->table[insn->opcode]; l != NULL; l = l->next)
+ if (xtensa_opcode_is_branch (isa, insn->opcode) == 1
+ || xtensa_opcode_is_loop (isa, insn->opcode) == 1)
{
- TransitionRule *rule = l->rule;
- if (xg_instruction_matches_rule (insn, rule))
- return rule;
+ int i;
+
+ for (i = 0; i < insn->ntok && i < num_ops; i++)
+ {
+ if (xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 1
+ && insn->tok[i].X_op == O_symbol)
+ {
+ symbolS *sym = insn->tok[i].X_add_symbol;
+ symbol_get_tc (sym)->is_branch_target = TRUE;
+ if (S_IS_DEFINED (sym))
+ symbol_get_frag (sym)->tc_frag_data.is_branch_target = TRUE;
+ }
+ }
}
- 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;
/* 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;
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;
}
+/* 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;
}
-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
}
-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;
the_fix = fix_new_exp (fragP, offset, fmt_length, expr,
howto->pc_relative, reloc);
- if (expr->X_add_symbol
- && (S_IS_EXTERNAL (expr->X_add_symbol)
- || S_IS_WEAK (expr->X_add_symbol)))
- the_fix->fx_plt = TRUE;
+ if (expr->X_add_symbol
+ && (S_IS_EXTERNAL (expr->X_add_symbol)
+ || S_IS_WEAK (expr->X_add_symbol)))
+ the_fix->fx_plt = TRUE;
+
+ the_fix->tc_fix_data.X_add_symbol = expr->X_add_symbol;
+ the_fix->tc_fix_data.X_add_number = expr->X_add_number;
+ the_fix->tc_fix_data.slot = slot;
+
+ return TRUE;
+}
+
+
+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];
- the_fix->tc_fix_data.X_add_symbol = expr->X_add_symbol;
- the_fix->tc_fix_data.X_add_number = expr->X_add_number;
- the_fix->tc_fix_data.slot = slot;
-
- return TRUE;
+ 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;
}
-void
-xg_resolve_literals (insn, lit_sym)
- TInsn *insn;
- symbolS *lit_sym;
+static void
+xg_resolve_literals (TInsn *insn, symbolS *lit_sym)
{
symbolS *sym = get_special_literal_symbol ();
int i;
}
-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;
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;
static bfd_boolean
-is_bad_loopend_opcode (tinsn)
- const TInsn * tinsn;
+is_bad_loopend_opcode (const TInsn *tinsn)
{
xtensa_opcode opcode = tinsn->opcode;
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;
}
-fragS *
-next_non_empty_frag (fragP)
- const fragS *fragP;
+static fragS *
+next_non_empty_frag (const fragS *fragP)
{
fragS *next_fragP = fragP->fr_next;
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);
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;
}
-/* 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);
}
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;
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. */
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. */
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;
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. */
}
-/* 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)
/* 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;
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
}
-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;
}
/* 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;
}
-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;
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);
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);
}
-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;
/* 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);
need. */
void
-md_begin ()
+md_begin (void)
{
segT current_section = now_seg;
int current_subsec = now_subseg;
/* 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;
/* 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. */
/* tc_unrecognized_line hook */
int
-xtensa_unrecognized_line (ch)
- int ch;
+xtensa_unrecognized_line (int ch)
{
switch (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"));
and bad things happen. */
static void
-error_reset_cur_vinsn ()
+error_reset_cur_vinsn (void)
{
if (cur_vinsn.inside_bundle)
{
void
-md_assemble (str)
- char *str;
+md_assemble (char *str)
{
xtensa_isa isa = xtensa_default_isa;
char *opname;
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)
/* 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;
}
/* 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;
/* TC_FORCE_RELOCATION hook */
int
-xtensa_force_relocation (fix)
- fixS *fix;
+xtensa_force_relocation (fixS *fix)
{
switch (fix->fx_r_type)
{
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"));
/* 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)
/* 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
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)
{
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];
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];
}
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;
return reloc;
}
+\f
+/* Checks for resource conflicts between instructions. */
+
+/* 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 (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 (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 (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;
-/* md_post_relax_hook */
+ 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);
+ }
-#define XTENSA_INSN_SEC_NAME ".xt.insn"
-#define XTENSA_LIT_SEC_NAME ".xt.lit"
-#define XTENSA_PROP_SEC_NAME ".xt.prop"
+ clear_resource_table (rt);
-void
-xtensa_post_relax_hook ()
-{
- 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);
+ 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);
+ }
- xtensa_find_unmarked_state_frags ();
+ return FALSE;
+}
- 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);
+\f
+/* finish_vinsn, emit_single_op and helper functions. */
- 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);
-}
+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;
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;
*/
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;
continue;
if (t2_inout == 'i' && (t1_inout == 'm' || t1_inout == 'o'))
- {
- conflict = 'a';
- continue;
- }
-
- if (t1_inout == 'i' && (t2_inout == 'm' || t2_inout == 'o'))
- {
- conflict = 'a';
- continue;
- }
-
- if (t1_inout != 'i' && t2_inout != 'i')
- return 'c';
- }
- }
- }
- }
-
- /* Check states. */
- t1_states = xtensa_opcode_num_stateOperands (isa, t1->opcode);
- t2_states = xtensa_opcode_num_stateOperands (isa, t2->opcode);
- for (j = 0; j < t2_states; j++)
- {
- xtensa_state t2_so = xtensa_stateOperand_state (isa, t2->opcode, j);
- t2_inout = xtensa_stateOperand_inout (isa, t2->opcode, j);
- for (i = 0; i < t1_states; i++)
- {
- xtensa_state t1_so = xtensa_stateOperand_state (isa, t1->opcode, i);
- t1_inout = xtensa_stateOperand_inout (isa, t1->opcode, i);
- if (t1_so != t2_so)
- continue;
-
- if (t2_inout == 'i' && (t1_inout == 'm' || t1_inout == 'o'))
- {
- conflict = 'a';
- continue;
- }
-
- if (t1_inout == 'i' && (t2_inout == 'm' || t2_inout == 'o'))
- {
- conflict = 'a';
- continue;
- }
-
- if (t1_inout != 'i' && t2_inout != 'i')
- return 'd';
- }
- }
-
- /* Check tieports. */
- t1_interfaces = xtensa_opcode_num_interfaceOperands (isa, t1->opcode);
- t2_interfaces = xtensa_opcode_num_interfaceOperands (isa, t2->opcode);
- for (j = 0; j < t2_interfaces; j++)
- {
- xtensa_interface t2_int
- = xtensa_interfaceOperand_interface (isa, t2->opcode, j);
- t2_inout = xtensa_interface_inout (isa, j);
- if (xtensa_interface_has_side_effect (isa, t2_int) == 1
- && t2_inout != 'i')
- t2_volatile = TRUE;
- for (i = 0; i < t1_interfaces; i++)
- {
- xtensa_interface t1_int
- = xtensa_interfaceOperand_interface (isa, t1->opcode, j);
- t1_inout = xtensa_interface_inout (isa, i);
- if (xtensa_interface_has_side_effect (isa, t1_int) == 1
- && t1_inout != 'i')
- t1_volatile = TRUE;
-
- if (t1_int != t2_int)
- continue;
-
- if (t2_inout == 'i' && t1_inout == 'o')
- {
- conflict = 'a';
- continue;
- }
-
- if (t1_inout == 'i' && t2_inout == 'o')
- {
- conflict = 'a';
- continue;
- }
-
- if (t1_inout != 'i' && t2_inout != 'i')
- return 'e';
- }
- }
-
- if (t1_volatile && t2_volatile)
- return 'f';
-
- return conflict;
-}
-
-
-/* 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. */
+ {
+ conflict = 'a';
+ continue;
+ }
-static bfd_boolean
-resources_conflict (vinsn)
- vliw_insn *vinsn;
-{
- int i;
- static resource_table *rt = NULL;
+ if (t1_inout == 'i' && (t2_inout == 'm' || t2_inout == 'o'))
+ {
+ conflict = 'a';
+ continue;
+ }
- /* This is the most common case by far. Optimize it. */
- if (vinsn->num_slots == 1)
- return FALSE;
+ if (t1_inout != 'i' && t2_inout != 'i')
+ return 'c';
+ }
+ }
+ }
+ }
- if (rt == NULL)
+ /* Check states. */
+ t1_states = xtensa_opcode_num_stateOperands (isa, t1->opcode);
+ t2_states = xtensa_opcode_num_stateOperands (isa, t2->opcode);
+ for (j = 0; j < t2_states; j++)
{
- 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);
- }
+ xtensa_state t2_so = xtensa_stateOperand_state (isa, t2->opcode, j);
+ t2_inout = xtensa_stateOperand_inout (isa, t2->opcode, j);
+ for (i = 0; i < t1_states; i++)
+ {
+ xtensa_state t1_so = xtensa_stateOperand_state (isa, t1->opcode, i);
+ t1_inout = xtensa_stateOperand_inout (isa, t1->opcode, i);
+ if (t1_so != t2_so)
+ continue;
- clear_resource_table (rt);
+ if (t2_inout == 'i' && (t1_inout == 'm' || t1_inout == 'o'))
+ {
+ conflict = 'a';
+ continue;
+ }
+
+ if (t1_inout == 'i' && (t2_inout == 'm' || t2_inout == 'o'))
+ {
+ conflict = 'a';
+ continue;
+ }
+
+ if (t1_inout != 'i' && t2_inout != 'i')
+ return 'd';
+ }
+ }
- for (i = 0; i < vinsn->num_slots; i++)
+ /* Check tieports. */
+ t1_interfaces = xtensa_opcode_num_interfaceOperands (isa, t1->opcode);
+ t2_interfaces = xtensa_opcode_num_interfaceOperands (isa, t2->opcode);
+ for (j = 0; j < t2_interfaces; j++)
{
- if (!resources_available (rt, vinsn->slots[i].opcode, 0))
- return TRUE;
- reserve_resources (rt, vinsn->slots[i].opcode, 0);
+ xtensa_interface t2_int
+ = xtensa_interfaceOperand_interface (isa, t2->opcode, j);
+ t2_inout = xtensa_interface_inout (isa, j);
+ if (xtensa_interface_has_side_effect (isa, t2_int) == 1
+ && t2_inout != 'i')
+ t2_volatile = TRUE;
+ for (i = 0; i < t1_interfaces; i++)
+ {
+ xtensa_interface t1_int
+ = xtensa_interfaceOperand_interface (isa, t1->opcode, j);
+ t1_inout = xtensa_interface_inout (isa, i);
+ if (xtensa_interface_has_side_effect (isa, t1_int) == 1
+ && t1_inout != 'i')
+ t1_volatile = TRUE;
+
+ if (t1_int != t2_int)
+ continue;
+
+ if (t2_inout == 'i' && t1_inout == 'o')
+ {
+ conflict = 'a';
+ continue;
+ }
+
+ if (t1_inout == 'i' && t2_inout == 'o')
+ {
+ conflict = 'a';
+ continue;
+ }
+
+ if (t1_inout != 'i' && t2_inout != 'i')
+ return 'e';
+ }
}
- return FALSE;
+ if (t1_volatile && t2_volatile)
+ return 'f';
+
+ return conflict;
}
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
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++;
}
}
}
each tinsn in the vinsn. */
static int
-relaxation_requirements (vinsn)
- vliw_insn *vinsn;
+relaxation_requirements (vliw_insn *vinsn)
{
int extra_space = 0;
int slot;
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;
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 */
/* 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;
}
\f
+/* 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 ();
static void
-xtensa_cleanup_align_frags ()
+xtensa_cleanup_align_frags (void)
{
frchainS *frchP;
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;
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;
}
+static bfd_boolean is_narrow_branch_guaranteed_in_range (fragS *, TInsn *);
+
static void
-xtensa_mark_narrow_branches ()
+xtensa_mark_narrow_branches (void)
{
frchainS *frchP;
/* 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;
static void
-xtensa_mark_zcl_first_insns ()
+xtensa_mark_zcl_first_insns (void)
{
frchainS *frchP;
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;
}
-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;
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;
}
-bfd_boolean
-next_instr_is_loop_end (fragP)
- fragS * fragP;
+static bfd_boolean
+next_instr_is_loop_end (fragS *fragP)
{
const fragS *next_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;
}
+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;
static size_t
-unrelaxed_frag_min_size (fragP)
- fragS *fragP;
+unrelaxed_frag_min_size (fragS *fragP)
{
size_t size = fragP->fr_fix;
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)
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;
}
+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;
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;
}
+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;
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;
/* 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;
/* 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;
}
-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;
/* 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++)
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);
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:
/* 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)
}
-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;
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
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;
\f
/* 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;
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;
/* 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;
}
+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
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;
}
+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;
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)
{
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;
*/
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;
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;
\f
/* 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;
}
-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;
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;
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];
}
+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;
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;
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;
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;
\f
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;
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)
/* 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
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)
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)
}
-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;
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;
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. */
/* 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;
}
-segT
-get_last_sec ()
+static segT
+get_last_sec (void)
{
segT last_sec = stdoutput->sections;
while (last_sec->next != NULL)
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])
{
}
-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
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;
/* 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);
/* 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;
/* 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;
/* 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;
/* 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));
\f
/* 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;
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;
}
-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;
}
-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);
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;
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;
}
-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;
}
-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;
}
-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;
/* 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;
/* 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
}
-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;
}
-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)
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. */
}
-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;
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;
}
-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;
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);
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]);
}
/* 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;
}
/* 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;
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);
}
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));
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));
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;
istack_empty () returns TRUE. */
void
-istack_pop (stack)
- IStack *stack;
+istack_pop (IStack *stack)
{
int rec = stack->ninsn - 1;
assert (!istack_empty (stack));
/* TInsn functions. */
void
-tinsn_init (dst)
- TInsn *dst;
+tinsn_init (TInsn *dst)
{
memset (dst, 0, sizeof (TInsn));
}
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];
/* 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;
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;
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;
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;
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;
/* 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;
/* 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;
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;
/* 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;
static int
-get_num_stack_text_bytes (istack)
- IStack *istack;
+get_num_stack_text_bytes (IStack *istack)
{
int i;
int text_bytes = 0;
static int
-get_num_stack_literal_bytes (istack)
- IStack *istack;
+get_num_stack_literal_bytes (IStack *istack)
{
int i;
int lit_bytes = 0;
\f
/* 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;
}
-void
-xg_clear_vinsn (v)
- vliw_insn *v;
+static void
+xg_clear_vinsn (vliw_insn *v)
{
int i;
v->format = XTENSA_UNDEFINED;
}
-bfd_boolean
-vinsn_has_specific_opcodes (v)
- vliw_insn *v;
+static bfd_boolean
+vinsn_has_specific_opcodes (vliw_insn *v)
{
int i;
}
-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);
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;
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;
/* 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);
}
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;
/* 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;
bfd_boolean
-expr_is_register (s)
- const expressionS *s;
+expr_is_register (const expressionS *s)
{
return (s->X_op == O_register);
}
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;
/* 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;
/* 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;
/* 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;
static void
-copy_expr (dst, src)
- expressionS *dst;
- const expressionS *src;
+copy_expr (expressionS *dst, const expressionS *src)
{
memcpy (dst, src, sizeof (expressionS));
}
/* 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;
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;
const char *
-xtensa_section_rename (name)
- const char *name;
+xtensa_section_rename (const char *name)
{
struct rename_section_struct *r = section_rename;