Update Copyright years for files modified in 2010.
[official-gcc.git] / gcc / config / arm / thumb2.md
blob11caa61207026da11fa1ecc41f84211fc5a9ce8a
1 ;; ARM Thumb-2 Machine Description
2 ;; Copyright (C) 2007, 2008, 2010 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 (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")))]
32   "TARGET_THUMB2"
33   "@
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)])))]
45   "TARGET_THUMB2"
46   "@
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")))]
60   "TARGET_THUMB2"
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))]
72   "TARGET_THUMB2"
73   "@
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))]
86   "TARGET_THUMB2"
87   "@
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))]
100   "TARGET_THUMB2"
101   "@
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))]
114   "TARGET_THUMB2"
115   "@
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 ;; Thumb-2 does not have rsc, so use a clever trick with shifter operands.
124 (define_insn "*thumb2_negdi2"
125   [(set (match_operand:DI         0 "s_register_operand" "=&r,r")
126         (neg:DI (match_operand:DI 1 "s_register_operand"  "?r,0")))
127    (clobber (reg:CC CC_REGNUM))]
128   "TARGET_THUMB2"
129   "negs\\t%Q0, %Q1\;sbc\\t%R0, %R1, %R1, lsl #1"
130   [(set_attr "conds" "clob")
131    (set_attr "length" "8")]
134 (define_insn "*thumb2_abssi2"
135   [(set (match_operand:SI         0 "s_register_operand" "=r,&r")
136         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
137    (clobber (reg:CC CC_REGNUM))]
138   "TARGET_THUMB2"
139   "@
140    cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
141    eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
142   [(set_attr "conds" "clob,*")
143    (set_attr "shift" "1")
144    ;; predicable can't be set based on the variant, so left as no
145    (set_attr "length" "10,8")]
148 (define_insn "*thumb2_neg_abssi2"
149   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
150         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
151    (clobber (reg:CC CC_REGNUM))]
152   "TARGET_THUMB2"
153   "@
154    cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
155    eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
156   [(set_attr "conds" "clob,*")
157    (set_attr "shift" "1")
158    ;; predicable can't be set based on the variant, so left as no
159    (set_attr "length" "10,8")]
162 ;; We have two alternatives here for memory loads (and similarly for stores)
163 ;; to reflect the fact that the permissible constant pool ranges differ
164 ;; between ldr instructions taking low regs and ldr instructions taking high
165 ;; regs.  The high register alternatives are not taken into account when
166 ;; choosing register preferences in order to reflect their expense.
167 (define_insn "*thumb2_movsi_insn"
168   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,l ,*hk,m,*m")
169         (match_operand:SI 1 "general_operand"      "rk ,I,K,j,mi,*mi,l,*hk"))]
170   "TARGET_THUMB2 && ! TARGET_IWMMXT
171    && !(TARGET_HARD_FLOAT && TARGET_VFP)
172    && (   register_operand (operands[0], SImode)
173        || register_operand (operands[1], SImode))"
174   "@
175    mov%?\\t%0, %1
176    mov%?\\t%0, %1
177    mvn%?\\t%0, #%B1
178    movw%?\\t%0, %1
179    ldr%?\\t%0, %1
180    ldr%?\\t%0, %1
181    str%?\\t%1, %0
182    str%?\\t%1, %0"
183   [(set_attr "type" "*,*,*,*,load1,load1,store1,store1")
184    (set_attr "predicable" "yes")
185    (set_attr "pool_range" "*,*,*,*,1020,4096,*,*")
186    (set_attr "neg_pool_range" "*,*,*,*,0,0,*,*")]
189 (define_insn "tls_load_dot_plus_four"
190   [(set (match_operand:SI 0 "register_operand" "=l,l,r,r")
191         (mem:SI (unspec:SI [(match_operand:SI 2 "register_operand" "0,1,0,1")
192                             (const_int 4)
193                             (match_operand 3 "" "")]
194                            UNSPEC_PIC_BASE)))
195    (clobber (match_scratch:SI 1 "=X,l,X,r"))]
196   "TARGET_THUMB2"
197   "*
198   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
199                              INTVAL (operands[3]));
200   return \"add\\t%2, %|pc\;ldr%?\\t%0, [%2]\";
201   "
202   [(set_attr "length" "4,4,6,6")]
205 ;; Thumb-2 always has load/store halfword instructions, so we can avoid a lot
206 ;; of the messiness associated with the ARM patterns.
207 (define_insn "*thumb2_movhi_insn"
208   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")
209         (match_operand:HI 1 "general_operand"      "rI,n,r,m"))]
210   "TARGET_THUMB2"
211   "@
212    mov%?\\t%0, %1\\t%@ movhi
213    movw%?\\t%0, %L1\\t%@ movhi
214    str%(h%)\\t%1, %0\\t%@ movhi
215    ldr%(h%)\\t%0, %1\\t%@ movhi"
216   [(set_attr "type" "*,*,store1,load1")
217    (set_attr "predicable" "yes")
218    (set_attr "pool_range" "*,*,*,4096")
219    (set_attr "neg_pool_range" "*,*,*,250")]
222 (define_insn "*thumb2_cmpsi_neg_shiftsi"
223   [(set (reg:CC CC_REGNUM)
224         (compare:CC (match_operand:SI 0 "s_register_operand" "r")
225                     (neg:SI (match_operator:SI 3 "shift_operator"
226                              [(match_operand:SI 1 "s_register_operand" "r")
227                               (match_operand:SI 2 "const_int_operand" "M")]))))]
228   "TARGET_THUMB2"
229   "cmn%?\\t%0, %1%S3"
230   [(set_attr "conds" "set")
231    (set_attr "shift" "1")
232    (set_attr "type" "alu_shift")]
235 (define_insn "*thumb2_mov_scc"
236   [(set (match_operand:SI 0 "s_register_operand" "=r")
237         (match_operator:SI 1 "arm_comparison_operator"
238          [(match_operand 2 "cc_register" "") (const_int 0)]))]
239   "TARGET_THUMB2"
240   "ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
241   [(set_attr "conds" "use")
242    (set_attr "length" "10")]
245 (define_insn "*thumb2_mov_negscc"
246   [(set (match_operand:SI 0 "s_register_operand" "=r")
247         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
248                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
249   "TARGET_THUMB2"
250   "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
251   [(set_attr "conds" "use")
252    (set_attr "length" "10")]
255 (define_insn "*thumb2_mov_notscc"
256   [(set (match_operand:SI 0 "s_register_operand" "=r")
257         (not:SI (match_operator:SI 1 "arm_comparison_operator"
258                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
259   "TARGET_THUMB2"
260   "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
261   [(set_attr "conds" "use")
262    (set_attr "length" "10")]
265 (define_insn "*thumb2_movsicc_insn"
266   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
267         (if_then_else:SI
268          (match_operator 3 "arm_comparison_operator"
269           [(match_operand 4 "cc_register" "") (const_int 0)])
270          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
271          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
272   "TARGET_THUMB2"
273   "@
274    it\\t%D3\;mov%D3\\t%0, %2
275    it\\t%D3\;mvn%D3\\t%0, #%B2
276    it\\t%d3\;mov%d3\\t%0, %1
277    it\\t%d3\;mvn%d3\\t%0, #%B1
278    ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
279    ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
280    ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
281    ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
282   [(set_attr "length" "6,6,6,6,10,10,10,10")
283    (set_attr "conds" "use")]
286 (define_insn "*thumb2_movsfcc_soft_insn"
287   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
288         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
289                           [(match_operand 4 "cc_register" "") (const_int 0)])
290                          (match_operand:SF 1 "s_register_operand" "0,r")
291                          (match_operand:SF 2 "s_register_operand" "r,0")))]
292   "TARGET_THUMB2 && TARGET_SOFT_FLOAT"
293   "@
294    it\\t%D3\;mov%D3\\t%0, %2
295    it\\t%d3\;mov%d3\\t%0, %1"
296   [(set_attr "length" "6,6")
297    (set_attr "conds" "use")]
300 (define_insn "*call_reg_thumb2"
301   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
302          (match_operand 1 "" ""))
303    (use (match_operand 2 "" ""))
304    (clobber (reg:SI LR_REGNUM))]
305   "TARGET_THUMB2"
306   "blx%?\\t%0"
307   [(set_attr "type" "call")]
310 (define_insn "*call_value_reg_thumb2"
311   [(set (match_operand 0 "" "")
312         (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
313               (match_operand 2 "" "")))
314    (use (match_operand 3 "" ""))
315    (clobber (reg:SI LR_REGNUM))]
316   "TARGET_THUMB2"
317   "blx\\t%1"
318   [(set_attr "type" "call")]
321 (define_insn "*thumb2_indirect_jump"
322   [(set (pc)
323         (match_operand:SI 0 "register_operand" "l*r"))]
324   "TARGET_THUMB2"
325   "bx\\t%0"
326   [(set_attr "conds" "clob")]
328 ;; Don't define thumb2_load_indirect_jump because we can't guarantee label
329 ;; addresses will have the thumb bit set correctly. 
332 (define_insn "*thumb2_and_scc"
333   [(set (match_operand:SI 0 "s_register_operand" "=r")
334         (and:SI (match_operator:SI 1 "arm_comparison_operator"
335                  [(match_operand 3 "cc_register" "") (const_int 0)])
336                 (match_operand:SI 2 "s_register_operand" "r")))]
337   "TARGET_THUMB2"
338   "ite\\t%D1\;mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
339   [(set_attr "conds" "use")
340    (set_attr "length" "10")]
343 (define_insn "*thumb2_ior_scc"
344   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
345         (ior:SI (match_operator:SI 2 "arm_comparison_operator"
346                  [(match_operand 3 "cc_register" "") (const_int 0)])
347                 (match_operand:SI 1 "s_register_operand" "0,?r")))]
348   "TARGET_THUMB2"
349   "@
350    it\\t%d2\;orr%d2\\t%0, %1, #1
351    ite\\t%D2\;mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
352   [(set_attr "conds" "use")
353    (set_attr "length" "6,10")]
356 (define_insn "*thumb2_cond_move"
357   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
358         (if_then_else:SI (match_operator 3 "equality_operator"
359                           [(match_operator 4 "arm_comparison_operator"
360                             [(match_operand 5 "cc_register" "") (const_int 0)])
361                            (const_int 0)])
362                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
363                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
364   "TARGET_THUMB2"
365   "*
366     if (GET_CODE (operands[3]) == NE)
367       {
368         if (which_alternative != 1)
369           output_asm_insn (\"it\\t%D4\;mov%D4\\t%0, %2\", operands);
370         if (which_alternative != 0)
371           output_asm_insn (\"it\\t%d4\;mov%d4\\t%0, %1\", operands);
372         return \"\";
373       }
374     switch (which_alternative)
375       {
376       case 0:
377         output_asm_insn (\"it\\t%d4\", operands);
378         break;
379       case 1:
380         output_asm_insn (\"it\\t%D4\", operands);
381         break;
382       case 2:
383         output_asm_insn (\"ite\\t%D4\", operands);
384         break;
385       default:
386         abort();
387       }
388     if (which_alternative != 0)
389       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
390     if (which_alternative != 1)
391       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
392     return \"\";
393   "
394   [(set_attr "conds" "use")
395    (set_attr "length" "6,6,10")]
398 (define_insn "*thumb2_cond_arith"
399   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
400         (match_operator:SI 5 "shiftable_operator" 
401          [(match_operator:SI 4 "arm_comparison_operator"
402            [(match_operand:SI 2 "s_register_operand" "r,r")
403             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
404           (match_operand:SI 1 "s_register_operand" "0,?r")]))
405    (clobber (reg:CC CC_REGNUM))]
406   "TARGET_THUMB2"
407   "*
408     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
409       return \"%i5\\t%0, %1, %2, lsr #31\";
411     output_asm_insn (\"cmp\\t%2, %3\", operands);
412     if (GET_CODE (operands[5]) == AND)
413       {
414         output_asm_insn (\"ite\\t%D4\", operands);
415         output_asm_insn (\"mov%D4\\t%0, #0\", operands);
416       }
417     else if (GET_CODE (operands[5]) == MINUS)
418       {
419         output_asm_insn (\"ite\\t%D4\", operands);
420         output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
421       }
422     else if (which_alternative != 0)
423       {
424         output_asm_insn (\"ite\\t%D4\", operands);
425         output_asm_insn (\"mov%D4\\t%0, %1\", operands);
426       }
427     else
428       output_asm_insn (\"it\\t%d4\", operands);
429     return \"%i5%d4\\t%0, %1, #1\";
430   "
431   [(set_attr "conds" "clob")
432    (set_attr "length" "14")]
435 (define_insn "*thumb2_cond_sub"
436   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
437         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
438                   (match_operator:SI 4 "arm_comparison_operator"
439                    [(match_operand:SI 2 "s_register_operand" "r,r")
440                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
441    (clobber (reg:CC CC_REGNUM))]
442   "TARGET_THUMB2"
443   "*
444     output_asm_insn (\"cmp\\t%2, %3\", operands);
445     if (which_alternative != 0)
446       {
447         output_asm_insn (\"ite\\t%D4\", operands);
448         output_asm_insn (\"mov%D4\\t%0, %1\", operands);
449       }
450     else
451       output_asm_insn (\"it\\t%d4\", operands);
452     return \"sub%d4\\t%0, %1, #1\";
453   "
454   [(set_attr "conds" "clob")
455    (set_attr "length" "10,14")]
458 (define_insn "*thumb2_negscc"
459   [(set (match_operand:SI 0 "s_register_operand" "=r")
460         (neg:SI (match_operator 3 "arm_comparison_operator"
461                  [(match_operand:SI 1 "s_register_operand" "r")
462                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
463    (clobber (reg:CC CC_REGNUM))]
464   "TARGET_THUMB2"
465   "*
466   if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
467     return \"asr\\t%0, %1, #31\";
469   if (GET_CODE (operands[3]) == NE)
470     return \"subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0\";
472   output_asm_insn (\"cmp\\t%1, %2\", operands);
473   output_asm_insn (\"ite\\t%D3\", operands);
474   output_asm_insn (\"mov%D3\\t%0, #0\", operands);
475   return \"mvn%d3\\t%0, #0\";
476   "
477   [(set_attr "conds" "clob")
478    (set_attr "length" "14")]
481 (define_insn "*thumb2_movcond"
482   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
483         (if_then_else:SI
484          (match_operator 5 "arm_comparison_operator"
485           [(match_operand:SI 3 "s_register_operand" "r,r,r")
486            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
487          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
488          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
489    (clobber (reg:CC CC_REGNUM))]
490   "TARGET_THUMB2"
491   "*
492   if (GET_CODE (operands[5]) == LT
493       && (operands[4] == const0_rtx))
494     {
495       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
496         {
497           if (operands[2] == const0_rtx)
498             return \"and\\t%0, %1, %3, asr #31\";
499           return \"ands\\t%0, %1, %3, asr #32\;it\\tcc\;movcc\\t%0, %2\";
500         }
501       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
502         {
503           if (operands[1] == const0_rtx)
504             return \"bic\\t%0, %2, %3, asr #31\";
505           return \"bics\\t%0, %2, %3, asr #32\;it\\tcs\;movcs\\t%0, %1\";
506         }
507       /* The only case that falls through to here is when both ops 1 & 2
508          are constants.  */
509     }
511   if (GET_CODE (operands[5]) == GE
512       && (operands[4] == const0_rtx))
513     {
514       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
515         {
516           if (operands[2] == const0_rtx)
517             return \"bic\\t%0, %1, %3, asr #31\";
518           return \"bics\\t%0, %1, %3, asr #32\;it\\tcs\;movcs\\t%0, %2\";
519         }
520       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
521         {
522           if (operands[1] == const0_rtx)
523             return \"and\\t%0, %2, %3, asr #31\";
524           return \"ands\\t%0, %2, %3, asr #32\;it\tcc\;movcc\\t%0, %1\";
525         }
526       /* The only case that falls through to here is when both ops 1 & 2
527          are constants.  */
528     }
529   if (GET_CODE (operands[4]) == CONST_INT
530       && !const_ok_for_arm (INTVAL (operands[4])))
531     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
532   else
533     output_asm_insn (\"cmp\\t%3, %4\", operands);
534   switch (which_alternative)
535     {
536     case 0:
537       output_asm_insn (\"it\\t%D5\", operands);
538       break;
539     case 1:
540       output_asm_insn (\"it\\t%d5\", operands);
541       break;
542     case 2:
543       output_asm_insn (\"ite\\t%d5\", operands);
544       break;
545     default:
546       abort();
547     }
548   if (which_alternative != 0)
549     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
550   if (which_alternative != 1)
551     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
552   return \"\";
553   "
554   [(set_attr "conds" "clob")
555    (set_attr "length" "10,10,14")]
558 ;; Zero and sign extension instructions.
560 ;; All supported Thumb2 implementations are armv6, so only that case is
561 ;; provided.
562 (define_insn "*thumb2_extendqisi_v6"
563   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
564         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
565   "TARGET_THUMB2 && arm_arch6"
566   "@
567    sxtb%?\\t%0, %1
568    ldr%(sb%)\\t%0, %1"
569   [(set_attr "type" "alu_shift,load_byte")
570    (set_attr "predicable" "yes")
571    (set_attr "pool_range" "*,4096")
572    (set_attr "neg_pool_range" "*,250")]
575 (define_insn "*thumb2_zero_extendhisi2_v6"
576   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
577         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
578   "TARGET_THUMB2 && arm_arch6"
579   "@
580    uxth%?\\t%0, %1
581    ldr%(h%)\\t%0, %1"
582   [(set_attr "type" "alu_shift,load_byte")
583    (set_attr "predicable" "yes")
584    (set_attr "pool_range" "*,4096")
585    (set_attr "neg_pool_range" "*,250")]
588 (define_insn "thumb2_zero_extendqisi2_v6"
589   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
590         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
591   "TARGET_THUMB2 && arm_arch6"
592   "@
593    uxtb%(%)\\t%0, %1
594    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
595   [(set_attr "type" "alu_shift,load_byte")
596    (set_attr "predicable" "yes")
597    (set_attr "pool_range" "*,4096")
598    (set_attr "neg_pool_range" "*,250")]
601 (define_insn "thumb2_casesi_internal"
602   [(parallel [(set (pc)
603                (if_then_else
604                 (leu (match_operand:SI 0 "s_register_operand" "r")
605                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
606                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
607                                  (label_ref (match_operand 2 "" ""))))
608                 (label_ref (match_operand 3 "" ""))))
609               (clobber (reg:CC CC_REGNUM))
610               (clobber (match_scratch:SI 4 "=&r"))
611               (use (label_ref (match_dup 2)))])]
612   "TARGET_THUMB2 && !flag_pic"
613   "* return thumb2_output_casesi(operands);"
614   [(set_attr "conds" "clob")
615    (set_attr "length" "16")]
618 (define_insn "thumb2_casesi_internal_pic"
619   [(parallel [(set (pc)
620                (if_then_else
621                 (leu (match_operand:SI 0 "s_register_operand" "r")
622                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
623                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
624                                  (label_ref (match_operand 2 "" ""))))
625                 (label_ref (match_operand 3 "" ""))))
626               (clobber (reg:CC CC_REGNUM))
627               (clobber (match_scratch:SI 4 "=&r"))
628               (clobber (match_scratch:SI 5 "=r"))
629               (use (label_ref (match_dup 2)))])]
630   "TARGET_THUMB2 && flag_pic"
631   "* return thumb2_output_casesi(operands);"
632   [(set_attr "conds" "clob")
633    (set_attr "length" "20")]
636 ;; Note: this is not predicable, to avoid issues with linker-generated
637 ;; interworking stubs.
638 (define_insn "*thumb2_return"
639   [(return)]
640   "TARGET_THUMB2 && USE_RETURN_INSN (FALSE)"
641   "*
642   {
643     return output_return_instruction (const_true_rtx, TRUE, FALSE);
644   }"
645   [(set_attr "type" "load1")
646    (set_attr "length" "12")]
649 (define_insn_and_split "thumb2_eh_return"
650   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
651                     VUNSPEC_EH_RETURN)
652    (clobber (match_scratch:SI 1 "=&r"))]
653   "TARGET_THUMB2"
654   "#"
655   "&& reload_completed"
656   [(const_int 0)]
657   "
658   {
659     thumb_set_return_address (operands[0], operands[1]);
660     DONE;
661   }"
664 (define_insn "*thumb2_alusi3_short"
665   [(set (match_operand:SI          0 "s_register_operand" "=l")
666         (match_operator:SI 3 "thumb_16bit_operator"
667          [(match_operand:SI 1 "s_register_operand" "0")
668           (match_operand:SI 2 "s_register_operand" "l")]))
669    (clobber (reg:CC CC_REGNUM))]
670   "TARGET_THUMB2 && reload_completed
671    && GET_CODE(operands[3]) != PLUS
672    && GET_CODE(operands[3]) != MINUS"
673   "%I3%!\\t%0, %1, %2"
674   [(set_attr "predicable" "yes")
675    (set_attr "length" "2")]
678 ;; Similarly for 16-bit shift instructions
679 ;; There is no 16-bit rotate by immediate instruction.
680 (define_peephole2
681   [(set (match_operand:SI   0 "low_register_operand" "")
682         (match_operator:SI  3 "shift_operator"
683          [(match_operand:SI 1 "low_register_operand" "")
684           (match_operand:SI 2 "low_reg_or_int_operand" "")]))]
685   "TARGET_THUMB2
686    && peep2_regno_dead_p(0, CC_REGNUM)
687    && ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
688        || REG_P(operands[2]))"
689   [(parallel
690     [(set (match_dup 0)
691           (match_op_dup 3
692            [(match_dup 1)
693             (match_dup 2)]))
694      (clobber (reg:CC CC_REGNUM))])]
695   ""
698 (define_insn "*thumb2_shiftsi3_short"
699   [(set (match_operand:SI   0 "low_register_operand" "=l")
700         (match_operator:SI  3 "shift_operator"
701          [(match_operand:SI 1 "low_register_operand"  "l")
702           (match_operand:SI 2 "low_reg_or_int_operand" "lM")]))
703    (clobber (reg:CC CC_REGNUM))]
704   "TARGET_THUMB2 && reload_completed
705    && ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
706        || REG_P(operands[2]))"
707   "* return arm_output_shift(operands, 2);"
708   [(set_attr "predicable" "yes")
709    (set_attr "shift" "1")
710    (set_attr "length" "2")
711    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
712                       (const_string "alu_shift")
713                       (const_string "alu_shift_reg")))]
716 ;; 16-bit load immediate
717 (define_peephole2
718   [(set (match_operand:QHSI 0 "low_register_operand" "")
719         (match_operand:QHSI 1 "const_int_operand" ""))]
720   "TARGET_THUMB2
721    && peep2_regno_dead_p(0, CC_REGNUM)
722    && (unsigned HOST_WIDE_INT) INTVAL(operands[1]) < 256"
723   [(parallel
724     [(set (match_dup 0)
725           (match_dup 1))
726      (clobber (reg:CC CC_REGNUM))])]
727   ""
730 (define_insn "*thumb2_mov<mode>_shortim"
731   [(set (match_operand:QHSI 0 "low_register_operand" "=l")
732         (match_operand:QHSI 1 "const_int_operand" "I"))
733    (clobber (reg:CC CC_REGNUM))]
734   "TARGET_THUMB2 && reload_completed"
735   "mov%!\t%0, %1"
736   [(set_attr "predicable" "yes")
737    (set_attr "length" "2")]
740 ;; 16-bit add/sub immediate
741 (define_peephole2
742   [(set (match_operand:SI 0 "low_register_operand" "")
743         (plus:SI (match_operand:SI 1 "low_register_operand" "")
744                  (match_operand:SI 2 "const_int_operand" "")))]
745   "TARGET_THUMB2
746    && peep2_regno_dead_p(0, CC_REGNUM)
747    && ((rtx_equal_p(operands[0], operands[1])
748         && INTVAL(operands[2]) > -256 && INTVAL(operands[2]) < 256)
749        || (INTVAL(operands[2]) > -8 && INTVAL(operands[2]) < 8))"
750   [(parallel
751     [(set (match_dup 0)
752           (plus:SI (match_dup 1)
753                    (match_dup 2)))
754      (clobber (reg:CC CC_REGNUM))])]
755   ""
758 (define_insn "*thumb2_addsi_short"
759   [(set (match_operand:SI 0 "low_register_operand" "=l,l")
760         (plus:SI (match_operand:SI 1 "low_register_operand" "l,0")
761                  (match_operand:SI 2 "low_reg_or_int_operand" "lPt,Ps")))
762    (clobber (reg:CC CC_REGNUM))]
763   "TARGET_THUMB2 && reload_completed"
764   "*
765     HOST_WIDE_INT val;
767     if (GET_CODE (operands[2]) == CONST_INT)
768       val = INTVAL(operands[2]);
769     else
770       val = 0;
772     /* We prefer eg. subs rn, rn, #1 over adds rn, rn, #0xffffffff.  */
773     if (val < 0 && const_ok_for_arm(ARM_SIGN_EXTEND (-val)))
774       return \"sub%!\\t%0, %1, #%n2\";
775     else
776       return \"add%!\\t%0, %1, %2\";
777   "
778   [(set_attr "predicable" "yes")
779    (set_attr "length" "2")]
782 (define_insn "divsi3"
783   [(set (match_operand:SI         0 "s_register_operand" "=r")
784         (div:SI (match_operand:SI 1 "s_register_operand"  "r")
785                 (match_operand:SI 2 "s_register_operand"  "r")))]
786   "TARGET_THUMB2 && arm_arch_hwdiv"
787   "sdiv%?\t%0, %1, %2"
788   [(set_attr "predicable" "yes")
789    (set_attr "insn" "sdiv")]
792 (define_insn "udivsi3"
793   [(set (match_operand:SI          0 "s_register_operand" "=r")
794         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
795                  (match_operand:SI 2 "s_register_operand"  "r")))]
796   "TARGET_THUMB2 && arm_arch_hwdiv"
797   "udiv%?\t%0, %1, %2"
798   [(set_attr "predicable" "yes")
799    (set_attr "insn" "udiv")]
802 (define_insn "*thumb2_subsi_short"
803   [(set (match_operand:SI 0 "low_register_operand" "=l")
804         (minus:SI (match_operand:SI 1 "low_register_operand" "l")
805                   (match_operand:SI 2 "low_register_operand" "l")))
806    (clobber (reg:CC CC_REGNUM))]
807   "TARGET_THUMB2 && reload_completed"
808   "sub%!\\t%0, %1, %2"
809   [(set_attr "predicable" "yes")
810    (set_attr "length" "2")]
813 (define_peephole2
814   [(set (match_operand:CC 0 "cc_register" "")
815         (compare:CC (match_operand:SI 1 "low_register_operand" "")
816                     (match_operand:SI 2 "const_int_operand" "")))]
817   "TARGET_THUMB2
818    && peep2_reg_dead_p (1, operands[1])
819    && satisfies_constraint_Pw (operands[2])"
820   [(parallel
821     [(set (match_dup 0) (compare:CC (match_dup 1) (match_dup 2)))
822      (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 3)))])]
823   "operands[3] = GEN_INT (- INTVAL (operands[2]));"
826 (define_peephole2
827   [(match_scratch:SI 3 "l")
828    (set (match_operand:CC 0 "cc_register" "")
829         (compare:CC (match_operand:SI 1 "low_register_operand" "")
830                     (match_operand:SI 2 "const_int_operand" "")))]
831   "TARGET_THUMB2
832    && satisfies_constraint_Px (operands[2])"
833   [(parallel
834     [(set (match_dup 0) (compare:CC (match_dup 1) (match_dup 2)))
835      (set (match_dup 3) (plus:SI (match_dup 1) (match_dup 4)))])]
836   "operands[4] = GEN_INT (- INTVAL (operands[2]));"
839 (define_insn "*thumb2_addsi3_compare0"
840   [(set (reg:CC_NOOV CC_REGNUM)
841         (compare:CC_NOOV
842           (plus:SI (match_operand:SI 1 "s_register_operand" "l,  0, r")
843                    (match_operand:SI 2 "arm_add_operand"    "lPt,Ps,rIL"))
844           (const_int 0)))
845    (set (match_operand:SI 0 "s_register_operand" "=l,l,r")
846         (plus:SI (match_dup 1) (match_dup 2)))]
847   "TARGET_THUMB2"
848   "*
849     HOST_WIDE_INT val;
851     if (GET_CODE (operands[2]) == CONST_INT)
852       val = INTVAL (operands[2]);
853     else
854       val = 0;
856     if (val < 0 && const_ok_for_arm (ARM_SIGN_EXTEND (-val)))
857       return \"subs\\t%0, %1, #%n2\";
858     else
859       return \"adds\\t%0, %1, %2\";
860   "
861   [(set_attr "conds" "set")
862    (set_attr "length" "2,2,4")]
865 (define_insn "*thumb2_addsi3_compare0_scratch"
866   [(set (reg:CC_NOOV CC_REGNUM)
867         (compare:CC_NOOV
868           (plus:SI (match_operand:SI 0 "s_register_operand" "l,  r")
869                    (match_operand:SI 1 "arm_add_operand"    "lPv,rIL"))
870           (const_int 0)))]
871   "TARGET_THUMB2"
872   "*
873     HOST_WIDE_INT val;
875     if (GET_CODE (operands[1]) == CONST_INT)
876       val = INTVAL (operands[1]);
877     else
878       val = 0;
880     if (val < 0 && const_ok_for_arm (ARM_SIGN_EXTEND (-val)))
881       return \"cmp\\t%0, #%n1\";
882     else
883       return \"cmn\\t%0, %1\";
884   "
885   [(set_attr "conds" "set")
886    (set_attr "length" "2,4")]
889 ;; 16-bit encodings of "muls" and "mul<c>".  We only use these when
890 ;; optimizing for size since "muls" is slow on all known
891 ;; implementations and since "mul<c>" will be generated by
892 ;; "*arm_mulsi3_v6" anyhow.  The assembler will use a 16-bit encoding
893 ;; for "mul<c>" whenever possible anyhow.
894 (define_peephole2
895   [(set (match_operand:SI 0 "low_register_operand" "")
896         (mult:SI (match_operand:SI 1 "low_register_operand" "")
897                  (match_dup 0)))]
898   "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
899   [(parallel
900     [(set (match_dup 0)
901            (mult:SI (match_dup 0) (match_dup 1)))
902      (clobber (reg:CC CC_REGNUM))])]
903   ""
906 (define_peephole2
907   [(set (match_operand:SI 0 "low_register_operand" "")
908         (mult:SI (match_dup 0)
909                  (match_operand:SI 1 "low_register_operand" "")))]
910   "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
911   [(parallel
912     [(set (match_dup 0)
913            (mult:SI (match_dup 0) (match_dup 1)))
914      (clobber (reg:CC CC_REGNUM))])]
915   ""
918 (define_insn "*thumb2_mulsi_short"
919   [(set (match_operand:SI 0 "low_register_operand" "=l")
920         (mult:SI (match_operand:SI 1 "low_register_operand" "%0")
921                  (match_operand:SI 2 "low_register_operand" "l")))
922    (clobber (reg:CC CC_REGNUM))]
923   "TARGET_THUMB2 && optimize_size && reload_completed"
924   "mul%!\\t%0, %2, %0"
925   [(set_attr "predicable" "yes")
926    (set_attr "length" "2")
927    (set_attr "insn" "muls")])
929 (define_insn "*thumb2_mulsi_short_compare0"
930   [(set (reg:CC_NOOV CC_REGNUM)
931         (compare:CC_NOOV
932          (mult:SI (match_operand:SI 1 "register_operand" "%0")
933                   (match_operand:SI 2 "register_operand" "l"))
934          (const_int 0)))
935    (set (match_operand:SI 0 "register_operand" "=l")
936         (mult:SI (match_dup 1) (match_dup 2)))]
937   "TARGET_THUMB2 && optimize_size"
938   "muls\\t%0, %2, %0"
939   [(set_attr "length" "2")
940    (set_attr "insn" "muls")])
942 (define_insn "*thumb2_mulsi_short_compare0_scratch"
943   [(set (reg:CC_NOOV CC_REGNUM)
944         (compare:CC_NOOV
945          (mult:SI (match_operand:SI 1 "register_operand" "%0")
946                   (match_operand:SI 2 "register_operand" "l"))
947          (const_int 0)))
948    (clobber (match_scratch:SI 0 "=l"))]
949   "TARGET_THUMB2 && optimize_size"
950   "muls\\t%0, %2, %0"
951   [(set_attr "length" "2")
952    (set_attr "insn" "muls")])
954 (define_insn "*thumb2_cbz"
955   [(set (pc) (if_then_else
956               (eq (match_operand:SI 0 "s_register_operand" "l,?r")
957                   (const_int 0))
958               (label_ref (match_operand 1 "" ""))
959               (pc)))
960    (clobber (reg:CC CC_REGNUM))]
961   "TARGET_THUMB2"
962   "*
963   if (get_attr_length (insn) == 2)
964     return \"cbz\\t%0, %l1\";
965   else
966     return \"cmp\\t%0, #0\;beq\\t%l1\";
967   "
968   [(set (attr "length") 
969         (if_then_else
970             (and (ge (minus (match_dup 1) (pc)) (const_int 2))
971                  (le (minus (match_dup 1) (pc)) (const_int 128))
972                  (eq (symbol_ref ("which_alternative")) (const_int 0)))
973             (const_int 2)
974             (const_int 8)))]
977 (define_insn "*thumb2_cbnz"
978   [(set (pc) (if_then_else
979               (ne (match_operand:SI 0 "s_register_operand" "l,?r")
980                   (const_int 0))
981               (label_ref (match_operand 1 "" ""))
982               (pc)))
983    (clobber (reg:CC CC_REGNUM))]
984   "TARGET_THUMB2"
985   "*
986   if (get_attr_length (insn) == 2)
987     return \"cbnz\\t%0, %l1\";
988   else
989     return \"cmp\\t%0, #0\;bne\\t%l1\";
990   "
991   [(set (attr "length") 
992         (if_then_else
993             (and (ge (minus (match_dup 1) (pc)) (const_int 2))
994                  (le (minus (match_dup 1) (pc)) (const_int 128))
995                  (eq (symbol_ref ("which_alternative")) (const_int 0)))
996             (const_int 2)
997             (const_int 8)))]
1000 ;; 16-bit complement
1001 (define_peephole2
1002   [(set (match_operand:SI 0 "low_register_operand" "")
1003         (not:SI (match_operand:SI 1 "low_register_operand" "")))]
1004   "TARGET_THUMB2
1005    && peep2_regno_dead_p(0, CC_REGNUM)"
1006   [(parallel
1007     [(set (match_dup 0)
1008           (not:SI (match_dup 1)))
1009      (clobber (reg:CC CC_REGNUM))])]
1010   ""
1013 (define_insn "*thumb2_one_cmplsi2_short"
1014   [(set (match_operand:SI 0 "low_register_operand" "=l")
1015         (not:SI (match_operand:SI 1 "low_register_operand" "l")))
1016    (clobber (reg:CC CC_REGNUM))]
1017   "TARGET_THUMB2 && reload_completed"
1018   "mvn%!\t%0, %1"
1019   [(set_attr "predicable" "yes")
1020    (set_attr "length" "2")]
1023 ;; 16-bit negate
1024 (define_peephole2
1025   [(set (match_operand:SI 0 "low_register_operand" "")
1026         (neg:SI (match_operand:SI 1 "low_register_operand" "")))]
1027   "TARGET_THUMB2
1028    && peep2_regno_dead_p(0, CC_REGNUM)"
1029   [(parallel
1030     [(set (match_dup 0)
1031           (neg:SI (match_dup 1)))
1032      (clobber (reg:CC CC_REGNUM))])]
1033   ""
1036 (define_insn "*thumb2_negsi2_short"
1037   [(set (match_operand:SI 0 "low_register_operand" "=l")
1038         (neg:SI (match_operand:SI 1 "low_register_operand" "l")))
1039    (clobber (reg:CC CC_REGNUM))]
1040   "TARGET_THUMB2 && reload_completed"
1041   "neg%!\t%0, %1"
1042   [(set_attr "predicable" "yes")
1043    (set_attr "length" "2")]
1046 (define_insn "*orsi_notsi_si"
1047   [(set (match_operand:SI 0 "s_register_operand" "=r")
1048         (ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1049                 (match_operand:SI 1 "s_register_operand" "r")))]
1050   "TARGET_THUMB2"
1051   "orn%?\\t%0, %1, %2"
1052   [(set_attr "predicable" "yes")]
1055 (define_insn "*orsi_not_shiftsi_si"
1056   [(set (match_operand:SI 0 "s_register_operand" "=r")
1057         (ior:SI (not:SI (match_operator:SI 4 "shift_operator"
1058                          [(match_operand:SI 2 "s_register_operand" "r")
1059                           (match_operand:SI 3 "const_int_operand" "M")]))
1060                 (match_operand:SI 1 "s_register_operand" "r")))]
1061   "TARGET_THUMB2"
1062   "orn%?\\t%0, %1, %2%S4"
1063   [(set_attr "predicable" "yes")
1064    (set_attr "shift" "2")
1065    (set_attr "type" "alu_shift")]
1068 (define_peephole2
1069   [(set (match_operand:CC_NOOV 0 "cc_register" "")
1070         (compare:CC_NOOV (zero_extract:SI
1071                           (match_operand:SI 1 "low_register_operand" "")
1072                           (const_int 1)
1073                           (match_operand:SI 2 "const_int_operand" ""))
1074                          (const_int 0)))
1075    (match_scratch:SI 3 "l")
1076    (set (pc)
1077         (if_then_else (match_operator:CC_NOOV 4 "equality_operator"
1078                        [(match_dup 0) (const_int 0)])
1079                       (match_operand 5 "" "")
1080                       (match_operand 6 "" "")))]
1081   "TARGET_THUMB2
1082    && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32)"
1083   [(parallel [(set (match_dup 0)
1084                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1085                                     (const_int 0)))
1086               (clobber (match_dup 3))])
1087    (set (pc)
1088         (if_then_else (match_op_dup 4 [(match_dup 0) (const_int 0)])
1089                       (match_dup 5) (match_dup 6)))]
1090   "
1091   operands[2] = GEN_INT (31 - INTVAL (operands[2]));
1092   operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? LT : GE,
1093                                 VOIDmode, operands[0], const0_rtx);
1094   ")
1096 (define_peephole2
1097   [(set (match_operand:CC_NOOV 0 "cc_register" "")
1098         (compare:CC_NOOV (zero_extract:SI
1099                           (match_operand:SI 1 "low_register_operand" "")
1100                           (match_operand:SI 2 "const_int_operand" "")
1101                           (const_int 0))
1102                          (const_int 0)))
1103    (match_scratch:SI 3 "l")
1104    (set (pc)
1105         (if_then_else (match_operator:CC_NOOV 4 "equality_operator"
1106                        [(match_dup 0) (const_int 0)])
1107                       (match_operand 5 "" "")
1108                       (match_operand 6 "" "")))]
1109   "TARGET_THUMB2
1110    && (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 32)"
1111   [(parallel [(set (match_dup 0)
1112                    (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2))
1113                                     (const_int 0)))
1114               (clobber (match_dup 3))])
1115    (set (pc)
1116         (if_then_else (match_op_dup 4 [(match_dup 0) (const_int 0)])
1117                       (match_dup 5) (match_dup 6)))]
1118   "
1119   operands[2] = GEN_INT (32 - INTVAL (operands[2]));
1120   ")