From 5a918ce730bca784591cef4b3696269510c5f814 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Wed, 26 Sep 2007 08:34:24 +0000 Subject: [PATCH] gas/ 2007-09-26 Jan Beulich * 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. --- gas/ChangeLog | 11 +++++++++++ gas/config/tc-i386.h | 2 ++ gas/config/tc-ia64.h | 1 + gas/doc/internals.texi | 10 ++++++++++ gas/expr.c | 16 ++++++++++++---- 5 files changed, 36 insertions(+), 4 deletions(-) diff --git a/gas/ChangeLog b/gas/ChangeLog index 6a9bb54023..9cf0f71d32 100644 --- a/gas/ChangeLog +++ b/gas/ChangeLog @@ -1,3 +1,14 @@ +2007-09-26 Jan Beulich + + * 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 * dw2gencfi.c: Conditionalize whole body upon TARGET_USE_CFIPOP. diff --git a/gas/config/tc-i386.h b/gas/config/tc-i386.h index e55d5cad5e..65e300a4f7 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 725e6eaa44..d0b0b1b09f 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 c63a2dbd77..a97ead386c 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 diff --git a/gas/expr.c b/gas/expr.c index b88328502e..4f4d380ff9 100644 --- a/gas/expr.c +++ b/gas/expr.c @@ -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; -- 2.34.1