FreeBSD/contrib/binutils/gas/config/tc-arm.c
/* Parse an ARM register list.  Returns the bitmask, or FAIL.  */
Parse an ARM register list.  Returns the bitmask, or FAIL.
Parse an ARM register list . Returns the bitmask or FAIL .
static long
parse_reg_list (char ** strp)
{
  char * str = * strp;
  long	 range = 0;
  int	 another_range;
  do
    {
      another_range = 0;
      if (*str == '{')
	{
	  int in_range = 0;
	  int cur_reg = -1;
	  str++;
	  do
	    {
	      int reg;
	      if ((reg = arm_reg_parse (&str, REG_TYPE_RN)) == FAIL)
		{
		  first_error (_(reg_expected_msgs[REG_TYPE_RN]));
		  return FAIL;
		}
	      if (in_range)
		{
		  int i;
		  if (reg <= cur_reg)
		    {
		      first_error (_("bad range in register list"));
		      return FAIL;
		    }
		  for (i = cur_reg + 1; i < reg; i++)
		    {
		      if (range & (1 << i))
			as_tsktsk
			  (_("Warning: duplicated register (r%d) in register list"),
			   i);
		      else
			range |= 1 << i;
		    }
		  in_range = 0;
		}
	      if (range & (1 << reg))
		as_tsktsk (_("Warning: duplicated register (r%d) in register list"),
			   reg);
	      else if (reg <= cur_reg)
		as_tsktsk (_("Warning: register range not in ascending order"));
	      range |= 1 << reg;
	      cur_reg = reg;
	    }
	  while (skip_past_comma (&str) != FAIL
		 || (in_range = 1, *str++ == '-'));
	  str--;
	  if (*str++ != '}')
	    {
	      first_error (_("missing `}'"));
	      return FAIL;
	    }
	}
      else
	{
	  expressionS expr;
	  if (my_get_expression (&expr, &str, GE_NO_PREFIX))
	    return FAIL;
	  if (expr.X_op == O_constant)
	    {
	      if (expr.X_add_number
		  != (expr.X_add_number & 0x0000ffff))
		{
		  inst.error = _("invalid register mask");
		  return FAIL;
		}
	      if ((range & expr.X_add_number) != 0)
		{
		  int regno = range & expr.X_add_number;
		  regno &= -regno;
		  regno = (1 << regno) - 1;
		  as_tsktsk
		    (_("Warning: duplicated register (r%d) in register list"),
		     regno);
		}
	      range |= expr.X_add_number;
	    }
	  else
	    {
	      if (inst.reloc.type != 0)
		{
		  inst.error = _("expression too complex");
		  return FAIL;
		}
	      memcpy (&inst.reloc.exp, &expr, sizeof (expressionS));
	      inst.reloc.type = BFD_RELOC_ARM_MULTI;
	      inst.reloc.pc_rel = 0;
	    }
	}
      if (*str == '|' || *str == '+')
	{
	  str++;
	  another_range = 1;
	}
    }
  while (another_range);
  *strp = str;
  return range;
}
static long parse_reg_list ( char * * strp ) { char * str = * strp ; long range = 0 ; int another_range ; do { another_range = 0 ; if ( * str == ' ' ) { int in_range = 0 ; int cur_reg = -1 ; str ++ ; do { int reg ; if ( ( reg = arm_reg_parse ( & str , REG_TYPE_RN ) ) == FAIL ) { first_error ( _ ( reg_expected_msgs [ REG_TYPE_RN ] ) ) ; return FAIL ; } if ( in_range ) { int i ; if ( reg <= cur_reg ) { first_error ( _ ( " " ) ) ; return FAIL ; } for ( i = cur_reg + 1 ; i < reg ; i ++ ) { if ( range & ( 1 << i ) ) as_tsktsk ( _ ( " " ) , i ) ; else range |= 1 << i ; } in_range = 0 ; } if ( range & ( 1 << reg ) ) as_tsktsk ( _ ( " " ) , reg ) ; else if ( reg <= cur_reg ) as_tsktsk ( _ ( " " ) ) ; range |= 1 << reg ; cur_reg = reg ; } while ( skip_past_comma ( & str ) != FAIL || ( in_range = 1 , * str ++ == ' ' ) ) ; str -- ; if ( * str ++ != ' ' ) { first_error ( _ ( " " ) ) ; return FAIL ; } } else { expressionS expr ; if ( my_get_expression ( & expr , & str , GE_NO_PREFIX ) ) return FAIL ; if ( expr . X_op == O_constant ) { if ( expr . X_add_number != ( expr . X_add_number & 0x0000ffff ) ) { inst . error = _ ( " " ) ; return FAIL ; } if ( ( range & expr . X_add_number ) != 0 ) { int regno = range & expr . X_add_number ; regno &= - regno ; regno = ( 1 << regno ) - 1 ; as_tsktsk ( _ ( " " ) , regno ) ; } range |= expr . X_add_number ; } else { if ( inst . reloc . type != 0 ) { inst . error = _ ( " " ) ; return FAIL ; } memcpy ( & inst . reloc . exp , & expr , sizeof ( expressionS ) ) ; inst . reloc . type = BFD_RELOC_ARM_MULTI ; inst . reloc . pc_rel = 0 ; } } if ( * str == ' ' || * str == ' ' ) { str ++ ; another_range = 1 ; } } while ( another_range ) ; * strp = str ; return range ; }
Parse an ARM register list.
Parse an ARM register list .
/* We come back here if we get ranges concatenated by '+' or '|'.  */