* dwarf2dbg.c (user_filenum, user_filenum_allocated): Remove.
[deliverable/binutils-gdb.git] / gas / config / tc-ia64.c
index df566e2f81803066fed276f834e0eef5f7e1d154..a07ee7c76ae6f43f5fd333bbe5026034aa4dcbb9 100644 (file)
@@ -1,5 +1,5 @@
 /* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture.
-   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation.
+   Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
    This file is part of GAS, the GNU Assembler.
@@ -124,6 +124,13 @@ enum dynreg_type
     DYNREG_NUM_TYPES
   };
 
+enum operand_match_result
+  {
+    OPERAND_MATCH,
+    OPERAND_OUT_OF_RANGE,
+    OPERAND_MISMATCH
+  };
+
 /* On the ia64, we can't know the address of a text label until the
    instructions are packed into a bundle.  To handle this, we keep
    track of the list of labels that appear in front of each
@@ -190,7 +197,8 @@ static struct
       explicit_mode : 1,            /* which mode we're in */
       default_explicit_mode : 1,    /* which mode is the default */
       mode_explicitly_set : 1,      /* was the current mode explicitly set? */
-      auto_align : 1;
+      auto_align : 1,
+      keep_pending_output : 1;
 
     /* Each bundle consists of up to three instructions.  We keep
        track of four most recent instructions so we can correctly set
@@ -624,6 +632,7 @@ static struct
   /* TRUE if processing unwind directives in a prologue region.  */
   int prologue;
   int prologue_mask;
+  unsigned int prologue_count; /* number of .prologues seen so far */
 } unwind;
 
 typedef void (*vbyte_func) PARAMS ((int, char *, char *));
@@ -689,8 +698,9 @@ static void add_unwind_entry PARAMS((unw_rec_list *ptr));
 static symbolS *declare_register PARAMS ((const char *name, int regnum));
 static void declare_register_set PARAMS ((const char *, int, int));
 static unsigned int operand_width PARAMS ((enum ia64_opnd));
-static int operand_match PARAMS ((const struct ia64_opcode *idesc,
-                                 int index, expressionS *e));
+static enum operand_match_result operand_match PARAMS ((const struct ia64_opcode *idesc,
+                                                       int index,
+                                                       expressionS *e));
 static int parse_operand PARAMS ((expressionS *e));
 static struct ia64_opcode * parse_operands PARAMS ((struct ia64_opcode *));
 static void build_insn PARAMS ((struct slot *, bfd_vma *));
@@ -3047,7 +3057,7 @@ dot_restore (dummy)
      int dummy ATTRIBUTE_UNUSED;
 {
   expressionS e1, e2;
-  unsigned long ecount = 0;
+  unsigned long ecount;        /* # of _additional_ regions to pop */
   int sep;
 
   sep = parse_operand (&e1);
@@ -3060,14 +3070,21 @@ dot_restore (dummy)
   if (sep == ',')
     {
       parse_operand (&e2);
-      if (e1.X_op != O_constant)
+      if (e2.X_op != O_constant || e2.X_add_number < 0)
        {
-         as_bad ("Second operand to .restore must be constant");
+         as_bad ("Second operand to .restore must be a constant >= 0");
          return;
        }
-      ecount = e1.X_op;
+      ecount = e2.X_add_number;
     }
+  else
+    ecount = unwind.prologue_count - 1;
   add_unwind_entry (output_epilogue (ecount));
+
+  if (ecount < unwind.prologue_count)
+    unwind.prologue_count -= ecount + 1;
+  else
+    unwind.prologue_count = 0;
 }
 
 static void
@@ -3710,6 +3727,7 @@ dot_proc (dummy)
   demand_empty_rest_of_line ();
   ia64_do_align (16);
 
+  unwind.prologue_count = 0;
   unwind.list = unwind.tail = unwind.current_entry = NULL;
   unwind.personality_routine = 0;
 }
@@ -3764,6 +3782,7 @@ dot_prologue (dummy)
 
   unwind.prologue = 1;
   unwind.prologue_mask = mask;
+  ++unwind.prologue_count;
 }
 
 static void
@@ -4133,9 +4152,11 @@ dot_xdata (size)
   if (!name)
     return;
 
+  md.keep_pending_output = 1;
   set_section (name);
   cons (size);
   obj_elf_previous (0);
+  md.keep_pending_output = 0;
 }
 
 /* Why doesn't float_cons() call md_cons_align() the way cons() does?  */
