This is the mail archive of the binutils@sources.redhat.com mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Thumb32 assembler (60/69)


Another pass of rearrangement and function renames.

zw

	* config/tc-arm.c: Another general reorganization.  Move parser
        functions used only (transitively) from parse_operands to just above
        parse_operands.  Move all encoding subroutines just above all
        per-instruction encoding routines.  Move Thumb encoding routines below
        all ARM-format encoding routines.
	Rename all parse functions to begin with parse_, except
        my_get_expression.  Rename all encoding subroutines encode_arm_*
        instead of encode_*_arm.

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 62)
+++ gas/config/tc-arm.c	(revision 63)
@@ -502,7 +502,6 @@
 /* Pointer to a linked list of literal pools.  */
 literal_pool * list_of_pools = NULL;
 
-
 /* Pure syntax.	 */
 
 /* This array holds the chars that always start a comment.  If the
@@ -742,97 +741,6 @@
   return 0;
 }
 
-/* Returns the pseudo-register number of an FPA immediate constant,
-   or FAIL if there isn't a valid constant here.  */
-
-static int
-fpa_immediate (char ** str)
-{
-  LITTLENUM_TYPE words[MAX_LITTLENUMS];
-  char *	 save_in;
-  expressionS	 exp;
-  int		 i;
-  int		 j;
-
-  /* First try and match exact strings, this is to guarantee
-     that some formats will work even for cross assembly.  */
-
-  for (i = 0; fp_const[i]; i++)
-    {
-      if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
-	{
-	  char *start = *str;
-
-	  *str += strlen (fp_const[i]);
-	  if (is_end_of_line[(unsigned char) **str])
-	    return i + 8;
-	  *str = start;
-	}
-    }
-
-  /* Just because we didn't get a match doesn't mean that the constant
-     isn't valid, just that it is in a format that we don't
-     automatically recognize.  Try parsing it with the standard
-     expression routines.  */
-
-  memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
-
-  /* Look for a raw floating point number.  */
-  if ((save_in = atof_ieee (*str, 'x', words)) != NULL
-      && is_end_of_line[(unsigned char) *save_in])
-    {
-      for (i = 0; i < NUM_FLOAT_VALS; i++)
-	{
-	  for (j = 0; j < MAX_LITTLENUMS; j++)
-	    {
-	      if (words[j] != fp_values[i][j])
-		break;
-	    }
-
-	  if (j == MAX_LITTLENUMS)
-	    {
-	      *str = save_in;
-	      return i + 8;
-	    }
-	}
-    }
-
-  /* Try and parse a more complex expression, this will probably fail
-     unless the code uses a floating point prefix (eg "0f").  */
-  save_in = input_line_pointer;
-  input_line_pointer = *str;
-  if (expression (&exp) == absolute_section
-      && exp.X_op == O_big
-      && exp.X_add_number < 0)
-    {
-      /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
-	 Ditto for 15.	*/
-      if (gen_to_words (words, 5, (long) 15) == 0)
-	{
-	  for (i = 0; i < NUM_FLOAT_VALS; i++)
-	    {
-	      for (j = 0; j < MAX_LITTLENUMS; j++)
-		{
-		  if (words[j] != fp_values[i][j])
-		    break;
-		}
-
-	      if (j == MAX_LITTLENUMS)
-		{
-		  *str = input_line_pointer;
-		  input_line_pointer = save_in;
-		  return i + 8;
-		}
-	    }
-	}
-    }
-
-  *str = input_line_pointer;
-  input_line_pointer = save_in;
-  inst.error = _("invalid FPA immediate expression");
-  return FAIL;
-}
-
 /* We handle all bad expressions here, so that we can report the faulty
    instruction in the error message.  */
 void
@@ -844,38 +752,11 @@
 
 /* Immediate values.  */
 
-/* Generic immediate-value read function for use in insn parsing.
-   STR points to the beginning of the immediate (the leading #);
-   VAL receives the value; if the value is outside [MIN, MAX]
-   issue an error.  PREFIX_OPT is true if the immediate prefix is
-   optional.  */
+/* Generic immediate-value read function for use in directives.
+   Accepts anything that 'expression' can fold to a constant.
+   *val receives the number.  */
 
 static int
-immediate_required_here (char **str, int *val, int min, int max,
-			 bfd_boolean prefix_opt)
-{
-  expressionS exp;
-  my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
-  if (exp.X_op != O_constant)
-    {
-      inst.error = _("constant expression required");
-      return FAIL;
-    }
-
-  if (exp.X_add_number < min || exp.X_add_number > max)
-    {
-      inst.error = _("immediate value out of range");
-      return FAIL;
-    }
-
-  *val = exp.X_add_number;
-  return SUCCESS;
-}
-
-/* As above, but for use in directives, and does not provide
-   range checking.  */
-
-static int
 immediate_for_directive (int *val)
 {
   expressionS exp;
@@ -897,24 +778,6 @@
   return SUCCESS;
 }
 
-#define rotate_left(v, n) (v << n | v >> (32 - n))
-
-/* If VAL can be encoded in the immediate field of an ARM instruction,
-   return the encoded form.  Otherwise, return FAIL.  */
-
-static unsigned int
-encode_immediate_arm (unsigned int val)
-{
-  unsigned int a;
-  unsigned int i;
-
-  for (i = 0; i < 32; i += 2)
-    if ((a = rotate_left (val, i)) <= 0xff)
-      return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
-
-  return FAIL;
-}
-
 /* Register parsing.  */
 
 /* Generic register parser.  CCP points to what should be the
@@ -997,34 +860,9 @@
   return FAIL;
 }
 
-/* Encode a VFP SP register number into inst.instruction.  */
-
-static void
-vfp_sp_encode_reg (int reg, enum vfp_sp_reg_pos pos)
-{
-  switch (pos)
-    {
-    case VFP_REG_Sd:
-      inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
-      break;
-
-    case VFP_REG_Sn:
-      inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
-      break;
-
-    case VFP_REG_Sm:
-      inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
-      break;
-
-    default:
-      abort ();
-    }
-}
-
-/* Register lists.  */
-
+/* Parse an ARM register list.  Returns the bitmask, or FAIL.  */
 static long
