Remove trailing spaces in gas
[deliverable/binutils-gdb.git] / gas / config / tc-ia64.c
index a5100c28cf2b5d0fa0fb0edcdf7e60aeac48315b..d11570a9f1c7af0f913c8971afced2c7fdb8ee1e 100644 (file)
@@ -1,6 +1,5 @@
 /* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture.
-   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009, 2011   Free Software Foundation, Inc.
+   Copyright (C) 1998-2015 Free Software Foundation, Inc.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
    This file is part of GAS, the GNU Assembler.
@@ -114,7 +113,8 @@ enum reg_symbol
     REG_FR     = (REG_GR + 128),
     REG_AR     = (REG_FR + 128),
     REG_CR     = (REG_AR + 128),
-    REG_P      = (REG_CR + 128),
+    REG_DAHR   = (REG_CR + 128),
+    REG_P      = (REG_DAHR + 8),
     REG_BR     = (REG_P  + 64),
     REG_IP     = (REG_BR + 8),
     REG_CFM,
@@ -133,6 +133,7 @@ enum reg_symbol
     IND_PKR,
     IND_PMC,
     IND_PMD,
+    IND_DAHR,
     IND_RR,
     /* The following pseudo-registers are used for unwind directives only:  */
     REG_PSP,
@@ -539,6 +540,7 @@ indirect_reg[] =
     { "pkr",   IND_PKR },
     { "pmc",   IND_PMC },
     { "pmd",   IND_PMD },
+    { "dahr",  IND_DAHR },
     { "rr",    IND_RR },
   };
 
@@ -609,6 +611,12 @@ pseudo_func[] =
 
     /* hint constants: */
     { "pause", PSEUDO_FUNC_CONST, { 0x0 } },
+    { "priority", PSEUDO_FUNC_CONST, { 0x1 } },
+
+    /* tf constants: */
+    { "clz",   PSEUDO_FUNC_CONST, {  32 } },
+    { "mpy",   PSEUDO_FUNC_CONST, {  33 } },
+    { "datahints",     PSEUDO_FUNC_CONST, {  34 } },
 
     /* unwind-related constants:  */
     { "svr4",  PSEUDO_FUNC_CONST,      { ELFOSABI_NONE } },
@@ -821,7 +829,7 @@ ar_is_only_in_integer_unit (int reg)
   return reg >= 64 && reg <= 111;
 }
 
-/* Determine if application register REGNUM resides only in the memory 
+/* Determine if application register REGNUM resides only in the memory
    unit (as opposed to the integer unit).  */
 static int
 ar_is_only_in_memory_unit (int reg)
@@ -1039,6 +1047,141 @@ ia64_cons_align (int nbytes)
     }
 }
 
