Back to index

cell-binutils  2.17cvs20070401
Classes | Defines | Typedefs | Enumerations | Functions | Variables
tc-xtensa.c File Reference
#include <limits.h>
#include "as.h"
#include "sb.h"
#include "safe-ctype.h"
#include "tc-xtensa.h"
#include "subsegs.h"
#include "xtensa-relax.h"
#include "xtensa-istack.h"
#include "dwarf2dbg.h"
#include "struc-symbol.h"
#include "xtensa-config.h"

Go to the source code of this file.

Classes

struct  lit_state_struct
struct  seg_list_struct
struct  sym_list_struct
struct  frag_flags_struct
struct  xtensa_block_info_struct
struct  emit_state_struct
struct  op_placement_info_struct
struct  suffix_reloc_map
struct  directive_infoS
struct  state_stackS_struct
struct  subseg_map_struct
struct  rename_section_struct
struct  frag_flags_struct.insn

Defines

#define XSHAL_ABI   0
#define uint32   unsigned int
#define int32   signed int
#define UNREACHABLE_MAX_WIDTH   8
#define FLAG_IS_A0_WRITER   0x1
#define FLAG_IS_BAD_LOOPEND   0x2
#define LITERAL_SECTION_NAME   xtensa_section_rename (".literal")
#define LIT4_SECTION_NAME   xtensa_section_rename (".lit4")
#define INIT_SECTION_NAME   xtensa_section_rename (".init")
#define FINI_SECTION_NAME   xtensa_section_rename (".fini")
#define XTENSA_PROP_LITERAL   0x00000001
#define XTENSA_PROP_INSN   0x00000002
#define XTENSA_PROP_DATA   0x00000004
#define XTENSA_PROP_UNREACHABLE   0x00000008
#define XTENSA_PROP_INSN_LOOP_TARGET   0x00000010
#define XTENSA_PROP_INSN_BRANCH_TARGET   0x00000020
#define XTENSA_PROP_INSN_NO_DENSITY   0x00000040
#define XTENSA_PROP_INSN_NO_REORDER   0x00000080
#define XTENSA_PROP_INSN_NO_TRANSFORM   0x00000100
#define XTENSA_PROP_BT_ALIGN_MASK   0x00000600
#define XTENSA_PROP_BT_ALIGN_NONE   0x0
#define XTENSA_PROP_BT_ALIGN_LOW   0x1
#define XTENSA_PROP_BT_ALIGN_HIGH   0x2
#define XTENSA_PROP_BT_ALIGN_REQUIRE   0x3
#define GET_XTENSA_PROP_BT_ALIGN(flag)   (((unsigned) ((flag) & (XTENSA_PROP_BT_ALIGN_MASK))) >> 9)
#define SET_XTENSA_PROP_BT_ALIGN(flag, align)
#define XTENSA_PROP_ALIGN   0x00000800
#define XTENSA_PROP_ALIGNMENT_MASK   0x0001f000
#define GET_XTENSA_PROP_ALIGNMENT(flag)   (((unsigned) ((flag) & (XTENSA_PROP_ALIGNMENT_MASK))) >> 12)
#define SET_XTENSA_PROP_ALIGNMENT(flag, align)
#define XTENSA_PROP_INSN_ABSLIT   0x00020000
#define bit_is_set(bit, bf)   ((bf) & (0x01ll << (bit)))
#define set_bit(bit, bf)   ((bf) |= (0x01ll << (bit)))
#define clear_bit(bit, bf)   ((bf) &= ~(0x01ll << (bit)))
#define MAX_FORMATS   32
#define O_pltrel   O_md1 /* like O_symbol but use a PLT reloc */
#define O_hi16   O_md2 /* use high 16 bits of symbolic value */
#define O_lo16   O_md3 /* use low 16 bits of symbolic value */
#define SUFFIX_MAP(str, reloc, op)   { str, sizeof (str) - 1, reloc, op }
#define ERROR_REG_NUM   ((unsigned) -1)
#define MAX_IMMED6   65
#define REQUIRED_LOOP_DIVIDING_BYTES   12
#define LOOP_IMMED_OPN   1
#define XTINFO_NAME   "Xtensa_Info"
#define XTINFO_NAMESZ   12
#define XTINFO_TYPE   1
#define XTENSA_INSN_SEC_NAME   ".xt.insn"
#define XTENSA_LIT_SEC_NAME   ".xt.lit"
#define XTENSA_PROP_SEC_NAME   ".xt.prop"

Typedefs

typedef struct lit_state_struct lit_state
typedef struct seg_list_struct seg_list
typedef struct sym_list_struct sym_list
typedef struct frag_flags_struct
typedef struct emit_state_struct emit_state
typedef unsigned long long bitfield
typedef struct
op_placement_info_struct 
op_placement_info
typedef struct
op_placement_info_struct
op_placement_info_table
typedef struct state_stackS_struct state_stackS
typedef struct subseg_map_struct subseg_map
typedef bfd_boolean(* frag_predicate )(const fragS *)
typedef void(* frag_flags_fn )(const fragS *, frag_flags *)

Enumerations

enum  directiveE {
  directive_none = 0, directive_literal, directive_density, directive_transform,
  directive_freeregs, directive_longcalls, directive_literal_prefix, directive_schedule,
  directive_absolute_literals, directive_last_directive
}
enum  {
  option_density = OPTION_MD_BASE, option_no_density, option_relax, option_no_relax,
  option_link_relax, option_no_link_relax, option_generics, option_no_generics,
  option_transform, option_no_transform, option_text_section_literals, option_no_text_section_literals,
  option_absolute_literals, option_no_absolute_literals, option_align_targets, option_no_align_targets,
  option_warn_unaligned_targets, option_longcalls, option_no_longcalls, option_workaround_a0_b_retw,
  option_no_workaround_a0_b_retw, option_workaround_b_j_loop_end, option_no_workaround_b_j_loop_end, option_workaround_short_loop,
  option_no_workaround_short_loop, option_workaround_all_short_loops, option_no_workaround_all_short_loops, option_workaround_close_loop_end,
  option_no_workaround_close_loop_end, option_no_workarounds, option_rename_section_name, option_prefer_l32r,
  option_prefer_const16, option_target_hardware
}

Functions

static void xtensa_begin_directive (int)
static void xtensa_end_directive (int)
static void xtensa_literal_prefix (void)
static void xtensa_literal_position (int)
static void xtensa_literal_pseudo (int)
static void xtensa_frequency_pseudo (int)
static void xtensa_elf_cons (int)
static bfd_reloc_code_real_type xtensa_elf_suffix (char **, expressionS *)
bfd_boolean xg_is_single_relaxable_insn (TInsn *, TInsn *, bfd_boolean)
static bfd_boolean xg_build_to_insn (TInsn *, TInsn *, BuildInstr *)
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 *)
static int total_frag_text_expansion (fragS *)
static int get_text_align_power (unsigned)
static int get_text_align_max_fill_size (int, bfd_boolean, bfd_boolean)
static int branch_align_power (segT)
static long relax_frag_add_nop (fragS *)
static unsigned get_last_insn_flags (segT, subsegT)
static void set_last_insn_flags (segT, subsegT, unsigned, bfd_boolean)
static float get_subseg_total_freq (segT, subsegT)
static float get_subseg_target_freq (segT, subsegT)
static void set_subseg_freq (segT, subsegT, float, float)
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 segT cache_literal_section (bfd_boolean)
asectionxtensa_get_property_section (asection *, const char *)
static void init_op_placement_info_table (void)
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)
static int xg_get_single_slot (xtensa_opcode)
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 *)
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 (vliw_insn *, char *, fragS *, bfd_boolean)
static void vinsn_from_chars (vliw_insn *, char *)
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)
bfd_boolean expr_is_equal (expressionS *, expressionS *)
static void copy_expr (expressionS *, const expressionS *)
static void build_section_rename (const char *)
static void xtensa_setup_hw_workarounds (int earliest, int latest)
int md_parse_option (int c, char *arg)
void md_show_usage (FILE *stream)
static void xtensa_add_insn_label (symbolS *sym)
static void xtensa_clear_insn_labels (void)
static void xtensa_move_labels (fragS *new_frag, valueT new_offset)
static bfd_boolean use_transform (void)
static bfd_boolean do_align_targets (void)
static void directive_push (directiveE directive, bfd_boolean negated, const void *datum)
static void directive_pop (directiveE *directive, bfd_boolean *negated, const char **file, unsigned int *line, const void **datum)
static void directive_balance (void)
static bfd_boolean inside_directive (directiveE dir)
static void get_directive (directiveE *directive, bfd_boolean *negated)
static void xtensa_begin_directive (int ignore ATTRIBUTE_UNUSED)
static void xtensa_end_directive (int ignore ATTRIBUTE_UNUSED)
static void xtensa_literal_position (int ignore ATTRIBUTE_UNUSED)
static void xtensa_literal_pseudo (int ignored ATTRIBUTE_UNUSED)
static void xtensa_frequency_pseudo (int ignored ATTRIBUTE_UNUSED)
static unsigned char map_suffix_reloc_to_operator (bfd_reloc_code_real_type reloc)
static bfd_reloc_code_real_type map_operator_to_reloc (unsigned char operator)
static const char * expression_end (const char *name)
static unsigned tc_get_register (const char *prefix)
static void expression_maybe_register (xtensa_opcode opc, int opnd, expressionS *tok)
static int tokenize_arguments (char **args, char *str)
static bfd_boolean parse_arguments (TInsn *insn, int num_args, char **arg_strings)
static int get_invisible_operands (TInsn *insn)
static void xg_reverse_shift_count (char **cnt_argp)
static int xg_arg_is_constant (char *arg, offsetT *valp)
static void xg_replace_opname (char **popname, char *newop)
static int xg_check_num_args (int *pnum_args, int expected_num, char *opname, char **arg_strings)
static int xg_translate_sysreg_op (char **popname, int *pnum_args, char **arg_strings)
static int xtensa_translate_old_userreg_ops (char **popname)
static int xtensa_translate_zero_immed (char *old_op, char *new_op, char **popname, int *pnum_args, char **arg_strings)
static int xg_translate_idioms (char **popname, int *pnum_args, char **arg_strings)
static int get_relaxable_immed (xtensa_opcode opcode)
static xtensa_opcode get_opcode_from_buf (const char *buf, int slot)
static bfd_boolean is_direct_call_opcode (xtensa_opcode opcode)
static int decode_reloc (bfd_reloc_code_real_type reloc, int *slot, bfd_boolean *is_alt)
static bfd_reloc_code_real_type encode_reloc (int slot)
static bfd_reloc_code_real_type encode_alt_reloc (int slot)
static void 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)
static uint32 xtensa_insnbuf_get_operand (xtensa_insnbuf slotbuf, xtensa_format fmt, int slot, xtensa_opcode opcode, int opnum)
static bfd_boolean xg_instruction_matches_option_term (TInsn *insn ATTRIBUTE_UNUSED, const ReqOrOption *option)
static bfd_boolean xg_instruction_matches_or_options (TInsn *insn, const ReqOrOptionList *or_option)
static bfd_boolean xg_instruction_matches_options (TInsn *insn, const ReqOptionList *options)
static bfd_boolean xg_instruction_matches_rule (TInsn *insn, TransitionRule *rule)
static int transition_rule_cmp (const TransitionRule *a, const TransitionRule *b)
static TransitionRule * xg_instruction_match (TInsn *insn)
static bfd_boolean is_unique_insn_expansion (TransitionRule *r)
static int xg_get_max_insn_widen_size (xtensa_opcode opcode)
static int xg_get_max_insn_widen_literal_size (xtensa_opcode opcode)
static bfd_boolean xg_is_relaxable_insn (TInsn *insn, int lateral_steps)
static symbolS * get_special_literal_symbol (void)
static symbolS * get_special_label_symbol (void)
static bfd_boolean xg_valid_literal_expression (const expressionS *exp)
static bfd_boolean xg_check_operand (int32 value, xtensa_opcode opcode, int operand)
static bfd_boolean xg_immeds_fit (const TInsn *insn)
static bfd_boolean xg_symbolic_immeds_fit (const TInsn *insn, segT pc_seg, fragS *pc_frag, offsetT pc_offset, long stretch)
static bfd_boolean xg_build_to_stack (IStack *istack, TInsn *insn, BuildInstr *bi)
static bfd_boolean xg_expand_to_stack (IStack *istack, TInsn *insn, int lateral_steps)
static int xg_assembly_relax (IStack *istack, TInsn *insn, segT pc_seg, fragS *pc_frag, offsetT pc_offset, int min_steps, long stretch)
static void xg_force_frag_space (int size)
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)
static bfd_boolean is_next_frag_target (const fragS *fragP, const fragS *target)
static bfd_boolean is_branch_jmp_to_next (TInsn *insn, fragS *fragP)
static void xg_add_branch_and_loop_targets (TInsn *insn)
static bfd_boolean xg_build_token_insn (BuildInstr *instr_spec, TInsn *old_insn, TInsn *new_insn)
static bfd_boolean xg_simplify_insn (TInsn *old_insn, TInsn *new_insn)
static bfd_boolean xg_expand_assembly_insn (IStack *istack, TInsn *orig_insn)
static bfd_boolean get_is_linkonce_section (bfd *abfd ATTRIBUTE_UNUSED, segT sec)
static void xtensa_add_literal_sym (symbolS *sym)
static symbolS * xtensa_create_literal_symbol (segT sec, fragS *frag)
static symbolS * xg_assemble_literal (TInsn *insn)
static void xg_assemble_literal_space (int size, int slot)
static bfd_boolean xg_add_opcode_fix (TInsn *tinsn, int opnum, xtensa_format fmt, int slot, expressionS *expr, fragS *fragP, offsetT offset)
static bfd_boolean xg_emit_insn_to_buf (TInsn *tinsn, char *buf, fragS *fragP, offsetT offset, bfd_boolean build_fix)
static void xg_resolve_literals (TInsn *insn, symbolS *lit_sym)
static void xg_resolve_labels (TInsn *insn, symbolS *label_sym)
static bfd_boolean is_register_writer (const TInsn *insn, const char *regset, int regnum)
static bfd_boolean is_bad_loopend_opcode (const TInsn *tinsn)
static bfd_boolean is_unaligned_label (symbolS *sym)
static fragS * next_non_empty_frag (const fragS *fragP)
static bfd_boolean next_frag_opcode_is_loop (const fragS *fragP, xtensa_opcode *opcode)
static int frag_format_size (const fragS *fragP)
static int next_frag_format_size (const fragS *fragP)
static int get_loop_align_size (int insn_size)
static void update_next_frag_state (fragS *fragP)
static bfd_boolean next_frag_is_branch_target (const fragS *fragP)
static bfd_boolean next_frag_is_loop_target (const fragS *fragP)
static addressT next_frag_pre_opcode_bytes (const fragS *fragp)
static void build_nop (TInsn *tinsn, int size)
static void assemble_nop (int size, char *buf)
static bfd_boolean relaxable_section (asection *sec)
static void xtensa_find_unmarked_state_frags (void)
static void xtensa_find_unaligned_branch_targets (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *unused ATTRIBUTE_UNUSED)
static void xtensa_find_unaligned_loops (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *unused ATTRIBUTE_UNUSED)
static int xg_apply_fix_value (fixS *fixP, valueT val)
const char * xtensa_target_format (void)
void xtensa_file_arch_init (bfd *abfd)
void md_number_to_chars (char *buf, valueT val, int n)
void md_begin (void)
void xtensa_init_fix_data (fixS *x)
void xtensa_frob_label (symbolS *sym)
int xtensa_unrecognized_line (int ch)
void xtensa_flush_pending_output (void)
static void error_reset_cur_vinsn (void)
void md_assemble (char *str)
void xtensa_handle_align (fragS *fragP)
void xtensa_frag_init (fragS *frag)
symbolS * md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
valueT md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
long md_pcrel_from (fixS *fixP)
int xtensa_force_relocation (fixS *fix)
int xtensa_validate_fix_sub (fixS *fix)
bfd_boolean xtensa_check_inside_bundle (void)
void xtensa_elf_section_change_hook (void)
bfd_boolean xtensa_fix_adjustable (fixS *fixP)
void md_apply_fix (fixS *fixP, valueT *valP, segT seg)
char * md_atof (int type, char *litP, int *sizeP)
int md_estimate_size_before_relax (fragS *fragP, segT seg ATTRIBUTE_UNUSED)
arelenttc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
resource_tablenew_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)
void clear_resource_table (resource_table *rt)
void resize_resource_table (resource_table *rt, int cycles)
bfd_boolean resources_available (resource_table *rt, xtensa_opcode opcode, int cycle)
void reserve_resources (resource_table *rt, xtensa_opcode opcode, int cycle)
void release_resources (resource_table *rt, xtensa_opcode opcode, int cycle)
int opcode_funcUnit_use_unit (void *data, xtensa_opcode opcode, int idx)
int opcode_funcUnit_use_stage (void *data, xtensa_opcode opcode, int idx)
static bfd_boolean resources_conflict (vliw_insn *vinsn)
static bfd_boolean find_vinsn_conflicts (vliw_insn *)
static xtensa_format xg_find_narrowest_format (vliw_insn *)
static void xg_assemble_vliw_tokens (vliw_insn *)
static char check_t1_t2_reads_and_writes (TInsn *, TInsn *)
static int relaxation_requirements (vliw_insn *vinsn, bfd_boolean *pfinish_frag)
static void bundle_tinsn (TInsn *tinsn, vliw_insn *vinsn)
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)
static void xtensa_add_config_info (void)
void xtensa_end (void)
static bfd_boolean is_narrow_branch_guaranteed_in_range (fragS *, TInsn *)
static offsetT unrelaxed_frag_max_size (fragS *)
static bfd_boolean next_instrs_are_b_retw (fragS *)
static bfd_boolean next_instr_is_loop_end (fragS *)
static offsetT min_bytes_to_other_loop_end (fragS *, fragS *, offsetT)
static offsetT unrelaxed_frag_min_size (fragS *)
static int count_insns_to_loop_end (fragS *, bfd_boolean, int)
static bfd_boolean branch_before_loop_end (fragS *)
static int unrelaxed_frag_min_insn_count (fragS *)
static bfd_boolean unrelaxed_frag_has_b_j (fragS *)
static bfd_boolean is_empty_loop (const TInsn *, fragS *)
static bfd_boolean is_local_forward_loop (const TInsn *, fragS *)
static int get_text_align_fill_size (addressT address, int align_pow, int target_size, bfd_boolean use_nops, bfd_boolean use_no_density)
static int get_text_align_nop_count (offsetT fill_size, bfd_boolean use_no_density)
static int get_text_align_nth_nop_size (offsetT fill_size, int n, bfd_boolean use_no_density)
static addressT get_noop_aligned_address (fragS *fragP, addressT address)
static offsetT get_aligned_diff (fragS *fragP, addressT address, offsetT *max_diff)
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)
long xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p)
static long future_alignment_required (fragS *, long)
static addressT find_address_of_next_align_frag (fragS **fragPP, int *wide_nops, int *narrow_nops, int *widens, bfd_boolean *paddable)
static long bytes_to_stretch (fragS *, int, int, int, int)
static long future_alignment_required (fragS *fragP, long stretch ATTRIBUTE_UNUSED)
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 (bfd *abfd ATTRIBUTE_UNUSED, segT sec, fragS *fragp)
static fixS * fix_new_exp_in_seg (segT, subsegT, fragS *, int, int, expressionS *, int, bfd_reloc_code_real_type)
static void convert_frag_immed_finish_loop (segT, fragS *, TInsn *)
static subseg_mapget_subseg_info (segT seg, subsegT subseg)
static subseg_mapadd_subseg_info (segT seg, subsegT subseg)
static void xtensa_move_seg_list_to_beginning (seg_list *head)
static void mark_literal_frags (seg_list *)
static void xtensa_reorder_seg_list (seg_list *head, segT after)
static bfd_boolean match_section_group (bfd *abfd ATTRIBUTE_UNUSED, asection *sec, void *inf)
static bfd_boolean get_frag_is_literal (const fragS *)
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_typeretrieve_segment_info (segT)
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)
void xtensa_post_relax_hook (void)
static bfd_boolean xtensa_frag_flags_combinable (const frag_flags *prop_flags_1, const frag_flags *prop_flags_2)
static bfd_vma xt_block_aligned_size (const xtensa_block_info *xt_block)
static bfd_boolean xtensa_xt_block_combine (xtensa_block_info *xt_block, const xtensa_block_info *xt_block_2)
void istack_init (IStack *stack)
bfd_boolean istack_empty (IStack *stack)
bfd_boolean istack_full (IStack *stack)
TInsnistack_top (IStack *stack)
void istack_push (IStack *stack, TInsn *insn)
TInsnistack_push_space (IStack *stack)
void istack_pop (IStack *stack)
void tinsn_init (TInsn *dst)
static bfd_boolean tinsn_to_slotbuf (xtensa_format fmt, int slot, TInsn *tinsn, xtensa_insnbuf slotbuf)
static void tinsn_from_insnbuf (TInsn *tinsn, xtensa_insnbuf slotbuf, xtensa_format fmt, int slot)
char * xtensa_section_rename (char *name)