-reg_list (char ** strp)
+parse_reg_list (char ** strp)
 {
   char * str = * strp;
   long	 range = 0;
@@ -1152,7 +990,7 @@
    register.  Double precision registers are matched if DP is nonzero.	*/
 
 static int
-vfp_parse_reg_list (char **str, int *pbase, int dp)
+parse_vfp_reg_list (char **str, int *pbase, int dp)
 {
   int base_reg;
   int new_base;
@@ -1263,217 +1101,6 @@
   return count;
 }
 
-/* Shift operands.  */
-enum shift_kind
-{
-  SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX
-};
-
-struct asm_shift_name
-{
-  const char	  *name;
-  enum shift_kind  kind;
-};
-
-/* Third argument to parse_shift.  */
-enum parse_shift_mode
-{
-  NO_SHIFT_RESTRICT,		/* Any kind of shift is accepted.  */
-  SHIFT_IMMEDIATE,		/* Shift operand must be an immediate.	*/
-  SHIFT_LSL_OR_ASR_IMMEDIATE,	/* Shift must be LSL or ASR immediate.	*/
-  SHIFT_ASR_IMMEDIATE,		/* Shift must be ASR immediate.	 */
-  SHIFT_LSL_IMMEDIATE,		/* Shift must be LSL immediate.	 */
-};
-
-/* Parse a <shift> specifier on an ARM data processing instruction.
-   This has three forms:
-
-     (LSL|LSR|ASL|ASR|ROR) Rs
-     (LSL|LSR|ASL|ASR|ROR) #imm
-     RRX
-
-   Note that ASL is assimilated to LSL in the instruction encoding, and
-   RRX to ROR #0 (which cannot be written as such).  */
-
-static int
-parse_shift (char **str, int i, enum parse_shift_mode mode)
-{
-  const struct asm_shift_name *shift_name;
-  enum shift_kind shift;
-  char *s = *str;
-  char *p = s;
-  int reg;
-
-  for (p = *str; ISALPHA (*p); p++)
-    ;
-
-  if (p == *str)
-    {
-      inst.error = _("shift expression expected");
-      return FAIL;
-    }
-
-  shift_name = hash_find_n (arm_shift_hsh, *str, p - *str);
-
-  if (shift_name == NULL)
-    {
-      inst.error = _("shift expression expected");
-      return FAIL;
-    }
-
-  shift = shift_name->kind;
-
-  switch (mode)
-    {
-    case NO_SHIFT_RESTRICT:
-    case SHIFT_IMMEDIATE:   break;
-
-    case SHIFT_LSL_OR_ASR_IMMEDIATE:
-      if (shift != SHIFT_LSL && shift != SHIFT_ASR)
-	{
-	  inst.error = _("'LSL' or 'ASR' required");
-	  return FAIL;
-	}
-      break;
-
-    case SHIFT_LSL_IMMEDIATE:
-      if (shift != SHIFT_LSL)
-	{
-	  inst.error = _("'LSL' required");
-	  return FAIL;
-	}
-      break;
-
-    case SHIFT_ASR_IMMEDIATE:
-      if (shift != SHIFT_ASR)
-	{
-	  inst.error = _("'ASR' required");
-	  return FAIL;
-	}
-      break;
-
-    default: abort ();
-    }
-
-  if (shift != SHIFT_RRX)
-    {
-      /* Whitespace can appear here if the next thing is a bare digit.	*/
-      skip_whitespace (p);
-
-      if (mode == NO_SHIFT_RESTRICT
-	  && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
-	{
-	  inst.operands[i].imm = reg;
-	  inst.operands[i].immisreg = 1;
-	}
-      else if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
-	return FAIL;
-    }
-  inst.operands[i].shift_kind = shift;
-  inst.operands[i].shifted = 1;
-  *str = p;
-  return SUCCESS;
-}
-
-/* Encode a <shift> in an ARM-format instruction.  The immediate,
-   if any, is handled by md_apply_fix3.	 */
-static void
-encode_shift_arm (int i)
-{
-  if (inst.operands[i].shift_kind == SHIFT_RRX)
-    inst.instruction |= SHIFT_ROR << 5;
-  else
-    {
-      inst.instruction |= inst.operands[i].shift_kind << 5;
-      if (inst.operands[i].immisreg)
-	{
-	  inst.instruction |= SHIFT_BY_REG;
-	  inst.instruction |= inst.operands[i].imm << 8;
-	}
-      else
-	inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
-    }
-}
-
-/* Parse a <shifter_operand> for an ARM data processing instruction:
-
-      #<immediate>
-      #<immediate>, <rotate>
-      <Rm>
-      <Rm>, <shift>
-
-   where <shift> is defined by parse_shift above, and <rotate> is a
-   multiple of 2 between 0 and 30.  Validation of immediate operands
-   is deferred to md_apply_fix3.  */
-
-static int
-parse_shifter_operand (char **str, int i)
-{
-  int value;
-  expressionS expr;
-
-  if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
-    {
-      inst.operands[i].reg = value;
-      inst.operands[i].isreg = 1;
-
-      if (skip_past_comma (str) == FAIL)
-	return SUCCESS;
-
-      /* Shift operation on register.  */
-      return parse_shift (str, i, NO_SHIFT_RESTRICT);
-    }
-
-  if (my_get_expression (&inst.reloc.exp, str, GE_IMM_PREFIX))
-    return FAIL;
-
-  if (skip_past_comma (str) == SUCCESS)
-    {
-      /* #x, y -- ie explicit rotation by Y.  */
-      if (my_get_expression (&expr, str, GE_NO_PREFIX))
-	return FAIL;
-
-      if (expr.X_op != O_constant || inst.reloc.exp.X_op != O_constant)
-	{
-	  inst.error = _("constant expression expected");
-	  return FAIL;
-	}
-
-      value = expr.X_add_number;
-      if (value < 0 || value > 30 || value % 2 != 0)
-	{
-	  inst.error = _("invalid rotation");
-	  return FAIL;
-	}
-      if (inst.reloc.exp.X_add_number < 0 || inst.reloc.exp.X_add_number > 255)
-	{
-	  inst.error = _("invalid constant");
-	  return FAIL;
-	}
-
-      /* Convert to decoded value.  md_apply_fix3 will put it back.  */
-      inst.reloc.exp.X_add_number
-	= (((inst.reloc.exp.X_add_number << (32 - value))
-	    | (inst.reloc.exp.X_add_number >> value)) & 0xffffffff);
-    }
-
-  inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
-  inst.reloc.pc_rel = 0;
-  return SUCCESS;
-}
-
-static void
-encode_shifter_operand_arm (int i)
-{
-  if (inst.operands[i].isreg)
-    {
-      inst.instruction |= inst.operands[i].reg;
-      encode_shift_arm (i);
-    }
-  else
-    inst.instruction |= INST_IMMEDIATE;
-}
-
 /* Parse an explicit relocation suffix on an expression.  This is
    either nothing, or a word in parentheses.  Note that if !OBJ_ELF,
    arm_reloc_hsh contains no entries, so this function can only
@@ -1503,497 +1130,6 @@
   return r->reloc;
 }
 
-/* Parse all forms of an ARM address expression.  Information is written
-   to inst.operands[i] and/or inst.reloc.
-
-   Preindexed addressing (.preind=1):
-
-   [Rn, #offset]       .reg=Rn .reloc.exp=offset
-   [Rn, +/-Rm]	       .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
-   [Rn, +/-Rm, shift]  .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
-		       .shift_kind=shift .reloc.exp=shift_imm
-
-   These three may have a trailing ! which causes .writeback to be set also.
-
-   Postindexed addressing (.postind=1, .writeback=1):
-
-   [Rn], #offset       .reg=Rn .reloc.exp=offset
-   [Rn], +/-Rm	       .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
-   [Rn], +/-Rm, shift  .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
-		       .shift_kind=shift .reloc.exp=shift_imm
-
-   Unindexed addressing (.preind=0, .postind=0):
-
-   [Rn], {option}      .reg=Rn .imm=option .immisreg=0
-
-   Other:
-
-   [Rn]{!}	       shorthand for [Rn,#0]{!}
-   =immediate	       .isreg=0 .reloc.exp=immediate
-   label	       .reg=PC .reloc.pc_rel=1 .reloc.exp=label
-
-  It is the caller's responsibility to check for addressing modes not
-  supported by the instruction, and to set inst.reloc.type.  */
-
-static int
-parse_address (char **str, int i)
-{
-  char *p = *str;
-  int reg;
-
-  if (skip_past_char (&p, '[') == FAIL)
-    {
-      if (skip_past_char (&p, '=') == FAIL)
-	{
-	  /* bare address - translate to PC-relative offset */
-	  inst.reloc.pc_rel = 1;
-	  inst.operands[i].reg = REG_PC;
-	  inst.operands[i].isreg = 1;
-	  inst.operands[i].preind = 1;
-	}
-      /* else a load-constant pseudo op, no special treatment needed here */
-
-      if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
-	return FAIL;
-
-      *str = p;
-      return SUCCESS;
-    }
-
-  if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
-    {
-      inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
-      return FAIL;
-    }
-  inst.operands[i].reg = reg;
-  inst.operands[i].isreg = 1;
-
-  if (skip_past_comma (&p) == SUCCESS)
-    {
-      inst.operands[i].preind = 1;
-
-      if (*p == '+') p++;
-      else if (*p == '-') p++, inst.operands[i].negative = 1;
-
-      if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
-	{
-	  inst.operands[i].imm = reg;
-	  inst.operands[i].immisreg = 1;
-
-	  if (skip_past_comma (&p) == SUCCESS)
-	    if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
-	      return FAIL;
-	}
-      else
-	{
-	  if (inst.operands[i].negative)
-	    {
-	      inst.operands[i].negative = 0;
-	      p--;
-	    }
-	  if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
-	    return FAIL;
-	}
-    }
-
-  if (skip_past_char (&p, ']') == FAIL)
-    {
-      inst.error = _("']' expected");
-      return FAIL;
-    }
-
-  if (skip_past_char (&p, '!') == SUCCESS)
-    inst.operands[i].writeback = 1;
-
-  else if (skip_past_comma (&p) == SUCCESS)
-    {
-      if (skip_past_char (&p, '{') == SUCCESS)
-	{
-	  /* [Rn], {expr} - unindexed, with option */
-	  if (immediate_required_here (&p, &inst.operands[i].imm,
-				       0, 255, TRUE) == FAIL)
-	    return FAIL;
-
-	  if (skip_past_char (&p, '}') == FAIL)
-	    {
-	      inst.error = _("'}' expected at end of 'option' field");
-	      return FAIL;
-	    }
-	  if (inst.operands[i].preind)
-	    {
-	      inst.error = _("cannot combine index with option");
-	      return FAIL;
-	    }
-	  *str = p;
-	  return SUCCESS;
-	}
-      else
-	{
-	  inst.operands[i].postind = 1;
-	  inst.operands[i].writeback = 1;
-
-	  if (inst.operands[i].preind)
-	    {
-	      inst.error = _("cannot combine pre- and post-indexing");
-	      return FAIL;
-	    }
-
-	  if (*p == '+') p++;
-	  else if (*p == '-') p++, inst.operands[i].negative = 1;
-
-	  if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
-	    {
-	      inst.operands[i].imm = reg;
-	      inst.operands[i].immisreg = 1;
-
-	      if (skip_past_comma (&p) == SUCCESS)
-		if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
-		  return FAIL;
-	    }
-	  else
-	    {
-	      if (inst.operands[i].negative)
-		{
-		  inst.operands[i].negative = 0;
-		  p--;
-		}
-	      if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
-		return FAIL;
-	    }
-	}
-    }
-
-  /* If at this point neither .preind nor .postind is set, we have a
-     bare [Rn]{!}, which is shorthand for [Rn,#0]{!}.  */
-  if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
-    {
-      inst.operands[i].preind = 1;
-      inst.reloc.exp.X_op = O_constant;
-      inst.reloc.exp.X_add_number = 0;
-    }
-  *str = p;
-  return SUCCESS;
-}
-
-/* Miscellaneous: PSR flags, endian specifiers, coprocessor
-   operands. */
-
-/* Parse a PSR flag operand.  The value returned is FAIL on syntax error,
-   or a bitmask suitable to be or-ed into the ARM msr instruction.  */
-static int
-parse_psr (char **str)
-{
-  char *p;
-  unsigned long psr_field;
-
-  /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
-     feature for ease of use and backwards compatibility.  */
-  p = *str;
-  if (*p == 's' || *p == 'S')
-    psr_field = SPSR_BIT;
-  else if (*p == 'c' || *p == 'C')
-    psr_field = 0;
-  else
-    goto error;
-
-  p++;
-  if (strncasecmp (p, "PSR", 3) != 0)
-    goto error;
-  p += 3;
-
-  if (*p == '_')
-    {
-      /* A suffix follows.  */
-      const struct asm_psr *psr;
-      char *start;
-
-      p++;
-      start = p;
-
-      do
-	p++;
-      while (ISALNUM (*p) || *p == '_');
-
-      psr = hash_find_n (arm_psr_hsh, start, p - start);
-      if (!psr)
-	goto error;
-
-      psr_field |= psr->field;
-    }
-  else
-    {
-      if (ISALNUM (*p))
-	goto error;    /* Garbage after "[CS]PSR".  */
-
-      psr_field |= (PSR_c | PSR_f);
-    }
-  *str = p;
-  return psr_field;
-
- error:
-  inst.error = _("flag for {c}psr instruction expected");
-  return FAIL;
-}
-
-/* Subroutine of encode_addr_mode_2_arm and encode_addr_mode_3_arm.  */
-static void
-encode_addr_mode_common_arm (int i, bfd_boolean is_t)
-{
-  assert (inst.operands[i].isreg);
-  inst.instruction |= inst.operands[i].reg << 16;
-
-  if (inst.operands[i].preind)
-    {
-      if (is_t)
-	{
-	  inst.error = _("instruction does not accept preindexed addressing");
-	  return;
-	}
-      inst.instruction |= PRE_INDEX;
-      if (inst.operands[i].writeback)
-	inst.instruction |= WRITE_BACK;
-
-    }
-  else if (inst.operands[i].postind)
-    {
-      assert (inst.operands[i].writeback);
-      if (is_t)
-	inst.instruction |= WRITE_BACK;
-    }
-  else /* unindexed - only for coprocessor */
-    {
-      inst.error = _("instruction does not accept unindexed addressing");
-      return;
-    }
-
-  if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
-      && (((inst.instruction & 0x000f0000) >> 16)
-	  == ((inst.instruction & 0x0000f000) >> 12)))
-    as_warn ((inst.instruction & LOAD_BIT)
-	     ? _("destination register same as write-back base")
-	     : _("source register same as write-back base"));
-}
-
-/* inst.operands[i] was set up by parse_address.  Encode it into an
-   ARM-format mode 2 load or store instruction.	 If is_t is true,
-   reject forms that cannot be used with a T instruction (i.e. not
-   post-indexed).  */
-static void
-encode_addr_mode_2_arm (int i, bfd_boolean is_t)
-{
-  encode_addr_mode_common_arm (i, is_t);
-
-  if (inst.operands[i].immisreg)
-    {
-      inst.instruction |= INST_IMMEDIATE;  /* yes, this is backwards */
-      inst.instruction |= inst.operands[i].imm;
-      if (!inst.operands[i].negative)
-	inst.instruction |= INDEX_UP;
-      if (inst.operands[i].shifted)
-	{
-	  if (inst.operands[i].shift_kind == SHIFT_RRX)
-	    inst.instruction |= SHIFT_ROR << 5;
-	  else
-	    {
-	      inst.instruction |= inst.operands[i].shift_kind << 5;
-	      inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
-	    }
-	}
-    }
-  else /* immediate offset in inst.reloc */
-    {
-      if (inst.reloc.type == BFD_RELOC_UNUSED)
-	inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
-      if (inst.reloc.pc_rel)
-	inst.reloc.exp.X_add_number -= 8;  /* pipeline offset */
-    }
-}
-
-/* inst.operands[i] was set up by parse_address.  Encode it into an
-   ARM-format mode 3 load or store instruction.	 Reject forms that
-   cannot be used with such instructions.  If is_t is true, reject
-   forms that cannot be used with a T instruction (i.e. not
-   post-indexed).  */
-static void
-encode_addr_mode_3_arm (int i, bfd_boolean is_t)
-{
-  if (inst.operands[i].immisreg && inst.operands[i].shifted)
-    {
-      inst.error = _("instruction does not accept scaled register index");
-      return;
-    }
-
-  encode_addr_mode_common_arm (i, is_t);
-
-  if (inst.operands[i].immisreg)
-    {
-      inst.instruction |= inst.operands[i].imm;
-      if (!inst.operands[i].negative)
-	inst.instruction |= INDEX_UP;
-    }
-  else /* immediate offset in inst.reloc */
-    {
-      inst.instruction |= HWOFFSET_IMM;
-      if (inst.reloc.type == BFD_RELOC_UNUSED)
-	inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
-      if (inst.reloc.pc_rel)
-	inst.reloc.exp.X_add_number -= 8;  /* pipeline offset */
-    }
-}
-
-/* inst.operands[i] was set up by parse_address.  Encode it into an
-   ARM-format instruction.  Reject all forms which cannot be encoded
-   into a coprocessor load/store instruction.  If wb_ok is false,
-   reject use of writeback; if unind_ok is false, reject use of
-   unindexed addressing.  If reloc_override is not 0, use it instead
-   of BFD_ARM_CP_OFF_IMM.  */
-
-static int
-encode_cp_address_arm (int i, int wb_ok, int unind_ok, int reloc_override)
-{
-  inst.instruction |= inst.operands[i].reg << 16;
-
-  assert (!(inst.operands[i].preind && inst.operands[i].postind));
-
-  if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
-    {
-      assert (!inst.operands[i].writeback);
-      if (!unind_ok)
-	{
-	  inst.error = _("instruction does not support unindexed addressing");
-	  return FAIL;
-	}
-      inst.instruction |= inst.operands[i].imm;
-      inst.instruction |= INDEX_UP;
-      return SUCCESS;
-    }
-
-  if (inst.operands[i].preind)
-    inst.instruction |= PRE_INDEX;
-
-  if (inst.operands[i].writeback)
-    {
-      if (inst.operands[i].reg == REG_PC)
-	{
-	  inst.error = _("pc may not be used with write-back");
-	  return FAIL;
-	}
-      if (!wb_ok)
-	{
-	  inst.error = _("instruction does not support writeback");
-	  return FAIL;
-	}
-      inst.instruction |= WRITE_BACK;
-    }
-
-  if (reloc_override)
-    inst.reloc.type = reloc_override;
-  else
-    inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
-  if (inst.reloc.pc_rel)
-    inst.reloc.exp.X_add_number -= 8;
-  return SUCCESS;
-}
-
-/* Parse the flags argument to CPSI[ED].  Returns FAIL on error, or a
-   value suitable for splatting into the AIF field of the instruction.	*/
-
-static int
-parse_cps_flags (char **str)
-{
-  int val = 0;
-  int saw_a_flag = 0;
-  char *s = *str;
-
-  for (;;)
-    switch (*s++)
-      {
-      case '\0': case ',':
-	goto done;
-
-      case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
-      case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
-      case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
-
-      default:
-	inst.error = _("unrecognized CPS flag");
-	return FAIL;
-      }
-
- done:
-  if (saw_a_flag == 0)
-    {
-      inst.error = _("missing CPS flags");
-      return FAIL;
-    }
-
-  *str = s - 1;
-  return val;
-}
-
-/* Parse an endian specifier ("BE" or "LE", case insensitive);
-   returns 0 for big-endian, 1 for little-endian, FAIL for an error.  */
-
-static int
-parse_endian_specifier (char **str)
-{
-  int little_endian;
-  char *s = *str;
-
-  if (strncasecmp (s, "BE", 2))
-    little_endian = 0;
-  else if (strncasecmp (s, "LE", 2))
-    little_endian = 1;
-  else
-    {
-      inst.error = _("valid endian specifiers are be or le");
-      return FAIL;
-    }
-
-  if (ISALNUM (s[2]) || s[2] == '_')
-    {
-      inst.error = _("valid endian specifiers are be or le");
-      return FAIL;
-    }
-
-  *str = s + 2;
-  return little_endian;
-}
-
-/* Parse a rotation specifier: ROR #0, #8, #16, #24.  *val receives a
-   value suitable for poking into the rotate field of an sxt or sxta
-   instruction, or FAIL on error.  */
-
-static int
-parse_ror (char **str)
-{
-  int rot;
-  char *s = *str;
-
-  if (strncasecmp (s, "ROR", 3) == 0)
-    s += 3;
-  else
-    {
-      inst.error = _("missing rotation field after comma");
-      return FAIL;
-    }
-
-  if (immediate_required_here (&s, &rot, 0, 24, FALSE) == FAIL)
-    return FAIL;
-
-  switch (rot)
-    {
-    case  0: *str = s; return 0x0;
-    case  8: *str = s; return 0x1;
-    case 16: *str = s; return 0x2;
-    case 24: *str = s; return 0x3;
-
-    default:
-      inst.error = _("rotation can only be 0, 8, 16, or 24");
-      return FAIL;
-    }
-}
-
 /* Directives: register aliases.  */
 
 static void
@@ -2686,81 +1822,6 @@
   return SUCCESS;
 }
 
