diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/f/ChangeLog | 15 | ||||
-rw-r--r-- | gcc/f/equiv.c | 59 | ||||
-rw-r--r-- | gcc/f/target.c | 3 | ||||
-rw-r--r-- | gcc/f/version.c | 2 |
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"; |