]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
backport: re PR target/13926 (GCC generates jumps that are too large to fit in word...
authorEric Botcazou <ebotcazou@libertysurf.fr>
Sat, 17 Jul 2004 19:49:21 +0000 (21:49 +0200)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Sat, 17 Jul 2004 19:49:21 +0000 (19:49 +0000)
Backport from mainline:
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.

From-SVN: r84879

gcc/ChangeLog
gcc/config/sparc/sparc-protos.h
gcc/config/sparc/sparc.c
gcc/config/sparc/sparc.md

index 571c11148b4a30612d7c178d5a88e7556b7a53c8..23d290fe2e46b5ec9168a6d98ee15a77709d0bf7 100644 (file)
@@ -1,3 +1,13 @@
+2004-07-17  Eric Botcazou  <ebotcazou@libertysurf.fr>
+
+       Backport from mainline:
+       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
index 0aa6e58f7da983528c1d6198aebab97c60854db6..8f7c9872ec2423f2a1d900a85276d10317af7a4f 100644 (file)
@@ -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,
index 9f4d552cc062bf1c570f1e13961e88bf5374bfdf..d8cd82b6dedcf9bbe97f5912710cf2f572dd7a4c 100644 (file)
@@ -5442,18 +5442,80 @@ sparc_va_arg (valist, type)
   return addr_rtx;
 }
 \f
+/* 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.
index 85759caeef01847cf07278166d724ba884664f9f..9e8117a0698e23d1495b58dedb9481bc8a679f52 100644 (file)
   [(set_attr "type" "shift")])
 \f
 ;; 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"