-/* inst.reloc.exp describes an "=expr" load pseudo-operation.
-   Determine whether it can be performed with a move instruction; if
-   it can, convert inst.instruction to that move instruction and
-   return 1; if it can't, convert inst.instruction to a literal-pool
-   load and return 0.  If this is not a valid thing to do in the
-   current context, set inst.error and return 1.
-
-   inst.operands[i] describes the destination register.	 */
-
-static int
-move_or_literal_pool (int i, bfd_boolean thumb_p, bfd_boolean mode_3)
-{
-  if ((inst.instruction & (thumb_p ? THUMB_LOAD_BIT : LOAD_BIT)) == 0)
-    {
-      inst.error = _("invalid pseudo operation");
-      return 1;
-    }
-  if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol)
-    {
-      inst.error = _("constant expression expected");
-      return 1;
-    }
-  if (inst.reloc.exp.X_op == O_constant)
-    {
-      if (thumb_p)
-	{
-	  if ((inst.reloc.exp.X_add_number & ~0xFF) == 0)
-	    {
-	      /* This can be done with a mov instruction.  */
-	      inst.instruction	= T_OPCODE_MOV_I8 | (inst.operands[i].reg << 8);
-	      inst.instruction |= inst.reloc.exp.X_add_number;
-	      return 1;
-	    }
-	}
-      else
-	{
-	  int value = encode_immediate_arm (inst.reloc.exp.X_add_number);
-	  if (value != FAIL)
-	    {
-	      /* This can be done with a mov instruction.  */
-	      inst.instruction &= LITERAL_MASK;
-	      inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
-	      inst.instruction |= value & 0xfff;
-	      return 1;
-	    }
-
-	  value = encode_immediate_arm (~inst.reloc.exp.X_add_number);
-	  if (value != FAIL)
-	    {
-	      /* This can be done with a mvn instruction.  */
-	      inst.instruction &= LITERAL_MASK;
-	      inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
-	      inst.instruction |= value & 0xfff;
-	      return 1;
-	    }
-	}
-    }
-
-  if (add_to_lit_pool () == FAIL)
-    {
-      inst.error = _("literal pool insertion failed");
-      return 1;
-    }
-  inst.operands[1].reg = REG_PC;
-  inst.operands[1].isreg = 1;
-  inst.operands[1].preind = 1;
-  inst.reloc.pc_rel = 1;
-  inst.reloc.type = (thumb_p
-		     ? BFD_RELOC_ARM_THUMB_OFFSET
-		     : (mode_3
-			? BFD_RELOC_ARM_HWLITERAL
-			: BFD_RELOC_ARM_LITERAL));
-  return 0;
-}
-
 /* Can't use symbol_new here, so have to create a symbol and then at
    a later date assign it a value. Thats what these functions do.  */
 
@@ -3123,7 +2184,7 @@
   long range;
   int n;
 
