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 (5/69)


This introduces a less cumbersome, macro-based notation for the very
common operation of trying to parse something, and if that failed,
setting inst.error and returning.  Also, more redundant do_* functions
are collapsed together, and the i18n friendliness of some diagnostics
is improved.

zw

	* config/tc-arm.c (ERR_NO_ACCUM): Rename BAD_ACCUM.
	(my_get_expression): Set inst.error here ...
	(md_operand): ... not here.
	(accum0_required_here): Rename to xsc_reg_required_here.
	Avoid modifying input stream.
	(comma_or_fail, expression_or_fail, immediate_or_fail)
	(reg_or_fail, note_reg_or_fail): New convenience macros.
	(do_adr, do_adrl, do_arit, bfci_lsb_and_width, do_bfc, do_bfi)
	(do_bfx, do_branch, do_branch25, do_blx, do_cdp, do_clz, do_cmp)
	(do_co_reg, do_co_reg2c, do_ldrex, do_ldst, do_ldstt, do_ldstv4)
	(do_ldsttv4, do_lstc, do_mlas, do_mov, do_mov16, do_mrs, do_mul)
	(do_mull, do_pkh_core, do_pld, do_qadd, do_qadd16, do_rbit, do_rev)
	(do_rfe, do_sat, do_sat16, do_smla, do_smlal, do_smul, do_strex)
	(do_swap, do_sxtah, do_sxth, do_vfp_reg_from_sp, do_vfp_reg_from_ctrl)
	(vfp_sp_ldstm, vfp_dp_ldstm, do_fpa_ctrl, do_fpa_to_reg, do_xsc_mia)
	(do_xsc_mar, do_xsc_mra): Use new convenience macros.
	(do_ldst, do_ldstt, do_ldstv4, do_ldsttv4):
	Do not translate words in isolation from their sentences.
	(do_sat, do_sat16): Take char *, not char **, argument.
	Call end_of_line here.
	(do_ssat, do_usat, do_ssat16, do_usat16): Adjust to match.
	(do_cdp2, do_co_reg2, do_lstc2): Delete.
	(insns): Replace do_cdp2, do_co_reg2, and do_lstc2 with
	do_cdp, do_co_reg, and do_lstc respectively.

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 5)
+++ gas/config/tc-arm.c	(revision 6)
@@ -938,7 +938,7 @@
 #define BAD_ARGS 	_("bad arguments to instruction")
 #define BAD_PC 		_("r15 not allowed here")
 #define BAD_COND 	_("instruction is not conditional")
-#define ERR_NO_ACCUM	_("acc0 expected")
+#define BAD_ACCUM	_("acc0 expected")
 
 static struct hash_control * arm_ops_hsh   = NULL;
 static struct hash_control * arm_tops_hsh  = NULL;
@@ -1040,6 +1040,15 @@
   return comma ? SUCCESS : FAIL;
 }
 
+#define comma_or_fail(str)			\
+do {						\
+  if (skip_past_comma (str) == FAIL)		\
+    {						\
+      inst.error = BAD_ARGS;			\
+      return;					\
+    }						\
+ } while (0)
+
 /* Arithmetic expressions (possibly involving symbols).  */
 
 /* Return TRUE if anything in the expression is a bignum.  */
@@ -1081,6 +1090,8 @@
       /* We found a bad expression in md_operand().  */
       *str = input_line_pointer;
       input_line_pointer = save_in;
+      if (inst.error == NULL)
+	inst.error = _("bad expression");
       return 1;
     }
 
@@ -1091,7 +1102,7 @@
       && seg != bss_section
       && seg != undefined_section)
     {
-      inst.error = _("bad_segment");
+      inst.error = _("bad segment");
       *str = input_line_pointer;
       input_line_pointer = save_in;
       return 1;
@@ -1118,6 +1129,12 @@
   return 0;
 }
 
+#define expression_or_fail(exp, str)		\
+do {						\
+  if (my_get_expression (exp, str))		\
+    return;					\
+ } while (0)
+
 /* Turn a string in input_line_pointer into a floating point constant
    of type TYPE, and store the appropriate bytes in *LITP.  The number
    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
@@ -1281,11 +1298,7 @@
 md_operand (expressionS * expr)
 {
   if (in_my_get_expression)
-    {
-      expr->X_op = O_illegal;
-      if (inst.error == NULL)
-	inst.error = _("bad expression");
-    }
+    expr->X_op = O_illegal;
 }
 
 /* Immediate values.  */
@@ -1329,6 +1342,12 @@
   return SUCCESS;
 }
 
+#define immediate_or_fail(str, var, min, max, popt)			\
+do {									\
+  if (immediate_required_here (str, var, min, max, popt) == FAIL)	\
+    return;								\
+ } while (0)
+
 /* As above, but for use in directives, and does not provide
    range checking.  */
 
@@ -1515,7 +1534,18 @@
   return FAIL;
 }
 
+#define reg_or_fail(str, shift, no_pc)			\
+do {							\
+  if (reg_required_here (str, shift, no_pc) == FAIL)	\
+    return;						\
+ } while (0)
 
+#define note_reg_or_fail(var, str, shift, no_pc)		\
+do {								\
+  if ((var = reg_required_here (str, shift, no_pc)) == FAIL)	\
+    return;							\
+ } while (0)
+
 /* Parse and validate that a register is of the right form, this saves
    repeated checking of this information in many similar cases.
    Unlike the 32-bit case we do not insert the register into the opcode
@@ -1788,32 +1818,17 @@
   At that time this routine and its callers can be upgraded to suit.)  */
 
 static int
-accum0_required_here (char ** str)
+xsc_reg_required_here (char ** str)
 {
-  static char buff [128];	/* Note the address is taken.  Hence, static.  */
-  char * p = * str;
-  char   c;
-  int result = 0;		/* The accum number.  */
+  skip_whitespace (*str);
 
-  skip_whitespace (p);
-
-  *str = p;			/* Advance caller's string pointer too.  */
-  c = *p++;
-  while (ISALNUM (c))
-    c = *p++;
-
-  *--p = 0;			/* Aap nul into input buffer at non-alnum.  */
-
-  if (! ( streq (*str, "acc0") || streq (*str, "ACC0")))
+  if (strncasecmp (*str, "acc0", 4) != 0 || ISALNUM ((*str)[4]))
     {
-      sprintf (buff, _("acc0 expected, not '%.100s'"), *str);
-      inst.error = buff;
-      result = FAIL;
+      inst.error = BAD_ACCUM;
+      return FAIL;
     }
-
-  *p = c;			/* Unzap.  */
-  *str = p;			/* Caller's string pointer to after match.  */
-  return result;
+  *str += 4;
+  return 0;
 }
 
 /* Register lists.  */
