From: Eric Botcazou Date: Sat, 17 Jul 2004 19:49:21 +0000 (+0200) Subject: backport: re PR target/13926 (GCC generates jumps that are too large to fit in word... X-Git-Tag: releases/gcc-3.3.5~112 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6e342e56399fe7cd4b3c38451d9620940743d2d8;p=thirdparty%2Fgcc.git backport: re PR target/13926 (GCC generates jumps that are too large to fit in word displacement field) Backport from mainline: 2004-07-13 Eric Botcazou 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: r84879 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 571c11148b4a..23d290fe2e46 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2004-07-17 Eric Botcazou + + Backport from mainline: + 2004-07-13 Eric Botcazou + + 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 PR target/16494 diff --git a/gcc/config/sparc/sparc-protos.h b/gcc/config/sparc/sparc-protos.h index 0aa6e58f7da9..8f7c9872ec24 100644 --- a/gcc/config/sparc/sparc-protos.h +++ b/gcc/config/sparc/sparc-protos.h @@ -88,6 +88,7 @@ extern void sparc_emit_set_const64 PARAMS ((rtx, rtx)); extern void sparc_emit_set_symbolic_const64 PARAMS ((rtx, rtx, rtx)); extern int sparc_splitdi_legitimate PARAMS ((rtx, rtx)); extern int sparc_absnegfloat_split_legitimate PARAMS ((rtx, rtx)); +extern const char *output_ubranch PARAMS ((rtx, int, rtx)); extern char *output_cbranch PARAMS ((rtx, rtx, int, int, int, int, rtx)); extern const char *output_sibcall PARAMS ((rtx, rtx)); extern char *output_v9branch PARAMS ((rtx, rtx, int, int, int, int, int, diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 9f4d552cc062..d8cd82b6dedc 100644 --- a/gcc/config/sparc/sparc.c +++ b/gcc/config/sparc/sparc.c @@ -5442,18 +5442,80 @@ sparc_va_arg (valist, type) return addr_rtx; } +/* 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 (dest, label, insn) + 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. */ char * output_cbranch (op, dest, label, reversed, annul, noop, insn) @@ -5881,6 +5943,8 @@ sparc_emit_floatunsdi (operands) 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. diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md index 85759caeef01..9e8117a0698e 100644 --- a/gcc/config/sparc/sparc.md +++ b/gcc/config/sparc/sparc.md @@ -7220,27 +7220,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"