-  range = reg_list (&input_line_pointer);
+  range = parse_reg_list (&input_line_pointer);
   if (range == FAIL)
     {
       as_bad (_("expected register list"));
@@ -3245,7 +2306,7 @@
   int reg;
   valueT op;
 
-  count = vfp_parse_reg_list (&input_line_pointer, &reg, 1);
+  count = parse_vfp_reg_list (&input_line_pointer, &reg, 1);
   if (count == FAIL)
     {
       as_bad (_("expected register list"));
@@ -3740,7 +2801,637 @@
   { 0, 0, 0 }
 };
 
-/* Matcher codes for operand_parse.  */
+/* Parser functions used exclusively in instruction operands.  */
+
+/* Generic immediate-value read function for use in insn parsing.
+   STR points to the beginning of the immediate (the leading #);
+   VAL receives the value; if the value is outside [MIN, MAX]
+   issue an error.  PREFIX_OPT is true if the immediate prefix is
+   optional.  */
+
+static int
+parse_immediate (char **str, int *val, int min, int max,
+		 bfd_boolean prefix_opt)
+{
+  expressionS exp;
+  my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
+  if (exp.X_op != O_constant)
+    {
+      inst.error = _("constant expression required");
+      return FAIL;
+    }
+
+  if (exp.X_add_number < min || exp.X_add_number > max)
+    {
+      inst.error = _("immediate value out of range");
+      return FAIL;
+    }
+
+  *val = exp.X_add_number;
+  return SUCCESS;
+}
+
+/* Returns the pseudo-register number of an FPA immediate constant,
+   or FAIL if there isn't a valid constant here.  */
+
+static int
+parse_fpa_immediate (char ** str)
+{
+  LITTLENUM_TYPE words[MAX_LITTLENUMS];
+  char *	 save_in;
+  expressionS	 exp;
+  int		 i;
+  int		 j;
+
+  /* First try and match exact strings, this is to guarantee
+     that some formats will work even for cross assembly.  */
+
+  for (i = 0; fp_const[i]; i++)
+    {
+      if (strncmp (*str, fp_const[i], strlen (fp_const[i])) == 0)
+	{
+	  char *start = *str;
+
+	  *str += strlen (fp_const[i]);
+	  if (is_end_of_line[(unsigned char) **str])
+	    return i + 8;
+	  *str = start;
+	}
+    }
+
+  /* Just because we didn't get a match doesn't mean that the constant
+     isn't valid, just that it is in a format that we don't
+     automatically recognize.  Try parsing it with the standard
+     expression routines.  */
+
+  memset (words, 0, MAX_LITTLENUMS * sizeof (LITTLENUM_TYPE));
+
+  /* Look for a raw floating point number.  */
+  if ((save_in = atof_ieee (*str, 'x', words)) != NULL
+      && is_end_of_line[(unsigned char) *save_in])
+    {
+      for (i = 0; i < NUM_FLOAT_VALS; i++)
+	{
+	  for (j = 0; j < MAX_LITTLENUMS; j++)
+	    {
+	      if (words[j] != fp_values[i][j])
+		break;
+	    }
+
+	  if (j == MAX_LITTLENUMS)
+	    {
+	      *str = save_in;
+	      return i + 8;
+	    }
+	}
+    }
+
+  /* Try and parse a more complex expression, this will probably fail
+     unless the code uses a floating point prefix (eg "0f").  */
+  save_in = input_line_pointer;
+  input_line_pointer = *str;
+  if (expression (&exp) == absolute_section
+      && exp.X_op == O_big
+      && exp.X_add_number < 0)
+    {
+      /* FIXME: 5 = X_PRECISION, should be #define'd where we can use it.
+	 Ditto for 15.	*/
+      if (gen_to_words (words, 5, (long) 15) == 0)
+	{
+	  for (i = 0; i < NUM_FLOAT_VALS; i++)
+	    {
+	      for (j = 0; j < MAX_LITTLENUMS; j++)
+		{
+		  if (words[j] != fp_values[i][j])
+		    break;
+		}
+
+	      if (j == MAX_LITTLENUMS)
+		{
+		  *str = input_line_pointer;
+		  input_line_pointer = save_in;
+		  return i + 8;
+		}
+	    }
+	}
+    }
+
+  *str = input_line_pointer;
+  input_line_pointer = save_in;
+  inst.error = _("invalid FPA immediate expression");
+  return FAIL;
+}
+
+/* Shift operands.  */
+enum shift_kind
+{
+  SHIFT_LSL, SHIFT_LSR, SHIFT_ASR, SHIFT_ROR, SHIFT_RRX
+};
+
+struct asm_shift_name
+{
+  const char	  *name;
+  enum shift_kind  kind;
+};
+
+/* Third argument to parse_shift.  */
+enum parse_shift_mode
+{
+  NO_SHIFT_RESTRICT,		/* Any kind of shift is accepted.  */
+  SHIFT_IMMEDIATE,		/* Shift operand must be an immediate.	*/
+  SHIFT_LSL_OR_ASR_IMMEDIATE,	/* Shift must be LSL or ASR immediate.	*/
+  SHIFT_ASR_IMMEDIATE,		/* Shift must be ASR immediate.	 */
+  SHIFT_LSL_IMMEDIATE,		/* Shift must be LSL immediate.	 */
+};
+
+/* Parse a <shift> specifier on an ARM data processing instruction.
+   This has three forms:
+
+     (LSL|LSR|ASL|ASR|ROR) Rs
+     (LSL|LSR|ASL|ASR|ROR) #imm
+     RRX
+
+   Note that ASL is assimilated to LSL in the instruction encoding, and
+   RRX to ROR #0 (which cannot be written as such).  */
+
+static int
+parse_shift (char **str, int i, enum parse_shift_mode mode)
+{
+  const struct asm_shift_name *shift_name;
+  enum shift_kind shift;
+  char *s = *str;
+  char *p = s;
+  int reg;
+
+  for (p = *str; ISALPHA (*p); p++)
+    ;
+
+  if (p == *str)
+    {
+      inst.error = _("shift expression expected");
+      return FAIL;
+    }
+
+  shift_name = hash_find_n (arm_shift_hsh, *str, p - *str);
+
+  if (shift_name == NULL)
+    {
+      inst.error = _("shift expression expected");
+      return FAIL;
+    }
+
+  shift = shift_name->kind;
+
+  switch (mode)
+    {
+    case NO_SHIFT_RESTRICT:
+    case SHIFT_IMMEDIATE:   break;
+
+    case SHIFT_LSL_OR_ASR_IMMEDIATE:
+      if (shift != SHIFT_LSL && shift != SHIFT_ASR)
+	{
+	  inst.error = _("'LSL' or 'ASR' required");
+	  return FAIL;
+	}
+      break;
+
+    case SHIFT_LSL_IMMEDIATE:
+      if (shift != SHIFT_LSL)
+	{
+	  inst.error = _("'LSL' required");
+	  return FAIL;
+	}
+      break;
+
+    case SHIFT_ASR_IMMEDIATE:
+      if (shift != SHIFT_ASR)
+	{
+	  inst.error = _("'ASR' required");
+	  return FAIL;
+	}
+      break;
+
+    default: abort ();
+    }
+
+  if (shift != SHIFT_RRX)
+    {
+      /* Whitespace can appear here if the next thing is a bare digit.	*/
+      skip_whitespace (p);
+
+      if (mode == NO_SHIFT_RESTRICT
+	  && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
+	{
+	  inst.operands[i].imm = reg;
+	  inst.operands[i].immisreg = 1;
+	}
+      else if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+	return FAIL;
+    }
+  inst.operands[i].shift_kind = shift;
+  inst.operands[i].shifted = 1;
+  *str = p;
+  return SUCCESS;
+}
+
+/* Parse a <shifter_operand> for an ARM data processing instruction:
+
+      #<immediate>
+      #<immediate>, <rotate>
+      <Rm>
+      <Rm>, <shift>
+
+   where <shift> is defined by parse_shift above, and <rotate> is a
+   multiple of 2 between 0 and 30.  Validation of immediate operands
+   is deferred to md_apply_fix3.  */
+
+static int
+parse_shifter_operand (char **str, int i)
+{
+  int value;
+  expressionS expr;
+
+  if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
+    {
+      inst.operands[i].reg = value;
+      inst.operands[i].isreg = 1;
+
+      if (skip_past_comma (str) == FAIL)
+	return SUCCESS;
+
+      /* Shift operation on register.  */
+      return parse_shift (str, i, NO_SHIFT_RESTRICT);
+    }
+
+  if (my_get_expression (&inst.reloc.exp, str, GE_IMM_PREFIX))
+    return FAIL;
+
+  if (skip_past_comma (str) == SUCCESS)
+    {
+      /* #x, y -- ie explicit rotation by Y.  */
+      if (my_get_expression (&expr, str, GE_NO_PREFIX))
+	return FAIL;
+
+      if (expr.X_op != O_constant || inst.reloc.exp.X_op != O_constant)
+	{
+	  inst.error = _("constant expression expected");
+	  return FAIL;
+	}
+
+      value = expr.X_add_number;
+      if (value < 0 || value > 30 || value % 2 != 0)
+	{
+	  inst.error = _("invalid rotation");
+	  return FAIL;
+	}
+      if (inst.reloc.exp.X_add_number < 0 || inst.reloc.exp.X_add_number > 255)
+	{
+	  inst.error = _("invalid constant");
+	  return FAIL;
+	}
+
+      /* Convert to decoded value.  md_apply_fix3 will put it back.  */
+      inst.reloc.exp.X_add_number
+	= (((inst.reloc.exp.X_add_number << (32 - value))
+	    | (inst.reloc.exp.X_add_number >> value)) & 0xffffffff);
+    }
+
+  inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
+  inst.reloc.pc_rel = 0;
+  return SUCCESS;
+}
+
+/* Parse all forms of an ARM address expression.  Information is written
+   to inst.operands[i] and/or inst.reloc.
+
+   Preindexed addressing (.preind=1):
+
+   [Rn, #offset]       .reg=Rn .reloc.exp=offset
+   [Rn, +/-Rm]	       .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
+   [Rn, +/-Rm, shift]  .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
+		       .shift_kind=shift .reloc.exp=shift_imm
+
+   These three may have a trailing ! which causes .writeback to be set also.
+
+   Postindexed addressing (.postind=1, .writeback=1):
+
+   [Rn], #offset       .reg=Rn .reloc.exp=offset
+   [Rn], +/-Rm	       .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
+   [Rn], +/-Rm, shift  .reg=Rn .imm=Rm .immisreg=1 .negative=0/1
+		       .shift_kind=shift .reloc.exp=shift_imm
+
+   Unindexed addressing (.preind=0, .postind=0):
+
+   [Rn], {option}      .reg=Rn .imm=option .immisreg=0
+
+   Other:
+
+   [Rn]{!}	       shorthand for [Rn,#0]{!}
+   =immediate	       .isreg=0 .reloc.exp=immediate
+   label	       .reg=PC .reloc.pc_rel=1 .reloc.exp=label
+
+  It is the caller's responsibility to check for addressing modes not
+  supported by the instruction, and to set inst.reloc.type.  */
+
+static int
+parse_address (char **str, int i)
+{
+  char *p = *str;
+  int reg;
+
+  if (skip_past_char (&p, '[') == FAIL)
+    {
+      if (skip_past_char (&p, '=') == FAIL)
+	{
+	  /* bare address - translate to PC-relative offset */
+	  inst.reloc.pc_rel = 1;
+	  inst.operands[i].reg = REG_PC;
+	  inst.operands[i].isreg = 1;
+	  inst.operands[i].preind = 1;
+	}
+      /* else a load-constant pseudo op, no special treatment needed here */
+
+      if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
+	return FAIL;
+
+      *str = p;
+      return SUCCESS;
+    }
+
+  if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) == FAIL)
+    {
+      inst.error = _(reg_expected_msgs[REG_TYPE_RN]);
+      return FAIL;
+    }
+  inst.operands[i].reg = reg;
+  inst.operands[i].isreg = 1;
+
+  if (skip_past_comma (&p) == SUCCESS)
+    {
+      inst.operands[i].preind = 1;
+
+      if (*p == '+') p++;
+      else if (*p == '-') p++, inst.operands[i].negative = 1;
+
+      if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
+	{
+	  inst.operands[i].imm = reg;
+	  inst.operands[i].immisreg = 1;
+
+	  if (skip_past_comma (&p) == SUCCESS)
+	    if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
+	      return FAIL;
+	}
+      else
+	{
+	  if (inst.operands[i].negative)
+	    {
+	      inst.operands[i].negative = 0;
+	      p--;
+	    }
+	  if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+	    return FAIL;
+	}
+    }
+
+  if (skip_past_char (&p, ']') == FAIL)
+    {
+      inst.error = _("']' expected");
+      return FAIL;
+    }
+
+  if (skip_past_char (&p, '!') == SUCCESS)
+    inst.operands[i].writeback = 1;
+
+  else if (skip_past_comma (&p) == SUCCESS)
+    {
+      if (skip_past_char (&p, '{') == SUCCESS)
+	{
+	  /* [Rn], {expr} - unindexed, with option */
+	  if (parse_immediate (&p, &inst.operands[i].imm,
+				       0, 255, TRUE) == FAIL)
+	    return FAIL;
+
+	  if (skip_past_char (&p, '}') == FAIL)
+	    {
+	      inst.error = _("'}' expected at end of 'option' field");
+	      return FAIL;
+	    }
+	  if (inst.operands[i].preind)
+	    {
+	      inst.error = _("cannot combine index with option");
+	      return FAIL;
+	    }
+	  *str = p;
+	  return SUCCESS;
+	}
+      else
+	{
+	  inst.operands[i].postind = 1;
+	  inst.operands[i].writeback = 1;
+
+	  if (inst.operands[i].preind)
+	    {
+	      inst.error = _("cannot combine pre- and post-indexing");
+	      return FAIL;
+	    }
+
+	  if (*p == '+') p++;
+	  else if (*p == '-') p++, inst.operands[i].negative = 1;
+
+	  if ((reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
+	    {
+	      inst.operands[i].imm = reg;
+	      inst.operands[i].immisreg = 1;
+
+	      if (skip_past_comma (&p) == SUCCESS)
+		if (parse_shift (&p, i, SHIFT_IMMEDIATE) == FAIL)
+		  return FAIL;
+	    }
+	  else
+	    {
+	      if (inst.operands[i].negative)
+		{
+		  inst.operands[i].negative = 0;
+		  p--;
+		}
+	      if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
+		return FAIL;
+	    }
+	}
+    }
+
+  /* If at this point neither .preind nor .postind is set, we have a
+     bare [Rn]{!}, which is shorthand for [Rn,#0]{!}.  */
+  if (inst.operands[i].preind == 0 && inst.operands[i].postind == 0)
+    {
+      inst.operands[i].preind = 1;
+      inst.reloc.exp.X_op = O_constant;
+      inst.reloc.exp.X_add_number = 0;
+    }
+  *str = p;
+  return SUCCESS;
+}
+
+/* Miscellaneous. */
+
+/* Parse a PSR flag operand.  The value returned is FAIL on syntax error,
+   or a bitmask suitable to be or-ed into the ARM msr instruction.  */
+static int
+parse_psr (char **str)
+{
+  char *p;
+  unsigned long psr_field;
+
+  /* CPSR's and SPSR's can now be lowercase.  This is just a convenience
+     feature for ease of use and backwards compatibility.  */
+  p = *str;
+  if (*p == 's' || *p == 'S')
+    psr_field = SPSR_BIT;
+  else if (*p == 'c' || *p == 'C')
+    psr_field = 0;
+  else
+    goto error;
+
+  p++;
+  if (strncasecmp (p, "PSR", 3) != 0)
+    goto error;
+  p += 3;
+
+  if (*p == '_')
+    {
+      /* A suffix follows.  */
+      const struct asm_psr *psr;
+      char *start;
+
+      p++;
+      start = p;
+
+      do
+	p++;
+      while (ISALNUM (*p) || *p == '_');
+
+      psr = hash_find_n (arm_psr_hsh, start, p - start);
+      if (!psr)
+	goto error;
+
+      psr_field |= psr->field;
+    }
+  else
+    {
+      if (ISALNUM (*p))
+	goto error;    /* Garbage after "[CS]PSR".  */
+
+      psr_field |= (PSR_c | PSR_f);
+    }
+  *str = p;
+  return psr_field;
+
+ error:
+  inst.error = _("flag for {c}psr instruction expected");
+  return FAIL;
+}
+
+/* Parse the flags argument to CPSI[ED].  Returns FAIL on error, or a
+   value suitable for splatting into the AIF field of the instruction.	*/
+
+static int
+parse_cps_flags (char **str)
+{
+  int val = 0;
+  int saw_a_flag = 0;
+  char *s = *str;
+
+  for (;;)
+    switch (*s++)
+      {
+      case '\0': case ',':
+	goto done;
+
+      case 'a': case 'A': saw_a_flag = 1; val |= 0x4; break;
+      case 'i': case 'I': saw_a_flag = 1; val |= 0x2; break;
+      case 'f': case 'F': saw_a_flag = 1; val |= 0x1; break;
+
+      default:
+	inst.error = _("unrecognized CPS flag");
+	return FAIL;
+      }
+
+ done:
+  if (saw_a_flag == 0)
+    {
+      inst.error = _("missing CPS flags");
+      return FAIL;
+    }
+
+  *str = s - 1;
+  return val;
+}
+
+/* Parse an endian specifier ("BE" or "LE", case insensitive);
+   returns 0 for big-endian, 1 for little-endian, FAIL for an error.  */
+
+static int
+parse_endian_specifier (char **str)
+{
+  int little_endian;
+  char *s = *str;
+
+  if (strncasecmp (s, "BE", 2))
+    little_endian = 0;
+  else if (strncasecmp (s, "LE", 2))
+    little_endian = 1;
+  else
+    {
+      inst.error = _("valid endian specifiers are be or le");
+      return FAIL;
+    }
+
+  if (ISALNUM (s[2]) || s[2] == '_')
+    {
+      inst.error = _("valid endian specifiers are be or le");
+      return FAIL;
+    }
+
+  *str = s + 2;
+  return little_endian;
+}
+
+/* Parse a rotation specifier: ROR #0, #8, #16, #24.  *val receives a
+   value suitable for poking into the rotate field of an sxt or sxta
+   instruction, or FAIL on error.  */
+
+static int
+parse_ror (char **str)
+{
+  int rot;
+  char *s = *str;
+
+  if (strncasecmp (s, "ROR", 3) == 0)
+    s += 3;
+  else
+    {
+      inst.error = _("missing rotation field after comma");
+      return FAIL;
+    }
+
+  if (parse_immediate (&s, &rot, 0, 24, FALSE) == FAIL)
+    return FAIL;
+
+  switch (rot)
+    {
+    case  0: *str = s; return 0x0;
+    case  8: *str = s; return 0x1;
+    case 16: *str = s; return 0x2;
+    case 24: *str = s; return 0x3;
+
+    default:
+      inst.error = _("rotation can only be 0, 8, 16, or 24");
+      return FAIL;
+    }
+}
+
+/* Matcher codes for parse_operands.  */
 enum operand_parse_code
 {
   OP_stop,	/* end of line */
@@ -3853,10 +3544,10 @@
   inst.operands[i].isreg = 1;			\
 } while (0)
 
-#define po_imm_or_fail(min, max, popt) do {				\
-  if (immediate_required_here (&str, &val, min, max, popt) == FAIL)	\
-    goto failure;							\
-  inst.operands[i].imm = val;						\
+#define po_imm_or_fail(min, max, popt) do {			\
+  if (parse_immediate (&str, &val, min, max, popt) == FAIL)	\
+    goto failure;						\
+  inst.operands[i].imm = val;					\
 } while (0)
 
 #define po_misc_or_fail(expr) do {		\
@@ -4001,11 +3692,11 @@
 	  if (!is_immediate_prefix (*str))
 	    goto bad_args;
 	  str++;
-	  val = fpa_immediate (&str);
+	  val = parse_fpa_immediate (&str);
 	  if (val == FAIL)
 	    goto failure;
 	  /* FPA immediates are encoded as registers 8-15.
-	     fpa_immediate has already applied the offset.  */
+	     parse_fpa_immediate has already applied the offset.  */
 	  inst.operands[i].reg = val;
 	  inst.operands[i].isreg = 1;
 	  break;
@@ -4032,7 +3723,7 @@
 
 	  /* Register lists */
 	case OP_REGLST:
-	  val = reg_list (&str);
+	  val = parse_reg_list (&str);
 	  if (*str == '^')
 	    {
 	      inst.operands[1].writeback = 1;
@@ -4041,11 +3732,11 @@
 	  break;
 
 	case OP_VRSLST:
-	  val = vfp_parse_reg_list (&str, &inst.operands[i].reg, 0);
+	  val = parse_vfp_reg_list (&str, &inst.operands[i].reg, 0);
 	  break;
 
 	case OP_VRDLST:
-	  val = vfp_parse_reg_list (&str, &inst.operands[i].reg, 1);
+	  val = parse_vfp_reg_list (&str, &inst.operands[i].reg, 1);
 	  break;
 
 	  /* Addressing modes */
@@ -4132,7 +3823,6 @@
 #undef po_reg_or_fail
 #undef po_reg_or_goto
 #undef po_imm_or_fail
-
 
 /* Shorthand macro for instruction encoding functions issuing errors.  */
 #define constraint(expr, err) do {		\
@@ -4143,6 +3833,317 @@
     }						\
 } while (0)
 
