[AArch64] Fix typo in comments on relocation name
[deliverable/binutils-gdb.git] / gas / config / tc-xtensa.c
index 4aa421b6156328dd8420555f106073851810c6a5..836b5505246c5a3ce7f0de5b9c3c337794eef6ee 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-xtensa.c -- Assemble Xtensa instructions.
-   Copyright (C) 2003-2016 Free Software Foundation, Inc.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -29,6 +29,7 @@
 #include "xtensa-istack.h"
 #include "struc-symbol.h"
 #include "xtensa-config.h"
+#include "elf/xtensa.h"
 
 /* Provide default values for new configuration settings.  */
 #ifndef XSHAL_ABI
@@ -71,13 +72,13 @@ const char FLT_CHARS[] = "rRsSfFdDxXpP";
 /* Flags to indicate whether the hardware supports the density and
    absolute literals options.  */
 
-bfd_boolean density_supported = XCHAL_HAVE_DENSITY;
-bfd_boolean absolute_literals_supported = XSHAL_USE_ABSOLUTE_LITERALS;
+bfd_boolean density_supported;
+bfd_boolean absolute_literals_supported;
 
 static vliw_insn cur_vinsn;
 
 unsigned xtensa_num_pipe_stages;
-unsigned xtensa_fetch_width = XCHAL_INST_FETCH_WIDTH;
+unsigned xtensa_fetch_width;
 
 static enum debug_info_type xt_saved_debug_type = DEBUG_NONE;
 
@@ -213,8 +214,6 @@ int generating_literals = 0;
 /* Required branch target alignment.  */
 #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) \
   (((flag) & (~XTENSA_PROP_BT_ALIGN_MASK)) | \
     (((align) << 9) & XTENSA_PROP_BT_ALIGN_MASK))
@@ -235,8 +234,6 @@ int generating_literals = 0;
 
 #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) \
   (((flag) & (~XTENSA_PROP_ALIGNMENT_MASK)) | \
     (((align) << 12) & XTENSA_PROP_ALIGNMENT_MASK))
@@ -364,7 +361,7 @@ struct suffix_reloc_map
   const char *suffix;
   int length;
   bfd_reloc_code_real_type reloc;
-  unsigned char operator;
+  operatorT operator;
 };
 
 #define SUFFIX_MAP(str, reloc, op) { str, sizeof (str) - 1, reloc, op }
@@ -380,7 +377,6 @@ static struct suffix_reloc_map suffix_relocs[] =
   SUFFIX_MAP ("tlscall", BFD_RELOC_XTENSA_TLS_CALL,    O_tlscall),
   SUFFIX_MAP ("tpoff", BFD_RELOC_XTENSA_TLS_TPOFF,     O_tpoff),
   SUFFIX_MAP ("dtpoff",        BFD_RELOC_XTENSA_TLS_DTPOFF,    O_dtpoff),
-  { (char *) 0, 0,     BFD_RELOC_UNUSED,               0 }
 };
 
 
@@ -423,21 +419,13 @@ bfd_boolean directive_state[] =
 {
   FALSE,                       /* none */
   FALSE,                       /* literal */
-#if !XCHAL_HAVE_DENSITY
   FALSE,                       /* density */
-#else
-  TRUE,                                /* density */
-#endif
   TRUE,                                /* transform */
   FALSE,                       /* freeregs */
   FALSE,                       /* longcalls */
   FALSE,                       /* literal_prefix */
   FALSE,                       /* schedule */
-#if XSHAL_USE_ABSOLUTE_LITERALS
-  TRUE                         /* absolute_literals */
-#else
   FALSE                                /* absolute_literals */
-#endif
 };
 
 /* A circular list of all potential and actual literal pool locations
@@ -529,10 +517,6 @@ 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);
 
-/* Import from elf32-xtensa.c in BFD library.  */
-
-extern asection *xtensa_make_property_section (asection *, const char *);
-
 /* op_placement_info functions.  */
 
 static void init_op_placement_info_table (void);
