[9fb94bf] | 1 | Submitted By: Jonathan Norman (jonathan at bluesquarelinux.co.uk)
|
---|
| 2 | Date: 2011-07-12
|
---|
| 3 | Initial Package Version: 4.6.0
|
---|
| 4 | Origin: Upstream
|
---|
| 5 | Upstream Status: Applied
|
---|
| 6 | Description: Fixes a issue with Mips that causes GCC to setfault
|
---|
| 7 | when using optimation greater than -O0. Taken from
|
---|
| 8 | GCC Revision 174541 and applied to GCC 4.6.0
|
---|
| 9 |
|
---|
| 10 | diff -Naur gcc-4.6.0.orig/gcc/expmed.c gcc-4.6.0/gcc/expmed.c
|
---|
| 11 | --- gcc-4.6.0.orig/gcc/expmed.c 2011-07-12 16:18:33.939215981 +0000
|
---|
| 12 | +++ gcc-4.6.0/gcc/expmed.c 2011-07-12 16:33:51.121616152 +0000
|
---|
| 13 | @@ -1431,7 +1431,7 @@
|
---|
| 14 | unsigned int nwords = (bitsize + (BITS_PER_WORD - 1)) / BITS_PER_WORD;
|
---|
| 15 | unsigned int i;
|
---|
| 16 |
|
---|
| 17 | - if (target == 0 || !REG_P (target))
|
---|
| 18 | + if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
|
---|
| 19 | target = gen_reg_rtx (mode);
|
---|
| 20 |
|
---|
| 21 | /* Indicate for flow that the entire target reg is being set. */
|
---|
| 22 | diff -Naur gcc-4.6.0.orig/gcc/optabs.c gcc-4.6.0/gcc/optabs.c
|
---|
| 23 | --- gcc-4.6.0.orig/gcc/optabs.c 2011-07-12 16:18:34.119217377 +0000
|
---|
| 24 | +++ gcc-4.6.0/gcc/optabs.c 2011-07-12 16:33:00.296108734 +0000
|
---|
| 25 | @@ -1694,7 +1694,10 @@
|
---|
| 26 |
|
---|
| 27 | /* If TARGET is the same as one of the operands, the REG_EQUAL note
|
---|
| 28 | won't be accurate, so use a new target. */
|
---|
| 29 | - if (target == 0 || target == op0 || target == op1)
|
---|
| 30 | + if (target == 0
|
---|
| 31 | + || target == op0
|
---|
| 32 | + || target == op1
|
---|
| 33 | + || !valid_multiword_target_p (target))
|
---|
| 34 | target = gen_reg_rtx (mode);
|
---|
| 35 |
|
---|
| 36 | start_sequence ();
|
---|
| 37 | @@ -1762,7 +1765,10 @@
|
---|
| 38 |
|
---|
| 39 | /* If TARGET is the same as one of the operands, the REG_EQUAL note
|
---|
| 40 | won't be accurate, so use a new target. */
|
---|
| 41 | - if (target == 0 || target == op0 || target == op1)
|
---|
| 42 | + if (target == 0
|
---|
| 43 | + || target == op0
|
---|
| 44 | + || target == op1
|
---|
| 45 | + || !valid_multiword_target_p (target))
|
---|
| 46 | target = gen_reg_rtx (mode);
|
---|
| 47 |
|
---|
| 48 | start_sequence ();
|
---|
| 49 | @@ -1816,7 +1822,11 @@
|
---|
| 50 | opportunities, and second because if target and op0 happen to be MEMs
|
---|
| 51 | designating the same location, we would risk clobbering it too early
|
---|
| 52 | in the code sequence we generate below. */
|
---|
| 53 | - if (target == 0 || target == op0 || target == op1 || ! REG_P (target))
|
---|
| 54 | + if (target == 0
|
---|
| 55 | + || target == op0
|
---|
| 56 | + || target == op1
|
---|
| 57 | + || !REG_P (target)
|
---|
| 58 | + || !valid_multiword_target_p (target))
|
---|
| 59 | target = gen_reg_rtx (mode);
|
---|
| 60 |
|
---|
| 61 | start_sequence ();
|
---|
| 62 | @@ -1936,7 +1946,7 @@
|
---|
| 63 |
|
---|
| 64 | xtarget = gen_reg_rtx (mode);
|
---|
| 65 |
|
---|
| 66 | - if (target == 0 || !REG_P (target))
|
---|
| 67 | + if (target == 0 || !REG_P (target) || !valid_multiword_target_p (target))
|
---|
| 68 | target = xtarget;
|
---|
| 69 |
|
---|
| 70 | /* Indicate for flow that the entire target reg is being set. */
|
---|
| 71 | @@ -2689,7 +2699,7 @@
|
---|
| 72 | t0 = expand_unop (word_mode, bswap_optab,
|
---|
| 73 | operand_subword_force (op, 1, mode), NULL_RTX, true);
|
---|
| 74 |
|
---|
| 75 | - if (target == 0)
|
---|
| 76 | + if (target == 0 || !valid_multiword_target_p (target))
|
---|
| 77 | target = gen_reg_rtx (mode);
|
---|
| 78 | if (REG_P (target))
|
---|
| 79 | emit_clobber (target);
|
---|
| 80 | @@ -2932,7 +2942,9 @@
|
---|
| 81 | if (code == ABS)
|
---|
| 82 | mask = double_int_not (mask);
|
---|
| 83 |
|
---|
| 84 | - if (target == 0 || target == op0)
|
---|
| 85 | + if (target == 0
|
---|
| 86 | + || target == op0
|
---|
| 87 | + || (nwords > 1 && !valid_multiword_target_p (target)))
|
---|
| 88 | target = gen_reg_rtx (mode);
|
---|
| 89 |
|
---|
| 90 | if (nwords > 1)
|
---|
| 91 | @@ -3140,7 +3152,7 @@
|
---|
| 92 | int i;
|
---|
| 93 | rtx insns;
|
---|
| 94 |
|
---|
| 95 | - if (target == 0 || target == op0)
|
---|
| 96 | + if (target == 0 || target == op0 || !valid_multiword_target_p (target))
|
---|
| 97 | target = gen_reg_rtx (mode);
|
---|
| 98 |
|
---|
| 99 | start_sequence ();
|
---|
| 100 | @@ -3611,7 +3623,10 @@
|
---|
| 101 |
|
---|
| 102 | mask = double_int_setbit (double_int_zero, bitpos);
|
---|
| 103 |
|
---|
| 104 | - if (target == 0 || target == op0 || target == op1)
|
---|
| 105 | + if (target == 0
|
---|
| 106 | + || target == op0
|
---|
| 107 | + || target == op1
|
---|
| 108 | + || (nwords > 1 && !valid_multiword_target_p (target)))
|
---|
| 109 | target = gen_reg_rtx (mode);
|
---|
| 110 |
|
---|
| 111 | if (nwords > 1)
|
---|
| 112 | @@ -7330,4 +7345,21 @@
|
---|
| 113 | return NULL_RTX;
|
---|
| 114 | }
|
---|
| 115 |
|
---|
| 116 | +/* TARGET is a target of a multiword operation that we are going to
|
---|
| 117 | + implement as a series of word-mode operations. Return true if
|
---|
| 118 | + TARGET is suitable for this purpose. */
|
---|
| 119 | +
|
---|
| 120 | +bool
|
---|
| 121 | +valid_multiword_target_p (rtx target)
|
---|
| 122 | +{
|
---|
| 123 | + enum machine_mode mode;
|
---|
| 124 | + int i;
|
---|
| 125 | +
|
---|
| 126 | + mode = GET_MODE (target);
|
---|
| 127 | + for (i = 0; i < GET_MODE_SIZE (mode); i += UNITS_PER_WORD)
|
---|
| 128 | + if (!validate_subreg (word_mode, mode, target, i))
|
---|
| 129 | + return false;
|
---|
| 130 | + return true;
|
---|
| 131 | +}
|
---|
| 132 | +
|
---|
| 133 | #include "gt-optabs.h"
|
---|
| 134 | diff -Naur gcc-4.6.0.orig/gcc/optabs.h gcc-4.6.0/gcc/optabs.h
|
---|
| 135 | --- gcc-4.6.0.orig/gcc/optabs.h 2011-07-12 16:18:34.119217377 +0000
|
---|
| 136 | +++ gcc-4.6.0/gcc/optabs.h 2011-07-12 16:24:10.888292947 +0000
|
---|
| 137 | @@ -923,4 +923,6 @@
|
---|
| 138 | extern rtx optab_libfunc (optab optab, enum machine_mode mode);
|
---|
| 139 | extern rtx convert_optab_libfunc (convert_optab optab, enum machine_mode mode1,
|
---|
| 140 | enum machine_mode mode2);
|
---|
| 141 | +
|
---|
| 142 | +extern bool valid_multiword_target_p (rtx);
|
---|
| 143 | #endif /* GCC_OPTABS_H */
|
---|
| 144 | diff -Naur gcc-4.6.0.orig/gcc/testsuite/gcc.target/mips/pr45074.c gcc-4.6.0/gcc/testsuite/gcc.target/mips/pr45074.c
|
---|
| 145 | --- gcc-4.6.0.orig/gcc/testsuite/gcc.target/mips/pr45074.c 1970-01-01 00:00:00.000000000 +0000
|
---|
| 146 | +++ gcc-4.6.0/gcc/testsuite/gcc.target/mips/pr45074.c 2011-07-12 16:19:49.925768556 +0000
|
---|
| 147 | @@ -0,0 +1,8 @@
|
---|
| 148 | +/* { dg-options "-mhard-float -mgp32 -O" } */
|
---|
| 149 | +register double g __asm__("$f20");
|
---|
| 150 | +
|
---|
| 151 | +NOMIPS16 void
|
---|
| 152 | +test (double a)
|
---|
| 153 | +{
|
---|
| 154 | + g = -a;
|
---|
| 155 | +}
|
---|