diff options
author | Kumar Gala <galak@kernel.crashing.org> | 2011-08-26 09:33:53 -0500 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2011-08-29 13:47:59 +0100 |
commit | 5d463057b4b7eb38a2ff009904ad1f240193f3ad (patch) | |
tree | 4d1a219403354ac1cc582ab50dea3b13fc20f7eb /meta/recipes-devtools/gcc/gcc-4.5.1 | |
parent | 36cda027159528f9304dfe9e43aaba708b796b24 (diff) | |
download | poky-5d463057b4b7eb38a2ff009904ad1f240193f3ad.tar.gz |
gcc-4.5.1: Drop gcc-poison-parameters.patch, replace with bug fix patch
The gcc-poison-parameters was added specifically to deal with an issue
on ppc targets and a bug when we build with -Os -frename-registers.
This bug below reports the issue and is fixed in gcc-4.6.x/mainline:
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44618
Backport patch to gcc 4.5.1.
(From OE-Core rev: fef385e37e82a0eec743fbd1da11021b9e7158b5)
Signed-off-by: Kumar Gala <galak@kernel.crashing.org>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.5.1')
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-4.5.1/gcc-poison-parameters.patch | 85 | ||||
-rw-r--r-- | meta/recipes-devtools/gcc/gcc-4.5.1/pr44618.patch | 314 |
2 files changed, 314 insertions, 85 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.5.1/gcc-poison-parameters.patch b/meta/recipes-devtools/gcc/gcc-4.5.1/gcc-poison-parameters.patch deleted file mode 100644 index 74d45277e2..0000000000 --- a/meta/recipes-devtools/gcc/gcc-4.5.1/gcc-poison-parameters.patch +++ /dev/null | |||
@@ -1,85 +0,0 @@ | |||
1 | Upstream-Status: Pending | ||
2 | |||
3 | gcc: add poison parameters detection | ||
4 | |||
5 | Add the logic that, if not configured with "--enable-target-optspace", | ||
6 | gcc will meet error when build target app with "-Os" option. | ||
7 | This could avoid potential binary crash. | ||
8 | |||
9 | Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com> | ||
10 | |||
11 | diff --git a/gcc/config.in b/gcc/config.in | ||
12 | index a9e208f..3004321 100644 | ||
13 | --- a/gcc/config.in | ||
14 | +++ b/gcc/config.in | ||
15 | @@ -132,6 +132,12 @@ | ||
16 | #endif | ||
17 | |||
18 | |||
19 | +/* Define to enable target optspace support. */ | ||
20 | +#ifndef USED_FOR_TARGET | ||
21 | +#undef ENABLE_TARGET_OPTSPACE | ||
22 | +#endif | ||
23 | + | ||
24 | + | ||
25 | /* Define if you want all operations on RTL (the basic data structure of the | ||
26 | optimizer and back end) to be checked for dynamic type safety at runtime. | ||
27 | This is quite expensive. */ | ||
28 | diff --git a/gcc/configure b/gcc/configure | ||
29 | index 2e022ed..004ec0b 100755 | ||
30 | --- a/gcc/configure | ||
31 | +++ b/gcc/configure | ||
32 | @@ -909,6 +909,7 @@ enable_maintainer_mode | ||
33 | enable_version_specific_runtime_libs | ||
34 | with_slibdir | ||
35 | enable_plugin | ||
36 | +enable_target_optspace | ||
37 | ' | ||
38 | ac_precious_vars='build_alias | ||
39 | host_alias | ||
40 | @@ -25289,6 +25290,13 @@ $as_echo "#define ENABLE_PLUGIN 1" >>confdefs.h | ||
41 | |||
42 | fi | ||
43 | |||
44 | +if test x"$enable_target_optspace" != x; then : | ||
45 | + | ||
46 | +$as_echo "#define ENABLE_TARGET_OPTSPACE 1" >>confdefs.h | ||
47 | + | ||
48 | +fi | ||
49 | + | ||
50 | + | ||
51 | # Configure the subdirectories | ||
52 | # AC_CONFIG_SUBDIRS($subdirs) | ||
53 | |||
54 | diff --git a/gcc/configure.ac b/gcc/configure.ac | ||
55 | index ac4ca70..18ec0aa 100644 | ||
56 | --- a/gcc/configure.ac | ||
57 | +++ b/gcc/configure.ac | ||
58 | @@ -4434,6 +4434,11 @@ if test x"$enable_plugin" = x"yes"; then | ||
59 | AC_DEFINE(ENABLE_PLUGIN, 1, [Define to enable plugin support.]) | ||
60 | fi | ||
61 | |||
62 | +AC_SUBST(enable_target_optspace) | ||
63 | +if test x"$enable_target_optspace" != x; then | ||
64 | + AC_DEFINE(ENABLE_TARGET_OPTSPACE, 1, [Define to enable target optspace support.]) | ||
65 | +fi | ||
66 | + | ||
67 | # Configure the subdirectories | ||
68 | # AC_CONFIG_SUBDIRS($subdirs) | ||
69 | |||
70 | diff --git a/gcc/opts.c b/gcc/opts.c | ||
71 | index 139cd26..2fdd96a 100644 | ||
72 | --- a/gcc/opts.c | ||
73 | +++ b/gcc/opts.c | ||
74 | @@ -945,6 +945,11 @@ decode_options (unsigned int argc, const char **argv) | ||
75 | else | ||
76 | set_param_value ("min-crossjump-insns", initial_min_crossjump_insns); | ||
77 | |||
78 | +#ifndef ENABLE_TARGET_OPTSPACE | ||
79 | + if (optimize_size == 1) | ||
80 | + error ("Do not use -Os option if --enable-target-optspace is not set."); | ||
81 | +#endif | ||
82 | + | ||
83 | if (first_time_p) | ||
84 | { | ||
85 | /* Initialize whether `char' is signed. */ | ||
diff --git a/meta/recipes-devtools/gcc/gcc-4.5.1/pr44618.patch b/meta/recipes-devtools/gcc/gcc-4.5.1/pr44618.patch new file mode 100644 index 0000000000..23f41ccd90 --- /dev/null +++ b/meta/recipes-devtools/gcc/gcc-4.5.1/pr44618.patch | |||
@@ -0,0 +1,314 @@ | |||
1 | Upstream-Status: Pending | ||
2 | |||
3 | Backport of bugfix in gcc-4.6.x and mainline that address bug 44618 in | ||
4 | which we get wrong code generation with -Os -frename-registers. | ||
5 | |||
6 | 2011-06-13 Edmar Wienskoski <edmar@freescale.com> | ||
7 | |||
8 | PR target/44618 | ||
9 | * config/rs6000/rs6000.md (save_gpregs_<mode>): Replaced pattern | ||
10 | with a set of similar patterns, where the MATCH_OPERAND for the | ||
11 | function argument is replaced with individual references to hardware | ||
12 | registers. | ||
13 | (save_fpregs_<mode>): Ditto | ||
14 | (restore_gpregs_<mode>): Ditto | ||
15 | (return_and_restore_gpregs_<mode>): Ditto | ||
16 | (return_and_restore_fpregs_<mode>): Ditto | ||
17 | (return_and_restore_fpregs_aix_<mode>): Ditto | ||
18 | |||
19 | * gcc.target/powerpc/outofline_rnreg.c: New testcase. | ||
20 | |||
21 | Index: gcc-4.5.1/gcc/config/rs6000/rs6000.md | ||
22 | =================================================================== | ||
23 | --- gcc-4.5.1.orig/gcc/config/rs6000/rs6000.md | ||
24 | +++ gcc-4.5.1/gcc/config/rs6000/rs6000.md | ||
25 | @@ -15256,25 +15256,88 @@ | ||
26 | "{stm|stmw} %2,%1" | ||
27 | [(set_attr "type" "store_ux")]) | ||
28 | |||
29 | -(define_insn "*save_gpregs_<mode>" | ||
30 | +; The following comment applies to: | ||
31 | +; save_gpregs_* | ||
32 | +; save_fpregs_* | ||
33 | +; restore_gpregs* | ||
34 | +; return_and_restore_gpregs* | ||
35 | +; return_and_restore_fpregs* | ||
36 | +; return_and_restore_fpregs_aix* | ||
37 | +; | ||
38 | +; The out-of-line save / restore functions expects one input argument. | ||
39 | +; Since those are not standard call_insn's, we must avoid using | ||
40 | +; MATCH_OPERAND for that argument. That way the register rename | ||
41 | +; optimization will not try to rename this register. | ||
42 | +; Each pattern is repeated for each possible register number used in | ||
43 | +; various ABIs (r11, r1, and for some functions r12) | ||
44 | + | ||
45 | +(define_insn "*save_gpregs_<mode>_r11" | ||
46 | + [(match_parallel 0 "any_parallel_operand" | ||
47 | + [(clobber (reg:P 65)) | ||
48 | + (use (match_operand:P 1 "symbol_ref_operand" "s")) | ||
49 | + (use (reg:P 11)) | ||
50 | + (set (match_operand:P 2 "memory_operand" "=m") | ||
51 | + (match_operand:P 3 "gpc_reg_operand" "r"))])] | ||
52 | + "" | ||
53 | + "bl %1" | ||
54 | + [(set_attr "type" "branch") | ||
55 | + (set_attr "length" "4")]) | ||
56 | + | ||
57 | +(define_insn "*save_gpregs_<mode>_r12" | ||
58 | + [(match_parallel 0 "any_parallel_operand" | ||
59 | + [(clobber (reg:P 65)) | ||
60 | + (use (match_operand:P 1 "symbol_ref_operand" "s")) | ||
61 | + (use (reg:P 12)) | ||
62 | + (set (match_operand:P 2 "memory_operand" "=m") | ||
63 | + (match_operand:P 3 "gpc_reg_operand" "r"))])] | ||
64 | + "" | ||
65 | + "bl %1" | ||
66 | + [(set_attr "type" "branch") | ||
67 | + (set_attr "length" "4")]) | ||
68 | + | ||
69 | +(define_insn "*save_gpregs_<mode>_r1" | ||
70 | + [(match_parallel 0 "any_parallel_operand" | ||
71 | + [(clobber (reg:P 65)) | ||
72 | + (use (match_operand:P 1 "symbol_ref_operand" "s")) | ||
73 | + (use (reg:P 1)) | ||
74 | + (set (match_operand:P 2 "memory_operand" "=m") | ||
75 | + (match_operand:P 3 "gpc_reg_operand" "r"))])] | ||
76 | + "" | ||
77 | + "bl %1" | ||
78 | + [(set_attr "type" "branch") | ||
79 | + (set_attr "length" "4")]) | ||
80 | + | ||
81 | +(define_insn "*save_fpregs_<mode>_r11" | ||
82 | + [(match_parallel 0 "any_parallel_operand" | ||
83 | + [(clobber (reg:P 65)) | ||
84 | + (use (match_operand:P 1 "symbol_ref_operand" "s")) | ||
85 | + (use (reg:P 11)) | ||
86 | + (set (match_operand:DF 2 "memory_operand" "=m") | ||
87 | + (match_operand:DF 3 "gpc_reg_operand" "d"))])] | ||
88 | + "" | ||
89 | + "bl %1" | ||
90 | + [(set_attr "type" "branch") | ||
91 | + (set_attr "length" "4")]) | ||
92 | + | ||
93 | +(define_insn "*save_fpregs_<mode>_r12" | ||
94 | [(match_parallel 0 "any_parallel_operand" | ||
95 | [(clobber (reg:P 65)) | ||
96 | (use (match_operand:P 1 "symbol_ref_operand" "s")) | ||
97 | - (use (match_operand:P 2 "gpc_reg_operand" "r")) | ||
98 | - (set (match_operand:P 3 "memory_operand" "=m") | ||
99 | - (match_operand:P 4 "gpc_reg_operand" "r"))])] | ||
100 | + (use (reg:P 12)) | ||
101 | + (set (match_operand:DF 2 "memory_operand" "=m") | ||
102 | + (match_operand:DF 3 "gpc_reg_operand" "d"))])] | ||
103 | "" | ||
104 | "bl %1" | ||
105 | [(set_attr "type" "branch") | ||
106 | (set_attr "length" "4")]) | ||
107 | |||
108 | -(define_insn "*save_fpregs_<mode>" | ||
109 | +(define_insn "*save_fpregs_<mode>_r1" | ||
110 | [(match_parallel 0 "any_parallel_operand" | ||
111 | [(clobber (reg:P 65)) | ||
112 | (use (match_operand:P 1 "symbol_ref_operand" "s")) | ||
113 | - (use (match_operand:P 2 "gpc_reg_operand" "r")) | ||
114 | - (set (match_operand:DF 3 "memory_operand" "=m") | ||
115 | - (match_operand:DF 4 "gpc_reg_operand" "d"))])] | ||
116 | + (use (reg:P 1)) | ||
117 | + (set (match_operand:DF 2 "memory_operand" "=m") | ||
118 | + (match_operand:DF 3 "gpc_reg_operand" "d"))])] | ||
119 | "" | ||
120 | "bl %1" | ||
121 | [(set_attr "type" "branch") | ||
122 | @@ -15372,52 +15435,156 @@ | ||
123 | ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall | ||
124 | ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... | ||
125 | |||
126 | -(define_insn "*restore_gpregs_<mode>" | ||
127 | +; The following comment applies to: | ||
128 | +; save_gpregs_* | ||
129 | +; save_fpregs_* | ||
130 | +; restore_gpregs* | ||
131 | +; return_and_restore_gpregs* | ||
132 | +; return_and_restore_fpregs* | ||
133 | +; return_and_restore_fpregs_aix* | ||
134 | +; | ||
135 | +; The out-of-line save / restore functions expects one input argument. | ||
136 | +; Since those are not standard call_insn's, we must avoid using | ||
137 | +; MATCH_OPERAND for that argument. That way the register rename | ||
138 | +; optimization will not try to rename this register. | ||
139 | +; Each pattern is repeated for each possible register number used in | ||
140 | +; various ABIs (r11, r1, and for some functions r12) | ||
141 | + | ||
142 | +(define_insn "*restore_gpregs_<mode>_r11" | ||
143 | + [(match_parallel 0 "any_parallel_operand" | ||
144 | + [(clobber (match_operand:P 1 "register_operand" "=l")) | ||
145 | + (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
146 | + (use (reg:P 11)) | ||
147 | + (set (match_operand:P 3 "gpc_reg_operand" "=r") | ||
148 | + (match_operand:P 4 "memory_operand" "m"))])] | ||
149 | + "" | ||
150 | + "bl %2" | ||
151 | + [(set_attr "type" "branch") | ||
152 | + (set_attr "length" "4")]) | ||
153 | + | ||
154 | +(define_insn "*restore_gpregs_<mode>_r12" | ||
155 | [(match_parallel 0 "any_parallel_operand" | ||
156 | [(clobber (match_operand:P 1 "register_operand" "=l")) | ||
157 | (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
158 | - (use (match_operand:P 3 "gpc_reg_operand" "r")) | ||
159 | - (set (match_operand:P 4 "gpc_reg_operand" "=r") | ||
160 | - (match_operand:P 5 "memory_operand" "m"))])] | ||
161 | + (use (reg:P 12)) | ||
162 | + (set (match_operand:P 3 "gpc_reg_operand" "=r") | ||
163 | + (match_operand:P 4 "memory_operand" "m"))])] | ||
164 | "" | ||
165 | "bl %2" | ||
166 | [(set_attr "type" "branch") | ||
167 | (set_attr "length" "4")]) | ||
168 | |||
169 | -(define_insn "*return_and_restore_gpregs_<mode>" | ||
170 | +(define_insn "*restore_gpregs_<mode>_r1" | ||
171 | + [(match_parallel 0 "any_parallel_operand" | ||
172 | + [(clobber (match_operand:P 1 "register_operand" "=l")) | ||
173 | + (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
174 | + (use (reg:P 1)) | ||
175 | + (set (match_operand:P 3 "gpc_reg_operand" "=r") | ||
176 | + (match_operand:P 4 "memory_operand" "m"))])] | ||
177 | + "" | ||
178 | + "bl %2" | ||
179 | + [(set_attr "type" "branch") | ||
180 | + (set_attr "length" "4")]) | ||
181 | + | ||
182 | +(define_insn "*return_and_restore_gpregs_<mode>_r11" | ||
183 | + [(match_parallel 0 "any_parallel_operand" | ||
184 | + [(return) | ||
185 | + (clobber (match_operand:P 1 "register_operand" "=l")) | ||
186 | + (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
187 | + (use (reg:P 11)) | ||
188 | + (set (match_operand:P 3 "gpc_reg_operand" "=r") | ||
189 | + (match_operand:P 4 "memory_operand" "m"))])] | ||
190 | + "" | ||
191 | + "b %2" | ||
192 | + [(set_attr "type" "branch") | ||
193 | + (set_attr "length" "4")]) | ||
194 | + | ||
195 | +(define_insn "*return_and_restore_gpregs_<mode>_r12" | ||
196 | + [(match_parallel 0 "any_parallel_operand" | ||
197 | + [(return) | ||
198 | + (clobber (match_operand:P 1 "register_operand" "=l")) | ||
199 | + (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
200 | + (use (reg:P 12)) | ||
201 | + (set (match_operand:P 3 "gpc_reg_operand" "=r") | ||
202 | + (match_operand:P 4 "memory_operand" "m"))])] | ||
203 | + "" | ||
204 | + "b %2" | ||
205 | + [(set_attr "type" "branch") | ||
206 | + (set_attr "length" "4")]) | ||
207 | + | ||
208 | +(define_insn "*return_and_restore_gpregs_<mode>_r1" | ||
209 | [(match_parallel 0 "any_parallel_operand" | ||
210 | [(return) | ||
211 | (clobber (match_operand:P 1 "register_operand" "=l")) | ||
212 | (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
213 | - (use (match_operand:P 3 "gpc_reg_operand" "r")) | ||
214 | - (set (match_operand:P 4 "gpc_reg_operand" "=r") | ||
215 | - (match_operand:P 5 "memory_operand" "m"))])] | ||
216 | + (use (reg:P 1)) | ||
217 | + (set (match_operand:P 3 "gpc_reg_operand" "=r") | ||
218 | + (match_operand:P 4 "memory_operand" "m"))])] | ||
219 | "" | ||
220 | "b %2" | ||
221 | [(set_attr "type" "branch") | ||
222 | (set_attr "length" "4")]) | ||
223 | |||
224 | -(define_insn "*return_and_restore_fpregs_<mode>" | ||
225 | +(define_insn "*return_and_restore_fpregs_<mode>_r11" | ||
226 | [(match_parallel 0 "any_parallel_operand" | ||
227 | [(return) | ||
228 | (clobber (match_operand:P 1 "register_operand" "=l")) | ||
229 | (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
230 | - (use (match_operand:P 3 "gpc_reg_operand" "r")) | ||
231 | - (set (match_operand:DF 4 "gpc_reg_operand" "=d") | ||
232 | - (match_operand:DF 5 "memory_operand" "m"))])] | ||
233 | + (use (reg:P 11)) | ||
234 | + (set (match_operand:DF 3 "gpc_reg_operand" "=d") | ||
235 | + (match_operand:DF 4 "memory_operand" "m"))])] | ||
236 | + "" | ||
237 | + "b %2" | ||
238 | + [(set_attr "type" "branch") | ||
239 | + (set_attr "length" "4")]) | ||
240 | + | ||
241 | +(define_insn "*return_and_restore_fpregs_<mode>_r12" | ||
242 | + [(match_parallel 0 "any_parallel_operand" | ||
243 | + [(return) | ||
244 | + (clobber (match_operand:P 1 "register_operand" "=l")) | ||
245 | + (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
246 | + (use (reg:P 12)) | ||
247 | + (set (match_operand:DF 3 "gpc_reg_operand" "=d") | ||
248 | + (match_operand:DF 4 "memory_operand" "m"))])] | ||
249 | + "" | ||
250 | + "b %2" | ||
251 | + [(set_attr "type" "branch") | ||
252 | + (set_attr "length" "4")]) | ||
253 | + | ||
254 | +(define_insn "*return_and_restore_fpregs_<mode>_r1" | ||
255 | + [(match_parallel 0 "any_parallel_operand" | ||
256 | + [(return) | ||
257 | + (clobber (match_operand:P 1 "register_operand" "=l")) | ||
258 | + (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
259 | + (use (reg:P 1)) | ||
260 | + (set (match_operand:DF 3 "gpc_reg_operand" "=d") | ||
261 | + (match_operand:DF 4 "memory_operand" "m"))])] | ||
262 | + "" | ||
263 | + "b %2" | ||
264 | + [(set_attr "type" "branch") | ||
265 | + (set_attr "length" "4")]) | ||
266 | + | ||
267 | +(define_insn "*return_and_restore_fpregs_aix_<mode>_r11" | ||
268 | + [(match_parallel 0 "any_parallel_operand" | ||
269 | + [(return) | ||
270 | + (use (match_operand:P 1 "register_operand" "l")) | ||
271 | + (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
272 | + (use (reg:P 11)) | ||
273 | + (set (match_operand:DF 3 "gpc_reg_operand" "=d") | ||
274 | + (match_operand:DF 4 "memory_operand" "m"))])] | ||
275 | "" | ||
276 | "b %2" | ||
277 | [(set_attr "type" "branch") | ||
278 | (set_attr "length" "4")]) | ||
279 | |||
280 | -(define_insn "*return_and_restore_fpregs_aix_<mode>" | ||
281 | +(define_insn "*return_and_restore_fpregs_aix_<mode>_r1" | ||
282 | [(match_parallel 0 "any_parallel_operand" | ||
283 | [(return) | ||
284 | (use (match_operand:P 1 "register_operand" "l")) | ||
285 | (use (match_operand:P 2 "symbol_ref_operand" "s")) | ||
286 | - (use (match_operand:P 3 "gpc_reg_operand" "r")) | ||
287 | - (set (match_operand:DF 4 "gpc_reg_operand" "=d") | ||
288 | - (match_operand:DF 5 "memory_operand" "m"))])] | ||
289 | + (use (reg:P 1)) | ||
290 | + (set (match_operand:DF 3 "gpc_reg_operand" "=d") | ||
291 | + (match_operand:DF 4 "memory_operand" "m"))])] | ||
292 | "" | ||
293 | "b %2" | ||
294 | [(set_attr "type" "branch") | ||
295 | Index: gcc-4.5.1/gcc/testsuite/gcc.target/powerpc/outofline_rnreg.c | ||
296 | =================================================================== | ||
297 | --- /dev/null | ||
298 | +++ gcc-4.5.1/gcc/testsuite/gcc.target/powerpc/outofline_rnreg.c | ||
299 | @@ -0,0 +1,15 @@ | ||
300 | +/* Test that registers used by out of line restore functions does not get renamed. | ||
301 | + AIX, and 64 bit targets uses r1, which rnreg stays away from. | ||
302 | + Linux 32 bits targets uses r11, which is susceptible to be renamed */ | ||
303 | +/* { dg-do compile } */ | ||
304 | +/* { dg-require-effective-target ilp32 } */ | ||
305 | +/* { dg-options "-Os -frename-registers -fdump-rtl-rnreg" } */ | ||
306 | +/* "* renamed" or "* no available better choice" results are not acceptable */ | ||
307 | +/* { dg-final { scan-rtl-dump-not "Register 11 in insn *" "rnreg" { target powerpc*-*-linux* } } } */ | ||
308 | +/* { dg-final { cleanup-rtl-dump "rnreg" } } */ | ||
309 | +int | ||
310 | +calc (int j) | ||
311 | +{ | ||
312 | + if (j<=1) return 1; | ||
313 | + return calc(j-1)*(j+1); | ||
314 | +} | ||