+/* Functions for operand encoding.  ARM, then Thumb.  */
+
+#define rotate_left(v, n) (v << n | v >> (32 - n))
+
+/* If VAL can be encoded in the immediate field of an ARM instruction,
+   return the encoded form.  Otherwise, return FAIL.  */
+
+static unsigned int
+encode_arm_immediate (unsigned int val)
+{
+  unsigned int a;
+  unsigned int i;
+
+  for (i = 0; i < 32; i += 2)
+    if ((a = rotate_left (val, i)) <= 0xff)
+      return a | (i << 7); /* 12-bit pack: [shift-cnt,const].  */
+
+  return FAIL;
+}
+
+/* Encode a VFP SP register number into inst.instruction.  */
+
+static void
+encode_arm_vfp_sp_reg (int reg, enum vfp_sp_reg_pos pos)
+{
+  switch (pos)
+    {
+    case VFP_REG_Sd:
+      inst.instruction |= ((reg >> 1) << 12) | ((reg & 1) << 22);
+      break;
+
+    case VFP_REG_Sn:
+      inst.instruction |= ((reg >> 1) << 16) | ((reg & 1) << 7);
+      break;
+
+    case VFP_REG_Sm:
+      inst.instruction |= ((reg >> 1) << 0) | ((reg & 1) << 5);
+      break;
+
+    default:
+      abort ();
+    }
+}
+
+/* Encode a <shift> in an ARM-format instruction.  The immediate,
+   if any, is handled by md_apply_fix3.	 */
+static void
+encode_arm_shift (int i)
+{
+  if (inst.operands[i].shift_kind == SHIFT_RRX)
+    inst.instruction |= SHIFT_ROR << 5;
+  else
+    {
+      inst.instruction |= inst.operands[i].shift_kind << 5;
+      if (inst.operands[i].immisreg)
+	{
+	  inst.instruction |= SHIFT_BY_REG;
+	  inst.instruction |= inst.operands[i].imm << 8;
+	}
+      else
+	inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+    }
+}
+
+static void
+encode_arm_shifter_operand (int i)
+{
+  if (inst.operands[i].isreg)
+    {
+      inst.instruction |= inst.operands[i].reg;
+      encode_arm_shift (i);
+    }
+  else
+    inst.instruction |= INST_IMMEDIATE;
+}
+
+/* Subroutine of encode_arm_addr_mode_2 and encode_arm_addr_mode_3.  */
+static void
+encode_arm_addr_mode_common (int i, bfd_boolean is_t)
+{
+  assert (inst.operands[i].isreg);
+  inst.instruction |= inst.operands[i].reg << 16;
+
+  if (inst.operands[i].preind)
+    {
+      if (is_t)
+	{
+	  inst.error = _("instruction does not accept preindexed addressing");
+	  return;
+	}
+      inst.instruction |= PRE_INDEX;
+      if (inst.operands[i].writeback)
+	inst.instruction |= WRITE_BACK;
+
+    }
+  else if (inst.operands[i].postind)
+    {
+      assert (inst.operands[i].writeback);
+      if (is_t)
+	inst.instruction |= WRITE_BACK;
+    }
+  else /* unindexed - only for coprocessor */
+    {
+      inst.error = _("instruction does not accept unindexed addressing");
+      return;
+    }
+
+  if (((inst.instruction & WRITE_BACK) || !(inst.instruction & PRE_INDEX))
+      && (((inst.instruction & 0x000f0000) >> 16)
+	  == ((inst.instruction & 0x0000f000) >> 12)))
+    as_warn ((inst.instruction & LOAD_BIT)
+	     ? _("destination register same as write-back base")
+	     : _("source register same as write-back base"));
+}
+
+/* inst.operands[i] was set up by parse_address.  Encode it into an
+   ARM-format mode 2 load or store instruction.	 If is_t is true,
+   reject forms that cannot be used with a T instruction (i.e. not
+   post-indexed).  */
+static void
+encode_arm_addr_mode_2 (int i, bfd_boolean is_t)
+{
+  encode_arm_addr_mode_common (i, is_t);
+
+  if (inst.operands[i].immisreg)
+    {
+      inst.instruction |= INST_IMMEDIATE;  /* yes, this is backwards */
+      inst.instruction |= inst.operands[i].imm;
+      if (!inst.operands[i].negative)
+	inst.instruction |= INDEX_UP;
+      if (inst.operands[i].shifted)
+	{
+	  if (inst.operands[i].shift_kind == SHIFT_RRX)
+	    inst.instruction |= SHIFT_ROR << 5;
+	  else
+	    {
+	      inst.instruction |= inst.operands[i].shift_kind << 5;
+	      inst.reloc.type = BFD_RELOC_ARM_SHIFT_IMM;
+	    }
+	}
+    }
+  else /* immediate offset in inst.reloc */
+    {
+      if (inst.reloc.type == BFD_RELOC_UNUSED)
+	inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
+      if (inst.reloc.pc_rel)
+	inst.reloc.exp.X_add_number -= 8;  /* pipeline offset */
+    }
+}
+
+/* inst.operands[i] was set up by parse_address.  Encode it into an
+   ARM-format mode 3 load or store instruction.	 Reject forms that
+   cannot be used with such instructions.  If is_t is true, reject
+   forms that cannot be used with a T instruction (i.e. not
+   post-indexed).  */
+static void
+encode_arm_addr_mode_3 (int i, bfd_boolean is_t)
+{
+  if (inst.operands[i].immisreg && inst.operands[i].shifted)
+    {
+      inst.error = _("instruction does not accept scaled register index");
+      return;
+    }
+
+  encode_arm_addr_mode_common (i, is_t);
+
+  if (inst.operands[i].immisreg)
+    {
+      inst.instruction |= inst.operands[i].imm;
+      if (!inst.operands[i].negative)
+	inst.instruction |= INDEX_UP;
+    }
+  else /* immediate offset in inst.reloc */
+    {
+      inst.instruction |= HWOFFSET_IMM;
+      if (inst.reloc.type == BFD_RELOC_UNUSED)
+	inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;
+      if (inst.reloc.pc_rel)
+	inst.reloc.exp.X_add_number -= 8;  /* pipeline offset */
+    }
+}
+
+/* inst.operands[i] was set up by parse_address.  Encode it into an
+   ARM-format instruction.  Reject all forms which cannot be encoded
+   into a coprocessor load/store instruction.  If wb_ok is false,
+   reject use of writeback; if unind_ok is false, reject use of
+   unindexed addressing.  If reloc_override is not 0, use it instead
+   of BFD_ARM_CP_OFF_IMM.  */
+
+static int
+encode_arm_cp_address (int i, int wb_ok, int unind_ok, int reloc_override)
+{
+  inst.instruction |= inst.operands[i].reg << 16;
+
+  assert (!(inst.operands[i].preind && inst.operands[i].postind));
+
+  if (!inst.operands[i].preind && !inst.operands[i].postind) /* unindexed */
+    {
+      assert (!inst.operands[i].writeback);
+      if (!unind_ok)
+	{
+	  inst.error = _("instruction does not support unindexed addressing");
+	  return FAIL;
+	}
+      inst.instruction |= inst.operands[i].imm;
+      inst.instruction |= INDEX_UP;
+      return SUCCESS;
+    }
+
+  if (inst.operands[i].preind)
+    inst.instruction |= PRE_INDEX;
+
+  if (inst.operands[i].writeback)
+    {
+      if (inst.operands[i].reg == REG_PC)
+	{
+	  inst.error = _("pc may not be used with write-back");
+	  return FAIL;
+	}
+      if (!wb_ok)
+	{
+	  inst.error = _("instruction does not support writeback");
+	  return FAIL;
+	}
+      inst.instruction |= WRITE_BACK;
+    }
+
+  if (reloc_override)
+    inst.reloc.type = reloc_override;
+  else
+    inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+  if (inst.reloc.pc_rel)
+    inst.reloc.exp.X_add_number -= 8;
+  return SUCCESS;
+}
+
+/* inst.reloc.exp describes an "=expr" load pseudo-operation.
+   Determine whether it can be performed with a move instruction; if
+   it can, convert inst.instruction to that move instruction and
+   return 1; if it can't, convert inst.instruction to a literal-pool
+   load and return 0.  If this is not a valid thing to do in the
+   current context, set inst.error and return 1.
+
+   inst.operands[i] describes the destination register.	 */
+
+static int
+move_or_literal_pool (int i, bfd_boolean thumb_p, bfd_boolean mode_3)
+{
+  if ((inst.instruction & (thumb_p ? THUMB_LOAD_BIT : LOAD_BIT)) == 0)
+    {
+      inst.error = _("invalid pseudo operation");
+      return 1;
+    }
+  if (inst.reloc.exp.X_op != O_constant && inst.reloc.exp.X_op != O_symbol)
+    {
+      inst.error = _("constant expression expected");
+      return 1;
+    }
+  if (inst.reloc.exp.X_op == O_constant)
+    {
+      if (thumb_p)
+	{
+	  if ((inst.reloc.exp.X_add_number & ~0xFF) == 0)
+	    {
+	      /* This can be done with a mov instruction.  */
+	      inst.instruction	= T_OPCODE_MOV_I8 | (inst.operands[i].reg << 8);
+	      inst.instruction |= inst.reloc.exp.X_add_number;
+	      return 1;
+	    }
+	}
+      else
+	{
+	  int value = encode_arm_immediate (inst.reloc.exp.X_add_number);
+	  if (value != FAIL)
+	    {
+	      /* This can be done with a mov instruction.  */
+	      inst.instruction &= LITERAL_MASK;
+	      inst.instruction |= INST_IMMEDIATE | (OPCODE_MOV << DATA_OP_SHIFT);
+	      inst.instruction |= value & 0xfff;
+	      return 1;
+	    }
+
+	  value = encode_arm_immediate (~inst.reloc.exp.X_add_number);
+	  if (value != FAIL)
+	    {
+	      /* This can be done with a mvn instruction.  */
+	      inst.instruction &= LITERAL_MASK;
+	      inst.instruction |= INST_IMMEDIATE | (OPCODE_MVN << DATA_OP_SHIFT);
+	      inst.instruction |= value & 0xfff;
+	      return 1;
+	    }
+	}
+    }
+
+  if (add_to_lit_pool () == FAIL)
+    {
+      inst.error = _("literal pool insertion failed");
+      return 1;
+    }
+  inst.operands[1].reg = REG_PC;
+  inst.operands[1].isreg = 1;
+  inst.operands[1].preind = 1;
+  inst.reloc.pc_rel = 1;
+  inst.reloc.type = (thumb_p
+		     ? BFD_RELOC_ARM_THUMB_OFFSET
+		     : (mode_3
+			? BFD_RELOC_ARM_HWLITERAL
+			: BFD_RELOC_ARM_LITERAL));
+  return 0;
+}
+
 /* Functions for instruction encoding, sorted by subarchitecture.
    First some generics; their names are taken from the conventional
    bit positions for register arguments in ARM format instructions.  */
