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