@@ -4179,9 +4200,11 @@ dot_xfloat_cons (kind)
   if (!name)
     return;
 
+  md.keep_pending_output = 1;
   set_section (name);
   stmt_float_cons (kind);
   obj_elf_previous (0);
+  md.keep_pending_output = 0;
 }
 
 static void
@@ -4192,9 +4215,11 @@ dot_xstringer (zero)
   if (!name)
     return;
 
+  md.keep_pending_output = 1;
   set_section (name);
   stringer (zero);
   obj_elf_previous (0);
+  md.keep_pending_output = 0;
 }
 
 static void
@@ -4206,11 +4231,13 @@ dot_xdata_ua (size)
   if (!name)
     return;
 
+  md.keep_pending_output = 1;
   set_section (name);
   md.auto_align = 0;
   cons (size);
   md.auto_align = saved_auto_align;
   obj_elf_previous (0);
+  md.keep_pending_output = 0;
 }
 
 static void
@@ -4222,11 +4249,13 @@ dot_xfloat_cons_ua (kind)
   if (!name)
     return;
 
+  md.keep_pending_output = 1;
   set_section (name);
   md.auto_align = 0;
   stmt_float_cons (kind);
   md.auto_align = saved_auto_align;
   obj_elf_previous (0);
+  md.keep_pending_output = 0;
 }
 
 /* .reg.val <regname>,value */
@@ -4730,7 +4759,7 @@ operand_width (opnd)
   return bits;
 }
 
-static int
+static enum operand_match_result
 operand_match (idesc, index, e)
      const struct ia64_opcode *idesc;
      int index;
@@ -4747,62 +4776,77 @@ operand_match (idesc, index, e)
 
     case IA64_OPND_AR_CCV:
       if (e->X_op == O_register && e->X_add_number == REG_AR + 32)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_AR_PFS:
       if (e->X_op == O_register && e->X_add_number == REG_AR + 64)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_GR0:
       if (e->X_op == O_register && e->X_add_number == REG_GR + 0)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_IP:
       if (e->X_op == O_register && e->X_add_number == REG_IP)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_PR:
       if (e->X_op == O_register && e->X_add_number == REG_PR)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_PR_ROT:
       if (e->X_op == O_register && e->X_add_number == REG_PR_ROT)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_PSR:
       if (e->X_op == O_register && e->X_add_number == REG_PSR)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_PSR_L:
       if (e->X_op == O_register && e->X_add_number == REG_PSR_L)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_PSR_UM:
       if (e->X_op == O_register && e->X_add_number == REG_PSR_UM)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_C1:
-      if (e->X_op == O_constant && e->X_add_number == 1)
-       return 1;
+      if (e->X_op == O_constant)
+       {
+         if (e->X_add_number == 1)
+           return OPERAND_MATCH;
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
       break;
 
     case IA64_OPND_C8:
-      if (e->X_op == O_constant && e->X_add_number == 8)
-       return 1;
+      if (e->X_op == O_constant)
+       {
+         if (e->X_add_number == 8)
+           return OPERAND_MATCH;
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
       break;
 
     case IA64_OPND_C16:
-      if (e->X_op == O_constant && e->X_add_number == 16)
-       return 1;
+      if (e->X_op == O_constant)
+       {
+         if (e->X_add_number == 16)
+           return OPERAND_MATCH;
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
       break;
 
       /* register operands:  */
@@ -4810,20 +4854,20 @@ operand_match (idesc, index, e)
     case IA64_OPND_AR3:
       if (e->X_op == O_register && e->X_add_number >= REG_AR
          && e->X_add_number < REG_AR + 128)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_B1:
     case IA64_OPND_B2:
       if (e->X_op == O_register && e->X_add_number >= REG_BR
          && e->X_add_number < REG_BR + 8)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_CR3:
       if (e->X_op == O_register && e->X_add_number >= REG_CR
          && e->X_add_number < REG_CR + 128)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_F1:
@@ -4832,14 +4876,14 @@ operand_match (idesc, index, e)
     case IA64_OPND_F4:
       if (e->X_op == O_register && e->X_add_number >= REG_FR
          && e->X_add_number < REG_FR + 128)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_P1:
     case IA64_OPND_P2:
       if (e->X_op == O_register && e->X_add_number >= REG_P
          && e->X_add_number < REG_P + 64)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_R1:
@@ -4847,13 +4891,17 @@ operand_match (idesc, index, e)
     case IA64_OPND_R3:
       if (e->X_op == O_register && e->X_add_number >= REG_GR
          && e->X_add_number < REG_GR + 128)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_R3_2:
-      if (e->X_op == O_register && e->X_add_number >= REG_GR
-         && e->X_add_number < REG_GR + 4)
-       return 1;
+      if (e->X_op == O_register && e->X_add_number >= REG_GR)
+       { 
+         if (e->X_add_number < REG_GR + 4)
+           return OPERAND_MATCH;
+         else if (e->X_add_number < REG_GR + 128)
+           return OPERAND_OUT_OF_RANGE;
+       }
       break;
 
       /* indirect operands:  */
@@ -4870,12 +4918,12 @@ operand_match (idesc, index, e)
       if (e->X_op == O_index && e->X_op_symbol
          && (S_GET_VALUE (e->X_op_symbol) - IND_CPUID
              == opnd - IA64_OPND_CPUID_R3))
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_MR3:
       if (e->X_op == O_index && !e->X_op_symbol)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
       /* immediate operands:  */
@@ -4883,40 +4931,58 @@ operand_match (idesc, index, e)
     case IA64_OPND_LEN4:
     case IA64_OPND_LEN6:
       bits = operand_width (idesc->operands[index]);
-      if (e->X_op == O_constant
-         && (bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits))
-       return 1;
+      if (e->X_op == O_constant)
+       {
+         if ((bfd_vma) (e->X_add_number - 1) < ((bfd_vma) 1 << bits))
+           return OPERAND_MATCH;
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
       break;
 
     case IA64_OPND_CNT2b:
-      if (e->X_op == O_constant
-         && (bfd_vma) (e->X_add_number - 1) < 3)
-       return 1;
+      if (e->X_op == O_constant)
+       {
+         if ((bfd_vma) (e->X_add_number - 1) < 3)
+           return OPERAND_MATCH;
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
       break;
 
     case IA64_OPND_CNT2c:
       val = e->X_add_number;
-      if (e->X_op == O_constant
-         && (val == 0 || val == 7 || val == 15 || val == 16))
-       return 1;
+      if (e->X_op == O_constant)
+       {
+         if ((val == 0 || val == 7 || val == 15 || val == 16))
+           return OPERAND_MATCH;
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
       break;
 
     case IA64_OPND_SOR:
       /* SOR must be an integer multiple of 8 */
-      if (e->X_add_number & 0x7)
-       break;
+      if (e->X_op == O_constant && e->X_add_number & 0x7)
+       return OPERAND_OUT_OF_RANGE;
     case IA64_OPND_SOF:
     case IA64_OPND_SOL:
-      if (e->X_op == O_constant &&
-         (bfd_vma) e->X_add_number <= 96)
-       return 1;
+      if (e->X_op == O_constant)
+       {
+         if ((bfd_vma) e->X_add_number <= 96)
+           return OPERAND_MATCH;
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
       break;
 
     case IA64_OPND_IMMU62:
       if (e->X_op == O_constant)
        {
          if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << 62))
-           return 1;
+           return OPERAND_MATCH;
+         else
+           return OPERAND_OUT_OF_RANGE;
        }
       else
        {
@@ -4942,10 +5008,10 @@ operand_match (idesc, index, e)
          fix->expr = *e;
          fix->is_pcrel = 0;
          ++CURR_SLOT.num_fixups;
-         return 1;
+         return OPERAND_MATCH;
        }
       else if (e->X_op == O_constant)
-       return 1;
+       return OPERAND_MATCH;
       break;
 
     case IA64_OPND_CCNT5:
@@ -4963,59 +5029,78 @@ operand_match (idesc, index, e)
     case IA64_OPND_MHTYPE8:
     case IA64_OPND_POS6:
       bits = operand_width (idesc->operands[index]);
-      if (e->X_op == O_constant
-         && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
-       return 1;
+      if (e->X_op == O_constant)
+       {
+         if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
+           return OPERAND_MATCH;
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
       break;
 
     case IA64_OPND_IMMU9:
       bits = operand_width (idesc->operands[index]);
-      if (e->X_op == O_constant
-         && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
+      if (e->X_op == O_constant)
        {
-         int lobits = e->X_add_number & 0x3;
-         if (((bfd_vma) e->X_add_number & 0x3C) != 0 && lobits == 0)
-           e->X_add_number |= (bfd_vma) 0x3;
-         return 1;
+         if ((bfd_vma) e->X_add_number < ((bfd_vma) 1 << bits))
+           {
+             int lobits = e->X_add_number & 0x3;
+             if (((bfd_vma) e->X_add_number & 0x3C) != 0 && lobits == 0)
+               e->X_add_number |= (bfd_vma) 0x3;
+             return OPERAND_MATCH;
+           }
+         else
+           return OPERAND_OUT_OF_RANGE;
        }
       break;
 
     case IA64_OPND_IMM44:
       /* least 16 bits must be zero */
       if ((e->X_add_number & 0xffff) != 0)
+       /* XXX technically, this is wrong: we should not be issuing warning
+          messages until we're sure this instruction pattern is going to
+          be used! */
        as_warn (_("lower 16 bits of mask ignored"));
 
-      if (e->X_op == O_constant
-         && ((e->X_add_number >= 0
-              && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 44))
-             || (e->X_add_number < 0
-                 && (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 44))))
+      if (e->X_op == O_constant)
        {
-         /* sign-extend */
-         if (e->X_add_number >= 0
-             && (e->X_add_number & ((bfd_vma) 1 << 43)) != 0)
+         if (((e->X_add_number >= 0
+               && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 44))
+              || (e->X_add_number < 0
+                  && (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 44))))
            {
-             e->X_add_number |= ~(((bfd_vma) 1 << 44) - 1);
+             /* sign-extend */
+             if (e->X_add_number >= 0
+                 && (e->X_add_number & ((bfd_vma) 1 << 43)) != 0)
+               {
+                 e->X_add_number |= ~(((bfd_vma) 1 << 44) - 1);
+               }
+             return OPERAND_MATCH;
            }
-         return 1;
+         else
+           return OPERAND_OUT_OF_RANGE;
        }
       break;
 
     case IA64_OPND_IMM17:
       /* bit 0 is a don't care (pr0 is hardwired to 1) */
-      if (e->X_op == O_constant
-         && ((e->X_add_number >= 0
-              && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 17))
-             || (e->X_add_number < 0
-                 && (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 17))))
-       {
-         /* sign-extend */
-         if (e->X_add_number >= 0
-             && (e->X_add_number & ((bfd_vma) 1 << 16)) != 0)
+      if (e->X_op == O_constant)
+       {
+         if (((e->X_add_number >= 0
+               && (bfd_vma) e->X_add_number < ((bfd_vma) 1 << 17))
+              || (e->X_add_number < 0
+                  && (bfd_vma) -e->X_add_number <= ((bfd_vma) 1 << 17))))
            {
-             e->X_add_number |= ~(((bfd_vma) 1 << 17) - 1);
+             /* sign-extend */
+             if (e->X_add_number >= 0
+                 && (e->X_add_number & ((bfd_vma) 1 << 16)) != 0)
+               {
+                 e->X_add_number |= ~(((bfd_vma) 1 << 17) - 1);
+               }
+             return OPERAND_MATCH;
            }
-         return 1;
+         else
+           return OPERAND_OUT_OF_RANGE;
        }
       break;
 
@@ -5053,18 +5138,18 @@ operand_match (idesc, index, e)
          fix->expr = *e;
          fix->is_pcrel = 0;
          ++CURR_SLOT.num_fixups;
-         return 1;
+         return OPERAND_MATCH;
        }
       else if (e->X_op != O_constant
               && ! (e->X_op == O_big && opnd == IA64_OPND_IMM8M1U8))
-       return 0;
+       return OPERAND_MISMATCH;
 
       if (opnd == IA64_OPND_IMM8M1U4)
        {
          /* Zero is not valid for unsigned compares that take an adjusted
             constant immediate range.  */
          if (e->X_add_number == 0)
-           return 0;
+           return OPERAND_OUT_OF_RANGE;
 
          /* Sign-extend 32-bit unsigned numbers, so that the following range
             checks will work.  */
@@ -5076,7 +5161,7 @@ operand_match (idesc, index, e)
          /* Check for 0x100000000.  This is valid because
             0x100000000-1 is the same as ((uint32_t) -1).  */
          if (val == ((bfd_signed_vma) 1 << 32))
-           return 1;
+           return OPERAND_MATCH;
 
          val = val - 1;
        }
@@ -5085,7 +5170,7 @@ operand_match (idesc, index, e)
          /* Zero is not valid for unsigned compares that take an adjusted
             constant immediate range.  */
          if (e->X_add_number == 0)
-           return 0;
+           return OPERAND_OUT_OF_RANGE;
 
          /* Check for 0x10000000000000000.  */
          if (e->X_op == O_big)
@@ -5095,9 +5180,9 @@ operand_match (idesc, index, e)
                  && generic_bignum[2] == 0
                  && generic_bignum[3] == 0
                  && generic_bignum[4] == 1)
-               return 1;
+               return OPERAND_MATCH;
              else
-               return 0;
+               return OPERAND_OUT_OF_RANGE;
            }
          else
            val = e->X_add_number - 1;
@@ -5118,17 +5203,22 @@ operand_match (idesc, index, e)
 
       if ((val >= 0 && (bfd_vma) val < ((bfd_vma) 1 << (bits - 1)))
          || (val < 0 && (bfd_vma) -val <= ((bfd_vma) 1 << (bits - 1))))
-       return 1;
-      break;
+       return OPERAND_MATCH;
+      else
+       return OPERAND_OUT_OF_RANGE;
 
     case IA64_OPND_INC3:
       /* +/- 1, 4, 8, 16 */
       val = e->X_add_number;
       if (val < 0)
        val = -val;
-      if (e->X_op == O_constant
-         && (val == 1 || val == 4 || val == 8 || val == 16))
-       return 1;
+      if (e->X_op == O_constant)
+       {
+         if ((val == 1 || val == 4 || val == 8 || val == 16))
+           return OPERAND_MATCH;
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
       break;
 
     case IA64_OPND_TGT25:
@@ -5154,14 +5244,14 @@ operand_match (idesc, index, e)
          fix->expr = *e;
          fix->is_pcrel = 1;
          ++CURR_SLOT.num_fixups;
-         return 1;
+         return OPERAND_MATCH;
        }
     case IA64_OPND_TAG13:
     case IA64_OPND_TAG13b:
       switch (e->X_op)
        {
        case O_constant:
-         return 1;
+         return OPERAND_MATCH;
 
        case O_symbol:
          fix = CURR_SLOT.fixup + CURR_SLOT.num_fixups;
@@ -5173,7 +5263,7 @@ operand_match (idesc, index, e)
          fix->expr = *e;
          fix->is_pcrel = 1;
          ++CURR_SLOT.num_fixups;
-         return 1;
+         return OPERAND_MATCH;
 
        default:
          break;
@@ -5183,7 +5273,7 @@ operand_match (idesc, index, e)
     default:
       break;
     }
-  return 0;
+  return OPERAND_MISMATCH;
 }
 
 static int
@@ -5231,8 +5321,9 @@ parse_operands (idesc)
      struct ia64_opcode *idesc;
 {
   int i = 0, highest_unmatched_operand, num_operands = 0, num_outputs = 0;
-  int sep = 0;
+  int error_pos, out_of_range_pos, curr_out_of_range_pos, sep = 0;
   enum ia64_opnd expected_operand = IA64_OPND_NIL;
+  enum operand_match_result result;
   char mnemonic[129];
   char *first_arg = 0, *end, *saved_input_pointer;
   unsigned int sof;
@@ -5314,6 +5405,8 @@ parse_operands (idesc)
     }
 
   highest_unmatched_operand = 0;
+  curr_out_of_range_pos = -1;
+  error_pos = 0;
   expected_operand = idesc->operands[0];
   for (; idesc; idesc = get_next_opcode (idesc))
     {
@@ -5321,16 +5414,52 @@ parse_operands (idesc)
        continue;               /* mismatch in # of outputs */
 
       CURR_SLOT.num_fixups = 0;
+
+      /* Try to match all operands.  If we see an out-of-range operand,
+        then continue trying to match the rest of the operands, since if
+        the rest match, then this idesc will give the best error message.  */
+
+      out_of_range_pos = -1;
       for (i = 0; i < num_operands && idesc->operands[i]; ++i)
-       if (!operand_match (idesc, i, CURR_SLOT.opnd + i))
-         break;
+       {
+         result = operand_match (idesc, i, CURR_SLOT.opnd + i);
+         if (result != OPERAND_MATCH)
+           {
+             if (result != OPERAND_OUT_OF_RANGE)
+               break;
+             if (out_of_range_pos < 0)
+               /* remember position of the first out-of-range operand: */
+               out_of_range_pos = i;
+           }
+       }
 
-      if (i != num_operands)
+      /* If we did not match all operands, or if at least one operand was
+        out-of-range, then this idesc does not match.  Keep track of which
+        idesc matched the most operands before failing.  If we have two
+        idescs that failed at the same position, and one had an out-of-range
+        operand, then prefer the out-of-range operand.  Thus if we have
+        "add r0=0x1000000,r1" we get an error saying the constant is out
+        of range instead of an error saying that the constant should have been
+        a register.  */
+
+      if (i != num_operands || out_of_range_pos >= 0)
        {
-         if (i > highest_unmatched_operand)
+         if (i > highest_unmatched_operand
+             || (i == highest_unmatched_operand
+                 && out_of_range_pos > curr_out_of_range_pos))
            {
              highest_unmatched_operand = i;
-             expected_operand = idesc->operands[i];
+             if (out_of_range_pos >= 0)
+               {
+                 expected_operand = idesc->operands[out_of_range_pos];
+                 error_pos = out_of_range_pos;
+               }
+             else
+               {
+                 expected_operand = idesc->operands[i];
+                 error_pos = i;
+               }
+             curr_out_of_range_pos = out_of_range_pos;
            }
          continue;
        }
@@ -5345,7 +5474,7 @@ parse_operands (idesc)
     {
       if (expected_operand)
        as_bad ("Operand %u of `%s' should be %s",
-               highest_unmatched_operand + 1, mnemonic,
+               error_pos + 1, mnemonic,
                elf64_ia64_operands[expected_operand].desc);
       else
        as_bad ("Operand mismatch");
@@ -5931,6 +6060,7 @@ md_parse_option (c, arg)
      int c;
      char *arg;
 {
+
   switch (c)
     {
     /* Switches from the Intel assembler.  */
@@ -6350,16 +6480,32 @@ ia64_target_format ()
       if (md.flags & EF_IA_64_BE)
        {
          if (md.flags & EF_IA_64_ABI64)
+#ifdef TE_AIX50
+           return "elf64-ia64-aix-big";
+#else
            return "elf64-ia64-big";
+#endif
          else
+#ifdef TE_AIX50
+           return "elf32-ia64-aix-big";
+#else
            return "elf32-ia64-big";
+#endif
        }
       else
        {
          if (md.flags & EF_IA_64_ABI64)
+#ifdef TE_AIX50
+           return "elf64-ia64-aix-little";
+#else
            return "elf64-ia64-little";
+#endif
          else
+#ifdef TE_AIX50
+           return "elf32-ia64-aix-little";
+#else
            return "elf32-ia64-little";
+#endif
        }
     }
   else
@@ -6478,14 +6624,36 @@ ia64_unrecognized_line (ch)
        char *s;
        char c;
        symbolS *tag;
+       int temp;
 
        if (md.qp.X_op == O_register)
          {
            as_bad ("Tag must come before qualifying predicate.");
            return 0;
          }
-       s = input_line_pointer;
-       c = get_symbol_end ();
+
+       /* This implements just enough of read_a_source_file in read.c to
+          recognize labels.  */
+       if (is_name_beginner (*input_line_pointer))
+         {
+           s = input_line_pointer;
+           c = get_symbol_end ();
+         }
+       else if (LOCAL_LABELS_FB
+                && isdigit ((unsigned char) *input_line_pointer))
+         {
+           temp = 0;
+           while (isdigit ((unsigned char) *input_line_pointer))
+             temp = (temp * 10) + *input_line_pointer++ - '0';
+           fb_label_instance_inc (temp);
+           s = fb_label_name (temp, 0);
+           c = *input_line_pointer;
+         }
+       else
+         {
+           s = NULL;
+           c = '\0';
+         }
        if (c != ':')
          {
            /* Put ':' back for error messages' sake.  */
@@ -6493,6 +6661,7 @@ ia64_unrecognized_line (ch)
            as_bad ("Expected ':'");
            return 0;
          }
+
        defining_tag = 1;
        tag = colon (s);
        defining_tag = 0;
@@ -6560,7 +6729,8 @@ ia64_frob_label (sym)
 void
 ia64_flush_pending_output ()
 {
-  if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
+  if (!md.keep_pending_output
+      && bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
     {
       /* ??? This causes many unnecessary stop bits to be emitted.
         Unfortunately, it isn't clear if it is safe to remove this.  */
This page took 0.033683 seconds and 4 git commands to generate.