@@ -1195,7 +1179,7 @@ directive_pop (directiveE *directive,
 
   if (!directive_state_stack)
     {
-      as_bad (_("unmatched end directive"));
+      as_bad (_("unmatched .end directive"));
       *directive = directive_none;
       return;
     }
@@ -1724,7 +1708,7 @@ xtensa_elf_suffix (char **str_p, expressionS *exp_p)
   char *str2;
   int ch;
   int len;
-  struct suffix_reloc_map *ptr;
+  unsigned int i;
 
   if (*str++ != '@')
     return BFD_RELOC_NONE;
@@ -1741,10 +1725,10 @@ xtensa_elf_suffix (char **str_p, expressionS *exp_p)
   len = str2 - ident;
 
   ch = ident[0];
-  for (ptr = &suffix_relocs[0]; ptr->length > 0; ptr++)
-    if (ch == ptr->suffix[0]
-       && len == ptr->length
-       && memcmp (ident, ptr->suffix, ptr->length) == 0)
+  for (i = 0; i < ARRAY_SIZE (suffix_relocs); i++)
+    if (ch == suffix_relocs[i].suffix[0]
+       && len == suffix_relocs[i].length
+       && memcmp (ident, suffix_relocs[i].suffix, suffix_relocs[i].length) == 0)
       {
        /* Now check for "identifier@suffix+constant".  */
        if (*str == '-' || *str == '+')
@@ -1765,7 +1749,7 @@ xtensa_elf_suffix (char **str_p, expressionS *exp_p)
          }
 
        *str_p = str;
-       return ptr->reloc;
+       return suffix_relocs[i].reloc;
       }
 
   return BFD_RELOC_UNUSED;
@@ -1773,21 +1757,21 @@ xtensa_elf_suffix (char **str_p, expressionS *exp_p)
 
 
 /* Find the matching operator type.  */
-static unsigned char
+static operatorT
 map_suffix_reloc_to_operator (bfd_reloc_code_real_type reloc)
 {
-  struct suffix_reloc_map *sfx;
-  unsigned char operator = (unsigned char) -1;
+  operatorT operator = O_illegal;
+  unsigned int i;
 
-  for (sfx = &suffix_relocs[0]; sfx->suffix; sfx++)
+  for (i = 0; i < ARRAY_SIZE (suffix_relocs); i++)
     {
-      if (sfx->reloc == reloc)
+      if (suffix_relocs[i].reloc == reloc)
        {
-         operator = sfx->operator;
+         operator = suffix_relocs[i].operator;
          break;
        }
     }
-  gas_assert (operator != (unsigned char) -1);
+  gas_assert (operator != O_illegal);
   return operator;
 }
 
@@ -1796,14 +1780,14 @@ map_suffix_reloc_to_operator (bfd_reloc_code_real_type reloc)
 static bfd_reloc_code_real_type
 map_operator_to_reloc (unsigned char operator, bfd_boolean is_literal)
 {
-  struct suffix_reloc_map *sfx;
+  unsigned int i;
   bfd_reloc_code_real_type reloc = BFD_RELOC_UNUSED;
 
-  for (sfx = &suffix_relocs[0]; sfx->suffix; sfx++)
+  for (i = 0; i < ARRAY_SIZE (suffix_relocs); i++)
     {
-      if (sfx->operator == operator)
+      if (suffix_relocs[i].operator == operator)
        {
-         reloc = sfx->reloc;
+         reloc = suffix_relocs[i].reloc;
          break;
        }
     }
@@ -2236,7 +2220,7 @@ xg_reverse_shift_count (char **cnt_argp)
   cnt_arg = *cnt_argp;
 
   /* replace the argument with "31-(argument)" */
-  new_arg = concat ("31-(", cnt_argp, ")", (char *) NULL);
+  new_arg = concat ("31-(", cnt_arg, ")", (char *) NULL);
 
   free (cnt_arg);
   *cnt_argp = new_arg;
@@ -2424,7 +2408,7 @@ xtensa_translate_old_userreg_ops (char **popname)
 
   /* Translate the opcode.  */
   sr_name = xtensa_sysreg_name (isa, sr);
-  new_opname = (char *) xmalloc (strlen (sr_name) + 6);
+  new_opname = XNEWVEC (char, strlen (sr_name) + 6);
   sprintf (new_opname, "%s%cur.%s", (has_underbar ? "_" : ""),
           opname[0], sr_name);
   free (*popname);
@@ -5224,6 +5208,24 @@ md_number_to_chars (char *buf, valueT val, int n)
     number_to_chars_littleendian (buf, val, n);
 }
 