+#ifdef TE_VMS
+
+/* .vms_common section, symbol, size, alignment  */
+
+static void
+obj_elf_vms_common (int ignore ATTRIBUTE_UNUSED)
+{
+  char *sec_name;
+  char *sym_name;
+  char c;
+  offsetT size;
+  offsetT cur_size;
+  offsetT temp;
+  symbolS *symbolP;
+  segT current_seg = now_seg;
+  subsegT current_subseg = now_subseg;
+  offsetT log_align;
+
+  /* Section name.  */
+  sec_name = obj_elf_section_name ();
+  if (sec_name == NULL)
+    return;
+
+  /* Symbol name.  */
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer == ',')
+    {
+      input_line_pointer++;
+      SKIP_WHITESPACE ();
+    }
+  else
+    {
+      as_bad (_("expected ',' after section name"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  sym_name = input_line_pointer;
+  c = get_symbol_end ();
+
+  if (input_line_pointer == sym_name)
+    {
+      *input_line_pointer = c;
+      as_bad (_("expected symbol name"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  symbolP = symbol_find_or_make (sym_name);
+  *input_line_pointer = c;
+
+  if ((S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP))
+      && !S_IS_COMMON (symbolP))
+    {
+      as_bad (_("Ignoring attempt to re-define symbol"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  /* Symbol size.  */
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer == ',')
+    {
+      input_line_pointer++;
+      SKIP_WHITESPACE ();
+    }
+  else
+    {
+      as_bad (_("expected ',' after symbol name"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  temp = get_absolute_expression ();
+  size = temp;
+  size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
+  if (temp != size)
+    {
+      as_warn (_("size (%ld) out of range, ignored"), (long) temp);
+      ignore_rest_of_line ();
+      return;
+    }
+
+  /* Alignment.  */
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer == ',')
+    {
+      input_line_pointer++;
+      SKIP_WHITESPACE ();
+    }
+  else
+    {
+      as_bad (_("expected ',' after symbol size"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  log_align = get_absolute_expression ();
+
+  demand_empty_rest_of_line ();
+
+  obj_elf_change_section
+    (sec_name, SHT_NOBITS,
+     SHF_ALLOC | SHF_WRITE | SHF_IA_64_VMS_OVERLAID | SHF_IA_64_VMS_GLOBAL,
+     0, NULL, 1, 0);
+
+  S_SET_VALUE (symbolP, 0);
+  S_SET_SIZE (symbolP, size);
+  S_SET_EXTERNAL (symbolP);
+  S_SET_SEGMENT (symbolP, now_seg);
+
+  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
+
+  record_alignment (now_seg, log_align);
+
+  cur_size = bfd_section_size (stdoutput, now_seg);
+  if ((int) size > cur_size)
+    {
+      char *pfrag
+        = frag_var (rs_fill, 1, 1, (relax_substateT)0, NULL,
+                    (valueT)size - (valueT)cur_size, NULL);
+      *pfrag = 0;
+      bfd_section_size (stdoutput, now_seg) = size;
+    }
+
+  /* Switch back to current segment.  */
+  subseg_set (current_seg, current_subseg);
+
+#ifdef md_elf_section_change_hook
+  md_elf_section_change_hook ();
+#endif
+}
+
+#endif /* TE_VMS */
+
 /* Output COUNT bytes to a memory location.  */
 static char *vbyte_mem_ptr = NULL;
 
@@ -2834,7 +2977,7 @@ ia64_estimate_size_before_relax (fragS *frag,
 }
 
 /* This function converts a rs_machine_dependent variant frag into a
-  normal fill frag with the unwind image from the the record list.  */
+  normal fill frag with the unwind image from the record list.  */
 void
 ia64_convert_frag (fragS *frag)
 {
@@ -3544,7 +3687,7 @@ generate_unwind_image (const segT text_seg)
 
       /* Set expression which points to start of unwind descriptor area.  */
       unwind.info = expr_build_dot ();
-      
+
       frag_var (rs_machine_dependent, size, size, 0, 0,
                (offsetT) (long) unwind.personality_routine,
                (char *) list);
@@ -4323,14 +4466,15 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
                                          symbol_get_frag (unwind.proc_pending.sym));
       else
        e.X_add_symbol = unwind.proc_pending.sym;
-      ia64_cons_fix_new (frag_now, where, bytes_per_address, &e);
+      ia64_cons_fix_new (frag_now, where, bytes_per_address, &e,
+                        BFD_RELOC_NONE);
 
       e.X_op = O_pseudo_fixup;
       e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
       e.X_add_number = 0;
       e.X_add_symbol = proc_end;
       ia64_cons_fix_new (frag_now, where + bytes_per_address,
-                        bytes_per_address, &e);
+                        bytes_per_address, &e, BFD_RELOC_NONE);
 
       if (unwind.info)
        {
@@ -4339,7 +4483,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
          e.X_add_number = 0;
          e.X_add_symbol = unwind.info;
          ia64_cons_fix_new (frag_now, where + (bytes_per_address * 2),
-                            bytes_per_address, &e);
+                            bytes_per_address, &e, BFD_RELOC_NONE);
        }
     }
   subseg_set (saved_seg, saved_subseg);
@@ -5232,6 +5376,10 @@ const pseudo_typeS md_pseudo_table[] =
     {"4byte", stmt_cons_ua, 4},
     {"8byte", stmt_cons_ua, 8},
 
+#ifdef TE_VMS
+    {"vms_common", obj_elf_vms_common, 0},
+#endif
+
     { NULL, 0, 0 }
   };
 
@@ -5428,6 +5576,12 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
        return OPERAND_MATCH;
       break;
 
+    case IA64_OPND_DAHR3:
+      if (e->X_op == O_register && e->X_add_number >= REG_DAHR
+         && e->X_add_number < REG_DAHR + 8)
+       return OPERAND_MATCH;
+      break;
+
     case IA64_OPND_F1:
     case IA64_OPND_F2:
     case IA64_OPND_F3:
@@ -5472,6 +5626,7 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
     case IA64_OPND_PKR_R3:
     case IA64_OPND_PMC_R3:
     case IA64_OPND_PMD_R3:
+    case IA64_OPND_DAHR_R3:
     case IA64_OPND_RR_R3:
       if (e->X_op == O_index && e->X_op_symbol
          && (S_GET_VALUE (e->X_op_symbol) - IND_CPUID
@@ -5592,6 +5747,8 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
     case IA64_OPND_IMMU2:
     case IA64_OPND_IMMU7a:
     case IA64_OPND_IMMU7b:
+    case IA64_OPND_IMMU16:
+    case IA64_OPND_IMMU19:
     case IA64_OPND_IMMU21:
     case IA64_OPND_IMMU24:
     case IA64_OPND_MBTYPE4:
@@ -5848,6 +6005,39 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
       ++CURR_SLOT.num_fixups;
       return OPERAND_MATCH;
 
+    case IA64_OPND_STRD5b:
+      if (e->X_op == O_constant)
+       {
+         /* 5-bit signed scaled by 64 */
+         if ((e->X_add_number <=       ( 0xf  << 6 ))
+              && (e->X_add_number >=  -( 0x10 << 6 )))
+           {
+
+             /* Must be a multiple of 64 */
+             if ((e->X_add_number & 0x3f) != 0)
+               as_warn (_("stride must be a multiple of 64; lower 6 bits ignored"));
+
+             e->X_add_number &= ~ 0x3f;
+             return OPERAND_MATCH;
+           }
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
+      break;
+    case IA64_OPND_CNT6a:
+      if (e->X_op == O_constant)
+       {
+         /* 6-bit unsigned biased by 1 -- count 0 is meaningless */
+         if ((e->X_add_number     <=   64)
+              && (e->X_add_number > 0) )
+           {
+             return OPERAND_MATCH;
+           }
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
+      break;
+
     default:
       break;
     }
@@ -5953,7 +6143,7 @@ parse_operands (struct ia64_opcode *idesc)
 
   for (; ; ++i)
     {
-      if (i < NELEMS (CURR_SLOT.opnd)) 
+      if (i < NELEMS (CURR_SLOT.opnd))
        {
          sep = parse_operand_maybe_eval (CURR_SLOT.opnd + i, '=',
                                          idesc->operands[i]);
@@ -6298,6 +6488,10 @@ build_insn (struct slot *slot, bfd_vma *insnp)
          val -= REG_CR;
          break;
 
+       case IA64_OPND_DAHR3:
+         val -= REG_DAHR;
+         break;
+
        case IA64_OPND_F1:
        case IA64_OPND_F2:
        case IA64_OPND_F3:
@@ -6324,6 +6518,7 @@ build_insn (struct slot *slot, bfd_vma *insnp)
        case IA64_OPND_PKR_R3:
        case IA64_OPND_PMC_R3:
        case IA64_OPND_PMD_R3:
+       case IA64_OPND_DAHR_R3:
        case IA64_OPND_RR_R3:
          val -= REG_GR;
          break;
@@ -6739,15 +6934,6 @@ emit_one_bundle (void)
          md.slot[curr].unwind_record = NULL;
        }
 
-      if (required_unit == IA64_UNIT_L)
-       {
-         know (i == 1);
-         /* skip one slot for long/X-unit instructions */
-         ++i;
-       }
-      --md.num_slots_in_use;
-      last_slot = i;
-
       for (j = 0; j < md.slot[curr].num_fixups; ++j)
        {
          ifix = md.slot[curr].fixup + j;
@@ -6760,6 +6946,17 @@ emit_one_bundle (void)
 
       end_of_insn_group = md.slot[curr].end_of_insn_group;
 
+      /* This adjustment to "i" must occur after the fix, otherwise the fix
+        is assigned to the wrong slot, and the VMS linker complains.  */
+      if (required_unit == IA64_UNIT_L)
+       {
+         know (i == 1);
+         /* skip one slot for long/X-unit instructions */
+         ++i;
+       }
+      --md.num_slots_in_use;
+      last_slot = i;
+
       /* clear slot:  */
       ia64_free_opcode (md.slot[curr].idesc);
       memset (md.slot + curr, 0, sizeof (md.slot[curr]));
@@ -6814,7 +7011,7 @@ emit_one_bundle (void)
        as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
                      _("Missing '}' at end of file"));
     }
-       
+
   know (md.num_slots_in_use < NUM_SLOTS);
 
   t0 = end_of_insn_group | (template_val << 1) | (insn[0] << 5) | (insn[1] << 46);
@@ -7296,6 +7493,9 @@ md_begin (void)
   for (i = 0; i < NELEMS (cr); ++i)
     declare_register (cr[i].name, REG_CR + cr[i].regnum);
 
+  /* dahr registers:  */
+  declare_register_set ("dahr", 8, REG_DAHR);
+
   declare_register ("ip", REG_IP);
   declare_register ("cfm", REG_CFM);
   declare_register ("psr", REG_PSR);
@@ -7646,9 +7846,9 @@ ia64_frob_label (struct symbol *sym)
 int
 ia64_frob_symbol (struct symbol *sym)
 {
-  if ((S_GET_SEGMENT (sym) == &bfd_und_section && ! symbol_used_p (sym) &&
+  if ((S_GET_SEGMENT (sym) == bfd_und_section_ptr && ! symbol_used_p (sym) &&
        ELF_ST_VISIBILITY (S_GET_OTHER (sym)) == STV_DEFAULT)
-      || (S_GET_SEGMENT (sym) == &bfd_abs_section
+      || (S_GET_SEGMENT (sym) == bfd_abs_section_ptr
          && ! S_IS_EXTERNAL (sym)))
     return 1;
   return 0;
@@ -8549,6 +8749,22 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note)
        }
       break;
 
+    case IA64_RS_DAHR:
+      if (note == 0)
+       {
+         if (idesc->operands[!rsrc_write] == IA64_OPND_DAHR3)
+           {
+             specs[count] = tmpl;
+             specs[count++].index =
+               CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_DAHR;
+           }
+       }
+      else
+       {
+         UNHANDLED;
+       }
+      break;
+
     case IA64_RS_FR:
     case IA64_RS_FRb:
       if (note != 1)
@@ -8623,6 +8839,7 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note)
                      || idesc->operands[i] == IA64_OPND_PKR_R3
                      || idesc->operands[i] == IA64_OPND_PMC_R3
                      || idesc->operands[i] == IA64_OPND_PMD_R3
+                     || idesc->operands[i] == IA64_OPND_DAHR_R3
                      || idesc->operands[i] == IA64_OPND_RR_R3
                      || ((i >= idesc->num_outputs)
                          && (idesc->operands[i] == IA64_OPND_R1
@@ -9436,7 +9653,7 @@ update_qp_mutex (valueT mask)
                  print_prmask (qp_mutexes[i].prmask);
                  fprintf (stderr, "\n");
                }
-             
+
              /* Deal with the old mutex with more than 3+ PRs only if
                 the new mutex on the same execution path with it.
 
@@ -9449,7 +9666,7 @@ update_qp_mutex (valueT mask)
                  if (add == 0
                      && (qp_mutexes[i].prmask & mask) == mask)
                    add = 1;
-                 
+
                  qp_mutexes[i].prmask &= ~mask;
                  if (qp_mutexes[i].prmask & (qp_mutexes[i].prmask - 1))
                    {
@@ -9459,7 +9676,7 @@ update_qp_mutex (valueT mask)
                      i++;
                    }
                }
-             
+
              if (keep == 0)
                /* Remove the mutex.  */
                qp_mutexes[i] = qp_mutexes[--qp_mutexeslen];
@@ -10580,7 +10797,7 @@ md_assemble (char *str)
     {
       enum ia64_opnd opnd1, opnd2;
       int rop;
-      
+
       opnd1 = idesc->operands[0];
       opnd2 = idesc->operands[1];
       if (opnd1 == IA64_OPND_AR3)
@@ -10840,9 +11057,9 @@ ia64_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
    fixup.  We pick the right reloc code depending on the byteorder
    currently in effect.  */
 void
-ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp)
+ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp,
+                  bfd_reloc_code_real_type code)
 {
-  bfd_reloc_code_real_type code;
   fixS *fix;
 
   switch (nbytes)
@@ -11483,7 +11700,7 @@ ia64_handle_align (fragS *fragp)
   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   p = fragp->fr_literal + fragp->fr_fix;
 
-  /* If no paddings are needed, we check if we need a stop bit.  */ 
+  /* If no paddings are needed, we check if we need a stop bit.  */
   if (!bytes && fragp->tc_frag_data)
     {
       if (fragp->fr_fix < 16)
@@ -11664,7 +11881,7 @@ dot_alias (int section)
   h = (struct alias *) xmalloc (sizeof (struct alias));
   as_where (&h->file, &h->line);
   h->name = name;
-  
+
   error_string = hash_jam (ahash, alias, (void *) h);
   if (error_string)
     {
@@ -11784,7 +12001,7 @@ ia64_vms_note (void)
   bname = xstrdup (lbasename (out_file_name));
   if ((p = strrchr (bname, '.')))
     *p = '\0';
-  
+
   /* VMS note header is 24 bytes long.  */
   p = frag_more (8 + 8 + 8);
   number_to_chars_littleendian (p + 0, 8, 8);
This page took 0.029892 seconds and 4 git commands to generate.