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


Cleanup: return values from some of the parse_* functions instead of
using out-parameters.  Also, some rearrangement to remove duplicate
code in parse_operands.

zw

	* config/tc-arm.c (parse_cps_flags, parse_endian_specifier, parse_ror):
	On success, return the value instead of poking it into an out-parameter.
	(parse_operands): Migrate value checks to a second switch statement
	for compactness and clarity.  Update to match above interface changes.

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 40)
+++ gas/config/tc-arm.c	(revision 41)
@@ -2454,12 +2454,11 @@
   return SUCCESS;
 }
 
-/* Parse the flags argument to CPSI[ED].  Returns SUCCESS or FAIL as
-   appropriate; on success, *valp gets a value suitable for splatting
-   into the AIF field of the instruction.  */
+/* Parse the flags argument to CPSI[ED].  Returns FAIL on error, or a
+   value suitable for splatting into the AIF field of the instruction.  */
 
 static int
-parse_cps_flags (int *valp, char **str)
+parse_cps_flags (char **str)
 {
   int val = 0;
   int saw_a_flag = 0;
@@ -2488,8 +2487,7 @@
     }
 
   *str = s - 1;
-  *valp = val;
-  return SUCCESS;
+  return val;
 }
 
 static int
@@ -2515,11 +2513,10 @@
 }
 
 /* Parse an endian specifier ("BE" or "LE", case insensitive);
-   write 0 into *val for big-endian, 1 for little-endian; return
-   SUCCESS for successful parse, or FAIL and set inst.error.  */
+   returns 0 for big-endian, 1 for little-endian, FAIL for an error.  */
 
 static int
-parse_endian_specifier (int *val, char **str)
+parse_endian_specifier (char **str)
 {
   int little_endian;
   char *s = *str;
@@ -2540,17 +2537,16 @@
       return FAIL;
     }
 
-  *val = little_endian;
   *str = s + 2;
-  return SUCCESS;
+  return little_endian;
 }
 
 /* Parse a rotation specifier: ROR #0, #8, #16, #24.  *val receives a
    value suitable for poking into the rotate field of an sxt or sxta
-   instruction.  */
+   instruction, or FAIL on error.  */
 
 static int
-parse_ror (int *val, char **str)
+parse_ror (char **str)
 {
   int rot;
   char *s = *str;
@@ -2568,17 +2564,15 @@
 
   switch (rot)
     {
-    case  0: *val = 0x0; break;
-    case  8: *val = 0x1; break;
-    case 16: *val = 0x2; break;
-    case 24: *val = 0x3; break;
+    case  0: *str = s; return 0x0;
+    case  8: *str = s; return 0x1;
+    case 16: *str = s; return 0x2;
+    case 24: *str = s; return 0x3;
 
     default:
       inst.error = _("rotation can only be 0, 8, 16, or 24");
       return FAIL;
     }
-  *str = s;
-  return SUCCESS;
 }
 
 /* Directives: register aliases.  */
