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


Move the processing of (occasionally) optional immediate prefixes into
my_get_expression from its callers.  This will facilitate a future
change (not in this patch series) to make all immediate prefixes
optional, as is recommended by the ARM "new assembly syntax"
supplement.  I haven't done that for this patch series because it
would require lots of careful testing and it's tangential.

zw

	* config/tc-arm.c (my_get_expression): Add handling of immediate
        prefix, under control of third tristate argument.
	(GE_NO_PREFIX, GE_IMM_PREFIX, GE_OPT_PREFIX): New macros.
	(expression_or_fail): Pass down third argument.
	(immediate_required_here, decode_shift, data_op2)
	(cp_address_required_here, parse_thumb_address, parse_operands):
	Update to match.  No need to handle immediate prefix here.
	(reg_list, ldst_extend, ldst_extend_v4, ld_mode_required_here)
	(do_ldst, do_ldstv4): Update to match.
	(cp_address_offset): Merge into cp_address_required_here.

===================================================================
Index: gas/config/tc-arm.c
--- gas/config/tc-arm.c	(revision 47)
+++ gas/config/tc-arm.c	(revision 48)
@@ -707,12 +707,35 @@
 
 static int in_my_get_expression = 0;
 
+/* Third argument to my_get_expression.  */
+#define GE_NO_PREFIX 0
+#define GE_IMM_PREFIX 1
+#define GE_OPT_PREFIX 2
+
 static int
-my_get_expression (expressionS * ep, char ** str)
+my_get_expression (expressionS * ep, char ** str, int prefix_mode)
 {
   char * save_in;
   segT   seg;
 
+  switch (prefix_mode)
+    {
+    case GE_NO_PREFIX: break;
+    case GE_IMM_PREFIX:
+      if (!is_immediate_prefix (**str))
+	{
+	  inst.error = _("immediate expression requires a # prefix");
+	  return FAIL;
+	}
+      (*str)++;
+      break;
+    case GE_OPT_PREFIX:
+      if (is_immediate_prefix (**str))
+	(*str)++;
+      break;
+    default: abort ();
+    }
+
   memset (ep, 0, sizeof (expressionS));
 
   save_in = input_line_pointer;
@@ -765,9 +788,9 @@
   return 0;
 }
 
-#define expression_or_fail(exp, str)		\
+#define expression_or_fail(exp, str, pmode)	\
 do {						\
-  if (my_get_expression (exp, str))		\
+  if (my_get_expression (exp, str, pmode))	\
     return;					\
  } while (0)
 
