gcc/
[official-gcc.git] / gcc / config / arm / thumb2.md
blob8c754d90d589e98f80ca63bdc9a2f099a444f3a8
1 ;; ARM Thumb-2 Machine Description
2 ;; Copyright (C) 2007-2015 Free Software Foundation, Inc.
3 ;; Written by CodeSourcery, LLC.
4 ;;
5 ;; This file is part of GCC.
6 ;;
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)
10 ;; any later version.
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 ;; Thumb-2 only allows shift by constant on data processing instructions
28 (define_insn "*thumb_andsi_not_shiftsi_si"
29   [(set (match_operand:SI 0 "s_register_operand" "=r")
30         (and:SI (not:SI (match_operator:SI 4 "shift_operator"
31                          [(match_operand:SI 2 "s_register_operand" "r")
32                           (match_operand:SI 3 "const_int_operand" "M")]))
33                 (match_operand:SI 1 "s_register_operand" "r")))]
34   "TARGET_THUMB2"
35   "bic%?\\t%0, %1, %2%S4"
36   [(set_attr "predicable" "yes")
37    (set_attr "predicable_short_it" "no")
38    (set_attr "shift" "2")
39    (set_attr "type" "alu_shift_imm")]
42 ;; We use the '0' constraint for operand 1 because reload should
43 ;; be smart enough to generate an appropriate move for the r/r/r case.
44 (define_insn_and_split "*thumb2_smaxsi3"
45   [(set (match_operand:SI          0 "s_register_operand" "=r,l,r")
46         (smax:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
47                  (match_operand:SI 2 "arm_rhs_operand"    "r,Py,I")))
48    (clobber (reg:CC CC_REGNUM))]
49    "TARGET_THUMB2"
50    "#"
51    ; cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %2
52   "TARGET_THUMB2 && reload_completed"
53   [(set (reg:CC CC_REGNUM)
54         (compare:CC (match_dup 1) (match_dup 2)))
55    (cond_exec (lt:SI (reg:CC CC_REGNUM) (const_int 0))
56               (set (match_dup 0)
57                    (match_dup 2)))]
58   ""
59   [(set_attr "conds" "clob")
60    (set_attr "enabled_for_depr_it" "yes,yes,no")
61    (set_attr "length" "6,6,10")
62    (set_attr "type" "multiple")]
65 (define_insn_and_split "*thumb2_sminsi3"
66   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
67         (smin:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
68                  (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
69    (clobber (reg:CC CC_REGNUM))]
70   "TARGET_THUMB2"
71   "#"
72   ; cmp\\t%1, %2\;it\\tge\;movge\\t%0, %2
73   "TARGET_THUMB2 && reload_completed"
74   [(set (reg:CC CC_REGNUM)
75         (compare:CC (match_dup 1) (match_dup 2)))
76    (cond_exec (ge:SI (reg:CC CC_REGNUM) (const_int 0))
77               (set (match_dup 0)
78                    (match_dup 2)))]
79   ""
80   [(set_attr "conds" "clob")
81    (set_attr "enabled_for_depr_it" "yes,yes,no")
82    (set_attr "length" "6,6,10")
83    (set_attr "type" "multiple")]
86 (define_insn_and_split "*thumb32_umaxsi3"
87   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
88         (umax:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
89                  (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
90   (clobber (reg:CC CC_REGNUM))]
91   "TARGET_THUMB2"
92   "#"
93   ; cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %2
94   "TARGET_THUMB2 && reload_completed"
95   [(set (reg:CC CC_REGNUM)
96         (compare:CC (match_dup 1) (match_dup 2)))
97    (cond_exec (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
98               (set (match_dup 0)
99                    (match_dup 2)))]
100   ""
101   [(set_attr "conds" "clob")
102    (set_attr "length" "6,6,10")
103    (set_attr "enabled_for_depr_it" "yes,yes,no")
104    (set_attr "type" "multiple")]
107 (define_insn_and_split "*thumb2_uminsi3"
108   [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
109         (umin:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
110                  (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
111    (clobber (reg:CC CC_REGNUM))]
112   "TARGET_THUMB2"
113   "#"
114   ; cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %2
115   "TARGET_THUMB2 && reload_completed"
116   [(set (reg:CC CC_REGNUM)
117         (compare:CC (match_dup 1) (match_dup 2)))
118    (cond_exec (geu:SI (reg:CC CC_REGNUM) (const_int 0))
119               (set (match_dup 0)
120                    (match_dup 2)))]
121   ""
122   [(set_attr "conds" "clob")
123    (set_attr "length" "6,6,10")
124    (set_attr "enabled_for_depr_it" "yes,yes,no")
125    (set_attr "type" "multiple")]
128 ;; Thumb-2 does not have rsc, so use a clever trick with shifter operands.
129 (define_insn_and_split "*thumb2_negdi2"
130   [(set (match_operand:DI         0 "s_register_operand" "=&r,r")
131         (neg:DI (match_operand:DI 1 "s_register_operand"  "?r,0")))
132    (clobber (reg:CC CC_REGNUM))]
133   "TARGET_THUMB2"
134   "#" ; negs\\t%Q0, %Q1\;sbc\\t%R0, %R1, %R1, lsl #1
135   "&& reload_completed"
136   [(parallel [(set (reg:CC CC_REGNUM)
137                    (compare:CC (const_int 0) (match_dup 1)))
138               (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))])
139    (set (match_dup 2) (minus:SI (minus:SI (match_dup 3)
140                                           (ashift:SI (match_dup 3)
141                                                      (const_int 1)))
142                                 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))]
143   {
144     operands[2] = gen_highpart (SImode, operands[0]);
145     operands[0] = gen_lowpart (SImode, operands[0]);
146     operands[3] = gen_highpart (SImode, operands[1]);
147     operands[1] = gen_lowpart (SImode, operands[1]);
148   }
149   [(set_attr "conds" "clob")
150    (set_attr "length" "8")
151    (set_attr "type" "multiple")]
154 (define_insn_and_split "*thumb2_abssi2"
155   [(set (match_operand:SI         0 "s_register_operand" "=&r,l,r")
156         (abs:SI (match_operand:SI 1 "s_register_operand" "r,0,0")))
157    (clobber (reg:CC CC_REGNUM))]
158   "TARGET_THUMB2"
159   "#"
160    ; eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
161    ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
162    ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
163   "&& reload_completed"
164   [(const_int 0)]
165   {
166     if (REGNO(operands[0]) == REGNO(operands[1]))
167       {
168        rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
170        emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (CCmode, operands[0],
171                                                         const0_rtx)));
172        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
173                                     (gen_rtx_LT (SImode,
174                                                  cc_reg,
175                                                  const0_rtx)),
176                                     (gen_rtx_SET (operands[0],
177                                                   (gen_rtx_MINUS (SImode,
178                                                                   const0_rtx,
179                                                                   operands[1]))))));
180       }
181     else
182       {
183         emit_insn (gen_rtx_SET (operands[0],
184                                 gen_rtx_XOR (SImode,
185                                              gen_rtx_ASHIFTRT (SImode,
186                                                                operands[1],
187                                                                GEN_INT (31)),
188                                              operands[1])));
189         emit_insn (gen_rtx_SET (operands[0],
190                                 gen_rtx_MINUS (SImode,
191                                                operands[0],
192                                                gen_rtx_ASHIFTRT (SImode,
193                                                                  operands[1],
194                                                                  GEN_INT (31)))));
195       }
196     DONE;
197   }
198   [(set_attr "conds" "*,clob,clob")
199    (set_attr "shift" "1")
200    (set_attr "predicable" "yes,no,no")
201    (set_attr "predicable_short_it" "no")
202    (set_attr "enabled_for_depr_it" "yes,yes,no")
203    (set_attr "ce_count" "2")
204    (set_attr "length" "8,6,10")
205    (set_attr "type" "multiple")]
208 (define_insn_and_split "*thumb2_neg_abssi2"
209   [(set (match_operand:SI 0 "s_register_operand" "=&r,l,r")
210         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "r,0,0"))))
211    (clobber (reg:CC CC_REGNUM))]
212   "TARGET_THUMB2"
213   "#"
214    ; eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
215    ; cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
216    ; cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
217   "&& reload_completed"
218   [(const_int 0)]
219   {
220     if (REGNO(operands[0]) == REGNO(operands[1]))
221       {
222        rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
224        emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (CCmode, operands[0],
225                                                         const0_rtx)));
226        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
227                                     (gen_rtx_GT (SImode,
228                                                  cc_reg,
229                                                  const0_rtx)),
230                                     (gen_rtx_SET (operands[0],
231                                                   (gen_rtx_MINUS (SImode,
232                                                                   const0_rtx,
233                                                                   operands[1]))))));
234       }
235     else
236       {
237         emit_insn (gen_rtx_SET (operands[0],
238                                 gen_rtx_XOR (SImode,
239                                              gen_rtx_ASHIFTRT (SImode,
240                                                                operands[1],
241                                                                GEN_INT (31)),
242                                              operands[1])));
243         emit_insn (gen_rtx_SET (operands[0],
244                                 gen_rtx_MINUS (SImode,
245                                                gen_rtx_ASHIFTRT (SImode,
246                                                                  operands[1],
247                                                                  GEN_INT (31)),
248                                                operands[0])));
249       }
250     DONE;
251   }
252   [(set_attr "conds" "*,clob,clob")
253    (set_attr "shift" "1")
254    (set_attr "predicable" "yes,no,no")
255    (set_attr "enabled_for_depr_it" "yes,yes,no")
256    (set_attr "predicable_short_it" "no")
257    (set_attr "ce_count" "2")
258    (set_attr "length" "8,6,10")
259    (set_attr "type" "multiple")]
262 ;; Pop a single register as its size is preferred over a post-incremental load
263 (define_insn "*thumb2_pop_single"
264   [(set (match_operand:SI 0 "low_register_operand" "=r")
265         (mem:SI (post_inc:SI (reg:SI SP_REGNUM))))]
266   "TARGET_THUMB2 && (reload_in_progress || reload_completed)"
267   "pop\t{%0}"
268   [(set_attr "type" "load1")
269    (set_attr "length" "2")
270    (set_attr "predicable" "yes")]
273 ;; We have two alternatives here for memory loads (and similarly for stores)
274 ;; to reflect the fact that the permissible constant pool ranges differ
275 ;; between ldr instructions taking low regs and ldr instructions taking high
276 ;; regs.  The high register alternatives are not taken into account when
277 ;; choosing register preferences in order to reflect their expense.
278 (define_insn "*thumb2_movsi_insn"
279   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,l ,*hk,m,*m")
280         (match_operand:SI 1 "general_operand"      "rk,I,Py,K,j,mi,*mi,l,*hk"))]
281   "TARGET_THUMB2 && ! TARGET_IWMMXT
282    && !(TARGET_HARD_FLOAT && TARGET_VFP)
283    && (   register_operand (operands[0], SImode)
284        || register_operand (operands[1], SImode))"
285   "@
286    mov%?\\t%0, %1
287    mov%?\\t%0, %1
288    mov%?\\t%0, %1
289    mvn%?\\t%0, #%B1
290    movw%?\\t%0, %1
291    ldr%?\\t%0, %1
292    ldr%?\\t%0, %1
293    str%?\\t%1, %0
294    str%?\\t%1, %0"
295   [(set_attr "type" "mov_reg,mov_imm,mov_imm,mvn_imm,mov_imm,load1,load1,store1,store1")
296    (set_attr "length" "2,4,2,4,4,4,4,4,4")
297    (set_attr "predicable" "yes")
298    (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no,no,no")
299    (set_attr "pool_range" "*,*,*,*,*,1018,4094,*,*")
300    (set_attr "neg_pool_range" "*,*,*,*,*,0,0,*,*")]
303 (define_insn "tls_load_dot_plus_four"
304   [(set (match_operand:SI 0 "register_operand" "=l,l,r,r")
305         (mem:SI (unspec:SI [(match_operand:SI 2 "register_operand" "0,1,0,1")
306                             (const_int 4)
307                             (match_operand 3 "" "")]
308                            UNSPEC_PIC_BASE)))
309    (clobber (match_scratch:SI 1 "=X,l,X,r"))]
310   "TARGET_THUMB2"
311   "*
312   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
313                              INTVAL (operands[3]));
314   return \"add\\t%2, %|pc\;ldr%?\\t%0, [%2]\";
315   "
316   [(set_attr "length" "4,4,6,6")
317    (set_attr "type" "multiple")]
320 ;; Thumb-2 always has load/store halfword instructions, so we can avoid a lot
321 ;; of the messiness associated with the ARM patterns.
322 (define_insn "*thumb2_movhi_insn"
323   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,l,r,m,r")
324         (match_operand:HI 1 "general_operand"      "rk,I,Py,n,r,m"))]
325   "TARGET_THUMB2
326   && (register_operand (operands[0], HImode)
327      || register_operand (operands[1], HImode))"
328   "@
329    mov%?\\t%0, %1\\t%@ movhi
330    mov%?\\t%0, %1\\t%@ movhi
331    mov%?\\t%0, %1\\t%@ movhi
332    movw%?\\t%0, %L1\\t%@ movhi
333    str%(h%)\\t%1, %0\\t%@ movhi
334    ldr%(h%)\\t%0, %1\\t%@ movhi"
335   [(set_attr "type" "mov_reg,mov_imm,mov_imm,mov_imm,store1,load1")
336    (set_attr "predicable" "yes")
337    (set_attr "predicable_short_it" "yes,no,yes,no,no,no")
338    (set_attr "length" "2,4,2,4,4,4")
339    (set_attr "pool_range" "*,*,*,*,*,4094")
340    (set_attr "neg_pool_range" "*,*,*,*,*,250")]
343 (define_insn "*thumb2_storewb_pairsi"
344   [(set (match_operand:SI 0 "register_operand" "=&kr")
345         (plus:SI (match_operand:SI 1 "register_operand" "0")
346                  (match_operand:SI 2 "const_int_operand" "n")))
347    (set (mem:SI (plus:SI (match_dup 0) (match_dup 2)))
348         (match_operand:SI 3 "register_operand" "r"))
349    (set (mem:SI (plus:SI (match_dup 0)
350                          (match_operand:SI 5 "const_int_operand" "n")))
351         (match_operand:SI 4 "register_operand" "r"))]
352   "TARGET_THUMB2
353    && INTVAL (operands[5]) == INTVAL (operands[2]) + 4"
354   "strd\\t%3, %4, [%0, %2]!"
355   [(set_attr "type" "store2")]
358 (define_insn "*thumb2_cmpsi_neg_shiftsi"
359   [(set (reg:CC CC_REGNUM)
360         (compare:CC (match_operand:SI 0 "s_register_operand" "r")
361                     (neg:SI (match_operator:SI 3 "shift_operator"
362                              [(match_operand:SI 1 "s_register_operand" "r")
363                               (match_operand:SI 2 "const_int_operand" "M")]))))]
364   "TARGET_THUMB2"
365   "cmn%?\\t%0, %1%S3"
366   [(set_attr "conds" "set")
367    (set_attr "shift" "1")
368    (set_attr "type" "alus_shift_imm")]
371 (define_insn_and_split "*thumb2_mov_scc"
372   [(set (match_operand:SI 0 "s_register_operand" "=l,r")
373         (match_operator:SI 1 "arm_comparison_operator"
374          [(match_operand 2 "cc_register" "") (const_int 0)]))]
375   "TARGET_THUMB2"
376   "#"   ; "ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
377   "TARGET_THUMB2"
378   [(set (match_dup 0)
379         (if_then_else:SI (match_dup 1)
380                          (const_int 1)
381                          (const_int 0)))]
382   ""
383   [(set_attr "conds" "use")
384    (set_attr "enabled_for_depr_it" "yes,no")
385    (set_attr "length" "8,10")
386    (set_attr "type" "multiple")]
389 (define_insn_and_split "*thumb2_mov_negscc"
390   [(set (match_operand:SI 0 "s_register_operand" "=r")
391         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
392                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
393   "TARGET_THUMB2 && !arm_restrict_it"
394   "#"   ; "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
395   "TARGET_THUMB2"
396   [(set (match_dup 0)
397         (if_then_else:SI (match_dup 1)
398                          (match_dup 3)
399                          (const_int 0)))]
400   {
401     operands[3] = GEN_INT (~0);
402   }
403   [(set_attr "conds" "use")
404    (set_attr "length" "10")
405    (set_attr "type" "multiple")]
408 (define_insn_and_split "*thumb2_mov_negscc_strict_it"
409   [(set (match_operand:SI 0 "low_register_operand" "=l")
410         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
411                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
412   "TARGET_THUMB2 && arm_restrict_it"
413   "#"   ; ";mvn\\t%0, #0 ;it\\t%D1\;mov%D1\\t%0, #0\"
414   "&& reload_completed"
415   [(set (match_dup 0)
416         (match_dup 3))
417    (cond_exec (match_dup 4)
418               (set (match_dup 0)
419                    (const_int 0)))]
420   {
421     operands[3] = GEN_INT (~0);
422     machine_mode mode = GET_MODE (operands[2]);
423     enum rtx_code rc = GET_CODE (operands[1]);
425     if (mode == CCFPmode || mode == CCFPEmode)
426       rc = reverse_condition_maybe_unordered (rc);
427     else
428       rc = reverse_condition (rc);
429     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
431   }
432   [(set_attr "conds" "use")
433    (set_attr "length" "8")
434    (set_attr "type" "multiple")]
437 (define_insn_and_split "*thumb2_mov_notscc"
438   [(set (match_operand:SI 0 "s_register_operand" "=r")
439         (not:SI (match_operator:SI 1 "arm_comparison_operator"
440                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
441   "TARGET_THUMB2 && !arm_restrict_it"
442   "#"   ; "ite\\t%D1\;mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
443   "TARGET_THUMB2"
444   [(set (match_dup 0)
445         (if_then_else:SI (match_dup 1)
446                          (match_dup 3)
447                          (match_dup 4)))]
448   {
449     operands[3] = GEN_INT (~1);
450     operands[4] = GEN_INT (~0);
451   }
452   [(set_attr "conds" "use")
453    (set_attr "length" "10")
454    (set_attr "type" "multiple")]
457 (define_insn_and_split "*thumb2_mov_notscc_strict_it"
458   [(set (match_operand:SI 0 "low_register_operand" "=l")
459         (not:SI (match_operator:SI 1 "arm_comparison_operator"
460                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
461   "TARGET_THUMB2 && arm_restrict_it"
462   "#"   ; "mvn %0, #0 ; it%d1 ; lsl%d1 %0, %0, #1"
463   "&& reload_completed"
464   [(set (match_dup 0)
465         (match_dup 3))
466    (cond_exec (match_dup 4)
467               (set (match_dup 0)
468                    (ashift:SI (match_dup 0)
469                               (const_int 1))))]
470   {
471     operands[3] = GEN_INT (~0);
472     operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
473                                   VOIDmode, operands[2], const0_rtx);
474   }
475   [(set_attr "conds" "use")
476    (set_attr "length" "8")
477    (set_attr "type" "multiple")]
480 (define_insn_and_split "*thumb2_movsicc_insn"
481   [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r,r,r,r,r,r,r,r,r")
482         (if_then_else:SI
483          (match_operator 3 "arm_comparison_operator"
484           [(match_operand 4 "cc_register" "") (const_int 0)])
485          (match_operand:SI 1 "arm_not_operand" "0 ,lPy,0 ,0,rI,K,I ,r,rI,K ,K,r")
486          (match_operand:SI 2 "arm_not_operand" "lPy,0 ,rI,K,0 ,0,rI,I,K ,rI,K,r")))]
487   "TARGET_THUMB2"
488   "@
489    it\\t%D3\;mov%D3\\t%0, %2
490    it\\t%d3\;mov%d3\\t%0, %1
491    it\\t%D3\;mov%D3\\t%0, %2
492    it\\t%D3\;mvn%D3\\t%0, #%B2
493    it\\t%d3\;mov%d3\\t%0, %1
494    it\\t%d3\;mvn%d3\\t%0, #%B1
495    #
496    #
497    #
498    #
499    #
500    #"
501    ; alt 6: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
502    ; alt 7: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
503    ; alt 8: ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
504    ; alt 9: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
505    ; alt 10: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2
506    ; alt 11: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
507   "&& reload_completed"
508   [(const_int 0)]
509   {
510     enum rtx_code rev_code;
511     machine_mode mode;
512     rtx rev_cond;
514     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
515                                   operands[3],
516                                   gen_rtx_SET (operands[0], operands[1])));
517     rev_code = GET_CODE (operands[3]);
518     mode = GET_MODE (operands[4]);
519     if (mode == CCFPmode || mode == CCFPEmode)
520       rev_code = reverse_condition_maybe_unordered (rev_code);
521     else
522       rev_code = reverse_condition (rev_code);
524     rev_cond = gen_rtx_fmt_ee (rev_code,
525                                VOIDmode,
526                                gen_rtx_REG (mode, CC_REGNUM),
527                                const0_rtx);
528     emit_insn (gen_rtx_COND_EXEC (VOIDmode,
529                                   rev_cond,
530                                   gen_rtx_SET (operands[0], operands[2])));
531     DONE;
532   }
533   [(set_attr "length" "4,4,6,6,6,6,10,8,10,10,10,6")
534    (set_attr "enabled_for_depr_it" "yes,yes,no,no,no,no,no,no,no,no,no,yes")
535    (set_attr "conds" "use")
536    (set_attr_alternative "type"
537                          [(if_then_else (match_operand 2 "const_int_operand" "")
538                                         (const_string "mov_imm")
539                                         (const_string "mov_reg"))
540                           (if_then_else (match_operand 1 "const_int_operand" "")
541                                         (const_string "mov_imm")
542                                         (const_string "mov_reg"))
543                           (if_then_else (match_operand 2 "const_int_operand" "")
544                                         (const_string "mov_imm")
545                                         (const_string "mov_reg"))
546                           (const_string "mvn_imm")
547                           (if_then_else (match_operand 1 "const_int_operand" "")
548                                         (const_string "mov_imm")
549                                         (const_string "mov_reg"))
550                           (const_string "mvn_imm")
551                           (const_string "multiple")
552                           (const_string "multiple")
553                           (const_string "multiple")
554                           (const_string "multiple")
555                           (const_string "multiple")
556                           (const_string "multiple")])]
559 (define_insn "*thumb2_movsfcc_soft_insn"
560   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
561         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
562                           [(match_operand 4 "cc_register" "") (const_int 0)])
563                          (match_operand:SF 1 "s_register_operand" "0,r")
564                          (match_operand:SF 2 "s_register_operand" "r,0")))]
565   "TARGET_THUMB2 && TARGET_SOFT_FLOAT"
566   "@
567    it\\t%D3\;mov%D3\\t%0, %2
568    it\\t%d3\;mov%d3\\t%0, %1"
569   [(set_attr "length" "6,6")
570    (set_attr "conds" "use")
571    (set_attr "type" "multiple")]
574 (define_insn "*call_reg_thumb2"
575   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
576          (match_operand 1 "" ""))
577    (use (match_operand 2 "" ""))
578    (clobber (reg:SI LR_REGNUM))]
579   "TARGET_THUMB2"
580   "blx%?\\t%0"
581   [(set_attr "type" "call")]
584 (define_insn "*call_value_reg_thumb2"
585   [(set (match_operand 0 "" "")
586         (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
587               (match_operand 2 "" "")))
588    (use (match_operand 3 "" ""))
589    (clobber (reg:SI LR_REGNUM))]
590   "TARGET_THUMB2"
591   "blx\\t%1"
592   [(set_attr "type" "call")]
595 (define_insn "*thumb2_indirect_jump"
596   [(set (pc)
597         (match_operand:SI 0 "register_operand" "l*r"))]
598   "TARGET_THUMB2"
599   "bx\\t%0"
600   [(set_attr "conds" "clob")
601    (set_attr "type" "branch")]
603 ;; Don't define thumb2_load_indirect_jump because we can't guarantee label
604 ;; addresses will have the thumb bit set correctly.
607 (define_insn_and_split "*thumb2_and_scc"
608   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
609         (and:SI (match_operator:SI 1 "arm_comparison_operator"
610                  [(match_operand 2 "cc_register" "") (const_int 0)])
611                 (match_operand:SI 3 "s_register_operand" "r")))]
612   "TARGET_THUMB2"
613   "#"   ; "and\\t%0, %3, #1\;it\\t%D1\;mov%D1\\t%0, #0"
614   "&& reload_completed"
615   [(set (match_dup 0)
616         (and:SI (match_dup 3) (const_int 1)))
617    (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))]
618   {
619     machine_mode mode = GET_MODE (operands[2]);
620     enum rtx_code rc = GET_CODE (operands[1]);
622     if (mode == CCFPmode || mode == CCFPEmode)
623       rc = reverse_condition_maybe_unordered (rc);
624     else
625       rc = reverse_condition (rc);
626     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
627   }
628   [(set_attr "conds" "use")
629    (set_attr "type" "multiple")
630    (set (attr "length") (if_then_else (match_test "arm_restrict_it")
631                                       (const_int 8)
632                                       (const_int 10)))]
635 (define_insn_and_split "*thumb2_ior_scc"
636   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
637         (ior:SI (match_operator:SI 1 "arm_comparison_operator"
638                  [(match_operand 2 "cc_register" "") (const_int 0)])
639                 (match_operand:SI 3 "s_register_operand" "0,?r")))]
640   "TARGET_THUMB2 && !arm_restrict_it"
641   "@
642    it\\t%d1\;orr%d1\\t%0, %3, #1
643    #"
644    ; alt 1: ite\\t%D1\;mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
645    "&& reload_completed
646     && REGNO (operands [0]) != REGNO (operands[3])"
647    [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
648     (cond_exec (match_dup 4) (set (match_dup 0)
649                                   (ior:SI (match_dup 3) (const_int 1))))]
650   {
651     machine_mode mode = GET_MODE (operands[2]);
652     enum rtx_code rc = GET_CODE (operands[1]);
654     operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
655     if (mode == CCFPmode || mode == CCFPEmode)
656       rc = reverse_condition_maybe_unordered (rc);
657     else
658       rc = reverse_condition (rc);
659     operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
660   }
661   [(set_attr "conds" "use")
662    (set_attr "length" "6,10")
663    (set_attr "type" "multiple")]
666 (define_insn "*thumb2_ior_scc_strict_it"
667   [(set (match_operand:SI 0 "s_register_operand" "=l,l")
668         (ior:SI (match_operator:SI 2 "arm_comparison_operator"
669                  [(match_operand 3 "cc_register" "") (const_int 0)])
670                 (match_operand:SI 1 "s_register_operand" "0,?l")))]
671   "TARGET_THUMB2 && arm_restrict_it"
672   "@
673    it\\t%d2\;mov%d2\\t%0, #1\;it\\t%d2\;orr%d2\\t%0, %1
674    mov\\t%0, #1\;orr\\t%0, %1\;it\\t%D2\;mov%D2\\t%0, %1"
675   [(set_attr "conds" "use")
676    (set_attr "length" "8")
677    (set_attr "type" "multiple")]
680 (define_insn "*thumb2_cond_move"
681   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
682         (if_then_else:SI (match_operator 3 "equality_operator"
683                           [(match_operator 4 "arm_comparison_operator"
684                             [(match_operand 5 "cc_register" "") (const_int 0)])
685                            (const_int 0)])
686                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
687                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
688   "TARGET_THUMB2"
689   "*
690     if (GET_CODE (operands[3]) == NE)
691       {
692         if (which_alternative != 1)
693           output_asm_insn (\"it\\t%D4\;mov%D4\\t%0, %2\", operands);
694         if (which_alternative != 0)
695           output_asm_insn (\"it\\t%d4\;mov%d4\\t%0, %1\", operands);
696         return \"\";
697       }
698     switch (which_alternative)
699       {
700       case 0:
701         output_asm_insn (\"it\\t%d4\", operands);
702         break;
703       case 1:
704         output_asm_insn (\"it\\t%D4\", operands);
705         break;
706       case 2:
707         if (arm_restrict_it)
708           output_asm_insn (\"it\\t%D4\", operands);
709         else
710           output_asm_insn (\"ite\\t%D4\", operands);
711         break;
712       default:
713         abort();
714       }
715     if (which_alternative != 0)
716       {
717         output_asm_insn (\"mov%D4\\t%0, %1\", operands);
718         if (arm_restrict_it && which_alternative == 2)
719           output_asm_insn (\"it\\t%d4\", operands);
720       }
721     if (which_alternative != 1)
722       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
723     return \"\";
724   "
725   [(set_attr "conds" "use")
726    (set_attr "length" "6,6,10")
727    (set_attr "type" "multiple")]
730 (define_insn "*thumb2_cond_arith"
731   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
732         (match_operator:SI 5 "shiftable_operator"
733          [(match_operator:SI 4 "arm_comparison_operator"
734            [(match_operand:SI 2 "s_register_operand" "r,r")
735             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
736           (match_operand:SI 1 "s_register_operand" "0,?r")]))
737    (clobber (reg:CC CC_REGNUM))]
738   "TARGET_THUMB2 && !arm_restrict_it"
739   "*
740     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
741       return \"%i5\\t%0, %1, %2, lsr #31\";
743     output_asm_insn (\"cmp\\t%2, %3\", operands);
744     if (GET_CODE (operands[5]) == AND)
745       {
746         output_asm_insn (\"ite\\t%D4\", operands);
747         output_asm_insn (\"mov%D4\\t%0, #0\", operands);
748       }
749     else if (GET_CODE (operands[5]) == MINUS)
750       {
751         output_asm_insn (\"ite\\t%D4\", operands);
752         output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
753       }
754     else if (which_alternative != 0)
755       {
756         output_asm_insn (\"ite\\t%D4\", operands);
757         output_asm_insn (\"mov%D4\\t%0, %1\", operands);
758       }
759     else
760       output_asm_insn (\"it\\t%d4\", operands);
761     return \"%i5%d4\\t%0, %1, #1\";
762   "
763   [(set_attr "conds" "clob")
764    (set_attr "length" "14")
765    (set_attr "type" "multiple")]
768 (define_insn_and_split "*thumb2_cond_arith_strict_it"
769   [(set (match_operand:SI 0 "s_register_operand" "=l")
770         (match_operator:SI 5 "shiftable_operator_strict_it"
771          [(match_operator:SI 4 "arm_comparison_operator"
772            [(match_operand:SI 2 "s_register_operand" "r")
773             (match_operand:SI 3 "arm_rhs_operand" "rI")])
774           (match_operand:SI 1 "s_register_operand" "0")]))
775    (clobber (reg:CC CC_REGNUM))]
776   "TARGET_THUMB2 && arm_restrict_it"
777   "#"
778   "&& reload_completed"
779   [(const_int 0)]
780   {
781     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
782       {
783         /*  %i5 %0, %1, %2, lsr #31  */
784         rtx shifted_op = gen_rtx_LSHIFTRT (SImode, operands[2], GEN_INT (31));
785         rtx op = NULL_RTX;
787         switch (GET_CODE (operands[5]))
788           {
789           case AND:
790             op = gen_rtx_AND (SImode, shifted_op, operands[1]);
791             break;
792            case PLUS:
793             op = gen_rtx_PLUS (SImode, shifted_op, operands[1]);
794             break;
795           default: gcc_unreachable ();
796           }
797         emit_insn (gen_rtx_SET (operands[0], op));
798         DONE;
799       }
801     /*  "cmp  %2, %3"  */
802     emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
803                             gen_rtx_COMPARE (CCmode, operands[2],
804                                              operands[3])));
806     if (GET_CODE (operands[5]) == AND)
807       {
808         /*  %i5  %0, %1, #1
809             it%D4
810             mov%D4  %0, #0  */
811         enum rtx_code rc = reverse_condition (GET_CODE (operands[4]));
812         emit_insn (gen_rtx_SET (operands[0], gen_rtx_AND (SImode, operands[1],
813                                                           GEN_INT (1))));
814         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
815                                       gen_rtx_fmt_ee (rc, VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx),
816                                       gen_rtx_SET (operands[0], const0_rtx)));
817         DONE;
818       }
819     else
820       {
821         /*  it\\t%d4
822             %i5%d4\\t%0, %1, #1   */
823         emit_insn (gen_rtx_COND_EXEC (VOIDmode, gen_rtx_fmt_ee (GET_CODE (operands[4]),
824                                                                 VOIDmode,
825                                                                 gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx),
826                                                 gen_rtx_SET (operands[0],
827                                                             gen_rtx_PLUS (SImode,
828                                                                           operands[1],
829                                                                           GEN_INT (1)))));
830         DONE;
831       }
832      FAIL;
833   }
834   [(set_attr "conds" "clob")
835    (set_attr "length" "12")
836    (set_attr "type" "multiple")]
839 (define_insn "*thumb2_cond_sub"
840   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
841         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?Ts")
842                   (match_operator:SI 4 "arm_comparison_operator"
843                    [(match_operand:SI 2 "s_register_operand" "r,r")
844                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
845    (clobber (reg:CC CC_REGNUM))]
846   "TARGET_THUMB2"
847   "*
848     output_asm_insn (\"cmp\\t%2, %3\", operands);
849     if (which_alternative != 0)
850       {
851         if (arm_restrict_it)
852           {
853             output_asm_insn (\"mov\\t%0, %1\", operands);
854             output_asm_insn (\"it\\t%d4\", operands);
855           }
856         else
857         {
858           output_asm_insn (\"ite\\t%D4\", operands);
859           output_asm_insn (\"mov%D4\\t%0, %1\", operands);
860         }
861       }
862     else
863       output_asm_insn (\"it\\t%d4\", operands);
864     return \"sub%d4\\t%0, %1, #1\";
865   "
866   [(set_attr "conds" "clob")
867    (set_attr "length" "10,14")
868    (set_attr "type" "multiple")]
871 (define_insn_and_split "*thumb2_negscc"
872   [(set (match_operand:SI 0 "s_register_operand" "=Ts")
873         (neg:SI (match_operator 3 "arm_comparison_operator"
874                  [(match_operand:SI 1 "s_register_operand" "r")
875                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
876    (clobber (reg:CC CC_REGNUM))]
877   "TARGET_THUMB2"
878   "#"
879   "&& reload_completed"
880   [(const_int 0)]
881   {
882     rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
884     if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
885       {
886         /* Emit asr\\t%0, %1, #31 */
887         emit_insn (gen_rtx_SET (operands[0],
888                                 gen_rtx_ASHIFTRT (SImode,
889                                                   operands[1],
890                                                   GEN_INT (31))));
891         DONE;
892       }
893     else if (GET_CODE (operands[3]) == NE && !arm_restrict_it)
894       {
895         /* Emit subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0 */
896         if (CONST_INT_P (operands[2]))
897           emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
898                                         GEN_INT (- INTVAL (operands[2]))));
899         else
900           emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
902         emit_insn (gen_rtx_COND_EXEC (VOIDmode,
903                                       gen_rtx_NE (SImode,
904                                                   cc_reg,
905                                                   const0_rtx),
906                                       gen_rtx_SET (operands[0],
907                                                    GEN_INT (~0))));
908         DONE;
909       }
910     else
911       {
912        /* Emit:  cmp\\t%1, %2\;mvn\\t%0, #0\;it\\t%D3\;mov%D3\\t%0, #0\;*/
913        enum rtx_code rc = reverse_condition (GET_CODE (operands[3]));
914        machine_mode mode = SELECT_CC_MODE (rc, operands[1], operands[2]);
915        rtx tmp1 = gen_rtx_REG (mode, CC_REGNUM);
917        emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (CCmode, operands[1],
918                                                         operands[2])));
920        emit_insn (gen_rtx_SET (operands[0], GEN_INT (~0)));
922        emit_insn (gen_rtx_COND_EXEC (VOIDmode,
923                                      gen_rtx_fmt_ee (rc,
924                                                      VOIDmode,
925                                                      tmp1,
926                                                      const0_rtx),
927                                      gen_rtx_SET (operands[0], const0_rtx)));
928        DONE;
929       }
930     FAIL;
931   }
932   [(set_attr "conds" "clob")
933    (set_attr "length" "14")
934    (set_attr "type" "multiple")]
937 (define_insn "*thumb2_movcond"
938   [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts")
939         (if_then_else:SI
940          (match_operator 5 "arm_comparison_operator"
941           [(match_operand:SI 3 "s_register_operand" "r,r,r")
942            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
943          (match_operand:SI 1 "arm_rhs_operand" "0,TsI,?TsI")
944          (match_operand:SI 2 "arm_rhs_operand" "TsI,0,TsI")))
945    (clobber (reg:CC CC_REGNUM))]
946   "TARGET_THUMB2"
947   "*
948   if (GET_CODE (operands[5]) == LT
949       && (operands[4] == const0_rtx))
950     {
951       if (which_alternative != 1 && REG_P (operands[1]))
952         {
953           if (operands[2] == const0_rtx)
954             return \"and\\t%0, %1, %3, asr #31\";
955           return \"ands\\t%0, %1, %3, asr #32\;it\\tcc\;movcc\\t%0, %2\";
956         }
957       else if (which_alternative != 0 && REG_P (operands[2]))
958         {
959           if (operands[1] == const0_rtx)
960             return \"bic\\t%0, %2, %3, asr #31\";
961           return \"bics\\t%0, %2, %3, asr #32\;it\\tcs\;movcs\\t%0, %1\";
962         }
963       /* The only case that falls through to here is when both ops 1 & 2
964          are constants.  */
965     }
967   if (GET_CODE (operands[5]) == GE
968       && (operands[4] == const0_rtx))
969     {
970       if (which_alternative != 1 && REG_P (operands[1]))
971         {
972           if (operands[2] == const0_rtx)
973             return \"bic\\t%0, %1, %3, asr #31\";
974           return \"bics\\t%0, %1, %3, asr #32\;it\\tcs\;movcs\\t%0, %2\";
975         }
976       else if (which_alternative != 0 && REG_P (operands[2]))
977         {
978           if (operands[1] == const0_rtx)
979             return \"and\\t%0, %2, %3, asr #31\";
980           return \"ands\\t%0, %2, %3, asr #32\;it\tcc\;movcc\\t%0, %1\";
981         }
982       /* The only case that falls through to here is when both ops 1 & 2
983          are constants.  */
984     }
985   if (CONST_INT_P (operands[4])
986       && !const_ok_for_arm (INTVAL (operands[4])))
987     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
988   else
989     output_asm_insn (\"cmp\\t%3, %4\", operands);
990   switch (which_alternative)
991     {
992     case 0:
993       output_asm_insn (\"it\\t%D5\", operands);
994       break;
995     case 1:
996       output_asm_insn (\"it\\t%d5\", operands);
997       break;
998     case 2:
999       if (arm_restrict_it)
1000         {
1001           output_asm_insn (\"mov\\t%0, %1\", operands);
1002           output_asm_insn (\"it\\t%D5\", operands);
1003         }
1004       else
1005         output_asm_insn (\"ite\\t%d5\", operands);
1006       break;
1007     default:
1008       abort();
1009     }
1010   if (which_alternative != 0 && !(arm_restrict_it && which_alternative == 2))
1011     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
1012   if (which_alternative != 1)
1013     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
1014   return \"\";
1015   "
1016   [(set_attr "conds" "clob")
1017    (set_attr "length" "10,10,14")
1018    (set_attr "type" "multiple")]
1021 ;; Zero and sign extension instructions.
1023 ;; All supported Thumb2 implementations are armv6, so only that case is
1024 ;; provided.
1025 (define_insn "*thumb2_extendqisi_v6"
1026   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1027         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1028   "TARGET_THUMB2 && arm_arch6"
1029   "@
1030    sxtb%?\\t%0, %1
1031    ldr%(sb%)\\t%0, %1"
1032   [(set_attr "type" "extend,load_byte")
1033    (set_attr "predicable" "yes")
1034    (set_attr "predicable_short_it" "no")
1035    (set_attr "pool_range" "*,4094")
1036    (set_attr "neg_pool_range" "*,250")]
1039 (define_insn "*thumb2_zero_extendhisi2_v6"
1040   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1041         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1042   "TARGET_THUMB2 && arm_arch6"
1043   "@
1044    uxth%?\\t%0, %1
1045    ldr%(h%)\\t%0, %1"
1046   [(set_attr "type" "extend,load_byte")
1047    (set_attr "predicable" "yes")
1048    (set_attr "predicable_short_it" "no")
1049    (set_attr "pool_range" "*,4094")
1050    (set_attr "neg_pool_range" "*,250")]
1053 (define_insn "thumb2_zero_extendqisi2_v6"
1054   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1055         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1056   "TARGET_THUMB2 && arm_arch6"
1057   "@
1058    uxtb%(%)\\t%0, %1
1059    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
1060   [(set_attr "type" "extend,load_byte")
1061    (set_attr "predicable" "yes")
1062    (set_attr "predicable_short_it" "no")
1063    (set_attr "pool_range" "*,4094")
1064    (set_attr "neg_pool_range" "*,250")]
1067 (define_insn "thumb2_casesi_internal"
1068   [(parallel [(set (pc)
1069                (if_then_else
1070                 (leu (match_operand:SI 0 "s_register_operand" "r")
1071                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
1072                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
1073                                  (label_ref (match_operand 2 "" ""))))
1074                 (label_ref (match_operand 3 "" ""))))
1075               (clobber (reg:CC CC_REGNUM))
1076               (clobber (match_scratch:SI 4 "=&r"))
1077               (use (label_ref (match_dup 2)))])]
1078   "TARGET_THUMB2 && !flag_pic"
1079   "* return thumb2_output_casesi(operands);"
1080   [(set_attr "conds" "clob")
1081    (set_attr "length" "16")
1082    (set_attr "type" "multiple")]
1085 (define_insn "thumb2_casesi_internal_pic"
1086   [(parallel [(set (pc)
1087                (if_then_else
1088                 (leu (match_operand:SI 0 "s_register_operand" "r")
1089                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
1090                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
1091                                  (label_ref (match_operand 2 "" ""))))
1092                 (label_ref (match_operand 3 "" ""))))
1093               (clobber (reg:CC CC_REGNUM))
1094               (clobber (match_scratch:SI 4 "=&r"))
1095               (clobber (match_scratch:SI 5 "=r"))
1096               (use (label_ref (match_dup 2)))])]
1097   "TARGET_THUMB2 && flag_pic"
1098   "* return thumb2_output_casesi(operands);"
1099   [(set_attr "conds" "clob")
1100    (set_attr "length" "20")
1101    (set_attr "type" "multiple")]
1104 (define_insn "*thumb2_return"
1105   [(simple_return)]
1106   "TARGET_THUMB2"
1107   "* return output_return_instruction (const_true_rtx, true, false, true);"
1108   [(set_attr "type" "branch")
1109    (set_attr "length" "4")]
1112 (define_insn_and_split "thumb2_eh_return"
1113   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
1114                     VUNSPEC_EH_RETURN)
1115    (clobber (match_scratch:SI 1 "=&r"))]
1116   "TARGET_THUMB2"
1117   "#"
1118   "&& reload_completed"
1119   [(const_int 0)]
1120   "
1121   {
1122     thumb_set_return_address (operands[0], operands[1]);
1123     DONE;
1124   }"
1127 (define_insn "*thumb2_alusi3_short"
1128   [(set (match_operand:SI          0 "s_register_operand" "=l")
1129         (match_operator:SI 3 "thumb_16bit_operator"
1130          [(match_operand:SI 1 "s_register_operand" "0")
1131           (match_operand:SI 2 "s_register_operand" "l")]))
1132    (clobber (reg:CC CC_REGNUM))]
1133   "TARGET_THUMB2 && reload_completed
1134    && GET_CODE(operands[3]) != PLUS
1135    && GET_CODE(operands[3]) != MINUS"
1136   "%I3%!\\t%0, %1, %2"
1137   [(set_attr "predicable" "yes")
1138    (set_attr "length" "2")
1139    (set_attr "type" "alu_sreg")]
1142 (define_insn "*thumb2_shiftsi3_short"
1143   [(set (match_operand:SI   0 "low_register_operand" "=l,l")
1144         (match_operator:SI  3 "shift_operator"
1145          [(match_operand:SI 1 "low_register_operand"  "0,l")
1146           (match_operand:SI 2 "low_reg_or_int_operand" "l,M")]))
1147    (clobber (reg:CC CC_REGNUM))]
1148   "TARGET_THUMB2 && reload_completed
1149    && ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
1150        || REG_P (operands[2]))"
1151   "* return arm_output_shift(operands, 2);"
1152   [(set_attr "predicable" "yes")
1153    (set_attr "shift" "1")
1154    (set_attr "length" "2")
1155    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
1156                       (const_string "alu_shift_imm")
1157                       (const_string "alu_shift_reg")))]
1160 (define_insn "*thumb2_mov<mode>_shortim"
1161   [(set (match_operand:QHSI 0 "low_register_operand" "=l")
1162         (match_operand:QHSI 1 "const_int_operand" "I"))
1163    (clobber (reg:CC CC_REGNUM))]
1164   "TARGET_THUMB2 && reload_completed"
1165   "mov%!\t%0, %1"
1166   [(set_attr "predicable" "yes")
1167    (set_attr "length" "2")
1168    (set_attr "type" "mov_imm")]
1171 (define_insn "*thumb2_addsi_short"
1172   [(set (match_operand:SI 0 "low_register_operand" "=l,l")
1173         (plus:SI (match_operand:SI 1 "low_register_operand" "l,0")
1174                  (match_operand:SI 2 "low_reg_or_int_operand" "lPt,Ps")))
1175    (clobber (reg:CC CC_REGNUM))]
1176   "TARGET_THUMB2 && reload_completed"
1177   "*
1178     HOST_WIDE_INT val;
1180     if (CONST_INT_P (operands[2]))
1181       val = INTVAL(operands[2]);
1182     else
1183       val = 0;
1185     /* We prefer eg. subs rn, rn, #1 over adds rn, rn, #0xffffffff.  */
1186     if (val < 0 && const_ok_for_arm(ARM_SIGN_EXTEND (-val)))
1187       return \"sub%!\\t%0, %1, #%n2\";
1188     else
1189       return \"add%!\\t%0, %1, %2\";
1190   "
1191   [(set_attr "predicable" "yes")
1192    (set_attr "length" "2")
1193    (set_attr_alternative "type"
1194                          [(if_then_else (match_operand 2 "const_int_operand" "")
1195                                         (const_string "alu_imm")
1196                                         (const_string "alu_sreg"))
1197                           (const_string "alu_imm")])]
1200 (define_insn "*thumb2_subsi_short"
1201   [(set (match_operand:SI 0 "low_register_operand" "=l")
1202         (minus:SI (match_operand:SI 1 "low_register_operand" "l")
1203                   (match_operand:SI 2 "low_register_operand" "l")))
1204    (clobber (reg:CC CC_REGNUM))]
1205   "TARGET_THUMB2 && reload_completed"
1206   "sub%!\\t%0, %1, %2"
1207   [(set_attr "predicable" "yes")
1208    (set_attr "length" "2")
1209    (set_attr "type" "alu_sreg")]
1212 (define_peephole2
1213   [(set (match_operand:CC 0 "cc_register" "")
1214         (compare:CC (match_operand:SI 1 "low_register_operand" "")
1215                     (match_operand:SI 2 "const_int_operand" "")))]
1216   "TARGET_THUMB2
1217    && peep2_reg_dead_p (1, operands[1])
1218    && satisfies_constraint_Pw (operands[2])"
1219   [(parallel
1220     [(set (match_dup 0) (compare:CC (match_dup 1) (match_dup 2)))
1221      (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 3)))])]
1222   "operands[3] = GEN_INT (- INTVAL (operands[2]));"
1225 (define_peephole2
1226   [(match_scratch:SI 3 "l")
1227    (set (match_operand:CC 0 "cc_register" "")
1228         (compare:CC (match_operand:SI 1 "low_register_operand" "")
1229                     (match_operand:SI 2 "const_int_operand" "")))]
1230   "TARGET_THUMB2
1231    && satisfies_constraint_Px (operands[2])"
1232   [(parallel
1233     [(set (match_dup 0) (compare:CC (match_dup 1) (match_dup 2)))
1234      (set (match_dup 3) (plus:SI (match_dup 1) (match_dup 4)))])]
1235   "operands[4] = GEN_INT (- INTVAL (operands[2]));"
1238 (define_insn "thumb2_addsi3_compare0"
1239   [(set (reg:CC_NOOV CC_REGNUM)
1240         (compare:CC_NOOV
1241           (plus:SI (match_operand:SI 1 "s_register_operand" "l,  0, r")
1242                    (match_operand:SI 2 "arm_add_operand"    "lPt,Ps,rIL"))
1243           (const_int 0)))
1244    (set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1245         (plus:SI (match_dup 1) (match_dup 2)))]
1246   "TARGET_THUMB2"
1247   "*
1248     HOST_WIDE_INT val;
1250     if (CONST_INT_P (operands[2]))
1251       val = INTVAL (operands[2]);
1252     else
1253       val = 0;
1255     if (val < 0 && const_ok_for_arm (ARM_SIGN_EXTEND (-val)))
1256       return \"subs\\t%0, %1, #%n2\";
1257     else
1258       return \"adds\\t%0, %1, %2\";
1259   "
1260   [(set_attr "conds" "set")
1261    (set_attr "length" "2,2,4")
1262    (set_attr_alternative "type"
1263                          [(if_then_else (match_operand 2 "const_int_operand" "")
1264                                         (const_string "alus_imm")
1265                                         (const_string "alus_sreg"))
1266                           (const_string "alus_imm")
1267                           (if_then_else (match_operand 2 "const_int_operand" "")
1268                                         (const_string "alus_imm")
1269                                         (const_string "alus_sreg"))])]
1272 (define_insn "*thumb2_addsi3_compare0_scratch"
1273   [(set (reg:CC_NOOV CC_REGNUM)
1274         (compare:CC_NOOV
1275           (plus:SI (match_operand:SI 0 "s_register_operand" "l,  r")
1276                    (match_operand:SI 1 "arm_add_operand"    "lPv,rIL"))
1277           (const_int 0)))]
1278   "TARGET_THUMB2"
1279   "*
1280     HOST_WIDE_INT val;
1282     if (CONST_INT_P (operands[1]))
1283       val = INTVAL (operands[1]);
1284     else
1285       val = 0;
1287     if (val < 0 && const_ok_for_arm (ARM_SIGN_EXTEND (-val)))
1288       return \"cmp\\t%0, #%n1\";
1289     else
1290       return \"cmn\\t%0, %1\";
1291   "
1292   [(set_attr "conds" "set")
1293    (set_attr "length" "2,4")
1294    (set (attr "type") (if_then_else (match_operand 1 "const_int_operand" "")
1295                                     (const_string "alus_imm")
1296                                     (const_string "alus_sreg")))]
1299 (define_insn "*thumb2_mulsi_short"
1300   [(set (match_operand:SI 0 "low_register_operand" "=l")
1301         (mult:SI (match_operand:SI 1 "low_register_operand" "%0")
1302                  (match_operand:SI 2 "low_register_operand" "l")))
1303    (clobber (reg:CC CC_REGNUM))]
1304   "TARGET_THUMB2 && optimize_size && reload_completed"
1305   "mul%!\\t%0, %2, %0"
1306   [(set_attr "predicable" "yes")
1307    (set_attr "length" "2")
1308    (set_attr "type" "muls")])
1310 (define_insn "*thumb2_mulsi_short_compare0"
1311   [(set (reg:CC_NOOV CC_REGNUM)
1312         (compare:CC_NOOV
1313          (mult:SI (match_operand:SI 1 "register_operand" "%0")
1314                   (match_operand:SI 2 "register_operand" "l"))
1315          (const_int 0)))
1316    (set (match_operand:SI 0 "register_operand" "=l")
1317         (mult:SI (match_dup 1) (match_dup 2)))]
1318   "TARGET_THUMB2 && optimize_size"
1319   "muls\\t%0, %2, %0"
1320   [(set_attr "length" "2")
1321    (set_attr "type" "muls")])
1323 (define_insn "*thumb2_mulsi_short_compare0_scratch"
1324   [(set (reg:CC_NOOV CC_REGNUM)
1325         (compare:CC_NOOV
1326          (mult:SI (match_operand:SI 1 "register_operand" "%0")
1327                   (match_operand:SI 2 "register_operand" "l"))
1328          (const_int 0)))
1329    (clobber (match_scratch:SI 0 "=l"))]
1330   "TARGET_THUMB2 && optimize_size"
1331   "muls\\t%0, %2, %0"
1332   [(set_attr "length" "2")
1333    (set_attr "type" "muls")])
1335 (define_insn "*thumb2_cbz"
1336   [(set (pc) (if_then_else
1337               (eq (match_operand:SI 0 "s_register_operand" "l,?r")
1338                   (const_int 0))
1339               (label_ref (match_operand 1 "" ""))
1340               (pc)))
1341    (clobber (reg:CC CC_REGNUM))]
1342   "TARGET_THUMB2"
1343   "*
1344   if (get_attr_length (insn) == 2)
1345     return \"cbz\\t%0, %l1\";
1346   else
1347     return \"cmp\\t%0, #0\;beq\\t%l1\";
1348   "
1349   [(set (attr "length")
1350         (if_then_else
1351             (and (ge (minus (match_dup 1) (pc)) (const_int 2))
1352                  (le (minus (match_dup 1) (pc)) (const_int 128))
1353                  (not (match_test "which_alternative")))
1354             (const_int 2)
1355             (const_int 8)))
1356    (set_attr "type" "branch,multiple")]
1359 (define_insn "*thumb2_cbnz"
1360   [(set (pc) (if_then_else
1361               (ne (match_operand:SI 0 "s_register_operand" "l,?r")
1362                   (const_int 0))
1363               (label_ref (match_operand 1 "" ""))
1364               (pc)))
1365    (clobber (reg:CC CC_REGNUM))]
1366   "TARGET_THUMB2"
1367   "*
1368   if (get_attr_length (insn) == 2)
1369     return \"cbnz\\t%0, %l1\";
1370   else
1371     return \"cmp\\t%0, #0\;bne\\t%l1\";
1372   "
1373   [(set (attr "length")
1374         (if_then_else
1375             (and (ge (minus (match_dup 1) (pc)) (const_int 2))
1376                  (le (minus (match_dup 1) (pc)) (const_int 128))
1377                  (not (match_test "which_alternative")))
1378             (const_int 2)
1379             (const_int 8)))
1380    (set_attr "type" "branch,multiple")]
1383 (define_insn "*thumb2_one_cmplsi2_short"
1384   [(set (match_operand:SI 0 "low_register_operand" "=l")
1385         (not:SI (match_operand:SI 1 "low_register_operand" "l")))
1386    (clobber (reg:CC CC_REGNUM))]
1387   "TARGET_THUMB2 && reload_completed"
1388   "mvn%!\t%0, %1"
1389   [(set_attr "predicable" "yes")
1390    (set_attr "length" "2")
1391    (set_attr "type" "mvn_reg")]
1394 (define_insn "*thumb2_negsi2_short"
1395   [(set (match_operand:SI 0 "low_register_operand" "=l")
1396         (neg:SI (match_operand:SI 1 "low_register_operand" "l")))
1397    (clobber (reg:CC CC_REGNUM))]
1398   "TARGET_THUMB2 && reload_completed"
1399   "neg%!\t%0, %1"
1400   [(set_attr "predicable" "yes")
1401    (set_attr "length" "2")
1402    (set_attr "type" "alu_sreg")]
1405 ; Constants for op 2 will never be given to these patterns.
1406 (define_insn_and_split "*iordi_notdi_di"
1407   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1408         (ior:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r"))
1409                 (match_operand:DI 2 "s_register_operand" "r,0")))]
1410   "TARGET_THUMB2"
1411   "#"
1412   "TARGET_THUMB2 && reload_completed"
1413   [(set (match_dup 0) (ior:SI (not:SI (match_dup 1)) (match_dup 2)))
1414    (set (match_dup 3) (ior:SI (not:SI (match_dup 4)) (match_dup 5)))]
1415   "
1416   {
1417     operands[3] = gen_highpart (SImode, operands[0]);
1418     operands[0] = gen_lowpart (SImode, operands[0]);
1419     operands[4] = gen_highpart (SImode, operands[1]);
1420     operands[1] = gen_lowpart (SImode, operands[1]);
1421     operands[5] = gen_highpart (SImode, operands[2]);
1422     operands[2] = gen_lowpart (SImode, operands[2]);
1423   }"
1424   [(set_attr "length" "8")
1425    (set_attr "predicable" "yes")
1426    (set_attr "predicable_short_it" "no")
1427    (set_attr "type" "multiple")]
1430 (define_insn_and_split "*iordi_notzesidi_di"
1431   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1432         (ior:DI (not:DI (zero_extend:DI
1433                          (match_operand:SI 2 "s_register_operand" "r,r")))
1434                 (match_operand:DI 1 "s_register_operand" "0,?r")))]
1435   "TARGET_THUMB2"
1436   "#"
1437   ; (not (zero_extend...)) means operand0 will always be 0xffffffff
1438   "TARGET_THUMB2 && reload_completed"
1439   [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
1440    (set (match_dup 3) (const_int -1))]
1441   "
1442   {
1443     operands[3] = gen_highpart (SImode, operands[0]);
1444     operands[0] = gen_lowpart (SImode, operands[0]);
1445     operands[1] = gen_lowpart (SImode, operands[1]);
1446   }"
1447   [(set_attr "length" "4,8")
1448    (set_attr "predicable" "yes")
1449    (set_attr "predicable_short_it" "no")
1450    (set_attr "type" "multiple")]
1453 (define_insn_and_split "*iordi_notdi_zesidi"
1454   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1455         (ior:DI (not:DI (match_operand:DI 2 "s_register_operand" "0,?r"))
1456                 (zero_extend:DI
1457                  (match_operand:SI 1 "s_register_operand" "r,r"))))]
1458   "TARGET_THUMB2"
1459   "#"
1460   "TARGET_THUMB2 && reload_completed"
1461   [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
1462    (set (match_dup 3) (not:SI (match_dup 4)))]
1463   "
1464   {
1465     operands[3] = gen_highpart (SImode, operands[0]);
1466     operands[0] = gen_lowpart (SImode, operands[0]);
1467     operands[1] = gen_lowpart (SImode, operands[1]);
1468     operands[4] = gen_highpart (SImode, operands[2]);
1469     operands[2] = gen_lowpart (SImode, operands[2]);
1470   }"
1471   [(set_attr "length" "8")
1472    (set_attr "predicable" "yes")
1473    (set_attr "predicable_short_it" "no")
1474    (set_attr "type" "multiple")]
1477 (define_insn_and_split "*iordi_notsesidi_di"
1478   [(set (match_operand:DI 0 "s_register_operand" "=&r,&r")
1479         (ior:DI (not:DI (sign_extend:DI
1480                          (match_operand:SI 2 "s_register_operand" "r,r")))
1481                 (match_operand:DI 1 "s_register_operand" "0,r")))]
1482   "TARGET_THUMB2"
1483   "#"
1484   "TARGET_THUMB2 && reload_completed"
1485   [(set (match_dup 0) (ior:SI (not:SI (match_dup 2)) (match_dup 1)))
1486    (set (match_dup 3) (ior:SI (not:SI
1487                                 (ashiftrt:SI (match_dup 2) (const_int 31)))
1488                                (match_dup 4)))]
1489   "
1490   {
1491     operands[3] = gen_highpart (SImode, operands[0]);
1492     operands[0] = gen_lowpart (SImode, operands[0]);
1493     operands[4] = gen_highpart (SImode, operands[1]);
1494     operands[1] = gen_lowpart (SImode, operands[1]);
1495   }"
1496   [(set_attr "length" "8")
1497    (set_attr "predicable" "yes")
1498    (set_attr "predicable_short_it" "no")
1499    (set_attr "type" "multiple")]
1502 (define_insn "*orsi_notsi_si"
1503   [(set (match_operand:SI 0 "s_register_operand" "=r")
1504         (ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1505                 (match_operand:SI 1 "s_register_operand" "r")))]
1506   "TARGET_THUMB2"
1507   "orn%?\\t%0, %1, %2"
1508   [(set_attr "predicable" "yes")
1509    (set_attr "predicable_short_it" "no")
1510    (set_attr "type" "logic_reg")]
1513 (define_insn "*orsi_not_shiftsi_si"
1514   [(set (match_operand:SI 0 "s_register_operand" "=r")
1515         (ior:SI (not:SI (match_operator:SI 4 "shift_operator"
1516                          [(match_operand:SI 2 "s_register_operand" "r")
1517                           (match_operand:SI 3 "const_int_operand" "M")]))
1518                 (match_operand:SI 1 "s_register_operand" "r")))]
1519   "TARGET_THUMB2"
1520   "orn%?\\t%0, %1, %2%S4"
1521   [(set_attr "predicable" "yes")
1522    (set_attr "predicable_short_it" "no")
1523    (set_attr "shift" "2")
1524    (set_attr "type" "alu_shift_imm")]
1527 (define_peephole2
1528   [(set (match_operand:CC_NOOV 0 "cc_register" "")
1529         (compare:CC_NOOV (zero_extract:SI
1530                           (match_operand:SI 1 "low_register_operand" "")
1531                           (const_int 1)
1532                           (match_operand:SI 2 "const_int_operand" ""))
1533                          (const_int 0)))
1534    (match_scratch:SI 3 "l")
1535    (set (pc)
1536         (if_then_else (match_operator:CC_NOOV 4 "equality_operator"
1537                        [(match_dup 0) (const_int 0)])
1538                       (match_operand 5 "" "")
1539                       (match_operand 6 "" "")))]
1540   "TARGET_THUMB2
1541    && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32)"
1542   [(parallel [(set (match_dup 0)
1543                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1544                                     (const_int 0)))
1545               (clobber (match_dup 3))])
1546    (set (pc)
1547         (if_then_else (match_op_dup 4 [(match_dup 0) (const_int 0)])
1548                       (match_dup 5) (match_dup 6)))]
1549   "
1550   operands[2] = GEN_INT (31 - INTVAL (operands[2]));
1551   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? LT : GE,
1552                                 VOIDmode, operands[0], const0_rtx);
1553   ")
1555 (define_peephole2
1556   [(set (match_operand:CC_NOOV 0 "cc_register" "")
1557         (compare:CC_NOOV (zero_extract:SI
1558                           (match_operand:SI 1 "low_register_operand" "")
1559                           (match_operand:SI 2 "const_int_operand" "")
1560                           (const_int 0))
1561                          (const_int 0)))
1562    (match_scratch:SI 3 "l")
1563    (set (pc)
1564         (if_then_else (match_operator:CC_NOOV 4 "equality_operator"
1565                        [(match_dup 0) (const_int 0)])
1566                       (match_operand 5 "" "")
1567                       (match_operand 6 "" "")))]
1568   "TARGET_THUMB2
1569    && (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 32)"
1570   [(parallel [(set (match_dup 0)
1571                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1572                                     (const_int 0)))
1573               (clobber (match_dup 3))])
1574    (set (pc)
1575         (if_then_else (match_op_dup 4 [(match_dup 0) (const_int 0)])
1576                       (match_dup 5) (match_dup 6)))]
1577   "
1578   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1579   ")
1581 ;; Define the subtract-one-and-jump insns so loop.c
1582 ;; knows what to generate.
1583 (define_expand "doloop_end"
1584   [(use (match_operand 0 "" ""))      ; loop pseudo
1585    (use (match_operand 1 "" ""))]     ; label
1586   "TARGET_32BIT"
1587   "
1589    /* Currently SMS relies on the do-loop pattern to recognize loops
1590       where (1) the control part consists of all insns defining and/or
1591       using a certain 'count' register and (2) the loop count can be
1592       adjusted by modifying this register prior to the loop.
1593       ??? The possible introduction of a new block to initialize the
1594       new IV can potentially affect branch optimizations.  */
1595    if (optimize > 0 && flag_modulo_sched)
1596    {
1597      rtx s0;
1598      rtx bcomp;
1599      rtx loc_ref;
1600      rtx cc_reg;
1601      rtx insn;
1602      rtx cmp;
1604      if (GET_MODE (operands[0]) != SImode)
1605        FAIL;
1607      s0 = operands [0];
1608      if (TARGET_THUMB2)
1609        insn = emit_insn (gen_thumb2_addsi3_compare0 (s0, s0, GEN_INT (-1)));
1610      else
1611        insn = emit_insn (gen_addsi3_compare0 (s0, s0, GEN_INT (-1)));
1613      cmp = XVECEXP (PATTERN (insn), 0, 0);
1614      cc_reg = SET_DEST (cmp);
1615      bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
1616      loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
1617      emit_jump_insn (gen_rtx_SET (pc_rtx,
1618                                   gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
1619                                                         loc_ref, pc_rtx)));
1620      DONE;
1621    }else
1622       FAIL;
1623  }")