aboutsummaryrefslogtreecommitdiff
path: root/4.4.4
diff options
context:
space:
mode:
authorRyan Hill <rhill@gentoo.org>2011-01-19 06:11:54 +0000
committerRyan Hill <rhill@gentoo.org>2011-01-19 06:11:54 +0000
commita69e5901c41cdf7e7139e6086390a0b2c09dca99 (patch)
tree32bddf42fc61b27eb40d6bad02c34a0f4bf042a3 /4.4.4
parentFix testsuite failures caused by our default warning patches. (diff)
downloadgcc-patches-a69e5901c41cdf7e7139e6086390a0b2c09dca99.tar.gz
gcc-patches-a69e5901c41cdf7e7139e6086390a0b2c09dca99.tar.bz2
gcc-patches-a69e5901c41cdf7e7139e6086390a0b2c09dca99.zip
Add HPPA patches for bug #349113 to 4.4.4 and 4.4.5.
Diffstat (limited to '4.4.4')
-rw-r--r--4.4.4/gentoo/60_all_4.4.5_hppa-wrong-code.patch311
-rw-r--r--4.4.4/gentoo/README.history3
2 files changed, 314 insertions, 0 deletions
diff --git a/4.4.4/gentoo/60_all_4.4.5_hppa-wrong-code.patch b/4.4.4/gentoo/60_all_4.4.5_hppa-wrong-code.patch
new file mode 100644
index 0000000..8be476c
--- /dev/null
+++ b/4.4.4/gentoo/60_all_4.4.5_hppa-wrong-code.patch
@@ -0,0 +1,311 @@
+[HPPA] Wrong code is generated for conditional branch followed by zero length asm
+
+http://gcc.gnu.org/PR46915
+https://bugs.gentoo.org/349113
+
+--- a/gcc/config/pa/pa.c
++++ b/gcc/config/pa/pa.c
+@@ -6118,6 +6118,95 @@ pa_scalar_mode_supported_p (enum machine_mode mode)
+ }
+ }
+
++/* Return TRUE if INSN, a jump insn, has an unfilled delay slot and
++ it branches into the delay slot. Otherwise, return FALSE. */
++
++static bool
++branch_to_delay_slot_p (rtx insn)
++{
++ rtx jump_insn;
++
++ if (dbr_sequence_length ())
++ return FALSE;
++
++ jump_insn = next_active_insn (JUMP_LABEL (insn));
++ while (insn)
++ {
++ insn = next_active_insn (insn);
++ if (jump_insn == insn)
++ return TRUE;
++
++ /* We can't rely on the length of asms. So, we return FALSE when
++ the branch is followed by an asm. */
++ if (!insn
++ || GET_CODE (PATTERN (insn)) == ASM_INPUT
++ || asm_noperands (PATTERN (insn)) >= 0
++ || get_attr_length (insn) > 0)
++ break;
++ }
++
++ return FALSE;
++}
++
++/* Return TRUE if INSN, a forward jump insn, needs a nop in its delay slot.
++
++ This occurs when INSN has an unfilled delay slot and is followed
++ by an asm. Disaster can occur if the asm is empty and the jump
++ branches into the delay slot. So, we add a nop in the delay slot
++ when this occurs. */
++
++static bool
++branch_needs_nop_p (rtx insn)
++{
++ rtx jump_insn;
++
++ if (dbr_sequence_length ())
++ return FALSE;
++
++ jump_insn = next_active_insn (JUMP_LABEL (insn));
++ while (insn)
++ {
++ insn = next_active_insn (insn);
++ if (!insn || jump_insn == insn)
++ return TRUE;
++
++ if (!(GET_CODE (PATTERN (insn)) == ASM_INPUT
++ || asm_noperands (PATTERN (insn)) >= 0)
++ && get_attr_length (insn) > 0)
++ break;
++ }
++
++ return FALSE;
++}
++
++/* Return TRUE if INSN, a forward jump insn, can use nullification
++ to skip the following instruction. This avoids an extra cycle due
++ to a mis-predicted branch when we fall through. */
++
++static bool
++use_skip_p (rtx insn)
++{
++ rtx jump_insn = next_active_insn (JUMP_LABEL (insn));
++
++ while (insn)
++ {
++ insn = next_active_insn (insn);
++
++ /* We can't rely on the length of asms, so we can't skip asms. */
++ if (!insn
++ || GET_CODE (PATTERN (insn)) == ASM_INPUT
++ || asm_noperands (PATTERN (insn)) >= 0)
++ break;
++ if (get_attr_length (insn) == 4
++ && jump_insn == next_active_insn (insn))
++ return TRUE;
++ if (get_attr_length (insn) > 0)
++ break;
++ }
++
++ return FALSE;
++}
++
+ /* This routine handles all the normal conditional branch sequences we
+ might need to generate. It handles compare immediate vs compare
+ register, nullification of delay slots, varying length branches,
+@@ -6129,7 +6218,7 @@ const char *
+ output_cbranch (rtx *operands, int negated, rtx insn)
+ {
+ static char buf[100];
+- int useskip = 0;
++ bool useskip;
+ int nullify = INSN_ANNULLED_BRANCH_P (insn);
+ int length = get_attr_length (insn);
+ int xdelay;
+@@ -6143,7 +6232,7 @@ output_cbranch (rtx *operands, int negated, rtx insn)
+ slot and the same branch target as this branch. We could check
+ for this but jump optimization should eliminate nop jumps. It
+ is always safe to emit a nop. */
+- if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn))
++ if (branch_to_delay_slot_p (insn))
+ return "nop";
+
+ /* The doubleword form of the cmpib instruction doesn't have the LEU
+@@ -6167,12 +6256,7 @@ output_cbranch (rtx *operands, int negated, rtx insn)
+ /* A forward branch over a single nullified insn can be done with a
+ comclr instruction. This avoids a single cycle penalty due to
+ mis-predicted branch if we fall through (branch not taken). */
+- if (length == 4
+- && next_real_insn (insn) != 0
+- && get_attr_length (next_real_insn (insn)) == 4
+- && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
+- && nullify)
+- useskip = 1;
++ useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE;
+
+ switch (length)
+ {
+@@ -6192,7 +6276,12 @@ output_cbranch (rtx *operands, int negated, rtx insn)
+ if (useskip)
+ strcat (buf, " %2,%r1,%%r0");
+ else if (nullify)
+- strcat (buf, ",n %2,%r1,%0");
++ {
++ if (branch_needs_nop_p (insn))
++ strcat (buf, ",n %2,%r1,%0%#");
++ else
++ strcat (buf, ",n %2,%r1,%0");
++ }
+ else
+ strcat (buf, " %2,%r1,%0");
+ break;
+@@ -6455,7 +6544,7 @@ const char *
+ output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
+ {
+ static char buf[100];
+- int useskip = 0;
++ bool useskip;
+ int nullify = INSN_ANNULLED_BRANCH_P (insn);
+ int length = get_attr_length (insn);
+ int xdelay;
+@@ -6465,7 +6554,7 @@ output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
+ is only used when optimizing; jump optimization should eliminate the
+ jump. But be prepared just in case. */
+
+- if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn))
++ if (branch_to_delay_slot_p (insn))
+ return "nop";
+
+ /* If this is a long branch with its delay slot unfilled, set `nullify'
+@@ -6481,13 +6570,7 @@ output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
+ /* A forward branch over a single nullified insn can be done with a
+ extrs instruction. This avoids a single cycle penalty due to
+ mis-predicted branch if we fall through (branch not taken). */
+-
+- if (length == 4
+- && next_real_insn (insn) != 0
+- && get_attr_length (next_real_insn (insn)) == 4
+- && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
+- && nullify)
+- useskip = 1;
++ useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE;
+
+ switch (length)
+ {
+@@ -6511,11 +6594,21 @@ output_bb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
+ if (useskip)
+ strcat (buf, " %0,%1,1,%%r0");
+ else if (nullify && negated)
+- strcat (buf, ",n %0,%1,%3");
++ {
++ if (branch_needs_nop_p (insn))
++ strcat (buf, ",n %0,%1,%3%#");
++ else
++ strcat (buf, ",n %0,%1,%3");
++ }
+ else if (nullify && ! negated)
+- strcat (buf, ",n %0,%1,%2");
++ {
++ if (branch_needs_nop_p (insn))
++ strcat (buf, ",n %0,%1,%2%#");
++ else
++ strcat (buf, ",n %0,%1,%2");
++ }
+ else if (! nullify && negated)
+- strcat (buf, "%0,%1,%3");
++ strcat (buf, " %0,%1,%3");
+ else if (! nullify && ! negated)
+ strcat (buf, " %0,%1,%2");
+ break;
+@@ -6636,7 +6729,7 @@ const char *
+ output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
+ {
+ static char buf[100];
+- int useskip = 0;
++ bool useskip;
+ int nullify = INSN_ANNULLED_BRANCH_P (insn);
+ int length = get_attr_length (insn);
+ int xdelay;
+@@ -6646,7 +6739,7 @@ output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
+ is only used when optimizing; jump optimization should eliminate the
+ jump. But be prepared just in case. */
+
+- if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn))
++ if (branch_to_delay_slot_p (insn))
+ return "nop";
+
+ /* If this is a long branch with its delay slot unfilled, set `nullify'
+@@ -6662,13 +6755,7 @@ output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
+ /* A forward branch over a single nullified insn can be done with a
+ extrs instruction. This avoids a single cycle penalty due to
+ mis-predicted branch if we fall through (branch not taken). */
+-
+- if (length == 4
+- && next_real_insn (insn) != 0
+- && get_attr_length (next_real_insn (insn)) == 4
+- && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
+- && nullify)
+- useskip = 1;
++ useskip = (length == 4 && nullify) ? use_skip_p (insn) : FALSE;
+
+ switch (length)
+ {
+@@ -6692,11 +6779,21 @@ output_bvb (rtx *operands ATTRIBUTE_UNUSED, int negated, rtx insn, int which)
+ if (useskip)
+ strcat (buf, "{ %0,1,%%r0| %0,%%sar,1,%%r0}");
+ else if (nullify && negated)
+- strcat (buf, "{,n %0,%3|,n %0,%%sar,%3}");
++ {
++ if (branch_needs_nop_p (insn))
++ strcat (buf, "{,n %0,%3%#|,n %0,%%sar,%3%#}");
++ else
++ strcat (buf, "{,n %0,%3|,n %0,%%sar,%3}");
++ }
+ else if (nullify && ! negated)
+- strcat (buf, "{,n %0,%2|,n %0,%%sar,%2}");
++ {
++ if (branch_needs_nop_p (insn))
++ strcat (buf, "{,n %0,%2%#|,n %0,%%sar,%2%#}");
++ else
++ strcat (buf, "{,n %0,%2|,n %0,%%sar,%2}");
++ }
+ else if (! nullify && negated)
+- strcat (buf, "{%0,%3|%0,%%sar,%3}");
++ strcat (buf, "{ %0,%3| %0,%%sar,%3}");
+ else if (! nullify && ! negated)
+ strcat (buf, "{ %0,%2| %0,%%sar,%2}");
+ break;
+@@ -6818,7 +6915,7 @@ output_dbra (rtx *operands, rtx insn, int which_alternative)
+ /* A conditional branch to the following instruction (e.g. the delay slot) is
+ asking for a disaster. Be prepared! */
+
+- if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn))
++ if (branch_to_delay_slot_p (insn))
+ {
+ if (which_alternative == 0)
+ return "ldo %1(%0),%0";
+@@ -6855,7 +6952,12 @@ output_dbra (rtx *operands, rtx insn, int which_alternative)
+ {
+ case 4:
+ if (nullify)
+- return "addib,%C2,n %1,%0,%3";
++ {
++ if (branch_needs_nop_p (insn))
++ return "addib,%C2,n %1,%0,%3%#";
++ else
++ return "addib,%C2,n %1,%0,%3";
++ }
+ else
+ return "addib,%C2 %1,%0,%3";
+
+@@ -6963,7 +7065,7 @@ output_movb (rtx *operands, rtx insn, int which_alternative,
+ /* A conditional branch to the following instruction (e.g. the delay slot) is
+ asking for a disaster. Be prepared! */
+
+- if (next_real_insn (JUMP_LABEL (insn)) == next_real_insn (insn))
++ if (branch_to_delay_slot_p (insn))
+ {
+ if (which_alternative == 0)
+ return "copy %1,%0";
+@@ -7001,7 +7103,12 @@ output_movb (rtx *operands, rtx insn, int which_alternative,
+ {
+ case 4:
+ if (nullify)
+- return "movb,%C2,n %1,%0,%3";
++ {
++ if (branch_needs_nop_p (insn))
++ return "movb,%C2,n %1,%0,%3%#";
++ else
++ return "movb,%C2,n %1,%0,%3";
++ }
+ else
+ return "movb,%C2 %1,%0,%3";
+
diff --git a/4.4.4/gentoo/README.history b/4.4.4/gentoo/README.history
index 03a856d..a7ef431 100644
--- a/4.4.4/gentoo/README.history
+++ b/4.4.4/gentoo/README.history
@@ -1,3 +1,6 @@
+1.4 pending
+ + 60_all_4.4.5_hppa-wrong-code.patch
+
1.3 29.11.2010
+ 05_all_gcc44-pr46173-all-tree.patch