PR target/43469
[official-gcc.git] / gcc / config / arm / thumb2.md
blob69a5e0683b488ea08440de8c685a88dcd1c45699
1 ;; ARM Thumb-2 Machine Description
2 ;; Copyright (C) 2007, 2008 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 (define_insn "*thumb2_notsi_shiftsi"
124   [(set (match_operand:SI 0 "s_register_operand" "=r")
125         (not:SI (match_operator:SI 3 "shift_operator"
126                  [(match_operand:SI 1 "s_register_operand" "r")
127                   (match_operand:SI 2 "const_int_operand"  "M")])))]
128   "TARGET_THUMB2"
129   "mvn%?\\t%0, %1%S3"
130   [(set_attr "predicable" "yes")
131    (set_attr "shift" "1")
132    (set_attr "type" "alu_shift")]
135 (define_insn "*thumb2_notsi_shiftsi_compare0"
136   [(set (reg:CC_NOOV CC_REGNUM)
137         (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
138                           [(match_operand:SI 1 "s_register_operand" "r")
139                            (match_operand:SI 2 "const_int_operand"  "M")]))
140                          (const_int 0)))
141    (set (match_operand:SI 0 "s_register_operand" "=r")
142         (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))]
143   "TARGET_THUMB2"
144   "mvn%.\\t%0, %1%S3"
145   [(set_attr "conds" "set")
146    (set_attr "shift" "1")
147    (set_attr "type" "alu_shift")]
150 (define_insn "*thumb2_not_shiftsi_compare0_scratch"
151   [(set (reg:CC_NOOV CC_REGNUM)
152         (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator"
153                           [(match_operand:SI 1 "s_register_operand" "r")
154                            (match_operand:SI 2 "const_int_operand"  "M")]))
155                          (const_int 0)))
156    (clobber (match_scratch:SI 0 "=r"))]
157   "TARGET_THUMB2"
158   "mvn%.\\t%0, %1%S3"
159   [(set_attr "conds" "set")
160    (set_attr "shift" "1")
161    (set_attr "type" "alu_shift")]
164 ;; Thumb-2 does not have rsc, so use a clever trick with shifter operands.
165 (define_insn "*thumb2_negdi2"
166   [(set (match_operand:DI         0 "s_register_operand" "=&r,r")
167         (neg:DI (match_operand:DI 1 "s_register_operand"  "?r,0")))
168    (clobber (reg:CC CC_REGNUM))]
169   "TARGET_THUMB2"
170   "negs\\t%Q0, %Q1\;sbc\\t%R0, %R1, %R1, lsl #1"
171   [(set_attr "conds" "clob")
172    (set_attr "length" "8")]
175 (define_insn "*thumb2_abssi2"
176   [(set (match_operand:SI         0 "s_register_operand" "=r,&r")
177         (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))
178    (clobber (reg:CC CC_REGNUM))]
179   "TARGET_THUMB2"
180   "@
181    cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
182    eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31"
183   [(set_attr "conds" "clob,*")
184    (set_attr "shift" "1")
185    ;; predicable can't be set based on the variant, so left as no
186    (set_attr "length" "10,8")]
189 (define_insn "*thumb2_neg_abssi2"
190   [(set (match_operand:SI 0 "s_register_operand" "=r,&r")
191         (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))))
192    (clobber (reg:CC CC_REGNUM))]
193   "TARGET_THUMB2"
194   "@
195    cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
196    eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31"
197   [(set_attr "conds" "clob,*")
198    (set_attr "shift" "1")
199    ;; predicable can't be set based on the variant, so left as no
200    (set_attr "length" "10,8")]
203 (define_insn "*thumb2_movdi"
204   [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m")
205         (match_operand:DI 1 "di_operand"              "rDa,Db,Dc,mi,r"))]
206   "TARGET_THUMB2
207   && !(TARGET_HARD_FLOAT && (TARGET_MAVERICK || TARGET_VFP))
208   && !TARGET_IWMMXT"
209   "*
210   switch (which_alternative)
211     {
212     case 0:
213     case 1:
214     case 2:
215       return \"#\";
216     default:
217       return output_move_double (operands);
218     }
219   "
220   [(set_attr "length" "8,12,16,8,8")
221    (set_attr "type" "*,*,*,load2,store2")
222    (set_attr "pool_range" "*,*,*,4096,*")
223    (set_attr "neg_pool_range" "*,*,*,0,*")]
226 (define_insn "*thumb2_movsi_insn"
227   [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m")
228         (match_operand:SI 1 "general_operand"      "rk ,I,K,j,mi,rk"))]
229   "TARGET_THUMB2 && ! TARGET_IWMMXT
230    && !(TARGET_HARD_FLOAT && TARGET_VFP)
231    && (   register_operand (operands[0], SImode)
232        || register_operand (operands[1], SImode))"
233   "@
234    mov%?\\t%0, %1
235    mov%?\\t%0, %1
236    mvn%?\\t%0, #%B1
237    movw%?\\t%0, %1
238    ldr%?\\t%0, %1
239    str%?\\t%1, %0"
240   [(set_attr "type" "*,*,*,*,load1,store1")
241    (set_attr "predicable" "yes")
242    (set_attr "pool_range" "*,*,*,*,4096,*")
243    (set_attr "neg_pool_range" "*,*,*,*,0,*")]
246 (define_insn "tls_load_dot_plus_four"
247   [(set (match_operand:SI 0 "register_operand" "=l,l,r,r")
248         (mem:SI (unspec:SI [(match_operand:SI 2 "register_operand" "0,1,0,1")
249                             (const_int 4)
250                             (match_operand 3 "" "")]
251                            UNSPEC_PIC_BASE)))
252    (clobber (match_scratch:SI 1 "=X,l,X,r"))]
253   "TARGET_THUMB2"
254   "*
255   (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
256                              INTVAL (operands[3]));
257   return \"add\\t%2, %|pc\;ldr%?\\t%0, [%2]\";
258   "
259   [(set_attr "length" "4,4,6,6")]
262 ;; Thumb-2 always has load/store halfword instructions, so we can avoid a lot
263 ;; of the messiness associated with the ARM patterns.
264 (define_insn "*thumb2_movhi_insn"
265   [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r")    
266         (match_operand:HI 1 "general_operand"      "rI,n,r,m"))]
267   "TARGET_THUMB2"
268   "@
269    mov%?\\t%0, %1\\t%@ movhi
270    movw%?\\t%0, %L1\\t%@ movhi
271    str%(h%)\\t%1, %0\\t%@ movhi
272    ldr%(h%)\\t%0, %1\\t%@ movhi"
273   [(set_attr "type" "*,*,store1,load1")
274    (set_attr "predicable" "yes")
275    (set_attr "pool_range" "*,*,*,4096")
276    (set_attr "neg_pool_range" "*,*,*,250")]
279 (define_insn "*thumb2_movsf_soft_insn"
280   [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m")
281         (match_operand:SF 1 "general_operand"  "r,mE,r"))]
282   "TARGET_THUMB2
283    && TARGET_SOFT_FLOAT
284    && (GET_CODE (operands[0]) != MEM
285        || register_operand (operands[1], SFmode))"
286   "@
287    mov%?\\t%0, %1
288    ldr%?\\t%0, %1\\t%@ float
289    str%?\\t%1, %0\\t%@ float"
290   [(set_attr "predicable" "yes")
291    (set_attr "type" "*,load1,store1")
292    (set_attr "pool_range" "*,4096,*")
293    (set_attr "neg_pool_range" "*,0,*")]
296 (define_insn "*thumb2_movdf_soft_insn"
297   [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m")
298         (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))]
299   "TARGET_THUMB2 && TARGET_SOFT_FLOAT
300    && (   register_operand (operands[0], DFmode)
301        || register_operand (operands[1], DFmode))"
302   "*
303   switch (which_alternative)
304     {
305     case 0:
306     case 1:
307     case 2:
308       return \"#\";
309     default:
310       return output_move_double (operands);
311     }
312   "
313   [(set_attr "length" "8,12,16,8,8")
314    (set_attr "type" "*,*,*,load2,store2")
315    (set_attr "pool_range" "1020")
316    (set_attr "neg_pool_range" "0")]
319 (define_insn "*thumb2_cmpsi_shiftsi"
320   [(set (reg:CC CC_REGNUM)
321         (compare:CC (match_operand:SI   0 "s_register_operand" "r")
322                     (match_operator:SI  3 "shift_operator"
323                      [(match_operand:SI 1 "s_register_operand" "r")
324                       (match_operand:SI 2 "const_int_operand"  "M")])))]
325   "TARGET_THUMB2"
326   "cmp%?\\t%0, %1%S3"
327   [(set_attr "conds" "set")
328    (set_attr "shift" "1")
329    (set_attr "type" "alu_shift")]
332 (define_insn "*thumb2_cmpsi_shiftsi_swp"
333   [(set (reg:CC_SWP CC_REGNUM)
334         (compare:CC_SWP (match_operator:SI 3 "shift_operator"
335                          [(match_operand:SI 1 "s_register_operand" "r")
336                           (match_operand:SI 2 "const_int_operand" "M")])
337                         (match_operand:SI 0 "s_register_operand" "r")))]
338   "TARGET_THUMB2"
339   "cmp%?\\t%0, %1%S3"
340   [(set_attr "conds" "set")
341    (set_attr "shift" "1")
342    (set_attr "type" "alu_shift")]
345 (define_insn "*thumb2_cmpsi_neg_shiftsi"
346   [(set (reg:CC CC_REGNUM)
347         (compare:CC (match_operand:SI 0 "s_register_operand" "r")
348                     (neg:SI (match_operator:SI 3 "shift_operator"
349                              [(match_operand:SI 1 "s_register_operand" "r")
350                               (match_operand:SI 2 "const_int_operand" "M")]))))]
351   "TARGET_THUMB2"
352   "cmn%?\\t%0, %1%S3"
353   [(set_attr "conds" "set")
354    (set_attr "shift" "1")
355    (set_attr "type" "alu_shift")]
358 (define_insn "*thumb2_mov_scc"
359   [(set (match_operand:SI 0 "s_register_operand" "=r")
360         (match_operator:SI 1 "arm_comparison_operator"
361          [(match_operand 2 "cc_register" "") (const_int 0)]))]
362   "TARGET_THUMB2"
363   "ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
364   [(set_attr "conds" "use")
365    (set_attr "length" "10")]
368 (define_insn "*thumb2_mov_negscc"
369   [(set (match_operand:SI 0 "s_register_operand" "=r")
370         (neg:SI (match_operator:SI 1 "arm_comparison_operator"
371                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
372   "TARGET_THUMB2"
373   "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
374   [(set_attr "conds" "use")
375    (set_attr "length" "10")]
378 (define_insn "*thumb2_mov_notscc"
379   [(set (match_operand:SI 0 "s_register_operand" "=r")
380         (not:SI (match_operator:SI 1 "arm_comparison_operator"
381                  [(match_operand 2 "cc_register" "") (const_int 0)])))]
382   "TARGET_THUMB2"
383   "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #1"
384   [(set_attr "conds" "use")
385    (set_attr "length" "10")]
388 (define_insn "*thumb2_movsicc_insn"
389   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r")
390         (if_then_else:SI
391          (match_operator 3 "arm_comparison_operator"
392           [(match_operand 4 "cc_register" "") (const_int 0)])
393          (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K")
394          (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))]
395   "TARGET_THUMB2"
396   "@
397    it\\t%D3\;mov%D3\\t%0, %2
398    it\\t%D3\;mvn%D3\\t%0, #%B2
399    it\\t%d3\;mov%d3\\t%0, %1
400    it\\t%d3\;mvn%d3\\t%0, #%B1
401    ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
402    ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
403    ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
404    ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2"
405   [(set_attr "length" "6,6,6,6,10,10,10,10")
406    (set_attr "conds" "use")]
409 (define_insn "*thumb2_movsfcc_soft_insn"
410   [(set (match_operand:SF 0 "s_register_operand" "=r,r")
411         (if_then_else:SF (match_operator 3 "arm_comparison_operator"
412                           [(match_operand 4 "cc_register" "") (const_int 0)])
413                          (match_operand:SF 1 "s_register_operand" "0,r")
414                          (match_operand:SF 2 "s_register_operand" "r,0")))]
415   "TARGET_THUMB2 && TARGET_SOFT_FLOAT"
416   "@
417    it\\t%D3\;mov%D3\\t%0, %2
418    it\\t%d3\;mov%d3\\t%0, %1"
419   [(set_attr "length" "6,6")
420    (set_attr "conds" "use")]
423 (define_insn "*call_reg_thumb2"
424   [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
425          (match_operand 1 "" ""))
426    (use (match_operand 2 "" ""))
427    (clobber (reg:SI LR_REGNUM))]
428   "TARGET_THUMB2"
429   "blx%?\\t%0"
430   [(set_attr "type" "call")]
433 (define_insn "*call_value_reg_thumb2"
434   [(set (match_operand 0 "" "")
435         (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
436               (match_operand 2 "" "")))
437    (use (match_operand 3 "" ""))
438    (clobber (reg:SI LR_REGNUM))]
439   "TARGET_THUMB2"
440   "blx\\t%1"
441   [(set_attr "type" "call")]
444 (define_insn "*thumb2_indirect_jump"
445   [(set (pc)
446         (match_operand:SI 0 "register_operand" "l*r"))]
447   "TARGET_THUMB2"
448   "bx\\t%0"
449   [(set_attr "conds" "clob")]
451 ;; Don't define thumb2_load_indirect_jump because we can't guarantee label
452 ;; addresses will have the thumb bit set correctly. 
455 ;; Patterns to allow combination of arithmetic, cond code and shifts
457 (define_insn "*thumb2_arith_shiftsi"
458   [(set (match_operand:SI 0 "s_register_operand" "=r")
459         (match_operator:SI 1 "shiftable_operator"
460           [(match_operator:SI 3 "shift_operator"
461              [(match_operand:SI 4 "s_register_operand" "r")
462               (match_operand:SI 5 "const_int_operand" "M")])
463            (match_operand:SI 2 "s_register_operand" "r")]))]
464   "TARGET_THUMB2"
465   "%i1%?\\t%0, %2, %4%S3"
466   [(set_attr "predicable" "yes")
467    (set_attr "shift" "4")
468    (set_attr "type" "alu_shift")]
471 ;; ??? What does this splitter do?  Copied from the ARM version
472 (define_split
473   [(set (match_operand:SI 0 "s_register_operand" "")
474         (match_operator:SI 1 "shiftable_operator"
475          [(match_operator:SI 2 "shiftable_operator"
476            [(match_operator:SI 3 "shift_operator"
477              [(match_operand:SI 4 "s_register_operand" "")
478               (match_operand:SI 5 "const_int_operand" "")])
479             (match_operand:SI 6 "s_register_operand" "")])
480           (match_operand:SI 7 "arm_rhs_operand" "")]))
481    (clobber (match_operand:SI 8 "s_register_operand" ""))]
482   "TARGET_32BIT"
483   [(set (match_dup 8)
484         (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
485                          (match_dup 6)]))
486    (set (match_dup 0)
487         (match_op_dup 1 [(match_dup 8) (match_dup 7)]))]
488   "")
490 (define_insn "*thumb2_arith_shiftsi_compare0"
491   [(set (reg:CC_NOOV CC_REGNUM)
492         (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
493                           [(match_operator:SI 3 "shift_operator"
494                             [(match_operand:SI 4 "s_register_operand" "r")
495                              (match_operand:SI 5 "const_int_operand" "M")])
496                            (match_operand:SI 2 "s_register_operand" "r")])
497                          (const_int 0)))
498    (set (match_operand:SI 0 "s_register_operand" "=r")
499         (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)])
500                          (match_dup 2)]))]
501   "TARGET_32BIT"
502   "%i1%.\\t%0, %2, %4%S3"
503   [(set_attr "conds" "set")
504    (set_attr "shift" "4")
505    (set_attr "type" "alu_shift")]
508 (define_insn "*thumb2_arith_shiftsi_compare0_scratch"
509   [(set (reg:CC_NOOV CC_REGNUM)
510         (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator"
511                           [(match_operator:SI 3 "shift_operator"
512                             [(match_operand:SI 4 "s_register_operand" "r")
513                              (match_operand:SI 5 "const_int_operand" "M")])
514                            (match_operand:SI 2 "s_register_operand" "r")])
515                          (const_int 0)))
516    (clobber (match_scratch:SI 0 "=r"))]
517   "TARGET_THUMB2"
518   "%i1%.\\t%0, %2, %4%S3"
519   [(set_attr "conds" "set")
520    (set_attr "shift" "4")
521    (set_attr "type" "alu_shift")]
524 (define_insn "*thumb2_sub_shiftsi"
525   [(set (match_operand:SI 0 "s_register_operand" "=r")
526         (minus:SI (match_operand:SI 1 "s_register_operand" "r")
527                   (match_operator:SI 2 "shift_operator"
528                    [(match_operand:SI 3 "s_register_operand" "r")
529                     (match_operand:SI 4 "const_int_operand" "M")])))]
530   "TARGET_THUMB2"
531   "sub%?\\t%0, %1, %3%S2"
532   [(set_attr "predicable" "yes")
533    (set_attr "shift" "3")
534    (set_attr "type" "alu_shift")]
537 (define_insn "*thumb2_sub_shiftsi_compare0"
538   [(set (reg:CC_NOOV CC_REGNUM)
539         (compare:CC_NOOV
540          (minus:SI (match_operand:SI 1 "s_register_operand" "r")
541                    (match_operator:SI 2 "shift_operator"
542                     [(match_operand:SI 3 "s_register_operand" "r")
543                      (match_operand:SI 4 "const_int_operand" "M")]))
544          (const_int 0)))
545    (set (match_operand:SI 0 "s_register_operand" "=r")
546         (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3)
547                                                  (match_dup 4)])))]
548   "TARGET_THUMB2"
549   "sub%.\\t%0, %1, %3%S2"
550   [(set_attr "conds" "set")
551    (set_attr "shift" "3")
552    (set_attr "type" "alu_shift")]
555 (define_insn "*thumb2_sub_shiftsi_compare0_scratch"
556   [(set (reg:CC_NOOV CC_REGNUM)
557         (compare:CC_NOOV
558          (minus:SI (match_operand:SI 1 "s_register_operand" "r")
559                    (match_operator:SI 2 "shift_operator"
560                     [(match_operand:SI 3 "s_register_operand" "r")
561                      (match_operand:SI 4 "const_int_operand" "M")]))
562          (const_int 0)))
563    (clobber (match_scratch:SI 0 "=r"))]
564   "TARGET_THUMB2"
565   "sub%.\\t%0, %1, %3%S2"
566   [(set_attr "conds" "set")
567    (set_attr "shift" "3")
568    (set_attr "type" "alu_shift")]
571 (define_insn "*thumb2_and_scc"
572   [(set (match_operand:SI 0 "s_register_operand" "=r")
573         (and:SI (match_operator:SI 1 "arm_comparison_operator"
574                  [(match_operand 3 "cc_register" "") (const_int 0)])
575                 (match_operand:SI 2 "s_register_operand" "r")))]
576   "TARGET_THUMB2"
577   "ite\\t%D1\;mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1"
578   [(set_attr "conds" "use")
579    (set_attr "length" "10")]
582 (define_insn "*thumb2_ior_scc"
583   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
584         (ior:SI (match_operator:SI 2 "arm_comparison_operator"
585                  [(match_operand 3 "cc_register" "") (const_int 0)])
586                 (match_operand:SI 1 "s_register_operand" "0,?r")))]
587   "TARGET_THUMB2"
588   "@
589    it\\t%d2\;orr%d2\\t%0, %1, #1
590    ite\\t%D2\;mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1"
591   [(set_attr "conds" "use")
592    (set_attr "length" "6,10")]
595 (define_insn "*thumb2_compare_scc"
596   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
597         (match_operator:SI 1 "arm_comparison_operator"
598          [(match_operand:SI 2 "s_register_operand" "r,r")
599           (match_operand:SI 3 "arm_add_operand" "rI,L")]))
600    (clobber (reg:CC CC_REGNUM))]
601   "TARGET_THUMB2"
602   "*
603     if (operands[3] == const0_rtx)
604       {
605         if (GET_CODE (operands[1]) == LT)
606           return \"lsr\\t%0, %2, #31\";
608         if (GET_CODE (operands[1]) == GE)
609           return \"mvn\\t%0, %2\;lsr\\t%0, %0, #31\";
611         if (GET_CODE (operands[1]) == EQ)
612           return \"rsbs\\t%0, %2, #1\;it\\tcc\;movcc\\t%0, #0\";
613       }
615     if (GET_CODE (operands[1]) == NE)
616       {
617         if (which_alternative == 1)
618           return \"adds\\t%0, %2, #%n3\;it\\tne\;movne\\t%0, #1\";
619         return \"subs\\t%0, %2, %3\;it\\tne\;movne\\t%0, #1\";
620       }
621     if (which_alternative == 1)
622       output_asm_insn (\"cmn\\t%2, #%n3\", operands);
623     else
624       output_asm_insn (\"cmp\\t%2, %3\", operands);
625     return \"ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1\";
626   "
627   [(set_attr "conds" "clob")
628    (set_attr "length" "14")]
631 (define_insn "*thumb2_cond_move"
632   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
633         (if_then_else:SI (match_operator 3 "equality_operator"
634                           [(match_operator 4 "arm_comparison_operator"
635                             [(match_operand 5 "cc_register" "") (const_int 0)])
636                            (const_int 0)])
637                          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
638                          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
639   "TARGET_THUMB2"
640   "*
641     if (GET_CODE (operands[3]) == NE)
642       {
643         if (which_alternative != 1)
644           output_asm_insn (\"it\\t%D4\;mov%D4\\t%0, %2\", operands);
645         if (which_alternative != 0)
646           output_asm_insn (\"it\\t%d4\;mov%d4\\t%0, %1\", operands);
647         return \"\";
648       }
649     switch (which_alternative)
650       {
651       case 0:
652         output_asm_insn (\"it\\t%d4\", operands);
653         break;
654       case 1:
655         output_asm_insn (\"it\\t%D4\", operands);
656         break;
657       case 2:
658         output_asm_insn (\"ite\\t%D4\", operands);
659         break;
660       default:
661         abort();
662       }
663     if (which_alternative != 0)
664       output_asm_insn (\"mov%D4\\t%0, %1\", operands);
665     if (which_alternative != 1)
666       output_asm_insn (\"mov%d4\\t%0, %2\", operands);
667     return \"\";
668   "
669   [(set_attr "conds" "use")
670    (set_attr "length" "6,6,10")]
673 (define_insn "*thumb2_cond_arith"
674   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
675         (match_operator:SI 5 "shiftable_operator" 
676          [(match_operator:SI 4 "arm_comparison_operator"
677            [(match_operand:SI 2 "s_register_operand" "r,r")
678             (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
679           (match_operand:SI 1 "s_register_operand" "0,?r")]))
680    (clobber (reg:CC CC_REGNUM))]
681   "TARGET_THUMB2"
682   "*
683     if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
684       return \"%i5\\t%0, %1, %2, lsr #31\";
686     output_asm_insn (\"cmp\\t%2, %3\", operands);
687     if (GET_CODE (operands[5]) == AND)
688       {
689         output_asm_insn (\"ite\\t%D4\", operands);
690         output_asm_insn (\"mov%D4\\t%0, #0\", operands);
691       }
692     else if (GET_CODE (operands[5]) == MINUS)
693       {
694         output_asm_insn (\"ite\\t%D4\", operands);
695         output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
696       }
697     else if (which_alternative != 0)
698       {
699         output_asm_insn (\"ite\\t%D4\", operands);
700         output_asm_insn (\"mov%D4\\t%0, %1\", operands);
701       }
702     else
703       output_asm_insn (\"it\\t%d4\", operands);
704     return \"%i5%d4\\t%0, %1, #1\";
705   "
706   [(set_attr "conds" "clob")
707    (set_attr "length" "14")]
710 (define_insn "*thumb2_cond_sub"
711   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
712         (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r")
713                   (match_operator:SI 4 "arm_comparison_operator"
714                    [(match_operand:SI 2 "s_register_operand" "r,r")
715                     (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
716    (clobber (reg:CC CC_REGNUM))]
717   "TARGET_THUMB2"
718   "*
719     output_asm_insn (\"cmp\\t%2, %3\", operands);
720     if (which_alternative != 0)
721       {
722         output_asm_insn (\"ite\\t%D4\", operands);
723         output_asm_insn (\"mov%D4\\t%0, %1\", operands);
724       }
725     else
726       output_asm_insn (\"it\\t%d4\", operands);
727     return \"sub%d4\\t%0, %1, #1\";
728   "
729   [(set_attr "conds" "clob")
730    (set_attr "length" "10,14")]
733 (define_insn "*thumb2_negscc"
734   [(set (match_operand:SI 0 "s_register_operand" "=r")
735         (neg:SI (match_operator 3 "arm_comparison_operator"
736                  [(match_operand:SI 1 "s_register_operand" "r")
737                   (match_operand:SI 2 "arm_rhs_operand" "rI")])))
738    (clobber (reg:CC CC_REGNUM))]
739   "TARGET_THUMB2"
740   "*
741   if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
742     return \"asr\\t%0, %1, #31\";
744   if (GET_CODE (operands[3]) == NE)
745     return \"subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0\";
747   output_asm_insn (\"cmp\\t%1, %2\", operands);
748   output_asm_insn (\"ite\\t%D3\", operands);
749   output_asm_insn (\"mov%D3\\t%0, #0\", operands);
750   return \"mvn%d3\\t%0, #0\";
751   "
752   [(set_attr "conds" "clob")
753    (set_attr "length" "14")]
756 (define_insn "*thumb2_movcond"
757   [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
758         (if_then_else:SI
759          (match_operator 5 "arm_comparison_operator"
760           [(match_operand:SI 3 "s_register_operand" "r,r,r")
761            (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
762          (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
763          (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))
764    (clobber (reg:CC CC_REGNUM))]
765   "TARGET_THUMB2"
766   "*
767   if (GET_CODE (operands[5]) == LT
768       && (operands[4] == const0_rtx))
769     {
770       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
771         {
772           if (operands[2] == const0_rtx)
773             return \"and\\t%0, %1, %3, asr #31\";
774           return \"ands\\t%0, %1, %3, asr #32\;it\\tcc\;movcc\\t%0, %2\";
775         }
776       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
777         {
778           if (operands[1] == const0_rtx)
779             return \"bic\\t%0, %2, %3, asr #31\";
780           return \"bics\\t%0, %2, %3, asr #32\;it\\tcs\;movcs\\t%0, %1\";
781         }
782       /* The only case that falls through to here is when both ops 1 & 2
783          are constants.  */
784     }
786   if (GET_CODE (operands[5]) == GE
787       && (operands[4] == const0_rtx))
788     {
789       if (which_alternative != 1 && GET_CODE (operands[1]) == REG)
790         {
791           if (operands[2] == const0_rtx)
792             return \"bic\\t%0, %1, %3, asr #31\";
793           return \"bics\\t%0, %1, %3, asr #32\;it\\tcs\;movcs\\t%0, %2\";
794         }
795       else if (which_alternative != 0 && GET_CODE (operands[2]) == REG)
796         {
797           if (operands[1] == const0_rtx)
798             return \"and\\t%0, %2, %3, asr #31\";
799           return \"ands\\t%0, %2, %3, asr #32\;it\tcc\;movcc\\t%0, %1\";
800         }
801       /* The only case that falls through to here is when both ops 1 & 2
802          are constants.  */
803     }
804   if (GET_CODE (operands[4]) == CONST_INT
805       && !const_ok_for_arm (INTVAL (operands[4])))
806     output_asm_insn (\"cmn\\t%3, #%n4\", operands);
807   else
808     output_asm_insn (\"cmp\\t%3, %4\", operands);
809   switch (which_alternative)
810     {
811     case 0:
812       output_asm_insn (\"it\\t%D5\", operands);
813       break;
814     case 1:
815       output_asm_insn (\"it\\t%d5\", operands);
816       break;
817     case 2:
818       output_asm_insn (\"ite\\t%d5\", operands);
819       break;
820     default:
821       abort();
822     }
823   if (which_alternative != 0)
824     output_asm_insn (\"mov%d5\\t%0, %1\", operands);
825   if (which_alternative != 1)
826     output_asm_insn (\"mov%D5\\t%0, %2\", operands);
827   return \"\";
828   "
829   [(set_attr "conds" "clob")
830    (set_attr "length" "10,10,14")]
833 ;; Zero and sign extension instructions.
835 (define_insn_and_split "*thumb2_zero_extendsidi2"
836   [(set (match_operand:DI 0 "s_register_operand" "=r")
837         (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
838   "TARGET_THUMB2"
839   "mov%?\\t%Q0, %1\;mov%?\\t%R0, #0"
840   "&& reload_completed"
841   [(set (match_dup 0) (match_dup 1))]
842   "
843   {
844     rtx lo_part = gen_lowpart (SImode, operands[0]);
845     if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
846       emit_move_insn (lo_part, operands[1]);
847     operands[0] = gen_highpart (SImode, operands[0]);
848     operands[1] = const0_rtx;
849   }
850   "
851   [(set_attr "length" "8")
852    (set_attr "ce_count" "2")
853    (set_attr "predicable" "yes")]
856 (define_insn_and_split "*thumb2_zero_extendhidi2"
857   [(set (match_operand:DI                 0 "s_register_operand"  "=r,r")
858         (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
859   "TARGET_THUMB2"
860   "@
861    uxth%?\\t%Q0, %1\;mov%?\\t%R0, #0
862    ldr%(h%)\\t%Q0, %1\;mov%?\\t%R0, #0"
863   "&& reload_completed"
864   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
865    (set (match_dup 2) (match_dup 3))]
866   "
867   {
868     operands[2] = gen_highpart (SImode, operands[0]);
869     operands[0] = gen_lowpart (SImode, operands[0]);
870     operands[3] = const0_rtx;
871   }
872   "
873   [(set_attr "length" "8")
874    (set_attr "ce_count" "2")
875    (set_attr "predicable" "yes")
876    (set_attr "type" "*,load_byte")
877    (set_attr "pool_range" "*,4092")
878    (set_attr "neg_pool_range" "*,250")]
881 (define_insn_and_split "*thumb2_zero_extendqidi2"
882   [(set (match_operand:DI                 0 "s_register_operand"  "=r,r")
883         (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
884   "TARGET_THUMB2"
885   "@
886    uxtb%?\\t%Q0, %1\;mov%?\\t%R0, #0
887    ldr%(b%)\\t%Q0, %1\;mov%?\\t%R0, #0"
888   "&& reload_completed"
889   [(set (match_dup 0) (zero_extend:SI (match_dup 1)))
890    (set (match_dup 2) (match_dup 3))]
891   "
892   {
893     operands[2] = gen_highpart (SImode, operands[0]);
894     operands[0] = gen_lowpart (SImode, operands[0]);
895     operands[3] = const0_rtx;
896   }
897   "
898   [(set_attr "length" "8")
899    (set_attr "ce_count" "2")
900    (set_attr "predicable" "yes")
901    (set_attr "type" "*,load_byte")
902    (set_attr "pool_range" "*,4092")
903    (set_attr "neg_pool_range" "*,250")]
906 (define_insn_and_split "*thumb2_extendsidi2"
907   [(set (match_operand:DI 0 "s_register_operand" "=r")
908         (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))]
909   "TARGET_THUMB2"
910   "mov%?\\t%Q0, %1\;asr?\\t%R0, %1, #31"
911   "&& reload_completed"
912   [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))]
913   {
914     rtx lo_part = gen_lowpart (SImode, operands[0]);
916     if (!REG_P (lo_part) || REGNO (lo_part) != REGNO (operands[1]))
917       emit_move_insn (lo_part, operands[1]);
918     operands[0] = gen_highpart (SImode, operands[0]);
919   }
920   [(set_attr "length" "8")
921    (set_attr "ce_count" "2")
922    (set_attr "shift" "1")
923    (set_attr "predicable" "yes")]
926 (define_insn_and_split "*thumb2_extendhidi2"
927   [(set (match_operand:DI                 0 "s_register_operand"  "=r,r")
928         (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
929   "TARGET_THUMB2"
930   "@
931    sxth%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
932    ldrsh%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
933   "&& reload_completed"
934   [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
935    (set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
936   "
937   {
938     operands[2] = gen_highpart (SImode, operands[0]);
939     operands[0] = gen_lowpart (SImode, operands[0]);
940   }
941   "
942   [(set_attr "length" "8")
943    (set_attr "ce_count" "2")
944    (set_attr "predicable" "yes")
945    (set_attr "type" "*,load_byte")
946    (set_attr "pool_range" "*,4092")
947    (set_attr "neg_pool_range" "*,250")]
950 (define_insn_and_split "*thumb2_extendqidi2"
951   [(set (match_operand:DI                 0 "s_register_operand"  "=r,r")
952         (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
953   "TARGET_THUMB2"
954   "@
955    sxtb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31
956    ldrsb%?\\t%Q0, %1\;asr%?\\t%R0, %Q0, #31"
957   "&& reload_completed"
958   [(set (match_dup 0) (sign_extend:SI (match_dup 1)))
959    (set (match_dup 2) (ashiftrt:SI (match_dup 0) (const_int 31)))]
960   "
961   {
962     operands[2] = gen_highpart (SImode, operands[0]);
963     operands[0] = gen_lowpart (SImode, operands[0]);
964   }
965   "
966   [(set_attr "length" "8")
967    (set_attr "ce_count" "2")
968    (set_attr "predicable" "yes")
969    (set_attr "type" "*,load_byte")
970    (set_attr "pool_range" "*,4092")
971    (set_attr "neg_pool_range" "*,250")]
974 ;; All supported Thumb2 implementations are armv6, so only that case is
975 ;; provided.
976 (define_insn "*thumb2_extendqisi_v6"
977   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
978         (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
979   "TARGET_THUMB2 && arm_arch6"
980   "@
981    sxtb%?\\t%0, %1
982    ldr%(sb%)\\t%0, %1"
983   [(set_attr "type" "alu_shift,load_byte")
984    (set_attr "predicable" "yes")
985    (set_attr "pool_range" "*,4096")
986    (set_attr "neg_pool_range" "*,250")]
989 (define_insn "*thumb2_zero_extendhisi2_v6"
990   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
991         (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
992   "TARGET_THUMB2 && arm_arch6"
993   "@
994    uxth%?\\t%0, %1
995    ldr%(h%)\\t%0, %1"
996   [(set_attr "type" "alu_shift,load_byte")
997    (set_attr "predicable" "yes")
998    (set_attr "pool_range" "*,4096")
999    (set_attr "neg_pool_range" "*,250")]
1002 (define_insn "*thumb2_zero_extendqisi2_v6"
1003   [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1004         (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1005   "TARGET_THUMB2 && arm_arch6"
1006   "@
1007    uxtb%(%)\\t%0, %1
1008    ldr%(b%)\\t%0, %1\\t%@ zero_extendqisi2"
1009   [(set_attr "type" "alu_shift,load_byte")
1010    (set_attr "predicable" "yes")
1011    (set_attr "pool_range" "*,4096")
1012    (set_attr "neg_pool_range" "*,250")]
1015 (define_insn "thumb2_casesi_internal"
1016   [(parallel [(set (pc)
1017                (if_then_else
1018                 (leu (match_operand:SI 0 "s_register_operand" "r")
1019                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
1020                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
1021                                  (label_ref (match_operand 2 "" ""))))
1022                 (label_ref (match_operand 3 "" ""))))
1023               (clobber (reg:CC CC_REGNUM))
1024               (clobber (match_scratch:SI 4 "=&r"))
1025               (use (label_ref (match_dup 2)))])]
1026   "TARGET_THUMB2 && !flag_pic"
1027   "* return thumb2_output_casesi(operands);"
1028   [(set_attr "conds" "clob")
1029    (set_attr "length" "16")]
1032 (define_insn "thumb2_casesi_internal_pic"
1033   [(parallel [(set (pc)
1034                (if_then_else
1035                 (leu (match_operand:SI 0 "s_register_operand" "r")
1036                      (match_operand:SI 1 "arm_rhs_operand" "rI"))
1037                 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
1038                                  (label_ref (match_operand 2 "" ""))))
1039                 (label_ref (match_operand 3 "" ""))))
1040               (clobber (reg:CC CC_REGNUM))
1041               (clobber (match_scratch:SI 4 "=&r"))
1042               (clobber (match_scratch:SI 5 "=r"))
1043               (use (label_ref (match_dup 2)))])]
1044   "TARGET_THUMB2 && flag_pic"
1045   "* return thumb2_output_casesi(operands);"
1046   [(set_attr "conds" "clob")
1047    (set_attr "length" "20")]
1050 (define_insn_and_split "thumb2_eh_return"
1051   [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
1052                     VUNSPEC_EH_RETURN)
1053    (clobber (match_scratch:SI 1 "=&r"))]
1054   "TARGET_THUMB2"
1055   "#"
1056   "&& reload_completed"
1057   [(const_int 0)]
1058   "
1059   {
1060     thumb_set_return_address (operands[0], operands[1]);
1061     DONE;
1062   }"
1065 ;; Peepholes and insns for 16-bit flag clobbering instructions.
1066 ;; The conditional forms of these instructions do not clobber CC.
1067 ;; However by the time peepholes are run it is probably too late to do
1068 ;; anything useful with this information.
1069 (define_peephole2
1070   [(set (match_operand:SI          0 "low_register_operand" "")
1071         (match_operator:SI 3 "thumb_16bit_operator"
1072          [(match_operand:SI 1  "low_register_operand" "")
1073           (match_operand:SI 2 "low_register_operand" "")]))]
1074   "TARGET_THUMB2
1075    && (rtx_equal_p(operands[0], operands[1])
1076        || GET_CODE(operands[3]) == PLUS
1077        || GET_CODE(operands[3]) == MINUS)
1078    && peep2_regno_dead_p(0, CC_REGNUM)"
1079   [(parallel
1080     [(set (match_dup 0)
1081           (match_op_dup 3
1082            [(match_dup 1)
1083             (match_dup 2)]))
1084      (clobber (reg:CC CC_REGNUM))])]
1085   ""
1088 (define_insn "*thumb2_alusi3_short"
1089   [(set (match_operand:SI          0 "s_register_operand" "=l")
1090         (match_operator:SI 3 "thumb_16bit_operator"
1091          [(match_operand:SI 1 "s_register_operand" "0")
1092           (match_operand:SI 2 "s_register_operand" "l")]))
1093    (clobber (reg:CC CC_REGNUM))]
1094   "TARGET_THUMB2 && reload_completed
1095    && GET_CODE(operands[3]) != PLUS
1096    && GET_CODE(operands[3]) != MINUS"
1097   "%I3%!\\t%0, %1, %2"
1098   [(set_attr "predicable" "yes")
1099    (set_attr "length" "2")]
1102 ;; Similarly for 16-bit shift instructions
1103 ;; There is no 16-bit rotate by immediate instruction.
1104 (define_peephole2
1105   [(set (match_operand:SI   0 "low_register_operand" "")
1106         (match_operator:SI  3 "shift_operator"
1107          [(match_operand:SI 1 "low_register_operand" "")
1108           (match_operand:SI 2 "low_reg_or_int_operand" "")]))]
1109   "TARGET_THUMB2
1110    && peep2_regno_dead_p(0, CC_REGNUM)
1111    && ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
1112        || REG_P(operands[2]))"
1113   [(parallel
1114     [(set (match_dup 0)
1115           (match_op_dup 3
1116            [(match_dup 1)
1117             (match_dup 2)]))
1118      (clobber (reg:CC CC_REGNUM))])]
1119   ""
1122 (define_insn "*thumb2_shiftsi3_short"
1123   [(set (match_operand:SI   0 "low_register_operand" "=l")
1124         (match_operator:SI  3 "shift_operator"
1125          [(match_operand:SI 1 "low_register_operand"  "l")
1126           (match_operand:SI 2 "low_reg_or_int_operand" "lM")]))
1127    (clobber (reg:CC CC_REGNUM))]
1128   "TARGET_THUMB2 && reload_completed
1129    && ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
1130        || REG_P(operands[2]))"
1131   "* return arm_output_shift(operands, 2);"
1132   [(set_attr "predicable" "yes")
1133    (set_attr "shift" "1")
1134    (set_attr "length" "2")
1135    (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
1136                       (const_string "alu_shift")
1137                       (const_string "alu_shift_reg")))]
1140 ;; 16-bit load immediate
1141 (define_peephole2
1142   [(set (match_operand:QHSI 0 "low_register_operand" "")
1143         (match_operand:QHSI 1 "const_int_operand" ""))]
1144   "TARGET_THUMB2
1145    && peep2_regno_dead_p(0, CC_REGNUM)
1146    && (unsigned HOST_WIDE_INT) INTVAL(operands[1]) < 256"
1147   [(parallel
1148     [(set (match_dup 0)
1149           (match_dup 1))
1150      (clobber (reg:CC CC_REGNUM))])]
1151   ""
1154 (define_insn "*thumb2_mov<mode>_shortim"
1155   [(set (match_operand:QHSI 0 "low_register_operand" "=l")
1156         (match_operand:QHSI 1 "const_int_operand" "I"))
1157    (clobber (reg:CC CC_REGNUM))]
1158   "TARGET_THUMB2 && reload_completed"
1159   "mov%!\t%0, %1"
1160   [(set_attr "predicable" "yes")
1161    (set_attr "length" "2")]
1164 ;; 16-bit add/sub immediate
1165 (define_peephole2
1166   [(set (match_operand:SI 0 "low_register_operand" "")
1167         (plus:SI (match_operand:SI 1 "low_register_operand" "")
1168                  (match_operand:SI 2 "const_int_operand" "")))]
1169   "TARGET_THUMB2
1170    && peep2_regno_dead_p(0, CC_REGNUM)
1171    && ((rtx_equal_p(operands[0], operands[1])
1172         && INTVAL(operands[2]) > -256 && INTVAL(operands[2]) < 256)
1173        || (INTVAL(operands[2]) > -8 && INTVAL(operands[2]) < 8))"
1174   [(parallel
1175     [(set (match_dup 0)
1176           (plus:SI (match_dup 1)
1177                    (match_dup 2)))
1178      (clobber (reg:CC CC_REGNUM))])]
1179   ""
1182 (define_insn "*thumb2_addsi_short"
1183   [(set (match_operand:SI 0 "low_register_operand" "=l,l")
1184         (plus:SI (match_operand:SI 1 "low_register_operand" "l,0")
1185                  (match_operand:SI 2 "low_reg_or_int_operand" "lPt,Ps")))
1186    (clobber (reg:CC CC_REGNUM))]
1187   "TARGET_THUMB2 && reload_completed"
1188   "*
1189     HOST_WIDE_INT val;
1191     if (GET_CODE (operands[2]) == CONST_INT)
1192       val = INTVAL(operands[2]);
1193     else
1194       val = 0;
1196     /* We prefer eg. subs rn, rn, #1 over adds rn, rn, #0xffffffff.  */
1197     if (val < 0 && const_ok_for_arm(ARM_SIGN_EXTEND (-val)))
1198       return \"sub%!\\t%0, %1, #%n2\";
1199     else
1200       return \"add%!\\t%0, %1, %2\";
1201   "
1202   [(set_attr "predicable" "yes")
1203    (set_attr "length" "2")]
1206 (define_insn "divsi3"
1207   [(set (match_operand:SI         0 "s_register_operand" "=r")
1208         (div:SI (match_operand:SI 1 "s_register_operand"  "r")
1209                 (match_operand:SI 2 "s_register_operand"  "r")))]
1210   "TARGET_THUMB2 && arm_arch_hwdiv"
1211   "sdiv%?\t%0, %1, %2"
1212   [(set_attr "predicable" "yes")
1213    (set_attr "insn" "sdiv")]
1216 (define_insn "udivsi3"
1217   [(set (match_operand:SI          0 "s_register_operand" "=r")
1218         (udiv:SI (match_operand:SI 1 "s_register_operand"  "r")
1219                  (match_operand:SI 2 "s_register_operand"  "r")))]
1220   "TARGET_THUMB2 && arm_arch_hwdiv"
1221   "udiv%?\t%0, %1, %2"
1222   [(set_attr "predicable" "yes")
1223    (set_attr "insn" "udiv")]
1226 (define_insn "*thumb2_subsi_short"
1227   [(set (match_operand:SI 0 "low_register_operand" "=l")
1228         (minus:SI (match_operand:SI 1 "low_register_operand" "l")
1229                   (match_operand:SI 2 "low_register_operand" "l")))
1230    (clobber (reg:CC CC_REGNUM))]
1231   "TARGET_THUMB2 && reload_completed"
1232   "sub%!\\t%0, %1, %2"
1233   [(set_attr "predicable" "yes")
1234    (set_attr "length" "2")]
1237 ;; 16-bit encodings of "muls" and "mul<c>".  We only use these when
1238 ;; optimizing for size since "muls" is slow on all known
1239 ;; implementations and since "mul<c>" will be generated by
1240 ;; "*arm_mulsi3_v6" anyhow.  The assembler will use a 16-bit encoding
1241 ;; for "mul<c>" whenever possible anyhow.
1242 (define_peephole2
1243   [(set (match_operand:SI 0 "low_register_operand" "")
1244         (mult:SI (match_operand:SI 1 "low_register_operand" "")
1245                  (match_dup 0)))]
1246   "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
1247   [(parallel
1248     [(set (match_dup 0)
1249            (mult:SI (match_dup 0) (match_dup 1)))
1250      (clobber (reg:CC CC_REGNUM))])]
1251   ""
1254 (define_peephole2
1255   [(set (match_operand:SI 0 "low_register_operand" "")
1256         (mult:SI (match_dup 0)
1257                  (match_operand:SI 1 "low_register_operand" "")))]
1258   "TARGET_THUMB2 && optimize_size && peep2_regno_dead_p (0, CC_REGNUM)"
1259   [(parallel
1260     [(set (match_dup 0)
1261            (mult:SI (match_dup 0) (match_dup 1)))
1262      (clobber (reg:CC CC_REGNUM))])]
1263   ""
1266 (define_insn "*thumb2_mulsi_short"
1267   [(set (match_operand:SI 0 "low_register_operand" "=l")
1268         (mult:SI (match_operand:SI 1 "low_register_operand" "%0")
1269                  (match_operand:SI 2 "low_register_operand" "l")))
1270    (clobber (reg:CC CC_REGNUM))]
1271   "TARGET_THUMB2 && optimize_size && reload_completed"
1272   "mul%!\\t%0, %2, %0"
1273   [(set_attr "predicable" "yes")
1274    (set_attr "length" "2")
1275    (set_attr "insn" "muls")])
1277 (define_insn "*thumb2_mulsi_short_compare0"
1278   [(set (reg:CC_NOOV CC_REGNUM)
1279         (compare:CC_NOOV
1280          (mult:SI (match_operand:SI 1 "register_operand" "%0")
1281                   (match_operand:SI 2 "register_operand" "l"))
1282          (const_int 0)))
1283    (set (match_operand:SI 0 "register_operand" "=l")
1284         (mult:SI (match_dup 1) (match_dup 2)))]
1285   "TARGET_THUMB2 && optimize_size"
1286   "muls\\t%0, %2, %0"
1287   [(set_attr "length" "2")
1288    (set_attr "insn" "muls")])
1290 (define_insn "*thumb2_mulsi_short_compare0_scratch"
1291   [(set (reg:CC_NOOV CC_REGNUM)
1292         (compare:CC_NOOV
1293          (mult:SI (match_operand:SI 1 "register_operand" "%0")
1294                   (match_operand:SI 2 "register_operand" "l"))
1295          (const_int 0)))
1296    (clobber (match_scratch:SI 0 "=l"))]
1297   "TARGET_THUMB2 && optimize_size"
1298   "muls\\t%0, %2, %0"
1299   [(set_attr "length" "2")
1300    (set_attr "insn" "muls")])
1302 (define_insn "*thumb2_cbz"
1303   [(set (pc) (if_then_else
1304               (eq (match_operand:SI 0 "s_register_operand" "l,?r")
1305                   (const_int 0))
1306               (label_ref (match_operand 1 "" ""))
1307               (pc)))
1308    (clobber (reg:CC CC_REGNUM))]
1309   "TARGET_THUMB2"
1310   "*
1311   if (get_attr_length (insn) == 2)
1312     return \"cbz\\t%0, %l1\";
1313   else
1314     return \"cmp\\t%0, #0\;beq\\t%l1\";
1315   "
1316   [(set (attr "length") 
1317         (if_then_else
1318             (and (ge (minus (match_dup 1) (pc)) (const_int 2))
1319                  (le (minus (match_dup 1) (pc)) (const_int 128))
1320                  (eq (symbol_ref ("which_alternative")) (const_int 0)))
1321             (const_int 2)
1322             (const_int 8)))]
1325 (define_insn "*thumb2_cbnz"
1326   [(set (pc) (if_then_else
1327               (ne (match_operand:SI 0 "s_register_operand" "l,?r")
1328                   (const_int 0))
1329               (label_ref (match_operand 1 "" ""))
1330               (pc)))
1331    (clobber (reg:CC CC_REGNUM))]
1332   "TARGET_THUMB2"
1333   "*
1334   if (get_attr_length (insn) == 2)
1335     return \"cbnz\\t%0, %l1\";
1336   else
1337     return \"cmp\\t%0, #0\;bne\\t%l1\";
1338   "
1339   [(set (attr "length") 
1340         (if_then_else
1341             (and (ge (minus (match_dup 1) (pc)) (const_int 2))
1342                  (le (minus (match_dup 1) (pc)) (const_int 128))
1343                  (eq (symbol_ref ("which_alternative")) (const_int 0)))
1344             (const_int 2)
1345             (const_int 8)))]
1348 ;; 16-bit complement
1349 (define_peephole2
1350   [(set (match_operand:SI 0 "low_register_operand" "")
1351         (not:SI (match_operand:SI 1 "low_register_operand" "")))]
1352   "TARGET_THUMB2
1353    && peep2_regno_dead_p(0, CC_REGNUM)"
1354   [(parallel
1355     [(set (match_dup 0)
1356           (not:SI (match_dup 1)))
1357      (clobber (reg:CC CC_REGNUM))])]
1358   ""
1361 (define_insn "*thumb2_one_cmplsi2_short"
1362   [(set (match_operand:SI 0 "low_register_operand" "=l")
1363         (not:SI (match_operand:SI 1 "low_register_operand" "l")))
1364    (clobber (reg:CC CC_REGNUM))]
1365   "TARGET_THUMB2 && reload_completed"
1366   "mvn%!\t%0, %1"
1367   [(set_attr "predicable" "yes")
1368    (set_attr "length" "2")]
1371 ;; 16-bit negate
1372 (define_peephole2
1373   [(set (match_operand:SI 0 "low_register_operand" "")
1374         (neg:SI (match_operand:SI 1 "low_register_operand" "")))]
1375   "TARGET_THUMB2
1376    && peep2_regno_dead_p(0, CC_REGNUM)"
1377   [(parallel
1378     [(set (match_dup 0)
1379           (neg:SI (match_dup 1)))
1380      (clobber (reg:CC CC_REGNUM))])]
1381   ""
1384 (define_insn "*thumb2_negsi2_short"
1385   [(set (match_operand:SI 0 "low_register_operand" "=l")
1386         (neg:SI (match_operand:SI 1 "low_register_operand" "l")))
1387    (clobber (reg:CC CC_REGNUM))]
1388   "TARGET_THUMB2 && reload_completed"
1389   "neg%!\t%0, %1"
1390   [(set_attr "predicable" "yes")
1391    (set_attr "length" "2")]
1394 (define_insn "orsi_notsi_si"
1395   [(set (match_operand:SI 0 "s_register_operand" "=r")
1396         (ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
1397                 (match_operand:SI 1 "s_register_operand" "r")))]
1398   "TARGET_THUMB2"
1399   "orn%?\\t%0, %1, %2"
1400   [(set_attr "predicable" "yes")]
1403 (define_insn "*thumb_orsi_not_shiftsi_si"
1404   [(set (match_operand:SI 0 "s_register_operand" "=r")
1405         (ior:SI (not:SI (match_operator:SI 4 "shift_operator"
1406                          [(match_operand:SI 2 "s_register_operand" "r")
1407                           (match_operand:SI 3 "const_int_operand" "M")]))
1408                 (match_operand:SI 1 "s_register_operand" "r")))]
1409   "TARGET_THUMB2"
1410   "orn%?\\t%0, %1, %2%S4"
1411   [(set_attr "predicable" "yes")
1412    (set_attr "shift" "2")
1413    (set_attr "type" "alu_shift")]
1416 (define_insn_and_split "*thumb2_iorsi3"
1417   [(set (match_operand:SI         0 "s_register_operand" "=r,r,r")
1418         (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,r")
1419                 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))]
1420   "TARGET_THUMB2"
1421   "@
1422    orr%?\\t%0, %1, %2
1423    orn%?\\t%0, %1, #%B2
1424    #"
1425   "TARGET_THUMB2
1426    && GET_CODE (operands[2]) == CONST_INT
1427    && !(const_ok_for_arm (INTVAL (operands[2]))
1428         || const_ok_for_arm (~INTVAL (operands[2])))"
1429   [(clobber (const_int 0))]
1430   "
1431   arm_split_constant  (IOR, SImode, curr_insn, 
1432                        INTVAL (operands[2]), operands[0], operands[1], 0);
1433   DONE;
1434   "
1435   [(set_attr "length" "4,4,16")
1436    (set_attr "predicable" "yes")]