@@ -972,16 +995,7 @@
 			 bfd_boolean prefix_opt)
 {
   expressionS exp;
-
-  if (is_immediate_prefix (**str))
-    (*str)++;
-  else if (!prefix_opt)
-    {
-      inst.error = _("immediate expression requires a # prefix");
-      return FAIL;
-    }
-
-  my_get_expression (&exp, str);
+  my_get_expression (&exp, str, prefix_opt ? GE_OPT_PREFIX : GE_IMM_PREFIX);
   if (exp.X_op != O_constant)
     {
       inst.error = _("constant expression required");
@@ -1332,7 +1346,7 @@
 	{
 	  expressionS expr;
 
-	  if (my_get_expression (&expr, &str))
+	  if (my_get_expression (&expr, &str, GE_NO_PREFIX))
 	    return FAIL;
 
 	  if (expr.X_op == O_constant)
@@ -1505,25 +1519,22 @@
 /* KIND indicates what kind of shifts are accepted.  */
 
 static int
-decode_shift (char ** str, int kind)
+decode_shift (char **str, int kind)
 {
-  const struct asm_shift_name * shift;
-  char * p;
-  char   c;
+  const struct asm_shift_name *shift;
+  int reg;
+  char *p;
 
-  for (p = * str; ISALPHA (* p); p ++)
+  for (p = *str; ISALPHA (*p); p++)
     ;
 
-  if (p == * str)
+  if (p == *str)
     {
       inst.error = _("shift expression expected");
       return FAIL;
     }
 
-  c = * p;
-  * p = '\0';
-  shift = (const struct asm_shift_name *) hash_find (arm_shift_hsh, * str);
-  * p = c;
+  shift = hash_find_n (arm_shift_hsh, *str, p - *str);
 
   if (shift == NULL)
     {
@@ -1531,7 +1542,8 @@
       return FAIL;
     }
 
-  assert (shift->properties->index == shift_properties[shift->properties->index].index);
+  assert (shift->properties->index ==
+	  shift_properties[shift->properties->index].index);
 
   if (kind == SHIFT_LSL_OR_ASR_IMMEDIATE
       && shift->properties->index != SHIFT_LSL
@@ -1555,7 +1567,7 @@
 
   if (shift->properties->index == SHIFT_RRX)
     {
-      * str = p;
+      *str = p;
       inst.instruction |= shift->properties->bit_field;
       return SUCCESS;
     }
@@ -1563,25 +1575,14 @@
   skip_whitespace (p);
 
   if (kind == NO_SHIFT_RESTRICT
-      && reg_required_here (& p, 8, REG_TYPE_RN) != FAIL)
+      && (reg = arm_reg_parse (&p, REG_TYPE_RN)) != FAIL)
     {
       inst.instruction |= shift->properties->bit_field | SHIFT_BY_REG;
-      * str = p;
+      inst.instruction |= reg << 8;
+      *str = p;
       return SUCCESS;
     }
-  else if (! is_immediate_prefix (* p))
-    {
-      inst.error = (NO_SHIFT_RESTRICT
-		    ? _("shift requires register or #expression")
-		    : _("shift requires #expression"));
-      * str = p;
-      return FAIL;
-    }
-
-  inst.error = NULL;
-  p ++;
-
-  if (my_get_expression (& inst.reloc.exp, & p))
+  else if (my_get_expression (&inst.reloc.exp, &p, GE_IMM_PREFIX))
     return FAIL;
 
   /* Validate some simple #expressions.  */
@@ -1726,85 +1727,72 @@
   int value;
   expressionS expr;
 
-  if (reg_required_here (str, 0, REG_TYPE_RN) != FAIL)
+  if ((value = arm_reg_parse (str, REG_TYPE_RN)) != FAIL)
     {
+      inst.instruction |= value;
       if (skip_past_comma (str) == SUCCESS)
 	/* Shift operation on register.  */
 	return decode_shift (str, NO_SHIFT_RESTRICT);
 
       return SUCCESS;
     }
+  else if (my_get_expression (&inst.reloc.exp, str, GE_IMM_PREFIX))
+    return FAIL;
+
+  if (inst.reloc.exp.X_add_symbol)
+    {
+      inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
+      inst.reloc.pc_rel = 0;
+    }
   else
     {
-      /* Immediate expression.  */
-      if (is_immediate_prefix (**str))
+      if (skip_past_comma (str) == SUCCESS)
 	{
-	  (*str)++;
-	  inst.error = NULL;
-
-	  if (my_get_expression (&inst.reloc.exp, str))
+	  /* #x, y -- ie explicit rotation by Y.  */
+	  if (my_get_expression (&expr, str, GE_NO_PREFIX))
 	    return FAIL;
 
-	  if (inst.reloc.exp.X_add_symbol)
+	  if (expr.X_op != O_constant)
 	    {
-	      inst.reloc.type = BFD_RELOC_ARM_IMMEDIATE;
-	      inst.reloc.pc_rel = 0;
+	      inst.error = _("constant expression expected");
+	      return FAIL;
 	    }
-	  else
-	    {
-	      if (skip_past_comma (str) == SUCCESS)
-		{
-		  /* #x, y -- ie explicit rotation by Y.  */
-		  if (my_get_expression (&expr, str))
-		    return FAIL;
 
-		  if (expr.X_op != O_constant)
-		    {
-		      inst.error = _("constant expression expected");
-		      return FAIL;
-		    }
-
-		  /* Rotate must be a multiple of 2.  */
-		  if (((unsigned) expr.X_add_number) > 30
-		      || (expr.X_add_number & 1) != 0
-		      || ((unsigned) inst.reloc.exp.X_add_number) > 255)
-		    {
-		      inst.error = _("invalid constant");
-		      return FAIL;
-		    }
-		  inst.instruction |= INST_IMMEDIATE;
-		  inst.instruction |= inst.reloc.exp.X_add_number;
-		  inst.instruction |= expr.X_add_number << 7;
-		  return SUCCESS;
-		}
-
-	      /* Implicit rotation, select a suitable one.  */
-	      value = validate_immediate (inst.reloc.exp.X_add_number);
-
-	      if (value == FAIL)
-		{
-		  /* Can't be done.  Perhaps the code reads something like
-		     "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
-		  if ((value = negate_data_op (&inst.instruction,
-					       inst.reloc.exp.X_add_number))
-		      == FAIL)
-		    {
-		      inst.error = _("invalid constant");
-		      return FAIL;
-		    }
-		}
-
-	      inst.instruction |= value;
+	  /* Rotate must be a multiple of 2.  */
+	  if (((unsigned) expr.X_add_number) > 30
+	      || (expr.X_add_number & 1) != 0
+	      || ((unsigned) inst.reloc.exp.X_add_number) > 255)
+	    {
+	      inst.error = _("invalid constant");
+	      return FAIL;
 	    }
-
 	  inst.instruction |= INST_IMMEDIATE;
+	  inst.instruction |= inst.reloc.exp.X_add_number;
+	  inst.instruction |= expr.X_add_number << 7;
 	  return SUCCESS;
 	}
 
-      (*str)++;
-      inst.error = _("register or shift expression expected");
-      return FAIL;
+      /* Implicit rotation, select a suitable one.  */
+      value = validate_immediate (inst.reloc.exp.X_add_number);
+
+      if (value == FAIL)
+	{
+	  /* Can't be done.  Perhaps the code reads something like
+	     "add Rd, Rn, #-n", where "sub Rd, Rn, #n" would be OK.  */
+	  if ((value = negate_data_op (&inst.instruction,
+				       inst.reloc.exp.X_add_number))
+	      == FAIL)
+	    {
+	      inst.error = _("invalid constant");
+	      return FAIL;
+	    }
+	}
+
+      inst.instruction |= value;
     }
+
+  inst.instruction |= INST_IMMEDIATE;
+  return SUCCESS;
 }
 
 /* Parse an explicit relocation suffix on an expression.  This is
@@ -1846,7 +1834,7 @@
     case '#':
     case '$':
       (*str)++;
-      if (my_get_expression (& inst.reloc.exp, str))
+      if (my_get_expression (& inst.reloc.exp, str, GE_NO_PREFIX))
 	return FAIL;
 
       if (inst.reloc.exp.X_op == O_constant)
@@ -1904,7 +1892,7 @@
     case '#':
     case '$':
       (*str)++;
-      if (my_get_expression (& inst.reloc.exp, str))
+      if (my_get_expression (& inst.reloc.exp, str, GE_NO_PREFIX))
 	return FAIL;
 
       if (inst.reloc.exp.X_op == O_constant)
@@ -2028,7 +2016,7 @@
     return FAIL;
   else				/* PC +- 8 bit immediate offset.  */
     {
-      if (my_get_expression (& inst.reloc.exp, & str))
+      if (my_get_expression (& inst.reloc.exp, & str, GE_NO_PREFIX))
 	return FAIL;
 
       inst.instruction            |= HWOFFSET_IMM;	/* The I bit.  */
@@ -2109,23 +2097,6 @@
 }
 
 static int
-cp_address_offset (char ** str, int reloc)
-{
-  if (! is_immediate_prefix (**str))
-    {
-      inst.error = _("immediate expression expected");
-      return FAIL;
-    }
-  (*str)++;
-  if (my_get_expression (& inst.reloc.exp, str))
-    return FAIL;
-
-  inst.reloc.type = reloc;
-
-  return SUCCESS;
-}
-
-static int
 cp_address_required_here (char ** str, int wb_ok, int reloc)
 {
   char * p = * str;
@@ -2175,8 +2146,9 @@
 		      return FAIL;
 		    }
 
-		  if (cp_address_offset (&p, reloc) == FAIL)
+		  if (my_get_expression (& inst.reloc.exp, &p, GE_IMM_PREFIX))
 		    return FAIL;
+		  inst.reloc.type = reloc;
 		}
 	      else
 		pre_inc = PRE_INDEX | INDEX_UP;
@@ -2218,11 +2190,11 @@
 	      return FAIL;
 	    }
 
+	  if (my_get_expression (& inst.reloc.exp, &p, GE_IMM_PREFIX))
+	    return FAIL;
+	  inst.reloc.type = reloc;
 	  pre_inc = PRE_INDEX;
 
-	  if (cp_address_offset (&p, reloc) == FAIL)
-	    return FAIL;
-
 	  if (*p++ != ']')
 	    {
 	      inst.error = _("missing ]");
@@ -2244,7 +2216,7 @@
     }
   else
     {
-      if (my_get_expression (&inst.reloc.exp, &p))
+      if (my_get_expression (&inst.reloc.exp, &p, GE_NO_PREFIX))
 	return FAIL;
 
       inst.reloc.type = reloc;
@@ -2291,16 +2263,8 @@
       inst.operands[i].isreg = 1;
       if (skip_past_comma (&s) != FAIL)
 	{
-	  if (is_immediate_prefix (*s))
+	  if ((Ro = arm_reg_parse (&s, REG_TYPE_RN)) != FAIL)
 	    {
-	      s++;
-	      if (my_get_expression (&inst.reloc.exp, &s))
-		return FAIL;
-	    }
-	  else
-	    {
-	      if ((Ro = arm_reg_parse (&s, REG_TYPE_RN)) == FAIL)
-		return FAIL;
 	      if (Ro > 7 || Rb > 7)
 		{
 		  inst.error = BAD_HIREG;
@@ -2309,6 +2273,8 @@
 	      inst.operands[i].imm = Ro;
 	      inst.operands[i].immisreg = 1;
 	    }
+	  else if (my_get_expression (&inst.reloc.exp, &s, GE_IMM_PREFIX))
+	    return FAIL;
 	}
       else
 	{
@@ -2325,7 +2291,7 @@
   else if (*s == '=')
     {
       s++;
-      if (my_get_expression (&inst.reloc.exp, &s))
+      if (my_get_expression (&inst.reloc.exp, &s, GE_NO_PREFIX))
 	return FAIL;
 
       if (   inst.reloc.exp.X_op != O_constant
@@ -2337,7 +2303,7 @@
     }
   else
     {
-      if (my_get_expression (&inst.reloc.exp, &s))
+      if (my_get_expression (&inst.reloc.exp, &s, GE_NO_PREFIX))
 	return FAIL;
 
       inst.reloc.exp.X_add_number -= 4; /* Pipeline offset.  */
@@ -4363,19 +4329,19 @@
 	  /* Expressions */
 	case OP_(iEXP):
 	iEXP:
-	  if (is_immediate_prefix (*str))
-	    str++;
-	  /* fall through */
+	  if (my_get_expression (&inst.reloc.exp, &str, GE_OPT_PREFIX))
+	    return FAIL;
+	  break;
 
 	case OP_(EXP):
 	EXP:
-	  if (my_get_expression (&inst.reloc.exp, &str))
+	  if (my_get_expression (&inst.reloc.exp, &str, GE_NO_PREFIX))
 	    return FAIL;
 	  break;
 
 	case OP_(EXPr):
 	EXPr:
-	  if (my_get_expression (&inst.reloc.exp, &str))
+	  if (my_get_expression (&inst.reloc.exp, &str, GE_NO_PREFIX))
 	    return FAIL;
 	  if (inst.reloc.exp.X_op == O_symbol)
 	    {
@@ -5124,7 +5090,7 @@
       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
       str++;
 
-      expression_or_fail (&inst.reloc.exp, &str);
+      expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX);
 
       if (inst.reloc.exp.X_op != O_constant
 	  && inst.reloc.exp.X_op != O_symbol)
@@ -5178,7 +5144,7 @@
     }
   else
     {
-      expression_or_fail (&inst.reloc.exp, &str);
+      expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX);
 
       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM;
 #ifndef TE_WINCE
@@ -5351,7 +5317,7 @@
       /* Parse an "ldr Rd, =expr" instruction; this is another pseudo op.  */
       str++;
 
-      expression_or_fail (&inst.reloc.exp, &str);
+      expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX);
 
       if (inst.reloc.exp.X_op != O_constant
 	  && inst.reloc.exp.X_op != O_symbol)
@@ -5404,7 +5370,7 @@
     }
   else
     {
-      expression_or_fail (&inst.reloc.exp, &str);
+      expression_or_fail (&inst.reloc.exp, &str, GE_NO_PREFIX);
 
       inst.instruction |= HWOFFSET_IMM;
       inst.reloc.type = BFD_RELOC_ARM_OFFSET_IMM8;

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