patches/gcc/3.3/sh4-kaz-workaround.patch
author "Yann E. MORIN" <yann.morin.1998@anciens.enib.fr>
Sat Feb 24 11:00:05 2007 +0000 (2007-02-24)
changeset 1 eeea35fbf182
permissions -rw-r--r--
Add the full crosstool-NG sources to the new repository of its own.
You might just say: 'Yeah! crosstool-NG's got its own repo!".
Unfortunately, that's because the previous repo got damaged beyond repair and I had no backup.
That means I'm putting backups in place in the afternoon.
That also means we've lost history... :-(
     1 [lightly edited to fit my patch directory - dank]
     2 
     3 From: kaz Kojima <kkojima@rr.iij4u.or.jp>
     4 Date: Sat, 09 Aug 2003 09:46:21 +0900
     5 To: dank@kegel.com
     6 
     7 Hi Dan,
     8 
     9 I've come back from the vacation and looked glibc string test
    10 failures on sh4. This looks a gcc problem. gcc-3.3/3.4 doesn't
    11 compile these tests correctly. The attached testcase aborts on
    12 gcc-3.3/3.4 -O2 but exits normally gcc-3.2 and gcc-3.0.
    13 The option -O2 is not essential but it makes the testcase small.
    14 The failed string tests include the same pattern of the code with
    15 f=random to generate ramdom strings but they get strings with
    16 embedded NULL characters :-(
    17 
    18 ...
    19 I've got a workaround below for this bug, though it might merely
    20 paper over the real bug. Anyway, I'd like to send a PR for this.
    21 
    22 Regards,
    23 	kaz
    24 --
    25 int val = 0xff00;
    26 
    27 int f (void) { return val; }
    28 
    29 unsigned char a[1];
    30 
    31 void
    32 foo (void)
    33 {
    34   a[0] = f () & 255;
    35 
    36   if (!a[0])
    37     a[0] = f () & 255;
    38 
    39   if (!a[0])
    40     a[0] = 1 + (f () & 127);
    41 }
    42 
    43 int
    44 main (int argc, char **argv)
    45 {
    46   foo ();
    47   if (!a[0])
    48     abort ();
    49 
    50   return 0;
    51 }
    52 
    53 --
    54 
    55 diff -u3prN ORIG/gcc/gcc/config/sh/sh.c LOCAL/gcc/gcc/config/sh/sh.c
    56 --- gcc/gcc/config/sh/sh.c.old	Fri Aug  8 18:39:02 2003
    57 +++ gcc/gcc/config/sh/sh.c	Fri Aug  8 22:31:02 2003
    58 @@ -6657,6 +6657,19 @@ arith_reg_dest (op, mode)
    59    return arith_reg_operand (op, mode);
    60  }
    61  
    62 +/* Like above, but for SImode compare destinations: forbid paradoxical
    63 +   subregs, because it would get the combiner confused.  */
    64 +int
    65 +arith_reg_cmp_dest (op, mode)
    66 +     rtx op;
    67 +     enum machine_mode mode;
    68 +{
    69 +  if (mode == SImode && GET_CODE (op) == SUBREG
    70 +      && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 4)
    71 +    return 0;
    72 +  return arith_reg_operand (op, mode);
    73 +}
    74 +
    75  int
    76  int_gpr_dest (op, mode)
    77       rtx op;
    78 diff -u3prN ORIG/gcc/gcc/config/sh/sh.h LOCAL/gcc/gcc/config/sh/sh.h
    79 --- gcc/gcc/config/sh/sh.h.old	Fri Aug  8 18:39:02 2003
    80 +++ gcc/gcc/config/sh/sh.h	Fri Aug  8 22:31:02 2003
    81 @@ -3365,6 +3365,7 @@ extern int rtx_equal_function_value_matt
    82    {"and_operand", {SUBREG, REG, CONST_INT}},				\
    83    {"any_register_operand", {SUBREG, REG}},				\
    84    {"arith_operand", {SUBREG, REG, CONST_INT}},				\
    85 +  {"arith_reg_cmp_dest", {SUBREG, REG}},				\
    86    {"arith_reg_dest", {SUBREG, REG}},					\
    87    {"arith_reg_operand", {SUBREG, REG}},					\
    88    {"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}},	\
    89 
    90 --- gcc-3.3/gcc/config/sh/sh.md.orig	Tue Apr 15 10:06:10 2003
    91 +++ gcc-3.3/gcc/config/sh/sh.md	Sat Aug  9 22:31:13 2003
    92 @@ -616,7 +616,7 @@
    93  
    94  (define_insn ""
    95    [(set (reg:SI T_REG)
    96 -	(eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
    97 +	(eq:SI (and:SI (match_operand:SI 0 "arith_reg_cmp_dest" "z,r")
    98  		       (match_operand:SI 1 "arith_operand" "L,r"))
    99  	       (const_int 0)))]
   100    "TARGET_SH1"
   101 @@ -631,7 +631,7 @@
   102  
   103  (define_insn "cmpeqsi_t"
   104    [(set (reg:SI T_REG)
   105 -	(eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
   106 +	(eq:SI (match_operand:SI 0 "arith_reg_cmp_dest" "r,z,r")
   107  	       (match_operand:SI 1 "arith_operand" "N,rI,r")))]
   108    "TARGET_SH1"
   109    "@
   110 @@ -642,7 +642,7 @@
   111  
   112  (define_insn "cmpgtsi_t"
   113    [(set (reg:SI T_REG)
   114 -	(gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
   115 +	(gt:SI (match_operand:SI 0 "arith_reg_cmp_dest" "r,r")
   116  	       (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
   117    "TARGET_SH1"
   118    "@
   119 @@ -652,7 +652,7 @@
   120  
   121  (define_insn "cmpgesi_t"
   122    [(set (reg:SI T_REG)
   123 -	(ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
   124 +	(ge:SI (match_operand:SI 0 "arith_reg_cmp_dest" "r,r")
   125  	       (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
   126    "TARGET_SH1"
   127    "@
   128 @@ -666,7 +666,7 @@
   129  
   130  (define_insn "cmpgeusi_t"
   131    [(set (reg:SI T_REG)
   132 -	(geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
   133 +	(geu:SI (match_operand:SI 0 "arith_reg_cmp_dest" "r")
   134  		(match_operand:SI 1 "arith_reg_operand" "r")))]
   135    "TARGET_SH1"
   136    "cmp/hs	%1,%0"
   137 @@ -674,7 +674,7 @@
   138  
   139  (define_insn "cmpgtusi_t"
   140    [(set (reg:SI T_REG)
   141 -	(gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
   142 +	(gtu:SI (match_operand:SI 0 "arith_reg_cmp_dest" "r")
   143  		(match_operand:SI 1 "arith_reg_operand" "r")))]
   144    "TARGET_SH1"
   145    "cmp/hi	%1,%0"