aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gas/ChangeLog11
-rw-r--r--gas/config/tc-i386.h2
-rw-r--r--gas/config/tc-ia64.h1
-rw-r--r--gas/doc/internals.texi10
-rw-r--r--gas/expr.c16
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
diff --git a/gas/expr.c b/gas/expr.c
index b883285..4f4d380 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;