| [76b06f6] | 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 | +} | 
|---|