1 ;; ARM Thumb-2 Machine Description
2 ;; Copyright (C) 2007, 2008 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery, LLC.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify it
8 ;; under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful, but
13 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 ;; General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>. */
21 ;; Note: Thumb-2 is the variant of the Thumb architecture that adds
22 ;; 32-bit encodings of [almost all of] the Arm instruction set.
23 ;; Some old documents refer to the relatively minor interworking
24 ;; changes made in armv5t as "thumb2". These are considered part
25 ;; the 16-bit Thumb-1 instruction set.
27 (define_insn "*thumb2_incscc"
28 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
29 (plus:SI (match_operator:SI 2 "arm_comparison_operator"
30 [(match_operand:CC 3 "cc_register" "") (const_int 0)])
31 (match_operand:SI 1 "s_register_operand" "0,?r")))]
34 it\\t%d2\;add%d2\\t%0, %1, #1
35 ite\\t%D2\;mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1"
36 [(set_attr "conds" "use")
37 (set_attr "length" "6,10")]
40 (define_insn "*thumb2_decscc"
41 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
42 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
43 (match_operator:SI 2 "arm_comparison_operator"
44 [(match_operand 3 "cc_register" "") (const_int 0)])))]
47 it\\t%d2\;sub%d2\\t%0, %1, #1
48 ite\\t%D2\;mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1"
49 [(set_attr "conds" "use")
50 (set_attr "length" "6,10")]
53 ;; Thumb-2 only allows shift by constant on data processing instructions
54 (define_insn "*thumb_andsi_not_shiftsi_si"
55 [(set (match_operand:SI 0 "s_register_operand" "=r")
56 (and:SI (not:SI (match_operator:SI 4 "shift_operator"
57 [(match_operand:SI 2 "s_register_operand" "r")
58 (match_operand:SI 3 "const_int_operand" "M")]))
59 (match_operand:SI 1 "s_register_operand" "r")))]
61 "bic%?\\t%0, %1, %2%S4"
62 [(set_attr "predicable" "yes")
63 (set_attr "shift" "2")
64 (set_attr "type" "alu_shift")]
67 (define_insn "*thumb2_smaxsi3"
68 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
69 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
70 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
71 (clobber (reg:CC CC_REGNUM))]
74 cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %2
75 cmp\\t%1, %2\;it\\tge\;movge\\t%0, %1
76 cmp\\t%1, %2\;ite\\tge\;movge\\t%0, %1\;movlt\\t%0, %2"
77 [(set_attr "conds" "clob")
78 (set_attr "length" "10,10,14")]
81 (define_insn "*thumb2_sminsi3"
82 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
83 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
84 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
85 (clobber (reg:CC CC_REGNUM))]
88 cmp\\t%1, %2\;it\\tge\;movge\\t%0, %2
89 cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %1
90 cmp\\t%1, %2\;ite\\tlt\;movlt\\t%0, %1\;movge\\t%0, %2"
91 [(set_attr "conds" "clob")
92 (set_attr "length" "10,10,14")]
95 (define_insn "*thumb32_umaxsi3"
96 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
97 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
98 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
99 (clobber (reg:CC CC_REGNUM))]
102 cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %2
103 cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %1
104 cmp\\t%1, %2\;ite\\tcs\;movcs\\t%0, %1\;movcc\\t%0, %2"
105 [(set_attr "conds" "clob")
106 (set_attr "length" "10,10,14")]
109 (define_insn "*thumb2_uminsi3"
110 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
111 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r")
112 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
113 (clobber (reg:CC CC_REGNUM))]
116 cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %2
117 cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %1
118 cmp\\t%1, %2\;ite\\tcc\;movcc\\t%0, %1\;movcs\\t%0, %2"
119 [(set_attr "conds" "clob")
120 (set_attr "length" "10,10,14")]
123 (define_insn "*thumb2_notsi_shiftsi"
124 [(set (match_operand:SI 0 "s_register_operand" "=r")
125 (not:SI (match_operator:SI 3 "shift_operator"
126 [(match_operand:SI 1 "s_register_operand" "r")
127 (match_operand:SI 2 "const_int_operand" "M")])))]
130 [(set_attr "predicable" "yes")
131 (set_attr "shift" "1")
132 (set_attr "type" "alu_shift")]
135 (define_insn "*thumb2_notsi_shiftsi_compare0"
136 [(set (reg:CC_NOOV CC_REGNUM)
137 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
138 [(match_operand:SI 1 "s_register_operand" "r")
139 (match_operand:SI 2 "const_int_operand" "M")]))
141 (set (match_operand:SI 0 "s_register_operand" "=r")
142 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
145 [(set_attr "conds" "set")
146 (set_attr "shift" "1")
147 (set_attr "type" "alu_shift")]
150 (define_insn "*thumb2_not_shiftsi_compare0_scratch"
151 [(set (reg:CC_NOOV CC_REGNUM)
152 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
153 [(match_operand:SI 1 "s_register_operand" "r")
154 (match_operand:SI 2 "const_int_operand" "M")]))
156 (clobber (match_scratch:SI 0 "=r"))]
159 [(set_attr "conds" "set")
160 (set_attr "shift" "1")
161 (set_attr "type" "alu_shift")]
164 ;; Thumb-2 does not have rsc, so use a clever trick with shifter operands.
165 (define_insn "*thumb2_negdi2"
166 [(set (match_operand:DI 0 "s_register_operand" "=&r,r")
167 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0")))
168 (clobber (reg:CC CC_REGNUM))]
170 "negs\\t%Q0, %Q1\;sbc\\t%R0, %R1, %R1, lsl #1"
171 [(set_attr "conds" "clob")
172 (set_attr "length" "8")]
175 (define_insn "*thumb2_abssi2"
176 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
177 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
178 (clobber (reg:CC CC_REGNUM))]
181 cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
182 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
183 [(set_attr "conds" "clob,*")
184 (set_attr "shift" "1")
185 ;; predicable can't be set based on the variant, so left as no
186 (set_attr "length" "10,8")]
189 (define_insn "*thumb2_neg_abssi2"
190 [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
191 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
192 (clobber (reg:CC CC_REGNUM))]
195 cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
196 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
197 [(set_attr "conds" "clob,*")
198 (set_attr "shift" "1")
199 ;; predicable can't be set based on the variant, so left as no
200 (set_attr "length" "10,8")]
203 ;; We have two alternatives here for memory loads (and similarly for stores)
204 ;; to reflect the fact that the permissible constant pool ranges differ
205 ;; between ldr instructions taking low regs and ldr instructions taking high
206 ;; regs. The high register alternatives are not taken into account when
207 ;; choosing register preferences in order to reflect their expense.
208 (define_insn "*thumb2_movsi_insn"
209 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,l ,*hk,m,*m")
210 (match_operand:SI 1 "general_operand" "rk ,I,K,j,mi,*mi,l,*hk"))]
211 "TARGET_THUMB2 && ! TARGET_IWMMXT
212 && !(TARGET_HARD_FLOAT && TARGET_VFP)
213 && ( register_operand (operands[0], SImode)
214 || register_operand (operands[1], SImode))"
224 [(set_attr "type" "*,*,*,*,load1,load1,store1,store1")
225 (set_attr "predicable" "yes")
226 (set_attr "pool_range" "*,*,*,*,1020,4096,*,*")
227 (set_attr "neg_pool_range" "*,*,*,*,0,0,*,*")]
230 (define_insn "tls_load_dot_plus_four"
231 [(set (match_operand:SI 0 "register_operand" "=l,l,r,r")
232 (mem:SI (unspec:SI [(match_operand:SI 2 "register_operand" "0,1,0,1")
234 (match_operand 3 "" "")]
236 (clobber (match_scratch:SI 1 "=X,l,X,r"))]
239 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
240 INTVAL (operands[3]));
241 return \"add\\t%2, %|pc\;ldr%?\\t%0, [%2]\";
243 [(set_attr "length" "4,4,6,6")]
246 ;; Thumb-2 always has load/store halfword instructions, so we can avoid a lot
247 ;; of the messiness associated with the ARM patterns.
248 (define_insn "*thumb2_movhi_insn"
249 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
250 (match_operand:HI 1 "general_operand" "rI,n,r,m"))]
253 mov%?\\t%0, %1\\t%@ movhi
254 movw%?\\t%0, %L1\\t%@ movhi
255 str%(h%)\\t%1, %0\\t%@ movhi
256 ldr%(h%)\\t%0, %1\\t%@ movhi"
257 [(set_attr "type" "*,*,store1,load1")
258 (set_attr "predicable" "yes")
259 (set_attr "pool_range" "*,*,*,4096")
260 (set_attr "neg_pool_range" "*,*,*,250")]
263 (define_insn "*thumb2_cmpsi_shiftsi"
264 [(set (reg:CC CC_REGNUM)
265 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
266 (match_operator:SI 3 "shift_operator"
267 [(match_operand:SI 1 "s_register_operand" "r")
268 (match_operand:SI 2 "const_int_operand" "M")])))]
271 [(set_attr "conds" "set")
272 (set_attr "shift" "1")
273 (set_attr "type" "alu_shift")]
276 (define_insn "*thumb2_cmpsi_shiftsi_swp"
277 [(set (reg:CC_SWP CC_REGNUM)
278 (compare:CC_SWP (match_operator:SI 3 "shift_operator"
279 [(match_operand:SI 1 "s_register_operand" "r")
280 (match_operand:SI 2 "const_int_operand" "M")])
281 (match_operand:SI 0 "s_register_operand" "r")))]
284 [(set_attr "conds" "set")
285 (set_attr "shift" "1")
286 (set_attr "type" "alu_shift")]
289 (define_insn "*thumb2_cmpsi_neg_shiftsi"
290 [(set (reg:CC CC_REGNUM)
291 (compare:CC (match_operand:SI 0 "s_register_operand" "r")
292 (neg:SI (match_operator:SI 3 "shift_operator"
293 [(match_operand:SI 1 "s_register_operand" "r")
294 (match_operand:SI 2 "const_int_operand" "M")]))))]
297 [(set_attr "conds" "set")
298 (set_attr "shift" "1")
299 (set_attr "type" "alu_shift")]
302 (define_insn "*thumb2_mov_scc"
303 [(set (match_operand:SI 0 "s_register_operand" "=r")
304 (match_operator:SI 1 "arm_comparison_operator"
305 [(match_operand 2 "cc_register" "") (const_int 0)]))]
307 "ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
308 [(set_attr "conds" "use")
309 (set_attr "length" "10")]
312 (define_insn "*thumb2_mov_negscc"
313 [(set (match_operand:SI 0 "s_register_operand" "=r")
314 (neg:SI (match_operator:SI 1 "arm_comparison_operator"
315 [(match_operand 2 "cc_register" "") (const_int 0)])))]
317 "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
318 [(set_attr "conds" "use")
319 (set_attr "length" "10")]
322 (define_insn "*thumb2_mov_notscc"
323 [(set (match_operand:SI 0 "s_register_operand" "=r")
324 (not:SI (match_operator:SI 1 "arm_comparison_operator"
325 [(match_operand 2 "cc_register" "") (const_int 0)])))]
327 "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
328 [(set_attr "conds" "use")
329 (set_attr "length" "10")]
332 (define_insn "*thumb2_movsicc_insn"
333 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
335 (match_operator 3 "arm_comparison_operator"
336 [(match_operand 4 "cc_register" "") (const_int 0)])
337 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
338 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
341 it\\t%D3\;mov%D3\\t%0, %2
342 it\\t%D3\;mvn%D3\\t%0, #%B2
343 it\\t%d3\;mov%d3\\t%0, %1
344 it\\t%d3\;mvn%d3\\t%0, #%B1
345 ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
346 ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
347 ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
348 ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
349 [(set_attr "length" "6,6,6,6,10,10,10,10")
350 (set_attr "conds" "use")]
353 (define_insn "*thumb2_movsfcc_soft_insn"
354 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
355 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
356 [(match_operand 4 "cc_register" "") (const_int 0)])
357 (match_operand:SF 1 "s_register_operand" "0,r")
358 (match_operand:SF 2 "s_register_operand" "r,0")))]
359 "TARGET_THUMB2 && TARGET_SOFT_FLOAT"
361 it\\t%D3\;mov%D3\\t%0, %2
362 it\\t%d3\;mov%d3\\t%0, %1"
363 [(set_attr "length" "6,6")
364 (set_attr "conds" "use")]
367 (define_insn "*call_reg_thumb2"
368 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
369 (match_operand 1 "" ""))
370 (use (match_operand 2 "" ""))
371 (clobber (reg:SI LR_REGNUM))]
374 [(set_attr "type" "call")]
377 (define_insn "*call_value_reg_thumb2"
378 [(set (match_operand 0 "" "")
379 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
380 (match_operand 2 "" "")))
381 (use (match_operand 3 "" ""))
382 (clobber (reg:SI LR_REGNUM))]
385 [(set_attr "type" "call")]
388 (define_insn "*thumb2_indirect_jump"
390 (match_operand:SI 0 "register_operand" "l*r"))]
393 [(set_attr "conds" "clob")]
395 ;; Don't define thumb2_load_indirect_jump because we can't guarantee label
396 ;; addresses will have the thumb bit set correctly.
399 ;; Patterns to allow combination of arithmetic, cond code and shifts
401 (define_insn "*thumb2_arith_shiftsi"
402 [(set (match_operand:SI 0 "s_register_operand" "=r")
403 (match_operator:SI 1 "shiftable_operator"
404 [(match_operator:SI 3 "shift_operator"
405 [(match_operand:SI 4 "s_register_operand" "r")
406 (match_operand:SI 5 "const_int_operand" "M")])
407 (match_operand:SI 2 "s_register_operand" "rk")]))]
409 "%i1%?\\t%0, %2, %4%S3"
410 [(set_attr "predicable" "yes")
411 (set_attr "shift" "4")
412 (set_attr "type" "alu_shift")]
415 ;; ??? What does this splitter do? Copied from the ARM version
417 [(set (match_operand:SI 0 "s_register_operand" "")
418 (match_operator:SI 1 "shiftable_operator"
419 [(match_operator:SI 2 "shiftable_operator"
420 [(match_operator:SI 3 "shift_operator"
421 [(match_operand:SI 4 "s_register_operand" "")
422 (match_operand:SI 5 "const_int_operand" "")])
423 (match_operand:SI 6 "s_register_operand" "")])
424 (match_operand:SI 7 "arm_rhs_operand" "")]))
425 (clobber (match_operand:SI 8 "s_register_operand" ""))]
428 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
431 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
434 (define_insn "*thumb2_arith_shiftsi_compare0"
435 [(set (reg:CC_NOOV CC_REGNUM)
436 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
437 [(match_operator:SI 3 "shift_operator"
438 [(match_operand:SI 4 "s_register_operand" "r")
439 (match_operand:SI 5 "const_int_operand" "M")])
440 (match_operand:SI 2 "s_register_operand" "r")])
442 (set (match_operand:SI 0 "s_register_operand" "=r")
443 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
446 "%i1%.\\t%0, %2, %4%S3"
447 [(set_attr "conds" "set")
448 (set_attr "shift" "4")
449 (set_attr "type" "alu_shift")]
452 (define_insn "*thumb2_arith_shiftsi_compare0_scratch"
453 [(set (reg:CC_NOOV CC_REGNUM)
454 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
455 [(match_operator:SI 3 "shift_operator"
456 [(match_operand:SI 4 "s_register_operand" "r")
457 (match_operand:SI 5 "const_int_operand" "M")])
458 (match_operand:SI 2 "s_register_operand" "r")])
460 (clobber (match_scratch:SI 0 "=r"))]
462 "%i1%.\\t%0, %2, %4%S3"
463 [(set_attr "conds" "set")
464 (set_attr "shift" "4")
465 (set_attr "type" "alu_shift")]
468 (define_insn "*thumb2_sub_shiftsi"
469 [(set (match_operand:SI 0 "s_register_operand" "=r")
470 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
471 (match_operator:SI 2 "shift_operator"
472 [(match_operand:SI 3 "s_register_operand" "r")
473 (match_operand:SI 4 "const_int_operand" "M")])))]
475 "sub%?\\t%0, %1, %3%S2"
476 [(set_attr "predicable" "yes")
477 (set_attr "shift" "3")
478 (set_attr "type" "alu_shift")]
481 (define_insn "*thumb2_sub_shiftsi_compare0"
482 [(set (reg:CC_NOOV CC_REGNUM)
484 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
485 (match_operator:SI 2 "shift_operator"
486 [(match_operand:SI 3 "s_register_operand" "r")
487 (match_operand:SI 4 "const_int_operand" "M")]))
489 (set (match_operand:SI 0 "s_register_operand" "=r")
490 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
493 "sub%.\\t%0, %1, %3%S2"
494 [(set_attr "conds" "set")
495 (set_attr "shift" "3")
496 (set_attr "type" "alu_shift")]
499 (define_insn "*thumb2_sub_shiftsi_compare0_scratch"
500 [(set (reg:CC_NOOV CC_REGNUM)
502 (minus:SI (match_operand:SI 1 "s_register_operand" "r")
503 (match_operator:SI 2 "shift_operator"
504 [(match_operand:SI 3 "s_register_operand" "r")
505 (match_operand:SI 4 "const_int_operand" "M")]))
507 (clobber (match_scratch:SI 0 "=r"))]
509 "sub%.\\t%0, %1, %3%S2"
510 [(set_attr "conds" "set")
511 (set_attr "shift" "3")
512 (set_attr "type" "alu_shift")]
515 (define_insn "*thumb2_and_scc"
516 [(set (match_operand:SI 0 "s_register_operand" "=r")
517 (and:SI (match_operator:SI 1 "arm_comparison_operator"
518 [(match_operand 3 "cc_register" "") (const_int 0)])
519 (match_operand:SI 2 "s_register_operand" "r")))]
521 "ite\\t%D1\;mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
522 [(set_attr "conds" "use")
523 (set_attr "length" "10")]
526 (define_insn "*thumb2_ior_scc"
527 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
528 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
529 [(match_operand 3 "cc_register" "") (const_int 0)])
530 (match_operand:SI 1 "s_register_operand" "0,?r")))]
533 it\\t%d2\;orr%d2\\t%0, %1, #1
534 ite\\t%D2\;mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
535 [(set_attr "conds" "use")
536 (set_attr "length" "6,10")]
539 (define_insn "*thumb2_cond_move"
540 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
541 (if_then_else:SI (match_operator 3 "equality_operator"
542 [(match_operator 4 "arm_comparison_operator"
543 [(match_operand 5 "cc_register" "") (const_int 0)])
545 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
546 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
549 if (GET_CODE (operands[3]) == NE)
551 if (which_alternative != 1)
552 output_asm_insn (\"it\\t%D4\;mov%D4\\t%0, %2\", operands);
553 if (which_alternative != 0)
554 output_asm_insn (\"it\\t%d4\;mov%d4\\t%0, %1\", operands);
557 switch (which_alternative)
560 output_asm_insn (\"it\\t%d4\", operands);
563 output_asm_insn (\"it\\t%D4\", operands);
566 output_asm_insn (\"ite\\t%D4\", operands);
571 if (which_alternative != 0)
572 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
573 if (which_alternative != 1)
574 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
577 [(set_attr "conds" "use")
578 (set_attr "length" "6,6,10")]
581 (define_insn "*thumb2_cond_arith"
582 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
583 (match_operator:SI 5 "shiftable_operator"
584 [(match_operator:SI 4 "arm_comparison_operator"
585 [(match_operand:SI 2 "s_register_operand" "r,r")
586 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
587 (match_operand:SI 1 "s_register_operand" "0,?r")]))
588 (clobber (reg:CC CC_REGNUM))]
591 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
592 return \"%i5\\t%0, %1, %2, lsr #31\";
594 output_asm_insn (\"cmp\\t%2, %3\", operands);
595 if (GET_CODE (operands[5]) == AND)
597 output_asm_insn (\"ite\\t%D4\", operands);
598 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
600 else if (GET_CODE (operands[5]) == MINUS)
602 output_asm_insn (\"ite\\t%D4\", operands);
603 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
605 else if (which_alternative != 0)
607 output_asm_insn (\"ite\\t%D4\", operands);
608 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
611 output_asm_insn (\"it\\t%d4\", operands);
612 return \"%i5%d4\\t%0, %1, #1\";
614 [(set_attr "conds" "clob")
615 (set_attr "length" "14")]
618 (define_insn "*thumb2_cond_sub"
619 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
620 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
621 (match_operator:SI 4 "arm_comparison_operator"
622 [(match_operand:SI 2 "s_register_operand" "r,r")
623 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
624 (clobber (reg:CC CC_REGNUM))]
627 output_asm_insn (\"cmp\\t%2, %3\", operands);
628 if (which_alternative != 0)
630 output_asm_insn (\"ite\\t%D4\", operands);
631 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
634 output_asm_insn (\"it\\t%d4\", operands);
635 return \"sub%d4\\t%0, %1, #1\";
637 [(set_attr "conds" "clob")
638 (set_attr "length" "10,14")]
641 (define_insn "*thumb2_negscc"
642 [(set (match_operand:SI 0 "s_register_operand" "=r")
643 (neg:SI (match_operator 3 "arm_comparison_operator"
644 [(match_operand:SI 1 "s_register_operand" "r")
645 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
646 (clobber (reg:CC CC_REGNUM))]
649 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
650 return \"asr\\t%0, %1, #31\";
652 if (GET_CODE (operands[3]) == NE)
653 return \"subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0\";
655 output_asm_insn (\"cmp\\t%1, %2\", operands);
656 output_asm_insn (\"ite\\t%D3\", operands);
657 output_asm_insn (\"mov%D3\\t%0, #0\", operands);
658 return \"mvn%d3\\t%0, #0\";
660 [(set_attr "conds" "clob")
661 (set_attr "length" "14")]
664 (define_insn "*thumb2_movcond"
665 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
667 (match_operator 5 "arm_comparison_operator"
668 [(match_operand:SI 3 "s_register_operand" "r,r,r")
669 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
670 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
671 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
672 (clobber (reg:CC CC_REGNUM))]
675 if (GET_CODE (operands[5]) == LT
676 && (operands[4] == const0_rtx))
678 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
680 if (operands[2] == const0_rtx)
681 return \"and\\t%0, %1, %3, asr #31\";
682 return \"ands\\t%0, %1, %3, asr #32\;it\\tcc\;movcc\\t%0, %2\";
684 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
686 if (operands[1] == const0_rtx)
687 return \"bic\\t%0, %2, %3, asr #31\";
688 return \"bics\\t%0, %2, %3, asr #32\;it\\tcs\;movcs\\t%0, %1\";
690 /* The only case that falls through to here is when both ops 1 & 2
694 if (GET_CODE (operands[5]) == GE
695 && (operands[4] == const0_rtx))
697 if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
699 if (operands[2] == const0_rtx)
700 return \"bic\\t%0, %1, %3, asr #31\";
701 return \"bics\\t%0, %1, %3, asr #32\;it\\tcs\;movcs\\t%0, %2\";
703 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
705 if (operands[1] == const0_rtx)
706 return \"and\\t%0, %2, %3, asr #31\";
707 return \"ands\\t%0, %2, %3, asr #32\;it\tcc\;movcc\\t%0, %1\";
709 /* The only case that falls through to here is when both ops 1 & 2
712 if (GET_CODE (operands[4]) == CONST_INT
713 && !const_ok_for_arm (INTVAL (operands[4])))
714 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
716 output_asm_insn (\"cmp\\t%3, %4\", operands);
717 switch (which_alternative)
720 output_asm_insn (\"it\\t%D5\", operands);
723 output_asm_insn (\"it\\t%d5\", operands);
726 output_asm_insn (\"ite\\t%d5\", operands);
731 if (which_alternative != 0)
732 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
733 if (which_alternative != 1)
734 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
737 [(set_attr "conds" "clob")
738 (set_attr "length" "10,10,14")]
741 ;; Zero and sign extension instructions.
743 (define_insn_and_split "*thumb2_zero_extendsidi2"
744 [(set (match_operand:DI 0 "s_register_operand" "=r")
745 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
747 "mov%?\\t%Q0, %1\;mov%?\\t%R0, #0"
748 "&& reload_completed"
749 [(set (match_dup 0) (match_dup 1))]
752 rtx lo_part = gen_lowpart (SImode, operands[0]);
753 if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
754 emit_move_insn (lo_part, operands[1]);
755 operands[0] = gen_highpart (SImode, operands[0]);
756 operands[1] = const0_rtx;
759 [(set_attr "length" "8")
760 (set_attr "ce_count" "2")
761 (set_attr "predicable" "yes")]
764 (define_insn_and_split "*thumb2_zero_extendhidi2"
765 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
766 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
769 uxth%?\\t%Q0, %1\;mov%?\\t%R0, #0
770 ldr%(h%)\\t%Q0, %1\;mov%?\\t%R0, #0"
771 "&& reload_completed"
772 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
773 (set (match_dup 2) (match_dup 3))]
776 operands[2] = gen_highpart (SImode, operands[0]);
777 operands[0] = gen_lowpart (SImode, operands[0]);
778 operands[3] = const0_rtx;
781 [(set_attr "length" "8")
782 (set_attr "ce_count" "2")
783 (set_attr "predicable" "yes")
784 (set_attr "type" "*,load_byte")
785 (set_attr "pool_range" "*,4092")
786 (set_attr "neg_pool_range" "*,250")]
789 (define_insn_and_split "*thumb2_zero_extendqidi2"
790 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
791 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
794 uxtb%?\\t%Q0, %1\;mov%?\\t%R0, #0
795 ldr%(b%)\\t%Q0, %1\;mov%?\\t%R0, #0"
796 "&& reload_completed"
797 [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
798 (set (match_dup 2) (match_dup 3))]
801 operands[2] = gen_highpart (SImode, operands[0]);
802 operands[0] = gen_lowpart (SImode, operands[0]);
803 operands[3] = const0_rtx;
806 [(set_attr "length" "8")
807 (set_attr "ce_count" "2")
808 (set_attr "predicable" "yes")
809 (set_attr "type" "*,load_byte")
810 (set_attr "pool_range" "*,4092")
811 (set_attr "neg_pool_range" "*,250")]
814 (define_insn_and_split "*thumb2_extendsidi2"
815 [(set (match_operand:DI 0 "s_register_operand" "=r")
816 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
818 "mov%?\\t%Q0, %1\;asr?\\t%R0, %1, #31"
819 "&& reload_completed"
820 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
822 rtx lo_part = gen_lowpart (SImode, operands[0]);
824 if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
825 emit_move_insn (lo_part, operands[1]);
826 operands[0] = gen_highpart (SImode, operands[0]);
828 [(set_attr "length" "8")
829 (set_attr "ce_count" "2")
830 (set_attr "shift" "1")
831 (set_attr "predicable" "yes")]
834 (define_insn_and_split "*thumb2_extendhidi2"
835 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
836 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
839 sxth%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
840 ldrsh%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
841 "&& reload_completed"
842 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
843 (set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
846 operands[2] = gen_highpart (SImode, operands[0]);
847 operands[0] = gen_lowpart (SImode, operands[0]);
850 [(set_attr "length" "8")
851 (set_attr "ce_count" "2")
852 (set_attr "predicable" "yes")
853 (set_attr "type" "*,load_byte")
854 (set_attr "pool_range" "*,4092")
855 (set_attr "neg_pool_range" "*,250")]
858 (define_insn_and_split "*thumb2_extendqidi2"
859 [(set (match_operand:DI 0 "s_register_operand" "=r,r")
860 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
863 sxtb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
864 ldrsb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
865 "&& reload_completed"
866 [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
867 (set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
870 operands[2] = gen_highpart (SImode, operands[0]);
871 operands[0] = gen_lowpart (SImode, operands[0]);
874 [(set_attr "length" "8")
875 (set_attr "ce_count" "2")
876 (set_attr "predicable" "yes")
877 (set_attr "type" "*,load_byte")
878 (set_attr "pool_range" "*,4092")
879 (set_attr "neg_pool_range" "*,250")]
882 ;; All supported Thumb2 implementations are armv6, so only that case is
884 (define_insn "*thumb2_extendqisi_v6"
885 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
886 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
887 "TARGET_THUMB2 && arm_arch6"
891 [(set_attr "type" "alu_shift,load_byte")
892 (set_attr "predicable" "yes")
893 (set_attr "pool_range" "*,4096")
894 (set_attr "neg_pool_range" "*,250")]
897 (define_insn "*thumb2_zero_extendhisi2_v6"
898 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
899 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
900 "TARGET_THUMB2 && arm_arch6"
904 [(set_attr "type" "alu_shift,load_byte")
905 (set_attr "predicable" "yes")
906 (set_attr "pool_range" "*,4096")
907 (set_attr "neg_pool_range" "*,250")]
910 (define_insn "thumb2_zero_extendqisi2_v6"
911 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
912 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
913 "TARGET_THUMB2 && arm_arch6"
916 ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
917 [(set_attr "type" "alu_shift,load_byte")
918 (set_attr "predicable" "yes")
919 (set_attr "pool_range" "*,4096")
920 (set_attr "neg_pool_range" "*,250")]
923 (define_insn "thumb2_casesi_internal"
924 [(parallel [(set (pc)
926 (leu (match_operand:SI 0 "s_register_operand" "r")
927 (match_operand:SI 1 "arm_rhs_operand" "rI"))
928 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
929 (label_ref (match_operand 2 "" ""))))
930 (label_ref (match_operand 3 "" ""))))
931 (clobber (reg:CC CC_REGNUM))
932 (clobber (match_scratch:SI 4 "=&r"))
933 (use (label_ref (match_dup 2)))])]
934 "TARGET_THUMB2 && !flag_pic"
935 "* return thumb2_output_casesi(operands);"
936 [(set_attr "conds" "clob")
937 (set_attr "length" "16")]
940 (define_insn "thumb2_casesi_internal_pic"
941 [(parallel [(set (pc)
943 (leu (match_operand:SI 0 "s_register_operand" "r")
944 (match_operand:SI 1 "arm_rhs_operand" "rI"))
945 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
946 (label_ref (match_operand 2 "" ""))))
947 (label_ref (match_operand 3 "" ""))))
948 (clobber (reg:CC CC_REGNUM))
949 (clobber (match_scratch:SI 4 "=&r"))
950 (clobber (match_scratch:SI 5 "=r"))
951 (use (label_ref (match_dup 2)))])]
952 "TARGET_THUMB2 && flag_pic"
953 "* return thumb2_output_casesi(operands);"
954 [(set_attr "conds" "clob")
955 (set_attr "length" "20")]
958 ;; Note: this is not predicable, to avoid issues with linker-generated
959 ;; interworking stubs.
960 (define_insn "*thumb2_return"
962 "TARGET_THUMB2 && USE_RETURN_INSN (FALSE)"
965 return output_return_instruction (const_true_rtx, TRUE, FALSE);
967 [(set_attr "type" "load1")
968 (set_attr "length" "12")]
971 (define_insn_and_split "thumb2_eh_return"
972 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
974 (clobber (match_scratch:SI 1 "=&r"))]
977 "&& reload_completed"
981 thumb_set_return_address (operands[0], operands[1]);
986 (define_insn "*thumb2_alusi3_short"
987 [(set (match_operand:SI 0 "s_register_operand" "=l")
988 (match_operator:SI 3 "thumb_16bit_operator"
989 [(match_operand:SI 1 "s_register_operand" "0")
990 (match_operand:SI 2 "s_register_operand" "l")]))
991 (clobber (reg:CC CC_REGNUM))]
992 "TARGET_THUMB2 && reload_completed
993 && GET_CODE(operands[3]) != PLUS
994 && GET_CODE(operands[3]) != MINUS"
996 [(set_attr "predicable" "yes")
997 (set_attr "length" "2")]
1000 ;; Similarly for 16-bit shift instructions
1001 ;; There is no 16-bit rotate by immediate instruction.
1003 [(set (match_operand:SI 0 "low_register_operand" "")
1004 (match_operator:SI 3 "shift_operator"
1005 [(match_operand:SI 1 "low_register_operand" "")
1006 (match_operand:SI 2 "low_reg_or_int_operand" "")]))]
1008 && peep2_regno_dead_p(0, CC_REGNUM)
1009 && ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
1010 || REG_P(operands[2]))"
1016 (clobber (reg:CC CC_REGNUM))])]
1020 (define_insn "*thumb2_shiftsi3_short"
1021 [(set (match_operand:SI 0 "low_register_operand" "=l")
1022 (match_operator:SI 3 "shift_operator"
1023 [(match_operand:SI 1 "low_register_operand" "l")
1024 (match_operand:SI 2 "low_reg_or_int_operand" "lM")]))
1025 (clobber (reg:CC CC_REGNUM))]
1026 "TARGET_THUMB2 && reload_completed
1027 && ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
1028 || REG_P(operands[2]))"
1029 "* return arm_output_shift(operands, 2);"
1030 [(set_attr "predicable" "yes")
1031 (set_attr "shift" "1")
1032 (set_attr "length" "2")
1033 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
1034 (const_string "alu_shift")
1035 (const_string "alu_shift_reg")))]
1038 ;; 16-bit load immediate
1040 [(set (match_operand:QHSI 0 "low_register_operand" "")
1041 (match_operand:QHSI 1 "const_int_operand" ""))]
1043 && peep2_regno_dead_p(0, CC_REGNUM)
1044 && (unsigned HOST_WIDE_INT) INTVAL(operands[1]) < 256"
1048 (clobber (reg:CC CC_REGNUM))])]
1052 (define_insn "*thumb2_mov<mode>_shortim"
1053 [(set (match_operand:QHSI 0 "low_register_operand" "=l")
1054 (match_operand:QHSI 1 "const_int_operand" "I"))
1055 (clobber (reg:CC CC_REGNUM))]
1056 "TARGET_THUMB2 && reload_completed"
1058 [(set_attr "predicable" "yes")
1059 (set_attr "length" "2")]
1062 ;; 16-bit add/sub immediate
1064 [(set (match_operand:SI 0 "low_register_operand" "")
1065 (plus:SI (match_operand:SI 1 "low_register_operand" "")
1066 (match_operand:SI 2 "const_int_operand" "")))]
1068 && peep2_regno_dead_p(0, CC_REGNUM)
1069 && ((rtx_equal_p(operands[0], operands[1])
1070 && INTVAL(operands[2]) > -256 && INTVAL(operands[2]) < 256)
1071 || (INTVAL(operands[2]) > -8 && INTVAL(operands[2]) < 8))"
1074 (plus:SI (match_dup 1)
1076 (clobber (reg:CC CC_REGNUM))])]
1080 (define_insn "*thumb2_addsi_short"
1081 [(set (match_operand:SI 0 "low_register_operand" "=l,l")
1082 (plus:SI (match_operand:SI 1 "low_register_operand" "l,0")
1083 (match_operand:SI 2 "low_reg_or_int_operand" "lPt,Ps")))
1084 (clobber (reg:CC CC_REGNUM))]
1085 "TARGET_THUMB2 && reload_completed"
1089 if (GET_CODE (operands[2]) == CONST_INT)
1090 val = INTVAL(operands[2]);
1094 /* We prefer eg. subs rn, rn, #1 over adds rn, rn, #0xffffffff. */
1095 if (val < 0 && const_ok_for_arm(ARM_SIGN_EXTEND (-val)))
1096 return \"sub%!\\t%0, %1, #%n2\";
1098 return \"add%!\\t%0, %1, %2\";
1100 [(set_attr "predicable" "yes")
1101 (set_attr "length" "2")]
1104 (define_insn "divsi3"
1105 [(set (match_operand:SI 0 "s_register_operand" "=r")
1106 (div:SI (match_operand:SI 1 "s_register_operand" "r")
1107 (match_operand:SI 2 "s_register_operand" "r")))]
1108 "TARGET_THUMB2 && arm_arch_hwdiv"
1109 "sdiv%?\t%0, %1, %2"
1110 [(set_attr "predicable" "yes")
1111 (set_attr "insn" "sdiv")]
1114 (define_insn "udivsi3"
1115 [(set (match_operand:SI 0 "s_register_operand" "=r")
1116 (udiv:SI (match_operand:SI 1 "s_register_operand" "r")
1117 (match_operand:SI 2 "s_register_operand" "r")))]
1118 "TARGET_THUMB2 && arm_arch_hwdiv"
1119 "udiv%?\t%0, %1, %2"
1120 [(set_attr "predicable" "yes")
1121 (set_attr "insn" "udiv")]
1124 (define_insn "*thumb2_subsi_short"
1125 [(set (match_operand:SI 0 "low_register_operand" "=l")
1126 (minus:SI (match_operand:SI 1 "low_register_operand" "l")
1127 (match_operand:SI 2 "low_register_operand" "l")))
1128 (clobber (reg:CC CC_REGNUM))]
1129 "TARGET_THUMB2 && reload_completed"
1130 "sub%!\\t%0, %1, %2"
1131 [(set_attr "predicable" "yes")
1132 (set_attr "length" "2")]
1136 [(set (match_operand:CC 0 "cc_register" "")
1137 (compare:CC (match_operand:SI 1 "low_register_operand" "")
1138 (match_operand:SI 2 "const_int_operand" "")))]
1140 && peep2_reg_dead_p (1, operands[1])
1141 && satisfies_constraint_Pw (operands[2])"
1143 [(set (match_dup 0) (compare:CC (match_dup 1) (match_dup 2)))
1144 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 3)))])]
1145 "operands[3] = GEN_INT (- INTVAL (operands[2]));"
1149 [(match_scratch:SI 3 "l")
1150 (set (match_operand:CC 0 "cc_register" "")
1151 (compare:CC (match_operand:SI 1 "low_register_operand" "")
1152 (match_operand:SI 2 "const_int_operand" "")))]
1154 && satisfies_constraint_Px (operands[2])"
1156 [(set (match_dup 0) (compare:CC (match_dup 1) (match_dup 2)))
1157 (set (match_dup 3) (plus:SI (match_dup 1) (match_dup 4)))])]
1158 "operands[4] = GEN_INT (- INTVAL (operands[2]));"
1161 (define_insn "*thumb2_addsi3_compare0"
1162 [(set (reg:CC_NOOV CC_REGNUM)
1164 (plus:SI (match_operand:SI 1 "s_register_operand" "l, 0, r")
1165 (match_operand:SI 2 "arm_add_operand" "lPt,Ps,rIL"))
1167 (set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1168 (plus:SI (match_dup 1) (match_dup 2)))]
1173 if (GET_CODE (operands[2]) == CONST_INT)
1174 val = INTVAL (operands[2]);
1178 if (val < 0 && const_ok_for_arm (ARM_SIGN_EXTEND (-val)))
1179 return \"subs\\t%0, %1, #%n2\";
1181 return \"adds\\t%0, %1, %2\";
1183 [(set_attr "conds" "set")
1184 (set_attr "length" "2,2,4")]
1187 (define_insn "*thumb2_addsi3_compare0_scratch"
1188 [(set (reg:CC_NOOV CC_REGNUM)
1190 (plus:SI (match_operand:SI 0 "s_register_operand" "l, r")
1191 (match_operand:SI 1 "arm_add_operand" "lPv,rIL"))
1197 if (GET_CODE (operands[1]) == CONST_INT)
1198 val = INTVAL (operands[1]);
1202 if (val < 0 && const_ok_for_arm (ARM_SIGN_EXTEND (-val)))
1203 return \"cmp\\t%0, #%n1\";
1205 return \"cmn\\t%0, %1\";
1207 [(set_attr "conds" "set")
1208 (set_attr "length" "2,4")]
1211 ;; 16-bit encodings of "muls" and "mul<c>". We only use these when
1212 ;; optimizing for size since "muls" is slow on all known
1213 ;; implementations and since "mul<c>" will be generated by
1214 ;; "*arm_mulsi3_v6" anyhow. The assembler will use a 16-bit encoding
1215 ;; for "mul<c>" whenever possible anyhow.
1217 [(set (match_operand:SI 0 "low_register_operand" "")
1218 (mult:SI (match_operand:SI 1 "low_register_operand" "")
1220 "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
1223 (mult:SI (match_dup 0) (match_dup 1)))
1224 (clobber (reg:CC CC_REGNUM))])]
1229 [(set (match_operand:SI 0 "low_register_operand" "")
1230 (mult:SI (match_dup 0)
1231 (match_operand:SI 1 "low_register_operand" "")))]
1232 "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
1235 (mult:SI (match_dup 0) (match_dup 1)))
1236 (clobber (reg:CC CC_REGNUM))])]
1240 (define_insn "*thumb2_mulsi_short"
1241 [(set (match_operand:SI 0 "low_register_operand" "=l")
1242 (mult:SI (match_operand:SI 1 "low_register_operand" "%0")
1243 (match_operand:SI 2 "low_register_operand" "l")))
1244 (clobber (reg:CC CC_REGNUM))]
1245 "TARGET_THUMB2 && optimize_size && reload_completed"
1246 "mul%!\\t%0, %2, %0"
1247 [(set_attr "predicable" "yes")
1248 (set_attr "length" "2")
1249 (set_attr "insn" "muls")])
1251 (define_insn "*thumb2_mulsi_short_compare0"
1252 [(set (reg:CC_NOOV CC_REGNUM)
1254 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1255 (match_operand:SI 2 "register_operand" "l"))
1257 (set (match_operand:SI 0 "register_operand" "=l")
1258 (mult:SI (match_dup 1) (match_dup 2)))]
1259 "TARGET_THUMB2 && optimize_size"
1261 [(set_attr "length" "2")
1262 (set_attr "insn" "muls")])
1264 (define_insn "*thumb2_mulsi_short_compare0_scratch"
1265 [(set (reg:CC_NOOV CC_REGNUM)
1267 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1268 (match_operand:SI 2 "register_operand" "l"))
1270 (clobber (match_scratch:SI 0 "=l"))]
1271 "TARGET_THUMB2 && optimize_size"
1273 [(set_attr "length" "2")
1274 (set_attr "insn" "muls")])
1276 (define_insn "*thumb2_cbz"
1277 [(set (pc) (if_then_else
1278 (eq (match_operand:SI 0 "s_register_operand" "l,?r")
1280 (label_ref (match_operand 1 "" ""))
1282 (clobber (reg:CC CC_REGNUM))]
1285 if (get_attr_length (insn) == 2)
1286 return \"cbz\\t%0, %l1\";
1288 return \"cmp\\t%0, #0\;beq\\t%l1\";
1290 [(set (attr "length")
1292 (and (ge (minus (match_dup 1) (pc)) (const_int 2))
1293 (le (minus (match_dup 1) (pc)) (const_int 128))
1294 (eq (symbol_ref ("which_alternative")) (const_int 0)))
1299 (define_insn "*thumb2_cbnz"
1300 [(set (pc) (if_then_else
1301 (ne (match_operand:SI 0 "s_register_operand" "l,?r")
1303 (label_ref (match_operand 1 "" ""))
1305 (clobber (reg:CC CC_REGNUM))]
1308 if (get_attr_length (insn) == 2)
1309 return \"cbnz\\t%0, %l1\";
1311 return \"cmp\\t%0, #0\;bne\\t%l1\";
1313 [(set (attr "length")
1315 (and (ge (minus (match_dup 1) (pc)) (const_int 2))
1316 (le (minus (match_dup 1) (pc)) (const_int 128))
1317 (eq (symbol_ref ("which_alternative")) (const_int 0)))
1322 ;; 16-bit complement
1324 [(set (match_operand:SI 0 "low_register_operand" "")
1325 (not:SI (match_operand:SI 1 "low_register_operand" "")))]
1327 && peep2_regno_dead_p(0, CC_REGNUM)"
1330 (not:SI (match_dup 1)))
1331 (clobber (reg:CC CC_REGNUM))])]
1335 (define_insn "*thumb2_one_cmplsi2_short"
1336 [(set (match_operand:SI 0 "low_register_operand" "=l")
1337 (not:SI (match_operand:SI 1 "low_register_operand" "l")))
1338 (clobber (reg:CC CC_REGNUM))]
1339 "TARGET_THUMB2 && reload_completed"
1341 [(set_attr "predicable" "yes")
1342 (set_attr "length" "2")]
1347 [(set (match_operand:SI 0 "low_register_operand" "")
1348 (neg:SI (match_operand:SI 1 "low_register_operand" "")))]
1350 && peep2_regno_dead_p(0, CC_REGNUM)"
1353 (neg:SI (match_dup 1)))
1354 (clobber (reg:CC CC_REGNUM))])]
1358 (define_insn "*thumb2_negsi2_short"
1359 [(set (match_operand:SI 0 "low_register_operand" "=l")
1360 (neg:SI (match_operand:SI 1 "low_register_operand" "l")))
1361 (clobber (reg:CC CC_REGNUM))]
1362 "TARGET_THUMB2 && reload_completed"
1364 [(set_attr "predicable" "yes")
1365 (set_attr "length" "2")]
1368 (define_insn "orsi_notsi_si"
1369 [(set (match_operand:SI 0 "s_register_operand" "=r")
1370 (ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1371 (match_operand:SI 1 "s_register_operand" "r")))]
1373 "orn%?\\t%0, %1, %2"
1374 [(set_attr "predicable" "yes")]
1377 (define_insn "*thumb_orsi_not_shiftsi_si"
1378 [(set (match_operand:SI 0 "s_register_operand" "=r")
1379 (ior:SI (not:SI (match_operator:SI 4 "shift_operator"
1380 [(match_operand:SI 2 "s_register_operand" "r")
1381 (match_operand:SI 3 "const_int_operand" "M")]))
1382 (match_operand:SI 1 "s_register_operand" "r")))]
1384 "orn%?\\t%0, %1, %2%S4"
1385 [(set_attr "predicable" "yes")
1386 (set_attr "shift" "2")
1387 (set_attr "type" "alu_shift")]
1390 (define_insn_and_split "*thumb2_iorsi3"
1391 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
1392 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1393 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1397 orn%?\\t%0, %1, #%B2
1400 && GET_CODE (operands[2]) == CONST_INT
1401 && !(const_ok_for_arm (INTVAL (operands[2]))
1402 || const_ok_for_arm (~INTVAL (operands[2])))"
1403 [(clobber (const_int 0))]
1405 arm_split_constant (IOR, SImode, curr_insn,
1406 INTVAL (operands[2]), operands[0], operands[1], 0);
1409 [(set_attr "length" "4,4,16")
1410 (set_attr "predicable" "yes")]
1414 [(set (match_operand:CC_NOOV 0 "cc_register" "")
1415 (compare:CC_NOOV (zero_extract:SI
1416 (match_operand:SI 1 "low_register_operand" "")
1418 (match_operand:SI 2 "const_int_operand" ""))
1420 (match_scratch:SI 3 "l")
1422 (if_then_else (match_operator:CC_NOOV 4 "equality_operator"
1423 [(match_dup 0) (const_int 0)])
1424 (match_operand 5 "" "")
1425 (match_operand 6 "" "")))]
1427 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32)"
1428 [(parallel [(set (match_dup 0)
1429 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1431 (clobber (match_dup 3))])
1433 (if_then_else (match_op_dup 4 [(match_dup 0) (const_int 0)])
1434 (match_dup 5) (match_dup 6)))]
1436 operands[2] = GEN_INT (31 - INTVAL (operands[2]));
1437 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? LT : GE,
1438 VOIDmode, operands[0], const0_rtx);
1442 [(set (match_operand:CC_NOOV 0 "cc_register" "")
1443 (compare:CC_NOOV (zero_extract:SI
1444 (match_operand:SI 1 "low_register_operand" "")
1445 (match_operand:SI 2 "const_int_operand" "")
1448 (match_scratch:SI 3 "l")
1450 (if_then_else (match_operator:CC_NOOV 4 "equality_operator"
1451 [(match_dup 0) (const_int 0)])
1452 (match_operand 5 "" "")
1453 (match_operand 6 "" "")))]
1455 && (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 32)"
1456 [(parallel [(set (match_dup 0)
1457 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1459 (clobber (match_dup 3))])
1461 (if_then_else (match_op_dup 4 [(match_dup 0) (const_int 0)])
1462 (match_dup 5) (match_dup 6)))]
1464 operands[2] = GEN_INT (32 - INTVAL (operands[2]));