@@ -4213,7 +4214,7 @@
 do_rd_cpaddr (void)
 {
   inst.instruction |= inst.operands[0].reg << 12;
-  encode_cp_address_arm (1, TRUE, TRUE, 0);
+  encode_arm_cp_address (1, TRUE, TRUE, 0);
 }
 
 /* ARM instructions, in alphabetical order by function name (except
@@ -4264,7 +4265,7 @@
     inst.operands[1].reg = inst.operands[0].reg;
   inst.instruction |= inst.operands[0].reg << 12;
   inst.instruction |= inst.operands[1].reg << 16;
-  encode_shifter_operand_arm (2);
+  encode_arm_shifter_operand (2);
 }
 
 static void
@@ -4418,7 +4419,7 @@
 do_cmp (void)
 {
   inst.instruction |= inst.operands[0].reg << 16;
-  encode_shifter_operand_arm (1);
+  encode_arm_shifter_operand (1);
 }
 
 /* Transfer between coprocessor and ARM registers.
@@ -4524,7 +4525,7 @@
   constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
   if (inst.instruction & LOAD_BIT)
     {
-      /* encode_addr_mode_3_arm will diagnose overlap between the base
+      /* encode_arm_addr_mode_3 will diagnose overlap between the base
 	 register and the first register written; we have to diagnose
 	 overlap between the base and the second register written here.	 */
 
@@ -4542,7 +4543,7 @@
     }
 
   inst.instruction |= inst.operands[0].reg << 12;
-  encode_addr_mode_3_arm (1, /*is_t=*/FALSE);
+  encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
 }
 
 static void
@@ -4552,7 +4553,7 @@
   if (!inst.operands[1].isreg)
     if (move_or_literal_pool (0, /*thumb_p=*/FALSE, /*mode_3=*/FALSE))
       return;
-  encode_addr_mode_2_arm (1, /*is_t=*/FALSE);
+  encode_arm_addr_mode_2 (1, /*is_t=*/FALSE);
 }
 
 static void
@@ -4571,7 +4572,7 @@
       inst.operands[1].writeback = 1;
     }
   inst.instruction |= inst.operands[0].reg << 12;
-  encode_addr_mode_2_arm (1, /*is_t=*/TRUE);
+  encode_arm_addr_mode_2 (1, /*is_t=*/TRUE);
 }
 
 /* Halfword and signed-byte load/store operations.  */
@@ -4583,7 +4584,7 @@
   if (!inst.operands[1].isreg)
     if (move_or_literal_pool (0, /*thumb_p=*/FALSE, /*mode_3=*/TRUE))
       return;
-  encode_addr_mode_3_arm (1, /*is_t=*/FALSE);
+  encode_arm_addr_mode_3 (1, /*is_t=*/FALSE);
 }
 
 static void
@@ -4602,7 +4603,7 @@
       inst.operands[1].writeback = 1;
     }
   inst.instruction |= inst.operands[0].reg << 12;
-  encode_addr_mode_3_arm (1, /*is_t=*/TRUE);
+  encode_arm_addr_mode_3 (1, /*is_t=*/TRUE);
 }
 
 /* Co-processor register load/store.
@@ -4612,7 +4613,7 @@
 {
   inst.instruction |= inst.operands[0].reg << 8;
   inst.instruction |= inst.operands[1].reg << 12;
-  encode_cp_address_arm (2, TRUE, TRUE, 0);
+  encode_arm_cp_address (2, TRUE, TRUE, 0);
 }
 
 static void
@@ -4635,7 +4636,7 @@
 do_mov (void)
 {
   inst.instruction |= inst.operands[0].reg << 12;
-  encode_shifter_operand_arm (1);
+  encode_arm_shifter_operand (1);
 }
 
 /* ARM V6T2 16-bit immediate register load: MOV[WT]{cond} Rd, #<imm16>.	 */
@@ -4734,7 +4735,7 @@
   inst.instruction |= inst.operands[1].reg << 16;
   inst.instruction |= inst.operands[2].reg;
   if (inst.operands[3].present)
-    encode_shift_arm (3);
+    encode_arm_shift (3);
 }
 
 /* ARM V6 PKHTB (Argument Parse).  */
@@ -4756,7 +4757,7 @@
       inst.instruction |= inst.operands[0].reg << 12;
       inst.instruction |= inst.operands[1].reg << 16;
       inst.instruction |= inst.operands[2].reg;
-      encode_shift_arm (3);
+      encode_arm_shift (3);
     }
 }
 
@@ -4778,7 +4779,7 @@
   constraint (!inst.operands[0].preind,
 	      _("unindexed addressing used in preload instruction"));
   inst.instruction |= inst.operands[0].reg;
-  encode_addr_mode_2_arm (0, /*is_t=*/FALSE);
+  encode_arm_addr_mode_2 (0, /*is_t=*/FALSE);
 }
 
 static void
@@ -4816,7 +4817,7 @@
   inst.instruction |= inst.operands[2].reg;
 
   if (inst.operands[3].present)
-    encode_shift_arm (3);
+    encode_arm_shift (3);
 }
 
 /* ARM V6 usat (argument parse).  */
@@ -4829,7 +4830,7 @@
   inst.instruction |= inst.operands[2].reg;
 
   if (inst.operands[3].present)
-    encode_shift_arm (3);
+    encode_arm_shift (3);
 }
 
 /* ARM V6 ssat16 (argument parse).  */
@@ -4993,8 +4994,396 @@
   inst.instruction |= inst.operands[1].reg;
   inst.instruction |= inst.operands[2].imm << 10;
 }
+
+/* VFP instructions.  In a logical order: SP variant first, monad
+   before dyad, arithmetic then move then load/store.  */
 
+static void
+do_vfp_sp_monadic (void)
+{
+  encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sd);
+  encode_arm_vfp_sp_reg (inst.operands[1].reg, VFP_REG_Sm);
+}
+
+static void
+do_vfp_sp_dyadic (void)
+{
+  encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sd);
+  encode_arm_vfp_sp_reg (inst.operands[1].reg, VFP_REG_Sn);
+  encode_arm_vfp_sp_reg (inst.operands[2].reg, VFP_REG_Sm);
+}
+
+static void
+do_vfp_sp_compare_z (void)
+{
+  encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sd);
+}
+
+static void
+do_vfp_dp_sp_cvt (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  encode_arm_vfp_sp_reg (inst.operands[1].reg, VFP_REG_Sm);
+}
+
+static void
+do_vfp_sp_dp_cvt (void)
+{
+  encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sd);
+  inst.instruction |= inst.operands[1].reg;
+}
+
+static void
+do_vfp_reg_from_sp (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  encode_arm_vfp_sp_reg (inst.operands[1].reg, VFP_REG_Sn);
+}
+
+static void
+do_vfp_reg2_from_sp2 (void)
+{
+  constraint (inst.operands[2].imm != 2,
+	      _("only two consecutive VFP SP registers allowed here"));
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+  encode_arm_vfp_sp_reg (inst.operands[2].reg, VFP_REG_Sm);
+}
+
+static void
+do_vfp_sp_from_reg (void)
+{
+  encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sn);
+  inst.instruction |= inst.operands[1].reg << 12;
+}
+
+static void
+do_vfp_sp2_from_reg2 (void)
+{
+  constraint (inst.operands[0].imm != 2,
+	      _("only two consecutive VFP SP registers allowed here"));
+  encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sm);
+  inst.instruction |= inst.operands[1].reg << 12;
+  inst.instruction |= inst.operands[2].reg << 16;
+}
+
+static void
+do_vfp_sp_ldst (void)
+{
+  encode_arm_vfp_sp_reg (inst.operands[0].reg, VFP_REG_Sd);
+  encode_arm_cp_address (1, FALSE, TRUE, 0);
+}
+
+static void
+do_vfp_dp_ldst (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  encode_arm_cp_address (1, FALSE, TRUE, 0);
+}
+
+
+static void
+vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
+{
+  if (inst.operands[0].writeback)
+    inst.instruction |= WRITE_BACK;
+  else
+    constraint (ldstm_type != VFP_LDSTMIA,
+		_("this addressing mode requires base-register writeback"));
+  inst.instruction |= inst.operands[0].reg << 16;
+  encode_arm_vfp_sp_reg (inst.operands[1].reg, VFP_REG_Sd);
+  inst.instruction |= inst.operands[1].imm;
+}
+
+static void
+vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
+{
+  int count;
+
+  if (inst.operands[0].writeback)
+    inst.instruction |= WRITE_BACK;
+  else
+    constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
+		_("this addressing mode requires base-register writeback"));
+
+  inst.instruction |= inst.operands[0].reg << 16;
+  inst.instruction |= inst.operands[1].reg << 12;
+
+  count = inst.operands[1].imm << 1;
+  if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
+    count += 1;
+
+  inst.instruction |= count;
+}
+
+static void
+do_vfp_sp_ldstmia (void)
+{
+  vfp_sp_ldstm (VFP_LDSTMIA);
+}
+
+static void
+do_vfp_sp_ldstmdb (void)
+{
+  vfp_sp_ldstm (VFP_LDSTMDB);
+}
+
+static void
+do_vfp_dp_ldstmia (void)
+{
+  vfp_dp_ldstm (VFP_LDSTMIA);
+}
+
+static void
+do_vfp_dp_ldstmdb (void)
+{
+  vfp_dp_ldstm (VFP_LDSTMDB);
+}
+
+static void
+do_vfp_xp_ldstmia (void)
+{
+  vfp_dp_ldstm (VFP_LDSTMIAX);
+}
+
+static void
+do_vfp_xp_ldstmdb (void)
+{
+  vfp_dp_ldstm (VFP_LDSTMDBX);
+}
 
