Commit fc9c984d by Kaz Kojima

re PR target/43744 (SH: Error: pcrel too far)

	PR target/43744
	* config/sh/sh.c (find_barrier): Don't emit a constant pool
	in the middle of insns for casesi_worker_2.

From-SVN: r158655
parent d5dceab8
2010-04-22 Kaz Kojima <kkojima@gcc.gnu.org>
PR target/43744
* config/sh/sh.c (find_barrier): Don't emit a constant pool
in the middle of insns for casesi_worker_2.
2010-04-22 David Edelsohn <edelsohn@gnu.org> 2010-04-22 David Edelsohn <edelsohn@gnu.org>
* config/rs6000/x-aix: Override LDFLAGS for all COMPILERS. * config/rs6000/x-aix: Override LDFLAGS for all COMPILERS.
......
...@@ -4410,6 +4410,7 @@ find_barrier (int num_mova, rtx mova, rtx from) ...@@ -4410,6 +4410,7 @@ find_barrier (int num_mova, rtx mova, rtx from)
int hi_limit; int hi_limit;
rtx orig = from; rtx orig = from;
rtx last_got = NULL_RTX; rtx last_got = NULL_RTX;
rtx last_symoff = NULL_RTX;
/* For HImode: range is 510, add 4 because pc counts from address of /* For HImode: range is 510, add 4 because pc counts from address of
second instruction after this one, subtract 2 for the jump instruction second instruction after this one, subtract 2 for the jump instruction
...@@ -4551,6 +4552,16 @@ find_barrier (int num_mova, rtx mova, rtx from) ...@@ -4551,6 +4552,16 @@ find_barrier (int num_mova, rtx mova, rtx from)
{ {
switch (untangle_mova (&num_mova, &mova, from)) switch (untangle_mova (&num_mova, &mova, from))
{ {
case 1:
if (flag_pic)
{
rtx src = SET_SRC (PATTERN (from));
if (GET_CODE (src) == CONST
&& GET_CODE (XEXP (src, 0)) == UNSPEC
&& XINT (XEXP (src, 0), 1) == UNSPEC_SYMOFF)
last_symoff = from;
}
break;
case 0: return find_barrier (0, 0, mova); case 0: return find_barrier (0, 0, mova);
case 2: case 2:
{ {
...@@ -4654,6 +4665,12 @@ find_barrier (int num_mova, rtx mova, rtx from) ...@@ -4654,6 +4665,12 @@ find_barrier (int num_mova, rtx mova, rtx from)
so we'll make one. */ so we'll make one. */
rtx label = gen_label_rtx (); rtx label = gen_label_rtx ();
/* Don't emit a constant table in the middle of insns for
casesi_worker_2. This is a bit overkill but is enough
because casesi_worker_2 wouldn't appear so frequently. */
if (last_symoff)
from = last_symoff;
/* If we exceeded the range, then we must back up over the last /* If we exceeded the range, then we must back up over the last
instruction we looked at. Otherwise, we just need to undo the instruction we looked at. Otherwise, we just need to undo the
NEXT_INSN at the end of the loop. */ NEXT_INSN at the end of the loop. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment