re PR target/13926 (GCC generates jumps that are too large to fit in word displacement field)

PR target/13926
	* config/sparc/sparc-protos.h (output_ubranch): New prototype.
	* config/sparc/sparc.c (output_ubranch): New function.
	* config/sparc/sparc.md (jump pattern): Use it.

From-SVN: r84621
This commit is contained in:
Eric Botcazou 2004-07-13 15:14:06 +02:00 committed by Eric Botcazou
parent 883d9e0c3f
commit 1b3c2c2d72
4 changed files with 73 additions and 21 deletions

View File

@ -1,3 +1,10 @@
2004-07-13 Eric Botcazou <ebotcazou@libertysurf.fr>
PR target/13926
* config/sparc/sparc-protos.h (output_ubranch): New prototype.
* config/sparc/sparc.c (output_ubranch): New function.
* config/sparc/sparc.md (jump pattern): Use it.
2004-07-13 Eric Botcazou <ebotcazou@libertysurf.fr>
PR target/16494

View File

@ -82,6 +82,7 @@ extern void sparc_emit_set_const64 (rtx, rtx);
extern void sparc_emit_set_symbolic_const64 (rtx, rtx, rtx);
extern int sparc_splitdi_legitimate (rtx, rtx);
extern int sparc_absnegfloat_split_legitimate (rtx, rtx);
extern const char *output_ubranch (rtx, int, rtx);
extern const char *output_cbranch (rtx, rtx, int, int, int, int, rtx);
extern const char *output_return (rtx);
extern const char *output_sibcall (rtx, rtx);

View File

@ -6085,18 +6085,77 @@ sparc_gimplify_va_arg (tree valist, tree type, tree *pre_p, tree *post_p)
return build_fold_indirect_ref (addr);
}
/* Return the string to output an unconditional branch to LABEL, which is
the operand number of the label.
DEST is the destination insn (i.e. the label), INSN is the source. */
const char *
output_ubranch (rtx dest, int label, rtx insn)
{
static char string[64];
bool noop = false;
char *p;
/* TurboSPARC is reported to have problems with
with
foo: b,a foo
i.e. an empty loop with the annul bit set. The workaround is to use
foo: b foo; nop
instead. */
if (! TARGET_V9 && flag_delayed_branch
&& (INSN_ADDRESSES (INSN_UID (dest))
== INSN_ADDRESSES (INSN_UID (insn))))
{
strcpy (string, "b\t");
noop = true;
}
else
{
bool v9_form = false;
if (TARGET_V9 && INSN_ADDRESSES_SET_P ())
{
int delta = (INSN_ADDRESSES (INSN_UID (dest))
- INSN_ADDRESSES (INSN_UID (insn)));
/* Leave some instructions for "slop". */
if (delta >= -260000 && delta < 260000)
v9_form = true;
}
if (v9_form)
strcpy (string, "ba%*,pt\t%%xcc, ");
else
strcpy (string, "b%*\t");
}
p = strchr (string, '\0');
*p++ = '%';
*p++ = 'l';
*p++ = '0' + label;
*p++ = '%';
if (noop)
*p++ = '#';
else
*p++ = '(';
*p = '\0';
return string;
}
/* Return the string to output a conditional branch to LABEL, which is
the operand number of the label. OP is the conditional expression.
XEXP (OP, 0) is assumed to be a condition code register (integer or
floating point) and its mode specifies what kind of comparison we made.
DEST is the destination insn (i.e. the label), INSN is the source.
REVERSED is nonzero if we should reverse the sense of the comparison.
ANNUL is nonzero if we should generate an annulling branch.
NOOP is nonzero if we have to follow this branch by a noop.
INSN, if set, is the insn. */
NOOP is nonzero if we have to follow this branch by a noop. */
const char *
output_cbranch (rtx op, rtx dest, int label, int reversed, int annul,
@ -6557,6 +6616,8 @@ sparc_emit_fixunsdi (rtx *operands, enum machine_mode mode)
operand number of the reg. OP is the conditional expression. The mode
of REG says what kind of comparison we made.
DEST is the destination insn (i.e. the label), INSN is the source.
REVERSED is nonzero if we should reverse the sense of the comparison.
ANNUL is nonzero if we should generate an annulling branch.

View File

@ -7278,27 +7278,10 @@
[(set_attr "type" "shift")])
;; Unconditional and other jump instructions
;; On the SPARC, by setting the annul bit on an unconditional branch, the
;; following insn is never executed. This saves us a nop. Dbx does not
;; handle such branches though, so we only use them when optimizing.
(define_insn "jump"
[(set (pc) (label_ref (match_operand 0 "" "")))]
""
{
/* TurboSPARC is reported to have problems with
with
foo: b,a foo
i.e. an empty loop with the annul bit set. The workaround is to use
foo: b foo; nop
instead. */
if (! TARGET_V9 && flag_delayed_branch
&& (INSN_ADDRESSES (INSN_UID (operands[0]))
== INSN_ADDRESSES (INSN_UID (insn))))
return "b\t%l0%#";
else
return TARGET_V9 ? "ba%*,pt\t%%xcc, %l0%(" : "b%*\t%l0%(";
}
"* return output_ubranch (operands[0], 0, insn);"
[(set_attr "type" "uncond_branch")])
(define_expand "tablejump"