Apply gcc 4.4
[vuplus_openembedded] / recipes / linux / linux-bm750-2.6.18 / linux_bm750_gcc_4.4.patch
1 diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
2 index 7b4553d..c402c37 100644
3 --- a/arch/mips/kernel/asm-offsets.c
4 +++ b/arch/mips/kernel/asm-offsets.c
5 @@ -22,7 +22,7 @@
6  #define offset(string, ptr, member) \
7         __asm__("\n@@@" string "%0" : : "i" (_offset(ptr, member)))
8  #define constant(string, member) \
9 -       __asm__("\n@@@" string "%X0" : : "ri" (member))
10 +       __asm__("\n@@@" string "%0" : : "ri" (member))
11  #define size(string, size) \
12         __asm__("\n@@@" string "%0" : : "i" (sizeof(size)))
13  #define linefeed text("")
14 diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
15 index ab3c3ea..c19c37f 100644
16 --- a/arch/mips/kernel/time.c
17 +++ b/arch/mips/kernel/time.c
18 @@ -281,10 +281,14 @@ static unsigned long fixed_rate_gettimeoffset(void)
19         /* .. relative to previous jiffy (32 bits is enough) */
20         count -= timerlo;
21  
22 +#ifndef GCC_NO_H_CONSTRAINT
23         __asm__("multu  %1,%2"
24                 : "=h" (res)
25                 : "r" (count), "r" (sll32_usecs_per_cycle)
26                 : "lo", GCC_REG_ACCUM);
27 +#else
28 +       res = ((uintx_t)count * sll32_usecs_per_cycle) >> BITS_PER_LONG;
29 +#endif
30  
31  #if    0
32         /*
33 @@ -337,10 +341,14 @@ static unsigned long calibrate_div32_gettimeoffset(void)
34         /* .. relative to previous jiffy (32 bits is enough) */
35         count -= timerlo;
36  
37 +#ifndef GCC_NO_H_CONSTRAINT
38         __asm__("multu  %1,%2"
39                 : "=h" (res)
40                 : "r" (count), "r" (quotient)
41                 : "lo", GCC_REG_ACCUM);
42 +#else
43 +       res = ((uintx_t)count * quotient) >> BITS_PER_LONG;
44 +#endif
45  
46         /*
47          * Due to possible jiffies inconsistencies, we need to check
48 @@ -393,10 +401,14 @@ static unsigned long calibrate_div64_gettimeoffset(void)
49         /* .. relative to previous jiffy (32 bits is enough) */
50         count -= timerlo;
51  
52 +#ifndef GCC_NO_H_CONSTRAINT
53         __asm__("multu  %1,%2"
54                 : "=h" (res)
55                 : "r" (count), "r" (quotient)
56                 : "lo", GCC_REG_ACCUM);
57 +#else
58 +       res = ((uintx_t)count * quotient) >> BITS_PER_LONG;
59 +#endif
60  
61         /*
62          * Due to possible jiffies inconsistencies, we need to check
63 @@ -440,7 +452,7 @@ EXPORT_SYMBOL(null_perf_irq);
64  EXPORT_SYMBOL(perf_irq);
65  
66  extern int performance_enabled;
67 -extern int test_all_counters();
68 +extern int test_all_counters(void);
69  
70  /*
71   * High-level timer interrupt service routines.  This function
72 diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
73 index 44b76d3..46ebcb8 100644
74 --- a/arch/mips/lib/Makefile
75 +++ b/arch/mips/lib/Makefile
76 @@ -10,6 +10,6 @@ obj-$(CONFIG_PCI)     += iomap-pci.o
77  
78  # libgcc-style stuff needed in the kernel
79  # PR43073: changed from lib-y
80 -obj-y += ashldi3.o ashrdi3.o lshrdi3.o
81 +obj-y += ashldi3.o ashrdi3.o lshrdi3.o ucmpdi2.o
82  
83  EXTRA_AFLAGS := $(CFLAGS)
84 diff --git a/arch/mips/lib/ucmpdi2.c b/arch/mips/lib/ucmpdi2.c
85 index e69de29..bb4cb2f 100644
86 --- a/arch/mips/lib/ucmpdi2.c
87 +++ b/arch/mips/lib/ucmpdi2.c
88 @@ -0,0 +1,21 @@
89 +#include <linux/module.h>
90 +
91 +#include "libgcc.h"
92 +
93 +word_type __ucmpdi2(unsigned long long a, unsigned long long b)
94 +{
95 +       const DWunion au = {.ll = a};
96 +       const DWunion bu = {.ll = b};
97 +
98 +       if ((unsigned int) au.s.high < (unsigned int) bu.s.high)
99 +               return 0;
100 +       else if ((unsigned int) au.s.high > (unsigned int) bu.s.high)
101 +               return 2;
102 +       if ((unsigned int) au.s.low < (unsigned int) bu.s.low)
103 +               return 0;
104 +       else if ((unsigned int) au.s.low > (unsigned int) bu.s.low)
105 +               return 2;
106 +       return 1;
107 +}
108 +
109 +EXPORT_SYMBOL(__ucmpdi2);
110 diff --git a/include/asm-mips/compiler.h b/include/asm-mips/compiler.h
111 index 169ae26..4b56fe4 100644
112 --- a/include/asm-mips/compiler.h
113 +++ b/include/asm-mips/compiler.h
114 @@ -8,10 +8,21 @@
115  #ifndef _ASM_COMPILER_H
116  #define _ASM_COMPILER_H
117  
118 +#include <asm/types.h>
119 +
120  #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
121  #define GCC_REG_ACCUM "$0"
122  #else
123  #define GCC_REG_ACCUM "accum"
124  #endif
125  
126 +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
127 +#define GCC_NO_H_CONSTRAINT
128 +#ifdef CONFIG_64BIT
129 +typedef unsigned int uintx_t __attribute__((mode(TI)));
130 +#else
131 +typedef u64 uintx_t;
132 +#endif
133 +#endif
134 +
135  #endif /* _ASM_COMPILER_H */
136 diff --git a/include/asm-mips/delay.h b/include/asm-mips/delay.h
137 index 223d156..7c9dc07 100644
138 --- a/include/asm-mips/delay.h
139 +++ b/include/asm-mips/delay.h
140 @@ -36,6 +36,37 @@ static inline void __delay(unsigned long loops)
141                 : "0" (loops));
142  }
143  
144 +/*
145 + * convert usecs to loops
146 + *
147 + * handle removal of 'h' constraint in GCC 4.4
148 + */
149 +
150 +#ifndef GCC_NO_H_CONSTRAINT    /* gcc <= 4.3 */
151 +static inline unsigned long __usecs_to_loops(unsigned long usecs, unsigned long lpj)
152 +{
153 +       unsigned long lo;
154 +
155 +       if (sizeof(long) == 4)
156 +               __asm__("multu\t%2, %3"
157 +               : "=h" (usecs), "=l" (lo)
158 +               : "r" (usecs), "r" (lpj)
159 +               : GCC_REG_ACCUM);
160 +       else if (sizeof(long) == 8)
161 +               __asm__("dmultu\t%2, %3"
162 +               : "=h" (usecs), "=l" (lo)
163 +               : "r" (usecs), "r" (lpj)
164 +               : GCC_REG_ACCUM);
165 +
166 +       return usecs;
167 +}
168 +#else  /* GCC_NO_H_CONSTRAINT, gcc >= 4.4 */
169 +static inline unsigned long __usecs_to_loops(unsigned long usecs,
170 +               unsigned long lpj)
171 +{
172 +       return ((uintx_t)usecs * lpj) >> BITS_PER_LONG;
173 +}
174 +#endif
175  
176  /*
177   * Division by multiplication: you don't have to worry about
178 @@ -50,8 +81,6 @@ static inline void __delay(unsigned long loops)
179  
180  static inline void __udelay(unsigned long usecs, unsigned long lpj)
181  {
182 -       unsigned long lo;
183 -
184         /*
185          * The rates of 128 is rounded wrongly by the catchall case
186          * for 64-bit.  Excessive precission?  Probably ...
187 @@ -64,19 +93,7 @@ static inline void __udelay(unsigned long usecs, unsigned long lpj)
188         usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) +
189                                    0x80000000ULL) >> 32);
190  #endif
191 -
192 -       if (sizeof(long) == 4)
193 -               __asm__("multu\t%2, %3"
194 -               : "=h" (usecs), "=l" (lo)
195 -               : "r" (usecs), "r" (lpj)
196 -               : GCC_REG_ACCUM);
197 -       else if (sizeof(long) == 8)
198 -               __asm__("dmultu\t%2, %3"
199 -               : "=h" (usecs), "=l" (lo)
200 -               : "r" (usecs), "r" (lpj)
201 -               : GCC_REG_ACCUM);
202 -
203 -       __delay(usecs);
204 +       __delay(__usecs_to_loops(usecs, lpj));
205  }
206  
207  #define __udelay_val cpu_data[raw_smp_processor_id()].udelay_val
208 diff --git a/include/asm-mips/div64.h b/include/asm-mips/div64.h
209 index 5f7dcf5..9325185 100644
210 --- a/include/asm-mips/div64.h
211 +++ b/include/asm-mips/div64.h
212 @@ -53,6 +53,23 @@
213         (res) = __quot; \
214         __mod; })
215  
216 +/*
217 + * __do_divu -- unsigned interger dividing
218 + *
219 + * handle removal of 'h' constraint in GCC 4.4
220 + */
221 +#ifndef GCC_NO_H_CONSTRAINT /* gcc <= 4.3*/
222 +#define __do_divu() ({ \
223 + __asm__("divu $0, %z2, %z3" \
224 + : "=h" (__upper), "=l" (__high) \
225 + : "Jr" (__high), "Jr" (__base) \
226 + : GCC_REG_ACCUM); })
227 +#else /* gcc >= 4.4 */
228 +#define __do_divu() ({ \
229 + __upper = (uintx_t)__high % __base; \
230 + __high = (uintx_t)__high / __base; })
231 +#endif
232 +
233  #define do_div(n, base) ({ \
234         unsigned long long __quot; \
235         unsigned long __mod; \
236 @@ -67,10 +84,7 @@
237         __upper = __high; \
238         \
239         if (__high) \
240 -               __asm__("divu   $0, %z2, %z3" \
241 -                       : "=h" (__upper), "=l" (__high) \
242 -                       : "Jr" (__high), "Jr" (__base) \
243 -                       : GCC_REG_ACCUM); \
244 +               __do_divu(); \
245         \
246         __mod = do_div64_32(__low, __upper, __low, __base); \
247         \