@@ -5025,17 +5040,13 @@
 {
   /* This is a pseudo-op of the form "adr rd, label" to be converted
      into a relative address of the form "add rd, pc, #label-.-8".  */
+
   skip_whitespace (str);
+  reg_or_fail (&str, 12, FALSE);
+  comma_or_fail (&str);
+  expression_or_fail (&inst.reloc.exp, &str);
+  end_of_line (str);
 
-  if (reg_required_here (&str, 12, FALSE) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || my_get_expression (&inst.reloc.exp, &str))
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
   /* Frag hacking will turn this into a sub instruction if the offset turns
      out to be negative.  */
   inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
@@ -5043,8 +5054,6 @@
   inst.reloc.exp.X_add_number -= 8; /* PC relative adjust.  */
 #endif
   inst.reloc.pc_rel = 1;
-
-  end_of_line (str);
 }
 
 static void
@@ -5056,18 +5065,11 @@
      add rd, rd, #high(label-.-8)"  */
 
   skip_whitespace (str);
-
-  if (reg_required_here (&str, 12, FALSE) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || my_get_expression (&inst.reloc.exp, &str))
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-
-      return;
-    }
-
+  reg_or_fail (&str, 12, FALSE);
+  comma_or_fail (&str);
+  expression_or_fail (&inst.reloc.exp, &str);
   end_of_line (str);
+
   /* Frag hacking will turn this into a sub instruction if the offset turns
      out to be negative.  */
   inst.reloc.type              = BFD_RELOC_ARM_ADRL_IMMEDIATE;
