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


Consolidate the check for invalid use of PC in one place, namely
reg_required_here.  As you'll see from later patches in this series, I
went back and forth a little on where this check should happen.
Making this change revealed that some of the do_* functions were
identical to other do_* functions, and so could be deleted.

zw

	* config/tc-arm.c (reg_required_here): Add no_pc argument.
	All callers changed.
	(s_unwind_movsp, do_bfc, do_bfi, do_clz, do_cmp, do_ldmstm, do_ldrex)
	(do_mlas, do_mov, do_mov16, do_mul, do_mull, do_pkh_core, 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_fpa_ctrl)
	(do_xsc_mia, do_xsc_mar, do_xsc_mra): No need for separate check
	for REG_PC.  Do not override inst.error setting from
	reg_required_here.  Do not use strlen and strncmp when checking
	for square brackets.
	(do_smlad, do_smlald, do_smmul, do_umaal): Delete.
	(insns): Replace do_smlad with do_smla; do_smlald and do_umaal
	with do_smlal; do_smmul with do_smul.
	* testsuite/gas/arm/r15-bad.l: Adjust expected error messages.

===================================================================
Index: gas/testsuite/gas/arm/r15-bad.l
--- gas/testsuite/gas/arm/r15-bad.l	(revision 4)
+++ gas/testsuite/gas/arm/r15-bad.l	(revision 5)
@@ -59,6 +59,6 @@
 [^:]*:62: Error: r15 not allowed here -- `pkhtb r1,r2,r15'
 [^:]*:63: Error: r15 not allowed here -- `ldrex r15,[[]r2[]]'
 [^:]*:64: Error: r15 not allowed here -- `ldrex r1,[[]r15[]]'
-[^:]*:65: Error: r15 not allowed in swap -- `swp r15,r2,[[]r3[]]'
-[^:]*:66: Error: r15 not allowed in swap -- `swp r1,r15,[[]r3[]]'
+[^:]*:65: Error: r15 not allowed here -- `swp r15,r2,[[]r3[]]'
+[^:]*:66: Error: r15 not allowed here -- `swp r1,r15,[[]r3[]]'
 [^:]*:67: Error: r15 not allowed here -- `swp r1,r2,[[]r15[]]'
===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 4)
+++ gas/config/tc-arm.c	(revision 5)
@@ -1485,7 +1485,7 @@
    Returns the reg#, or FAIL.  */
 
 static int