@@ -4405,6 +4399,9 @@
       switch (*p)
 	{
 	  /* Registers */
+	case OP_(RRnpc):
+	case OP_(oRL):
+	case OP_(RL):
 	case OP_(RR):    po_reg_or_fail (REG_TYPE_RN);      break;
 	case OP_(RCP):   po_reg_or_fail (REG_TYPE_CP);      break;
 	case OP_(RCN):   po_reg_or_fail (REG_TYPE_CN);      break;
@@ -4423,28 +4420,15 @@
 	case OP_(RIWG):  po_reg_or_fail (REG_TYPE_MMXWCG);  break;
 	case OP_(RXA):   po_reg_or_fail (REG_TYPE_XSCALE);  break;
 
-	  /* Register variants */
-	case OP_(RRnpc):
-	  po_reg_or_fail (REG_TYPE_RN);
-	  if (inst.operands[i].reg == REG_PC)
-	    inst.error = BAD_PC;
-	  /* We do not signal an immediate failure for the PC; this
-	     allows a syntax error to take precedence.  The error will
-	     be caught by output_inst.  */
-	  break;
-
 	case OP_(bRRnpc):
 	  po_char_or_fail ('[');
 	  po_reg_or_fail  (REG_TYPE_RN);
 	  po_char_or_fail (']');
-	  if (inst.operands[i].reg == REG_PC)
-	    inst.error = BAD_PC;
 	  break;
 
+	case OP_(RLw):
 	case OP_(RRw):
 	  po_reg_or_fail (REG_TYPE_RN);
-	  if (inst.operands[i].reg == REG_PC)
-	    inst.error = BAD_PC;
 	  if (*str == '!')
 	    {
 	      inst.operands[i].writeback = 1;
@@ -4452,38 +4436,16 @@
 	    }
 	  break;
 
-	case OP_(oRL):
-	case OP_(RL):
-	  po_reg_or_fail (REG_TYPE_RN);
-	  if (inst.operands[i].reg > 7)
-	    inst.error = BAD_HIREG;
-	  break;
-
 	case OP_(RLlb):
 	  po_char_or_fail ('[');
 	  po_reg_or_fail (REG_TYPE_RN);
-	  if (inst.operands[i].reg > 7)
-	    inst.error = BAD_HIREG;
 	  break;
 
 	case OP_(RLtb):
 	  po_reg_or_fail (REG_TYPE_RN);
 	  po_char_or_fail (']');
-	  if (inst.operands[i].reg > 7)
-	    inst.error = BAD_HIREG;
 	  break;
 
-	case OP_(RLw):
-	  po_reg_or_fail (REG_TYPE_RN);
-	  if (inst.operands[i].reg > 7)
-	    inst.error = BAD_HIREG;
-	  if (*str == '!')
-	    {
-	      inst.operands[i].writeback = 1;
-	      str++;
-	    }
-	  break;
-
 	  /* Immediates */
 	I0:
 	case OP_(I0):	 po_imm_or_fail (  0,      0, FALSE);	break;
@@ -4566,21 +4528,12 @@
 	  /* Register or expression */
 	case OP_(RR_EX):  po_reg_or_goto (REG_TYPE_RN, EXP);  break;
 	case OP_(RR_EXr): po_reg_or_goto (REG_TYPE_RN, EXPr); break;
-	case OP_(RR_iEX): po_reg_or_goto (REG_TYPE_RN, iEXP); break;
-
 	case OP_(oRL_iEX):
 	case OP_(RL_iEX):
-	  po_reg_or_goto (REG_TYPE_RN, iEXP);
-	  if (inst.operands[i].reg > 7)
-	    inst.error = BAD_HIREG;
-	  break;
+	case OP_(RR_iEX): po_reg_or_goto (REG_TYPE_RN, iEXP); break;
 
 	  /* Register or immediate */
-	case OP_(RRnpc_I0):
-	  po_reg_or_goto (REG_TYPE_RN, I0);
-	  if (inst.operands[i].reg == REG_PC)
-	    inst.error = BAD_PC;
-	  break;
+	case OP_(RRnpc_I0): po_reg_or_goto (REG_TYPE_RN, I0); break;
 
 	case OP_(RF_IF):
 	  if (!is_immediate_prefix (*str))
@@ -4599,31 +4552,14 @@
 	  break;
 
 	  /* Misc */
-	case OP_(CPSF):
-	  if (parse_cps_flags (&inst.operands[i].imm, &str))
-	    return FAIL;
-	  break;
+	case OP_(CPSF):	 val = parse_cps_flags (&str);		break;
+	case OP_(ENDI):	 val = parse_endian_specifier (&str);	break;
+	case OP_(oROR):	 val = parse_ror (&str);		break;
+	case OP_(PSR):	 val = parse_psr (&str);		break;
 
-	case OP_(ENDI):
-	  if (parse_endian_specifier (&inst.operands[i].imm, &str))
-	    return FAIL;
-	  break;
-
-	case OP_(oROR):
-	  if (parse_ror (&inst.operands[i].imm, &str))
-	    return FAIL;
-	  break;
-
-	case OP_(PSR):
-	  if ((val = parse_psr (&str)) == FAIL)
-	    return FAIL;
-	  inst.operands[i].imm = val;
-	  break;
-
+	  /* Register lists */
 	case OP_(REGLST):
-	  if ((val = reg_list (&str)) == FAIL)
-	    return FAIL;
-	  inst.operands[i].imm = val;
+	  val = reg_list (&str);
 	  if (*str == '^')
 	    {
 	      inst.operands[1].writeback = 1;
@@ -4633,20 +4569,56 @@
 
 	case OP_(VRSLST):
 	  val = vfp_parse_reg_list (&str, &inst.operands[i].reg, 0);
-	  goto vfp_reglist;
+	  break;
 
 	case OP_(VRDLST):
 	  val = vfp_parse_reg_list (&str, &inst.operands[i].reg, 1);
+	  break;
 
-	vfp_reglist:
+	default:
+	  as_fatal ("unhandled operand code %03o", *p);
+	}
+
+      /* Various value-based sanity checks and shared operations.  We
+	 do not signal immediate failures for the register constraints;
+	 this allows a syntax error to take precedence.  */
+      switch (*p)
+	{
+	case OP_(RRnpc):
+	case OP_(bRRnpc):
+	case OP_(RRw):
+	case OP_(RRnpc_I0):
+	  if (inst.operands[i].isreg && inst.operands[i].reg == REG_PC)
+	    inst.error = BAD_PC;
+	  break;
+
+	case OP_(oRL):
+	case OP_(RL):
+	case OP_(RLlb):
+	case OP_(RLtb):
+	case OP_(RLw):
+	case OP_(oRL_iEX):
+	case OP_(RL_iEX):
+	  if (inst.operands[i].isreg && inst.operands[i].reg > 7)
+	    inst.error = BAD_HIREG;
+	  break;
+
+	case OP_(CPSF):
+	case OP_(ENDI):
+	case OP_(oROR):
+	case OP_(PSR):
+	case OP_(REGLST):
+	case OP_(VRSLST):
+	case OP_(VRDLST):
 	  if (val == FAIL)
 	    return FAIL;
 	  inst.operands[i].imm = val;
 	  break;
 
 	default:
-	  as_fatal ("unhandled operand code %03o", *p);
+	  break;
 	}
+      
       /* If we get here, this operand was successfully parsed.  */
       inst.operands[i].present = 1;
 

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