1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/patches/gcc/3.3/sh4-kaz-workaround.patch Mon Jul 02 17:49:21 2007 +0000
1.3 @@ -0,0 +1,145 @@
1.4 +[lightly edited to fit my patch directory - dank]
1.5 +
1.6 +From: kaz Kojima <kkojima@rr.iij4u.or.jp>
1.7 +Date: Sat, 09 Aug 2003 09:46:21 +0900
1.8 +To: dank@kegel.com
1.9 +
1.10 +Hi Dan,
1.11 +
1.12 +I've come back from the vacation and looked glibc string test
1.13 +failures on sh4. This looks a gcc problem. gcc-3.3/3.4 doesn't
1.14 +compile these tests correctly. The attached testcase aborts on
1.15 +gcc-3.3/3.4 -O2 but exits normally gcc-3.2 and gcc-3.0.
1.16 +The option -O2 is not essential but it makes the testcase small.
1.17 +The failed string tests include the same pattern of the code with
1.18 +f=random to generate ramdom strings but they get strings with
1.19 +embedded NULL characters :-(
1.20 +
1.21 +...
1.22 +I've got a workaround below for this bug, though it might merely
1.23 +paper over the real bug. Anyway, I'd like to send a PR for this.
1.24 +
1.25 +Regards,
1.26 + kaz
1.27 +--
1.28 +int val = 0xff00;
1.29 +
1.30 +int f (void) { return val; }
1.31 +
1.32 +unsigned char a[1];
1.33 +
1.34 +void
1.35 +foo (void)
1.36 +{
1.37 + a[0] = f () & 255;
1.38 +
1.39 + if (!a[0])
1.40 + a[0] = f () & 255;
1.41 +
1.42 + if (!a[0])
1.43 + a[0] = 1 + (f () & 127);
1.44 +}
1.45 +
1.46 +int
1.47 +main (int argc, char **argv)
1.48 +{
1.49 + foo ();
1.50 + if (!a[0])
1.51 + abort ();
1.52 +
1.53 + return 0;
1.54 +}
1.55 +
1.56 +--
1.57 +
1.58 +diff -u3prN ORIG/gcc/gcc/config/sh/sh.c LOCAL/gcc/gcc/config/sh/sh.c
1.59 +--- gcc/gcc/config/sh/sh.c.old Fri Aug 8 18:39:02 2003
1.60 ++++ gcc/gcc/config/sh/sh.c Fri Aug 8 22:31:02 2003
1.61 +@@ -6657,6 +6657,19 @@ arith_reg_dest (op, mode)
1.62 + return arith_reg_operand (op, mode);
1.63 + }
1.64 +
1.65 ++/* Like above, but for SImode compare destinations: forbid paradoxical
1.66 ++ subregs, because it would get the combiner confused. */
1.67 ++int
1.68 ++arith_reg_cmp_dest (op, mode)
1.69 ++ rtx op;
1.70 ++ enum machine_mode mode;
1.71 ++{
1.72 ++ if (mode == SImode && GET_CODE (op) == SUBREG
1.73 ++ && GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))) < 4)
1.74 ++ return 0;
1.75 ++ return arith_reg_operand (op, mode);
1.76 ++}
1.77 ++
1.78 + int
1.79 + int_gpr_dest (op, mode)
1.80 + rtx op;
1.81 +diff -u3prN ORIG/gcc/gcc/config/sh/sh.h LOCAL/gcc/gcc/config/sh/sh.h
1.82 +--- gcc/gcc/config/sh/sh.h.old Fri Aug 8 18:39:02 2003
1.83 ++++ gcc/gcc/config/sh/sh.h Fri Aug 8 22:31:02 2003
1.84 +@@ -3365,6 +3365,7 @@ extern int rtx_equal_function_value_matt
1.85 + {"and_operand", {SUBREG, REG, CONST_INT}}, \
1.86 + {"any_register_operand", {SUBREG, REG}}, \
1.87 + {"arith_operand", {SUBREG, REG, CONST_INT}}, \
1.88 ++ {"arith_reg_cmp_dest", {SUBREG, REG}}, \
1.89 + {"arith_reg_dest", {SUBREG, REG}}, \
1.90 + {"arith_reg_operand", {SUBREG, REG}}, \
1.91 + {"arith_reg_or_0_operand", {SUBREG, REG, CONST_INT, CONST_VECTOR}}, \
1.92 +
1.93 +--- gcc-3.3/gcc/config/sh/sh.md.orig Tue Apr 15 10:06:10 2003
1.94 ++++ gcc-3.3/gcc/config/sh/sh.md Sat Aug 9 22:31:13 2003
1.95 +@@ -616,7 +616,7 @@
1.96 +
1.97 + (define_insn ""
1.98 + [(set (reg:SI T_REG)
1.99 +- (eq:SI (and:SI (match_operand:SI 0 "arith_reg_operand" "z,r")
1.100 ++ (eq:SI (and:SI (match_operand:SI 0 "arith_reg_cmp_dest" "z,r")
1.101 + (match_operand:SI 1 "arith_operand" "L,r"))
1.102 + (const_int 0)))]
1.103 + "TARGET_SH1"
1.104 +@@ -631,7 +631,7 @@
1.105 +
1.106 + (define_insn "cmpeqsi_t"
1.107 + [(set (reg:SI T_REG)
1.108 +- (eq:SI (match_operand:SI 0 "arith_reg_operand" "r,z,r")
1.109 ++ (eq:SI (match_operand:SI 0 "arith_reg_cmp_dest" "r,z,r")
1.110 + (match_operand:SI 1 "arith_operand" "N,rI,r")))]
1.111 + "TARGET_SH1"
1.112 + "@
1.113 +@@ -642,7 +642,7 @@
1.114 +
1.115 + (define_insn "cmpgtsi_t"
1.116 + [(set (reg:SI T_REG)
1.117 +- (gt:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
1.118 ++ (gt:SI (match_operand:SI 0 "arith_reg_cmp_dest" "r,r")
1.119 + (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
1.120 + "TARGET_SH1"
1.121 + "@
1.122 +@@ -652,7 +652,7 @@
1.123 +
1.124 + (define_insn "cmpgesi_t"
1.125 + [(set (reg:SI T_REG)
1.126 +- (ge:SI (match_operand:SI 0 "arith_reg_operand" "r,r")
1.127 ++ (ge:SI (match_operand:SI 0 "arith_reg_cmp_dest" "r,r")
1.128 + (match_operand:SI 1 "arith_reg_or_0_operand" "r,N")))]
1.129 + "TARGET_SH1"
1.130 + "@
1.131 +@@ -666,7 +666,7 @@
1.132 +
1.133 + (define_insn "cmpgeusi_t"
1.134 + [(set (reg:SI T_REG)
1.135 +- (geu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1.136 ++ (geu:SI (match_operand:SI 0 "arith_reg_cmp_dest" "r")
1.137 + (match_operand:SI 1 "arith_reg_operand" "r")))]
1.138 + "TARGET_SH1"
1.139 + "cmp/hs %1,%0"
1.140 +@@ -674,7 +674,7 @@
1.141 +
1.142 + (define_insn "cmpgtusi_t"
1.143 + [(set (reg:SI T_REG)
1.144 +- (gtu:SI (match_operand:SI 0 "arith_reg_operand" "r")
1.145 ++ (gtu:SI (match_operand:SI 0 "arith_reg_cmp_dest" "r")
1.146 + (match_operand:SI 1 "arith_reg_operand" "r")))]
1.147 + "TARGET_SH1"
1.148 + "cmp/hi %1,%0"