Variables

const char comment_chars [] = "#"
const char line_comment_chars [] = "#"
const char line_separator_chars [] = ";"
const char EXP_CHARS [] = "eE"
const char FLT_CHARS [] = "rRsSfFdDxXpP"
bfd_boolean density_supported = XCHAL_HAVE_DENSITY
bfd_boolean absolute_literals_supported = XSHAL_USE_ABSOLUTE_LITERALS
static vliw_insn cur_vinsn
unsigned xtensa_fetch_width = XCHAL_INST_FETCH_WIDTH
static lit_state default_lit_sections
static seg_list literal_head_h
static seg_listliteral_head = &literal_head_h
static sym_listinsn_labels = NULL
static sym_listfree_insn_labels = NULL
static sym_listsaved_insn_labels = NULL
static sym_listliteral_syms
int prefer_const16 = 0
int prefer_l32r = 0
int generating_literals = 0
op_placement_info_table op_placement_table
static struct suffix_reloc_map []
const directive_infoS directive_info []
bfd_boolean directive_state []
xtensa_isa xtensa_default_isa
int target_big_endian
static xtensa_opcode xtensa_addi_opcode
static xtensa_opcode xtensa_addmi_opcode
static xtensa_opcode xtensa_call0_opcode
static xtensa_opcode xtensa_call4_opcode
static xtensa_opcode xtensa_call8_opcode
static xtensa_opcode xtensa_call12_opcode
static xtensa_opcode xtensa_callx0_opcode
static xtensa_opcode xtensa_callx4_opcode
static xtensa_opcode xtensa_callx8_opcode
static xtensa_opcode xtensa_callx12_opcode
static xtensa_opcode xtensa_const16_opcode
static xtensa_opcode xtensa_entry_opcode
static xtensa_opcode xtensa_movi_opcode
static xtensa_opcode xtensa_movi_n_opcode
static xtensa_opcode xtensa_isync_opcode
static xtensa_opcode xtensa_jx_opcode
static xtensa_opcode xtensa_l32r_opcode
static xtensa_opcode xtensa_loop_opcode
static xtensa_opcode xtensa_loopnez_opcode
static xtensa_opcode xtensa_loopgtz_opcode
static xtensa_opcode xtensa_nop_opcode
static xtensa_opcode xtensa_nop_n_opcode
static xtensa_opcode xtensa_or_opcode
static xtensa_opcode xtensa_ret_opcode
static xtensa_opcode xtensa_ret_n_opcode
static xtensa_opcode xtensa_retw_opcode
static xtensa_opcode xtensa_retw_n_opcode
static xtensa_opcode xtensa_rsr_lcount_opcode
static xtensa_opcode xtensa_waiti_opcode
bfd_boolean use_literal_section = TRUE
static bfd_boolean align_targets = TRUE
static bfd_boolean warn_unaligned_branch_targets = FALSE
static bfd_boolean has_a0_b_retw = FALSE
static bfd_boolean workaround_a0_b_retw = FALSE
static bfd_boolean workaround_b_j_loop_end = FALSE
static bfd_boolean workaround_short_loop = FALSE
static bfd_boolean maybe_has_short_loop = FALSE
static bfd_boolean workaround_close_loop_end = FALSE
static bfd_boolean maybe_has_close_loop_end = FALSE
static bfd_boolean enforce_three_byte_loop_align = FALSE
static bfd_boolean workaround_all_short_loops = FALSE
const char * md_shortopts = ""
size_t md_longopts_size = sizeof md_longopts
state_stackSdirective_state_stack
const pseudo_typeS md_pseudo_table []
static int linkonce_len = sizeof (".gnu.linkonce.") - 1
static subseg_mapsseg_map = NULL
static struct
rename_section_struct
section_rename

Class Documentation

struct lit_state_struct

Definition at line 115 of file tc-xtensa.c.

Collaboration diagram for lit_state_struct:
Class Members
segT current_text_seg
segT lit4_seg
char * lit_prefix
segT lit_seg
struct seg_list_struct

Definition at line 130 of file tc-xtensa.c.

Collaboration diagram for seg_list_struct:
Class Members
struct seg_list_struct * next
segT seg
struct sym_list_struct

Definition at line 146 of file tc-xtensa.c.

Collaboration diagram for sym_list_struct:
Class Members
struct sym_list_struct * next
symbolS * sym
struct frag_flags_struct

Definition at line 255 of file tc-xtensa.c.

Class Members
unsigned alignment: 5
struct frag_flags_struct insn
unsigned is_align: 1
unsigned is_data: 1
unsigned is_insn: 1
unsigned is_literal: 1
unsigned is_unreachable: 1
struct xtensa_block_info_struct

Definition at line 289 of file tc-xtensa.c.

Collaboration diagram for xtensa_block_info_struct:
Class Members
frag_flags flags
struct xtensa_block_info_struct * next
bfd_vma offset
segT sec
size_t size
struct emit_state_struct

Definition at line 300 of file tc-xtensa.c.

Collaboration diagram for emit_state_struct:
Class Members
int generating_literals
const char * name
segT now_seg
subsegT now_subseg
struct op_placement_info_struct

Definition at line 318 of file tc-xtensa.c.

Class Members
bitfield formats
int issuef
xtensa_format narrowest
char narrowest_size
char narrowest_slot
int num_formats
bitfield slots
char slots_in_format
struct suffix_reloc_map

Definition at line 355 of file tc-xtensa.c.

Class Members
int length
unsigned char operator
bfd_reloc_code_real_type reloc
char * suffix
struct directive_infoS

Definition at line 390 of file tc-xtensa.c.

Class Members
bfd_boolean can_be_negated
const char * name
struct state_stackS_struct

Definition at line 978 of file tc-xtensa.c.

Collaboration diagram for state_stackS_struct:
Class Members
const void * datum
directiveE directive
const char * file
unsigned int line
bfd_boolean negated
bfd_boolean old_state
struct state_stackS_struct * prev
struct subseg_map_struct

Definition at line 9568 of file tc-xtensa.c.

Collaboration diagram for subseg_map_struct:
Class Members
unsigned flags
struct subseg_map_struct * next
segT seg
subsegT subseg
float target_freq
float total_freq
struct rename_section_struct

Definition at line 11607 of file tc-xtensa.c.

Collaboration diagram for rename_section_struct:
Class Members
char * new_name
struct rename_section_struct * next
char * old_name
struct frag_flags_struct.insn

Definition at line 266 of file tc-xtensa.c.

Class Members
unsigned bt_align_priority: 2
unsigned is_abslit: 1
unsigned is_branch_target: 1
unsigned is_loop_target: 1
unsigned is_no_density: 1
unsigned is_no_reorder: 1
unsigned is_no_transform: 1

Define Documentation

#define bit_is_set (   bit,
  bf 
)    ((bf) & (0x01ll << (bit)))

Definition at line 312 of file tc-xtensa.c.

#define clear_bit (   bit,
  bf 
)    ((bf) &= ~(0x01ll << (bit)))

Definition at line 314 of file tc-xtensa.c.

#define ERROR_REG_NUM   ((unsigned) -1)

Definition at line 1688 of file tc-xtensa.c.

#define FINI_SECTION_NAME   xtensa_section_rename (".fini")

Definition at line 104 of file tc-xtensa.c.

#define FLAG_IS_A0_WRITER   0x1

Definition at line 92 of file tc-xtensa.c.

#define FLAG_IS_BAD_LOOPEND   0x2

Definition at line 93 of file tc-xtensa.c.

#define GET_XTENSA_PROP_ALIGNMENT (   flag)    (((unsigned) ((flag) & (XTENSA_PROP_ALIGNMENT_MASK))) >> 12)

Definition at line 238 of file tc-xtensa.c.

#define GET_XTENSA_PROP_BT_ALIGN (   flag)    (((unsigned) ((flag) & (XTENSA_PROP_BT_ALIGN_MASK))) >> 9)

Definition at line 216 of file tc-xtensa.c.

#define INIT_SECTION_NAME   xtensa_section_rename (".init")

Definition at line 103 of file tc-xtensa.c.

#define int32   signed int

Definition at line 42 of file tc-xtensa.c.

#define LIT4_SECTION_NAME   xtensa_section_rename (".lit4")

Definition at line 102 of file tc-xtensa.c.

#define LITERAL_SECTION_NAME   xtensa_section_rename (".literal")

Definition at line 101 of file tc-xtensa.c.

#define LOOP_IMMED_OPN   1

Definition at line 7730 of file tc-xtensa.c.

#define MAX_FORMATS   32

Definition at line 316 of file tc-xtensa.c.

#define MAX_IMMED6   65

Definition at line 7054 of file tc-xtensa.c.

#define O_hi16   O_md2 /* use high 16 bits of symbolic value */

Definition at line 352 of file tc-xtensa.c.

#define O_lo16   O_md3 /* use low 16 bits of symbolic value */

Definition at line 353 of file tc-xtensa.c.

#define O_pltrel   O_md1 /* like O_symbol but use a PLT reloc */

Definition at line 351 of file tc-xtensa.c.

#define set_bit (   bit,
  bf 
)    ((bf) |= (0x01ll << (bit)))

Definition at line 313 of file tc-xtensa.c.

#define SET_XTENSA_PROP_ALIGNMENT (   flag,
  align 
)
Value:

Definition at line 240 of file tc-xtensa.c.

#define SET_XTENSA_PROP_BT_ALIGN (   flag,
  align 
)
Value:

Definition at line 218 of file tc-xtensa.c.

#define SUFFIX_MAP (   str,
  reloc,
  op 
)    { str, sizeof (str) - 1, reloc, op }

Definition at line 363 of file tc-xtensa.c.

#define uint32   unsigned int

Definition at line 39 of file tc-xtensa.c.

#define UNREACHABLE_MAX_WIDTH   8

Definition at line 78 of file tc-xtensa.c.

#define XSHAL_ABI   0

Definition at line 35 of file tc-xtensa.c.

#define XTENSA_INSN_SEC_NAME   ".xt.insn"

Definition at line 10115 of file tc-xtensa.c.

#define XTENSA_LIT_SEC_NAME   ".xt.lit"

Definition at line 10116 of file tc-xtensa.c.

#define XTENSA_PROP_ALIGN   0x00000800

Definition at line 234 of file tc-xtensa.c.

#define XTENSA_PROP_ALIGNMENT_MASK   0x0001f000

Definition at line 236 of file tc-xtensa.c.

#define XTENSA_PROP_BT_ALIGN_HIGH   0x2

Definition at line 212 of file tc-xtensa.c.

#define XTENSA_PROP_BT_ALIGN_LOW   0x1

Definition at line 210 of file tc-xtensa.c.

#define XTENSA_PROP_BT_ALIGN_MASK   0x00000600

Definition at line 205 of file tc-xtensa.c.

#define XTENSA_PROP_BT_ALIGN_NONE   0x0

Definition at line 208 of file tc-xtensa.c.

#define XTENSA_PROP_BT_ALIGN_REQUIRE   0x3

Definition at line 214 of file tc-xtensa.c.

#define XTENSA_PROP_DATA   0x00000004

Definition at line 182 of file tc-xtensa.c.

#define XTENSA_PROP_INSN   0x00000002

Definition at line 181 of file tc-xtensa.c.

#define XTENSA_PROP_INSN_ABSLIT   0x00020000

Definition at line 244 of file tc-xtensa.c.

#define XTENSA_PROP_INSN_BRANCH_TARGET   0x00000020

Definition at line 186 of file tc-xtensa.c.

#define XTENSA_PROP_INSN_LOOP_TARGET   0x00000010

Definition at line 185 of file tc-xtensa.c.

#define XTENSA_PROP_INSN_NO_DENSITY   0x00000040

Definition at line 188 of file tc-xtensa.c.

#define XTENSA_PROP_INSN_NO_REORDER   0x00000080

Definition at line 189 of file tc-xtensa.c.

#define XTENSA_PROP_INSN_NO_TRANSFORM   0x00000100

Definition at line 190 of file tc-xtensa.c.

#define XTENSA_PROP_LITERAL   0x00000001

Definition at line 180 of file tc-xtensa.c.

#define XTENSA_PROP_SEC_NAME   ".xt.prop"

Definition at line 10117 of file tc-xtensa.c.

#define XTENSA_PROP_UNREACHABLE   0x00000008

Definition at line 183 of file tc-xtensa.c.

#define XTINFO_NAME   "Xtensa_Info"

Definition at line 7824 of file tc-xtensa.c.

#define XTINFO_NAMESZ   12

Definition at line 7825 of file tc-xtensa.c.

#define XTINFO_TYPE   1

Definition at line 7826 of file tc-xtensa.c.


Typedef Documentation

Definition at line 311 of file tc-xtensa.c.

typedef void(* frag_flags_fn)(const fragS *, frag_flags *)

Definition at line 10120 of file tc-xtensa.c.

Definition at line 253 of file tc-xtensa.c.

typedef bfd_boolean(* frag_predicate)(const fragS *)

Definition at line 10119 of file tc-xtensa.c.


Enumeration Type Documentation

anonymous enum
Enumerator:
option_density 
option_no_density 
option_relax 
option_no_relax 
option_link_relax 
option_no_link_relax 
option_generics 
option_no_generics 
option_transform 
option_no_transform 
option_text_section_literals 
option_no_text_section_literals 
option_absolute_literals 
option_no_absolute_literals 
option_align_targets 
option_no_align_targets 
option_warn_unaligned_targets 
option_longcalls 
option_no_longcalls 
option_workaround_a0_b_retw 
option_no_workaround_a0_b_retw 
option_workaround_b_j_loop_end 
option_no_workaround_b_j_loop_end 
option_workaround_short_loop 
option_no_workaround_short_loop 
option_workaround_all_short_loops 
option_no_workaround_all_short_loops 
option_workaround_close_loop_end 
option_no_workaround_close_loop_end 
option_no_workarounds 
option_rename_section_name 
option_prefer_l32r 
option_prefer_const16 
option_target_hardware 

Definition at line 614 of file tc-xtensa.c.

enum directiveE
Enumerator:
directive_none 
directive_literal 
directive_density 
directive_transform 
directive_freeregs 
directive_longcalls 
directive_literal_prefix 
directive_schedule 
directive_absolute_literals 
directive_last_directive 

Definition at line 376 of file tc-xtensa.c.


Function Documentation

static subseg_map* add_subseg_info ( segT  seg,
subsegT  subseg 
) [static]

Definition at line 9600 of file tc-xtensa.c.

{
  subseg_map *subseg_e = (subseg_map *) xmalloc (sizeof (subseg_map));
  memset (subseg_e, 0, sizeof (subseg_map));
  subseg_e->seg = seg;
  subseg_e->subseg = subseg;
  subseg_e->flags = 0;
  /* Start off considering every branch target very important.  */
  subseg_e->target_freq = 1.0;
  subseg_e->total_freq = 1.0;
  subseg_e->next = sseg_map;
  sseg_map = subseg_e;
  return subseg_e;
}

Here is the call graph for this function:

Here is the caller graph for this 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 
) [static]

Definition at line 10519 of file tc-xtensa.c.

