diff options
-rw-r--r-- | gas/config/tc-hppa.c | 1 | ||||
-rw-r--r-- | gas/config/tc-ppc.c | 6 | ||||
-rw-r--r-- | gas/doc/internals.texi | 8 | ||||
-rw-r--r-- | gas/expr.c | 47 |
4 files changed, 40 insertions, 22 deletions
diff --git a/gas/config/tc-hppa.c b/gas/config/tc-hppa.c index c91b2b5..2e5de07 100644 --- a/gas/config/tc-hppa.c +++ b/gas/config/tc-hppa.c @@ -6354,6 +6354,7 @@ hppa_force_reg_syms_absolute (expressionS *resultP, expressionS *rightP) { if (fudge_reg_expressions + && resultP && rightP->X_op == O_register && resultP->X_op == O_register) { diff --git a/gas/config/tc-ppc.c b/gas/config/tc-ppc.c index 8b1d995..a8b034c 100644 --- a/gas/config/tc-ppc.c +++ b/gas/config/tc-ppc.c @@ -945,9 +945,9 @@ ppc_optimize_expr (expressionS *left, operatorT op, expressionS *right) } /* Accept the above plus <cr bit>, and <cr bit> plus the above. */ - if (right->X_op == O_register + if (op == O_add && left->X_op == O_register - && op == O_add + && right->X_op == O_register && ((right->X_md == PPC_OPERAND_CR_BIT && left->X_md == (PPC_OPERAND_CR_REG | PPC_OPERAND_CR_BIT)) || (right->X_md == (PPC_OPERAND_CR_REG | PPC_OPERAND_CR_BIT) @@ -959,7 +959,7 @@ ppc_optimize_expr (expressionS *left, operatorT op, expressionS *right) } /* Accept reg +/- constant. */ - if (left->X_op == O_register + if (left && left->X_op == O_register && !((op == O_add || op == O_subtract) && right->X_op == O_constant)) as_warn (_("invalid register expression")); diff --git a/gas/doc/internals.texi b/gas/doc/internals.texi index 56f10fd..3eea25b 100644 --- a/gas/doc/internals.texi +++ b/gas/doc/internals.texi @@ -1047,6 +1047,14 @@ pointer, for any expression that can not be recognized. When the function is called, @code{input_line_pointer} will point to the start of the expression. +@item md_optimize_expr +@cindex md_optimize_expr +GAS will call this function before trying to carry out certain operations, +like the adding of two constants. The function is passed the left-hand +operand, an @code{expressionS} pointer, the operator, an @code{operatorT} +value, and the right-hand operand, again an @code{expressionS} pointer. For +unary expressions NULL is passed as first argument. + @item md_register_arithmetic @cindex md_register_arithmetic If this macro is defined and evaluates to zero then GAS will not fold @@ -764,6 +764,7 @@ operand (expressionS *expressionP, enum expr_mode mode) symbolS *symbolP; /* Points to symbol. */ char *name; /* Points to name of symbol. */ segT segment; + operatorT op = O_absent; /* For unary operators. */ /* All integers are regarded as unsigned unless they are negated. This is because the only thing which cares whether a number is @@ -1029,19 +1030,33 @@ operand (expressionS *expressionP, enum expr_mode mode) /* '~' is permitted to start a label on the Delta. */ if (is_name_beginner (c)) goto isname; - /* Fall through. */ + op = O_bit_not; + goto unary; + case '!': + op = O_logical_not; + goto unary; + case '-': + op = O_uminus; + /* Fall through. */ case '+': { -#ifdef md_operator unary: -#endif operand (expressionP, mode); + +#ifdef md_optimize_expr + if (md_optimize_expr (NULL, op, expressionP)) + { + /* Skip. */ + ; + } + else +#endif if (expressionP->X_op == O_constant) { /* input_line_pointer -> char after operand. */ - if (c == '-') + if (op == O_uminus) { expressionP->X_add_number = - (addressT) expressionP->X_add_number; @@ -1052,13 +1067,13 @@ operand (expressionS *expressionP, enum expr_mode mode) if (expressionP->X_add_number) expressionP->X_extrabit ^= 1; } - else if (c == '~' || c == '"') + else if (op == O_bit_not) { expressionP->X_add_number = ~ expressionP->X_add_number; expressionP->X_extrabit ^= 1; expressionP->X_unsigned = 0; } - else if (c == '!') + else if (op == O_logical_not) { expressionP->X_add_number = ! expressionP->X_add_number; expressionP->X_unsigned = 1; @@ -1067,7 +1082,7 @@ operand (expressionS *expressionP, enum expr_mode mode) } else if (expressionP->X_op == O_big && expressionP->X_add_number <= 0 - && c == '-' + && op == O_uminus && (generic_floating_point_number.sign == '+' || generic_floating_point_number.sign == 'P')) { @@ -1082,7 +1097,7 @@ operand (expressionS *expressionP, enum expr_mode mode) { int i; - if (c == '~' || c == '-') + if (op == O_uminus || op == O_bit_not) { for (i = 0; i < expressionP->X_add_number; ++i) generic_bignum[i] = ~generic_bignum[i]; @@ -1095,7 +1110,7 @@ operand (expressionS *expressionP, enum expr_mode mode) generic_bignum[i] = ~(LITTLENUM_TYPE) 0; } - if (c == '-') + if (op == O_uminus) for (i = 0; i < expressionP->X_add_number; ++i) { generic_bignum[i] += 1; @@ -1103,7 +1118,7 @@ operand (expressionS *expressionP, enum expr_mode mode) break; } } - else if (c == '!') + else if (op == O_logical_not) { for (i = 0; i < expressionP->X_add_number; ++i) if (generic_bignum[i] != 0) @@ -1117,15 +1132,10 @@ operand (expressionS *expressionP, enum expr_mode mode) else if (expressionP->X_op != O_illegal && expressionP->X_op != O_absent) { - if (c != '+') + if (op != O_absent) { expressionP->X_add_symbol = make_expr_symbol (expressionP); - if (c == '-') - expressionP->X_op = O_uminus; - else if (c == '~' || c == '"') - expressionP->X_op = O_bit_not; - else - expressionP->X_op = O_logical_not; + expressionP->X_op = op; expressionP->X_add_number = 0; } else if (!md_register_arithmetic && expressionP->X_op == O_register) @@ -1288,8 +1298,7 @@ operand (expressionS *expressionP, enum expr_mode mode) #ifdef md_operator { - operatorT op = md_operator (name, 1, &c); - + op = md_operator (name, 1, &c); switch (op) { case O_uminus: |