+/* FPA instructions.  Also in a logical order.	*/
+
+static void
+do_fpa_cmp (void)
+{
+  inst.instruction |= inst.operands[0].reg << 16;
+  inst.instruction |= inst.operands[1].reg;
+}
+
+static void
+do_fpa_ldmstm (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  switch (inst.operands[1].imm)
+    {
+    case 1: inst.instruction |= CP_T_X;		 break;
+    case 2: inst.instruction |= CP_T_Y;		 break;
+    case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
+    case 4:					 break;
+    default: abort ();
+    }
+
+  if (inst.instruction & (PRE_INDEX | INDEX_UP))
+    {
+      /* The instruction specified "ea" or "fd", so we can only accept
+	 [Rn]{!}.  The instruction does not really support stacking or
+	 unstacking, so we have to emulate these by setting appropriate
+	 bits and offsets.  */
+      constraint (inst.reloc.exp.X_op != O_constant
+		  || inst.reloc.exp.X_add_number != 0,
+		  _("this instruction does not support indexing"));
+      if (inst.operands[2].writeback)
+	inst.instruction |= WRITE_BACK;
+      if (inst.instruction & (PRE_INDEX | WRITE_BACK))
+	inst.reloc.exp.X_add_number = 12 * inst.operands[1].imm;
+      else
+	inst.instruction |= PRE_INDEX;	/* prevent use of unindexed mode */
+
+      if (!(inst.instruction & INDEX_UP))
+	inst.reloc.exp.X_add_number = -inst.reloc.exp.X_add_number;
+
+      inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
+    }
+  else
+    encode_arm_cp_address (2, TRUE, TRUE, 0);
+}
+
+/* iWMMXt instructions: strictly in alphabetical order.	 */
+
+static void
+do_iwmmxt_tandorc (void)
+{
+  constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
+}
+
+static void
+do_iwmmxt_textrc (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].imm;
+}
+
+static void
+do_iwmmxt_textrm (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= inst.operands[2].imm;
+}
+
+static void
+do_iwmmxt_tinsr (void)
+{
+  inst.instruction |= inst.operands[0].reg << 16;
+  inst.instruction |= inst.operands[1].reg << 12;
+  inst.instruction |= inst.operands[2].imm;
+}
+
+static void
+do_iwmmxt_tmia (void)
+{
+  inst.instruction |= inst.operands[0].reg << 5;
+  inst.instruction |= inst.operands[1].reg;
+  inst.instruction |= inst.operands[2].reg << 12;
+}
+
+static void
+do_iwmmxt_waligni (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= inst.operands[2].reg;
+  inst.instruction |= inst.operands[3].imm << 20;
+}
+
+static void
+do_iwmmxt_wmov (void)
+{
+  /* WMOV rD, rN is an alias for WOR rD, rN, rN.  */
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= inst.operands[1].reg;
+}
+
+static void
+do_iwmmxt_wldst (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  encode_arm_cp_address (1, TRUE, FALSE, BFD_RELOC_ARM_CP_OFF_IMM_S2);
+}
+
+static void
+do_iwmmxt_wldstw (void)
+{
+  /* RIWR_RIWC clears .isreg for a control register.  */
+  if (!inst.operands[0].isreg)
+    {
+      constraint ((inst.instruction & COND_MASK) != COND_ALWAYS, BAD_COND);
+      inst.instruction |= 0xf0000000;
+    }
+
+  inst.instruction |= inst.operands[0].reg << 12;
+  encode_arm_cp_address (1, TRUE, TRUE, 0);
+}
+
+static void
+do_iwmmxt_wshufh (void)
+{
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+  inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
+  inst.instruction |= (inst.operands[2].imm & 0x0f);
+}
+
+static void
+do_iwmmxt_wzero (void)
+{
+  /* WZERO reg is an alias for WANDN reg, reg, reg.  */
+  inst.instruction |= inst.operands[0].reg;
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[0].reg << 16;
+}
+
+/* Cirrus Maverick instructions.  Simple 2-, 3-, and 4-register
+   operations first, then control, shift, and load/store.  */
+
+/* Insns like "foo X,Y,Z".  */
+
+static void
+do_mav_triple (void)
+{
+  inst.instruction |= inst.operands[0].reg << 16;
+  inst.instruction |= inst.operands[1].reg;
+  inst.instruction |= inst.operands[2].reg << 12;
+}
+
+/* Insns like "foo W,X,Y,Z".
+    where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
+
+static void
+do_mav_quad (void)
+{
+  inst.instruction |= inst.operands[0].reg << 5;
+  inst.instruction |= inst.operands[1].reg << 12;
+  inst.instruction |= inst.operands[2].reg << 16;
+  inst.instruction |= inst.operands[3].reg;
+}
+
+/* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
+static void
+do_mav_dspsc (void)
+{
+  inst.instruction |= inst.operands[1].reg << 12;
+}
+
+/* Maverick shift immediate instructions.
+   cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
+   cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
+
+static void
+do_mav_shift (void)
+{
+  int imm = inst.operands[2].imm;
+
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+
+  /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
+     Bits 5-7 of the insn should have bits 4-6 of the immediate.
+     Bit 4 should be 0.	 */
+  imm = (imm & 0xf) | ((imm & 0x70) << 1);
+
+  inst.instruction |= imm;
+}
+
+/* XScale instructions.	 Also sorted arithmetic before move.  */
+
+/* Xscale multiply-accumulate (argument parse)
+     MIAcc   acc0,Rm,Rs
+     MIAPHcc acc0,Rm,Rs
+     MIAxycc acc0,Rm,Rs.  */
+
+static void
+do_xsc_mia (void)
+{
+  inst.instruction |= inst.operands[1].reg;
+  inst.instruction |= inst.operands[2].reg << 12;
+}
+
+/* Xscale move-accumulator-register (argument parse)
+
+     MARcc   acc0,RdLo,RdHi.  */
+
+static void
+do_xsc_mar (void)
+{
+  inst.instruction |= inst.operands[1].reg << 12;
+  inst.instruction |= inst.operands[2].reg << 16;
+}
+
+/* Xscale move-register-accumulator (argument parse)
+
+     MRAcc   RdLo,RdHi,acc0.  */
+
+static void
+do_xsc_mra (void)
+{
+  constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
+  inst.instruction |= inst.operands[0].reg << 12;
+  inst.instruction |= inst.operands[1].reg << 16;
+}
+
 /* Thumb instructions, in alphabetical order. */
 
 /* Parse an add or subtract instruction.  The high bit of inst.instruction
@@ -5421,397 +5810,6 @@
   inst.instruction |= inst.operands[0].imm;
 }
 
-/* VFP instructions.  In a logical order: SP variant first, monad
-   before dyad, arithmetic then move then load/store.  */
-
-static void
-do_vfp_sp_monadic (void)
-{
-  vfp_sp_encode_reg (inst.operands[0].reg, VFP_REG_Sd);
-  vfp_sp_encode_reg (inst.operands[1].reg, VFP_REG_Sm);
-}
-
-static void
-do_vfp_sp_dyadic (void)
-{
-  vfp_sp_encode_reg (inst.operands[0].reg, VFP_REG_Sd);
-  vfp_sp_encode_reg (inst.operands[1].reg, VFP_REG_Sn);
-  vfp_sp_encode_reg (inst.operands[2].reg, VFP_REG_Sm);
-}
-
-static void
-do_vfp_sp_compare_z (void)
-{
-  vfp_sp_encode_reg (inst.operands[0].reg, VFP_REG_Sd);
-}
-
-static void
-do_vfp_dp_sp_cvt (void)
-{
-  inst.instruction |= inst.operands[0].reg << 12;
-  vfp_sp_encode_reg (inst.operands[1].reg, VFP_REG_Sm);
-}
-
-static void
-do_vfp_sp_dp_cvt (void)
-{
-  vfp_sp_encode_reg (inst.operands[0].reg, VFP_REG_Sd);
-  inst.instruction |= inst.operands[1].reg;
-}
-
-static void
-do_vfp_reg_from_sp (void)
-{
-  inst.instruction |= inst.operands[0].reg << 12;
-  vfp_sp_encode_reg (inst.operands[1].reg, VFP_REG_Sn);
-}
-
-static void
-do_vfp_reg2_from_sp2 (void)
-{
-  constraint (inst.operands[2].imm != 2,
-	      _("only two consecutive VFP SP registers allowed here"));
-  inst.instruction |= inst.operands[0].reg << 12;
-  inst.instruction |= inst.operands[1].reg << 16;
-  vfp_sp_encode_reg (inst.operands[2].reg, VFP_REG_Sm);
-}
-
-static void
-do_vfp_sp_from_reg (void)
-{
-  vfp_sp_encode_reg (inst.operands[0].reg, VFP_REG_Sn);
-  inst.instruction |= inst.operands[1].reg << 12;
-}
-
-static void
-do_vfp_sp2_from_reg2 (void)
-{
-  constraint (inst.operands[0].imm != 2,
-	      _("only two consecutive VFP SP registers allowed here"));
-  vfp_sp_encode_reg (inst.operands[0].reg, VFP_REG_Sm);
-  inst.instruction |= inst.operands[1].reg << 12;
-  inst.instruction |= inst.operands[2].reg << 16;
-}
-
-static void
-do_vfp_sp_ldst (void)
-{
-  vfp_sp_encode_reg (inst.operands[0].reg, VFP_REG_Sd);
-  encode_cp_address_arm (1, FALSE, TRUE, 0);
-}
-
-static void
-do_vfp_dp_ldst (void)
-{
-  inst.instruction |= inst.operands[0].reg << 12;
-  encode_cp_address_arm (1, FALSE, TRUE, 0);
-}
-
-
-static void
-vfp_sp_ldstm (enum vfp_ldstm_type ldstm_type)
-{
-  if (inst.operands[0].writeback)
-    inst.instruction |= WRITE_BACK;
-  else
-    constraint (ldstm_type != VFP_LDSTMIA,
-		_("this addressing mode requires base-register writeback"));
-  inst.instruction |= inst.operands[0].reg << 16;
-  vfp_sp_encode_reg (inst.operands[1].reg, VFP_REG_Sd);
-  inst.instruction |= inst.operands[1].imm;
-}
-
-static void
-vfp_dp_ldstm (enum vfp_ldstm_type ldstm_type)
-{
-  int count;
-
-  if (inst.operands[0].writeback)
-    inst.instruction |= WRITE_BACK;
-  else
-    constraint (ldstm_type != VFP_LDSTMIA && ldstm_type != VFP_LDSTMIAX,
-		_("this addressing mode requires base-register writeback"));
-
-  inst.instruction |= inst.operands[0].reg << 16;
-  inst.instruction |= inst.operands[1].reg << 12;
-
-  count = inst.operands[1].imm << 1;
-  if (ldstm_type == VFP_LDSTMIAX || ldstm_type == VFP_LDSTMDBX)
-    count += 1;
-
-  inst.instruction |= count;
-}
-
-static void
-do_vfp_sp_ldstmia (void)
-{
-  vfp_sp_ldstm (VFP_LDSTMIA);
-}
-
-static void
-do_vfp_sp_ldstmdb (void)
-{
-  vfp_sp_ldstm (VFP_LDSTMDB);
-}
-
-static void
-do_vfp_dp_ldstmia (void)
-{
-  vfp_dp_ldstm (VFP_LDSTMIA);
-}
-
-static void
-do_vfp_dp_ldstmdb (void)
-{
-  vfp_dp_ldstm (VFP_LDSTMDB);
-}
-
-static void
-do_vfp_xp_ldstmia (void)
-{
-  vfp_dp_ldstm (VFP_LDSTMIAX);
-}
-
-static void
-do_vfp_xp_ldstmdb (void)
-{
-  vfp_dp_ldstm (VFP_LDSTMDBX);
-}
-
-
-/* FPA instructions.  Also in a logical order.	*/
-
-static void
-do_fpa_cmp (void)
-{
-  inst.instruction |= inst.operands[0].reg << 16;
-  inst.instruction |= inst.operands[1].reg;
-}
-
-static void
-do_fpa_ldmstm (void)
-{
-  inst.instruction |= inst.operands[0].reg << 12;
-  switch (inst.operands[1].imm)
-    {
-    case 1: inst.instruction |= CP_T_X;		 break;
-    case 2: inst.instruction |= CP_T_Y;		 break;
-    case 3: inst.instruction |= CP_T_Y | CP_T_X; break;
-    case 4:					 break;
-    default: abort ();
-    }
-
-  if (inst.instruction & (PRE_INDEX | INDEX_UP))
-    {
-      /* The instruction specified "ea" or "fd", so we can only accept
-	 [Rn]{!}.  The instruction does not really support stacking or
-	 unstacking, so we have to emulate these by setting appropriate
-	 bits and offsets.  */
-      constraint (inst.reloc.exp.X_op != O_constant
-		  || inst.reloc.exp.X_add_number != 0,
-		  _("this instruction does not support indexing"));
-      if (inst.operands[2].writeback)
-	inst.instruction |= WRITE_BACK;
-      if (inst.instruction & (PRE_INDEX | WRITE_BACK))
-	inst.reloc.exp.X_add_number = 12 * inst.operands[1].imm;
-      else
-	inst.instruction |= PRE_INDEX;	/* prevent use of unindexed mode */
-
-      if (!(inst.instruction & INDEX_UP))
-	inst.reloc.exp.X_add_number = -inst.reloc.exp.X_add_number;
-
-      inst.reloc.type = BFD_RELOC_ARM_CP_OFF_IMM;
-    }
-  else
-    encode_cp_address_arm (2, TRUE, TRUE, 0);
-}
-
-
-/* iWMMXt instructions: strictly in alphabetical order.	 */
-
-static void
-do_iwmmxt_tandorc (void)
-{
-  constraint (inst.operands[0].reg != REG_PC, _("only r15 allowed here"));
-}
-
-static void
-do_iwmmxt_textrc (void)
-{
-  inst.instruction |= inst.operands[0].reg << 12;
-  inst.instruction |= inst.operands[1].imm;
-}
-
-static void
-do_iwmmxt_textrm (void)
-{
-  inst.instruction |= inst.operands[0].reg << 12;
-  inst.instruction |= inst.operands[1].reg << 16;
-  inst.instruction |= inst.operands[2].imm;
-}
-
-static void
-do_iwmmxt_tinsr (void)
-{
-  inst.instruction |= inst.operands[0].reg << 16;
-  inst.instruction |= inst.operands[1].reg << 12;
-  inst.instruction |= inst.operands[2].imm;
-}
-
-static void
-do_iwmmxt_tmia (void)
-{
-  inst.instruction |= inst.operands[0].reg << 5;
-  inst.instruction |= inst.operands[1].reg;
-  inst.instruction |= inst.operands[2].reg << 12;
-}
-
-static void
-do_iwmmxt_waligni (void)
-{
-  inst.instruction |= inst.operands[0].reg << 12;
-  inst.instruction |= inst.operands[1].reg << 16;
-  inst.instruction |= inst.operands[2].reg;
-  inst.instruction |= inst.operands[3].imm << 20;
-}
-
-static void
-do_iwmmxt_wmov (void)
-{
-  /* WMOV rD, rN is an alias for WOR rD, rN, rN.  */
-  inst.instruction |= inst.operands[0].reg << 12;
-  inst.instruction |= inst.operands[1].reg << 16;
-  inst.instruction |= inst.operands[1].reg;
-}
-
-static void
-do_iwmmxt_wldst (void)
-{
-  inst.instruction |= inst.operands[0].reg << 12;
-  encode_cp_address_arm (1, TRUE, FALSE, BFD_RELOC_ARM_CP_OFF_IMM_S2);
-}
-
-static void
-do_iwmmxt_wldstw (void)
-{
-  /* RIWR_RIWC clears .isreg for a control register.  */
-  if (!inst.operands[0].isreg)
-    {
-      constraint ((inst.instruction & COND_MASK) != COND_ALWAYS, BAD_COND);
-      inst.instruction |= 0xf0000000;
-    }
-
-  inst.instruction |= inst.operands[0].reg << 12;
-  encode_cp_address_arm (1, TRUE, TRUE, 0);
-}
-
-static void
-do_iwmmxt_wshufh (void)
-{
-  inst.instruction |= inst.operands[0].reg << 12;
-  inst.instruction |= inst.operands[1].reg << 16;
-  inst.instruction |= ((inst.operands[2].imm & 0xf0) << 16);
-  inst.instruction |= (inst.operands[2].imm & 0x0f);
-}
-
-static void
-do_iwmmxt_wzero (void)
-{
-  /* WZERO reg is an alias for WANDN reg, reg, reg.  */
-  inst.instruction |= inst.operands[0].reg;
-  inst.instruction |= inst.operands[0].reg << 12;
-  inst.instruction |= inst.operands[0].reg << 16;
-}
-
-/* Cirrus Maverick instructions.  Simple 2-, 3-, and 4-register
-   operations first, then control, shift, and load/store.  */
-
-/* Insns like "foo X,Y,Z".  */
-
-static void
-do_mav_triple (void)
-{
-  inst.instruction |= inst.operands[0].reg << 16;
-  inst.instruction |= inst.operands[1].reg;
-  inst.instruction |= inst.operands[2].reg << 12;
-}
-
-/* Insns like "foo W,X,Y,Z".
-    where W=MVAX[0:3] and X,Y,Z=MVFX[0:15].  */
-
-static void
-do_mav_quad (void)
-{
-  inst.instruction |= inst.operands[0].reg << 5;
-  inst.instruction |= inst.operands[1].reg << 12;
-  inst.instruction |= inst.operands[2].reg << 16;
-  inst.instruction |= inst.operands[3].reg;
-}
-
-/* cfmvsc32<cond> DSPSC,MVDX[15:0].  */
-static void
-do_mav_dspsc (void)
-{
-  inst.instruction |= inst.operands[1].reg << 12;
-}
-
-/* Maverick shift immediate instructions.
-   cfsh32<cond> MVFX[15:0],MVFX[15:0],Shift[6:0].
-   cfsh64<cond> MVDX[15:0],MVDX[15:0],Shift[6:0].  */
-
-static void
-do_mav_shift (void)
-{
-  int imm = inst.operands[2].imm;
-
-  inst.instruction |= inst.operands[0].reg << 12;
-  inst.instruction |= inst.operands[1].reg << 16;
-
-  /* Bits 0-3 of the insn should have bits 0-3 of the immediate.
-     Bits 5-7 of the insn should have bits 4-6 of the immediate.
-     Bit 4 should be 0.	 */
-  imm = (imm & 0xf) | ((imm & 0x70) << 1);
-
-  inst.instruction |= imm;
-}
-
-/* XScale instructions.	 Also sorted arithmetic before move.  */
-
-/* Xscale multiply-accumulate (argument parse)
-     MIAcc   acc0,Rm,Rs
-     MIAPHcc acc0,Rm,Rs
-     MIAxycc acc0,Rm,Rs.  */
-
-static void
-do_xsc_mia (void)
-{
-  inst.instruction |= inst.operands[1].reg;
-  inst.instruction |= inst.operands[2].reg << 12;
-}
-
-/* Xscale move-accumulator-register (argument parse)
-
-     MARcc   acc0,RdLo,RdHi.  */
-
-static void
-do_xsc_mar (void)
-{
-  inst.instruction |= inst.operands[1].reg << 12;
-  inst.instruction |= inst.operands[2].reg << 16;
-}
-
-/* Xscale move-register-accumulator (argument parse)
-
-     MRAcc   RdLo,RdHi,acc0.  */
-
-static void
-do_xsc_mra (void)
-{
-  constraint (inst.operands[0].reg == inst.operands[1].reg, BAD_OVERLAP);
-  inst.instruction |= inst.operands[0].reg << 12;
-  inst.instruction |= inst.operands[1].reg << 16;
-}
-
 /* Overall per-instruction processing.	*/
 
 /* We need to be able to fix up arbitrary expressions in some statements.
@@ -6060,7 +6058,6 @@
 
   return name;
 }
-
 
 /* Table of all register names defined by default.  The user can
    define additional names with .req.  Note that all register names
@@ -7572,7 +7569,6 @@
 #undef OPS6
 #undef do_0
 
-
 /* MD interface: bits in the object file.  */
 
 /* Turn an integer of n bytes (in val) into a stream of bytes appropriate
@@ -7768,7 +7764,6 @@
 
   return -1;
 }
-
 
 /* Code to deal with unwinding tables.	*/
 
@@ -8298,8 +8293,8 @@
   int op, new_inst;
   unsigned long negated, inverted;
 
-  negated = encode_immediate_arm (-value);
-  inverted = encode_immediate_arm (~value);
+  negated = encode_arm_immediate (-value);
+  inverted = encode_arm_immediate (~value);
 
   op = (*instruction >> DATA_OP_SHIFT) & 0xf;
   switch (op)
@@ -8426,7 +8421,7 @@
 	  break;
 	}
 
-      newimm = encode_immediate_arm (value);
+      newimm = encode_arm_immediate (value);
       temp = md_chars_to_number (buf, INSN_SIZE);
 
       /* If the instruction will fail, see if we can fix things up by
@@ -8449,7 +8444,7 @@
 	unsigned int highpart = 0;
 	unsigned int newinsn  = 0xe1a00000; /* nop.  */
 
-	newimm = encode_immediate_arm (value);
+	newimm = encode_arm_immediate (value);
 	temp = md_chars_to_number (buf, INSN_SIZE);
 
 	/* If the instruction will fail, see if we can fix things up by

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]