diff options
-rw-r--r-- | gas/ChangeLog | 11 | ||||
-rw-r--r-- | gas/config/tc-i386.h | 2 | ||||
-rw-r--r-- | gas/config/tc-ia64.h | 1 | ||||
-rw-r--r-- | gas/doc/internals.texi | 10 | ||||
-rw-r--r-- | gas/expr.c | 16 |
5 files changed, 36 insertions, 4 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog index 6a9bb54..9cf0f71 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,5 +1,16 @@ 2007-09-26 Jan Beulich <jbeulich@novell.com> + * config/tc-i386.h (md_register_arithmetic): Define. + * config/tc-ia64.h (md_register_arithmetic): Likewise. + * doc/internals.texi: Document md_register_arithmetic. + * expr.c (make_expr_symbol): Force O_register expressions into + reg_section. + (expr): Provide default for md_register_arithmetic. Don't resolve + adding/subtracting constants to/from registers if + md_register_arithmetic is zero. + +2007-09-26 Jan Beulich <jbeulich@novell.com> + * dw2gencfi.c: Conditionalize whole body upon TARGET_USE_CFIPOP. (cfi_finish): Add second empty instance. diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index e55d5ca..65e300a 100644 --- a/gas/config/tc-i386.h +++ b/gas/config/tc-i386.h @@ -272,6 +272,8 @@ extern int tc_i386_fix_adjustable (struct fix *); extern int i386_parse_name (char *, expressionS *, char *); #define md_parse_name(s, e, m, c) i386_parse_name (s, e, c) +#define md_register_arithmetic 0 + extern const struct relax_type md_relax_table[]; #define TC_GENERIC_RELAX_TABLE md_relax_table diff --git a/gas/config/tc-ia64.h b/gas/config/tc-ia64.h index 725e6ea..d0b0b1b 100644 --- a/gas/config/tc-ia64.h +++ b/gas/config/tc-ia64.h @@ -130,6 +130,7 @@ extern void ia64_convert_frag (fragS *); #endif /* TE_HPUX */ #define md_flush_pending_output() ia64_flush_pending_output () #define md_parse_name(s,e,m,c) ia64_parse_name (s, e, c) +#define md_register_arithmetic 0 #define tc_canonicalize_symbol_name(s) ia64_canonicalize_symbol_name (s) #define tc_canonicalize_section_name(s) ia64_canonicalize_symbol_name (s) #define md_optimize_expr(l,o,r) ia64_optimize_expr (l, o, r) diff --git a/gas/doc/internals.texi b/gas/doc/internals.texi index c63a2db..a97ead3 100644 --- a/gas/doc/internals.texi +++ b/gas/doc/internals.texi @@ -1045,6 +1045,16 @@ 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_register_arithmetic +@cindex md_register_arithmetic +If this macro is defined and evaluates to zero then GAS will not fold +expressions that add or subtract a constant to/from a register to give +another register. For example GAS's default behaviour is to fold the +expression "r8 + 1" into "r9", which is probably not the result +intended by the programmer. The default is to allow such folding, +since this maintains backwards compatibility with earlier releases of +GAS. + @item tc_unrecognized_line @cindex tc_unrecognized_line If you define this macro, GAS will call it when it finds a line that it can not @@ -95,7 +95,9 @@ make_expr_symbol (expressionS *expressionP) symbolP = symbol_create (FAKE_LABEL_NAME, (expressionP->X_op == O_constant ? absolute_section - : expr_section), + : expressionP->X_op == O_register + ? reg_section + : expr_section), 0, &zero_address_frag); symbol_set_value_expression (symbolP, expressionP); @@ -1722,7 +1724,11 @@ expr (int rankarg, /* Larger # is higher rank. */ } else #endif - if (op_left == O_add && right.X_op == O_constant) +#ifndef md_register_arithmetic +# define md_register_arithmetic 1 +#endif + if (op_left == O_add && right.X_op == O_constant + && (md_register_arithmetic || resultP->X_op != O_register)) { /* X + constant. */ resultP->X_add_number += right.X_add_number; @@ -1745,12 +1751,14 @@ expr (int rankarg, /* Larger # is higher rank. */ resultP->X_op = O_constant; resultP->X_add_symbol = 0; } - else if (op_left == O_subtract && right.X_op == O_constant) + else if (op_left == O_subtract && right.X_op == O_constant + && (md_register_arithmetic || resultP->X_op != O_register)) { /* X - constant. */ resultP->X_add_number -= right.X_add_number; } - else if (op_left == O_add && resultP->X_op == O_constant) + else if (op_left == O_add && resultP->X_op == O_constant + && (md_register_arithmetic || right.X_op != O_register)) { /* Constant + X. */ resultP->X_op = right.X_op; |