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.
This commit is contained in:
Jan Beulich 2009-04-20 06:26:23 +00:00
parent 383c383f84
commit fcaed75e52
3 changed files with 116 additions and 7 deletions

View 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.

View 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);

View 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);