summaryrefslogtreecommitdiff
path: root/gas/frags.c
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2006-04-04 08:04:57 +0000
committerAlan Modra <amodra@gmail.com>2006-04-04 08:04:57 +0000
commit99630778988bcd5195fc056fbd013d32d1362d5a (patch)
tree2dcd9e309b7a988ed9fbe72ea53005e3a2d38b2d /gas/frags.c
parentbb3af66b415e4c7b92894d0aca52119b05d728ec (diff)
PR 997
* frags.c (frag_offset_fixed_p): New function. * frags.h (frag_offset_fixed_p): Declare. * expr.c (expr): Use frag_offset_fixed_p when simplifying subtraction. (resolve_expression): Likewise.
Diffstat (limited to 'gas/frags.c')
-rw-r--r--gas/frags.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/gas/frags.c b/gas/frags.c
index 6dae8bc9c2..cfd183fb3d 100644
--- a/gas/frags.c
+++ b/gas/frags.c
@@ -1,6 +1,6 @@
/* frags.c - manage frags -
Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2003, 2004
+ 1999, 2000, 2001, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -383,3 +383,55 @@ frag_append_1_char (int datum)
}
obstack_1grow (&frchain_now->frch_obstack, datum);
}
+
+/* Return TRUE if FRAG1 and FRAG2 have a fixed relationship between
+ their start addresses. Set OFFSET to the difference in address
+ not already accounted for in the frag FR_ADDRESS. */
+
+bfd_boolean
+frag_offset_fixed_p (fragS *frag1, fragS *frag2, bfd_vma *offset)
+{
+ fragS *frag;
+ bfd_vma off;
+
+ /* Start with offset initialised to difference between the two frags.
+ Prior to assigning frag addresses this will be zero. */
+ off = frag1->fr_address - frag2->fr_address;
+ if (frag1 == frag2)
+ {
+ *offset = off;
+ return TRUE;
+ }
+
+ /* Maybe frag2 is after frag1. */
+ frag = frag1;
+ while (frag->fr_type == rs_fill)
+ {
+ off += frag->fr_fix + frag->fr_offset * frag->fr_var;
+ frag = frag->fr_next;
+ if (frag == NULL)
+ break;
+ if (frag == frag2)
+ {
+ *offset = off;
+ return TRUE;
+ }
+ }
+
+ /* Maybe frag1 is after frag2. */
+ frag = frag2;
+ while (frag->fr_type == rs_fill)
+ {
+ off -= frag->fr_fix + frag->fr_offset * frag->fr_var;
+ frag = frag->fr_next;
+ if (frag == NULL)
+ break;
+ if (frag == frag1)
+ {
+ *offset = off;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}