gas/
authorJan Beulich <jbeulich@novell.com>
Mon, 20 Apr 2009 06:26:23 +0000 (06:26 +0000)
committerJan Beulich <jbeulich@novell.com>
Mon, 20 Apr 2009 06:26:23 +0000 (06:26 +0000)
2009-04-20  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.

gas/ChangeLog
gas/expr.c
gas/expr.h

index a3442b36c0a1e3e20efde5677ee53b343e88cc25..cf41843190defd1a95ea0753ca133b80fbc6b748 100644 (file)
@@ -1,3 +1,14 @@
+2009-04-20  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.
+
 2008-04-15  Anthony Green  <green@moxielogic.com>
 
        * config/tc-moxie.h: New file.
index 39f21ef797ed4bc26d5ca13ae2cc9d61055f264c..a75be2c1ea850ccef73954866ec1a5ef6a88ad08 100644 (file)
@@ -950,10 +950,15 @@ operand (expressionS *expressionP, enum expr_mode mode)
 
       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);
@@ -1011,6 +1016,9 @@ operand (expressionS *expressionP, enum expr_mode mode)
     case '-':
     case '+':
       {
+#ifdef md_operator
+      unary:
+#endif
        operand (expressionP, mode);
        if (expressionP->X_op == O_constant)
          {
@@ -1207,7 +1215,7 @@ operand (expressionS *expressionP, enum expr_mode mode)
 #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.  */
@@ -1218,6 +1226,43 @@ operand (expressionS *expressionP, enum expr_mode mode)
          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
@@ -1516,6 +1561,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
@@ -1547,10 +1599,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 '-':
@@ -1689,10 +1781,14 @@ expr (int rankarg,              /* Larger # is higher rank.  */
 
       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.  */
@@ -1796,7 +1892,7 @@ expr (int rankarg,                /* Larger # is higher rank.  */
            }
          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;
@@ -1871,6 +1967,7 @@ expr (int rankarg,                /* Larger # is higher rank.  */
        }
       else
        {
+        general:
          /* The general case.  */
          resultP->X_add_symbol = make_expr_symbol (resultP);
          resultP->X_op_symbol = make_expr_symbol (&right);
index 789decf48fc5edf6fa05ea02ea528039fadc2a0e..2952a12cbacdafe71e81106b98fa99dc917c6b3c 100644 (file)
@@ -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);