+static void
+xg_init_global_config (void)
+{
+  target_big_endian = XCHAL_HAVE_BE;
+
+  density_supported = XCHAL_HAVE_DENSITY;
+  absolute_literals_supported = XSHAL_USE_ABSOLUTE_LITERALS;
+  xtensa_fetch_width = XCHAL_INST_FETCH_WIDTH;
+
+  directive_state[directive_density] = XCHAL_HAVE_DENSITY;
+  directive_state[directive_absolute_literals] = XSHAL_USE_ABSOLUTE_LITERALS;
+}
+
+void
+xtensa_init (int argc ATTRIBUTE_UNUSED, char **argv ATTRIBUTE_UNUSED)
+{
+  xg_init_global_config ();
+}
 
 /* This function is called once, at assembler startup time.  It should
    set up all the tables, etc. that the MD part of the assembler will
@@ -5515,7 +5517,7 @@ md_assemble (char *str)
   orig_insn.is_specific_opcode = (has_underbar || !use_transform ());
   orig_insn.opcode = xtensa_opcode_lookup (isa, opname);
 
-  /* Special case: Check for "CALLXn.TLS" psuedo op.  If found, grab its
+  /* Special case: Check for "CALLXn.TLS" pseudo op.  If found, grab its
      extra argument and set the opcode to "CALLXn".  */
   if (orig_insn.opcode == XTENSA_UNDEFINED
       && strncasecmp (opname, "callx", 5) == 0)
@@ -5564,7 +5566,7 @@ md_assemble (char *str)
        }
     }
 
-  /* Special case: Check for "j.l" psuedo op.  */
+  /* Special case: Check for "j.l" pseudo op.  */
   if (orig_insn.opcode == XTENSA_UNDEFINED
       && strncasecmp (opname, "j.l", 3) == 0)
     {
@@ -6147,9 +6149,9 @@ new_resource_table (void *data,
   rt->opcode_unit_use = ouuf;
   rt->opcode_unit_stage = ousf;
 
-  rt->units = (unsigned char **) xcalloc (cycles, sizeof (unsigned char *));
+  rt->units = XCNEWVEC (unsigned char *, cycles);
   for (i = 0; i < cycles; i++)
-    rt->units[i] = (unsigned char *) xcalloc (nu, sizeof (unsigned char));
+    rt->units[i] = XCNEWVEC (unsigned char, nu);
 
   return rt;
 }
@@ -6183,7 +6185,7 @@ resize_resource_table (resource_table *rt, int cycles)
   for (i = 0; i < old_cycles; i++)
     rt->units[i] = XRESIZEVEC (unsigned char, rt->units[i], rt->num_units);
   for (i = old_cycles; i < cycles; i++)
-    rt->units[i] = xcalloc (rt->num_units, sizeof (unsigned char));
+    rt->units[i] = XCNEWVEC (unsigned char, rt->num_units);
 }
 
 