{
  segment_info_type *seg_info;
  segment_info_type *xt_seg_info;
  bfd_vma seg_offset;
  fragS *fragP;

  xt_seg_info = retrieve_segment_info (xt_block_sec);
  seg_info = retrieve_segment_info (sec);

  /* Build it if needed.  */
  while (*xt_block != NULL)
    xt_block = &(*xt_block)->next;
  /* We are either at NULL at the beginning or at the end.  */

  /* Walk through the frags.  */
  seg_offset = 0;

  if (seg_info->frchainP)
    {
      for (fragP = seg_info->frchainP->frch_root;
          fragP;
          fragP = fragP->fr_next)
       {
         if (property_function (fragP)
             && (fragP->fr_type != rs_fill || fragP->fr_fix != 0))
           {
             if (*xt_block != NULL)
              {
                if ((*xt_block)->offset + (*xt_block)->size
                    == fragP->fr_address)
                  (*xt_block)->size += fragP->fr_fix;
                else
                  xt_block = &((*xt_block)->next);
              }
             if (*xt_block == NULL)
              {
                xtensa_block_info *new_block = (xtensa_block_info *)
                  xmalloc (sizeof (xtensa_block_info));
                new_block->sec = sec;
                new_block->offset = fragP->fr_address;
                new_block->size = fragP->fr_fix;
                new_block->next = NULL;
                xtensa_frag_flags_init (&new_block->flags);
                *xt_block = new_block;
              }
             if (end_property_function
                && end_property_function (fragP))
              {
                xt_block = &((*xt_block)->next);
              }
           }
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void add_xt_prop_frags ( segT  sec,
segT  xt_block_sec,
xtensa_block_info **  xt_block,
frag_flags_fn  property_function 
) [static]

Definition at line 10779 of file tc-xtensa.c.

{
  segment_info_type *seg_info;
  segment_info_type *xt_seg_info;
  bfd_vma seg_offset;
  fragS *fragP;

  xt_seg_info = retrieve_segment_info (xt_block_sec);
  seg_info = retrieve_segment_info (sec);
  /* Build it if needed.  */
  while (*xt_block != NULL)
    {
      xt_block = &(*xt_block)->next;
    }
  /* We are either at NULL at the beginning or at the end.  */

  /* Walk through the frags.  */
  seg_offset = 0;

  if (seg_info->frchainP)
    {
      for (fragP = seg_info->frchainP->frch_root; fragP;
          fragP = fragP->fr_next)
       {
         xtensa_block_info tmp_block;
         tmp_block.sec = sec;
         tmp_block.offset = fragP->fr_address;
         tmp_block.size = fragP->fr_fix;
         tmp_block.next = NULL;
         property_function (fragP, &tmp_block.flags);

         if (!xtensa_frag_flags_is_empty (&tmp_block.flags))
           /* && fragP->fr_fix != 0) */
           {
             if ((*xt_block) == NULL
                || !xtensa_xt_block_combine (*xt_block, &tmp_block))
              {
                xtensa_block_info *new_block;
                if ((*xt_block) != NULL)
                  xt_block = &(*xt_block)->next;
                new_block = (xtensa_block_info *)
                  xmalloc (sizeof (xtensa_block_info));
                *new_block = tmp_block;
                *xt_block = new_block;
              }
           }
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void assemble_nop ( int  size,
char *  buf 
) [static]

Definition at line 4608 of file tc-xtensa.c.

{
  static xtensa_insnbuf insnbuf = NULL;
  TInsn tinsn;

  build_nop (&tinsn, size);

  if (!insnbuf)
    insnbuf = xtensa_insnbuf_alloc (xtensa_default_isa);

  tinsn_to_insnbuf (&tinsn, insnbuf);
  xtensa_insnbuf_to_chars (xtensa_default_isa, insnbuf,
                        (unsigned char *) buf, 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int branch_align_power ( segT  sec) [static]

Definition at line 7952 of file tc-xtensa.c.

{
  /* If the Xtensa processor has a fetch width of 8 bytes, and the section
     is aligned to at least an 8-byte boundary, then a branch target need
     only fit within an 8-byte aligned block of memory to avoid a stall.
     Otherwise, try to fit branch targets within 4-byte aligned blocks
     (which may be insufficient, e.g., if the section has no alignment, but
     it's good enough).  */
  if (xtensa_fetch_width == 8)
    {
      if (get_recorded_alignment (sec) >= 3)
       return 3;
    }
  else
    assert (xtensa_fetch_width == 4);

  return 2;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean branch_before_loop_end ( fragS *  base_fragP) [static]

Definition at line 7617 of file tc-xtensa.c.

{
  fragS *fragP;

  for (fragP = base_fragP;
       fragP && !fragP->tc_frag_data.is_loop_target;
       fragP = fragP->fr_next)
    {
      if (unrelaxed_frag_has_b_j (fragP))
       return TRUE;
    }
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void build_nop ( TInsn tinsn,
int  size 
) [static]

Definition at line 4575 of file tc-xtensa.c.

{
  tinsn_init (tinsn);
  switch (size)
    {
    case 2:
      tinsn->opcode = xtensa_nop_n_opcode;
      tinsn->ntok = 0;
      if (tinsn->opcode == XTENSA_UNDEFINED)
       as_fatal (_("opcode 'NOP.N' unavailable in this configuration"));
      break;

    case 3:
      if (xtensa_nop_opcode == XTENSA_UNDEFINED)
       {
         tinsn->opcode = xtensa_or_opcode;
         set_expr_const (&tinsn->tok[0], 1);
         set_expr_const (&tinsn->tok[1], 1);
         set_expr_const (&tinsn->tok[2], 1);
         tinsn->ntok = 3;
       }
      else
       tinsn->opcode = xtensa_nop_opcode;

      assert (tinsn->opcode != XTENSA_UNDEFINED);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void build_section_rename ( const char *  arg) [static]

Definition at line 11623 of file tc-xtensa.c.

{
  struct rename_section_struct *r;
  char *this_arg = NULL;
  char *next_arg = NULL;

  for (this_arg = xstrdup (arg); this_arg != NULL; this_arg = next_arg)
    {
      char *old_name, *new_name;

      if (this_arg)
       {
         next_arg = strchr (this_arg, ':');
         if (next_arg)
           {
             *next_arg = '\0';
             next_arg++;
           }
       }

      old_name = this_arg;
      new_name = strchr (this_arg, '=');

      if (*old_name == '\0')
       {
         as_warn (_("ignoring extra '-rename-section' delimiter ':'"));
         continue;
       }
      if (!new_name || new_name[1] == '\0')
       {
         as_warn (_("ignoring invalid '-rename-section' specification: '%s'"),
                 old_name);
         continue;
       }
      *new_name = '\0';
      new_name++;

      /* Check for invalid section renaming.  */
      for (r = section_rename; r != NULL; r = r->next)
       {
         if (strcmp (r->old_name, old_name) == 0)
           as_bad (_("section %s renamed multiple times"), old_name);
         if (strcmp (r->new_name, new_name) == 0)
           as_bad (_("multiple sections remapped to output section %s"),
                  new_name);
       }

      /* Now add it.  */
      r = (struct rename_section_struct *)
       xmalloc (sizeof (struct rename_section_struct));
      r->old_name = xstrdup (old_name);
      r->new_name = xstrdup (new_name);
      r->next = section_rename;
      section_rename = r;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void bundle_tinsn ( TInsn tinsn,
vliw_insn vinsn 
) [static]

Definition at line 6493 of file tc-xtensa.c.

{
  xtensa_isa isa = xtensa_default_isa;
  int slot, chosen_slot;

  vinsn->format = xg_get_single_format (tinsn->opcode);
  assert (vinsn->format != XTENSA_UNDEFINED);
  vinsn->num_slots = xtensa_format_num_slots (isa, vinsn->format);

  chosen_slot = xg_get_single_slot (tinsn->opcode);
  for (slot = 0; slot < vinsn->num_slots; slot++)
    {
      if (slot == chosen_slot)
       vinsn->slots[slot] = *tinsn;
      else
       {
         vinsn->slots[slot].opcode =
           xtensa_format_slot_nop_opcode (isa, vinsn->format, slot);
         vinsn->slots[slot].ntok = 0;
         vinsn->slots[slot].insn_type = ITYPE_INSN;
       }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long bytes_to_stretch ( fragS *  this_frag,
int  wide_nops,
int  narrow_nops,
int  num_widens,
int  desired_diff 
) [static]

Definition at line 8660 of file tc-xtensa.c.

{
  int bytes_short = desired_diff - num_widens;

  assert (desired_diff >= 0 && desired_diff < 8);
  if (desired_diff == 0)
    return 0;

  assert (wide_nops > 0 || num_widens > 0);

  /* Always prefer widening to NOP-filling.  */
  if (bytes_short < 0)
    {
      /* There are enough RELAX_NARROW frags after this one
        to align the target without widening this frag in any way.  */
      return 0;
    }

  if (bytes_short == 0)
    {
      /* Widen every narrow between here and the align target
        and the align target will be properly aligned.  */
      if (this_frag->fr_subtype == RELAX_FILL_NOP)
       return 0;
      else
       return 1;
    }

  /* From here we will need at least one NOP to get an alignment.
     However, we may not be able to align at all, in which case,
     don't widen.  */
  if (this_frag->fr_subtype == RELAX_FILL_NOP)
    {
      switch (desired_diff)
       {
       case 1:
         return 0;
       case 2:
         if (!this_frag->tc_frag_data.is_no_density && narrow_nops == 1)
           return 2; /* case 2 */
         return 0;
       case 3:
         if (wide_nops > 1)
           return 0;
         else
           return 3; /* case 3a */
       case 4:
         if (num_widens >= 1 && wide_nops == 1)
           return 3; /* case 4a */
         if (!this_frag->tc_frag_data.is_no_density && narrow_nops == 2)
           return 2; /* case 4b */
         return 0;
       case 5:
         if (num_widens >= 2 && wide_nops == 1)
           return 3; /* case 5a */
         /* We will need two nops.  Are there enough nops
            between here and the align target?  */
         if (wide_nops < 2 || narrow_nops == 0)
           return 0;
         /* Are there other nops closer that can serve instead?  */
         if (wide_nops > 2 && narrow_nops > 1)
           return 0;
         /* Take the density one first, because there might not be
            another density one available.  */
         if (!this_frag->tc_frag_data.is_no_density)
           return 2; /* case 5b narrow */
         else
           return 3; /* case 5b wide */
         return 0;
       case 6:
         if (wide_nops == 2)
           return 3; /* case 6a */
         else if (num_widens >= 3 && wide_nops == 1)
           return 3; /* case 6b */
         return 0;
       case 7:
         if (wide_nops == 1 && num_widens >= 4)
           return 3; /* case 7a */
         else if (wide_nops == 2 && num_widens >= 1)
           return 3; /* case 7b */
         return 0;
       default:
         assert (0);
       }
    }
  else
    {
      /* We will need a NOP no matter what, but should we widen
        this instruction to help?

        This is a RELAX_NARROW frag.  */
      switch (desired_diff)
       {
       case 1:
         assert (0);
         return 0;
       case 2:
       case 3:
         return 0;
       case 4:
         if (wide_nops >= 1 && num_widens == 1)
           return 1; /* case 4a */
         return 0;
       case 5:
         if (wide_nops >= 1 && num_widens == 2)
           return 1; /* case 5a */
         return 0;
       case 6:
         if (wide_nops >= 2)
           return 0; /* case 6a */
         else if (wide_nops >= 1 && num_widens == 3)
           return 1; /* case 6b */
         return 0;
       case 7:
         if (wide_nops >= 1 && num_widens == 4)
           return 1; /* case 7a */
         else if (wide_nops >= 2 && num_widens == 1)
           return 1; /* case 7b */
         return 0;
       default:
         assert (0);
         return 0;
       }
    }
  assert (0);
  return 0;
}

Here is the caller graph for this function:

static segT cache_literal_section ( bfd_boolean  use_abs_literals) [static]

Definition at line 10006 of file tc-xtensa.c.

{
  const char *text_name, *group_name = 0;
  char *base_name, *name, *suffix;
  segT *pcached;
  segT seg, current_section;
  int current_subsec;
  bfd_boolean linkonce = FALSE;

  /* Save the current section/subsection.  */
  current_section = now_seg;
  current_subsec = now_subseg;

  /* Clear the cached values if they are no longer valid.  */
  if (now_seg != default_lit_sections.current_text_seg)
    {
      default_lit_sections.current_text_seg = now_seg;
      default_lit_sections.lit_seg = NULL;
      default_lit_sections.lit4_seg = NULL;
    }

  /* Check if the literal section is already cached.  */
  if (use_abs_literals)
    pcached = &default_lit_sections.lit4_seg;
  else
    pcached = &default_lit_sections.lit_seg;

  if (*pcached)
    return *pcached;
  
  text_name = default_lit_sections.lit_prefix;
  if (! text_name || ! *text_name)
    {
      text_name = segment_name (current_section);
      group_name = elf_group_name (current_section);
      linkonce = (current_section->flags & SEC_LINK_ONCE) != 0;
    }

  base_name = use_abs_literals ? ".lit4" : ".literal";
  if (group_name)
    {
      name = xmalloc (strlen (base_name) + strlen (group_name) + 2);
      sprintf (name, "%s.%s", base_name, group_name);
    }
  else if (strncmp (text_name, ".gnu.linkonce.", linkonce_len) == 0)
    {
      suffix = strchr (text_name + linkonce_len, '.');

      name = xmalloc (linkonce_len + strlen (base_name) + 1
                    + (suffix ? strlen (suffix) : 0));
      strcpy (name, ".gnu.linkonce");
      strcat (name, base_name);
      if (suffix)
       strcat (name, suffix);
      linkonce = TRUE;
    }
  else
    {
      /* If the section name ends with ".text", then replace that suffix
        instead of appending an additional suffix.  */
      size_t len = strlen (text_name);
      if (len >= 5 && strcmp (text_name + len - 5, ".text") == 0)
       len -= 5;

      name = xmalloc (len + strlen (base_name) + 1);
      strcpy (name, text_name);
      strcpy (name + len, base_name);
    }

  /* Canonicalize section names to allow renaming literal sections.
     The group name, if any, came from the current text section and
     has already been canonicalized.  */
  name = tc_canonicalize_symbol_name (name);

  seg = bfd_get_section_by_name_if (stdoutput, name, match_section_group,
                                (void *) group_name);
  if (! seg)
    {
      flagword flags;

      seg = subseg_force_new (name, 0);

      if (! use_abs_literals)
       {
         /* Add the newly created literal segment to the list.  */
         seg_list *n = (seg_list *) xmalloc (sizeof (seg_list));
         n->seg = seg;
         n->next = literal_head->next;
         literal_head->next = n;
       }

      flags = (SEC_HAS_CONTENTS | SEC_READONLY | SEC_ALLOC | SEC_LOAD
              | (linkonce ? (SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD) : 0)
              | (use_abs_literals ? SEC_DATA : SEC_CODE));

      elf_group_name (seg) = group_name;

      bfd_set_section_flags (stdoutput, seg, flags);
      bfd_set_section_alignment (stdoutput, seg, 2);
    }

  *pcached = seg;
  subseg_set (current_section, current_subsec);
  return seg;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char check_t1_t2_reads_and_writes ( TInsn t1,
TInsn t2 
) [static]

Definition at line 6197 of file tc-xtensa.c.

{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_regfile t1_regfile, t2_regfile;
  int t1_reg, t2_reg;
  int t1_base_reg, t1_last_reg;
  int t2_base_reg, t2_last_reg;
  char t1_inout, t2_inout;
  int i, j;
  char conflict = 'b';
  int t1_states;
  int t2_states;
  int t1_interfaces;
  int t2_interfaces;
  bfd_boolean t1_volatile = FALSE;
  bfd_boolean t2_volatile = FALSE;

  /* Check registers.  */
  for (j = 0; j < t2->ntok; j++)
    {
      if (xtensa_operand_is_register (isa, t2->opcode, j) != 1)
       continue;

      t2_regfile = xtensa_operand_regfile (isa, t2->opcode, j);
      t2_base_reg = t2->tok[j].X_add_number;
      t2_last_reg = t2_base_reg + xtensa_operand_num_regs (isa, t2->opcode, j);

      for (i = 0; i < t1->ntok; i++)
       {
         if (xtensa_operand_is_register (isa, t1->opcode, i) != 1)
           continue;

         t1_regfile = xtensa_operand_regfile (isa, t1->opcode, i);

         if (t1_regfile != t2_regfile)
           continue;

         t1_inout = xtensa_operand_inout (isa, t1->opcode, i);
         t2_inout = xtensa_operand_inout (isa, t2->opcode, j);

         if (xtensa_operand_is_known_reg (isa, t1->opcode, i) == 0
             || xtensa_operand_is_known_reg (isa, t2->opcode, j) == 0)
           {
             if (t1_inout == 'm' || t1_inout == 'o'
                || t2_inout == 'm' || t2_inout == 'o')
              {
                conflict = 'a';
                continue;
              }
           }

         t1_base_reg = t1->tok[i].X_add_number;
         t1_last_reg = (t1_base_reg
                      + xtensa_operand_num_regs (isa, t1->opcode, i));

         for (t1_reg = t1_base_reg; t1_reg < t1_last_reg; t1_reg++)
           {
             for (t2_reg = t2_base_reg; t2_reg < t2_last_reg; t2_reg++)
              {
                if (t1_reg != t2_reg)
                  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);
      int t2_class = xtensa_interface_class_id (isa, t2_int);

      t2_inout = xtensa_interface_inout (isa, t2_int);
      if (xtensa_interface_has_side_effect (isa, t2_int) == 1)
       t2_volatile = TRUE;

      for (i = 0; i < t1_interfaces; i++)
       {
         xtensa_interface t1_int
           = xtensa_interfaceOperand_interface (isa, t1->opcode, j);
         int t1_class = xtensa_interface_class_id (isa, t1_int);

         t1_inout = xtensa_interface_inout (isa, t1_int);
         if (xtensa_interface_has_side_effect (isa, t1_int) == 1)
           t1_volatile = TRUE;

         if (t1_volatile && t2_volatile && (t1_class == t2_class))
           return 'f';

         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 conflict;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5756 of file tc-xtensa.c.

{
  int i, j;
  for (i = 0; i < rt->allocated_cycles; i++)
    for (j = 0; j < rt->num_units; j++)
      rt->units[i][j] = 0;
}

Here is the caller graph for this function:

static void convert_frag_align_next_opcode ( fragS *  fragp) [static]

Definition at line 9046 of file tc-xtensa.c.

{
  char *nop_buf;            /* Location for Writing.  */
  bfd_boolean use_no_density = fragp->tc_frag_data.is_no_density;
  addressT aligned_address;
  offsetT fill_size;
  int nop, nop_count;

  aligned_address = get_noop_aligned_address (fragp, fragp->fr_address +
                                         fragp->fr_fix);
  fill_size = aligned_address - (fragp->fr_address + fragp->fr_fix);
  nop_count = get_text_align_nop_count (fill_size, use_no_density);
  nop_buf = fragp->fr_literal + fragp->fr_fix;

  for (nop = 0; nop < nop_count; nop++)
    {
      int nop_size;
      nop_size = get_text_align_nth_nop_size (fill_size, nop, use_no_density);

      assemble_nop (nop_size, nop_buf);
      nop_buf += nop_size;
    }

  fragp->fr_fix += fill_size;
  fragp->fr_var -= fill_size;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void convert_frag_fill_nop ( fragS *  fragP) [static]

Definition at line 9135 of file tc-xtensa.c.

{
  char *loc = &fragP->fr_literal[fragP->fr_fix];
  int size = fragP->tc_frag_data.text_expansion[0];
  assert ((unsigned) size == (fragP->fr_next->fr_address
                           - fragP->fr_address - fragP->fr_fix));
  if (size == 0)
    {
      /* No conversion.  */
      fragP->fr_var = 0;
      return;
    }
  assemble_nop (size, loc);
  fragP->tc_frag_data.is_insn = TRUE;
  fragP->fr_var -= size;
  fragP->fr_fix += size;
  frag_wane (fragP);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void convert_frag_immed ( segT  segP,
fragS *  fragP,
int  min_steps,
xtensa_format  fmt,
int  slot 
) [static]

Definition at line 9161 of file tc-xtensa.c.

{
  char *immed_instr = fragP->fr_opcode;
  TInsn orig_tinsn;
  bfd_boolean expanded = FALSE;
  bfd_boolean branch_jmp_to_next = FALSE;
  char *fr_opcode = fragP->fr_opcode;
  xtensa_isa isa = xtensa_default_isa;
  bfd_boolean wide_insn = FALSE;
  int bytes;
  bfd_boolean is_loop;

  assert (fr_opcode != NULL);

  xg_clear_vinsn (&cur_vinsn);

  vinsn_from_chars (&cur_vinsn, fr_opcode);
  if (cur_vinsn.num_slots > 1)
    wide_insn = TRUE;

  orig_tinsn = cur_vinsn.slots[slot];
  tinsn_immed_from_frag (&orig_tinsn, fragP, slot);

  is_loop = xtensa_opcode_is_loop (xtensa_default_isa, orig_tinsn.opcode) == 1;

  if (workaround_b_j_loop_end && ! fragP->tc_frag_data.is_no_transform)
    branch_jmp_to_next = is_branch_jmp_to_next (&orig_tinsn, fragP);

  if (branch_jmp_to_next && !next_frag_is_loop_target (fragP))
    {
      /* Conversion just inserts a NOP and marks the fix as completed.  */
      bytes = xtensa_format_length (isa, fmt);
      if (bytes >= 4)
       {
         cur_vinsn.slots[slot].opcode =
           xtensa_format_slot_nop_opcode (isa, cur_vinsn.format, slot);
         cur_vinsn.slots[slot].ntok = 0;
       }
      else
       {
         bytes += fragP->tc_frag_data.text_expansion[0];
         assert (bytes == 2 || bytes == 3);
         build_nop (&cur_vinsn.slots[0], bytes);
         fragP->fr_fix += fragP->tc_frag_data.text_expansion[0];
       }
      vinsn_to_insnbuf (&cur_vinsn, fr_opcode, frag_now, TRUE);
      xtensa_insnbuf_to_chars
       (isa, cur_vinsn.insnbuf, (unsigned char *) fr_opcode, 0);
      fragP->fr_var = 0;
    }
  else
    {
      /* Here is the fun stuff:  Get the immediate field from this
        instruction.  If it fits, we're done.  If not, find the next
        instruction sequence that fits.  */

      IStack istack;
      int i;
      symbolS *lit_sym = NULL;
      int total_size = 0;
      int target_offset = 0;
      int old_size;
      int diff;
      symbolS *gen_label = NULL;
      offsetT frag_offset;
      bfd_boolean first = TRUE;
      bfd_boolean last_is_jump;

      /* It does not fit.  Find something that does and
         convert immediately.  */
      frag_offset = fr_opcode - fragP->fr_literal;
      istack_init (&istack);
      xg_assembly_relax (&istack, &orig_tinsn,
                      segP, fragP, frag_offset, min_steps, 0);

      old_size = xtensa_format_length (isa, fmt);

      /* Assemble this right inline.  */

      /* First, create the mapping from a label name to the REAL label.  */
      target_offset = 0;
      for (i = 0; i < istack.ninsn; i++)
       {
         TInsn *tinsn = &istack.insn[i];
         fragS *lit_frag;

         switch (tinsn->insn_type)
           {
           case ITYPE_LITERAL:
             if (lit_sym != NULL)
              as_bad (_("multiple literals in expansion"));
             /* First find the appropriate space in the literal pool.  */
             lit_frag = fragP->tc_frag_data.literal_frags[slot];
             if (lit_frag == NULL)
              as_bad (_("no registered fragment for literal"));
             if (tinsn->ntok != 1)
              as_bad (_("number of literal tokens != 1"));

             /* Set the literal symbol and add a fixup.  */
             lit_sym = lit_frag->fr_symbol;
             break;

           case ITYPE_LABEL:
             if (align_targets && !is_loop)
              {
                fragS *unreach = fragP->fr_next;
                while (!(unreach->fr_type == rs_machine_dependent
                        && (unreach->fr_subtype == RELAX_MAYBE_UNREACHABLE
                            || unreach->fr_subtype == RELAX_UNREACHABLE)))
                  {
                    unreach = unreach->fr_next;
                  }

                assert (unreach->fr_type == rs_machine_dependent
                       && (unreach->fr_subtype == RELAX_MAYBE_UNREACHABLE
                           || unreach->fr_subtype == RELAX_UNREACHABLE));

                target_offset += unreach->tc_frag_data.text_expansion[0];
              }
             assert (gen_label == NULL);
             gen_label = symbol_new (FAKE_LABEL_NAME, now_seg,
                                  fr_opcode - fragP->fr_literal
                                  + target_offset, fragP);
             break;

           case ITYPE_INSN:
             if (first && wide_insn)
              {
                target_offset += xtensa_format_length (isa, fmt);
                first = FALSE;
                if (!opcode_fits_format_slot (tinsn->opcode, fmt, slot))
                  target_offset += xg_get_single_size (tinsn->opcode);
              }
             else
              target_offset += xg_get_single_size (tinsn->opcode);
             break;
           }
       }

      total_size = 0;
      first = TRUE;
      last_is_jump = FALSE;
      for (i = 0; i < istack.ninsn; i++)
       {
         TInsn *tinsn = &istack.insn[i];
         fragS *lit_frag;
         int size;
         segT target_seg;
         bfd_reloc_code_real_type reloc_type;

         switch (tinsn->insn_type)
           {
           case ITYPE_LITERAL:
             lit_frag = fragP->tc_frag_data.literal_frags[slot];
             /* Already checked.  */
             assert (lit_frag != NULL);
             assert (lit_sym != NULL);
             assert (tinsn->ntok == 1);
             /* Add a fixup.  */
             target_seg = S_GET_SEGMENT (lit_sym);
             assert (target_seg);
             reloc_type = map_operator_to_reloc (tinsn->tok[0].X_op);
             fix_new_exp_in_seg (target_seg, 0, lit_frag, 0, 4,
                              &tinsn->tok[0], FALSE, reloc_type);
             break;

           case ITYPE_LABEL:
             break;

           case ITYPE_INSN:
             xg_resolve_labels (tinsn, gen_label);
             xg_resolve_literals (tinsn, lit_sym);
             if (wide_insn && first)
              {
                first = FALSE;
                if (opcode_fits_format_slot (tinsn->opcode, fmt, slot))
                  {
                    cur_vinsn.slots[slot] = *tinsn;
                  }
                else
                  {
                    cur_vinsn.slots[slot].opcode =
                     xtensa_format_slot_nop_opcode (isa, fmt, slot);
                    cur_vinsn.slots[slot].ntok = 0;
                  }
                vinsn_to_insnbuf (&cur_vinsn, immed_instr, fragP, TRUE);
                xtensa_insnbuf_to_chars (isa, cur_vinsn.insnbuf,
                                      (unsigned char *) immed_instr, 0);
                fragP->tc_frag_data.is_insn = TRUE;
                size = xtensa_format_length (isa, fmt);
                if (!opcode_fits_format_slot (tinsn->opcode, fmt, slot))
                  {
                    xg_emit_insn_to_buf
                     (tinsn, immed_instr + size, fragP,
                      immed_instr - fragP->fr_literal + size, TRUE);
                    size += xg_get_single_size (tinsn->opcode);
                  }
              }
             else
              {
                size = xg_get_single_size (tinsn->opcode);
                xg_emit_insn_to_buf (tinsn, immed_instr, fragP,
                                   immed_instr - fragP->fr_literal, TRUE);
              }
             immed_instr += size;
             total_size += size;
             break;
           }
       }

      diff = total_size - old_size;
      assert (diff >= 0);
      if (diff != 0)
       expanded = TRUE;
      assert (diff <= fragP->fr_var);
      fragP->fr_var -= diff;
      fragP->fr_fix += diff;
    }

  /* Check for undefined immediates in LOOP instructions.  */
  if (is_loop)
    {
      symbolS *sym;
      sym = orig_tinsn.tok[1].X_add_symbol;
      if (sym != NULL && !S_IS_DEFINED (sym))
       {
         as_bad (_("unresolved loop target symbol: %s"), S_GET_NAME (sym));
         return;
       }
      sym = orig_tinsn.tok[1].X_op_symbol;
      if (sym != NULL && !S_IS_DEFINED (sym))
       {
         as_bad (_("unresolved loop target symbol: %s"), S_GET_NAME (sym));
         return;
       }
    }

  if (expanded && xtensa_opcode_is_loop (isa, orig_tinsn.opcode) == 1)
    convert_frag_immed_finish_loop (segP, fragP, &orig_tinsn);

  if (expanded && is_direct_call_opcode (orig_tinsn.opcode))
    {
      /* Add an expansion note on the expanded instruction.  */
      fix_new_exp_in_seg (now_seg, 0, fragP, fr_opcode - fragP->fr_literal, 4,
                       &orig_tinsn.tok[0], TRUE,
                       BFD_RELOC_XTENSA_ASM_EXPAND);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void convert_frag_immed_finish_loop ( segT  segP,
fragS *  fragP,
TInsn tinsn 
) [static]

Definition at line 9459 of file tc-xtensa.c.

{
  TInsn loop_insn;
  TInsn addi_insn;
  TInsn addmi_insn;
  unsigned long target;
  static xtensa_insnbuf insnbuf = NULL;
  unsigned int loop_length, loop_length_hi, loop_length_lo;
  xtensa_isa isa = xtensa_default_isa;
  addressT loop_offset;
  addressT addi_offset = 9;
  addressT addmi_offset = 12;
  fragS *next_fragP;
  int target_count;

  if (!insnbuf)
    insnbuf = xtensa_insnbuf_alloc (isa);

  /* Get the loop offset.  */
  loop_offset = get_expanded_loop_offset (tinsn->opcode);

  /* Validate that there really is a LOOP at the loop_offset.  Because
     loops are not bundleable, we can assume that the instruction will be
     in slot 0.  */
  tinsn_from_chars (&loop_insn, fragP->fr_opcode + loop_offset, 0);
  tinsn_immed_from_frag (&loop_insn, fragP, 0);

  assert (xtensa_opcode_is_loop (isa, loop_insn.opcode) == 1);
  addi_offset += loop_offset;
  addmi_offset += loop_offset;

  assert (tinsn->ntok == 2);
  if (tinsn->tok[1].X_op == O_constant)
    target = tinsn->tok[1].X_add_number;
  else if (tinsn->tok[1].X_op == O_symbol)
    {
      /* Find the fragment.  */
      symbolS *sym = tinsn->tok[1].X_add_symbol;
      assert (S_GET_SEGMENT (sym) == segP
             || S_GET_SEGMENT (sym) == absolute_section);
      target = (S_GET_VALUE (sym) + tinsn->tok[1].X_add_number);
    }
  else
    {
      as_bad (_("invalid expression evaluation type %d"), tinsn->tok[1].X_op);
      target = 0;
    }

  know (symbolP);
  know (symbolP->sy_frag);
  know (!(S_GET_SEGMENT (symbolP) == absolute_section)
       || symbol_get_frag (symbolP) == &zero_address_frag);

  loop_length = target - (fragP->fr_address + fragP->fr_fix);
  loop_length_hi = loop_length & ~0x0ff;
  loop_length_lo = loop_length & 0x0ff;
  if (loop_length_lo >= 128)
    {
      loop_length_lo -= 256;
      loop_length_hi += 256;
    }

  /* Because addmi sign-extends the immediate, 'loop_length_hi' can be at most
     32512.  If the loop is larger than that, then we just fail.  */
  if (loop_length_hi > 32512)
    as_bad_where (fragP->fr_file, fragP->fr_line,
                _("loop too long for LOOP instruction"));

  tinsn_from_chars (&addi_insn, fragP->fr_opcode + addi_offset, 0);
  assert (addi_insn.opcode == xtensa_addi_opcode);

  tinsn_from_chars (&addmi_insn, fragP->fr_opcode + addmi_offset, 0);
  assert (addmi_insn.opcode == xtensa_addmi_opcode);

  set_expr_const (&addi_insn.tok[2], loop_length_lo);
  tinsn_to_insnbuf (&addi_insn, insnbuf);

  fragP->tc_frag_data.is_insn = TRUE;
  xtensa_insnbuf_to_chars
    (isa, insnbuf, (unsigned char *) fragP->fr_opcode + addi_offset, 0);

  set_expr_const (&addmi_insn.tok[2], loop_length_hi);
  tinsn_to_insnbuf (&addmi_insn, insnbuf);
  xtensa_insnbuf_to_chars
    (isa, insnbuf, (unsigned char *) fragP->fr_opcode + addmi_offset, 0);

  /* Walk through all of the frags from here to the loop end
     and mark them as no_transform to keep them from being modified
     by the linker.  If we ever have a relocation for the
     addi/addmi of the difference of two symbols we can remove this.  */

  target_count = 0;
  for (next_fragP = fragP; next_fragP != NULL;
       next_fragP = next_fragP->fr_next)
    {
      next_fragP->tc_frag_data.is_no_transform = TRUE;
      if (next_fragP->tc_frag_data.is_loop_target)
       target_count++;
      if (target_count == 2)
       break;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void convert_frag_narrow ( segT  segP,
fragS *  fragP,
xtensa_format  fmt,
int  slot 
) [static]

Definition at line 9075 of file tc-xtensa.c.

{
  TInsn tinsn, single_target;
  int size, old_size, diff;
  offsetT frag_offset;

  assert (slot == 0);
  tinsn_from_chars (&tinsn, fragP->fr_opcode, 0);

  if (fragP->tc_frag_data.is_aligning_branch == 1)
    {
      assert (fragP->tc_frag_data.text_expansion[0] == 1
             || fragP->tc_frag_data.text_expansion[0] == 0);
      convert_frag_immed (segP, fragP, fragP->tc_frag_data.text_expansion[0],
                       fmt, slot);
      return;
    }

  if (fragP->tc_frag_data.text_expansion[0] == 0)
    {
      /* No conversion.  */
      fragP->fr_var = 0;
      return;
    }

  assert (fragP->fr_opcode != NULL);

  /* Frags in this relaxation state should only contain
     single instruction bundles.  */
  tinsn_immed_from_frag (&tinsn, fragP, 0);

  /* Just convert it to a wide form....  */
  size = 0;
  old_size = xg_get_single_size (tinsn.opcode);

  tinsn_init (&single_target);
  frag_offset = fragP->fr_opcode - fragP->fr_literal;

  if (! xg_is_single_relaxable_insn (&tinsn, &single_target, FALSE))
    {
      as_bad (_("unable to widen instruction"));
      return;
    }

  size = xg_get_single_size (single_target.opcode);
  xg_emit_insn_to_buf (&single_target, fragP->fr_opcode, fragP,
                     frag_offset, TRUE);

  diff = size - old_size;
  assert (diff >= 0);
  assert (diff <= fragP->fr_var);
  fragP->fr_var -= diff;
  fragP->fr_fix += diff;

  /* clean it up */
  fragP->fr_var = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void copy_expr ( expressionS dst,
const expressionS src 
) [static]

Definition at line 11599 of file tc-xtensa.c.

{
  memcpy (dst, src, sizeof (expressionS));
}

Here is the caller graph for this function:

static int count_insns_to_loop_end ( fragS *  base_fragP,
bfd_boolean  count_relax_add,
int  max_count 
) [static]

Definition at line 7545 of file tc-xtensa.c.

{
  fragS *fragP = NULL;
  int insn_count = 0;

  fragP = base_fragP;

  for (; fragP && !fragP->tc_frag_data.is_loop_target; fragP = fragP->fr_next)
    {
      insn_count += unrelaxed_frag_min_insn_count (fragP);
      if (insn_count >= max_count)
       return max_count;

      if (count_relax_add)
       {
         if (fragP->fr_type == rs_machine_dependent
             && fragP->fr_subtype == RELAX_ADD_NOP_IF_SHORT_LOOP)
           {
             /* In order to add the appropriate number of
                NOPs, we count an instruction for downstream
                occurrences.  */
             insn_count++;
             if (insn_count >= max_count)
              return max_count;
           }
       }
    }
  return insn_count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int decode_reloc ( bfd_reloc_code_real_type  reloc,
int slot,
bfd_boolean is_alt 
) [static]

Definition at line 2581 of file tc-xtensa.c.

Here is the caller graph for this function:

static void directive_balance ( void  ) [static]

Definition at line 1078 of file tc-xtensa.c.

{
  while (directive_state_stack)
    {
      directiveE directive;
      bfd_boolean negated;
      const char *file;
      unsigned int line;
      const void *datum;

      directive_pop (&directive, &negated, &file, &line, &datum);
      as_warn_where ((char *) file, line,
                   _(".begin directive with no matching .end directive"));
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void directive_pop ( directiveE directive,
bfd_boolean negated,
const char **  file,
unsigned int line,
const void **  datum 
) [static]

Definition at line 1051 of file tc-xtensa.c.

{
  state_stackS *top = directive_state_stack;

  if (!directive_state_stack)
    {
      as_bad (_("unmatched end directive"));
      *directive = directive_none;
      return;
    }

  directive_state[directive_state_stack->directive] = top->old_state;
  *directive = top->directive;
  *negated = top->negated;
  *file = top->file;
  *line = top->line;
  *datum = top->datum;
  directive_state_stack = top->prev;
  free (top);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void directive_push ( directiveE  directive,
bfd_boolean  negated,
const void *  datum 
) [static]

Definition at line 1029 of file tc-xtensa.c.

{
  char *file;
  unsigned int line;
  state_stackS *stack = (state_stackS *) xmalloc (sizeof (state_stackS));

  as_where (&file, &line);

  stack->directive = directive;
  stack->negated = negated;
  stack->old_state = directive_state[directive];
  stack->file = file;
  stack->line = line;
  stack->datum = datum;
  stack->prev = directive_state_stack;
  directive_state_stack = stack;

  directive_state[directive] = !negated;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean do_align_targets ( void  ) [static]

Definition at line 1018 of file tc-xtensa.c.

{
  /* Do not use this function after md_end; just look at align_targets
     instead.  There is no target-align directive, so alignment is either
     enabled for all frags or not done at all.  */
  assert (!past_xtensa_end);
  return align_targets && use_transform ();
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean emit_single_op ( TInsn orig_insn) [static]

Definition at line 6519 of file tc-xtensa.c.

{
  int i;
  IStack istack;            /* put instructions into here */
  symbolS *lit_sym = NULL;
  symbolS *label_sym = NULL;

  istack_init (&istack);

  /* Special-case for "movi aX, foo" which is guaranteed to need relaxing.
     Because the scheduling and bundling characteristics of movi and
     l32r or const16 are so different, we can do much better if we relax
     it prior to scheduling and bundling, rather than after.  */
  if ((orig_insn->opcode == xtensa_movi_opcode
       || orig_insn->opcode == xtensa_movi_n_opcode)
      && !cur_vinsn.inside_bundle
      && (orig_insn->tok[1].X_op == O_symbol
         || orig_insn->tok[1].X_op == O_pltrel)
      && !orig_insn->is_specific_opcode && use_transform ())
    xg_assembly_relax (&istack, orig_insn, now_seg, frag_now, 0, 1, 0);
  else
    if (xg_expand_assembly_insn (&istack, orig_insn))
      return TRUE;

  for (i = 0; i < istack.ninsn; i++)
    {
      TInsn *insn = &istack.insn[i];
      switch (insn->insn_type)
       {
       case ITYPE_LITERAL:
         assert (lit_sym == NULL);
         lit_sym = xg_assemble_literal (insn);
         break;
       case ITYPE_LABEL:
         {
           static int relaxed_sym_idx = 0;
           char *label = xmalloc (strlen (FAKE_LABEL_NAME) + 12);
           sprintf (label, "%s_rl_%x", FAKE_LABEL_NAME, relaxed_sym_idx++);
           colon (label);
           assert (label_sym == NULL);
           label_sym = symbol_find_or_make (label);
           assert (label_sym);
           free (label);
         }
         break;
       case ITYPE_INSN:
         {
           vliw_insn v;
           if (lit_sym)
             xg_resolve_literals (insn, lit_sym);
           if (label_sym)
             xg_resolve_labels (insn, label_sym);
           xg_init_vinsn (&v);
           bundle_tinsn (insn, &v);
           finish_vinsn (&v);
           xg_free_vinsn (&v);
         }
         break;
       default:
         assert (0);
         break;
       }
    }
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_reloc_code_real_type encode_alt_reloc ( int  slot) [static]

Definition at line 2620 of file tc-xtensa.c.

{
  if (slot < 0 || slot > 14)
    return BFD_RELOC_NONE;

  return BFD_RELOC_XTENSA_SLOT0_ALT + slot;
}

Here is the caller graph for this function:

static bfd_reloc_code_real_type encode_reloc ( int  slot) [static]

Definition at line 2607 of file tc-xtensa.c.

{
  if (slot < 0 || slot > 14)
    return BFD_RELOC_NONE;

  return BFD_RELOC_XTENSA_SLOT0_OP + slot;
}

Here is the caller graph for this function:

static void error_reset_cur_vinsn ( void  ) [static]

Definition at line 5119 of file tc-xtensa.c.

{
  if (cur_vinsn.inside_bundle)
    {
      if (*input_line_pointer == '}'
         || *(input_line_pointer - 1) == '}'
         || *(input_line_pointer - 2) == '}')
       xg_clear_vinsn (&cur_vinsn);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 11522 of file tc-xtensa.c.

{
  return (s->X_op == O_constant);
}

Here is the caller graph for this function:

Definition at line 11584 of file tc-xtensa.c.

{
  if (s1->X_op != s2->X_op)
    return FALSE;
  if (s1->X_add_symbol != s2->X_add_symbol)
    return FALSE;
  if (s1->X_op_symbol != s2->X_op_symbol)
    return FALSE;
  if (s1->X_add_number != s2->X_add_number)
    return FALSE;
  return TRUE;
}

Here is the caller graph for this function:

Definition at line 11552 of file tc-xtensa.c.

{
  return (s->X_op == O_register);
}

Here is the caller graph for this function:

static const char* expression_end ( const char *  name) [static]

Definition at line 1665 of file tc-xtensa.c.

{
  while (1)
    {
      switch (*name)
       {
       case '}':
       case ';':
       case '\0':
       case ',':
       case ':':
         return name;
       case ' ':
       case '\t':
         ++name;
         continue;
       default:
         return 0;
       }
    }
}

Here is the caller graph for this function:

static void expression_maybe_register ( xtensa_opcode  opc,
int  opnd,
expressionS tok 
) [static]

Definition at line 1746 of file tc-xtensa.c.

{
  xtensa_isa isa = xtensa_default_isa;

  /* Check if this is an immediate operand.  */
  if (xtensa_operand_is_register (isa, opc, opnd) == 0)
    {
      bfd_reloc_code_real_type reloc;
      segT t = expression (tok);
      if (t == absolute_section
         && xtensa_operand_is_PCrelative (isa, opc, opnd) == 1)
       {
         assert (tok->X_op == O_constant);
         tok->X_op = O_symbol;
         tok->X_add_symbol = &abs_symbol;
       }

      if ((tok->X_op == O_constant || tok->X_op == O_symbol)
         && ((reloc = xtensa_elf_suffix (&input_line_pointer, tok))
             != BFD_RELOC_NONE))
       {
         if (reloc == BFD_RELOC_UNUSED)
           {
             as_bad (_("unsupported relocation"));
             return;
           }

         if (tok->X_op == O_constant)
           {
             switch (reloc)
              {
              case BFD_RELOC_LO16:
                tok->X_add_number &= 0xffff;
                return;

              case BFD_RELOC_HI16:
                tok->X_add_number = ((unsigned) tok->X_add_number) >> 16;
                return;

              default:
                break;
              }
           }
         tok->X_op = map_suffix_reloc_to_operator (reloc);
       }
    }
  else
    {
      xtensa_regfile opnd_rf = xtensa_operand_regfile (isa, opc, opnd);
      unsigned reg = tc_get_register (xtensa_regfile_shortname (isa, opnd_rf));

      if (reg != ERROR_REG_NUM)    /* Already errored */
       {
         uint32 buf = reg;
         if (xtensa_operand_encode (isa, opc, opnd, &buf))
           as_bad (_("register number out of range"));
       }

      tok->X_op = O_register;
      tok->X_add_symbol = 0;
      tok->X_add_number = reg;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static addressT find_address_of_next_align_frag ( fragS **  fragPP,
int wide_nops,
int narrow_nops,
int widens,
bfd_boolean paddable 
) [static]

Definition at line 8415 of file tc-xtensa.c.

{
  fragS *fragP = *fragPP;
  addressT address = fragP->fr_address;

  /* Do not reset the counts to 0.  */

  while (fragP)
    {
      /* Limit this to a small search.  */
      if (*widens >= (int) xtensa_fetch_width)
       {
         *fragPP = fragP;
         return 0;
       }
      address += fragP->fr_fix;

      if (fragP->fr_type == rs_fill)
       address += fragP->fr_offset * fragP->fr_var;
      else if (fragP->fr_type == rs_machine_dependent)
       {
         switch (fragP->fr_subtype)
           {
           case RELAX_UNREACHABLE:
             *paddable = TRUE;
             break;

           case RELAX_FILL_NOP:
             (*wide_nops)++;
             if (!fragP->tc_frag_data.is_no_density)
              (*narrow_nops)++;
             break;

           case RELAX_SLOTS:
             if (fragP->tc_frag_data.slot_subtypes[0] == RELAX_NARROW)
              {
                (*widens)++;
                break;
              }
             address += total_frag_text_expansion (fragP);;
             break;

           case RELAX_IMMED:
             address += fragP->tc_frag_data.text_expansion[0];
             break;

           case RELAX_ALIGN_NEXT_OPCODE:
           case RELAX_DESIRE_ALIGN:
             *fragPP = fragP;
             return address;

           case RELAX_MAYBE_UNREACHABLE:
           case RELAX_MAYBE_DESIRE_ALIGN:
             /* Do nothing.  */
             break;

           default:
             /* Just punt if we don't know the type.  */
             *fragPP = fragP;
             return 0;
           }
       }
      else
       {
         /* Just punt if we don't know the type.  */
         *fragPP = fragP;
         return 0;
       }
      fragP = fragP->fr_next;
    }

  *fragPP = fragP;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean find_vinsn_conflicts ( vliw_insn vinsn) [static]

Definition at line 6111 of file tc-xtensa.c.

{
  int i, j;
  int branches = 0;
  xtensa_isa isa = xtensa_default_isa;

  assert (!past_xtensa_end);

  for (i = 0 ; i < vinsn->num_slots; i++)
    {
      TInsn *op1 = &vinsn->slots[i];
      if (op1->is_specific_opcode)
       op1->keep_wide = TRUE;
      else
       op1->keep_wide = FALSE;
    }

  for (i = 0 ; i < vinsn->num_slots; i++)
    {
      TInsn *op1 = &vinsn->slots[i];

      if (xtensa_opcode_is_branch (isa, op1->opcode) == 1)
       branches++;

      for (j = 0; j < vinsn->num_slots; j++)
       {
         if (i != j)
           {
             TInsn *op2 = &vinsn->slots[j];
             char conflict_type = check_t1_t2_reads_and_writes (op1, op2);
             switch (conflict_type)
              {
              case 'c':
                as_bad (_("opcodes '%s' (slot %d) and '%s' (slot %d) write the same register"),
                       xtensa_opcode_name (isa, op1->opcode), i,
                       xtensa_opcode_name (isa, op2->opcode), j);
                return TRUE;
              case 'd':
                as_bad (_("opcodes '%s' (slot %d) and '%s' (slot %d) write the same state"),
                       xtensa_opcode_name (isa, op1->opcode), i,
                       xtensa_opcode_name (isa, op2->opcode), j);
                return TRUE;
              case 'e':
                as_bad (_("opcodes '%s' (slot %d) and '%s' (slot %d) write the same port"),
                       xtensa_opcode_name (isa, op1->opcode), i,
                       xtensa_opcode_name (isa, op2->opcode), j);
                return TRUE;
              case 'f':
                as_bad (_("opcodes '%s' (slot %d) and '%s' (slot %d) both have volatile port accesses"),
                       xtensa_opcode_name (isa, op1->opcode), i,
                       xtensa_opcode_name (isa, op2->opcode), j);
                return TRUE;
              default:
                /* Everything is OK.  */
                break;
              }
             op2->is_specific_opcode = (op2->is_specific_opcode
                                    || conflict_type == 'a');
           }
       }
    }

  if (branches > 1)
    {
      as_bad (_("multiple branches or jumps in the same bundle"));
      return TRUE;
    }

  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void finish_vinsn ( vliw_insn vinsn) [static]

Definition at line 5913 of file tc-xtensa.c.

{
  IStack slotstack;
  int i;
  char *file_name;
  unsigned line;

  if (find_vinsn_conflicts (vinsn))
    {
      xg_clear_vinsn (vinsn);
      return;
    }

  /* First, find a format that works.  */
  if (vinsn->format == XTENSA_UNDEFINED)
    vinsn->format = xg_find_narrowest_format (vinsn);

  if (vinsn->format == XTENSA_UNDEFINED)
    {
      as_where (&file_name, &line);
      as_bad_where (file_name, line,
                  _("couldn't find a valid instruction format"));
      fprintf (stderr, _("    ops were: "));
      for (i = 0; i < vinsn->num_slots; i++)
       fprintf (stderr, _(" %s;"),
               xtensa_opcode_name (xtensa_default_isa,
                                 vinsn->slots[i].opcode));
      fprintf (stderr, _("\n"));
      xg_clear_vinsn (vinsn);
      return;
    }

  if (vinsn->num_slots
      != xtensa_format_num_slots (xtensa_default_isa, vinsn->format))
    {
      as_bad (_("format '%s' allows %d slots, but there are %d opcodes"),
             xtensa_format_name (xtensa_default_isa, vinsn->format),
             xtensa_format_num_slots (xtensa_default_isa, vinsn->format),
             vinsn->num_slots);
      xg_clear_vinsn (vinsn);
      return;
    }

  if (resources_conflict (vinsn))
    {
      as_where (&file_name, &line);
      as_bad_where (file_name, line, _("illegal resource usage in bundle"));
      fprintf (stderr, "    ops were: ");
      for (i = 0; i < vinsn->num_slots; i++)
       fprintf (stderr, " %s;",
               xtensa_opcode_name (xtensa_default_isa,
                                 vinsn->slots[i].opcode));
      fprintf (stderr, "\n");
      xg_clear_vinsn (vinsn);
      return;
    }

  for (i = 0; i < vinsn->num_slots; i++)
    {
      if (vinsn->slots[i].opcode != XTENSA_UNDEFINED)
       {
         symbolS *lit_sym = NULL;
         int j;
         bfd_boolean e = FALSE;
         bfd_boolean saved_density = density_supported;

         /* We don't want to narrow ops inside multi-slot bundles.  */
         if (vinsn->num_slots > 1)
           density_supported = FALSE;

         istack_init (&slotstack);
         if (vinsn->slots[i].opcode == xtensa_nop_opcode)
           {
             vinsn->slots[i].opcode =
              xtensa_format_slot_nop_opcode (xtensa_default_isa,
                                          vinsn->format, i);
             vinsn->slots[i].ntok = 0;
           }

         if (xg_expand_assembly_insn (&slotstack, &vinsn->slots[i]))
           {
             e = TRUE;
             continue;
           }

         density_supported = saved_density;

         if (e)
           {
             xg_clear_vinsn (vinsn);
             return;
           }

         for (j = 0; j < slotstack.ninsn; j++)
           {
             TInsn *insn = &slotstack.insn[j];
             if (insn->insn_type == ITYPE_LITERAL)
              {
                assert (lit_sym == NULL);
                lit_sym = xg_assemble_literal (insn);
              }
             else
              {
                assert (insn->insn_type == ITYPE_INSN);
                if (lit_sym)
                  xg_resolve_literals (insn, lit_sym);
                if (j != slotstack.ninsn - 1)
                  emit_single_op (insn);
              }
           }

         if (vinsn->num_slots > 1)
           {
             if (opcode_fits_format_slot
                (slotstack.insn[slotstack.ninsn - 1].opcode,
                 vinsn->format, i))
              {
                vinsn->slots[i] = slotstack.insn[slotstack.ninsn - 1];
              }
             else
              {
                emit_single_op (&slotstack.insn[slotstack.ninsn - 1]);
                if (vinsn->format == XTENSA_UNDEFINED)
                  vinsn->slots[i].opcode = xtensa_nop_opcode;
                else
                  vinsn->slots[i].opcode
                    = xtensa_format_slot_nop_opcode (xtensa_default_isa,
                                                 vinsn->format, i);

                vinsn->slots[i].ntok = 0;
              }
           }
         else
           {
             vinsn->slots[0] = slotstack.insn[slotstack.ninsn - 1];
             vinsn->format = XTENSA_UNDEFINED;
           }
       }
    }

  /* Now check resource conflicts on the modified bundle.  */
  if (resources_conflict (vinsn))
    {
      as_where (&file_name, &line);
      as_bad_where (file_name, line, _("illegal resource usage in bundle"));
      fprintf (stderr, "    ops were: ");
      for (i = 0; i < vinsn->num_slots; i++)
       fprintf (stderr, " %s;",
               xtensa_opcode_name (xtensa_default_isa,
                                 vinsn->slots[i].opcode));
      fprintf (stderr, "\n");
      xg_clear_vinsn (vinsn);
      return;
    }

  /* First, find a format that works.  */
  if (vinsn->format == XTENSA_UNDEFINED)
      vinsn->format = xg_find_narrowest_format (vinsn);

  xg_assemble_vliw_tokens (vinsn);

  xg_clear_vinsn (vinsn);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static fixS * 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 
) [static]

Definition at line 9419 of file tc-xtensa.c.

{
  fixS *new_fix;
  segT seg = now_seg;
  subsegT subseg = now_subseg;

  assert (new_seg != 0);
  subseg_set (new_seg, new_subseg);

  new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
  subseg_set (seg, subseg);
  return new_fix;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_vma frag_flags_to_number ( const frag_flags *  prop_flags) [static]

Definition at line 10635 of file tc-xtensa.c.

{
  bfd_vma num = 0;
  if (prop_flags->is_literal)
    num |= XTENSA_PROP_LITERAL;
  if (prop_flags->is_insn)
    num |= XTENSA_PROP_INSN;
  if (prop_flags->is_data)
    num |= XTENSA_PROP_DATA;
  if (prop_flags->is_unreachable)
    num |= XTENSA_PROP_UNREACHABLE;
  if (prop_flags->insn.is_loop_target)
    num |= XTENSA_PROP_INSN_LOOP_TARGET;
  if (prop_flags->insn.is_branch_target)
    {
      num |= XTENSA_PROP_INSN_BRANCH_TARGET;
      num = SET_XTENSA_PROP_BT_ALIGN (num, prop_flags->insn.bt_align_priority);
    }

  if (prop_flags->insn.is_no_density)
    num |= XTENSA_PROP_INSN_NO_DENSITY;
  if (prop_flags->insn.is_no_transform)
    num |= XTENSA_PROP_INSN_NO_TRANSFORM;
  if (prop_flags->insn.is_no_reorder)
    num |= XTENSA_PROP_INSN_NO_REORDER;
  if (prop_flags->insn.is_abslit)
    num |= XTENSA_PROP_INSN_ABSLIT;

  if (prop_flags->is_align)
    {
      num |= XTENSA_PROP_ALIGN;
      num = SET_XTENSA_PROP_ALIGNMENT (num, prop_flags->alignment);
    }

  return num;
}

Here is the caller graph for this function:

static int frag_format_size ( const fragS *  fragP) [static]

Definition at line 4339 of file tc-xtensa.c.

{
  static xtensa_insnbuf insnbuf = NULL;
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format fmt;
  int fmt_size;

  if (!insnbuf)
    insnbuf = xtensa_insnbuf_alloc (isa);

  if (fragP == NULL)
    return XTENSA_UNDEFINED;

  xtensa_insnbuf_from_chars (isa, insnbuf,
                          (unsigned char *) fragP->fr_literal, 0);

  fmt = xtensa_format_decode (isa, insnbuf);
  if (fmt == XTENSA_UNDEFINED)
    return XTENSA_UNDEFINED;
  fmt_size = xtensa_format_length (isa, fmt);

  /* If the next format won't be changing due to relaxation, just
     return the length of the first format.  */
  if (fragP->fr_opcode != fragP->fr_literal)
    return fmt_size;

  /* If during relaxation we have to pull an instruction out of a
     multi-slot instruction, we will return the more conservative
     number.  This works because alignment on bigger instructions
     is more restrictive than alignment on smaller instructions.
     This is more conservative than we would like, but it happens
     infrequently.  */

  if (xtensa_format_num_slots (xtensa_default_isa, fmt) > 1)
    return fmt_size;

  /* If we aren't doing one of our own relaxations or it isn't
     slot-based, then the insn size won't change.  */
  if (fragP->fr_type != rs_machine_dependent)
    return fmt_size;
  if (fragP->fr_subtype != RELAX_SLOTS)
    return fmt_size;

  /* If an instruction is about to grow, return the longer size.  */
  if (fragP->tc_frag_data.slot_subtypes[0] == RELAX_IMMED_STEP1
      || fragP->tc_frag_data.slot_subtypes[0] == RELAX_IMMED_STEP2)
    return 3;

  if (fragP->tc_frag_data.slot_subtypes[0] == RELAX_NARROW)
    return 2 + fragP->tc_frag_data.text_expansion[0];

  return fmt_size;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long future_alignment_required ( fragS *  ,
long   
) [static]

Here is the caller graph for this function:

static long future_alignment_required ( fragS *  fragP,
long stretch  ATTRIBUTE_UNUSED 
) [static]

Definition at line 8498 of file tc-xtensa.c.

{
  fragS *this_frag = fragP;
  long address;
  int num_widens = 0;
  int wide_nops = 0;
  int narrow_nops = 0;
  bfd_boolean paddable = FALSE;
  offsetT local_opt_diff;
  offsetT opt_diff;
  offsetT max_diff;
  int stretch_amount = 0;
  int local_stretch_amount;
  int global_stretch_amount;

  address = find_address_of_next_align_frag
    (&fragP, &wide_nops, &narrow_nops, &num_widens, &paddable);

  if (!address)
    {
      if (this_frag->tc_frag_data.is_aligning_branch)
       this_frag->tc_frag_data.slot_subtypes[0] = RELAX_IMMED;
      else
       frag_wane (this_frag);
    }
  else
    {
      local_opt_diff = get_aligned_diff (fragP, address, &max_diff);
      opt_diff = local_opt_diff;
      assert (opt_diff >= 0);
      assert (max_diff >= opt_diff);
      if (max_diff == 0)
       return 0;

      if (fragP)
       fragP = fragP->fr_next;

      while (fragP && opt_diff < max_diff && address)
       {
         /* We only use these to determine if we can exit early
            because there will be plenty of ways to align future
            align frags.  */
         int glob_widens = 0;
         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);
         /* If there is a padable portion, then skip.  */
         if (glob_pad || glob_widens >= (1 << branch_align_power (now_seg)))
           address = 0;

         if (address)
           {
             offsetT next_m_diff;
             offsetT next_o_diff;

             /* Downrange frags haven't had stretch added to them yet.  */
             address += stretch;

             /* The address also includes any text expansion from this
               frag in a previous pass, but we don't want that.  */
             address -= this_frag->tc_frag_data.text_expansion[0];

             /* Assume we are going to move at least opt_diff.  In
               reality, we might not be able to, but assuming that
               we will helps catch cases where moving opt_diff pushes
               the next target from aligned to unaligned.  */
             address += opt_diff;

             next_o_diff = get_aligned_diff (fragP, address, &next_m_diff);

             /* Now cleanup for the adjustments to address.  */
             next_o_diff += opt_diff;
             next_m_diff += opt_diff;
             if (next_o_diff <= max_diff && next_o_diff > opt_diff)
              opt_diff = next_o_diff;
             if (next_m_diff < max_diff)
              max_diff = next_m_diff;
             fragP = fragP->fr_next;
           }
       }

      /* If there are enough wideners in between, do it.  */
      if (paddable)
       {
         if (this_frag->fr_subtype == RELAX_UNREACHABLE)
           {
             assert (opt_diff <= UNREACHABLE_MAX_WIDTH);
             return opt_diff;
           }
         return 0;
       }
      local_stretch_amount
       = bytes_to_stretch (this_frag, wide_nops, narrow_nops,
                         num_widens, local_opt_diff);
      global_stretch_amount
       = bytes_to_stretch (this_frag, wide_nops, narrow_nops,
                         num_widens, opt_diff);
      /* If the condition below is true, then the frag couldn't
        stretch the correct amount for the global case, so we just
        optimize locally.  We'll rely on the subsequent frags to get
        the correct alignment in the global case.  */
      if (global_stretch_amount < local_stretch_amount)
       stretch_amount = local_stretch_amount;
      else
       stretch_amount = global_stretch_amount;

      if (this_frag->fr_subtype == RELAX_SLOTS
         && this_frag->tc_frag_data.slot_subtypes[0] == RELAX_NARROW)
       assert (stretch_amount <= 1);
      else if (this_frag->fr_subtype == RELAX_FILL_NOP)
       {
         if (this_frag->tc_frag_data.is_no_density)
           assert (stretch_amount == 3 || stretch_amount == 0);
         else
           assert (stretch_amount <= 3);
       }
    }
  return stretch_amount;
}

Here is the call graph for this function:

static offsetT get_aligned_diff ( fragS *  fragP,
addressT  address,
offsetT max_diff 
) [static]

Definition at line 8109 of file tc-xtensa.c.

{
  addressT target_address, loop_insn_offset;
  int target_size;
  xtensa_opcode loop_opcode;
  bfd_boolean is_loop;
  int align_power;
  offsetT opt_diff;
  offsetT branch_align;

  assert (fragP->fr_type == rs_machine_dependent);
  switch (fragP->fr_subtype)
    {
    case RELAX_DESIRE_ALIGN:
      target_size = next_frag_format_size (fragP);
      if (target_size == XTENSA_UNDEFINED)
       target_size = 3;
      align_power = branch_align_power (now_seg);
      branch_align = 1 << align_power;
      /* Don't count on the section alignment being as large as the target.  */
      if (target_size > branch_align)
       target_size = branch_align;
      opt_diff = get_text_align_fill_size (address, align_power,
                                      target_size, FALSE, FALSE);

      *max_diff = (opt_diff + branch_align
                 - (target_size + ((address + opt_diff) % branch_align)));
      assert (*max_diff >= opt_diff);
      return opt_diff;

    case RELAX_ALIGN_NEXT_OPCODE:
      target_size = get_loop_align_size (next_frag_format_size (fragP));
      loop_insn_offset = 0;
      is_loop = next_frag_opcode_is_loop (fragP, &loop_opcode);
      assert (is_loop);

      /* If the loop has been expanded then the LOOP instruction
        could be at an offset from this fragment.  */
      if (next_non_empty_frag(fragP)->tc_frag_data.slot_subtypes[0]
         != RELAX_IMMED)
       loop_insn_offset = get_expanded_loop_offset (loop_opcode);

      /* In an ideal world, which is what we are shooting for here,
        we wouldn't need to use any NOPs immediately prior to the
        LOOP instruction.  If this approach fails, relax_frag_loop_align
        will call get_noop_aligned_address.  */
      target_address =
       address + loop_insn_offset + xg_get_single_size (loop_opcode);
      align_power = get_text_align_power (target_size),
      opt_diff = get_text_align_fill_size (target_address, align_power,
                                      target_size, FALSE, FALSE);

      *max_diff = xtensa_fetch_width
       - ((target_address + opt_diff) % xtensa_fetch_width)
       - target_size + opt_diff;
      assert (*max_diff >= opt_diff);
      return opt_diff;

    default:
      break;
    }
  assert (0);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void get_directive ( directiveE directive,
bfd_boolean negated 
) [static]

Definition at line 1108 of file tc-xtensa.c.

{
  int len;
  unsigned i;
  char *directive_string;

  if (strncmp (input_line_pointer, "no-", 3) != 0)
    *negated = FALSE;
  else
    {
      *negated = TRUE;
      input_line_pointer += 3;
    }

  len = strspn (input_line_pointer,
              "abcdefghijklmnopqrstuvwxyz_-/0123456789.");

  /* This code is a hack to make .begin [no-][generics|relax] exactly
     equivalent to .begin [no-]transform.  We should remove it when
     we stop accepting those options.  */

  if (strncmp (input_line_pointer, "generics", strlen ("generics")) == 0)
    {
      as_warn (_("[no-]generics is deprecated; use [no-]transform instead"));
      directive_string = "transform";
    }
  else if (strncmp (input_line_pointer, "relax", strlen ("relax")) == 0)
    {
      as_warn (_("[no-]relax is deprecated; use [no-]transform instead"));
      directive_string = "transform";
    }
  else
    directive_string = input_line_pointer;

  for (i = 0; i < sizeof (directive_info) / sizeof (*directive_info); ++i)
    {
      if (strncmp (directive_string, directive_info[i].name, len) == 0)
       {
         input_line_pointer += len;
         *directive = (directiveE) i;
         if (*negated && !directive_info[i].can_be_negated)
           as_bad (_("directive %s cannot be negated"),
                  directive_info[i].name);
         return;
       }
    }

  as_bad (_("unknown directive"));
  *directive = (directiveE) XTENSA_UNDEFINED;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static addressT get_expanded_loop_offset ( xtensa_opcode  opcode) [static]

Definition at line 4632 of file tc-xtensa.c.

{
  /* This is the OFFSET of the loop instruction in the expanded loop.
     This MUST correspond directly to the specification of the loop
     expansion.  It will be validated on fragment conversion.  */
  assert (opcode != XTENSA_UNDEFINED);
  if (opcode == xtensa_loop_opcode)
    return 0;
  if (opcode == xtensa_loopnez_opcode)
    return 3;
  if (opcode == xtensa_loopgtz_opcode)
    return 6;
  as_fatal (_("get_expanded_loop_offset: invalid opcode"));
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 11532 of file tc-xtensa.c.

{
  assert (expr_is_const (s));
  return s->X_add_number;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 11562 of file tc-xtensa.c.

{
  assert (expr_is_register (s));
  return s->X_add_number;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean get_frag_is_literal ( const fragS *  fragP) [static]

Definition at line 10165 of file tc-xtensa.c.

{
  assert (fragP != NULL);
  return fragP->tc_frag_data.is_literal;
}

Here is the caller graph for this function:

static void get_frag_property_flags ( const fragS *  fragP,
frag_flags *  prop_flags 
) [static]

Definition at line 10602 of file tc-xtensa.c.

{
  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;
  else if (fragP->tc_frag_data.is_insn)
    {
      prop_flags->is_insn = TRUE;
      if (fragP->tc_frag_data.is_loop_target)
       prop_flags->insn.is_loop_target = TRUE;
      if (fragP->tc_frag_data.is_branch_target)
       prop_flags->insn.is_branch_target = TRUE;
      if (fragP->tc_frag_data.is_specific_opcode
         || fragP->tc_frag_data.is_no_transform)
       prop_flags->insn.is_no_transform = TRUE;
      if (fragP->tc_frag_data.is_no_density)
       prop_flags->insn.is_no_density = TRUE;
      if (fragP->tc_frag_data.use_absolute_literals)
       prop_flags->insn.is_abslit = TRUE;
    }
  if (fragP->tc_frag_data.is_align)
    {
      prop_flags->is_align = TRUE;
      prop_flags->alignment = fragP->tc_frag_data.alignment;
      if (xtensa_frag_flags_is_empty (prop_flags))
       prop_flags->is_data = TRUE;
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_invisible_operands ( TInsn insn) [static]

Definition at line 1998 of file tc-xtensa.c.

{
  xtensa_isa isa = xtensa_default_isa;
  static xtensa_insnbuf slotbuf = NULL;
  xtensa_format fmt;
  xtensa_opcode opc = insn->opcode;
  int slot, opnd, fmt_found;
  unsigned val;

  if (!slotbuf)
    slotbuf = xtensa_insnbuf_alloc (isa);

  /* Find format/slot where this can be encoded.  */
  fmt_found = 0;
  slot = 0;
  for (fmt = 0; fmt < xtensa_isa_num_formats (isa); fmt++)
    {
      for (slot = 0; slot < xtensa_format_num_slots (isa, fmt); slot++)
       {
         if (xtensa_opcode_encode (isa, fmt, slot, slotbuf, opc) == 0)
           {
             fmt_found = 1;
             break;
           }
       }
      if (fmt_found) break;
    }

  if (!fmt_found)
    {
      as_bad (_("cannot encode opcode \"%s\""), xtensa_opcode_name (isa, opc));
      return -1;
    }

  /* First encode all the visible operands
     (to deal with shared field operands).  */
  for (opnd = 0; opnd < insn->ntok; opnd++)
    {
      if (xtensa_operand_is_visible (isa, opc, opnd) == 1
         && (insn->tok[opnd].X_op == O_register
             || insn->tok[opnd].X_op == O_constant))
       {
         val = insn->tok[opnd].X_add_number;
         xtensa_operand_encode (isa, opc, opnd, &val);
         xtensa_operand_set_field (isa, opc, opnd, fmt, slot, slotbuf, val);
       }
    }

  /* Then pull out the values for the invisible ones.  */
  for (opnd = 0; opnd < insn->ntok; opnd++)
    {
      if (xtensa_operand_is_visible (isa, opc, opnd) == 0)
       {
         xtensa_operand_get_field (isa, opc, opnd, fmt, slot, slotbuf, &val);
         xtensa_operand_decode (isa, opc, opnd, &val);
         insn->tok[opnd].X_add_number = val;
         if (xtensa_operand_is_register (isa, opc, opnd) == 1)
           insn->tok[opnd].X_op = O_register;
         else
           insn->tok[opnd].X_op = O_constant;
       }
    }

  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean get_is_linkonce_section ( bfd *abfd  ATTRIBUTE_UNUSED,
segT  sec 
) [static]

Definition at line 3902 of file tc-xtensa.c.

{
  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
      && strncmp (segment_name (sec), ".gnu.linkonce.", linkonce_len) == 0)
    link_once_flags = SEC_LINK_ONCE;

  return (link_once_flags != 0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static unsigned get_last_insn_flags ( segT  seg,
subsegT  subseg 
) [static]

Definition at line 9617 of file tc-xtensa.c.

{
  subseg_map *subseg_e = get_subseg_info (seg, subseg);
  if (subseg_e)
    return subseg_e->flags;
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static fragS * get_literal_pool_location ( segT  seg) [static]

Definition at line 4650 of file tc-xtensa.c.

{
  return seg_info (seg)->tc_segment_info_data.literal_pool_loc;
}

Here is the caller graph for this function:

static int get_loop_align_size ( int  insn_size) [static]

Definition at line 4410 of file tc-xtensa.c.

Here is the caller graph for this function:

static addressT get_noop_aligned_address ( fragS *  fragP,
addressT  address 
) [static]

Definition at line 8031 of file tc-xtensa.c.

{
  /* The rule is: get next fragment's FIRST instruction.  Find
     the smallest number of bytes that need to be added to
     ensure that the next fragment's FIRST instruction will fit
     in a single word.

     E.G.,   2 bytes : 0, 1, 2 mod 4
            3 bytes: 0, 1 mod 4

     If the FIRST instruction MIGHT be relaxed,
     assume that it will become a 3-byte instruction.

     Note again here that LOOP instructions are not bundleable,
     and this relaxation only applies to LOOP opcodes.  */

  int fill_size = 0;
  int first_insn_size;
  int loop_insn_size;
  addressT pre_opcode_bytes;
  int align_power;
  fragS *first_insn;
  xtensa_opcode opcode;
  bfd_boolean is_loop;

  assert (fragP->fr_type == rs_machine_dependent);
  assert (fragP->fr_subtype == RELAX_ALIGN_NEXT_OPCODE);

  /* Find the loop frag.  */
  first_insn = next_non_empty_frag (fragP);
  /* Now find the first insn frag.  */
  first_insn = next_non_empty_frag (first_insn);

  is_loop = next_frag_opcode_is_loop (fragP, &opcode);
  assert (is_loop);
  loop_insn_size = xg_get_single_size (opcode);

  pre_opcode_bytes = next_frag_pre_opcode_bytes (fragP);
  pre_opcode_bytes += loop_insn_size;

  /* For loops, the alignment depends on the size of the
     instruction following the loop, not the LOOP instruction.  */

  if (first_insn == NULL)
    first_insn_size = xtensa_fetch_width;
  else
    first_insn_size = get_loop_align_size (frag_format_size (first_insn));

  /* If it was 8, then we'll need a larger alignment for the section.  */
  align_power = get_text_align_power (first_insn_size);
  record_alignment (now_seg, align_power);

  fill_size = get_text_align_fill_size
    (address + pre_opcode_bytes, align_power, first_insn_size, TRUE,
     fragP->tc_frag_data.is_no_density);

  return address + fill_size;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_num_stack_literal_bytes ( IStack istack) [static]

Definition at line 11323 of file tc-xtensa.c.

{
  int i;
  int lit_bytes = 0;

  for (i = 0; i < istack->ninsn; i++)
    {
      TInsn *tinsn = &istack->insn[i];
      if (tinsn->insn_type == ITYPE_LITERAL && tinsn->ntok == 1)
       lit_bytes += 4;
    }
  return lit_bytes;
}

Here is the caller graph for this function:

static int get_num_stack_text_bytes ( IStack istack) [static]

Definition at line 11307 of file tc-xtensa.c.

{
  int i;
  int text_bytes = 0;

  for (i = 0; i < istack->ninsn; i++)
    {
      TInsn *tinsn = &istack->insn[i];
      if (tinsn->insn_type == ITYPE_INSN)
       text_bytes += xg_get_single_size (tinsn->opcode);
    }
  return text_bytes;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static xtensa_opcode get_opcode_from_buf ( const char *  buf,
int  slot 
) [static]

Definition at line 2453 of file tc-xtensa.c.

{
  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  xtensa_isa isa = xtensa_default_isa;
  xtensa_format fmt;

  if (!insnbuf)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
    }

  xtensa_insnbuf_from_chars (isa, insnbuf, (const unsigned char *) buf, 0);
  fmt = xtensa_format_decode (isa, insnbuf);
  if (fmt == XTENSA_UNDEFINED)
    return XTENSA_UNDEFINED;

  if (slot >= xtensa_format_num_slots (isa, fmt))
    return XTENSA_UNDEFINED;

  xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf);
  return xtensa_opcode_decode (isa, fmt, slot, slotbuf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_relaxable_immed ( xtensa_opcode  opcode) [static]

Definition at line 2429 of file tc-xtensa.c.

{
  int last_immed = -1;
  int noperands, opi;

  if (opcode == XTENSA_UNDEFINED)
    return -1;

  noperands = xtensa_opcode_num_operands (xtensa_default_isa, opcode);
  for (opi = noperands - 1; opi >= 0; opi--)
    {
      if (xtensa_operand_is_visible (xtensa_default_isa, opcode, opi) == 0)
       continue;
      if (xtensa_operand_is_PCrelative (xtensa_default_isa, opcode, opi) == 1)
       return opi;
      if (last_immed == -1
         && xtensa_operand_is_register (xtensa_default_isa, opcode, opi) == 0)
       last_immed = opi;
    }
  return last_immed;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static symbolS* get_special_label_symbol ( void  ) [static]

Definition at line 3102 of file tc-xtensa.c.

{
  static symbolS *sym = NULL;

  if (sym == NULL)
    sym = symbol_find_or_make ("SPECIAL_LABEL0\001");
  return sym;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static symbolS* get_special_literal_symbol ( void  ) [static]

Definition at line 3091 of file tc-xtensa.c.

{
  static symbolS *sym = NULL;

  if (sym == NULL)
    sym = symbol_find_or_make ("SPECIAL_LITERAL0\001");
  return sym;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static subseg_map* get_subseg_info ( segT  seg,
subsegT  subseg 
) [static]

Definition at line 9586 of file tc-xtensa.c.

{
  subseg_map *subseg_e;

  for (subseg_e = sseg_map; subseg_e; subseg_e = subseg_e->next)
    {
      if (seg == subseg_e->seg && subseg == subseg_e->subseg)
       break;
    }
  return subseg_e;
}

Here is the caller graph for this function:

static float get_subseg_target_freq ( segT  seg,
subsegT  subseg 
) [static]

Definition at line 9653 of file tc-xtensa.c.

{
  subseg_map *subseg_e = get_subseg_info (seg, subseg);
  if (subseg_e)
    return subseg_e->target_freq;
  return 1.0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static float get_subseg_total_freq ( segT  seg,
subsegT  subseg 
) [static]

Definition at line 9643 of file tc-xtensa.c.

{
  subseg_map *subseg_e = get_subseg_info (seg, subseg);
  if (subseg_e)
    return subseg_e->total_freq;
  return 1.0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_text_align_fill_size ( addressT  address,
int  align_pow,
int  target_size,
bfd_boolean  use_nops,
bfd_boolean  use_no_density 
) [static]

Definition at line 7906 of file tc-xtensa.c.

{
  addressT alignment, fill, fill_limit, fill_step;
  bfd_boolean skip_one = FALSE;

  alignment = (1 << align_pow);
  assert (target_size > 0 && alignment >= (addressT) target_size);

  if (!use_nops)
    {
      fill_limit = alignment;
      fill_step = 1;
    }
  else if (!use_no_density)
    {
      /* Combine 2- and 3-byte NOPs to fill anything larger than one.  */
      fill_limit = alignment * 2;
      fill_step = 1;
      skip_one = TRUE;
    }
  else
    {
      /* Fill with 3-byte NOPs -- can only fill multiples of 3.  */
      fill_limit = alignment * 3;
      fill_step = 3;
    }

  /* Try all fill sizes until finding one that works.  */
  for (fill = 0; fill < fill_limit; fill += fill_step)
    {
      if (skip_one && fill == 1)
       continue;
      if ((address + fill) >> align_pow
         == (address + fill + target_size - 1) >> align_pow)
       return fill;
    }
  assert (0);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_text_align_max_fill_size ( int  align_pow,
bfd_boolean  use_nops,
bfd_boolean  use_no_density 
) [static]

Definition at line 7886 of file tc-xtensa.c.

{
  if (!use_nops)
    return (1 << align_pow);
  if (use_no_density)
    return 3 * (1 << align_pow);

  return 1 + (1 << align_pow);
}

Here is the caller graph for this function:

static int get_text_align_nop_count ( offsetT  fill_size,
bfd_boolean  use_no_density 
) [static]

Definition at line 7975 of file tc-xtensa.c.

{
  int count = 0;

  if (use_no_density)
    {
      assert (fill_size % 3 == 0);
      return (fill_size / 3);
    }

  assert (fill_size != 1);  /* Bad argument.  */

  while (fill_size > 1)
    {
      int insn_size = 3;
      if (fill_size == 2 || fill_size == 4)
       insn_size = 2;
      fill_size -= insn_size;
      count++;
    }
  assert (fill_size != 1);  /* Bad algorithm.  */
  return count;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_text_align_nth_nop_size ( offsetT  fill_size,
int  n,
bfd_boolean  use_no_density 
) [static]

Definition at line 8001 of file tc-xtensa.c.

{
  int count = 0;

  if (use_no_density)
    return 3;

  assert (fill_size != 1);  /* Bad argument.  */

  while (fill_size > 1)
    {
      int insn_size = 3;
      if (fill_size == 2 || fill_size == 4)
       insn_size = 2;
      fill_size -= insn_size;
      count++;
      if (n + 1 == count)
       return insn_size;
    }
  assert (0);
  return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_text_align_power ( unsigned  target_size) [static]

Definition at line 7876 of file tc-xtensa.c.

{
  if (target_size <= 4)
    return 2;
  assert (target_size == 8);
  return 3;
}

Here is the caller graph for this function:

static void init_op_placement_info_table ( void  ) [static]

Definition at line 10839 of file tc-xtensa.c.

{
  xtensa_isa isa = xtensa_default_isa;
  xtensa_insnbuf ibuf = xtensa_insnbuf_alloc (isa);
  xtensa_opcode opcode;
  xtensa_format fmt;
  int slot;
  int num_opcodes = xtensa_isa_num_opcodes (isa);

  op_placement_table = (op_placement_info_table)
    xmalloc (sizeof (op_placement_info) * num_opcodes);
  assert (xtensa_isa_num_formats (isa) < MAX_FORMATS);

  for (opcode = 0; opcode < num_opcodes; opcode++)
    {
      op_placement_info *opi = &op_placement_table[opcode];
      /* FIXME: Make tinsn allocation dynamic.  */
      if (xtensa_opcode_num_operands (isa, opcode) >= MAX_INSN_ARGS)
       as_fatal (_("too many operands in instruction"));
      opi->narrowest = XTENSA_UNDEFINED;
      opi->narrowest_size = 0x7F;
      opi->narrowest_slot = 0;
      opi->formats = 0;
      opi->num_formats = 0;
      opi->issuef = 0;
      for (fmt = 0; fmt < xtensa_isa_num_formats (isa); fmt++)
       {
         opi->slots[fmt] = 0;
         for (slot = 0; slot < xtensa_format_num_slots (isa, fmt); slot++)
           {
             if (xtensa_opcode_encode (isa, fmt, slot, ibuf, opcode) == 0)
              {
                int fmt_length = xtensa_format_length (isa, fmt);
                opi->issuef++;
                set_bit (fmt, opi->formats);
                set_bit (slot, opi->slots[fmt]);
                if (fmt_length < opi->narrowest_size
                    || (fmt_length == opi->narrowest_size
                       && (xtensa_format_num_slots (isa, fmt)
                           < xtensa_format_num_slots (isa,
                                                  opi->narrowest))))
                  {
                    opi->narrowest = fmt;
                    opi->narrowest_size = fmt_length;
                    opi->narrowest_slot = slot;
                  }
              }
           }
         if (opi->formats)
           opi->num_formats++;
       }
    }
  xtensa_insnbuf_free (isa, ibuf);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean inside_directive ( directiveE  dir) [static]

Definition at line 1096 of file tc-xtensa.c.

{
  state_stackS *top = directive_state_stack;

  while (top && top->directive != dir)
    top = top->prev;

  return (top != NULL);
}

Here is the caller graph for this function:

static bfd_boolean is_bad_loopend_opcode ( const TInsn tinsn) [static]

Definition at line 4242 of file tc-xtensa.c.

{
  xtensa_opcode opcode = tinsn->opcode;

  if (opcode == XTENSA_UNDEFINED)
    return FALSE;

  if (opcode == xtensa_call0_opcode
      || opcode == xtensa_callx0_opcode
      || opcode == xtensa_call4_opcode
      || opcode == xtensa_callx4_opcode
      || opcode == xtensa_call8_opcode
      || opcode == xtensa_callx8_opcode
      || opcode == xtensa_call12_opcode
      || opcode == xtensa_callx12_opcode
      || opcode == xtensa_isync_opcode
      || opcode == xtensa_ret_opcode
      || opcode == xtensa_ret_n_opcode
      || opcode == xtensa_retw_opcode
      || opcode == xtensa_retw_n_opcode
      || opcode == xtensa_waiti_opcode
      || opcode == xtensa_rsr_lcount_opcode)
    return TRUE;

  return FALSE;
}

Here is the caller graph for this function:

static bfd_boolean is_branch_jmp_to_next ( TInsn insn,
fragS *  fragP 
) [static]

Definition at line 3645 of file tc-xtensa.c.

{
  xtensa_isa isa = xtensa_default_isa;
  int i;
  int num_ops = xtensa_opcode_num_operands (isa, insn->opcode);
  int target_op = -1;
  symbolS *sym;
  fragS *target_frag;

  if (xtensa_opcode_is_branch (isa, insn->opcode) != 1
      && xtensa_opcode_is_jump (isa, insn->opcode) != 1)
    return FALSE;

  for (i = 0; i < num_ops; i++)
    {
      if (xtensa_operand_is_PCrelative (isa, insn->opcode, i) == 1)
       {
         target_op = i;
         break;
       }
    }
  if (target_op == -1)
    return FALSE;

  if (insn->ntok <= target_op)
    return FALSE;

  if (insn->tok[target_op].X_op != O_symbol)
    return FALSE;

  sym = insn->tok[target_op].X_add_symbol;
  if (sym == NULL)
    return FALSE;

  if (insn->tok[target_op].X_add_number != 0)
    return FALSE;

  target_frag = symbol_get_frag (sym);
  if (target_frag == NULL)
    return FALSE;

  if (is_next_frag_target (fragP->fr_next, target_frag)
      && S_GET_VALUE (sym) == target_frag->fr_address)
    return TRUE;

  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean is_direct_call_opcode ( xtensa_opcode  opcode) [static]

Definition at line 2558 of file tc-xtensa.c.

{
  xtensa_isa isa = xtensa_default_isa;
  int n, num_operands;

  if (xtensa_opcode_is_call (isa, opcode) != 1)
    return FALSE;

  num_operands = xtensa_opcode_num_operands (isa, opcode);
  for (n = 0; n < num_operands; n++)
    {
      if (xtensa_operand_is_register (isa, opcode, n) == 0
         && xtensa_operand_is_PCrelative (isa, opcode, n) == 1)
       return TRUE;
    }
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean is_empty_loop ( const TInsn insn,
fragS *  fragP 
) [static]

Definition at line 7735 of file tc-xtensa.c.

{
  const expressionS *expr;
  symbolS *symbolP;
  fragS *next_fragP;

  if (insn->insn_type != ITYPE_INSN)
    return FALSE;

  if (xtensa_opcode_is_loop (xtensa_default_isa, insn->opcode) != 1)
    return FALSE;

  if (insn->ntok <= LOOP_IMMED_OPN)
    return FALSE;

  expr = &insn->tok[LOOP_IMMED_OPN];

  if (expr->X_op != O_symbol)
    return FALSE;

  symbolP = expr->X_add_symbol;
  if (!symbolP)
    return FALSE;

  if (symbol_get_frag (symbolP) == NULL)
    return FALSE;

  if (S_GET_VALUE (symbolP) != 0)
    return FALSE;

  /* Walk through the zero-size fragments from this one.  If we find
     the target fragment, then this is a zero-size loop.  */

  for (next_fragP = fragP->fr_next;
       next_fragP != NULL;
       next_fragP = next_fragP->fr_next)
    {
      if (next_fragP == symbol_get_frag (symbolP))
       return TRUE;
      if (next_fragP->fr_fix != 0)
       return FALSE;
    }
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean is_local_forward_loop ( const TInsn insn,
fragS *  fragP 
) [static]

Definition at line 7782 of file tc-xtensa.c.

{
  const expressionS *expr;
  symbolS *symbolP;
  fragS *next_fragP;

  if (insn->insn_type != ITYPE_INSN)
    return FALSE;

  if (xtensa_opcode_is_loop (xtensa_default_isa, insn->opcode) != 1)
    return FALSE;

  if (insn->ntok <= LOOP_IMMED_OPN)
    return FALSE;

  expr = &insn->tok[LOOP_IMMED_OPN];

  if (expr->X_op != O_symbol)
    return FALSE;

  symbolP = expr->X_add_symbol;
  if (!symbolP)
    return FALSE;

  if (symbol_get_frag (symbolP) == NULL)
    return FALSE;

  /* Walk through fragments until we find the target.
     If we do not find the target, then this is an invalid loop.  */

  for (next_fragP = fragP->fr_next;
       next_fragP != NULL;
       next_fragP = next_fragP->fr_next)
    {
      if (next_fragP == symbol_get_frag (symbolP))
       return TRUE;
    }

  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean is_narrow_branch_guaranteed_in_range ( fragS *  fragP,
TInsn tinsn 
) [static]

Definition at line 7059 of file tc-xtensa.c.

{
  const expressionS *expr = &tinsn->tok[1];
  symbolS *symbolP = expr->X_add_symbol;
  offsetT max_distance = expr->X_add_number;
  fragS *target_frag;

  if (expr->X_op != O_symbol)
    return FALSE;

  target_frag = symbol_get_frag (symbolP);

  max_distance += (S_GET_VALUE (symbolP) - target_frag->fr_address);
  if (is_branch_jmp_to_next (tinsn, fragP))
    return FALSE;

  /* The branch doesn't branch over it's own frag,
     but over the subsequent ones.  */
  fragP = fragP->fr_next;
  while (fragP != NULL && fragP != target_frag && max_distance <= MAX_IMMED6)
    {
      max_distance += unrelaxed_frag_max_size (fragP);
      fragP = fragP->fr_next;
    }
  if (max_distance <= MAX_IMMED6 && fragP == target_frag)
    return TRUE;
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean is_next_frag_target ( const fragS *  fragP,
const fragS *  target 
) [static]

Definition at line 3621 of file tc-xtensa.c.

{
  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;
}

Here is the caller graph for this function:

static bfd_boolean is_register_writer ( const TInsn insn,
const char *  regset,
int  regnum 
) [static]

Definition at line 4212 of file tc-xtensa.c.

{
  int i;
  int num_ops;
  xtensa_isa isa = xtensa_default_isa;

  num_ops = xtensa_opcode_num_operands (isa, insn->opcode);

  for (i = 0; i < num_ops; i++)
    {
      char inout;
      inout = xtensa_operand_inout (isa, insn->opcode, i);
      if ((inout == 'o' || inout == 'm')
         && xtensa_operand_is_register (isa, insn->opcode, i) == 1)
       {
         xtensa_regfile opnd_rf =
           xtensa_operand_regfile (isa, insn->opcode, i);
         if (!strcmp (xtensa_regfile_shortname (isa, opnd_rf), regset))
           {
             if ((insn->tok[i].X_op == O_register)
                && (insn->tok[i].X_add_number == regnum))
              return TRUE;
           }
       }
    }
  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean is_unaligned_label ( symbolS *  sym) [static]

Definition at line 4276 of file tc-xtensa.c.

{
  const char *name = S_GET_NAME (sym);
  static size_t fake_size = 0;

  if (name
      && name[0] == '.'
      && name[1] == 'L' && (name[2] == 'n' || name[2] == 'M'))
    return TRUE;

  /* FAKE_LABEL_NAME followed by "F", "L" or "endfunc" */
  if (fake_size == 0)
    fake_size = strlen (FAKE_LABEL_NAME);

  if (name
      && strncmp (FAKE_LABEL_NAME, name, fake_size) == 0
      && (name[fake_size] == 'F'
         || name[fake_size] == 'L'
         || (name[fake_size] == 'e'
             && strncmp ("endfunc", name+fake_size, 7) == 0)))
    return TRUE;

  return FALSE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean is_unique_insn_expansion ( TransitionRule *  r) [static]

Definition at line 2919 of file tc-xtensa.c.

{
  if (!r->to_instr || r->to_instr->next != NULL)
    return FALSE;
  if (r->to_instr->typ != INSTR_INSTR)
    return FALSE;
  return TRUE;
}

Here is the caller graph for this function:

Definition at line 10936 of file tc-xtensa.c.

{
  return (stack->ninsn == 0);
}

Here is the caller graph for this function:

Definition at line 10943 of file tc-xtensa.c.

{
  return (stack->ninsn == MAX_ISTACK);
}

Here is the caller graph for this function:

void istack_init ( IStack stack)

Definition at line 10928 of file tc-xtensa.c.

{
  memset (stack, 0, sizeof (IStack));
  stack->ninsn = 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void istack_pop ( IStack stack)

Definition at line 10994 of file tc-xtensa.c.

{
  int rec = stack->ninsn - 1;
  assert (!istack_empty (stack));
  stack->ninsn--;
  tinsn_init (&stack->insn[rec]);
}

Here is the call graph for this function:

void istack_push ( IStack stack,
TInsn insn 
)

Definition at line 10965 of file tc-xtensa.c.

{
  int rec = stack->ninsn;
  assert (!istack_full (stack));
  stack->insn[rec] = *insn;
  stack->ninsn++;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 10978 of file tc-xtensa.c.

{
  int rec = stack->ninsn;
  TInsn *insn;
  assert (!istack_full (stack));
  insn = &stack->insn[rec];
  tinsn_init (insn);
  stack->ninsn++;
  return insn;
}

Here is the call graph for this function:

Here is the caller graph for this function:

TInsn* istack_top ( IStack stack)

Definition at line 10953 of file tc-xtensa.c.

{
  int rec = stack->ninsn - 1;
  assert (!istack_empty (stack));
  return &stack->insn[rec];
}

Here is the call graph for this function:

static bfd_reloc_code_real_type map_operator_to_reloc ( unsigned char  operator) [static]

Definition at line 1643 of file tc-xtensa.c.

{
  struct suffix_reloc_map *sfx;
  bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;

  for (sfx = &suffix_relocs[0]; sfx->suffix; sfx++)
    {
      if (sfx->operator == operator)
       {
         reloc = sfx->reloc;
         break;
       }
    }

  if (reloc == BFD_RELOC_UNUSED)
    return BFD_RELOC_32;

  return reloc;
}

Here is the caller graph for this function:

Definition at line 1623 of file tc-xtensa.c.

{
  struct suffix_reloc_map *sfx;
  unsigned char operator = (unsigned char) -1;
  
  for (sfx = &suffix_relocs[0]; sfx->suffix; sfx++)
    {
      if (sfx->reloc == reloc)
       {
         operator = sfx->operator;
         break;
       }
    }
  assert (operator != (unsigned char) -1);
  return operator;
}

Here is the caller graph for this function:

static void mark_literal_frags ( seg_list segment) [static]

Definition at line 9822 of file tc-xtensa.c.

{
  frchainS *frchain_from;
  fragS *search_frag;

  while (segment)
    {
      frchain_from = seg_info (segment->seg)->frchainP;
      search_frag = frchain_from->frch_root;
      while (search_frag)
       {
         search_frag->tc_frag_data.is_literal = TRUE;
         search_frag = search_frag->fr_next;
       }
      segment = segment->next;
    }
}

Here is the caller graph for this function:

static bfd_boolean match_section_group ( bfd *abfd  ATTRIBUTE_UNUSED,
asection sec,
void *  inf 
) [static]

Definition at line 9990 of file tc-xtensa.c.

{
  const char *gname = inf;
  const char *group_name = elf_group_name (sec);
  
  return (group_name == gname
         || (group_name != NULL
             && gname != NULL
             && strcmp (group_name, gname) == 0));
}

Here is the call graph for this function:

Here is the caller graph for this function:

void md_apply_fix ( fixS *  fixP,
valueT valP,
segT seg   
)

Definition at line 5498 of file tc-xtensa.c.

{
  char *const fixpos = fixP->fx_frag->fr_literal + fixP->fx_where;
  valueT val = 0;

  /* Subtracted symbols are only allowed for a few relocation types, and
     unless linkrelax is enabled, they should not make it to this point.  */
  if (fixP->fx_subsy && !(linkrelax && (fixP->fx_r_type == BFD_RELOC_32
                                   || fixP->fx_r_type == BFD_RELOC_16
                                   || fixP->fx_r_type == BFD_RELOC_8)))
    as_bad_where (fixP->fx_file, fixP->fx_line, _("expression too complex"));

  switch (fixP->fx_r_type)
    {
    case BFD_RELOC_32:
    case BFD_RELOC_16:
    case BFD_RELOC_8:
      if (fixP->fx_subsy)
       {
         switch (fixP->fx_r_type)
           {
           case BFD_RELOC_8:
             fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8;
             break;
           case BFD_RELOC_16:
             fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16;
             break;
           case BFD_RELOC_32:
             fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32;
             break;
           default:
             break;
           }

         /* An offset is only allowed when it results from adjusting a
            local symbol into a section-relative offset.  If the offset
            came from the original expression, tc_fix_adjustable will have
            prevented the fix from being converted to a section-relative
            form so that we can flag the error here.  */
         if (fixP->fx_offset != 0 && !symbol_section_p (fixP->fx_addsy))
           as_bad_where (fixP->fx_file, fixP->fx_line,
                       _("cannot represent subtraction with an offset"));

         val = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset
               - S_GET_VALUE (fixP->fx_subsy));

         /* The difference value gets written out, and the DIFF reloc
            identifies the address of the subtracted symbol (i.e., the one
            with the lowest address).  */
         *valP = val;
         fixP->fx_offset -= val;
         fixP->fx_subsy = NULL;
       }
      else if (! fixP->fx_addsy)
       {
         val = *valP;
         fixP->fx_done = 1;
       }
      /* fall through */

    case BFD_RELOC_XTENSA_PLT:
      md_number_to_chars (fixpos, val, fixP->fx_size);
      fixP->fx_no_overflow = 0; /* Use the standard overflow check.  */
      break;

    case BFD_RELOC_XTENSA_SLOT0_OP:
    case BFD_RELOC_XTENSA_SLOT1_OP:
    case BFD_RELOC_XTENSA_SLOT2_OP:
    case BFD_RELOC_XTENSA_SLOT3_OP:
    case BFD_RELOC_XTENSA_SLOT4_OP:
    case BFD_RELOC_XTENSA_SLOT5_OP:
    case BFD_RELOC_XTENSA_SLOT6_OP:
    case BFD_RELOC_XTENSA_SLOT7_OP:
    case BFD_RELOC_XTENSA_SLOT8_OP:
    case BFD_RELOC_XTENSA_SLOT9_OP:
    case BFD_RELOC_XTENSA_SLOT10_OP:
    case BFD_RELOC_XTENSA_SLOT11_OP:
    case BFD_RELOC_XTENSA_SLOT12_OP:
    case BFD_RELOC_XTENSA_SLOT13_OP:
    case BFD_RELOC_XTENSA_SLOT14_OP:
      if (linkrelax)
       {
         /* Write the tentative value of a PC-relative relocation to a
            local symbol into the instruction.  The value will be ignored
            by the linker, and it makes the object file disassembly
            readable when all branch targets are encoded in relocations.  */

         assert (fixP->fx_addsy);
         if (S_GET_SEGMENT (fixP->fx_addsy) == seg
             && !S_FORCE_RELOC (fixP->fx_addsy, 1))
           {
             val = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset
                   - md_pcrel_from (fixP));
             (void) xg_apply_fix_value (fixP, val);
           }
       }
      else if (! fixP->fx_addsy)
       {
         val = *valP;
         if (xg_apply_fix_value (fixP, val))
           fixP->fx_done = 1;
       }
      break;

    case BFD_RELOC_XTENSA_ASM_EXPAND:
    case BFD_RELOC_XTENSA_SLOT0_ALT:
    case BFD_RELOC_XTENSA_SLOT1_ALT:
    case BFD_RELOC_XTENSA_SLOT2_ALT:
    case BFD_RELOC_XTENSA_SLOT3_ALT:
    case BFD_RELOC_XTENSA_SLOT4_ALT:
    case BFD_RELOC_XTENSA_SLOT5_ALT:
    case BFD_RELOC_XTENSA_SLOT6_ALT:
    case BFD_RELOC_XTENSA_SLOT7_ALT:
    case BFD_RELOC_XTENSA_SLOT8_ALT:
    case BFD_RELOC_XTENSA_SLOT9_ALT:
    case BFD_RELOC_XTENSA_SLOT10_ALT:
    case BFD_RELOC_XTENSA_SLOT11_ALT:
    case BFD_RELOC_XTENSA_SLOT12_ALT:
    case BFD_RELOC_XTENSA_SLOT13_ALT:
    case BFD_RELOC_XTENSA_SLOT14_ALT:
      /* These all need to be resolved at link-time.  Do nothing now.  */
      break;

    case BFD_RELOC_VTABLE_INHERIT:
    case BFD_RELOC_VTABLE_ENTRY:
      fixP->fx_done = 0;
      break;

    default:
      as_bad (_("unhandled local relocation fix %s"),
             bfd_get_reloc_code_name (fixP->fx_r_type));
    }
}

Here is the call graph for this function:

void md_assemble ( char *  str)

Definition at line 5132 of file tc-xtensa.c.

{
  xtensa_isa isa = xtensa_default_isa;
  char *opname, *file_name;
  unsigned opnamelen;
  bfd_boolean has_underbar = FALSE;
  char *arg_strings[MAX_INSN_ARGS];
  int num_args;
  TInsn orig_insn;          /* Original instruction from the input.  */

  tinsn_init (&orig_insn);

  /* Split off the opcode.  */
  opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/0123456789.");
  opname = xmalloc (opnamelen + 1);
  memcpy (opname, str, opnamelen);
  opname[opnamelen] = '\0';

  num_args = tokenize_arguments (arg_strings, str + opnamelen);
  if (num_args == -1)
    {
      as_bad (_("syntax error"));
      return;
    }

  if (xg_translate_idioms (&opname, &num_args, arg_strings))
    return;

  /* Check for an underbar prefix.  */
  if (*opname == '_')
    {
      has_underbar = TRUE;
      opname += 1;
    }

  orig_insn.insn_type = ITYPE_INSN;
  orig_insn.ntok = 0;
  orig_insn.is_specific_opcode = (has_underbar || !use_transform ());

  orig_insn.opcode = xtensa_opcode_lookup (isa, opname);
  if (orig_insn.opcode == XTENSA_UNDEFINED)
    {
      xtensa_format fmt = xtensa_format_lookup (isa, opname);
      if (fmt == XTENSA_UNDEFINED)
       {
         as_bad (_("unknown opcode or format name '%s'"), opname);
         error_reset_cur_vinsn ();
         return;
       }
      if (!cur_vinsn.inside_bundle)
       {
         as_bad (_("format names only valid inside bundles"));
         error_reset_cur_vinsn ();
         return;
       }
      if (cur_vinsn.format != XTENSA_UNDEFINED)
       as_warn (_("multiple formats specified for one bundle; using '%s'"),
               opname);
      cur_vinsn.format = fmt;
      free (has_underbar ? opname - 1 : opname);
      error_reset_cur_vinsn ();
      return;
    }

  /* Parse the arguments.  */
  if (parse_arguments (&orig_insn, num_args, arg_strings))
    {
      as_bad (_("syntax error"));
      error_reset_cur_vinsn ();
      return;
    }

  /* Free the opcode and argument strings, now that they've been parsed.  */
  free (has_underbar ? opname - 1 : opname);
  opname = 0;
  while (num_args-- > 0)
    free (arg_strings[num_args]);

  /* Get expressions for invisible operands.  */
  if (get_invisible_operands (&orig_insn))
    {
      error_reset_cur_vinsn ();
      return;
    }

  /* Check for the right number and type of arguments.  */
  if (tinsn_check_arguments (&orig_insn))
    {
      error_reset_cur_vinsn ();
      return;
    }

  /* A FLIX bundle may be spread across multiple input lines.  We want to
     report the first such line in the debug information.  Record the line
     number for each TInsn (assume the file name doesn't change), so the
     first line can be found later.  */
  as_where (&file_name, &orig_insn.linenum);

  xg_add_branch_and_loop_targets (&orig_insn);

  /* Check that immediate value for ENTRY is >= 16.  */
  if (orig_insn.opcode == xtensa_entry_opcode && orig_insn.ntok >= 3)
    {
      expressionS *exp = &orig_insn.tok[2];
      if (exp->X_op == O_constant && exp->X_add_number < 16)
       as_warn (_("entry instruction with stack decrement < 16"));
    }

  /* Finish it off:
     assemble_tokens (opcode, tok, ntok);
     expand the tokens from the orig_insn into the
     stack of instructions that will not expand
     unless required at relaxation time.  */

  if (!cur_vinsn.inside_bundle)
    emit_single_op (&orig_insn);
  else /* We are inside a bundle.  */
    {
      cur_vinsn.slots[cur_vinsn.num_slots] = orig_insn;
      cur_vinsn.num_slots++;
      if (*input_line_pointer == '}'
         || *(input_line_pointer - 1) == '}'
         || *(input_line_pointer - 2) == '}')
       finish_vinsn (&cur_vinsn);
    }

  /* We've just emitted a new instruction so clear the list of labels.  */
  xtensa_clear_insn_labels ();
}

Here is the call graph for this function:

char* md_atof ( int type  ,
char *  litP,
int sizeP 
)

Definition at line 5634 of file tc-xtensa.c.

{
  int prec;
  LITTLENUM_TYPE words[4];
  char *t;
  int i;

  switch (type)
    {
    case 'f':
      prec = 2;
      break;

    case 'd':
      prec = 4;
      break;

    default:
      *sizeP = 0;
      return "bad call to md_atof";
    }

  t = atof_ieee (input_line_pointer, type, words);
  if (t)
    input_line_pointer = t;

  *sizeP = prec * 2;

  for (i = prec - 1; i >= 0; i--)
    {
      int idx = i;
      if (target_big_endian)
       idx = (prec - 1 - i);

      md_number_to_chars (litP, (valueT) words[idx], 2);
      litP += 2;
    }

  return NULL;
}

Here is the call graph for this function:

void md_begin ( void  )

Definition at line 4908 of file tc-xtensa.c.

{
  segT current_section = now_seg;
  int current_subsec = now_subseg;
  xtensa_isa isa;

  xtensa_default_isa = xtensa_isa_init (0, 0);
  isa = xtensa_default_isa;

  linkrelax = 1;

  /* Set up the literal sections.  */
  memset (&default_lit_sections, 0, sizeof (default_lit_sections));

  subseg_set (current_section, current_subsec);

  xg_init_vinsn (&cur_vinsn);

  xtensa_addi_opcode = xtensa_opcode_lookup (isa, "addi");
  xtensa_addmi_opcode = xtensa_opcode_lookup (isa, "addmi");
  xtensa_call0_opcode = xtensa_opcode_lookup (isa, "call0");
  xtensa_call4_opcode = xtensa_opcode_lookup (isa, "call4");
  xtensa_call8_opcode = xtensa_opcode_lookup (isa, "call8");
  xtensa_call12_opcode = xtensa_opcode_lookup (isa, "call12");
  xtensa_callx0_opcode = xtensa_opcode_lookup (isa, "callx0");
  xtensa_callx4_opcode = xtensa_opcode_lookup (isa, "callx4");
  xtensa_callx8_opcode = xtensa_opcode_lookup (isa, "callx8");
  xtensa_callx12_opcode = xtensa_opcode_lookup (isa, "callx12");
  xtensa_const16_opcode = xtensa_opcode_lookup (isa, "const16");
  xtensa_entry_opcode = xtensa_opcode_lookup (isa, "entry");
  xtensa_movi_opcode = xtensa_opcode_lookup (isa, "movi");
  xtensa_movi_n_opcode = xtensa_opcode_lookup (isa, "movi.n");
  xtensa_isync_opcode = xtensa_opcode_lookup (isa, "isync");
  xtensa_jx_opcode = xtensa_opcode_lookup (isa, "jx");
  xtensa_l32r_opcode = xtensa_opcode_lookup (isa, "l32r");
  xtensa_loop_opcode = xtensa_opcode_lookup (isa, "loop");
  xtensa_loopnez_opcode = xtensa_opcode_lookup (isa, "loopnez");
  xtensa_loopgtz_opcode = xtensa_opcode_lookup (isa, "loopgtz");
  xtensa_nop_opcode = xtensa_opcode_lookup (isa, "nop");
  xtensa_nop_n_opcode = xtensa_opcode_lookup (isa, "nop.n");
  xtensa_or_opcode = xtensa_opcode_lookup (isa, "or");
  xtensa_ret_opcode = xtensa_opcode_lookup (isa, "ret");
  xtensa_ret_n_opcode = xtensa_opcode_lookup (isa, "ret.n");
  xtensa_retw_opcode = xtensa_opcode_lookup (isa, "retw");
  xtensa_retw_n_opcode = xtensa_opcode_lookup (isa, "retw.n");
  xtensa_rsr_lcount_opcode = xtensa_opcode_lookup (isa, "rsr.lcount");
  xtensa_waiti_opcode = xtensa_opcode_lookup (isa, "waiti");

  init_op_placement_info_table ();

  /* Set up the assembly state.  */
  if (!frag_now->tc_frag_data.is_assembly_state_set)
    xtensa_set_frag_assembly_state (frag_now);
}

Here is the call graph for this function:

void md_convert_frag ( bfd *abfd  ATTRIBUTE_UNUSED,
segT sec  ,
fragS *  fragp 
)

Definition at line 8931 of file tc-xtensa.c.

{
  static xtensa_insnbuf vbuf = NULL;
  xtensa_isa isa = xtensa_default_isa;
  int slot;
  int num_slots;
  xtensa_format fmt;
  char *file_name;
  unsigned line;

  as_where (&file_name, &line);
  new_logical_line (fragp->fr_file, fragp->fr_line);

  switch (fragp->fr_subtype)
    {
    case RELAX_ALIGN_NEXT_OPCODE:
      /* Always convert.  */
      convert_frag_align_next_opcode (fragp);
      break;

    case RELAX_DESIRE_ALIGN:
      /* Do nothing.  If not aligned already, too bad.  */
      break;

    case RELAX_LITERAL:
    case RELAX_LITERAL_FINAL:
      break;

    case RELAX_SLOTS:
      if (vbuf == NULL)
       vbuf = xtensa_insnbuf_alloc (isa);

      xtensa_insnbuf_from_chars
       (isa, vbuf, (unsigned char *) fragp->fr_opcode, 0);
      fmt = xtensa_format_decode (isa, vbuf);
      num_slots = xtensa_format_num_slots (isa, fmt);

      for (slot = 0; slot < num_slots; slot++)
       {
         switch (fragp->tc_frag_data.slot_subtypes[slot])
           {
           case RELAX_NARROW:
             convert_frag_narrow (sec, fragp, fmt, slot);
             break;

           case RELAX_IMMED:
           case RELAX_IMMED_STEP1:
           case RELAX_IMMED_STEP2:
             /* Place the immediate.  */
             convert_frag_immed
              (sec, fragp,
               fragp->tc_frag_data.slot_subtypes[slot] - RELAX_IMMED,
               fmt, slot);
             break;

           default:
             /* This is OK because some slots could have
               relaxations and others have none.  */
             break;
           }
       }
      break;

    case RELAX_UNREACHABLE:
      memset (&fragp->fr_literal[fragp->fr_fix], 0, fragp->fr_var);
      fragp->fr_fix += fragp->tc_frag_data.text_expansion[0];
      fragp->fr_var -= fragp->tc_frag_data.text_expansion[0];
      frag_wane (fragp);
      break;

    case RELAX_MAYBE_UNREACHABLE:
    case RELAX_MAYBE_DESIRE_ALIGN:
      frag_wane (fragp);
      break;

    case RELAX_FILL_NOP:
      convert_frag_fill_nop (fragp);
      break;

    case RELAX_LITERAL_NR:
      if (use_literal_section)
       {
         /* This should have been handled during relaxation.  When
            relaxing a code segment, literals sometimes need to be
            added to the corresponding literal segment.  If that
            literal segment has already been relaxed, then we end up
            in this situation.  Marking the literal segments as data
            would make this happen less often (since GAS always relaxes
            code before data), but we could still get into trouble if
            there are instructions in a segment that is not marked as
            containing code.  Until we can implement a better solution,
            cheat and adjust the addresses of all the following frags.
            This could break subsequent alignments, but the linker's
            literal coalescing will do that anyway.  */

         fragS *f;
         fragp->fr_subtype = RELAX_LITERAL_FINAL;
         assert (fragp->tc_frag_data.unreported_expansion == 4);
         memset (&fragp->fr_literal[fragp->fr_fix], 0, 4);
         fragp->fr_var -= 4;
         fragp->fr_fix += 4;
         for (f = fragp->fr_next; f; f = f->fr_next)
           f->fr_address += 4;
       }
      else
       as_bad (_("invalid relaxation fragment result"));
      break;
    }

  fragp->fr_var = 0;
  new_logical_line (file_name, line);
}

Here is the call graph for this function:

int md_estimate_size_before_relax ( fragS *  fragP,
segT seg  ATTRIBUTE_UNUSED 
)

Definition at line 5677 of file tc-xtensa.c.

{
  return total_frag_text_expansion (fragP);
}

Here is the call graph for this function:

void md_number_to_chars ( char *  buf,
valueT  val,
int  n 
)

Definition at line 4894 of file tc-xtensa.c.

Here is the call graph for this function:

int md_parse_option ( int c  ,
char *  arg 
)

Definition at line 743 of file tc-xtensa.c.

{
  switch (c)
    {
    case option_density:
      as_warn (_("--density option is ignored"));
      return 1;
    case option_no_density:
      as_warn (_("--no-density option is ignored"));
      return 1;
    case option_link_relax:
      linkrelax = 1;
      return 1;
    case option_no_link_relax:
      linkrelax = 0;
      return 1;
    case option_generics:
      as_warn (_("--generics is deprecated; use --transform instead"));
      return md_parse_option (option_transform, arg);
    case option_no_generics:
      as_warn (_("--no-generics is deprecated; use --no-transform instead"));
      return md_parse_option (option_no_transform, arg);
    case option_relax:
      as_warn (_("--relax is deprecated; use --transform instead"));
      return md_parse_option (option_transform, arg);
    case option_no_relax:
      as_warn (_("--no-relax is deprecated; use --no-transform instead"));
      return md_parse_option (option_no_transform, arg);
    case option_longcalls:
      directive_state[directive_longcalls] = TRUE;
      return 1;
    case option_no_longcalls:
      directive_state[directive_longcalls] = FALSE;
      return 1;
    case option_text_section_literals:
      use_literal_section = FALSE;
      return 1;
    case option_no_text_section_literals:
      use_literal_section = TRUE;
      return 1;
    case option_absolute_literals:
      if (!absolute_literals_supported)
       {
         as_fatal (_("--absolute-literals option not supported in this Xtensa configuration"));
         return 0;
       }
      directive_state[directive_absolute_literals] = TRUE;
      return 1;
    case option_no_absolute_literals:
      directive_state[directive_absolute_literals] = FALSE;
      return 1;

    case option_workaround_a0_b_retw:
      workaround_a0_b_retw = TRUE;
      return 1;
    case option_no_workaround_a0_b_retw:
      workaround_a0_b_retw = FALSE;
      return 1;
    case option_workaround_b_j_loop_end:
      workaround_b_j_loop_end = TRUE;
      return 1;
    case option_no_workaround_b_j_loop_end:
      workaround_b_j_loop_end = FALSE;
      return 1;

    case option_workaround_short_loop:
      workaround_short_loop = TRUE;
      return 1;
    case option_no_workaround_short_loop:
      workaround_short_loop = FALSE;
      return 1;

    case option_workaround_all_short_loops:
      workaround_all_short_loops = TRUE;
      return 1;
    case option_no_workaround_all_short_loops:
      workaround_all_short_loops = FALSE;
      return 1;

    case option_workaround_close_loop_end:
      workaround_close_loop_end = TRUE;
      return 1;
    case option_no_workaround_close_loop_end:
      workaround_close_loop_end = FALSE;
      return 1;

    case option_no_workarounds:
      workaround_a0_b_retw = FALSE;
      workaround_b_j_loop_end = FALSE;
      workaround_short_loop = FALSE;
      workaround_all_short_loops = FALSE;
      workaround_close_loop_end = FALSE;
      return 1;

    case option_align_targets:
      align_targets = TRUE;
      return 1;
    case option_no_align_targets:
      align_targets = FALSE;
      return 1;

    case option_warn_unaligned_targets:
      warn_unaligned_branch_targets = TRUE;
      return 1;

    case option_rename_section_name:
      build_section_rename (arg);
      return 1;

    case 'Q':
      /* -Qy, -Qn: SVR4 arguments controlling whether a .comment section
         should be emitted or not.  FIXME: Not implemented.  */
      return 1;

    case option_prefer_l32r:
      if (prefer_const16)
       as_fatal (_("prefer-l32r conflicts with prefer-const16"));
      prefer_l32r = 1;
      return 1;

    case option_prefer_const16:
      if (prefer_l32r)
       as_fatal (_("prefer-const16 conflicts with prefer-l32r"));
      prefer_const16 = 1;
      return 1;

    case option_target_hardware:
      {
       int earliest, latest = 0;
       if (*arg == 0 || *arg == '-')
         as_fatal (_("invalid target hardware version"));

       earliest = strtol (arg, &arg, 0);

       if (*arg == 0)
         latest = earliest;
       else if (*arg == '-')
         {
           if (*++arg == 0)
             as_fatal (_("invalid target hardware version"));
           latest = strtol (arg, &arg, 0);
         }
       if (*arg != 0)
         as_fatal (_("invalid target hardware version"));

       xtensa_setup_hw_workarounds (earliest, latest);
       return 1;
      }

    case option_transform:
      /* This option has no affect other than to use the defaults,
        which are already set.  */
      return 1;

    case option_no_transform:
      /* This option turns off all transformations of any kind.
        However, because we want to preserve the state of other
        directives, we only change its own field.  Thus, before
        you perform any transformation, always check if transform
        is available.  If you use the functions we provide for this
        purpose, you will be ok.  */
      directive_state[directive_transform] = FALSE;
      return 1;

    default:
      return 0;
    }
}

Here is the call graph for this function:

long md_pcrel_from ( fixS *  fixP)

Definition at line 5321 of file tc-xtensa.c.

{
  char *insn_p;
  static xtensa_insnbuf insnbuf = NULL;
  static xtensa_insnbuf slotbuf = NULL;
  int opnum;
  uint32 opnd_value;
  xtensa_opcode opcode;
  xtensa_format fmt;
  int slot;
  xtensa_isa isa = xtensa_default_isa;
  valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
  bfd_boolean alt_reloc;

  if (fixP->fx_r_type == BFD_RELOC_XTENSA_ASM_EXPAND)
    return 0;

  if (!insnbuf)
    {
      insnbuf = xtensa_insnbuf_alloc (isa);
      slotbuf = xtensa_insnbuf_alloc (isa);
    }

  insn_p = &fixP->fx_frag->fr_literal[fixP->fx_where];
  xtensa_insnbuf_from_chars (isa, insnbuf, (unsigned char *) insn_p, 0);
  fmt = xtensa_format_decode (isa, insnbuf);

  if (fmt == XTENSA_UNDEFINED)
    as_fatal (_("bad instruction format"));

  if (decode_reloc (fixP->fx_r_type, &slot, &alt_reloc) != 0)
    as_fatal (_("invalid relocation"));

  xtensa_format_get_slot (isa, fmt, slot, insnbuf, slotbuf);
  opcode = xtensa_opcode_decode (isa, fmt, slot, slotbuf);

  /* Check for "alternate" relocations (operand not specified).  None
     of the current uses for these are really PC-relative.  */
  if (alt_reloc || opcode == xtensa_const16_opcode)
    {
      if (opcode != xtensa_l32r_opcode
         && opcode != xtensa_const16_opcode)
       as_fatal (_("invalid relocation for '%s' instruction"),
                xtensa_opcode_name (isa, opcode));
      return 0;
    }

  opnum = get_relaxable_immed (opcode);
  opnd_value = 0;
  if (xtensa_operand_is_PCrelative (isa, opcode, opnum) != 1
      || xtensa_operand_do_reloc (isa, opcode, opnum, &opnd_value, addr))
    {
      as_bad_where (fixP->fx_file,
                  fixP->fx_line,
                  _("invalid relocation for operand %d of '%s'"),
                  opnum, xtensa_opcode_name (isa, opcode));
      return 0;
    }
  return 0 - opnd_value;
}

Here is the call graph for this function:

valueT md_section_align ( segT segment  ATTRIBUTE_UNUSED,
valueT size   
)

Definition at line 5314 of file tc-xtensa.c.

{
  return size;                     /* Byte alignment is fine.  */
}
void md_show_usage ( FILE *  stream)

Definition at line 914 of file tc-xtensa.c.

{
  fputs ("\n\
Xtensa options:\n\
  --[no-]text-section-literals\n\
                          [Do not] put literals in the text section\n\
  --[no-]absolute-literals\n\
                          [Do not] default to use non-PC-relative literals\n\
  --[no-]target-align     [Do not] try to align branch targets\n\
  --[no-]longcalls        [Do not] emit 32-bit call sequences\n\
  --[no-]transform        [Do not] transform instructions\n\
  --rename-section old=new Rename section 'old' to 'new'\n", stream);
}
symbolS* md_undefined_symbol ( char *name  ATTRIBUTE_UNUSED)

Definition at line 5305 of file tc-xtensa.c.

{
  return NULL;
}
static offsetT min_bytes_to_other_loop_end ( fragS *  fragP,
fragS *  current_target,
offsetT  max_size 
) [static]

Definition at line 7397 of file tc-xtensa.c.

{
  offsetT offset = 0;
  fragS *current_fragP;

  for (current_fragP = fragP;
       current_fragP;
       current_fragP = current_fragP->fr_next)
    {
      if (current_fragP->tc_frag_data.is_loop_target
         && current_fragP != current_target)
       return offset;

      offset += unrelaxed_frag_min_size (current_fragP);

      if (offset >= max_size)
       return max_size;
    }
  return max_size;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 5728 of file tc-xtensa.c.

{
  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 = (unsigned char **) xcalloc (cycles, sizeof (unsigned char *));
  for (i = 0; i < cycles; i++)
    rt->units[i] = (unsigned char *) xcalloc (nu, sizeof (unsigned char));

  return rt;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int next_frag_format_size ( const fragS *  fragP) [static]

Definition at line 4395 of file tc-xtensa.c.

{
  const fragS *next_fragP = next_non_empty_frag (fragP);
  return frag_format_size (next_fragP);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static bfd_boolean next_frag_is_branch_target ( const fragS *  fragP) [static]

Definition at line 4470 of file tc-xtensa.c.

{
  /* Sometimes an empty will end up here due to storage allocation issues,
     so we have to skip until we find something legit.  */
  for (fragP = fragP->fr_next; fragP; fragP = fragP->fr_next)
    {
      if (fragP->tc_frag_data.is_branch_target)
       return TRUE;
      if (fragP->fr_fix != 0)
       break;
    }
  return FALSE;
}

Here is the caller graph for this function: