summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/f/ChangeLog15
-rw-r--r--gcc/f/equiv.c59
-rw-r--r--gcc/f/target.c3
-rw-r--r--gcc/f/version.c2
4 files changed, 62 insertions, 17 deletions
diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog
index b4821f78632..9f8068f4702 100644
--- a/gcc/f/ChangeLog
+++ b/gcc/f/ChangeLog
@@ -1,3 +1,18 @@
+Wed Jul 1 11:19:13 1998 Craig Burley <burley@gnu.org>
+
+ Fix 980701-1.f (which was producing "unaligned trap"
+ on an Alpha running GNU/Linux, as predicted):
+ * equiv.c (ffeequiv_layout_local_): Don't bother
+ coping with pre-padding of entire area while building
+ it; do that instead after the building is done, and
+ do it by modifying only the modulo field. This covers
+ the case of alignment stringency being increased without
+ lowering the starting offset, unlike the previous changes,
+ and even more elegantly than those.
+
+ * target.c (ffetarget_align): Make sure alignments
+ are non-zero, just in case.
+
Mon Jun 29 09:47:33 1998 Craig Burley <burley@gnu.org>
Fix 980628-*.f:
diff --git a/gcc/f/equiv.c b/gcc/f/equiv.c
index 9fd856bd024..8c0975128c1 100644
--- a/gcc/f/equiv.c
+++ b/gcc/f/equiv.c
@@ -368,6 +368,7 @@ ffeequiv_layout_local_ (ffeequiv eq)
ffestorag item_st; /* Storage for var. */
ffesymbol item_sym; /* Var itself. */
ffetargetOffset item_offset; /* Offset for var from root. */
+ ffetargetOffset new_size;
item_exp = ffebld_head (item);
item_sym = ffeequiv_symbol (item_exp);
@@ -433,28 +434,18 @@ ffeequiv_layout_local_ (ffeequiv eq)
}
else if (item_offset < ffestorag_offset (st))
{
- ffetargetOffset new_size;
-
- /* First, calculate the initial padding necessary
- to preserve the current alignment/modulo requirements
- for the storage area. */
- pad = (-item_offset) % ffestorag_alignment (st);
- if (pad != 0)
- pad = ffestorag_alignment (st) - pad;
-
- /* Increase size of equiv area to start for lower offset relative
- to root symbol. */
+ /* Increase size of equiv area to start for lower offset
+ relative to root symbol. */
if (! ffetarget_offset_add (&new_size,
- (ffestorag_offset (st)
- - item_offset)
- + pad,
- ffestorag_size (st)))
+ ffestorag_offset (st)
+ - item_offset,
+ ffestorag_size (st)))
ffetarget_offset_overflow (ffesymbol_text (s));
else
ffestorag_set_size (st, new_size);
ffestorag_set_symbol (st, item_sym);
- ffestorag_set_offset (st, item_offset - pad);
+ ffestorag_set_offset (st, item_offset);
#if FFEEQUIV_DEBUG
fprintf (stderr, " [eq offset=%" ffetargetOffset_f
@@ -538,6 +529,42 @@ ffeequiv_layout_local_ (ffeequiv eq)
ffeequiv_kill (eq); /* Fully processed, no longer needed. */
+ /* If the offset for this storage area is zero (it cannot be positive),
+ that means the alignment/modulo info is already correct. Otherwise,
+ the alignment info is correct, but the modulo info reflects a
+ zero offset, so fix it. */
+
+ if (ffestorag_offset (st) < 0)
+ {
+ /* Calculate the initial padding necessary to preserve
+ the alignment/modulo requirements for the storage area.
+ These requirements are themselves kept track of in the
+ record for the storage area as a whole, but really pertain
+ to offset 0 of that area, which is where the root symbol
+ was originally placed.
+
+ The goal here is to have the offset and size for the area
+ faithfully reflect the area itself, not extra requirements
+ like alignment. So to meet the alignment requirements,
+ the modulo for the area should be set as if the area had an
+ alignment requirement of alignment/0 and was aligned/padded
+ downward to meet the alignment requirements of the area at
+ offset zero, the amount of padding needed being the desired
+ value for the modulo of the area. */
+
+ alignment = ffestorag_alignment (st);
+ modulo = ffestorag_modulo (st);
+
+ /* Since we want to move the whole area *down* (lower memory
+ addresses) as required by the alignment/modulo paid, negate
+ the offset to ffetarget_align, which assumes aligning *up*
+ is desired. */
+ pad = ffetarget_align (&alignment, &modulo,
+ - ffestorag_offset (st),
+ alignment, 0);
+ ffestorag_set_modulo (st, pad);
+ }
+
if (init)
ffedata_gather (st); /* Gather subordinate inits into one init. */
}
diff --git a/gcc/f/target.c b/gcc/f/target.c
index 2244dbc1fad..5de05ff07ca 100644
--- a/gcc/f/target.c
+++ b/gcc/f/target.c
@@ -214,6 +214,9 @@ ffetarget_align (ffetargetAlign *updated_alignment,
ffetargetAlign i;
ffetargetAlign j;
+ assert (alignment > 0);
+ assert (*updated_alignment > 0);
+
assert (*updated_modulo < *updated_alignment);
assert (modulo < alignment);
diff --git a/gcc/f/version.c b/gcc/f/version.c
index fbec2902f45..98e877b79c7 100644
--- a/gcc/f/version.c
+++ b/gcc/f/version.c
@@ -1 +1 @@
-char *ffe_version_string = "0.5.24-19980629";
+char *ffe_version_string = "0.5.24-19980701";