@@ -7434,7 +7436,7 @@ xtensa_create_trampoline_frag (bfd_boolean needs_jump_around)
 
   if (ts == NULL)
     {
-      ts = (struct trampoline_seg *)xcalloc(sizeof (struct trampoline_seg), 1);
+      ts = XCNEW(struct trampoline_seg);
       ts->next = trampoline_seg_list.next;
       trampoline_seg_list.next = ts;
       ts->seg = now_seg;
@@ -7549,12 +7551,16 @@ xtensa_maybe_create_literal_pool_frag (bfd_boolean create,
 
   if (lps == NULL)
     {
-      lps = (struct litpool_seg *)xcalloc (sizeof (struct litpool_seg), 1);
+      lps = XCNEW (struct litpool_seg);
       lps->next = litpool_seg_list.next;
       litpool_seg_list.next = lps;
       lps->seg = now_seg;
       lps->frag_list.next = &lps->frag_list;
       lps->frag_list.prev = &lps->frag_list;
+      /* Put candidate literal pool at the beginning of every section,
+         so that even when section starts with literal load there's a
+        literal pool available.  */
+      lps->frag_count = auto_litpool_limit;
     }
 
   lps->frag_count++;
@@ -9422,7 +9428,9 @@ xtensa_relax_frag (fragS *fragP, long stretch, int *stretched_p)
                          /* Move the fix-up from the original j insn to this one.  */
                          fixP->fx_frag = fragP;
                          fixP->fx_where = fragP->fr_fix - 3;
+                         fixP->fx_size = 3;
                          fixP->tc_fix_data.slot = 0;
+                         fixP->fx_r_type = BFD_RELOC_XTENSA_SLOT0_OP;
 
                          xtensa_add_cached_fixup (&fixup_cache, fixP);
 
@@ -10053,11 +10061,21 @@ add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag)
   xtensa_format fmt;
   xtensa_isa isa = xtensa_default_isa;
   int growth = 0;
+  int i, slot = -1;
+
+  for (i = 0; i < MAX_SLOTS; ++i)
+    if (origfrag->tc_frag_data.slot_symbols[i])
+      {
+       gas_assert (slot == -1);
+       slot = i;
+      }
+
+  gas_assert (slot >= 0 && slot < MAX_SLOTS);
 
   lsym = tramp->fr_symbol;
   /* Assemble a jump to the target label in the trampoline frag.  */
-  tsym = origfrag->tc_frag_data.slot_symbols[0];
-  toffset = origfrag-> tc_frag_data.slot_offsets[0];
+  tsym = origfrag->tc_frag_data.slot_symbols[slot];
+  toffset = origfrag-> tc_frag_data.slot_offsets[slot];
   tinsn_init (&insn);
   insn.insn_type = ITYPE_INSN;
   insn.opcode = xtensa_j_opcode;
@@ -10077,8 +10095,8 @@ add_jump_to_trampoline (struct trampoline_frag *trampP, fragS *origfrag)
   if (fixP)
     fixP->fx_offset += 3;
   /* Modify the original j to point here.  */
-  origfrag->tc_frag_data.slot_symbols[0] = lsym;
-  origfrag->tc_frag_data.slot_offsets[0] = tramp->fr_fix - 3;
+  origfrag->tc_frag_data.slot_symbols[slot] = lsym;
+  origfrag->tc_frag_data.slot_offsets[slot] = tramp->fr_fix - 3;
   /* If trampoline is full, remove it from the list.  */
   check_and_update_trampolines ();
 
@@ -11030,6 +11048,30 @@ xtensa_move_seg_list_to_beginning (seg_list *head)
 
 static void mark_literal_frags (seg_list *);
 
+static void
+xg_promote_candidate_litpool (struct litpool_seg *lps,
+                             struct litpool_frag *lp)
+{
+  fragS *poolbeg;
+  fragS *poolend;
+  symbolS *lsym;
+  char label[10 + 2 * sizeof (fragS *)];
+
+  poolbeg = lp->fragP;
+  lp->priority = 1;
+  poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN;
+  poolend = poolbeg->fr_next;
+  gas_assert (poolend->fr_type == rs_machine_dependent &&
+             poolend->fr_subtype == RELAX_LITERAL_POOL_END);
+  /* Create a local symbol pointing to the
+     end of the pool.  */
+  sprintf (label, ".L0_LT_%p", poolbeg);
+  lsym = (symbolS *)local_symbol_make (label, lps->seg,
+                                      0, poolend);
+  poolbeg->fr_symbol = lsym;
+  /* Rest is done in xtensa_relax_frag.  */
+}
+
 static void
 xtensa_move_literals (void)
 {
@@ -11117,27 +11159,17 @@ xtensa_move_literals (void)
                                      /* This is still a "candidate" but the next one
                                         will be too far away, so revert to the nearest
                                         one, convert it and add the jump around.  */
-                                     fragS *poolbeg;
-                                     fragS *poolend;
-                                     symbolS *lsym;
-                                     char label[10 + 2 * sizeof (fragS *)];
                                      lp = lpf->prev;
-                                     poolbeg = lp->fragP;
-                                     lp->priority = 1;
-                                     poolbeg->fr_subtype = RELAX_LITERAL_POOL_BEGIN;
-                                     poolend = poolbeg->fr_next;
-                                     gas_assert (poolend->fr_type == rs_machine_dependent &&
-                                                 poolend->fr_subtype == RELAX_LITERAL_POOL_END);
-                                     /* Create a local symbol pointing to the
-                                        end of the pool.  */
-                                     sprintf (label, ".L0_LT_%p", poolbeg);
-                                     lsym = (symbolS *)local_symbol_make (label, lps->seg,
-                                                                          0, poolend);
-                                     poolbeg->fr_symbol = lsym;
-                                     /* Rest is done in xtensa_relax_frag.  */
+                                     break;
                                    }
                                }
                            }
