diff options
author | Ryan Hill <rhill@gentoo.org> | 2011-01-19 06:11:54 +0000 |
---|---|---|
committer | Ryan Hill <rhill@gentoo.org> | 2011-01-19 06:11:54 +0000 |
commit | a69e5901c41cdf7e7139e6086390a0b2c09dca99 (patch) | |
tree | 32bddf42fc61b27eb40d6bad02c34a0f4bf042a3 /4.4.4 | |
parent | Fix testsuite failures caused by our default warning patches. (diff) | |
download | gcc-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.patch | 311 | ||||
-rw-r--r-- | 4.4.4/gentoo/README.history | 3 |
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 |