This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
fix alpha explicit relocs alignment error
- From: Richard Henderson <rth at redhat dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 9 Dec 2001 14:00:33 -0800
- Subject: fix alpha explicit relocs alignment error
Found with an EV4 bootstrap, instead of my normal EV6 build.
With TARGET_EXPLICIT_RELOCS, we separate the call and the gp
reload into separate instructions. However, these instructions
must remain contiguous, or the gp will be reloaded with the
wrong address. This worked everywhere but in the alpha_reorg
where we manage code alignment.
Before and after looks like
ldq $27,fprintf($29) !literal
mov $10,$16
- jsr $26,($27),fprintf
bis $31,$31,$31
+ jsr $26,($27),fprintf
ldah $29,0($26) !gpdisp!20
cpys $f31,$f31,$f19
lda $29,0($29) !gpdisp!20
r~
* config/alpha/alpha.c (alpha_align_insns): Suppress realignment
immediately after a call; insert nops before a call.
Index: alpha.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/alpha/alpha.c,v
retrieving revision 1.211
diff -c -p -d -r1.211 alpha.c
*** alpha.c 2001/12/09 21:47:49 1.211
--- alpha.c 2001/12/09 21:52:18
*************** alpha_align_insns (insns, max_align, nex
*** 7622,7636 ****
else if ((int) align < len)
{
unsigned int new_log_align = len > 8 ? 4 : 3;
! rtx where;
! where = prev_nonnote_insn (i);
if (!where || GET_CODE (where) != CODE_LABEL)
where = i;
! emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
! align = 1 << new_log_align;
! ofs = 0;
}
/* If the group won't fit in the same INT16 as the previous,
--- 7622,7641 ----
else if ((int) align < len)
{
unsigned int new_log_align = len > 8 ? 4 : 3;
! rtx prev, where;
! where = prev = prev_nonnote_insn (i);
if (!where || GET_CODE (where) != CODE_LABEL)
where = i;
! /* Can't realign between a call and its gp reload. */
! if (! (TARGET_EXPLICIT_RELOCS
! && prev && GET_CODE (prev) == CALL_INSN))
! {
! emit_insn_before (gen_realign (GEN_INT (new_log_align)), where);
! align = 1 << new_log_align;
! ofs = 0;
! }
}
/* If the group won't fit in the same INT16 as the previous,
*************** alpha_align_insns (insns, max_align, nex
*** 7644,7651 ****
int nop_count = (align - ofs) / 4;
rtx where;
! /* Insert nops before labels and branches to truely merge the
! execution of the nops with the previous instruction group. */
where = prev_nonnote_insn (i);
if (where)
{
--- 7649,7656 ----
int nop_count = (align - ofs) / 4;
rtx where;
! /* Insert nops before labels, branches, and calls to truely merge
! the execution of the nops with the previous instruction group. */
where = prev_nonnote_insn (i);
if (where)
{
*************** alpha_align_insns (insns, max_align, nex
*** 7655,7661 ****
if (where2 && GET_CODE (where2) == JUMP_INSN)
where = where2;
}
! else if (GET_CODE (where) != JUMP_INSN)
where = i;
}
else
--- 7660,7666 ----
if (where2 && GET_CODE (where2) == JUMP_INSN)
where = where2;
}
! else if (GET_CODE (where) == INSN)
where = i;
}
else