+
+                         /* Convert candidate and add the jump around.  */
+                         if (lp->fragP->fr_subtype ==
+                             RELAX_LITERAL_POOL_CANDIDATE_BEGIN)
+                           xg_promote_candidate_litpool (lps, lp);
+
                          if (! litfrag->tc_frag_data.literal_frag)
                            {
                              /* Take earliest use of this literal to avoid
@@ -11231,7 +11263,7 @@ xtensa_move_literals (void)
          /* First, move the frag out of the literal section and
             to the appropriate place.  */
 
-         /* Insert an aligmnent frag at start of pool.  */
+         /* Insert an alignment frag at start of pool.  */
          if (literal_pool->fr_next->fr_type == rs_machine_dependent &&
              literal_pool->fr_next->fr_subtype == RELAX_LITERAL_POOL_END)
            {
@@ -11409,7 +11441,6 @@ xtensa_switch_to_literal_fragment (emit_state *result)
 static void
 xtensa_switch_to_non_abs_literal_fragment (emit_state *result)
 {
-  static bfd_boolean recursive = FALSE;
   fragS *pool_location = get_literal_pool_location (now_seg);
   segT lit_seg;
   bfd_boolean is_init =
@@ -11419,23 +11450,14 @@ xtensa_switch_to_non_abs_literal_fragment (emit_state *result)
 
   if (pool_location == NULL
       && !use_literal_section
-      && !recursive
       && !is_init && ! is_fini)
     {
       if (!auto_litpools)
        {
          as_bad (_("literal pool location required for text-section-literals; specify with .literal_position"));
        }
-
-      /* When we mark a literal pool location, we want to put a frag in
-        the literal pool that points to it.  But to do that, we want to
-        switch_to_literal_fragment.  But literal sections don't have
-        literal pools, so their location is always null, so we would
-        recurse forever.  This is kind of hacky, but it works.  */
-
-      recursive = TRUE;
-      xtensa_mark_literal_pool_location ();
-      recursive = FALSE;
+      xtensa_maybe_create_literal_pool_frag (TRUE, TRUE);
+      pool_location = get_literal_pool_location (now_seg);
     }
 
   lit_seg = cache_literal_section (FALSE);
@@ -11564,7 +11586,7 @@ cache_literal_section (bfd_boolean use_abs_literals)
              || strncmp (text_name, ".text", 5) == 0))
        len -= 5;
 
-      name = xmalloc (len + strlen (base_name) + 1);
+      name = XNEWVEC (char, len + strlen (base_name) + 1);
       if (strncmp (text_name, ".text", 5) == 0)
        {
          strcpy (name, base_name);
This page took 0.031485 seconds and 4 git commands to generate.