-reg_required_here (char ** str, int shift)
+reg_required_here (char ** str, int shift, bfd_boolean no_pc)
 {
   static char buff [128]; /* XXX  */
   int         reg;
@@ -1493,6 +1493,12 @@
 
   if ((reg = arm_reg_parse (str, all_reg_maps[REG_TYPE_RN].htab)) != FAIL)
     {
+      if (reg == REG_PC && no_pc)
+	{
+	  inst.error = BAD_PC;
+	  return FAIL;
+	}
+
       if (shift >= 0)
 	inst.instruction |= reg << shift;
       return reg;
@@ -1521,7 +1527,7 @@
 {
   int reg;
 
-  if ((reg = reg_required_here (strp, -1)) == FAIL)
+  if ((reg = reg_required_here (strp, -1, FALSE)) == FAIL)
     return FAIL;
 
   switch (hi_lo)
@@ -1836,7 +1842,7 @@
 
 	      skip_whitespace (str);
 
-	      if ((reg = reg_required_here (& str, -1)) == FAIL)
+	      if ((reg = reg_required_here (& str, -1, FALSE)) == FAIL)
 		return FAIL;
 
 	      if (in_range)
@@ -2124,7 +2130,7 @@
 
   skip_whitespace (p);
 
-  if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8) != FAIL)
+  if (kind == NO_SHIFT_RESTRICT && reg_required_here (& p, 8, FALSE) != FAIL)
     {
       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
       * str = p;
@@ -2289,7 +2295,7 @@
 
   skip_whitespace (* str);
 
-  if (reg_required_here (str, 0) != FAIL)
+  if (reg_required_here (str, 0, FALSE) != FAIL)
     {
       if (skip_past_comma (str) == SUCCESS)
 	/* Shift operation on register.  */
@@ -2517,7 +2523,7 @@
       /* Fall through.  */
 
     default:
-      if (reg_required_here (str, 0) == FAIL)
+      if (reg_required_here (str, 0, FALSE) == FAIL)
 	return FAIL;
 
       inst.instruction |= add | OFFSET_REG;
@@ -2579,7 +2585,7 @@
       /* Fall through.  */
 
     default:
-      if (reg_required_here (str, 0) == FAIL)
+      if (reg_required_here (str, 0, FALSE) == FAIL)
 	return FAIL;
 
       inst.instruction |= add;
@@ -2609,7 +2615,7 @@
 
       skip_whitespace (str);
 
-      if ((rn = reg_required_here (& str, 16)) == FAIL)
+      if ((rn = reg_required_here (& str, 16, FALSE)) == FAIL)
 	return FAIL;
 
       skip_whitespace (str);
@@ -2939,7 +2945,7 @@
       p++;
       skip_whitespace (p);
 
-      if ((reg = reg_required_here (& p, 16)) == FAIL)
+      if ((reg = reg_required_here (& p, 16, FALSE)) == FAIL)
 	return FAIL;
 
       skip_whitespace (p);
@@ -3127,7 +3133,7 @@
       p++;
       skip_whitespace (p);
 
-      if ((reg = reg_required_here (& p, 16)) == FAIL)
+      if ((reg = reg_required_here (& p, 16, FALSE)) == FAIL)
         return FAIL;
 
       skip_whitespace (p);
@@ -4790,17 +4796,18 @@
   valueT op;
 
   SKIP_WHITESPACE ();
-  reg = reg_required_here (&input_line_pointer, -1);
+  reg = reg_required_here (&input_line_pointer, -1, TRUE);
   if (reg == FAIL)
     {
-      as_bad (_("ARM register expected"));
+      as_bad (inst.error);
       ignore_rest_of_line ();
       return;
     }
 
-  if (reg == 13 || reg == 15)
+  /* pc handled in reg_required_here */
+  if (reg == 13)
     {
-      as_bad (_("r%d not permitted in .unwind_movsp directive"), reg);
+      as_bad (_("r13 not permitted in .unwind_movsp directive"));
       ignore_rest_of_line ();
       return;
     }
@@ -4852,11 +4859,11 @@
   int fp_reg;
   int offset;
 
-  fp_reg = reg_required_here (&input_line_pointer, -1);
+  fp_reg = reg_required_here (&input_line_pointer, -1, FALSE);
   if (skip_past_comma (&input_line_pointer) == FAIL)
     sp_reg = FAIL;
   else
-    sp_reg = reg_required_here (&input_line_pointer, -1);
+    sp_reg = reg_required_here (&input_line_pointer, -1, FALSE);
 
   if (fp_reg == FAIL || sp_reg == FAIL)
     {
@@ -5020,7 +5027,7 @@
      into a relative address of the form "add rd, pc, #label-.-8".  */
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL
+  if (reg_required_here (&str, 12, FALSE) == FAIL
       || skip_past_comma (&str) == FAIL
       || my_get_expression (&inst.reloc.exp, &str))
     {
@@ -5050,7 +5057,7 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL
+  if (reg_required_here (&str, 12, FALSE) == FAIL
       || skip_past_comma (&str) == FAIL
       || my_get_expression (&inst.reloc.exp, &str))
     {
@@ -5076,9 +5083,9 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL
+  if (reg_required_here (&str, 12, FALSE) == FAIL
       || skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 16) == FAIL
+      || reg_required_here (&str, 16, FALSE) == FAIL
       || skip_past_comma (&str) == FAIL
       || data_op2 (&str) == FAIL)
     {
@@ -5122,21 +5129,15 @@
 static void
 do_bfc (char *str)
 {
-  int rd;
-
   /* Rd.  */
   skip_whitespace (str);
-  if (((rd = reg_required_here (&str, 12)) == FAIL)
-      || (skip_past_comma (&str) == FAIL))
+  if (reg_required_here (&str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
-  else if (rd == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
 
   bfci_lsb_and_width (str);
 }
@@ -5144,21 +5145,15 @@
 static void
 do_bfi (char *str)
 {
-  int rd, rm;
-
   /* Rd.  */
   skip_whitespace (str);
-  if (((rd = reg_required_here (&str, 12)) == FAIL)
-      || (skip_past_comma (&str) == FAIL))
+  if (reg_required_here (&str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
-  else if (rd == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
 
   /* Rm.  Accept #0 in this position as an alternative syntax for bfc.  */
   skip_whitespace (str);
@@ -5171,16 +5166,8 @@
     }
   else
     {
-      if ((rm = reg_required_here (&str, 0)) == FAIL)
-	{
-	  inst.error = BAD_ARGS;
-	  return;
-	}
-      else if (rm == REG_PC)
-	{
-	  inst.error = BAD_PC;
-	  return;
-	}
+      if (reg_required_here (&str, 0, TRUE) == FAIL)
+	return;
     }
   if (skip_past_comma (&str) == FAIL)
     {
@@ -5198,8 +5185,9 @@
 
   /* Rd.  */
   skip_whitespace (str);
-  if (reg_required_here (&str, 12) == FAIL
-      || skip_past_comma (&str) == FAIL)
+  if (reg_required_here (&str, 12, FALSE) == FAIL)
+    return;
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
@@ -5207,7 +5195,7 @@
 
   /* Rm.  */
   skip_whitespace (str);
-  if (reg_required_here (&str, 0) == FAIL
+  if (reg_required_here (&str, 0, FALSE) == FAIL
       || skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
@@ -5364,7 +5352,7 @@
 
   skip_whitespace (str);
 
-  if ((reg = reg_required_here (&str, 0)) == FAIL)
+  if ((reg = reg_required_here (&str, 0, FALSE)) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
@@ -5392,7 +5380,7 @@
   int rm;
 
   skip_whitespace (mystr);
-  rm = reg_required_here (& mystr, 0);
+  rm = reg_required_here (& mystr, 0, FALSE);
 
   /* The above may set inst.error.  Ignore his opinion.  */
   inst.error = 0;
@@ -5431,11 +5419,8 @@
 
   skip_whitespace (str);
 
-  if ((reg = reg_required_here (&str, 0)) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  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)
@@ -5573,20 +5558,19 @@
 static void
 do_clz (char * str)
 {
-  int rd, rm;
-
   skip_whitespace (str);
 
-  if (((rd = reg_required_here (& str, 12)) == FAIL)
-      || (skip_past_comma (& str) == FAIL)
-      || ((rm = reg_required_here (& str, 0)) == FAIL))
-    inst.error = BAD_ARGS;
+  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;
 
-  else if (rd == REG_PC || rm == REG_PC )
-    inst.error = BAD_PC;
-
-  else
-    end_of_line (str);
+  end_of_line (str);
 }
 
 static void
@@ -5594,12 +5578,8 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 16) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  if (reg_required_here (&str, 16, FALSE) == FAIL)
+    return;
 
   if (skip_past_comma (&str) == FAIL
       || data_op2 (&str) == FAIL)
@@ -5636,7 +5616,7 @@
     }
 
   if (skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 12) == FAIL)
+      || reg_required_here (&str, 12, FALSE) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -5699,7 +5679,7 @@
     }
 
   if (skip_past_comma (& str) == FAIL
-      || reg_required_here (& str, 12) == FAIL)
+      || reg_required_here (& str, 12, FALSE) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -5767,7 +5747,7 @@
     }
 
   if (skip_past_comma (& str) == FAIL
-      || (rd = reg_required_here (& str, 12)) == FAIL)
+      || (rd = reg_required_here (& str, 12, FALSE)) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -5775,7 +5755,7 @@
     }
 
   if (skip_past_comma (& str) == FAIL
-      || (rn = reg_required_here (& str, 16)) == FAIL)
+      || (rn = reg_required_here (& str, 16, FALSE)) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -5829,15 +5809,9 @@
 
   skip_whitespace (str);
 
-  if ((base_reg = reg_required_here (&str, 16)) == FAIL)
+  if ((base_reg = reg_required_here (&str, 16, TRUE)) == FAIL)
     return;
 
-  if (base_reg == REG_PC)
-    {
-      inst.error = _("r15 not allowed as base register");
-      return;
-    }
-
   skip_whitespace (str);
 
   if (*str == '!')
@@ -5903,7 +5877,7 @@
 
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (& str, 12)) == FAIL)
+  if ((rd = reg_required_here (& str, 12, FALSE)) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
@@ -5958,48 +5932,39 @@
 static void
 do_ldrex (char * str)
 {
-  int rd, rn;
-
   skip_whitespace (str);
 
   /* Parse Rd.  */
-  if (((rd = reg_required_here (&str, 12)) == FAIL)
-      || (skip_past_comma (&str) == FAIL))
+  if (reg_required_here (&str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
-  else if (rd == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
-  skip_whitespace (str);
 
   /* Skip past '['.  */
-  if ((strlen (str) >= 1)
-      &&strncmp (str, "[", 1) == 0)
-    str += 1;
   skip_whitespace (str);
-
-  /* Parse Rn.  */
-  if ((rn = reg_required_here (&str, 16)) == FAIL)
+  if (*str != '[')
     {
       inst.error = BAD_ARGS;
       return;
     }
-  else if (rn == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
+  str++;
+
+  /* Parse Rn.  */
   skip_whitespace (str);
+  if (reg_required_here (&str, 16, TRUE) == FAIL)
+    return;
 
   /* Skip past ']'.  */
-  if ((strlen (str) >= 1)
-      && strncmp (str, "]", 1) == 0)
-    str += 1;
-
+  skip_whitespace (str);
+  if (*str != ']')
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  str++;
   end_of_line (str);
 }
 
@@ -6012,7 +5977,7 @@
 
   skip_whitespace (str);
 
-  if ((conflict_reg = reg_required_here (&str, 12)) == FAIL)
+  if ((conflict_reg = reg_required_here (&str, 12, FALSE)) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -6033,7 +5998,7 @@
 
       skip_whitespace (str);
 
-      if ((reg = reg_required_here (&str, 16)) == FAIL)
+      if ((reg = reg_required_here (&str, 16, FALSE)) == FAIL)
 	return;
 
       /* Conflicts can occur on stores as well as loads.  */
@@ -6200,7 +6165,7 @@
 
   skip_whitespace (str);
 
-  if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
+  if ((conflict_reg = reg_required_here (& str, 12, FALSE)) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -6221,7 +6186,7 @@
 
       skip_whitespace (str);
 
-      if ((reg = reg_required_here (&str, 16)) == FAIL)
+      if ((reg = reg_required_here (&str, 16, FALSE)) == FAIL)
 	return;
 
       /* ldrt/strt always use post-indexed addressing, so if the base is
@@ -6281,7 +6246,7 @@
 
   skip_whitespace (str);
 
-  if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
+  if ((conflict_reg = reg_required_here (& str, 12, FALSE)) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -6302,7 +6267,7 @@
 
       skip_whitespace (str);
 
-      if ((reg = reg_required_here (&str, 16)) == FAIL)
+      if ((reg = reg_required_here (&str, 16, FALSE)) == FAIL)
 	return;
 
       /* Conflicts can occur on stores as well as loads.  */
@@ -6472,7 +6437,7 @@
 
   skip_whitespace (str);
 
-  if ((conflict_reg = reg_required_here (& str, 12)) == FAIL)
+  if ((conflict_reg = reg_required_here (& str, 12, FALSE)) == FAIL)
     {
       if (!inst.error)
 	inst.error = BAD_ARGS;
@@ -6493,7 +6458,7 @@
 
       skip_whitespace (str);
 
-      if ((reg = reg_required_here (&str, 16)) == FAIL)
+      if ((reg = reg_required_here (&str, 16, FALSE)) == FAIL)
 	return;
 
       /* ldrt/strt always use post-indexed addressing, so if the base is
@@ -6616,50 +6581,39 @@
   /* Only one format "rd, rm, rs, rn".  */
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (&str, 16)) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  if ((rd = reg_required_here (&str, 16, TRUE)) == FAIL)
+    return;
 
-  if (rd == REG_PC)
+  if (skip_past_comma (&str) == FAIL)
     {
-      inst.error = BAD_PC;
-      return;
-    }
-
-  if (skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 0)) == FAIL)
-    {
       inst.error = BAD_ARGS;
       return;
     }
+  if ((rm = reg_required_here (&str, 0, TRUE)) == FAIL)
+    return;
 
-  if (rm == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
-
   /* 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"));
 
-  if (skip_past_comma (&str) == FAIL
-      || (rd = reg_required_here (&str, 8)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 12)) == FAIL)
+  /* Rs.  */
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
+  if ((rm = reg_required_here (&str, 8, TRUE)) == FAIL)
+    return;
 
-  if (rd == REG_PC || rm == REG_PC)
+  /* Rn.  */
+  if (skip_past_comma (&str) == FAIL)
     {
-      inst.error = BAD_PC;
+      inst.error = BAD_ARGS;
       return;
     }
+  if ((rm = reg_required_here (&str, 12, TRUE)) == FAIL)
+    return;
 
   end_of_line (str);
 }
@@ -6681,12 +6635,8 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  if (reg_required_here (&str, 12, FALSE) == FAIL)
+    return;
 
   if (skip_past_comma (&str) == FAIL
       || data_op2 (&str) == FAIL)
@@ -6704,22 +6654,17 @@
 static void
 do_mov16 (char *str)
 {
-  int rd;
   int val;
 
   /* Rd.  */
   skip_whitespace (str);
-  if (((rd = reg_required_here (&str, 12)) == FAIL)
-      || (skip_past_comma (&str) == FAIL))
+  if (reg_required_here (&str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
-  else if (rd == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
 
   /* Imm16.  */
   if (immediate_required_here (&str, &val, 0, 65535, FALSE) == FAIL)
@@ -6740,11 +6685,8 @@
   /* Only one syntax.  */
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  if (reg_required_here (&str, 12, FALSE) == FAIL)
+    return;
 
   if (skip_past_comma (&str) == FAIL)
     {
@@ -6798,7 +6740,7 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (& str, 0) != FAIL)
+  if (reg_required_here (& str, 0, FALSE) != FAIL)
     {
       inst.error = NULL;
       end_of_line (str);
@@ -6854,46 +6796,29 @@
   /* Only one format "rd, rm, rs".  */
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (&str, 16)) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  if ((rd = reg_required_here (&str, 16, TRUE)) == FAIL)
+    return;
 
-  if (rd == REG_PC)
+  if (skip_past_comma (&str) == FAIL)
     {
-      inst.error = BAD_PC;
-      return;
-    }
-
-  if (skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 0)) == FAIL)
-    {
       inst.error = BAD_ARGS;
       return;
     }
 
-  if (rm == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
+  if ((rm = reg_required_here (&str, 0, TRUE)) == FAIL)
+    return;
 
   if (rm == rd)
     as_tsktsk (_("rd and rm should be different in mul"));
 
-  if (skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 8)) == FAIL)
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  if (rm == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
+  if (reg_required_here (&str, 8, TRUE) == FAIL)
+    return;
 
   end_of_line (str);
 }
@@ -6907,48 +6832,45 @@
 static void
 do_mull (char * str)
 {
-  int rdlo, rdhi, rm, rs;
+  int rdlo, rdhi, rm;
 
   /* Only one format "rdlo, rdhi, rm, rs".  */
   skip_whitespace (str);
 
-  if ((rdlo = reg_required_here (&str, 12)) == FAIL)
+  if ((rdlo = reg_required_here (&str, 12, TRUE)) == FAIL)
+    return;
+
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  if (skip_past_comma (&str) == FAIL
-      || (rdhi = reg_required_here (&str, 16)) == FAIL)
+  if ((rdhi = reg_required_here (&str, 16, TRUE)) == FAIL)
+    return;
+
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
+    
+  if ((rm = reg_required_here (&str, 0, TRUE)) == FAIL)
+    return;
 
-  if (skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 0)) == FAIL)
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
+  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"));
 
-  if (skip_past_comma (&str) == FAIL
-      || (rs = reg_required_here (&str, 8)) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC || rdhi == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
-
   end_of_line (str);
 }
 
@@ -6982,25 +6904,32 @@
 static void
 do_pkh_core (char * str, int shift)
 {
-  int rd, rn, rm;
+  int rm, rn;
 
   skip_whitespace (str);
-  if (((rd = reg_required_here (&str, 12)) == FAIL)
-      || (skip_past_comma (&str) == FAIL)
-      || ((rn = reg_required_here (&str, 16)) == FAIL)
-      || (skip_past_comma (&str) == FAIL)
-      || ((rm = reg_required_here (&str, 0)) == FAIL))
+
+  if (reg_required_here (&str, 12, TRUE) == FAIL)
+    return;
+
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
+  if ((rn = reg_required_here (&str, 16, TRUE)) == FAIL)
+    return;
+
+  if (skip_past_comma (&str) == FAIL)
     {
-      inst.error = BAD_PC;
+      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)
     {
@@ -7060,7 +6989,7 @@
   ++str;
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (& str, 16)) == FAIL)
+  if ((rd = reg_required_here (& str, 16, FALSE)) == FAIL)
     return;
 
   skip_whitespace (str);
@@ -7127,22 +7056,27 @@
 static void
 do_qadd (char * str)
 {
-  int rd, rm, rn;
-
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (& str, 12)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rm = reg_required_here (& str, 0)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rn = reg_required_here (& str, 16)) == FAIL)
-    inst.error = BAD_ARGS;
+  if (reg_required_here (&str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (&str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
 
-  else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
-    inst.error = BAD_PC;
+  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;
 
-  else
-    end_of_line (str);
+  end_of_line (str);
 }
 
 /* ARM V6 Perform Two Sixteen Bit Integer Additions. (argument parse).
@@ -7153,43 +7087,43 @@
 static void
 do_qadd16 (char * str)
 {
-  int rd, rm, rn;
-
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (&str, 12)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rn = reg_required_here (&str, 16)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 0)) == FAIL)
-    inst.error = BAD_ARGS;
+  if (reg_required_here (&str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (&str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
 
-  else if (rd == REG_PC || rm == REG_PC || rn == REG_PC)
-    inst.error = BAD_PC;
+  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;
 
-  else
-    end_of_line (str);
+  end_of_line (str);
 }
 
 static void
 do_rbit (char *str)
 {
-  /* Rd.  */
   skip_whitespace (str);
-  if (reg_required_here (&str, 12) == FAIL
-      || skip_past_comma (&str) == FAIL)
+  if (reg_required_here (&str, 12, FALSE) == FAIL)
+    return;
+  if (skip_past_comma (&str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  /* Rm.  */
-  skip_whitespace (str);
-  if (reg_required_here (&str, 0) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
+  if (reg_required_here (&str, 0, FALSE) == FAIL)
+    return;
 
   end_of_line (str);
 }
@@ -7203,20 +7137,19 @@
 static void
 do_rev (char * str)
 {
-  int rd, rm;
-
   skip_whitespace (str);
+  if (reg_required_here (&str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (&str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
 
-  if ((rd = reg_required_here (&str, 12)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 0)) == FAIL)
-    inst.error = BAD_ARGS;
+  if (reg_required_here (&str, 0, TRUE) == FAIL)
+    return;
 
-  else if (rd == REG_PC || rm == REG_PC)
-    inst.error = BAD_PC;
-
-  else
-    end_of_line (str);
+  end_of_line (str);
 }
 
 /* ARM V6 RFE (Return from Exception) loads the PC and CPSR from the
@@ -7228,19 +7161,11 @@
 static void
 do_rfe (char * str)
 {
-  int rn;
-
   skip_whitespace (str);
 
-  if ((rn = reg_required_here (&str, 16)) == FAIL)
+  if (reg_required_here (&str, 16, TRUE) == FAIL)
     return;
 
-  if (rn == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
-
   skip_whitespace (str);
 
   if (*str == '!')
@@ -7254,22 +7179,18 @@
 static void
 do_sat (char ** str, int bias)
 {
-  int rd, rm, val;
+  int val;
 
   skip_whitespace (*str);
 
   /* Parse <Rd>, field.  */
-  if ((rd = reg_required_here (str, 12)) == FAIL
-      || skip_past_comma (str) == FAIL)
+  if (reg_required_here (str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
-  if (rd == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
 
   /* Parse #<immed>,  field.  */
   if (immediate_required_here (str, &val, 0 - bias, 31 - bias, FALSE) == FAIL)
@@ -7283,16 +7204,8 @@
     }
 
   /* Parse <Rm> field.  */
-  if ((rm = reg_required_here (str, 0)) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if (rm == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
+  if (reg_required_here (str, 0, TRUE) == FAIL)
+    return;
 
   if (skip_past_comma (str) == SUCCESS)
     decode_shift (str, SHIFT_LSL_OR_ASR_IMMEDIATE);
@@ -7319,22 +7232,18 @@
 static void
 do_sat16 (char ** str, int bias)
 {
-  int rd, rm, val;
+  int val;
 
   skip_whitespace (*str);
 
   /* Parse the <Rd> field.  */
-  if ((rd = reg_required_here (str, 12)) == FAIL
-      || skip_past_comma (str) == FAIL)
+  if (reg_required_here (str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
-  if (rd == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
 
   /* Parse #<immed>, field.  */
   if (immediate_required_here (str, &val, 0 - bias, 15 - bias, FALSE) == FAIL)
@@ -7348,16 +7257,8 @@
     }
 
   /* Parse <Rm> field.  */
-  if ((rm = reg_required_here (str, 0)) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-  if (rm == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
+  if (reg_required_here (str, 0, TRUE) == FAIL)
+    return;
 }
 
 /* ARM V6 ssat16 (argument parse).  */
@@ -7431,56 +7332,35 @@
 static void
 do_smla (char * str)
 {
-  int rd, rm, rs, rn;
-
   skip_whitespace (str);
 
-  if ((rd = reg_required_here (& str, 16)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rm = reg_required_here (& str, 0)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rs = reg_required_here (& str, 8)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rn = reg_required_here (& str, 12)) == FAIL)
-    inst.error = BAD_ARGS;
-
-  else if (rd == REG_PC || rm == REG_PC || rs == REG_PC || rn == REG_PC)
-    inst.error = BAD_PC;
-
-  else
-    end_of_line (str);
-}
-
-/* ARM V6 SMLAD (argument parse).  Signed multiply accumulate dual.
-   smlad{x}{<cond>} Rd, Rm, Rs, Rn */
-
-static void
-do_smlad (char * str)
-{
-  int rd, rm, rs, rn;
-
-  skip_whitespace (str);
-  if ((rd = reg_required_here (&str, 16)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 0)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rs = reg_required_here (&str, 8)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rn = reg_required_here (&str, 12)) == FAIL)
+  if (reg_required_here (& str, 16, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  if (   rd == REG_PC
-      || rn == REG_PC
-      || rs == REG_PC
-      || rm == REG_PC)
+  if (reg_required_here (& str, 0, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
-      inst.error = BAD_PC;
+      inst.error = BAD_ARGS;
       return;
     }
+  
+  if (reg_required_here (& str, 8, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
 
+  if (reg_required_here (& str, 12, TRUE) == FAIL)
+    return;
+
   end_of_line (str);
 }
 
@@ -7492,120 +7372,73 @@
 static void
 do_smlal (char * str)
 {
-  int rdlo, rdhi, rm, rs;
+  int rdlo, rdhi;
 
   skip_whitespace (str);
 
-  if ((rdlo = reg_required_here (& str, 12)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rdhi = reg_required_here (& str, 16)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rm = reg_required_here (& str, 0)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rs = reg_required_here (& str, 8)) == FAIL)
+  if ((rdlo = reg_required_here (& str, 12, TRUE)) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
+  if ((rdhi = reg_required_here (& str, 16, TRUE)) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
-      inst.error = BAD_PC;
+      inst.error = BAD_ARGS;
       return;
     }
-
-  if (rdlo == rdhi)
-    as_tsktsk (_("rdhi and rdlo must be different"));
-
-  end_of_line (str);
-}
-
-/* ARM V6 SMLALD (argument parse).  */
-
-static void
-do_smlald (char * str)
-{
-  int rdlo, rdhi, rm, rs;
-
-  skip_whitespace (str);
-  if ((rdlo = reg_required_here (&str, 12)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rdhi = reg_required_here (&str, 16)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 0)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rs = reg_required_here (&str, 8)) == FAIL)
+  
+  if (reg_required_here (& str, 0, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  if (   rdlo == REG_PC
-      || rdhi == REG_PC
-      || rm == REG_PC
-      || rs == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
+  if (reg_required_here (& str, 8, TRUE) == FAIL)
+    return;
 
+  if (rdlo == rdhi)
+    as_tsktsk (_("rdhi and rdlo must be different"));
+
   end_of_line (str);
 }
 
-/* ARM V6 SMMUL (argument parse).  */
+/* ARM V5E (El Segundo) signed-multiply (argument parse)
+   SMULxy{cond} Rd,Rm,Rs
+   Error if any register is R15.  */
 
 static void
-do_smmul (char * str)
+do_smul (char * str)
 {
-  int rd, rm, rs;
-
   skip_whitespace (str);
-  if ((rd = reg_required_here (&str, 16)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 0)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rs = reg_required_here (&str, 8)) == FAIL)
+  if (reg_required_here (& str, 16, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  if (   rd == REG_PC
-      || rm == REG_PC
-      || rs == REG_PC)
+  if (reg_required_here (& str, 0, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
-      inst.error = BAD_PC;
+      inst.error = BAD_ARGS;
       return;
     }
+  
+  if (reg_required_here (& str, 8, TRUE) == FAIL)
+    return;
 
   end_of_line (str);
 }
 
-/* ARM V5E (El Segundo) signed-multiply (argument parse)
-   SMULxy{cond} Rd,Rm,Rs
-   Error if any register is R15.  */
-
-static void
-do_smul (char * str)
-{
-  int rd, rm, rs;
-
-  skip_whitespace (str);
-
-  if ((rd = reg_required_here (& str, 16)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rm = reg_required_here (& str, 0)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rs = reg_required_here (& str, 8)) == FAIL)
-    inst.error = BAD_ARGS;
-
-  else if (rd == REG_PC || rm == REG_PC || rs == REG_PC)
-    inst.error = BAD_PC;
-
-  else
-    end_of_line (str);
-}
-
 /* ARM V6 srs (argument parse).  */
 
 static void
@@ -7636,19 +7469,22 @@
 
   /* Parse Rd, Rm,.  */
   skip_whitespace (str);
-  if ((rd = reg_required_here (& str, 12)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rm = reg_required_here (& str, 0)) == FAIL
-      || skip_past_comma (& str) == FAIL)
+  if ((rd = reg_required_here (& str, 12, TRUE)) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
-  if (rd == REG_PC || rm == REG_PC)
+
+  if ((rm = reg_required_here (& str, 0, TRUE)) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
-      inst.error = BAD_PC;
+      inst.error = BAD_ARGS;
       return;
     }
+    
   if (rd == rm)
     {
       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
@@ -7656,23 +7492,17 @@
     }
 
   /* Skip past '['.  */
-  if ((strlen (str) >= 1)
-      && strncmp (str, "[", 1) == 0)
-    str += 1;
-
-  skip_whitespace (str);
-
-  /* Parse Rn.  */
-  if ((rn = reg_required_here (& str, 16)) == FAIL)
+  if (*str != '[')
     {
       inst.error = BAD_ARGS;
       return;
     }
-  else if (rn == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
+  str++;
+  skip_whitespace (str);
+
+  /* Parse Rn.  */
+  if ((rn = reg_required_here (& str, 16, TRUE)) == FAIL)
+    return;
   if (rd == rn)
     {
       inst.error = _("Rd equal to Rm or Rn yields unpredictable results");
@@ -7681,9 +7511,12 @@
   skip_whitespace (str);
 
   /* Skip past ']'.  */
-  if ((strlen (str) >= 1)
-      && strncmp (str, "]", 1) == 0)
-    str += 1;
+  if (*str != ']')
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
+  str++;
 
   end_of_line (str);
 }
@@ -7695,29 +7528,18 @@
 
   skip_whitespace (str);
 
-  if ((reg = reg_required_here (&str, 12)) == FAIL)
+  if (reg_required_here (&str, 12, TRUE) == FAIL)
     return;
 
-  if (reg == REG_PC)
+  if (skip_past_comma (&str) == FAIL)
     {
-      inst.error = _("r15 not allowed in swap");
+      inst.error = BAD_ARGS;
       return;
     }
 
-  if (skip_past_comma (&str) == FAIL
-      || (reg = reg_required_here (&str, 0)) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  if (reg_required_here (&str, 0, TRUE) == FAIL)
+    return;
 
-  if (reg == REG_PC)
-    {
-      inst.error = _("r15 not allowed in swap");
-      return;
-    }
-
   if (skip_past_comma (&str) == FAIL
       || *str++ != '[')
     {
@@ -7727,15 +7549,9 @@
 
   skip_whitespace (str);
 
-  if ((reg = reg_required_here (&str, 16)) == FAIL)
+  if ((reg = reg_required_here (&str, 16, TRUE)) == FAIL)
     return;
 
-  if (reg == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
-
   skip_whitespace (str);
 
   if (*str++ != ']')
@@ -7758,28 +7574,31 @@
 static void
 do_sxtah (char * str)
 {
-  int rd, rn, rm, rot;
+  int rot;
   int rotation_clear_mask = 0xfffff3ff;
   int rotation_eight_mask = 0x00000400;
   int rotation_sixteen_mask = 0x00000800;
   int rotation_twenty_four_mask = 0x00000c00;
 
   skip_whitespace (str);
-  if ((rd = reg_required_here (&str, 12)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rn = reg_required_here (&str, 16)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 0)) == FAIL)
+  if (reg_required_here (& str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  else if (rd == REG_PC || rn == REG_PC || rm == REG_PC)
+  if (reg_required_here (& str, 16, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
-      inst.error = BAD_PC;
+      inst.error = BAD_ARGS;
       return;
     }
+  
+  if (reg_required_here (& str, 0, TRUE) == FAIL)
+    return;
 
   /* Zero out the rotation field.  */
   inst.instruction &= rotation_clear_mask;
@@ -7840,7 +7659,7 @@
 static void
 do_sxth (char * str)
 {
-  int rd, rm, rot;
+  int rot;
 
   int rotation_clear_mask = 0xfffff3ff;
   int rotation_eight_mask = 0x00000400;
@@ -7848,19 +7667,16 @@
   int rotation_twenty_four_mask = 0x00000c00;
 
   skip_whitespace (str);
-  if ((rd = reg_required_here (&str, 12)) == FAIL
-      || skip_past_comma (&str) == FAIL
-      || (rm = reg_required_here (&str, 0)) == FAIL)
+  if (reg_required_here (& str, 12, TRUE) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
     {
       inst.error = BAD_ARGS;
       return;
     }
 
-  else if (rd == REG_PC || rm == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
+  if (reg_required_here (& str, 0, TRUE) == FAIL)
+    return;
 
   /* Zero out the rotation field.  */
   inst.instruction &= rotation_clear_mask;
@@ -7910,35 +7726,6 @@
   end_of_line (str);
 }
 
-/* ARM V6 umaal (argument parse).  */
-
-static void
-do_umaal (char * str)
-{
-  int rdlo, rdhi, rm, rs;
-
-  skip_whitespace (str);
-  if ((rdlo = reg_required_here (& str, 12)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rdhi = reg_required_here (& str, 16)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rm = reg_required_here (& str, 0)) == FAIL
-      || skip_past_comma (& str) == FAIL
-      || (rs = reg_required_here (& str, 8)) == FAIL)
-    {
-      inst.error = BAD_ARGS;
-      return;
-    }
-
-  if (rdlo == REG_PC || rdhi == REG_PC || rm == REG_PC || rs == REG_PC)
-    {
-      inst.error = BAD_PC;
-      return;
-    }
-
-  end_of_line (str);
-}
-
 
 /* Thumb instructions.  The generic argument parsing routines
    (thumb_*) come first, in alphabetical order, then the
@@ -8527,7 +8314,7 @@
   skip_whitespace (str);
 
   /* Store Rd in temporary location inside instruction.  */
-  if ((reg = reg_required_here (&str, 4)) == FAIL
+  if ((reg = reg_required_here (&str, 4, FALSE)) == FAIL
       || (reg > 7)  /* For Thumb reg must be r0..r7.  */
       || skip_past_comma (&str) == FAIL
       || my_get_expression (&inst.reloc.exp, &str))
@@ -8642,7 +8429,7 @@
   /* Note that this call is to the ARM register recognizer.  BLX(2)
      uses the ARM register space, not the Thumb one, so a call to
      thumb_reg() would be wrong.  */
-  rm = reg_required_here (& mystr, 3);
+  rm = reg_required_here (& mystr, 3, FALSE);
   inst.error = 0;
 
   if (rm != FAIL)
@@ -9104,7 +8891,7 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL)
+  if (reg_required_here (&str, 12, FALSE) == FAIL)
     return;
 
   if (skip_past_comma (&str) == FAIL
@@ -9125,9 +8912,9 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL
+  if (reg_required_here (&str, 12, FALSE) == FAIL
       || skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 16) == FAIL
+      || reg_required_here (&str, 16, FALSE) == FAIL
       || skip_past_comma (&str) == FAIL)
     {
       if (! inst.error)
@@ -9155,7 +8942,7 @@
     return;
 
   if (skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 12) == FAIL)
+      || reg_required_here (&str, 12, FALSE) == FAIL)
     {
       if (! inst.error)
 	inst.error = BAD_ARGS;
@@ -9181,9 +8968,9 @@
   vfp_sp_encode_reg (reg, VFP_REG_Sm);
 
   if (skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 12) == FAIL
+      || reg_required_here (&str, 12, FALSE) == FAIL
       || skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 16) == FAIL)
+      || reg_required_here (&str, 16, FALSE) == FAIL)
     {
       if (! inst.error)
 	inst.error = BAD_ARGS;
@@ -9198,7 +8985,7 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL)
+  if (reg_required_here (&str, 12, FALSE) == FAIL)
     return;
 
   if (skip_past_comma (&str) == FAIL
@@ -9217,11 +9004,11 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL)
+  if (reg_required_here (&str, 12, FALSE) == FAIL)
     return;
 
   if (skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 16) == FAIL
+      || reg_required_here (&str, 16, FALSE) == FAIL
       || skip_past_comma (&str) == FAIL
       || vfp_dp_reg_required_here (&str, VFP_REG_Dm) == FAIL)
     {
@@ -9242,7 +9029,7 @@
     return;
 
   if (skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 12) == FAIL)
+      || reg_required_here (&str, 12, FALSE) == FAIL)
     {
       if (! inst.error)
 	inst.error = BAD_ARGS;
@@ -9261,9 +9048,9 @@
     return;
 
   if (skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 12) == FAIL
+      || reg_required_here (&str, 12, FALSE) == FAIL
       || skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 16) == FAIL)
+      || reg_required_here (&str, 16, FALSE) == FAIL)
     {
       if (! inst.error)
 	inst.error = BAD_ARGS;
@@ -9278,7 +9065,7 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL)
+  if (reg_required_here (&str, 12, FALSE) == FAIL)
     return;
 
   if (skip_past_comma (&str) == FAIL
@@ -9301,7 +9088,7 @@
     return;
 
   if (skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 12) == FAIL)
+      || reg_required_here (&str, 12, FALSE) == FAIL)
     {
       if (! inst.error)
 	inst.error = BAD_ARGS;
@@ -9366,7 +9153,7 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 16) == FAIL)
+  if (reg_required_here (&str, 16, FALSE) == FAIL)
     return;
 
   skip_whitespace (str);
@@ -9403,7 +9190,7 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 16) == FAIL)
+  if (reg_required_here (&str, 16, FALSE) == FAIL)
     return;
 
   skip_whitespace (str);
@@ -9482,12 +9269,8 @@
 
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL)
-    {
-      if (!inst.error)
-	inst.error = BAD_ARGS;
-      return;
-    }
+  if (reg_required_here (&str, 12, FALSE) == FAIL)
+    return;
 
   end_of_line (str);
 }
@@ -9582,7 +9365,7 @@
     }
 
   if (skip_past_comma (&str) == FAIL
-      || reg_required_here (&str, 12) == FAIL)
+      || reg_required_here (&str, 12, FALSE) == FAIL)
     {
       if (! inst.error)
 	inst.error = BAD_ARGS;
@@ -9597,7 +9380,7 @@
 {
   skip_whitespace (str);
 
-  if (reg_required_here (&str, 12) == FAIL)
+  if (reg_required_here (&str, 12, FALSE) == FAIL)
     return;
 
   if (skip_past_comma (&str) == FAIL
@@ -9690,7 +9473,7 @@
       str++;
       skip_whitespace (str);
 
-      if ((reg = reg_required_here (&str, 16)) == FAIL)
+      if ((reg = reg_required_here (&str, 16, FALSE)) == FAIL)
 	return;
 
       skip_whitespace (str);
@@ -9776,7 +9559,7 @@
   switch (insn_type)
     {
     case check_rd:
-      if ((reg = reg_required_here (&str, 12)) == FAIL)
+      if ((reg = reg_required_here (&str, 12, FALSE)) == FAIL)
 	return FAIL;
       break;
 
@@ -9813,12 +9596,12 @@
     case check_tbcst:
       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
 	   || skip_past_comma (&str) == FAIL
-	   || reg_required_here (&str, 12) == FAIL))
+	   || reg_required_here (&str, 12, FALSE) == FAIL))
 	return FAIL;
       break;
 
     case check_tmovmsk:
-      if ((reg_required_here (&str, 12) == FAIL
+      if ((reg_required_here (&str, 12, FALSE) == FAIL
 	   || skip_past_comma (&str) == FAIL
 	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL))
 	return FAIL;
@@ -9827,25 +9610,25 @@
     case check_tmia:
       if ((wreg_required_here (&str, 5, IWMMXT_REG_WR) == FAIL
 	   || skip_past_comma (&str) == FAIL
-	   || reg_required_here (&str, 0) == FAIL
+	   || reg_required_here (&str, 0, FALSE) == FAIL
 	   || skip_past_comma (&str) == FAIL
-	   || reg_required_here (&str, 12) == FAIL))
+	   || reg_required_here (&str, 12, FALSE) == FAIL))
 	return FAIL;
       break;
 
     case check_tmcrr:
       if ((wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL
 	   || skip_past_comma (&str) == FAIL
-	   || reg_required_here (&str, 12) == FAIL
+	   || reg_required_here (&str, 12, FALSE) == FAIL
 	   || skip_past_comma (&str) == FAIL
-	   || reg_required_here (&str, 16) == FAIL))
+	   || reg_required_here (&str, 16, FALSE) == FAIL))
 	return FAIL;
       break;
 
     case check_tmrrc:
-      if ((reg_required_here (&str, 12) == FAIL
+      if ((reg_required_here (&str, 12, FALSE) == FAIL
 	   || skip_past_comma (&str) == FAIL
-	   || reg_required_here (&str, 16) == FAIL
+	   || reg_required_here (&str, 16, FALSE) == FAIL
 	   || skip_past_comma (&str) == FAIL
 	   || wreg_required_here (&str, 0, IWMMXT_REG_WR) == FAIL))
 	return FAIL;
@@ -9854,12 +9637,12 @@
     case check_tmcr:
       if ((wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL
 	   || skip_past_comma (&str) == FAIL
-	   || reg_required_here (&str, 12) == FAIL))
+	   || reg_required_here (&str, 12, FALSE) == FAIL))
 	return FAIL;
       break;
 
     case check_tmrc:
-      if ((reg_required_here (&str, 12) == FAIL
+      if ((reg_required_here (&str, 12, FALSE) == FAIL
 	   || skip_past_comma (&str) == FAIL
 	   || wreg_required_here (&str, 16, IWMMXT_REG_WC) == FAIL))
 	return FAIL;
@@ -9868,13 +9651,13 @@
     case check_tinsr:
       if ((wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
 	   || skip_past_comma (&str) == FAIL
-	   || reg_required_here (&str, 12) == FAIL
+	   || reg_required_here (&str, 12, FALSE) == FAIL
 	   || skip_past_comma (&str) == FAIL))
 	return FAIL;
       break;
 
     case check_textrc:
-      if ((reg_required_here (&str, 12) == FAIL
+      if ((reg_required_here (&str, 12, FALSE) == FAIL
 	   || skip_past_comma (&str) == FAIL))
 	return FAIL;
       break;
@@ -9890,7 +9673,7 @@
       break;
 
     case check_textrm:
-      if ((reg_required_here (&str, 12) == FAIL
+      if ((reg_required_here (&str, 12, FALSE) == FAIL
 	   || skip_past_comma (&str) == FAIL
 	   || wreg_required_here (&str, 16, IWMMXT_REG_WR) == FAIL
 	   || skip_past_comma (&str) == FAIL))
@@ -10573,7 +10356,7 @@
   if (mav_reg_required_here (&str, 12, reg0) == FAIL
       || skip_past_comma (&str) == FAIL
       || *str++ != '['
-      || reg_required_here (&str, 16) == FAIL)
+      || reg_required_here (&str, 16, FALSE) == FAIL)
     goto fail_ldst;
 
   if (skip_past_comma (&str) == SUCCESS)
@@ -10662,26 +10445,28 @@
 static void
 do_xsc_mia (char * str)
 {
-  int rs;
-  int rm;
-
   if (accum0_required_here (& str) == FAIL)
     inst.error = ERR_NO_ACCUM;
 
-  else if (skip_past_comma (& str) == FAIL
-	   || (rm = reg_required_here (& str, 0)) == FAIL)
-    inst.error = BAD_ARGS;
+  if (skip_past_comma (& str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
 
-  else if (skip_past_comma (& str) == FAIL
-	   || (rs = reg_required_here (& str, 12)) == FAIL)
-    inst.error = BAD_ARGS;
+  if (reg_required_here (& str, 0, TRUE) == FAIL)
+    return;
 
-  /* inst.instruction has now been zapped with both rm and rs.  */
-  else if (rm == REG_PC || rs == REG_PC)
-    inst.error = BAD_PC;	/* Undefined result if rm or rs is R15.  */
+  if (skip_past_comma (& str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
 
-  else
-    end_of_line (str);
+  if (reg_required_here (& str, 12, TRUE) == FAIL)
+    return;
+
+  end_of_line (str);
 }
 
 /* Xscale move-accumulator-register (argument parse)
@@ -10691,25 +10476,28 @@
 static void
 do_xsc_mar (char * str)
 {
-  int rdlo, rdhi;
-
   if (accum0_required_here (& str) == FAIL)
     inst.error = ERR_NO_ACCUM;
 
-  else if (skip_past_comma (& str) == FAIL
-	   || (rdlo = reg_required_here (& str, 12)) == FAIL)
-    inst.error = BAD_ARGS;
+  if (skip_past_comma (& str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
 
-  else if (skip_past_comma (& str) == FAIL
-	   || (rdhi = reg_required_here (& str, 16)) == FAIL)
-    inst.error = BAD_ARGS;
+  if (reg_required_here (& str, 12, TRUE) == FAIL)
+    return;
 
-  /* inst.instruction has now been zapped with both rdlo and rdhi.  */
-  else if (rdlo == REG_PC || rdhi == REG_PC)
-    inst.error = BAD_PC;	/* Undefined result if rdlo or rdhi is R15.  */
+  if (skip_past_comma (& str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
 
-  else
-    end_of_line (str);
+  if (reg_required_here (& str, 16, TRUE) == FAIL)
+    return;
+
+  end_of_line (str);
 }
 
 /* Xscale move-register-accumulator (argument parse)
@@ -10724,25 +10512,36 @@
 
   skip_whitespace (str);
 
-  if ((rdlo = reg_required_here (& str, 12)) == FAIL)
-    inst.error = BAD_ARGS;
+  if ((rdlo = reg_required_here (& str, 12, TRUE)) == FAIL)
+    return;
+  if (skip_past_comma (& str) == FAIL)
+    {
+      inst.error = BAD_ARGS;
+      return;
+    }
 
-  else if (skip_past_comma (& str) == FAIL
-	   || (rdhi = reg_required_here (& str, 16)) == FAIL)
-    inst.error = BAD_ARGS;
+  if ((rdhi = reg_required_here (& str, 16, TRUE)) == FAIL)
+    return;
 
-  else if  (skip_past_comma (& str) == FAIL
-	    || accum0_required_here (& str) == FAIL)
-    inst.error = ERR_NO_ACCUM;
+  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.  */
-  else if (rdlo == rdhi)
-    inst.error = BAD_ARGS;	/* Undefined result if 2 writes to same reg.  */
+  if (rdlo == rdhi)
+    {
+      inst.error = BAD_ARGS;	/* Undefined result if 2 writes to same reg.  */
+      return;
+    }
 
-  else if (rdlo == REG_PC || rdhi == REG_PC)
-    inst.error = BAD_PC;	/* Undefined result if rdlo or rdhi is R15.  */
-  else
-    end_of_line (str);
+  end_of_line (str);
 }
 
 /* Overall per-instruction processing.  */
@@ -11262,24 +11061,24 @@
   { "uxtb",      0xe6ef0070, 4,  ARM_EXT_V6,       do_sxth},
   { "sel",       0xe68000b0, 3,  ARM_EXT_V6,       do_qadd16},
   { "setend",    0xf1010000, 0,  ARM_EXT_V6,       do_setend},
-  { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smlad},
-  { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smlad},
-  { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlald},
-  { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlald},
-  { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smlad},
-  { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smlad},
-  { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlald},
-  { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlald},
-  { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smlad},
-  { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smlad},
-  { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smlad},
-  { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smlad},
-  { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smmul},
-  { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smmul},
-  { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smmul},
-  { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smmul},
-  { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smmul},
-  { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smmul},
+  { "smlad",     0xe7000010, 5,  ARM_EXT_V6,       do_smla},
+  { "smladx",    0xe7000030, 6,  ARM_EXT_V6,       do_smla},
+  { "smlald",    0xe7400010, 6,  ARM_EXT_V6,       do_smlal},
+  { "smlaldx",   0xe7400030, 7,  ARM_EXT_V6,       do_smlal},
+  { "smlsd",     0xe7000050, 5,  ARM_EXT_V6,       do_smla},
+  { "smlsdx",    0xe7000070, 6,  ARM_EXT_V6,       do_smla},
+  { "smlsld",    0xe7400050, 6,  ARM_EXT_V6,       do_smlal},
+  { "smlsldx",   0xe7400070, 7,  ARM_EXT_V6,       do_smlal},
+  { "smmla",     0xe7500010, 5,  ARM_EXT_V6,       do_smla},
+  { "smmlar",    0xe7500030, 6,  ARM_EXT_V6,       do_smla},
+  { "smmls",     0xe75000d0, 5,  ARM_EXT_V6,       do_smla},
+  { "smmlsr",    0xe75000f0, 6,  ARM_EXT_V6,       do_smla},
+  { "smmul",     0xe750f010, 5,  ARM_EXT_V6,       do_smul},
+  { "smmulr",    0xe750f030, 6,  ARM_EXT_V6,       do_smul},
+  { "smuad",     0xe700f010, 5,  ARM_EXT_V6,       do_smul},
+  { "smuadx",    0xe700f030, 6,  ARM_EXT_V6,       do_smul},
+  { "smusd",     0xe700f050, 5,  ARM_EXT_V6,       do_smul},
+  { "smusdx",    0xe700f070, 6,  ARM_EXT_V6,       do_smul},
   { "srsia",     0xf8cd0500, 0,  ARM_EXT_V6,       do_srs},
   { "srsib",     0xf9cd0500, 0,  ARM_EXT_V6,       do_srs},
   { "srsda",     0xf84d0500, 0,  ARM_EXT_V6,       do_srs},
@@ -11287,9 +11086,9 @@
   { "ssat",      0xe6a00010, 4,  ARM_EXT_V6,       do_ssat},
   { "ssat16",    0xe6a00f30, 6,  ARM_EXT_V6,       do_ssat16},
   { "strex",     0xe1800f90, 5,  ARM_EXT_V6,       do_strex},
-  { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_umaal},
-  { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smmul},
-  { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smlad},
+  { "umaal",     0xe0400090, 5,  ARM_EXT_V6,       do_smlal},
+  { "usad8",     0xe780f010, 5,  ARM_EXT_V6,       do_smul},
+  { "usada8",    0xe7800010, 6,  ARM_EXT_V6,       do_smla},
   { "usat",      0xe6e00010, 4,  ARM_EXT_V6,       do_usat},
   { "usat16",    0xe6e00f30, 6,  ARM_EXT_V6,       do_usat16},
 

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