This is the mail archive of the binutils@sourceware.org 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]

[PATCH 1/2] add hooks for new Intel syntax parser


This adds some hooks (namely md_operator(), md_need_index_operator(),
and expr_set_rank()) in preparation for replacing the ad-hoc Intel
syntax parser in tc-i386.c with logic using the generic expression
parser. Intel syntax uses operators with symbolic names and hence needs
callouts from the generic parser in order to handle them.

gas/
2009-04-16  Jan Beulich  <jbeulich@novell.com>

	* expr.c (operand): Call md_need_index_operator() and
	md_operator() if defined. Add unary label.
	(operator): Call md_operator() if defined.
	(expr): Adjust assertions on range and rank of op_left and
	op_right. Don't abort on unhandled operators when reducing
	expressions with both operands being constant.
	(expr_set_rank): New.
	* expr.h (expr_set_rank): Declare.

--- 2009-04-15/gas/expr.c	2008-01-07 14:44:01.000000000 +0100
+++ 2009-04-15/gas/expr.c	2009-04-15 14:41:32.000000000 +0200
@@ -943,10 +943,15 @@ operand (expressionS *expressionP, enum 
 
       break;
 
-    case '(':
 #ifndef NEED_INDEX_OPERATOR
     case '[':
+# ifdef md_need_index_operator
+      if (md_need_index_operator())
+	goto de_fault;
+# endif
+      /* FALLTHROUGH */
 #endif
+    case '(':
       /* Didn't begin with digit & not a name.  */
       if (mode != expr_defer)
 	segment = expression (expressionP);
@@ -1004,6 +1009,9 @@ operand (expressionS *expressionP, enum 
     case '-':
     case '+':
       {
+#ifdef md_operator
+      unary:
+#endif
 	operand (expressionP, mode);
 	if (expressionP->X_op == O_constant)
 	  {
@@ -1200,7 +1208,7 @@ operand (expressionS *expressionP, enum 
 #endif
 
     default:
-#ifdef TC_M68K
+#if defined(md_need_index_operator) || defined(TC_M68K)
     de_fault:
 #endif
       if (is_name_beginner (c))	/* Here if did not begin with a digit.  */
@@ -1211,6 +1219,43 @@ operand (expressionS *expressionP, enum 
 	  name = --input_line_pointer;
 	  c = get_symbol_end ();
 
+#ifdef md_operator
+	  {
+	    operatorT operator = md_operator (name, 1, &c);
+
+	    switch (operator)
+	      {
+	      case O_uminus:
+		*input_line_pointer = c;
+		c = '-';
+		goto unary;
+	      case O_bit_not:
+		*input_line_pointer = c;
+		c = '~';
+		goto unary;
+	      case O_logical_not:
+		*input_line_pointer = c;
+		c = '!';
+		goto unary;
+	      case O_illegal:
+		as_bad (_("invalid use of operator \"%s\""), name);
+		break;
+	      default:
+		break;
+	      }
+	    if (operator != O_absent && operator != O_illegal)
+	      {
+		*input_line_pointer = c;
+		expr (9, expressionP, mode);
+		expressionP->X_add_symbol = make_expr_symbol (expressionP);
+		expressionP->X_op_symbol = NULL;
+		expressionP->X_add_number = 0;
+		expressionP->X_op = operator;
+		break;
+	      }
+	  }
+#endif
+
 #ifdef md_parse_name
 	  /* This is a hook for the backend to parse certain names
 	     specially in certain contexts.  If a name always has a
@@ -1509,6 +1554,13 @@ expr_set_precedence (void)
     }
 }
 
+void
+expr_set_rank (operatorT operator, operator_rankT rank)
+{
+  assert (operator >= O_md1 && operator < ARRAY_SIZE (op_rank));
+  op_rank[operator] = rank;
+}
+
 /* Initialize the expression parser.  */
 
 void
@@ -1540,10 +1592,50 @@ operator (int *num_chars)
   if (is_end_of_line[c])
     return O_illegal;
 
+#ifdef md_operator
+  if (is_name_beginner (c))
+    {
+      char *name = input_line_pointer;
+      char c = get_symbol_end ();
+
+      ret = md_operator (name, 2, &c);
+      switch (ret)
+	{
+	case O_absent:
+	  *input_line_pointer = c;
+	  input_line_pointer = name;
+	  break;
+	case O_uminus:
+	case O_bit_not:
+	case O_logical_not:
+	  as_bad (_("invalid use of operator \"%s\""), name);
+	  ret = O_illegal;
+	  /* FALLTHROUGH */
+	default:
+	  *input_line_pointer = c;
+	  *num_chars = input_line_pointer - name;
+	  input_line_pointer = name;
+	  return ret;
+	}
+    }
+#endif
+
   switch (c)
     {
     default:
-      return op_encoding[c];
+      ret = op_encoding[c];
+#ifdef md_operator
+      if (ret == O_illegal)
+	{
+	  char *start = input_line_pointer;
+
+	  ret = md_operator (NULL, 2, NULL);
+	  if (ret != O_illegal)
+	    *num_chars = input_line_pointer - start;
+	  input_line_pointer = start;
+	}
+#endif
+      return ret;
 
     case '+':
     case '-':
@@ -1682,10 +1774,14 @@ expr (int rankarg,		/* Larger # is highe
 
       op_right = operator (&op_chars);
 
-      know (op_right == O_illegal
+      know (op_right == O_illegal || op_left == O_index
 	    || op_rank[(int) op_right] <= op_rank[(int) op_left]);
-      know ((int) op_left >= (int) O_multiply
-	    && (int) op_left <= (int) O_index);
+      know ((int) op_left >= (int) O_multiply);
+#ifndef md_operator
+      know ((int) op_left <= (int) O_index);
+#else
+      know ((int) op_left < (int) O_max);
+#endif
 
       /* input_line_pointer->after right-hand quantity.  */
       /* left-hand quantity in resultP.  */
@@ -1781,7 +1877,7 @@ expr (int rankarg,		/* Larger # is highe
 	    }
 	  switch (op_left)
 	    {
-	    default:			abort ();
+	    default:			goto general;
 	    case O_multiply:		resultP->X_add_number *= v; break;
 	    case O_divide:		resultP->X_add_number /= v; break;
 	    case O_modulus:		resultP->X_add_number %= v; break;
@@ -1856,6 +1952,7 @@ expr (int rankarg,		/* Larger # is highe
 	}
       else
 	{
+        general:
 	  /* The general case.  */
 	  resultP->X_add_symbol = make_expr_symbol (resultP);
 	  resultP->X_op_symbol = make_expr_symbol (&right);
--- 2009-04-15/gas/expr.h	2007-08-22 11:01:50.000000000 +0200
+++ 2009-04-15/gas/expr.h	2008-02-14 10:28:03.000000000 +0100
@@ -169,6 +169,7 @@ typedef char operator_rankT;
 extern char get_symbol_end (void);
 extern void expr_begin (void);
 extern void expr_set_precedence (void);
+extern void expr_set_rank (operatorT, operator_rankT);
 extern segT expr (int, expressionS *, enum expr_mode);
 extern unsigned int get_single_number (void);
 extern symbolS *make_expr_symbol (expressionS * expressionP);



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