@@ -5082,12 +5084,12 @@
 do_arit (char * str)
 {
   skip_whitespace (str);
+  reg_or_fail (&str, 12, FALSE);
+  comma_or_fail (&str);
+  reg_or_fail (&str, 16, FALSE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (&str, 12, FALSE) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 16, FALSE) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || data_op2 (&str) == FAIL)
+  if (data_op2 (&str) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -5102,17 +5104,10 @@
 {
   int lsb, width;
 
-  if (immediate_required_here (&str, &lsb, 0, 31, FALSE) == FAIL)
-    return;
-
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if (immediate_required_here (&str, &width, 1, 32, FALSE) == FAIL)
-    return;
-
+  comma_or_fail (&str);
+  immediate_or_fail (&str, &lsb, 0, 31, FALSE);
+  comma_or_fail (&str);
+  immediate_or_fail (&str, &width, 1, 32, FALSE);
   end_of_line (str);
 
   if (width + lsb > 32)
@@ -5129,16 +5124,8 @@
 static void
 do_bfc (char *str)
 {
-  /* Rd.  */
   skip_whitespace (str);
-  if (reg_required_here (&str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-
+  reg_or_fail (&str, 12, TRUE);
   bfci_lsb_and_width (str);
 }
 
@@ -5147,33 +5134,19 @@
 {
   /* Rd.  */
   skip_whitespace (str);
-  if (reg_required_here (&str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
   /* Rm.  Accept #0 in this position as an alternative syntax for bfc.  */
-  skip_whitespace (str);
-  if (is_immediate_prefix (*str))
+  if (reg_required_here (&str, 0, TRUE) == FAIL)
     {
-      int val;
-      if (immediate_required_here (&str, &val, 0, 0, FALSE) == FAIL)
+      int dummy;
+
+      inst.error = 0;
+      if (immediate_required_here (&str, &dummy, 0, 0, FALSE) == FAIL)
 	return;
       inst.instruction |= 0x0000000f;  /* Rm = PC -> bfc, not bfi.  */
     }
-  else
-    {
-      if (reg_required_here (&str, 0, TRUE) == FAIL)
-	return;
-    }
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
 
   bfci_lsb_and_width (str);
 }
@@ -5185,34 +5158,17 @@
 
   /* Rd.  */
   skip_whitespace (str);
-  if (reg_required_here (&str, 12, FALSE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, FALSE);
+  comma_or_fail (&str);
 
   /* Rm.  */
-  skip_whitespace (str);
-  if (reg_required_here (&str, 0, FALSE) == FAIL
-      || skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 0, FALSE);
+  comma_or_fail (&str);
 
-  if (immediate_required_here (&str, &lsb, 0, 31, FALSE) == FAIL)
-    return;
-
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if (immediate_required_here (&str, &width, 1, 32, FALSE) == FAIL)
-    return;
-
+  /* lsb, width. */
+  immediate_or_fail (&str, &lsb, 0, 31, FALSE);
+  comma_or_fail (&str);
+  immediate_or_fail (&str, &width, 1, 32, FALSE);
   end_of_line (str);
 
   if (width + lsb > 32)
@@ -5255,8 +5211,7 @@
 static void
 do_branch (char * str)
 {
-  if (my_get_expression (&inst.reloc.exp, &str))
-    return;
+  expression_or_fail (&inst.reloc.exp, &str);
 
 #ifdef OBJ_ELF
   {
@@ -5303,8 +5258,7 @@
 static void
 do_branch25 (char * str)
 {
-  if (my_get_expression (& inst.reloc.exp, & str))
-    return;
+  expression_or_fail (&inst.reloc.exp, &str);
 
 #ifdef OBJ_ELF
   {
@@ -5351,18 +5305,12 @@
   int reg;
 
   skip_whitespace (str);
+  note_reg_or_fail (reg, &str, 0, FALSE);
+  end_of_line (str);
 
-  if ((reg = reg_required_here (&str, 0, FALSE)) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-
   /* Note - it is not illegal to do a "bx pc".  Useless, but not illegal.  */
   if (reg == REG_PC)
     as_tsktsk (_("use of r15 in bx in ARM mode is not really useful"));
-
-  end_of_line (str);
 }
 
 /* ARM V5 branch-link-exchange instruction (argument parse)
@@ -5376,26 +5324,25 @@
 static void
 do_blx (char * str)
 {
-  char * mystr = str;
   int rm;
 
-  skip_whitespace (mystr);
-  rm = reg_required_here (& mystr, 0, FALSE);
+  skip_whitespace (str);
+  rm = reg_required_here (&str, 0, FALSE);
 
-  /* The above may set inst.error.  Ignore his opinion.  */
-  inst.error = 0;
-
   if (rm != FAIL)
     {
-      /* Arg is a register.
-	 Use the condition code our caller put in inst.instruction.
-	 Pass ourselves off as a BX with a funny opcode.  */
+      /* Arg is a register.  Use the condition code our caller put in
+	 inst.instruction, and zap the opcode.  */
       inst.instruction |= 0x012fff30;
-      do_bx (str);
+
+      /* It is not illegal to do "blx pc", just useless.  */
+      if (rm == REG_PC)
+	as_tsktsk (_("use of r15 in blx in ARM mode is not really useful"));
+      end_of_line (str);
     }
   else
     {
-      /* This must be is BLX <target address>, no condition allowed.  */
+      /* This must be BLX <target address>, no condition allowed.  */
       if (inst.instruction != COND_ALWAYS)
 	{
 	  inst.error = BAD_COND;
@@ -5418,135 +5365,49 @@
   int reg;
 
   skip_whitespace (str);
+  note_reg_or_fail (reg, &str, 0, FALSE);
+  end_of_line (str);
 
-  if ((reg = reg_required_here (&str, 0, FALSE)) == FAIL)
-    return;
-
   /* Note - it is not illegal to do a "bxj pc".  Useless, but not illegal.  */
   if (reg == REG_PC)
     as_tsktsk (_("use of r15 in bxj is not really useful"));
-
-  end_of_line (str);
 }
 
+/* Co-processor data operation:
+      CDP{cond} <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}
+      CDP2      <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>{, <opcode_2>}  */
 static void
 do_cdp (char * str)
 {
-  /* Co-processor data operation.
-     Format: CDP{cond} CP#,<expr>,CRd,CRn,CRm{,<expr>}  */
   skip_whitespace (str);
 
   if (co_proc_number (&str) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+    return;
 
-  if (skip_past_comma (&str) == FAIL
-      || cp_opc_expr (&str, 20,4) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL
-      || cp_reg_required_here (&str, 12) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  if (cp_opc_expr (&str, 20, 4) == FAIL)
+    return;
 
-  if (skip_past_comma (&str) == FAIL
-      || cp_reg_required_here (&str, 16) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL
-      || cp_reg_required_here (&str, 0) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  if (cp_reg_required_here (&str, 12) == FAIL)
+    return;
 
-  if (skip_past_comma (&str) == SUCCESS)
-    {
-      if (cp_opc_expr (&str, 5, 3) == FAIL)
-	{
-	  if (!inst.error)
-	    inst.error = BAD_ARGS;
-	  return;
-	}
-    }
+  comma_or_fail (&str);
 
-  end_of_line (str);
-}
+  if (cp_reg_required_here (&str, 16) == FAIL)
+    return;
 
-/* ARM V5 (argument parse)
-     CDP2 <coproc>, <opcode_1>, <CRd>, <CRn>, <CRm>, <opcode_2>
-     Instruction is not conditional, and has 0xf in the condition field.
-     Otherwise, it's the same as CDP.  */
+  comma_or_fail (&str);
+  
+  if (cp_reg_required_here (&str, 0) == FAIL)
+    return;
 
-static void
-do_cdp2 (char * str)
-{
-  skip_whitespace (str);
-
-  if (co_proc_number (& str) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
+  if (skip_past_comma (&str) == SUCCESS)
+    if (cp_opc_expr (&str, 5, 3) == FAIL)
       return;
-    }
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_opc_expr (& str, 20,4) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 12) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 16) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 0) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (skip_past_comma (& str) == SUCCESS)
-    {
-      if (cp_opc_expr (& str, 5, 3) == FAIL)
-	{
-	  if (!inst.error)
-	    inst.error = BAD_ARGS;
-	  return;
-	}
-    }
-
   end_of_line (str);
 }
 
@@ -5560,16 +5421,9 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (& str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if (reg_required_here (& str, 0, TRUE) == FAIL)
-    return;
-
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
+  reg_or_fail (&str, 0, TRUE);
   end_of_line (str);
 }
 
@@ -5578,11 +5432,10 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 16, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 16, FALSE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL
-      || data_op2 (&str) == FAIL)
+  if (data_op2 (&str) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -5592,189 +5445,85 @@
   end_of_line (str);
 }
 
+/* Transfer between coprocessor and ARM registers.
+   MRC{cond} <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>{, <opcode_2>}
+   MRC2
+   MCR{cond}
+   MCR2
+
+   No special properties.  */
+
 static void
 do_co_reg (char * str)
 {
-  /* Co-processor register transfer.
-     Format: <MCR|MRC>{cond} CP#,<expr1>,Rd,CRn,CRm{,<expr2>}  */
-
   skip_whitespace (str);
 
   if (co_proc_number (&str) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+    return;
 
-  if (skip_past_comma (&str) == FAIL
-      || cp_opc_expr (&str, 21, 3) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  comma_or_fail (&str);
+  
+  if (cp_opc_expr (&str, 21, 3) == FAIL)
+    return;
 
-  if (skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 12, FALSE) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL
-      || cp_reg_required_here (&str, 16) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, FALSE);
 
-  if (skip_past_comma (&str) == FAIL
-      || cp_reg_required_here (&str, 0) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == SUCCESS)
-    {
-      if (cp_opc_expr (&str, 5, 3) == FAIL)
-	{
-	  if (!inst.error)
-	    inst.error = BAD_ARGS;
-	  return;
-	}
-    }
+  if (cp_reg_required_here (&str, 16) == FAIL)
+    return;
 
-  end_of_line (str);
-}
+  comma_or_fail (&str);
 
-/* ARM V5 (argument parse)
-     MCR2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
-     MRC2 <coproc>, <opcode_1>, <Rd>, <CRn>, <CRm>, <opcode_2>
-     Instruction is not conditional, and has 0xf in the condition field.
-     Otherwise, it's the same as MCR/MRC.  */
+  if (cp_reg_required_here (&str, 0) == FAIL)
+    return;
 
-static void
-do_co_reg2 (char * str)
-{
-  skip_whitespace (str);
-
-  if (co_proc_number (& str) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
+  if (skip_past_comma (&str) == SUCCESS)
+    if (cp_opc_expr (&str, 5, 3) == FAIL)
       return;
-    }
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_opc_expr (& str, 21, 3) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (skip_past_comma (& str) == FAIL
-      || reg_required_here (& str, 12, FALSE) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 16) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 0) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (skip_past_comma (& str) == SUCCESS)
-    {
-      if (cp_opc_expr (& str, 5, 3) == FAIL)
-	{
-	  if (!inst.error)
-	    inst.error = BAD_ARGS;
-	  return;
-	}
-    }
-
   end_of_line (str);
 }
 
-/* ARM V5E (el Segundo)
-   MCRRcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
-   MRRCcc <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
+/* Transfer between coprocessor register and pair of ARM registers.
+   MCRR{cond} <coproc>, <opcode>, <Rd>, <Rn>, <CRm>.
+   MCRR2
+   MRRC{cond}
+   MRRC2
 
-   These are equivalent to the XScale instructions MAR and MRA,
-   respectively, when coproc == 0, opcode == 0, and CRm == 0.
+   Two XScale instructions are special cases of these:
 
+     MAR{cond} acc0, <RdLo>, <RdHi> == MCRR{cond} p0, #0, <RdLo>, <RdHi>, c0
+     MRA{cond} acc0, <RdLo>, <RdHi> == MRRC{cond} p0, #0, <RdLo>, <RdHi>, c0
+
    Result unpredicatable if Rd or Rn is R15.  */
 
 static void
 do_co_reg2c (char * str)
 {
-  int rd, rn;
-
   skip_whitespace (str);
 
   if (co_proc_number (& str) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+    return;
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_opc_expr (& str, 4, 4) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  comma_or_fail (&str);
 
-  if (skip_past_comma (& str) == FAIL
-      || (rd = reg_required_here (& str, 12, FALSE)) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  if (cp_opc_expr (&str, 4, 4) == FAIL)
+    return;
 
-  if (skip_past_comma (& str) == FAIL
-      || (rn = reg_required_here (& str, 16, FALSE)) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  comma_or_fail (&str);
+  reg_or_fail (&str, 12, TRUE);
 
-  /* Unpredictable result if rd or rn is R15.  */
-  if (rd == REG_PC || rn == REG_PC)
-    as_tsktsk
-      (_("Warning: instruction unpredictable when using r15"));
+  comma_or_fail (&str);
+  reg_or_fail (&str, 16, TRUE);
 
-  if (skip_past_comma (& str) == FAIL
-      || cp_reg_required_here (& str, 0) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  comma_or_fail (&str);
 
+  if (cp_reg_required_here (& str, 0) == FAIL)
+    return;
+
   end_of_line (str);
 }
 
@@ -5809,8 +5558,7 @@
 
   skip_whitespace (str);
 
-  if ((base_reg = reg_required_here (&str, 16, TRUE)) == FAIL)
-    return;
+  note_reg_or_fail (base_reg, &str, 16, TRUE);
 
   skip_whitespace (str);
 
@@ -5820,14 +5568,11 @@
       str++;
     }
 
-  if (skip_past_comma (&str) == FAIL
-      || (range = reg_list (&str)) == FAIL)
-    {
-      if (! inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  comma_or_fail (&str);
 
+  if ((range = reg_list (&str)) == FAIL)
+    return;
+
   if (*str == '^')
     {
       str++;
@@ -5877,14 +5622,11 @@
 
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (& str, 12, FALSE)) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (rd, &str, 12, FALSE);
 
-  if (skip_past_comma (& str) == FAIL
-      || (rn = ld_mode_required_here (& str)) == FAIL)
+  comma_or_fail (&str);
+
+  if ((rn = ld_mode_required_here (& str)) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -5924,7 +5666,7 @@
 }
 
 /* ARM V6 Load Register Exclusive instruction (argument parse).
-   LDREX{,B,D,H}{<cond>} <Rd, [<Rn>]
+   LDREX{,B,D,H}{<cond>} <Rd>, [<Rn>]
    Condition defaults to COND_ALWAYS.
    Error if Rd or Rn are R15.
    See ARMARMv6 A4.1.27: LDREX.  */
@@ -5935,13 +5677,8 @@
   skip_whitespace (str);
 
   /* Parse Rd.  */
-  if (reg_required_here (&str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
   /* Skip past '['.  */
   skip_whitespace (str);
@@ -5952,10 +5689,7 @@
     }
   str++;
 
-  /* Parse Rn.  */
-  skip_whitespace (str);
-  if (reg_required_here (&str, 16, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 16, TRUE);
 
   /* Skip past ']'.  */
   skip_whitespace (str);
@@ -5977,19 +5711,9 @@
 
   skip_whitespace (str);
 
-  if ((conflict_reg = reg_required_here (&str, 12, FALSE)) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (conflict_reg, &str, 12, FALSE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = _("address expected");
-      return;
-    }
-
   if (*str == '[')
     {
       int reg;
@@ -5998,8 +5722,7 @@
 
       skip_whitespace (str);
 
-      if ((reg = reg_required_here (&str, 16, FALSE)) == FAIL)
-	return;
+      note_reg_or_fail (reg, &str, 16, FALSE);
 
       /* Conflicts can occur on stores as well as loads.  */
       conflict_reg = (conflict_reg == reg);
@@ -6016,9 +5739,9 @@
 	      if (ldst_extend (&str) == FAIL)
 		return;
 	      if (conflict_reg)
-		as_warn (_("%s register same as write-back base"),
-			 ((inst.instruction & LOAD_BIT)
-			  ? _("destination") : _("source")));
+		as_warn ((inst.instruction & LOAD_BIT)
+			  ? _("destination register same as write-back base")
+			  : _("source register same as write-back base"));
 	    }
 	  else
 	    {
@@ -6028,9 +5751,9 @@
 	      if (*str == '!')
 		{
 		  if (conflict_reg)
-		    as_warn (_("%s register same as write-back base"),
-			     ((inst.instruction & LOAD_BIT)
-			      ? _("destination") : _("source")));
+		    as_warn ((inst.instruction & LOAD_BIT)
+			     ? _("destination register same as write-back base")
+			     : _("source register same as write-back base"));
 		  str++;
 		  inst.instruction |= WRITE_BACK;
 		}
@@ -6042,11 +5765,7 @@
       else
 	{
 	  /* [Rn,...]  */
-	  if (skip_past_comma (&str) == FAIL)
-	    {
-	      inst.error = _("pre-indexed expression expected");
-	      return;
-	    }
+	  comma_or_fail (&str);
 
 	  pre_inc = 1;
 	  if (ldst_extend (&str) == FAIL)
@@ -6065,9 +5784,9 @@
 	  if (*str == '!')
 	    {
 	      if (conflict_reg)
-		as_warn (_("%s register same as write-back base"),
-			 ((inst.instruction & LOAD_BIT)
-			  ? _("destination") : _("source")));
+		as_warn ((inst.instruction & LOAD_BIT)
+			  ? _("destination register same as write-back base")
+			  : _("source register same as write-back base"));
 	      str++;
 	      inst.instruction |= WRITE_BACK;
 	    }
@@ -6085,10 +5804,8 @@
       str++;
 
       skip_whitespace (str);
+      expression_or_fail (&inst.reloc.exp, &str);
 
-      if (my_get_expression (&inst.reloc.exp, &str))
-	return;
-
       if (inst.reloc.exp.X_op != O_constant
 	  && inst.reloc.exp.X_op != O_symbol)
 	{
@@ -6141,8 +5858,7 @@
     }
   else
     {
-      if (my_get_expression (&inst.reloc.exp, &str))
-	return;
+      expression_or_fail (&inst.reloc.exp, &str);
 
       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
 #ifndef TE_WINCE
@@ -6164,20 +5880,9 @@
   int conflict_reg;
 
   skip_whitespace (str);
+  note_reg_or_fail (conflict_reg, &str, 12, FALSE);
+  comma_or_fail (&str);
 
-  if ((conflict_reg = reg_required_here (& str, 12, FALSE)) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = _("address expected");
-      return;
-    }
-
   if (*str == '[')
     {
       int reg;
@@ -6185,16 +5890,14 @@
       str++;
 
       skip_whitespace (str);
+      note_reg_or_fail (reg, &str, 16, FALSE);
 
-      if ((reg = reg_required_here (&str, 16, FALSE)) == FAIL)
-	return;
-
       /* ldrt/strt always use post-indexed addressing, so if the base is
 	 the same as Rd, we warn.  */
       if (conflict_reg == reg)
-	as_warn (_("%s register same as write-back base"),
-		 ((inst.instruction & LOAD_BIT)
-		  ? _("destination") : _("source")));
+	as_warn ((inst.instruction & LOAD_BIT)
+		 ? _("destination register same as write-back base")
+		 : _("source register same as write-back base"));
 
       skip_whitespace (str);
 
@@ -6245,20 +5948,9 @@
   int value;
 
   skip_whitespace (str);
+  note_reg_or_fail (conflict_reg, &str, 12, FALSE);
+  comma_or_fail (&str);
 
-  if ((conflict_reg = reg_required_here (& str, 12, FALSE)) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = _("address expected");
-      return;
-    }
-
   if (*str == '[')
     {
       int reg;
@@ -6267,8 +5959,7 @@
 
       skip_whitespace (str);
 
-      if ((reg = reg_required_here (&str, 16, FALSE)) == FAIL)
-	return;
+      note_reg_or_fail (reg, &str, 16, FALSE);
 
       /* Conflicts can occur on stores as well as loads.  */
       conflict_reg = (conflict_reg == reg);
@@ -6285,9 +5976,9 @@
 	      if (ldst_extend_v4 (&str) == FAIL)
 		return;
 	      if (conflict_reg)
-		as_warn (_("%s register same as write-back base"),
-			 ((inst.instruction & LOAD_BIT)
-			  ? _("destination") : _("source")));
+		as_warn ((inst.instruction & LOAD_BIT)
+			  ? _("destination register same as write-back base")
+			  : _("source register same as write-back base"));
 	    }
 	  else
 	    {
@@ -6299,9 +5990,9 @@
 	      if (*str == '!')
 		{
 		  if (conflict_reg)
-		    as_warn (_("%s register same as write-back base"),
-			     ((inst.instruction & LOAD_BIT)
-			      ? _("destination") : _("source")));
+		    as_warn ((inst.instruction & LOAD_BIT)
+			     ? _("destination register same as write-back base")
+			     : _("source register same as write-back base"));
 		  str++;
 		  inst.instruction |= WRITE_BACK;
 		}
@@ -6336,9 +6027,9 @@
 	  if (*str == '!')
 	    {
 	      if (conflict_reg)
-		as_warn (_("%s register same as write-back base"),
-			 ((inst.instruction & LOAD_BIT)
-			  ? _("destination") : _("source")));
+		as_warn ((inst.instruction & LOAD_BIT)
+			  ? _("destination register same as write-back base")
+			  : _("source register same as write-back base"));
 	      str++;
 	      inst.instruction |= WRITE_BACK;
 	    }
@@ -6437,19 +6128,9 @@
 
   skip_whitespace (str);
 
-  if ((conflict_reg = reg_required_here (& str, 12, FALSE)) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (conflict_reg, &str, 12, FALSE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = _("address expected");
-      return;
-    }
-
   if (*str == '[')
     {
       int reg;
@@ -6457,19 +6138,16 @@
       str++;
 
       skip_whitespace (str);
+      note_reg_or_fail (reg, &str, 16, FALSE);
 
-      if ((reg = reg_required_here (&str, 16, FALSE)) == FAIL)
-	return;
-
       /* ldrt/strt always use post-indexed addressing, so if the base is
 	 the same as Rd, we warn.  */
-      if (conflict_reg == reg)
-	as_warn (_("%s register same as write-back base"),
-		 ((inst.instruction & LOAD_BIT)
-		  ? _("destination") : _("source")));
+      if (reg == conflict_reg)
+	as_warn ((inst.instruction & LOAD_BIT)
+		 ? _("destination register same as write-back base")
+		 : _("source register same as write-back base"));
 
       skip_whitespace (str);
-
       if (*str == ']')
 	{
 	  str ++;
@@ -6516,61 +6194,19 @@
   skip_whitespace (str);
 
   if (co_proc_number (&str) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+    return;
 
-  if (skip_past_comma (&str) == FAIL
-      || cp_reg_required_here (&str, 12) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL
-      || cp_address_required_here (&str, CP_WB_OK) == FAIL)
-    {
-      if (! inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  if (cp_reg_required_here (&str, 12) == FAIL)
+    return;
 
-  end_of_line (str);
-}
+  comma_or_fail (&str);
 
-/* ARM V5 (argument parse)
-     LDC2{L} <coproc>, <CRd>, <addressing mode>
-     STC2{L} <coproc>, <CRd>, <addressing mode>
-     Instruction is not conditional, and has 0xf in the condition field.
-     Otherwise, it's the same as LDC/STC.  */
+  if (cp_address_required_here (&str, CP_WB_OK) == FAIL)
+    return;
 
-static void
-do_lstc2 (char * str)
-{
-  skip_whitespace (str);
-
-  if (co_proc_number (& str) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-    }
-  else if (skip_past_comma (& str) == FAIL
-	   || cp_reg_required_here (& str, 12) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-    }
-  else if (skip_past_comma (& str) == FAIL
-	   || cp_address_required_here (&str, CP_WB_OK) == FAIL)
-    {
-      if (! inst.error)
-	inst.error = BAD_ARGS;
-    }
-  else
-    end_of_line (str);
+  end_of_line (str);
 }
 
 static void
@@ -6581,41 +6217,22 @@
   /* Only one format "rd, rm, rs, rn".  */
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (&str, 16, TRUE)) == FAIL)
-    return;
+  note_reg_or_fail (rd, &str, 16, TRUE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if ((rm = reg_required_here (&str, 0, TRUE)) == FAIL)
-    return;
+  note_reg_or_fail (rm, &str, 0, TRUE);
+  comma_or_fail (&str);
 
+  reg_or_fail (&str, 8, TRUE);
+  comma_or_fail (&str);
+
+  reg_or_fail (&str, 12, TRUE);
+  end_of_line (str);
+  
   /* This restriction does not apply to mls (nor to mla in v6, but
      that's hard to detect at present).  */
   if (rm == rd && !is_mls)
     as_tsktsk (_("rd and rm should be different in mla"));
-
-  /* Rs.  */
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if ((rm = reg_required_here (&str, 8, TRUE)) == FAIL)
-    return;
-
-  /* Rn.  */
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if ((rm = reg_required_here (&str, 12, TRUE)) == FAIL)
-    return;
-
-  end_of_line (str);
 }
 
 static void
@@ -6635,11 +6252,10 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, FALSE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL
-      || data_op2 (&str) == FAIL)
+  if (data_op2 (&str) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -6656,20 +6272,10 @@
 {
   int val;
 
-  /* Rd.  */
   skip_whitespace (str);
-  if (reg_required_here (&str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-
-  /* Imm16.  */
-  if (immediate_required_here (&str, &val, 0, 65535, FALSE) == FAIL)
-    return;
-
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
+  immediate_or_fail (&str, &val, 0, 65535, FALSE);
   end_of_line (str);
 
   /* The value is in two pieces: 0:11, 16:19.  */
@@ -6680,42 +6286,37 @@
 static void
 do_mrs (char * str)
 {
-  int skip = 0;
-
   /* Only one syntax.  */
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, FALSE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL)
+  skip_whitespace (str);
+
+  /* Lower case accepted for backwards compatibility.  */
+  if (*str == 'c' || *str == 'C')
+    ; /* SPSR bit is already clear.  */
+  else if (*str == 's' || *str == 'S')
+    inst.instruction |= SPSR_BIT;
+  else
     {
-      inst.error = _("comma expected after register name");
+      inst.error = _("'CPSR' or 'SPSR' expected");
       return;
     }
+  str++;
 
-  skip_whitespace (str);
-
-  if (   streq (str, "CPSR")
-      || streq (str, "SPSR")
-	 /* Lower case versions for backwards compatibility.  */
-      || streq (str, "cpsr")
-      || streq (str, "spsr"))
-    skip = 4;
-
-  /* This is for backwards compatibility with older toolchains.  */
-  else if (   streq (str, "cpsr_all")
-	   || streq (str, "spsr_all"))
-    skip = 8;
-  else
+  if (strncasecmp (str, "PSR", 3) != 0)
     {
-      inst.error = _("CPSR or SPSR expected");
+      inst.error = _("'CPSR' or 'SPSR' expected");
       return;
     }
+  str += 3;
 
-  if (* str == 's' || * str == 'S')
-    inst.instruction |= SPSR_BIT;
-  str += skip;
+  /* For backward compatibility, allow a trailing "_all"
+     (lowercase only).  */
+  if (strncmp (str, "_all", 4) == 0)
+    str += 4;
 
   end_of_line (str);
 }
@@ -6729,18 +6330,14 @@
 {
   skip_whitespace (str);
 
-  if (psr_required_here (& str) == FAIL)
+  if (psr_required_here (&str) == FAIL)
     return;
 
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = _("comma missing after psr flags");
-      return;
-    }
+  comma_or_fail (&str);
 
   skip_whitespace (str);
 
-  if (reg_required_here (& str, 0, FALSE) != FAIL)
+  if (reg_required_here (&str, 0, FALSE) != FAIL)
     {
       inst.error = NULL;
       end_of_line (str);
@@ -6796,31 +6393,17 @@
   /* Only one format "rd, rm, rs".  */
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (&str, 16, TRUE)) == FAIL)
-    return;
+  note_reg_or_fail (rd, &str, 16, TRUE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (rm, &str, 0, TRUE);
+  comma_or_fail (&str);
 
-  if ((rm = reg_required_here (&str, 0, TRUE)) == FAIL)
-    return;
+  reg_required_here (&str, 8, TRUE);
+  end_of_line (str);
 
   if (rm == rd)
     as_tsktsk (_("rd and rm should be different in mul"));
-
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (reg_required_here (&str, 8, TRUE) == FAIL)
-    return;
-
-  end_of_line (str);
 }
 
 /* Long Multiply Parser
@@ -6837,41 +6420,21 @@
   /* Only one format "rdlo, rdhi, rm, rs".  */
   skip_whitespace (str);
 
-  if ((rdlo = reg_required_here (&str, 12, TRUE)) == FAIL)
-    return;
+  note_reg_or_fail (rdlo, &str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-
-  if ((rdhi = reg_required_here (&str, 16, TRUE)) == FAIL)
-    return;
-
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (rdhi, &str, 16, TRUE);
+  comma_or_fail (&str);
     
-  if ((rm = reg_required_here (&str, 0, TRUE)) == FAIL)
-    return;
+  note_reg_or_fail (rm, &str, 0, TRUE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 8, TRUE);
+  end_of_line (str);
 
-  if (reg_required_here (&str, 8, TRUE) == FAIL)
-    return;
-
   /* rdhi, rdlo and rm must all be different.  */
   if (rdlo == rdhi || rdlo == rm || rdhi == rm)
     as_tsktsk (_("rdhi, rdlo and rm must all be different"));
-
-  end_of_line (str);
 }
 
 static void
@@ -6908,28 +6471,15 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (rn, &str, 16, TRUE);
+  comma_or_fail (&str);
 
-  if ((rn = reg_required_here (&str, 16, TRUE)) == FAIL)
-    return;
+  note_reg_or_fail (rm, &str, 0, TRUE);
 
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
 
-  if ((rm = reg_required_here (&str, 0, TRUE)) == FAIL)
-    return;
-
-
   /* Check for optional shift immediate constant.  */
   if (skip_past_comma (&str) == FAIL)
     {
@@ -6989,8 +6539,7 @@
   ++str;
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (& str, 16, FALSE)) == FAIL)
-    return;
+  note_reg_or_fail (rd, &str, 16, FALSE);
 
   skip_whitespace (str);
 
@@ -7058,24 +6607,13 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (&str, 0, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if (reg_required_here (&str, 16, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 0, TRUE);
+  comma_or_fail (&str);
 
+  reg_or_fail (&str, 16, TRUE);
   end_of_line (str);
 }
 
@@ -7089,24 +6627,13 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (&str, 16, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if (reg_required_here (&str, 0, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 16, TRUE);
+  comma_or_fail (&str);
 
+  reg_or_fail (&str, 0, TRUE);
   end_of_line (str);
 }
 
@@ -7114,17 +6641,10 @@
 do_rbit (char *str)
 {
   skip_whitespace (str);
-  if (reg_required_here (&str, 12, FALSE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, FALSE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (&str, 0, FALSE) == FAIL)
-    return;
-
+  reg_or_fail (&str, 0, FALSE);
   end_of_line (str);
 }
 
@@ -7138,17 +6658,11 @@
 do_rev (char * str)
 {
   skip_whitespace (str);
-  if (reg_required_here (&str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
 
-  if (reg_required_here (&str, 0, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
+  reg_or_fail (&str, 0, TRUE);
   end_of_line (str);
 }
 
@@ -7163,8 +6677,7 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 16, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 16, TRUE);
 
   skip_whitespace (str);
 
@@ -7177,38 +6690,28 @@
 }
 
 static void
-do_sat (char ** str, int bias)
+do_sat (char *str, int bias)
 {
   int val;
 
-  skip_whitespace (*str);
+  skip_whitespace (str);
 
   /* Parse <Rd>, field.  */
-  if (reg_required_here (str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
   /* Parse #<immed>,  field.  */
-  if (immediate_required_here (str, &val, 0 - bias, 31 - bias, FALSE) == FAIL)
-    return;
-
+  immediate_or_fail (&str, &val, 0 - bias, 31 - bias, FALSE);
+  comma_or_fail (&str);
   inst.instruction |= (val + bias) << 16;
-  if (skip_past_comma (str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
 
   /* Parse <Rm> field.  */
-  if (reg_required_here (str, 0, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 0, TRUE);
 
-  if (skip_past_comma (str) == SUCCESS)
-    decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
+  if (skip_past_comma (&str) == SUCCESS)
+    decode_shift (&str, SHIFT_LSL_OR_ASR_IMMEDIATE);
+
+  end_of_line (str);
 }
 
 /* ARM V6 ssat (argument parse).  */
@@ -7216,8 +6719,7 @@
 static void
 do_ssat (char * str)
 {
-  do_sat (&str, /*bias=*/-1);
-  end_of_line (str);
+  do_sat (str, /*bias=*/-1);
 }
 
 /* ARM V6 usat (argument parse).  */
@@ -7225,40 +6727,28 @@
 static void
 do_usat (char * str)
 {
-  do_sat (&str, /*bias=*/0);
-  end_of_line (str);
+  do_sat (str, /*bias=*/0);
 }
 
 static void
-do_sat16 (char ** str, int bias)
+do_sat16 (char *str, int bias)
 {
   int val;
 
-  skip_whitespace (*str);
+  skip_whitespace (str);
 
   /* Parse the <Rd> field.  */
-  if (reg_required_here (str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
   /* Parse #<immed>, field.  */
-  if (immediate_required_here (str, &val, 0 - bias, 15 - bias, FALSE) == FAIL)
-    return;
-
+  immediate_or_fail (&str, &val, 0 - bias, 15 - bias, FALSE);
+  comma_or_fail (&str);
   inst.instruction |= (val + bias) << 16;
-  if (skip_past_comma (str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
 
   /* Parse <Rm> field.  */
-  if (reg_required_here (str, 0, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 0, TRUE);
+  end_of_line (str);
 }
 
 /* ARM V6 ssat16 (argument parse).  */
@@ -7266,15 +6756,13 @@
 static void
 do_ssat16 (char * str)
 {
-  do_sat16 (&str, /*bias=*/-1);
-  end_of_line (str);
+  do_sat16 (str, /*bias=*/-1);
 }
 
 static void
 do_usat16 (char * str)
 {
-  do_sat16 (&str, /*bias=*/0);
-  end_of_line (str);
+  do_sat16 (str, /*bias=*/0);
 }
 
 /* ARM V6 SETEND (argument parse).  Sets the E bit in the CPSR while
@@ -7334,32 +6822,16 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (& str, 16, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 16, TRUE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (& str, 0, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 0, TRUE);
+  comma_or_fail (&str);
   
-  if (reg_required_here (& str, 8, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 8, TRUE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (& str, 12, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, TRUE);
 
   end_of_line (str);
 }
@@ -7376,32 +6848,16 @@
 
   skip_whitespace (str);
 
-  if ((rdlo = reg_required_here (& str, 12, TRUE)) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (rdlo, &str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if ((rdhi = reg_required_here (& str, 16, TRUE)) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (rdhi, &str, 16, TRUE);
+  comma_or_fail (&str);
   
-  if (reg_required_here (& str, 0, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 0, TRUE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (& str, 8, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 8, TRUE);
 
   if (rdlo == rdhi)
     as_tsktsk (_("rdhi and rdlo must be different"));
@@ -7417,24 +6873,13 @@
 do_smul (char * str)
 {
   skip_whitespace (str);
-  if (reg_required_here (& str, 16, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 16, TRUE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (& str, 0, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 0, TRUE);
+  comma_or_fail (&str);
   
-  if (reg_required_here (& str, 8, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 8, TRUE);
 
   end_of_line (str);
 }
@@ -7469,21 +6914,11 @@
 
   /* Parse Rd, Rm,.  */
   skip_whitespace (str);
-  if ((rd = reg_required_here (& str, 12, TRUE)) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (rd, &str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if ((rm = reg_required_here (& str, 0, TRUE)) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (rm, &str, 0, TRUE);
+  comma_or_fail (&str);
     
   if (rd == rm)
     {
@@ -7501,8 +6936,7 @@
   skip_whitespace (str);
 
   /* Parse Rn.  */
-  if ((rn = reg_required_here (& str, 16, TRUE)) == FAIL)
-    return;
+  note_reg_or_fail (rn, &str, 16, TRUE);
   if (rd == rn)
     {
       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
@@ -7528,18 +6962,11 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if (skip_past_comma (&str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 0, TRUE);
 
-  if (reg_required_here (&str, 0, TRUE) == FAIL)
-    return;
-
   if (skip_past_comma (&str) == FAIL
       || *str++ != '[')
     {
@@ -7549,8 +6976,7 @@
 
   skip_whitespace (str);
 
-  if ((reg = reg_required_here (&str, 16, TRUE)) == FAIL)
-    return;
+  note_reg_or_fail (reg, &str, 16, TRUE);
 
   skip_whitespace (str);
 
@@ -7581,24 +7007,13 @@
   int rotation_twenty_four_mask = 0x00000c00;
 
   skip_whitespace (str);
-  if (reg_required_here (& str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (& str, 16, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 16, TRUE);
+  comma_or_fail (&str);
   
-  if (reg_required_here (& str, 0, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 0, TRUE);
 
   /* Zero out the rotation field.  */
   inst.instruction &= rotation_clear_mask;
@@ -7667,16 +7082,10 @@
   int rotation_twenty_four_mask = 0x00000c00;
 
   skip_whitespace (str);
-  if (reg_required_here (& str, 12, TRUE) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (& str, 0, TRUE) == FAIL)
-    return;
+  reg_or_fail (&str, 0, TRUE);
 
   /* Zero out the rotation field.  */
   inst.instruction &= rotation_clear_mask;
@@ -8891,8 +8300,7 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, FALSE);
 
   if (skip_past_comma (&str) == FAIL
       || vfp_sp_reg_required_here (&str, VFP_REG_Sn) == FAIL)
@@ -8985,8 +8393,7 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, FALSE);
 
   if (skip_past_comma (&str) == FAIL
       || vfp_dp_reg_required_here (&str, VFP_REG_Dn) == FAIL)
@@ -9004,8 +8411,7 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, FALSE);
 
   if (skip_past_comma (&str) == FAIL
       || reg_required_here (&str, 16, FALSE) == FAIL
@@ -9065,8 +8471,7 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, FALSE);
 
   if (skip_past_comma (&str) == FAIL
       || vfp_psr_required_here (&str) == FAIL)
@@ -9153,8 +8558,7 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 16, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 16, FALSE);
 
   skip_whitespace (str);
 
@@ -9190,8 +8594,7 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 16, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 16, FALSE);
 
   skip_whitespace (str);
 
@@ -9269,8 +8672,7 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, FALSE);
 
   end_of_line (str);
 }
@@ -9380,8 +8782,7 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12, FALSE) == FAIL)
-    return;
+  reg_or_fail (&str, 12, FALSE);
 
   if (skip_past_comma (&str) == FAIL
       || fp_reg_required_here (&str, 0) == FAIL)
@@ -10445,27 +9846,14 @@
 static void
 do_xsc_mia (char * str)
 {
-  if (accum0_required_here (& str) == FAIL)
-    inst.error = ERR_NO_ACCUM;
-
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (reg_required_here (& str, 0, TRUE) == FAIL)
+  if (xsc_reg_required_here (&str) == FAIL)
     return;
+  comma_or_fail (&str);
 
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 0, TRUE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (& str, 12, TRUE) == FAIL)
-    return;
-
+  reg_or_fail (&str, 12, TRUE);
   end_of_line (str);
 }
 
@@ -10476,27 +9864,14 @@
 static void
 do_xsc_mar (char * str)
 {
-  if (accum0_required_here (& str) == FAIL)
-    inst.error = ERR_NO_ACCUM;
-
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (reg_required_here (& str, 12, TRUE) == FAIL)
+  if (xsc_reg_required_here (& str) == FAIL)
     return;
+  comma_or_fail (&str);
 
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  reg_or_fail (&str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if (reg_required_here (& str, 16, TRUE) == FAIL)
-    return;
-
+  reg_or_fail (&str, 16, TRUE);
   end_of_line (str);
 }
 
@@ -10512,36 +9887,19 @@
 
   skip_whitespace (str);
 
-  if ((rdlo = reg_required_here (& str, 12, TRUE)) == FAIL)
-    return;
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  note_reg_or_fail (rdlo, &str, 12, TRUE);
+  comma_or_fail (&str);
 
-  if ((rdhi = reg_required_here (& str, 16, TRUE)) == FAIL)
+  note_reg_or_fail (rdhi, &str, 16, TRUE);
+  comma_or_fail (&str);
+
+  if (xsc_reg_required_here (& str) == FAIL)
     return;
+  end_of_line (str);
 
-  if (skip_past_comma (& str) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if (accum0_required_here (& str) == FAIL)
-    {
-      inst.error = ERR_NO_ACCUM;
-      return;
-    }
-
   /* inst.instruction has now been zapped with both rdlo and rdhi.  */
   if (rdlo == rdhi)
-    {
-      inst.error = BAD_ARGS;	/* Undefined result if 2 writes to same reg.  */
-      return;
-    }
-
-  end_of_line (str);
+    inst.error = BAD_ARGS;	/* Undefined result if 2 writes to same reg.  */
 }
 
 /* Overall per-instruction processing.  */
@@ -10945,13 +10303,13 @@
   {"blx",        0xe0000000, 3,  ARM_EXT_V5,       do_blx},
   {"clz",        0xe16f0f10, 3,  ARM_EXT_V5,       do_clz},
   {"bkpt",       0xe1200070, 0,  ARM_EXT_V5,       do_bkpt},
-  {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc2},
-  {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc2},
-  {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc2},
-  {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc2},
-  {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp2},
-  {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg2},
-  {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg2},
+  {"ldc2",       0xfc100000, 0,  ARM_EXT_V5,       do_lstc},
+  {"ldc2l",      0xfc500000, 0,  ARM_EXT_V5,       do_lstc},
+  {"stc2",       0xfc000000, 0,  ARM_EXT_V5,       do_lstc},
+  {"stc2l",      0xfc400000, 0,  ARM_EXT_V5,       do_lstc},
+  {"cdp2",       0xfe000000, 0,  ARM_EXT_V5,       do_cdp},
+  {"mcr2",       0xfe000010, 0,  ARM_EXT_V5,       do_co_reg},
+  {"mrc2",       0xfe100010, 0,  ARM_EXT_V5,       do_co_reg},
 
   /*  ARM Architecture 5TExP.  */
   {"smlabb",     0xe1000080, 6,  ARM_EXT_V5ExP,    do_smla},

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