diff options
Diffstat (limited to 'toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106807.patch')
-rw-r--r-- | toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106807.patch | 767 |
1 files changed, 767 insertions, 0 deletions
diff --git a/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106807.patch b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106807.patch new file mode 100644 index 0000000000..9474030f57 --- /dev/null +++ b/toolchain-layer/recipes-devtools/gcc/gcc-4.6/linaro/gcc-4.6-linaro-r106807.patch | |||
@@ -0,0 +1,767 @@ | |||
1 | 2011-08-26 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> | ||
2 | |||
3 | Backport from FSF mainline: | ||
4 | 2011-04-06 Wei Guozhi <carrot@google.com> | ||
5 | |||
6 | PR target/47855 | ||
7 | gcc/ | ||
8 | * config/arm/arm.md (arm_cmpsi_insn): Compute attr "length". | ||
9 | (arm_cond_branch): Likewise. | ||
10 | (arm_cond_branch_reversed): Likewise. | ||
11 | (arm_jump): Likewise. | ||
12 | (push_multi): Likewise. | ||
13 | * config/arm/constraints.md (Py): New constraint. | ||
14 | |||
15 | 2011-04-08 Wei Guozhi <carrot@google.com> | ||
16 | |||
17 | PR target/47855 | ||
18 | * config/arm/arm-protos.h (arm_attr_length_push_multi): New prototype. | ||
19 | * config/arm/arm.c (arm_attr_length_push_multi): New function. | ||
20 | * config/arm/arm.md (*push_multi): Change the length computation to | ||
21 | call a C function. | ||
22 | |||
23 | 2011-08-26 Ramana Radhakrishnan <ramana.radhakrishnan@linaro.org> | ||
24 | |||
25 | Backport from FSF mainline: | ||
26 | |||
27 | 2011-08-18 Jiangning Liu <jiangning.liu@arm.com> | ||
28 | |||
29 | gcc/ | ||
30 | * config/arm/arm.md (*ior_scc_scc): Enable for Thumb2 as well. | ||
31 | (*ior_scc_scc_cmp): Likewise | ||
32 | (*and_scc_scc): Likewise. | ||
33 | (*and_scc_scc_cmp): Likewise. | ||
34 | (*and_scc_scc_nodom): Likewise. | ||
35 | (*cmp_ite0, *cmp_ite1, *cmp_and, *cmp_ior): Handle Thumb2. | ||
36 | |||
37 | gcc/testsuite | ||
38 | * gcc.target/arm/thumb2-cond-cmp-1.c: New. Make sure conditional | ||
39 | compare can be generated. | ||
40 | * gcc.target/arm/thumb2-cond-cmp-2.c: Likewise. | ||
41 | * gcc.target/arm/thumb2-cond-cmp-3.c: Likewise. | ||
42 | * gcc.target/arm/thumb2-cond-cmp-4.c: Likewise. | ||
43 | |||
44 | === modified file 'gcc/config/arm/arm-protos.h' | ||
45 | --- old/gcc/config/arm/arm-protos.h 2011-09-12 11:03:11 +0000 | ||
46 | +++ new/gcc/config/arm/arm-protos.h 2011-09-12 14:14:00 +0000 | ||
47 | @@ -156,6 +156,7 @@ | ||
48 | extern const char *arm_output_memory_barrier (rtx *); | ||
49 | extern const char *arm_output_sync_insn (rtx, rtx *); | ||
50 | extern unsigned int arm_sync_loop_insns (rtx , rtx *); | ||
51 | +extern int arm_attr_length_push_multi(rtx, rtx); | ||
52 | |||
53 | #if defined TREE_CODE | ||
54 | extern void arm_init_cumulative_args (CUMULATIVE_ARGS *, tree, rtx, tree); | ||
55 | |||
56 | === modified file 'gcc/config/arm/arm.c' | ||
57 | --- old/gcc/config/arm/arm.c 2011-09-12 11:03:11 +0000 | ||
58 | +++ new/gcc/config/arm/arm.c 2011-09-12 14:14:00 +0000 | ||
59 | @@ -24391,4 +24391,30 @@ | ||
60 | return NO_REGS; | ||
61 | } | ||
62 | |||
63 | +/* Compute the atrribute "length" of insn "*push_multi". | ||
64 | + So this function MUST be kept in sync with that insn pattern. */ | ||
65 | +int | ||
66 | +arm_attr_length_push_multi(rtx parallel_op, rtx first_op) | ||
67 | +{ | ||
68 | + int i, regno, hi_reg; | ||
69 | + int num_saves = XVECLEN (parallel_op, 0); | ||
70 | + | ||
71 | + /* ARM mode. */ | ||
72 | + if (TARGET_ARM) | ||
73 | + return 4; | ||
74 | + | ||
75 | + /* Thumb2 mode. */ | ||
76 | + regno = REGNO (first_op); | ||
77 | + hi_reg = (REGNO_REG_CLASS (regno) == HI_REGS) && (regno != LR_REGNUM); | ||
78 | + for (i = 1; i < num_saves && !hi_reg; i++) | ||
79 | + { | ||
80 | + regno = REGNO (XEXP (XVECEXP (parallel_op, 0, i), 0)); | ||
81 | + hi_reg |= (REGNO_REG_CLASS (regno) == HI_REGS) && (regno != LR_REGNUM); | ||
82 | + } | ||
83 | + | ||
84 | + if (!hi_reg) | ||
85 | + return 2; | ||
86 | + return 4; | ||
87 | +} | ||
88 | + | ||
89 | #include "gt-arm.h" | ||
90 | |||
91 | === modified file 'gcc/config/arm/arm.md' | ||
92 | --- old/gcc/config/arm/arm.md 2011-09-12 12:32:29 +0000 | ||
93 | +++ new/gcc/config/arm/arm.md 2011-09-12 14:14:00 +0000 | ||
94 | @@ -48,6 +48,15 @@ | ||
95 | (DOM_CC_X_OR_Y 2) | ||
96 | ] | ||
97 | ) | ||
98 | +;; conditional compare combination | ||
99 | +(define_constants | ||
100 | + [(CMP_CMP 0) | ||
101 | + (CMN_CMP 1) | ||
102 | + (CMP_CMN 2) | ||
103 | + (CMN_CMN 3) | ||
104 | + (NUM_OF_COND_CMP 4) | ||
105 | + ] | ||
106 | +) | ||
107 | |||
108 | ;; UNSPEC Usage: | ||
109 | ;; Note: sin and cos are no-longer used. | ||
110 | @@ -7198,13 +7207,17 @@ | ||
111 | |||
112 | (define_insn "*arm_cmpsi_insn" | ||
113 | [(set (reg:CC CC_REGNUM) | ||
114 | - (compare:CC (match_operand:SI 0 "s_register_operand" "r,r") | ||
115 | - (match_operand:SI 1 "arm_add_operand" "rI,L")))] | ||
116 | + (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r") | ||
117 | + (match_operand:SI 1 "arm_add_operand" "Py,r,rI,L")))] | ||
118 | "TARGET_32BIT" | ||
119 | "@ | ||
120 | cmp%?\\t%0, %1 | ||
121 | + cmp%?\\t%0, %1 | ||
122 | + cmp%?\\t%0, %1 | ||
123 | cmn%?\\t%0, #%n1" | ||
124 | - [(set_attr "conds" "set")] | ||
125 | + [(set_attr "conds" "set") | ||
126 | + (set_attr "arch" "t2,t2,any,any") | ||
127 | + (set_attr "length" "2,2,4,4")] | ||
128 | ) | ||
129 | |||
130 | (define_insn "*cmpsi_shiftsi" | ||
131 | @@ -7375,7 +7388,14 @@ | ||
132 | return \"b%d1\\t%l0\"; | ||
133 | " | ||
134 | [(set_attr "conds" "use") | ||
135 | - (set_attr "type" "branch")] | ||
136 | + (set_attr "type" "branch") | ||
137 | + (set (attr "length") | ||
138 | + (if_then_else | ||
139 | + (and (ne (symbol_ref "TARGET_THUMB2") (const_int 0)) | ||
140 | + (and (ge (minus (match_dup 0) (pc)) (const_int -250)) | ||
141 | + (le (minus (match_dup 0) (pc)) (const_int 256)))) | ||
142 | + (const_int 2) | ||
143 | + (const_int 4)))] | ||
144 | ) | ||
145 | |||
146 | (define_insn "*arm_cond_branch_reversed" | ||
147 | @@ -7394,7 +7414,14 @@ | ||
148 | return \"b%D1\\t%l0\"; | ||
149 | " | ||
150 | [(set_attr "conds" "use") | ||
151 | - (set_attr "type" "branch")] | ||
152 | + (set_attr "type" "branch") | ||
153 | + (set (attr "length") | ||
154 | + (if_then_else | ||
155 | + (and (ne (symbol_ref "TARGET_THUMB2") (const_int 0)) | ||
156 | + (and (ge (minus (match_dup 0) (pc)) (const_int -250)) | ||
157 | + (le (minus (match_dup 0) (pc)) (const_int 256)))) | ||
158 | + (const_int 2) | ||
159 | + (const_int 4)))] | ||
160 | ) | ||
161 | |||
162 | |||
163 | @@ -7846,7 +7873,14 @@ | ||
164 | return \"b%?\\t%l0\"; | ||
165 | } | ||
166 | " | ||
167 | - [(set_attr "predicable" "yes")] | ||
168 | + [(set_attr "predicable" "yes") | ||
169 | + (set (attr "length") | ||
170 | + (if_then_else | ||
171 | + (and (ne (symbol_ref "TARGET_THUMB2") (const_int 0)) | ||
172 | + (and (ge (minus (match_dup 0) (pc)) (const_int -2044)) | ||
173 | + (le (minus (match_dup 0) (pc)) (const_int 2048)))) | ||
174 | + (const_int 2) | ||
175 | + (const_int 4)))] | ||
176 | ) | ||
177 | |||
178 | (define_insn "*thumb_jump" | ||
179 | @@ -8931,40 +8965,85 @@ | ||
180 | (set_attr "length" "8,12")] | ||
181 | ) | ||
182 | |||
183 | -;; ??? Is it worth using these conditional patterns in Thumb-2 mode? | ||
184 | (define_insn "*cmp_ite0" | ||
185 | [(set (match_operand 6 "dominant_cc_register" "") | ||
186 | (compare | ||
187 | (if_then_else:SI | ||
188 | (match_operator 4 "arm_comparison_operator" | ||
189 | - [(match_operand:SI 0 "s_register_operand" "r,r,r,r") | ||
190 | - (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) | ||
191 | + [(match_operand:SI 0 "s_register_operand" | ||
192 | + "l,l,l,r,r,r,r,r,r") | ||
193 | + (match_operand:SI 1 "arm_add_operand" | ||
194 | + "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) | ||
195 | (match_operator:SI 5 "arm_comparison_operator" | ||
196 | - [(match_operand:SI 2 "s_register_operand" "r,r,r,r") | ||
197 | - (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]) | ||
198 | + [(match_operand:SI 2 "s_register_operand" | ||
199 | + "l,r,r,l,l,r,r,r,r") | ||
200 | + (match_operand:SI 3 "arm_add_operand" | ||
201 | + "lPy,rI,L,lPy,lPy,rI,rI,L,L")]) | ||
202 | (const_int 0)) | ||
203 | (const_int 0)))] | ||
204 | - "TARGET_ARM" | ||
205 | + "TARGET_32BIT" | ||
206 | "* | ||
207 | { | ||
208 | - static const char * const opcodes[4][2] = | ||
209 | - { | ||
210 | - {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\", | ||
211 | - \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"}, | ||
212 | - {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", | ||
213 | - \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"}, | ||
214 | - {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", | ||
215 | - \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"}, | ||
216 | - {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\", | ||
217 | - \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"} | ||
218 | - }; | ||
219 | + static const char * const cmp1[NUM_OF_COND_CMP][2] = | ||
220 | + { | ||
221 | + {\"cmp%d5\\t%0, %1\", | ||
222 | + \"cmp%d4\\t%2, %3\"}, | ||
223 | + {\"cmn%d5\\t%0, #%n1\", | ||
224 | + \"cmp%d4\\t%2, %3\"}, | ||
225 | + {\"cmp%d5\\t%0, %1\", | ||
226 | + \"cmn%d4\\t%2, #%n3\"}, | ||
227 | + {\"cmn%d5\\t%0, #%n1\", | ||
228 | + \"cmn%d4\\t%2, #%n3\"} | ||
229 | + }; | ||
230 | + static const char * const cmp2[NUM_OF_COND_CMP][2] = | ||
231 | + { | ||
232 | + {\"cmp\\t%2, %3\", | ||
233 | + \"cmp\\t%0, %1\"}, | ||
234 | + {\"cmp\\t%2, %3\", | ||
235 | + \"cmn\\t%0, #%n1\"}, | ||
236 | + {\"cmn\\t%2, #%n3\", | ||
237 | + \"cmp\\t%0, %1\"}, | ||
238 | + {\"cmn\\t%2, #%n3\", | ||
239 | + \"cmn\\t%0, #%n1\"} | ||
240 | + }; | ||
241 | + static const char * const ite[2] = | ||
242 | + { | ||
243 | + \"it\\t%d5\", | ||
244 | + \"it\\t%d4\" | ||
245 | + }; | ||
246 | + static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, | ||
247 | + CMP_CMP, CMN_CMP, CMP_CMP, | ||
248 | + CMN_CMP, CMP_CMN, CMN_CMN}; | ||
249 | int swap = | ||
250 | comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); | ||
251 | |||
252 | - return opcodes[which_alternative][swap]; | ||
253 | + output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); | ||
254 | + if (TARGET_THUMB2) { | ||
255 | + output_asm_insn (ite[swap], operands); | ||
256 | + } | ||
257 | + output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); | ||
258 | + return \"\"; | ||
259 | }" | ||
260 | [(set_attr "conds" "set") | ||
261 | - (set_attr "length" "8")] | ||
262 | + (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") | ||
263 | + (set_attr_alternative "length" | ||
264 | + [(const_int 6) | ||
265 | + (const_int 8) | ||
266 | + (const_int 8) | ||
267 | + (const_int 8) | ||
268 | + (const_int 8) | ||
269 | + (if_then_else (eq_attr "is_thumb" "no") | ||
270 | + (const_int 8) | ||
271 | + (const_int 10)) | ||
272 | + (if_then_else (eq_attr "is_thumb" "no") | ||
273 | + (const_int 8) | ||
274 | + (const_int 10)) | ||
275 | + (if_then_else (eq_attr "is_thumb" "no") | ||
276 | + (const_int 8) | ||
277 | + (const_int 10)) | ||
278 | + (if_then_else (eq_attr "is_thumb" "no") | ||
279 | + (const_int 8) | ||
280 | + (const_int 10))])] | ||
281 | ) | ||
282 | |||
283 | (define_insn "*cmp_ite1" | ||
284 | @@ -8972,35 +9051,81 @@ | ||
285 | (compare | ||
286 | (if_then_else:SI | ||
287 | (match_operator 4 "arm_comparison_operator" | ||
288 | - [(match_operand:SI 0 "s_register_operand" "r,r,r,r") | ||
289 | - (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) | ||
290 | + [(match_operand:SI 0 "s_register_operand" | ||
291 | + "l,l,l,r,r,r,r,r,r") | ||
292 | + (match_operand:SI 1 "arm_add_operand" | ||
293 | + "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) | ||
294 | (match_operator:SI 5 "arm_comparison_operator" | ||
295 | - [(match_operand:SI 2 "s_register_operand" "r,r,r,r") | ||
296 | - (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]) | ||
297 | + [(match_operand:SI 2 "s_register_operand" | ||
298 | + "l,r,r,l,l,r,r,r,r") | ||
299 | + (match_operand:SI 3 "arm_add_operand" | ||
300 | + "lPy,rI,L,lPy,lPy,rI,rI,L,L")]) | ||
301 | (const_int 1)) | ||
302 | (const_int 0)))] | ||
303 | - "TARGET_ARM" | ||
304 | + "TARGET_32BIT" | ||
305 | "* | ||
306 | { | ||
307 | - static const char * const opcodes[4][2] = | ||
308 | - { | ||
309 | - {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\", | ||
310 | - \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"}, | ||
311 | - {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\", | ||
312 | - \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"}, | ||
313 | - {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\", | ||
314 | - \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"}, | ||
315 | - {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\", | ||
316 | - \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"} | ||
317 | - }; | ||
318 | + static const char * const cmp1[NUM_OF_COND_CMP][2] = | ||
319 | + { | ||
320 | + {\"cmp\\t%0, %1\", | ||
321 | + \"cmp\\t%2, %3\"}, | ||
322 | + {\"cmn\\t%0, #%n1\", | ||
323 | + \"cmp\\t%2, %3\"}, | ||
324 | + {\"cmp\\t%0, %1\", | ||
325 | + \"cmn\\t%2, #%n3\"}, | ||
326 | + {\"cmn\\t%0, #%n1\", | ||
327 | + \"cmn\\t%2, #%n3\"} | ||
328 | + }; | ||
329 | + static const char * const cmp2[NUM_OF_COND_CMP][2] = | ||
330 | + { | ||
331 | + {\"cmp%d4\\t%2, %3\", | ||
332 | + \"cmp%D5\\t%0, %1\"}, | ||
333 | + {\"cmp%d4\\t%2, %3\", | ||
334 | + \"cmn%D5\\t%0, #%n1\"}, | ||
335 | + {\"cmn%d4\\t%2, #%n3\", | ||
336 | + \"cmp%D5\\t%0, %1\"}, | ||
337 | + {\"cmn%d4\\t%2, #%n3\", | ||
338 | + \"cmn%D5\\t%0, #%n1\"} | ||
339 | + }; | ||
340 | + static const char * const ite[2] = | ||
341 | + { | ||
342 | + \"it\\t%d4\", | ||
343 | + \"it\\t%D5\" | ||
344 | + }; | ||
345 | + static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, | ||
346 | + CMP_CMP, CMN_CMP, CMP_CMP, | ||
347 | + CMN_CMP, CMP_CMN, CMN_CMN}; | ||
348 | int swap = | ||
349 | comparison_dominates_p (GET_CODE (operands[5]), | ||
350 | reverse_condition (GET_CODE (operands[4]))); | ||
351 | |||
352 | - return opcodes[which_alternative][swap]; | ||
353 | + output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); | ||
354 | + if (TARGET_THUMB2) { | ||
355 | + output_asm_insn (ite[swap], operands); | ||
356 | + } | ||
357 | + output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); | ||
358 | + return \"\"; | ||
359 | }" | ||
360 | [(set_attr "conds" "set") | ||
361 | - (set_attr "length" "8")] | ||
362 | + (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") | ||
363 | + (set_attr_alternative "length" | ||
364 | + [(const_int 6) | ||
365 | + (const_int 8) | ||
366 | + (const_int 8) | ||
367 | + (const_int 8) | ||
368 | + (const_int 8) | ||
369 | + (if_then_else (eq_attr "is_thumb" "no") | ||
370 | + (const_int 8) | ||
371 | + (const_int 10)) | ||
372 | + (if_then_else (eq_attr "is_thumb" "no") | ||
373 | + (const_int 8) | ||
374 | + (const_int 10)) | ||
375 | + (if_then_else (eq_attr "is_thumb" "no") | ||
376 | + (const_int 8) | ||
377 | + (const_int 10)) | ||
378 | + (if_then_else (eq_attr "is_thumb" "no") | ||
379 | + (const_int 8) | ||
380 | + (const_int 10))])] | ||
381 | ) | ||
382 | |||
383 | (define_insn "*cmp_and" | ||
384 | @@ -9008,34 +9133,80 @@ | ||
385 | (compare | ||
386 | (and:SI | ||
387 | (match_operator 4 "arm_comparison_operator" | ||
388 | - [(match_operand:SI 0 "s_register_operand" "r,r,r,r") | ||
389 | - (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) | ||
390 | + [(match_operand:SI 0 "s_register_operand" | ||
391 | + "l,l,l,r,r,r,r,r,r") | ||
392 | + (match_operand:SI 1 "arm_add_operand" | ||
393 | + "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) | ||
394 | (match_operator:SI 5 "arm_comparison_operator" | ||
395 | - [(match_operand:SI 2 "s_register_operand" "r,r,r,r") | ||
396 | - (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])) | ||
397 | + [(match_operand:SI 2 "s_register_operand" | ||
398 | + "l,r,r,l,l,r,r,r,r") | ||
399 | + (match_operand:SI 3 "arm_add_operand" | ||
400 | + "lPy,rI,L,lPy,lPy,rI,rI,L,L")])) | ||
401 | (const_int 0)))] | ||
402 | - "TARGET_ARM" | ||
403 | + "TARGET_32BIT" | ||
404 | "* | ||
405 | { | ||
406 | - static const char *const opcodes[4][2] = | ||
407 | - { | ||
408 | - {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\", | ||
409 | - \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"}, | ||
410 | - {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", | ||
411 | - \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"}, | ||
412 | - {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", | ||
413 | - \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"}, | ||
414 | - {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\", | ||
415 | - \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"} | ||
416 | - }; | ||
417 | + static const char *const cmp1[NUM_OF_COND_CMP][2] = | ||
418 | + { | ||
419 | + {\"cmp%d5\\t%0, %1\", | ||
420 | + \"cmp%d4\\t%2, %3\"}, | ||
421 | + {\"cmn%d5\\t%0, #%n1\", | ||
422 | + \"cmp%d4\\t%2, %3\"}, | ||
423 | + {\"cmp%d5\\t%0, %1\", | ||
424 | + \"cmn%d4\\t%2, #%n3\"}, | ||
425 | + {\"cmn%d5\\t%0, #%n1\", | ||
426 | + \"cmn%d4\\t%2, #%n3\"} | ||
427 | + }; | ||
428 | + static const char *const cmp2[NUM_OF_COND_CMP][2] = | ||
429 | + { | ||
430 | + {\"cmp\\t%2, %3\", | ||
431 | + \"cmp\\t%0, %1\"}, | ||
432 | + {\"cmp\\t%2, %3\", | ||
433 | + \"cmn\\t%0, #%n1\"}, | ||
434 | + {\"cmn\\t%2, #%n3\", | ||
435 | + \"cmp\\t%0, %1\"}, | ||
436 | + {\"cmn\\t%2, #%n3\", | ||
437 | + \"cmn\\t%0, #%n1\"} | ||
438 | + }; | ||
439 | + static const char *const ite[2] = | ||
440 | + { | ||
441 | + \"it\\t%d5\", | ||
442 | + \"it\\t%d4\" | ||
443 | + }; | ||
444 | + static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, | ||
445 | + CMP_CMP, CMN_CMP, CMP_CMP, | ||
446 | + CMN_CMP, CMP_CMN, CMN_CMN}; | ||
447 | int swap = | ||
448 | comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); | ||
449 | |||
450 | - return opcodes[which_alternative][swap]; | ||
451 | + output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); | ||
452 | + if (TARGET_THUMB2) { | ||
453 | + output_asm_insn (ite[swap], operands); | ||
454 | + } | ||
455 | + output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); | ||
456 | + return \"\"; | ||
457 | }" | ||
458 | [(set_attr "conds" "set") | ||
459 | (set_attr "predicable" "no") | ||
460 | - (set_attr "length" "8")] | ||
461 | + (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") | ||
462 | + (set_attr_alternative "length" | ||
463 | + [(const_int 6) | ||
464 | + (const_int 8) | ||
465 | + (const_int 8) | ||
466 | + (const_int 8) | ||
467 | + (const_int 8) | ||
468 | + (if_then_else (eq_attr "is_thumb" "no") | ||
469 | + (const_int 8) | ||
470 | + (const_int 10)) | ||
471 | + (if_then_else (eq_attr "is_thumb" "no") | ||
472 | + (const_int 8) | ||
473 | + (const_int 10)) | ||
474 | + (if_then_else (eq_attr "is_thumb" "no") | ||
475 | + (const_int 8) | ||
476 | + (const_int 10)) | ||
477 | + (if_then_else (eq_attr "is_thumb" "no") | ||
478 | + (const_int 8) | ||
479 | + (const_int 10))])] | ||
480 | ) | ||
481 | |||
482 | (define_insn "*cmp_ior" | ||
483 | @@ -9043,34 +9214,80 @@ | ||
484 | (compare | ||
485 | (ior:SI | ||
486 | (match_operator 4 "arm_comparison_operator" | ||
487 | - [(match_operand:SI 0 "s_register_operand" "r,r,r,r") | ||
488 | - (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) | ||
489 | + [(match_operand:SI 0 "s_register_operand" | ||
490 | + "l,l,l,r,r,r,r,r,r") | ||
491 | + (match_operand:SI 1 "arm_add_operand" | ||
492 | + "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) | ||
493 | (match_operator:SI 5 "arm_comparison_operator" | ||
494 | - [(match_operand:SI 2 "s_register_operand" "r,r,r,r") | ||
495 | - (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])) | ||
496 | + [(match_operand:SI 2 "s_register_operand" | ||
497 | + "l,r,r,l,l,r,r,r,r") | ||
498 | + (match_operand:SI 3 "arm_add_operand" | ||
499 | + "lPy,rI,L,lPy,lPy,rI,rI,L,L")])) | ||
500 | (const_int 0)))] | ||
501 | - "TARGET_ARM" | ||
502 | + "TARGET_32BIT" | ||
503 | "* | ||
504 | -{ | ||
505 | - static const char *const opcodes[4][2] = | ||
506 | { | ||
507 | - {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\", | ||
508 | - \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"}, | ||
509 | - {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\", | ||
510 | - \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"}, | ||
511 | - {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\", | ||
512 | - \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"}, | ||
513 | - {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\", | ||
514 | - \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"} | ||
515 | - }; | ||
516 | - int swap = | ||
517 | - comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); | ||
518 | + static const char *const cmp1[NUM_OF_COND_CMP][2] = | ||
519 | + { | ||
520 | + {\"cmp\\t%0, %1\", | ||
521 | + \"cmp\\t%2, %3\"}, | ||
522 | + {\"cmn\\t%0, #%n1\", | ||
523 | + \"cmp\\t%2, %3\"}, | ||
524 | + {\"cmp\\t%0, %1\", | ||
525 | + \"cmn\\t%2, #%n3\"}, | ||
526 | + {\"cmn\\t%0, #%n1\", | ||
527 | + \"cmn\\t%2, #%n3\"} | ||
528 | + }; | ||
529 | + static const char *const cmp2[NUM_OF_COND_CMP][2] = | ||
530 | + { | ||
531 | + {\"cmp%D4\\t%2, %3\", | ||
532 | + \"cmp%D5\\t%0, %1\"}, | ||
533 | + {\"cmp%D4\\t%2, %3\", | ||
534 | + \"cmn%D5\\t%0, #%n1\"}, | ||
535 | + {\"cmn%D4\\t%2, #%n3\", | ||
536 | + \"cmp%D5\\t%0, %1\"}, | ||
537 | + {\"cmn%D4\\t%2, #%n3\", | ||
538 | + \"cmn%D5\\t%0, #%n1\"} | ||
539 | + }; | ||
540 | + static const char *const ite[2] = | ||
541 | + { | ||
542 | + \"it\\t%D4\", | ||
543 | + \"it\\t%D5\" | ||
544 | + }; | ||
545 | + static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, | ||
546 | + CMP_CMP, CMN_CMP, CMP_CMP, | ||
547 | + CMN_CMP, CMP_CMN, CMN_CMN}; | ||
548 | + int swap = | ||
549 | + comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); | ||
550 | |||
551 | - return opcodes[which_alternative][swap]; | ||
552 | -} | ||
553 | -" | ||
554 | + output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); | ||
555 | + if (TARGET_THUMB2) { | ||
556 | + output_asm_insn (ite[swap], operands); | ||
557 | + } | ||
558 | + output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); | ||
559 | + return \"\"; | ||
560 | + } | ||
561 | + " | ||
562 | [(set_attr "conds" "set") | ||
563 | - (set_attr "length" "8")] | ||
564 | + (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") | ||
565 | + (set_attr_alternative "length" | ||
566 | + [(const_int 6) | ||
567 | + (const_int 8) | ||
568 | + (const_int 8) | ||
569 | + (const_int 8) | ||
570 | + (const_int 8) | ||
571 | + (if_then_else (eq_attr "is_thumb" "no") | ||
572 | + (const_int 8) | ||
573 | + (const_int 10)) | ||
574 | + (if_then_else (eq_attr "is_thumb" "no") | ||
575 | + (const_int 8) | ||
576 | + (const_int 10)) | ||
577 | + (if_then_else (eq_attr "is_thumb" "no") | ||
578 | + (const_int 8) | ||
579 | + (const_int 10)) | ||
580 | + (if_then_else (eq_attr "is_thumb" "no") | ||
581 | + (const_int 8) | ||
582 | + (const_int 10))])] | ||
583 | ) | ||
584 | |||
585 | (define_insn_and_split "*ior_scc_scc" | ||
586 | @@ -9082,11 +9299,11 @@ | ||
587 | [(match_operand:SI 4 "s_register_operand" "r") | ||
588 | (match_operand:SI 5 "arm_add_operand" "rIL")]))) | ||
589 | (clobber (reg:CC CC_REGNUM))] | ||
590 | - "TARGET_ARM | ||
591 | + "TARGET_32BIT | ||
592 | && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y) | ||
593 | != CCmode)" | ||
594 | "#" | ||
595 | - "TARGET_ARM && reload_completed" | ||
596 | + "TARGET_32BIT && reload_completed" | ||
597 | [(set (match_dup 7) | ||
598 | (compare | ||
599 | (ior:SI | ||
600 | @@ -9115,9 +9332,9 @@ | ||
601 | (set (match_operand:SI 7 "s_register_operand" "=r") | ||
602 | (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) | ||
603 | (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] | ||
604 | - "TARGET_ARM" | ||
605 | + "TARGET_32BIT" | ||
606 | "#" | ||
607 | - "TARGET_ARM && reload_completed" | ||
608 | + "TARGET_32BIT && reload_completed" | ||
609 | [(set (match_dup 0) | ||
610 | (compare | ||
611 | (ior:SI | ||
612 | @@ -9138,11 +9355,11 @@ | ||
613 | [(match_operand:SI 4 "s_register_operand" "r") | ||
614 | (match_operand:SI 5 "arm_add_operand" "rIL")]))) | ||
615 | (clobber (reg:CC CC_REGNUM))] | ||
616 | - "TARGET_ARM | ||
617 | + "TARGET_32BIT | ||
618 | && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) | ||
619 | != CCmode)" | ||
620 | "#" | ||
621 | - "TARGET_ARM && reload_completed | ||
622 | + "TARGET_32BIT && reload_completed | ||
623 | && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) | ||
624 | != CCmode)" | ||
625 | [(set (match_dup 7) | ||
626 | @@ -9173,9 +9390,9 @@ | ||
627 | (set (match_operand:SI 7 "s_register_operand" "=r") | ||
628 | (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) | ||
629 | (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] | ||
630 | - "TARGET_ARM" | ||
631 | + "TARGET_32BIT" | ||
632 | "#" | ||
633 | - "TARGET_ARM && reload_completed" | ||
634 | + "TARGET_32BIT && reload_completed" | ||
635 | [(set (match_dup 0) | ||
636 | (compare | ||
637 | (and:SI | ||
638 | @@ -9200,11 +9417,11 @@ | ||
639 | [(match_operand:SI 4 "s_register_operand" "r,r,r") | ||
640 | (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")]))) | ||
641 | (clobber (reg:CC CC_REGNUM))] | ||
642 | - "TARGET_ARM | ||
643 | + "TARGET_32BIT | ||
644 | && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) | ||
645 | == CCmode)" | ||
646 | "#" | ||
647 | - "TARGET_ARM && reload_completed" | ||
648 | + "TARGET_32BIT && reload_completed" | ||
649 | [(parallel [(set (match_dup 0) | ||
650 | (match_op_dup 3 [(match_dup 1) (match_dup 2)])) | ||
651 | (clobber (reg:CC CC_REGNUM))]) | ||
652 | @@ -10314,6 +10531,8 @@ | ||
653 | ;; Push multiple registers to the stack. Registers are in parallel (use ...) | ||
654 | ;; expressions. For simplicity, the first register is also in the unspec | ||
655 | ;; part. | ||
656 | +;; To avoid the usage of GNU extension, the length attribute is computed | ||
657 | +;; in a C function arm_attr_length_push_multi. | ||
658 | (define_insn "*push_multi" | ||
659 | [(match_parallel 2 "multi_register_push" | ||
660 | [(set (match_operand:BLK 0 "memory_operand" "=m") | ||
661 | @@ -10353,7 +10572,9 @@ | ||
662 | |||
663 | return \"\"; | ||
664 | }" | ||
665 | - [(set_attr "type" "store4")] | ||
666 | + [(set_attr "type" "store4") | ||
667 | + (set (attr "length") | ||
668 | + (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))] | ||
669 | ) | ||
670 | |||
671 | (define_insn "stack_tie" | ||
672 | |||
673 | === modified file 'gcc/config/arm/constraints.md' | ||
674 | --- old/gcc/config/arm/constraints.md 2011-08-25 13:26:58 +0000 | ||
675 | +++ new/gcc/config/arm/constraints.md 2011-09-12 14:14:00 +0000 | ||
676 | @@ -31,7 +31,7 @@ | ||
677 | ;; The following multi-letter normal constraints have been used: | ||
678 | ;; in ARM/Thumb-2 state: Da, Db, Dc, Dn, Dl, DL, Dv, Dy, Di, Dz | ||
679 | ;; in Thumb-1 state: Pa, Pb, Pc, Pd | ||
680 | -;; in Thumb-2 state: Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px | ||
681 | +;; in Thumb-2 state: Pj, PJ, Ps, Pt, Pu, Pv, Pw, Px, Py | ||
682 | |||
683 | ;; The following memory constraints have been used: | ||
684 | ;; in ARM/Thumb-2 state: Q, Ut, Uv, Uy, Un, Um, Us | ||
685 | @@ -201,6 +201,11 @@ | ||
686 | (and (match_code "const_int") | ||
687 | (match_test "TARGET_THUMB2 && ival >= -7 && ival <= -1"))) | ||
688 | |||
689 | +(define_constraint "Py" | ||
690 | + "@internal In Thumb-2 state a constant in the range 0 to 255" | ||
691 | + (and (match_code "const_int") | ||
692 | + (match_test "TARGET_THUMB2 && ival >= 0 && ival <= 255"))) | ||
693 | + | ||
694 | (define_constraint "G" | ||
695 | "In ARM/Thumb-2 state a valid FPA immediate constant." | ||
696 | (and (match_code "const_double") | ||
697 | |||
698 | === added file 'gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-1.c' | ||
699 | --- old/gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-1.c 1970-01-01 00:00:00 +0000 | ||
700 | +++ new/gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-1.c 2011-09-12 14:14:00 +0000 | ||
701 | @@ -0,0 +1,13 @@ | ||
702 | +/* Use conditional compare */ | ||
703 | +/* { dg-options "-O2" } */ | ||
704 | +/* { dg-skip-if "" { arm_thumb1_ok } } */ | ||
705 | +/* { dg-final { scan-assembler "cmpne" } } */ | ||
706 | + | ||
707 | +int f(int i, int j) | ||
708 | +{ | ||
709 | + if ( (i == '+') || (j == '-') ) { | ||
710 | + return 1; | ||
711 | + } else { | ||
712 | + return 0; | ||
713 | + } | ||
714 | +} | ||
715 | |||
716 | === added file 'gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-2.c' | ||
717 | --- old/gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-2.c 1970-01-01 00:00:00 +0000 | ||
718 | +++ new/gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-2.c 2011-09-12 14:14:00 +0000 | ||
719 | @@ -0,0 +1,13 @@ | ||
720 | +/* Use conditional compare */ | ||
721 | +/* { dg-options "-O2" } */ | ||
722 | +/* { dg-skip-if "" { arm_thumb1_ok } } */ | ||
723 | +/* { dg-final { scan-assembler "cmpeq" } } */ | ||
724 | + | ||
725 | +int f(int i, int j) | ||
726 | +{ | ||
727 | + if ( (i == '+') && (j == '-') ) { | ||
728 | + return 1; | ||
729 | + } else { | ||
730 | + return 0; | ||
731 | + } | ||
732 | +} | ||
733 | |||
734 | === added file 'gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-3.c' | ||
735 | --- old/gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-3.c 1970-01-01 00:00:00 +0000 | ||
736 | +++ new/gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-3.c 2011-09-12 14:14:00 +0000 | ||
737 | @@ -0,0 +1,12 @@ | ||
738 | +/* Use conditional compare */ | ||
739 | +/* { dg-options "-O2" } */ | ||
740 | +/* { dg-skip-if "" { arm_thumb1_ok } } */ | ||
741 | +/* { dg-final { scan-assembler "cmpgt" } } */ | ||
742 | + | ||
743 | +int f(int i, int j) | ||
744 | +{ | ||
745 | + if ( (i >= '+') ? (j > '-') : 0) | ||
746 | + return 1; | ||
747 | + else | ||
748 | + return 0; | ||
749 | +} | ||
750 | |||
751 | === added file 'gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-4.c' | ||
752 | --- old/gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-4.c 1970-01-01 00:00:00 +0000 | ||
753 | +++ new/gcc/testsuite/gcc.target/arm/thumb2-cond-cmp-4.c 2011-09-12 14:14:00 +0000 | ||
754 | @@ -0,0 +1,12 @@ | ||
755 | +/* Use conditional compare */ | ||
756 | +/* { dg-options "-O2" } */ | ||
757 | +/* { dg-skip-if "" { arm_thumb1_ok } } */ | ||
758 | +/* { dg-final { scan-assembler "cmpgt" } } */ | ||
759 | + | ||
760 | +int f(int i, int j) | ||
761 | +{ | ||
762 | + if ( (i >= '+') ? (j <= '-') : 1) | ||
763 | + return 1; | ||
764 | + else | ||
765 | + return 0; | ||
766 | +} | ||
767 | |||