]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/config/arm/thumb2.md
arm: force use of r4 for __gnu_cmse_nonsecure_call when !FPCXT [PR99271]
[thirdparty/gcc.git] / gcc / config / arm / thumb2.md
CommitLineData
5b3e6663 1;; ARM Thumb-2 Machine Description
99dee823 2;; Copyright (C) 2007-2021 Free Software Foundation, Inc.
5b3e6663
PB
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
2f83c7d6 9;; the Free Software Foundation; either version 3, or (at your option)
5b3e6663
PB
10;; any later version.
11;;
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.
16;;
17;; You should have received a copy of the GNU General Public License
2f83c7d6
NC
18;; along with GCC; see the file COPYING3. If not see
19;; <http://www.gnu.org/licenses/>. */
5b3e6663
PB
20
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.
26
95b97fac
KT
27;; We use the '0' constraint for operand 1 because reload should
28;; be smart enough to generate an appropriate move for the r/r/r case.
0a7dbb76 29(define_insn_and_split "*thumb2_smaxsi3"
95b97fac
KT
30 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
31 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
32 (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
5b3e6663 33 (clobber (reg:CC CC_REGNUM))]
95b97fac
KT
34 "TARGET_THUMB2"
35 "#"
36 ; cmp\\t%1, %2\;it\\tlt\;movlt\\t%0, %2
37 "TARGET_THUMB2 && reload_completed"
0a7dbb76
GY
38 [(set (reg:CC CC_REGNUM)
39 (compare:CC (match_dup 1) (match_dup 2)))
95b97fac
KT
40 (cond_exec (lt:SI (reg:CC CC_REGNUM) (const_int 0))
41 (set (match_dup 0)
42 (match_dup 2)))]
0a7dbb76 43 ""
5b3e6663 44 [(set_attr "conds" "clob")
113c53c3 45 (set_attr "enabled_for_short_it" "yes,yes,no")
594726e4
JG
46 (set_attr "length" "6,6,10")
47 (set_attr "type" "multiple")]
5b3e6663
PB
48)
49
0a7dbb76 50(define_insn_and_split "*thumb2_sminsi3"
95b97fac
KT
51 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
52 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
53 (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
5b3e6663
PB
54 (clobber (reg:CC CC_REGNUM))]
55 "TARGET_THUMB2"
0a7dbb76 56 "#"
95b97fac
KT
57 ; cmp\\t%1, %2\;it\\tge\;movge\\t%0, %2
58 "TARGET_THUMB2 && reload_completed"
0a7dbb76
GY
59 [(set (reg:CC CC_REGNUM)
60 (compare:CC (match_dup 1) (match_dup 2)))
95b97fac
KT
61 (cond_exec (ge:SI (reg:CC CC_REGNUM) (const_int 0))
62 (set (match_dup 0)
63 (match_dup 2)))]
0a7dbb76 64 ""
5b3e6663 65 [(set_attr "conds" "clob")
113c53c3 66 (set_attr "enabled_for_short_it" "yes,yes,no")
594726e4
JG
67 (set_attr "length" "6,6,10")
68 (set_attr "type" "multiple")]
5b3e6663
PB
69)
70
0a7dbb76 71(define_insn_and_split "*thumb32_umaxsi3"
95b97fac
KT
72 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
73 (umax:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
74 (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
75 (clobber (reg:CC CC_REGNUM))]
5b3e6663 76 "TARGET_THUMB2"
0a7dbb76 77 "#"
95b97fac
KT
78 ; cmp\\t%1, %2\;it\\tcc\;movcc\\t%0, %2
79 "TARGET_THUMB2 && reload_completed"
0a7dbb76
GY
80 [(set (reg:CC CC_REGNUM)
81 (compare:CC (match_dup 1) (match_dup 2)))
95b97fac
KT
82 (cond_exec (ltu:SI (reg:CC CC_REGNUM) (const_int 0))
83 (set (match_dup 0)
84 (match_dup 2)))]
0a7dbb76 85 ""
5b3e6663 86 [(set_attr "conds" "clob")
95b97fac 87 (set_attr "length" "6,6,10")
113c53c3 88 (set_attr "enabled_for_short_it" "yes,yes,no")
594726e4 89 (set_attr "type" "multiple")]
5b3e6663
PB
90)
91
0a7dbb76 92(define_insn_and_split "*thumb2_uminsi3"
95b97fac
KT
93 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r")
94 (umin:SI (match_operand:SI 1 "s_register_operand" "%0,0,0")
95 (match_operand:SI 2 "arm_rhs_operand" "r,Py,I")))
5b3e6663
PB
96 (clobber (reg:CC CC_REGNUM))]
97 "TARGET_THUMB2"
0a7dbb76 98 "#"
95b97fac
KT
99 ; cmp\\t%1, %2\;it\\tcs\;movcs\\t%0, %2
100 "TARGET_THUMB2 && reload_completed"
0a7dbb76
GY
101 [(set (reg:CC CC_REGNUM)
102 (compare:CC (match_dup 1) (match_dup 2)))
95b97fac
KT
103 (cond_exec (geu:SI (reg:CC CC_REGNUM) (const_int 0))
104 (set (match_dup 0)
105 (match_dup 2)))]
0a7dbb76 106 ""
5b3e6663 107 [(set_attr "conds" "clob")
95b97fac 108 (set_attr "length" "6,6,10")
113c53c3 109 (set_attr "enabled_for_short_it" "yes,yes,no")
594726e4 110 (set_attr "type" "multiple")]
5b3e6663
PB
111)
112
0a7dbb76 113(define_insn_and_split "*thumb2_abssi2"
95b97fac
KT
114 [(set (match_operand:SI 0 "s_register_operand" "=&r,l,r")
115 (abs:SI (match_operand:SI 1 "s_register_operand" "r,0,0")))
5b3e6663
PB
116 (clobber (reg:CC CC_REGNUM))]
117 "TARGET_THUMB2"
0a7dbb76 118 "#"
0a7dbb76 119 ; eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31
95b97fac
KT
120 ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
121 ; cmp\\t%0, #0\;it\tlt\;rsblt\\t%0, %0, #0
0a7dbb76
GY
122 "&& reload_completed"
123 [(const_int 0)]
124 {
0a7dbb76
GY
125 if (REGNO(operands[0]) == REGNO(operands[1]))
126 {
127 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
128
f7df4a84
RS
129 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (CCmode, operands[0],
130 const0_rtx)));
0a7dbb76
GY
131 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
132 (gen_rtx_LT (SImode,
133 cc_reg,
134 const0_rtx)),
f7df4a84 135 (gen_rtx_SET (operands[0],
0a7dbb76
GY
136 (gen_rtx_MINUS (SImode,
137 const0_rtx,
138 operands[1]))))));
139 }
140 else
141 {
f7df4a84 142 emit_insn (gen_rtx_SET (operands[0],
0a7dbb76
GY
143 gen_rtx_XOR (SImode,
144 gen_rtx_ASHIFTRT (SImode,
145 operands[1],
146 GEN_INT (31)),
147 operands[1])));
f7df4a84 148 emit_insn (gen_rtx_SET (operands[0],
0a7dbb76
GY
149 gen_rtx_MINUS (SImode,
150 operands[0],
151 gen_rtx_ASHIFTRT (SImode,
152 operands[1],
153 GEN_INT (31)))));
154 }
155 DONE;
156 }
95b97fac 157 [(set_attr "conds" "*,clob,clob")
5b3e6663 158 (set_attr "shift" "1")
95b97fac 159 (set_attr "predicable" "yes,no,no")
113c53c3 160 (set_attr "enabled_for_short_it" "yes,yes,no")
9cd9d33b 161 (set_attr "ce_count" "2")
594726e4
JG
162 (set_attr "length" "8,6,10")
163 (set_attr "type" "multiple")]
5b3e6663
PB
164)
165
0a7dbb76 166(define_insn_and_split "*thumb2_neg_abssi2"
95b97fac
KT
167 [(set (match_operand:SI 0 "s_register_operand" "=&r,l,r")
168 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "r,0,0"))))
5b3e6663
PB
169 (clobber (reg:CC CC_REGNUM))]
170 "TARGET_THUMB2"
0a7dbb76 171 "#"
95b97fac
KT
172 ; eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31
173 ; cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
0a7dbb76 174 ; cmp\\t%0, #0\;it\\tgt\;rsbgt\\t%0, %0, #0
0a7dbb76
GY
175 "&& reload_completed"
176 [(const_int 0)]
177 {
0a7dbb76
GY
178 if (REGNO(operands[0]) == REGNO(operands[1]))
179 {
180 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
181
f7df4a84
RS
182 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (CCmode, operands[0],
183 const0_rtx)));
0a7dbb76
GY
184 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
185 (gen_rtx_GT (SImode,
186 cc_reg,
187 const0_rtx)),
f7df4a84 188 (gen_rtx_SET (operands[0],
0a7dbb76
GY
189 (gen_rtx_MINUS (SImode,
190 const0_rtx,
191 operands[1]))))));
192 }
193 else
194 {
f7df4a84 195 emit_insn (gen_rtx_SET (operands[0],
0a7dbb76
GY
196 gen_rtx_XOR (SImode,
197 gen_rtx_ASHIFTRT (SImode,
198 operands[1],
199 GEN_INT (31)),
200 operands[1])));
f7df4a84 201 emit_insn (gen_rtx_SET (operands[0],
0a7dbb76
GY
202 gen_rtx_MINUS (SImode,
203 gen_rtx_ASHIFTRT (SImode,
204 operands[1],
205 GEN_INT (31)),
206 operands[0])));
207 }
208 DONE;
209 }
95b97fac 210 [(set_attr "conds" "*,clob,clob")
5b3e6663 211 (set_attr "shift" "1")
95b97fac 212 (set_attr "predicable" "yes,no,no")
113c53c3 213 (set_attr "enabled_for_short_it" "yes,yes,no")
9cd9d33b 214 (set_attr "ce_count" "2")
594726e4
JG
215 (set_attr "length" "8,6,10")
216 (set_attr "type" "multiple")]
5b3e6663
PB
217)
218
f7d2b513
JY
219;; Pop a single register as its size is preferred over a post-incremental load
220(define_insn "*thumb2_pop_single"
221 [(set (match_operand:SI 0 "low_register_operand" "=r")
222 (mem:SI (post_inc:SI (reg:SI SP_REGNUM))))]
223 "TARGET_THUMB2 && (reload_in_progress || reload_completed)"
224 "pop\t{%0}"
89b2133e 225 [(set_attr "type" "load_4")
f7d2b513
JY
226 (set_attr "length" "2")
227 (set_attr "predicable" "yes")]
228)
229
28907f9a
MS
230;; We have two alternatives here for memory loads (and similarly for stores)
231;; to reflect the fact that the permissible constant pool ranges differ
232;; between ldr instructions taking low regs and ldr instructions taking high
233;; regs. The high register alternatives are not taken into account when
234;; choosing register preferences in order to reflect their expense.
5b3e6663 235(define_insn "*thumb2_movsi_insn"
75088696
WD
236 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,l,r,r,lk*r,m")
237 (match_operand:SI 1 "general_operand" "rk,I,Py,K,j,mi,lk*r"))]
00ea1506 238 "TARGET_THUMB2 && !TARGET_IWMMXT && !TARGET_HARD_FLOAT
5b3e6663
PB
239 && ( register_operand (operands[0], SImode)
240 || register_operand (operands[1], SImode))"
8d33eae8
TP
241{
242 switch (which_alternative)
243 {
244 case 0:
245 case 1:
246 case 2:
247 return \"mov%?\\t%0, %1\";
248 case 3: return \"mvn%?\\t%0, #%B1\";
249 case 4: return \"movw%?\\t%0, %1\";
250 case 5:
8d33eae8
TP
251 /* Cannot load it directly, split to load it via MOV / MOVT. */
252 if (!MEM_P (operands[1]) && arm_disable_literal_pool)
253 return \"#\";
254 return \"ldr%?\\t%0, %1\";
75088696 255 case 6: return \"str%?\\t%1, %0\";
8d33eae8
TP
256 default: gcc_unreachable ();
257 }
258}
75088696
WD
259 [(set_attr "type" "mov_reg,mov_imm,mov_imm,mvn_imm,mov_imm,load_4,store_4")
260 (set_attr "length" "2,4,2,4,4,4,4")
5b3e6663 261 (set_attr "predicable" "yes")
75088696 262 (set_attr "predicable_short_it" "yes,no,yes,no,no,no,no")
cefbac6e 263 (set_attr "pool_range" "*,*,*,*,*,1018,*")
75088696 264 (set_attr "neg_pool_range" "*,*,*,*,*,0,*")]
5b3e6663
PB
265)
266
87d05b44 267(define_insn "tls_load_dot_plus_four"
2e5505a4
RE
268 [(set (match_operand:SI 0 "register_operand" "=l,l,r,r")
269 (mem:SI (unspec:SI [(match_operand:SI 2 "register_operand" "0,1,0,1")
87d05b44 270 (const_int 4)
2e5505a4
RE
271 (match_operand 3 "" "")]
272 UNSPEC_PIC_BASE)))
273 (clobber (match_scratch:SI 1 "=X,l,X,r"))]
5b3e6663
PB
274 "TARGET_THUMB2"
275 "*
5b3e6663 276 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\",
2e5505a4
RE
277 INTVAL (operands[3]));
278 return \"add\\t%2, %|pc\;ldr%?\\t%0, [%2]\";
5b3e6663 279 "
594726e4
JG
280 [(set_attr "length" "4,4,6,6")
281 (set_attr "type" "multiple")]
5b3e6663
PB
282)
283
284;; Thumb-2 always has load/store halfword instructions, so we can avoid a lot
44c7bd63 285;; of the messiness associated with the ARM patterns.
5b3e6663 286(define_insn "*thumb2_movhi_insn"
7cb14cb8 287 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,l,r,m,r")
0a2938ae 288 (match_operand:HI 1 "general_operand" "rk,I,Py,n,r,m"))]
c2954af9
RR
289 "TARGET_THUMB2
290 && (register_operand (operands[0], HImode)
291 || register_operand (operands[1], HImode))"
5b3e6663 292 "@
7cb14cb8
KT
293 mov%?\\t%0, %1\\t%@ movhi
294 mov%?\\t%0, %1\\t%@ movhi
5b3e6663
PB
295 mov%?\\t%0, %1\\t%@ movhi
296 movw%?\\t%0, %L1\\t%@ movhi
bae4ce0f
RR
297 strh%?\\t%1, %0\\t%@ movhi
298 ldrh%?\\t%0, %1\\t%@ movhi"
89b2133e 299 [(set_attr "type" "mov_reg,mov_imm,mov_imm,mov_imm,store_4,load_4")
5b3e6663 300 (set_attr "predicable" "yes")
7cb14cb8
KT
301 (set_attr "predicable_short_it" "yes,no,yes,no,no,no")
302 (set_attr "length" "2,4,2,4,4,4")
303 (set_attr "pool_range" "*,*,*,*,*,4094")
304 (set_attr "neg_pool_range" "*,*,*,*,*,250")]
5b3e6663
PB
305)
306
5a200acb
RE
307(define_insn "*thumb2_storewb_pairsi"
308 [(set (match_operand:SI 0 "register_operand" "=&kr")
309 (plus:SI (match_operand:SI 1 "register_operand" "0")
310 (match_operand:SI 2 "const_int_operand" "n")))
311 (set (mem:SI (plus:SI (match_dup 0) (match_dup 2)))
312 (match_operand:SI 3 "register_operand" "r"))
313 (set (mem:SI (plus:SI (match_dup 0)
314 (match_operand:SI 5 "const_int_operand" "n")))
315 (match_operand:SI 4 "register_operand" "r"))]
316 "TARGET_THUMB2
317 && INTVAL (operands[5]) == INTVAL (operands[2]) + 4"
318 "strd\\t%3, %4, [%0, %2]!"
89b2133e 319 [(set_attr "type" "store_8")]
5a200acb
RE
320)
321
0a7dbb76 322(define_insn_and_split "*thumb2_mov_scc"
95b97fac 323 [(set (match_operand:SI 0 "s_register_operand" "=l,r")
ac4bf407 324 (match_operator:SI 1 "arm_comparison_operator_mode"
5b3e6663
PB
325 [(match_operand 2 "cc_register" "") (const_int 0)]))]
326 "TARGET_THUMB2"
0a7dbb76
GY
327 "#" ; "ite\\t%D1\;mov%D1\\t%0, #0\;mov%d1\\t%0, #1"
328 "TARGET_THUMB2"
329 [(set (match_dup 0)
330 (if_then_else:SI (match_dup 1)
331 (const_int 1)
332 (const_int 0)))]
333 ""
5b3e6663 334 [(set_attr "conds" "use")
113c53c3 335 (set_attr "enabled_for_short_it" "yes,no")
594726e4
JG
336 (set_attr "length" "8,10")
337 (set_attr "type" "multiple")]
5b3e6663
PB
338)
339
0a7dbb76 340(define_insn_and_split "*thumb2_mov_negscc"
5b3e6663 341 [(set (match_operand:SI 0 "s_register_operand" "=r")
ac4bf407 342 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
5b3e6663 343 [(match_operand 2 "cc_register" "") (const_int 0)])))]
f6ff841b
RE
344 "TARGET_THUMB2
345 && !arm_restrict_it
346 && !arm_borrow_operation (operands[1], SImode)"
0a7dbb76 347 "#" ; "ite\\t%D1\;mov%D1\\t%0, #0\;mvn%d1\\t%0, #0"
86f697aa 348 "&& true"
0a7dbb76
GY
349 [(set (match_dup 0)
350 (if_then_else:SI (match_dup 1)
351 (match_dup 3)
352 (const_int 0)))]
353 {
354 operands[3] = GEN_INT (~0);
355 }
5b3e6663 356 [(set_attr "conds" "use")
594726e4
JG
357 (set_attr "length" "10")
358 (set_attr "type" "multiple")]
5b3e6663
PB
359)
360
95b97fac
KT
361(define_insn_and_split "*thumb2_mov_negscc_strict_it"
362 [(set (match_operand:SI 0 "low_register_operand" "=l")
ac4bf407 363 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode"
95b97fac 364 [(match_operand 2 "cc_register" "") (const_int 0)])))]
f6ff841b
RE
365 "TARGET_THUMB2
366 && arm_restrict_it
367 && !arm_borrow_operation (operands[1], SImode)"
95b97fac
KT
368 "#" ; ";mvn\\t%0, #0 ;it\\t%D1\;mov%D1\\t%0, #0\"
369 "&& reload_completed"
370 [(set (match_dup 0)
371 (match_dup 3))
372 (cond_exec (match_dup 4)
373 (set (match_dup 0)
374 (const_int 0)))]
375 {
376 operands[3] = GEN_INT (~0);
ef4bddc2 377 machine_mode mode = GET_MODE (operands[2]);
95b97fac
KT
378 enum rtx_code rc = GET_CODE (operands[1]);
379
380 if (mode == CCFPmode || mode == CCFPEmode)
381 rc = reverse_condition_maybe_unordered (rc);
382 else
383 rc = reverse_condition (rc);
384 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
385
386 }
387 [(set_attr "conds" "use")
594726e4
JG
388 (set_attr "length" "8")
389 (set_attr "type" "multiple")]
95b97fac
KT
390)
391
0a7dbb76 392(define_insn_and_split "*thumb2_mov_notscc"
5b3e6663 393 [(set (match_operand:SI 0 "s_register_operand" "=r")
ac4bf407 394 (not:SI (match_operator:SI 1 "arm_comparison_operator_mode"
5b3e6663 395 [(match_operand 2 "cc_register" "") (const_int 0)])))]
95b97fac 396 "TARGET_THUMB2 && !arm_restrict_it"
0a7dbb76 397 "#" ; "ite\\t%D1\;mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1"
86f697aa 398 "&& true"
0a7dbb76
GY
399 [(set (match_dup 0)
400 (if_then_else:SI (match_dup 1)
401 (match_dup 3)
402 (match_dup 4)))]
403 {
404 operands[3] = GEN_INT (~1);
405 operands[4] = GEN_INT (~0);
406 }
5b3e6663 407 [(set_attr "conds" "use")
594726e4
JG
408 (set_attr "length" "10")
409 (set_attr "type" "multiple")]
5b3e6663
PB
410)
411
95b97fac
KT
412(define_insn_and_split "*thumb2_mov_notscc_strict_it"
413 [(set (match_operand:SI 0 "low_register_operand" "=l")
ac4bf407 414 (not:SI (match_operator:SI 1 "arm_comparison_operator_mode"
95b97fac
KT
415 [(match_operand 2 "cc_register" "") (const_int 0)])))]
416 "TARGET_THUMB2 && arm_restrict_it"
417 "#" ; "mvn %0, #0 ; it%d1 ; lsl%d1 %0, %0, #1"
418 "&& reload_completed"
419 [(set (match_dup 0)
420 (match_dup 3))
421 (cond_exec (match_dup 4)
422 (set (match_dup 0)
423 (ashift:SI (match_dup 0)
424 (const_int 1))))]
425 {
426 operands[3] = GEN_INT (~0);
427 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[1]),
428 VOIDmode, operands[2], const0_rtx);
429 }
430 [(set_attr "conds" "use")
594726e4
JG
431 (set_attr "length" "8")
432 (set_attr "type" "multiple")]
95b97fac
KT
433)
434
0a7dbb76 435(define_insn_and_split "*thumb2_movsicc_insn"
544f7fc8 436 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r,r,r,r,r,r,r,r,r")
5b3e6663
PB
437 (if_then_else:SI
438 (match_operator 3 "arm_comparison_operator"
439 [(match_operand 4 "cc_register" "") (const_int 0)])
544f7fc8
YR
440 (match_operand:SI 1 "arm_not_operand" "0 ,lPy,0 ,0,rI,K,I ,r,rI,K ,K,r")
441 (match_operand:SI 2 "arm_not_operand" "lPy,0 ,rI,K,0 ,0,rI,I,K ,rI,K,r")))]
5b3e6663
PB
442 "TARGET_THUMB2"
443 "@
956a95a5
KT
444 it\\t%D3\;mov%D3\\t%0, %2
445 it\\t%d3\;mov%d3\\t%0, %1
5b3e6663
PB
446 it\\t%D3\;mov%D3\\t%0, %2
447 it\\t%D3\;mvn%D3\\t%0, #%B2
448 it\\t%d3\;mov%d3\\t%0, %1
449 it\\t%d3\;mvn%d3\\t%0, #%B1
0a7dbb76
GY
450 #
451 #
452 #
956a95a5 453 #
544f7fc8 454 #
0a7dbb76 455 #"
956a95a5 456 ; alt 6: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
544f7fc8
YR
457 ; alt 7: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
458 ; alt 8: ite\\t%d3\;mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2
459 ; alt 9: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2
460 ; alt 10: ite\\t%d3\;mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2
461 ; alt 11: ite\\t%d3\;mov%d3\\t%0, %1\;mov%D3\\t%0, %2
0a7dbb76
GY
462 "&& reload_completed"
463 [(const_int 0)]
464 {
465 enum rtx_code rev_code;
ef4bddc2 466 machine_mode mode;
0a7dbb76
GY
467 rtx rev_cond;
468
469 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
470 operands[3],
f7df4a84 471 gen_rtx_SET (operands[0], operands[1])));
0a7dbb76
GY
472 rev_code = GET_CODE (operands[3]);
473 mode = GET_MODE (operands[4]);
474 if (mode == CCFPmode || mode == CCFPEmode)
475 rev_code = reverse_condition_maybe_unordered (rev_code);
476 else
477 rev_code = reverse_condition (rev_code);
478
479 rev_cond = gen_rtx_fmt_ee (rev_code,
480 VOIDmode,
481 gen_rtx_REG (mode, CC_REGNUM),
482 const0_rtx);
483 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
484 rev_cond,
f7df4a84 485 gen_rtx_SET (operands[0], operands[2])));
0a7dbb76
GY
486 DONE;
487 }
544f7fc8 488 [(set_attr "length" "4,4,6,6,6,6,10,8,10,10,10,6")
113c53c3 489 (set_attr "enabled_for_short_it" "yes,yes,no,no,no,no,no,no,no,no,no,yes")
594726e4 490 (set_attr "conds" "use")
544f7fc8
YR
491 (set_attr_alternative "type"
492 [(if_then_else (match_operand 2 "const_int_operand" "")
493 (const_string "mov_imm")
494 (const_string "mov_reg"))
495 (if_then_else (match_operand 1 "const_int_operand" "")
496 (const_string "mov_imm")
497 (const_string "mov_reg"))
498 (if_then_else (match_operand 2 "const_int_operand" "")
499 (const_string "mov_imm")
500 (const_string "mov_reg"))
501 (const_string "mvn_imm")
502 (if_then_else (match_operand 1 "const_int_operand" "")
503 (const_string "mov_imm")
504 (const_string "mov_reg"))
505 (const_string "mvn_imm")
506 (const_string "multiple")
507 (const_string "multiple")
508 (const_string "multiple")
509 (const_string "multiple")
510 (const_string "multiple")
511 (const_string "multiple")])]
5b3e6663
PB
512)
513
514(define_insn "*thumb2_movsfcc_soft_insn"
515 [(set (match_operand:SF 0 "s_register_operand" "=r,r")
516 (if_then_else:SF (match_operator 3 "arm_comparison_operator"
517 [(match_operand 4 "cc_register" "") (const_int 0)])
518 (match_operand:SF 1 "s_register_operand" "0,r")
519 (match_operand:SF 2 "s_register_operand" "r,0")))]
c7be0832 520 "TARGET_THUMB2 && TARGET_SOFT_FLOAT && !TARGET_HAVE_MVE"
5b3e6663
PB
521 "@
522 it\\t%D3\;mov%D3\\t%0, %2
523 it\\t%d3\;mov%d3\\t%0, %1"
524 [(set_attr "length" "6,6")
594726e4
JG
525 (set_attr "conds" "use")
526 (set_attr "type" "multiple")]
5b3e6663
PB
527)
528
529(define_insn "*call_reg_thumb2"
530 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r"))
531 (match_operand 1 "" ""))
532 (use (match_operand 2 "" ""))
533 (clobber (reg:SI LR_REGNUM))]
534 "TARGET_THUMB2"
535 "blx%?\\t%0"
536 [(set_attr "type" "call")]
537)
538
44ab1cc1 539(define_insn "*nonsecure_call_reg_thumb2_fpcxt"
a464ffc2 540 [(call (unspec:SI [(mem:SI (match_operand:SI 0 "s_register_operand" "l*r"))]
c92e08e3 541 UNSPEC_NONSECURE_MEM)
a464ffc2
MI
542 (match_operand 1 "" ""))
543 (use (match_operand 2 "" ""))
0a413fbc 544 (clobber (reg:SI LR_REGNUM))]
44ab1cc1
RE
545 "TARGET_THUMB2 && use_cmse && TARGET_HAVE_FPCXT_CMSE"
546 "blxns\\t%0"
547 [(set_attr "length" "4")
548 (set_attr "type" "call")]
549)
550
551(define_insn "*nonsecure_call_reg_thumb2"
552 [(call (unspec:SI [(mem:SI (reg:SI R4_REGNUM))]
553 UNSPEC_NONSECURE_MEM)
554 (match_operand 0 "" ""))
555 (use (match_operand 1 "" ""))
556 (clobber (reg:SI LR_REGNUM))]
557 "TARGET_THUMB2 && use_cmse && !TARGET_HAVE_FPCXT_CMSE"
558 "bl\\t__gnu_cmse_nonsecure_call"
c92e08e3
AV
559 [(set_attr "length" "4")
560 (set_attr "type" "call")]
561)
562
5b3e6663
PB
563(define_insn "*call_value_reg_thumb2"
564 [(set (match_operand 0 "" "")
565 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r"))
566 (match_operand 2 "" "")))
567 (use (match_operand 3 "" ""))
568 (clobber (reg:SI LR_REGNUM))]
569 "TARGET_THUMB2"
570 "blx\\t%1"
571 [(set_attr "type" "call")]
c92e08e3
AV
572)
573
44ab1cc1 574(define_insn "*nonsecure_call_value_reg_thumb2_fpcxt"
c92e08e3
AV
575 [(set (match_operand 0 "" "")
576 (call
a464ffc2 577 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "l*r"))]
c92e08e3 578 UNSPEC_NONSECURE_MEM)
a464ffc2
MI
579 (match_operand 2 "" "")))
580 (use (match_operand 3 "" ""))
0a413fbc 581 (clobber (reg:SI LR_REGNUM))]
44ab1cc1
RE
582 "TARGET_THUMB2 && use_cmse && TARGET_HAVE_FPCXT_CMSE"
583 "blxns\\t%1"
584 [(set_attr "length" "4")
585 (set_attr "type" "call")]
586)
587
588(define_insn "*nonsecure_call_value_reg_thumb2"
589 [(set (match_operand 0 "" "")
590 (call
591 (unspec:SI [(mem:SI (reg:SI R4_REGNUM))] UNSPEC_NONSECURE_MEM)
592 (match_operand 1 "" "")))
593 (use (match_operand 2 "" ""))
594 (clobber (reg:SI LR_REGNUM))]
595 "TARGET_THUMB2 && use_cmse && !TARGET_HAVE_FPCXT_CMSE"
596 "bl\\t__gnu_cmse_nonsecure_call"
c92e08e3
AV
597 [(set_attr "length" "4")
598 (set_attr "type" "call")]
5b3e6663
PB
599)
600
601(define_insn "*thumb2_indirect_jump"
602 [(set (pc)
603 (match_operand:SI 0 "register_operand" "l*r"))]
604 "TARGET_THUMB2"
605 "bx\\t%0"
594726e4
JG
606 [(set_attr "conds" "clob")
607 (set_attr "type" "branch")]
5b3e6663
PB
608)
609;; Don't define thumb2_load_indirect_jump because we can't guarantee label
9e64a0bf 610;; addresses will have the thumb bit set correctly.
5b3e6663
PB
611
612
0a7dbb76 613(define_insn_and_split "*thumb2_and_scc"
956a95a5 614 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
5b3e6663 615 (and:SI (match_operator:SI 1 "arm_comparison_operator"
0a7dbb76
GY
616 [(match_operand 2 "cc_register" "") (const_int 0)])
617 (match_operand:SI 3 "s_register_operand" "r")))]
5b3e6663 618 "TARGET_THUMB2"
956a95a5 619 "#" ; "and\\t%0, %3, #1\;it\\t%D1\;mov%D1\\t%0, #0"
0a7dbb76 620 "&& reload_completed"
956a95a5
KT
621 [(set (match_dup 0)
622 (and:SI (match_dup 3) (const_int 1)))
623 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0)))]
0a7dbb76 624 {
ef4bddc2 625 machine_mode mode = GET_MODE (operands[2]);
0a7dbb76
GY
626 enum rtx_code rc = GET_CODE (operands[1]);
627
0a7dbb76
GY
628 if (mode == CCFPmode || mode == CCFPEmode)
629 rc = reverse_condition_maybe_unordered (rc);
630 else
631 rc = reverse_condition (rc);
956a95a5 632 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
0a7dbb76 633 }
5b3e6663 634 [(set_attr "conds" "use")
594726e4 635 (set_attr "type" "multiple")
956a95a5
KT
636 (set (attr "length") (if_then_else (match_test "arm_restrict_it")
637 (const_int 8)
638 (const_int 10)))]
5b3e6663
PB
639)
640
0a7dbb76 641(define_insn_and_split "*thumb2_ior_scc"
5b3e6663 642 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
0a7dbb76
GY
643 (ior:SI (match_operator:SI 1 "arm_comparison_operator"
644 [(match_operand 2 "cc_register" "") (const_int 0)])
645 (match_operand:SI 3 "s_register_operand" "0,?r")))]
95b97fac 646 "TARGET_THUMB2 && !arm_restrict_it"
5b3e6663 647 "@
0a7dbb76
GY
648 it\\t%d1\;orr%d1\\t%0, %3, #1
649 #"
650 ; alt 1: ite\\t%D1\;mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1
651 "&& reload_completed
652 && REGNO (operands [0]) != REGNO (operands[3])"
653 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3)))
654 (cond_exec (match_dup 4) (set (match_dup 0)
655 (ior:SI (match_dup 3) (const_int 1))))]
656 {
ef4bddc2 657 machine_mode mode = GET_MODE (operands[2]);
0a7dbb76
GY
658 enum rtx_code rc = GET_CODE (operands[1]);
659
660 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
661 if (mode == CCFPmode || mode == CCFPEmode)
662 rc = reverse_condition_maybe_unordered (rc);
663 else
664 rc = reverse_condition (rc);
665 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx);
666 }
5b3e6663 667 [(set_attr "conds" "use")
594726e4
JG
668 (set_attr "length" "6,10")
669 (set_attr "type" "multiple")]
5b3e6663
PB
670)
671
fce661e8
KT
672(define_insn_and_split "*thumb2_ior_scc_strict_it"
673 [(set (match_operand:SI 0 "s_register_operand" "=&r")
95b97fac
KT
674 (ior:SI (match_operator:SI 2 "arm_comparison_operator"
675 [(match_operand 3 "cc_register" "") (const_int 0)])
fce661e8 676 (match_operand:SI 1 "s_register_operand" "r")))]
95b97fac 677 "TARGET_THUMB2 && arm_restrict_it"
fce661e8
KT
678 "#" ; orr\\t%0, %1, #1\;it\\t%D2\;mov%D2\\t%0, %1
679 "&& reload_completed"
680 [(set (match_dup 0) (ior:SI (match_dup 1) (const_int 1)))
681 (cond_exec (match_dup 4)
682 (set (match_dup 0) (match_dup 1)))]
683 {
684 machine_mode mode = GET_MODE (operands[3]);
685 rtx_code rc = GET_CODE (operands[2]);
686
687 if (mode == CCFPmode || mode == CCFPEmode)
688 rc = reverse_condition_maybe_unordered (rc);
689 else
690 rc = reverse_condition (rc);
691 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx);
692 }
95b97fac 693 [(set_attr "conds" "use")
594726e4
JG
694 (set_attr "length" "8")
695 (set_attr "type" "multiple")]
95b97fac
KT
696)
697
5b3e6663
PB
698(define_insn "*thumb2_cond_move"
699 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r")
700 (if_then_else:SI (match_operator 3 "equality_operator"
701 [(match_operator 4 "arm_comparison_operator"
702 [(match_operand 5 "cc_register" "") (const_int 0)])
703 (const_int 0)])
704 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI")
705 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))]
706 "TARGET_THUMB2"
707 "*
708 if (GET_CODE (operands[3]) == NE)
709 {
710 if (which_alternative != 1)
711 output_asm_insn (\"it\\t%D4\;mov%D4\\t%0, %2\", operands);
712 if (which_alternative != 0)
713 output_asm_insn (\"it\\t%d4\;mov%d4\\t%0, %1\", operands);
714 return \"\";
715 }
716 switch (which_alternative)
717 {
718 case 0:
719 output_asm_insn (\"it\\t%d4\", operands);
720 break;
721 case 1:
722 output_asm_insn (\"it\\t%D4\", operands);
723 break;
724 case 2:
95b97fac
KT
725 if (arm_restrict_it)
726 output_asm_insn (\"it\\t%D4\", operands);
727 else
728 output_asm_insn (\"ite\\t%D4\", operands);
5b3e6663
PB
729 break;
730 default:
731 abort();
732 }
733 if (which_alternative != 0)
95b97fac
KT
734 {
735 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
736 if (arm_restrict_it && which_alternative == 2)
737 output_asm_insn (\"it\\t%d4\", operands);
738 }
5b3e6663
PB
739 if (which_alternative != 1)
740 output_asm_insn (\"mov%d4\\t%0, %2\", operands);
741 return \"\";
742 "
743 [(set_attr "conds" "use")
594726e4
JG
744 (set_attr "length" "6,6,10")
745 (set_attr "type" "multiple")]
5b3e6663
PB
746)
747
748(define_insn "*thumb2_cond_arith"
749 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
9e64a0bf 750 (match_operator:SI 5 "shiftable_operator"
5b3e6663
PB
751 [(match_operator:SI 4 "arm_comparison_operator"
752 [(match_operand:SI 2 "s_register_operand" "r,r")
753 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])
754 (match_operand:SI 1 "s_register_operand" "0,?r")]))
755 (clobber (reg:CC CC_REGNUM))]
95b97fac 756 "TARGET_THUMB2 && !arm_restrict_it"
5b3e6663
PB
757 "*
758 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
759 return \"%i5\\t%0, %1, %2, lsr #31\";
760
761 output_asm_insn (\"cmp\\t%2, %3\", operands);
778f19ff
SD
762
763 if (GET_CODE (operands[5]) == PLUS && TARGET_COND_ARITH)
764 return \"cinc\\t%0, %1, %d4\";
765
5b3e6663
PB
766 if (GET_CODE (operands[5]) == AND)
767 {
768 output_asm_insn (\"ite\\t%D4\", operands);
769 output_asm_insn (\"mov%D4\\t%0, #0\", operands);
770 }
771 else if (GET_CODE (operands[5]) == MINUS)
772 {
773 output_asm_insn (\"ite\\t%D4\", operands);
774 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands);
775 }
776 else if (which_alternative != 0)
777 {
778 output_asm_insn (\"ite\\t%D4\", operands);
779 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
780 }
781 else
782 output_asm_insn (\"it\\t%d4\", operands);
783 return \"%i5%d4\\t%0, %1, #1\";
784 "
785 [(set_attr "conds" "clob")
594726e4
JG
786 (set_attr "length" "14")
787 (set_attr "type" "multiple")]
5b3e6663
PB
788)
789
95b97fac
KT
790(define_insn_and_split "*thumb2_cond_arith_strict_it"
791 [(set (match_operand:SI 0 "s_register_operand" "=l")
792 (match_operator:SI 5 "shiftable_operator_strict_it"
793 [(match_operator:SI 4 "arm_comparison_operator"
794 [(match_operand:SI 2 "s_register_operand" "r")
795 (match_operand:SI 3 "arm_rhs_operand" "rI")])
796 (match_operand:SI 1 "s_register_operand" "0")]))
797 (clobber (reg:CC CC_REGNUM))]
798 "TARGET_THUMB2 && arm_restrict_it"
799 "#"
800 "&& reload_completed"
801 [(const_int 0)]
802 {
803 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx)
804 {
805 /* %i5 %0, %1, %2, lsr #31 */
806 rtx shifted_op = gen_rtx_LSHIFTRT (SImode, operands[2], GEN_INT (31));
807 rtx op = NULL_RTX;
808
809 switch (GET_CODE (operands[5]))
810 {
811 case AND:
812 op = gen_rtx_AND (SImode, shifted_op, operands[1]);
813 break;
814 case PLUS:
815 op = gen_rtx_PLUS (SImode, shifted_op, operands[1]);
816 break;
817 default: gcc_unreachable ();
818 }
f7df4a84 819 emit_insn (gen_rtx_SET (operands[0], op));
95b97fac
KT
820 DONE;
821 }
822
823 /* "cmp %2, %3" */
f7df4a84
RS
824 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM),
825 gen_rtx_COMPARE (CCmode, operands[2],
826 operands[3])));
95b97fac
KT
827
828 if (GET_CODE (operands[5]) == AND)
829 {
830 /* %i5 %0, %1, #1
831 it%D4
832 mov%D4 %0, #0 */
833 enum rtx_code rc = reverse_condition (GET_CODE (operands[4]));
f7df4a84
RS
834 emit_insn (gen_rtx_SET (operands[0], gen_rtx_AND (SImode, operands[1],
835 GEN_INT (1))));
95b97fac
KT
836 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
837 gen_rtx_fmt_ee (rc, VOIDmode, gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx),
f7df4a84 838 gen_rtx_SET (operands[0], const0_rtx)));
95b97fac
KT
839 DONE;
840 }
841 else
842 {
843 /* it\\t%d4
844 %i5%d4\\t%0, %1, #1 */
845 emit_insn (gen_rtx_COND_EXEC (VOIDmode, gen_rtx_fmt_ee (GET_CODE (operands[4]),
846 VOIDmode,
847 gen_rtx_REG (CCmode, CC_REGNUM), const0_rtx),
f7df4a84 848 gen_rtx_SET (operands[0],
95b97fac
KT
849 gen_rtx_PLUS (SImode,
850 operands[1],
851 GEN_INT (1)))));
852 DONE;
853 }
854 FAIL;
855 }
856 [(set_attr "conds" "clob")
594726e4
JG
857 (set_attr "length" "12")
858 (set_attr "type" "multiple")]
95b97fac
KT
859)
860
5b3e6663 861(define_insn "*thumb2_cond_sub"
95b97fac
KT
862 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts")
863 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?Ts")
5b3e6663
PB
864 (match_operator:SI 4 "arm_comparison_operator"
865 [(match_operand:SI 2 "s_register_operand" "r,r")
866 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))
867 (clobber (reg:CC CC_REGNUM))]
868 "TARGET_THUMB2"
869 "*
870 output_asm_insn (\"cmp\\t%2, %3\", operands);
871 if (which_alternative != 0)
872 {
95b97fac
KT
873 if (arm_restrict_it)
874 {
875 output_asm_insn (\"mov\\t%0, %1\", operands);
876 output_asm_insn (\"it\\t%d4\", operands);
877 }
878 else
879 {
880 output_asm_insn (\"ite\\t%D4\", operands);
881 output_asm_insn (\"mov%D4\\t%0, %1\", operands);
882 }
5b3e6663
PB
883 }
884 else
885 output_asm_insn (\"it\\t%d4\", operands);
886 return \"sub%d4\\t%0, %1, #1\";
887 "
888 [(set_attr "conds" "clob")
594726e4
JG
889 (set_attr "length" "10,14")
890 (set_attr "type" "multiple")]
5b3e6663
PB
891)
892
0a7dbb76 893(define_insn_and_split "*thumb2_negscc"
956a95a5 894 [(set (match_operand:SI 0 "s_register_operand" "=Ts")
5b3e6663
PB
895 (neg:SI (match_operator 3 "arm_comparison_operator"
896 [(match_operand:SI 1 "s_register_operand" "r")
897 (match_operand:SI 2 "arm_rhs_operand" "rI")])))
898 (clobber (reg:CC CC_REGNUM))]
04dc198c 899 "TARGET_THUMB2 && !TARGET_COND_ARITH"
0a7dbb76
GY
900 "#"
901 "&& reload_completed"
902 [(const_int 0)]
903 {
904 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM);
5b3e6663 905
0a7dbb76
GY
906 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx)
907 {
908 /* Emit asr\\t%0, %1, #31 */
f7df4a84 909 emit_insn (gen_rtx_SET (operands[0],
0a7dbb76
GY
910 gen_rtx_ASHIFTRT (SImode,
911 operands[1],
912 GEN_INT (31))));
913 DONE;
914 }
956a95a5 915 else if (GET_CODE (operands[3]) == NE && !arm_restrict_it)
0a7dbb76
GY
916 {
917 /* Emit subs\\t%0, %1, %2\;it\\tne\;mvnne\\t%0, #0 */
918 if (CONST_INT_P (operands[2]))
919 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
73ba6c71
JJ
920 gen_int_mode (-INTVAL (operands[2]),
921 SImode)));
0a7dbb76
GY
922 else
923 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2]));
924
925 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
926 gen_rtx_NE (SImode,
927 cc_reg,
928 const0_rtx),
f7df4a84 929 gen_rtx_SET (operands[0],
0a7dbb76
GY
930 GEN_INT (~0))));
931 DONE;
932 }
933 else
934 {
956a95a5 935 /* Emit: cmp\\t%1, %2\;mvn\\t%0, #0\;it\\t%D3\;mov%D3\\t%0, #0\;*/
0a7dbb76 936 enum rtx_code rc = reverse_condition (GET_CODE (operands[3]));
ef4bddc2 937 machine_mode mode = SELECT_CC_MODE (rc, operands[1], operands[2]);
0a7dbb76
GY
938 rtx tmp1 = gen_rtx_REG (mode, CC_REGNUM);
939
f7df4a84
RS
940 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (CCmode, operands[1],
941 operands[2])));
956a95a5 942
f7df4a84 943 emit_insn (gen_rtx_SET (operands[0], GEN_INT (~0)));
956a95a5 944
0a7dbb76
GY
945 emit_insn (gen_rtx_COND_EXEC (VOIDmode,
946 gen_rtx_fmt_ee (rc,
947 VOIDmode,
948 tmp1,
949 const0_rtx),
f7df4a84 950 gen_rtx_SET (operands[0], const0_rtx)));
0a7dbb76
GY
951 DONE;
952 }
953 FAIL;
954 }
5b3e6663 955 [(set_attr "conds" "clob")
594726e4
JG
956 (set_attr "length" "14")
957 (set_attr "type" "multiple")]
5b3e6663
PB
958)
959
c2bb84be
SD
960(define_insn "*thumb2_csinv"
961 [(set (match_operand:SI 0 "arm_general_register_operand" "=r, r")
962 (if_then_else:SI
963 (match_operand 1 "arm_comparison_operation" "")
964 (not:SI (match_operand:SI 2 "arm_general_register_operand" "r, r"))
965 (match_operand:SI 3 "reg_or_zero_operand" "r, Pz")))]
966 "TARGET_COND_ARITH"
967 "@
968 csinv\\t%0, %3, %2, %D1
969 csinv\\t%0, zr, %2, %D1"
970 [(set_attr "type" "csel")
971 (set_attr "predicable" "no")]
778f19ff
SD
972)
973
974(define_insn "*thumb2_csinc"
975 [(set (match_operand:SI 0 "arm_general_register_operand" "=r, r")
976 (if_then_else:SI
977 (match_operand 1 "arm_comparison_operation" "")
978 (plus:SI (match_operand:SI 2 "arm_general_register_operand" "r, r")
979 (const_int 1))
980 (match_operand:SI 3 "reg_or_zero_operand" "r, Pz")))]
981 "TARGET_COND_ARITH"
982 "@
983 csinc\\t%0, %3, %2, %D1
984 csinc\\t%0, zr, %2, %D1"
985 [(set_attr "type" "csel")
986 (set_attr "predicable" "no")]
04dc198c
SD
987)
988
989(define_insn "*thumb2_csneg"
990 [(set (match_operand:SI 0 "arm_general_register_operand" "=r, r")
991 (if_then_else:SI
992 (match_operand 1 "arm_comparison_operation" "")
993 (neg:SI (match_operand:SI 2 "arm_general_register_operand" "r, r"))
994 (match_operand:SI 3 "reg_or_zero_operand" "r, Pz")))]
995 "TARGET_COND_ARITH"
996 "@
997 csneg\\t%0, %3, %2, %D1
998 csneg\\t%0, zr, %2, %D1"
999 [(set_attr "type" "csel")
1000 (set_attr "predicable" "no")]
c2bb84be
SD
1001)
1002
5b3e6663 1003(define_insn "*thumb2_movcond"
95b97fac 1004 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts,Ts")
5b3e6663
PB
1005 (if_then_else:SI
1006 (match_operator 5 "arm_comparison_operator"
1007 [(match_operand:SI 3 "s_register_operand" "r,r,r")
1008 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")])
95b97fac
KT
1009 (match_operand:SI 1 "arm_rhs_operand" "0,TsI,?TsI")
1010 (match_operand:SI 2 "arm_rhs_operand" "TsI,0,TsI")))
5b3e6663 1011 (clobber (reg:CC CC_REGNUM))]
c2bb84be 1012 "TARGET_THUMB2 && !TARGET_COND_ARITH"
5b3e6663
PB
1013 "*
1014 if (GET_CODE (operands[5]) == LT
1015 && (operands[4] == const0_rtx))
1016 {
d435a4be 1017 if (which_alternative != 1 && REG_P (operands[1]))
5b3e6663
PB
1018 {
1019 if (operands[2] == const0_rtx)
1020 return \"and\\t%0, %1, %3, asr #31\";
1021 return \"ands\\t%0, %1, %3, asr #32\;it\\tcc\;movcc\\t%0, %2\";
1022 }
d435a4be 1023 else if (which_alternative != 0 && REG_P (operands[2]))
5b3e6663
PB
1024 {
1025 if (operands[1] == const0_rtx)
1026 return \"bic\\t%0, %2, %3, asr #31\";
1027 return \"bics\\t%0, %2, %3, asr #32\;it\\tcs\;movcs\\t%0, %1\";
1028 }
1029 /* The only case that falls through to here is when both ops 1 & 2
1030 are constants. */
1031 }
1032
1033 if (GET_CODE (operands[5]) == GE
1034 && (operands[4] == const0_rtx))
1035 {
d435a4be 1036 if (which_alternative != 1 && REG_P (operands[1]))
5b3e6663
PB
1037 {
1038 if (operands[2] == const0_rtx)
1039 return \"bic\\t%0, %1, %3, asr #31\";
1040 return \"bics\\t%0, %1, %3, asr #32\;it\\tcs\;movcs\\t%0, %2\";
1041 }
d435a4be 1042 else if (which_alternative != 0 && REG_P (operands[2]))
5b3e6663
PB
1043 {
1044 if (operands[1] == const0_rtx)
1045 return \"and\\t%0, %2, %3, asr #31\";
1046 return \"ands\\t%0, %2, %3, asr #32\;it\tcc\;movcc\\t%0, %1\";
1047 }
1048 /* The only case that falls through to here is when both ops 1 & 2
1049 are constants. */
1050 }
d435a4be 1051 if (CONST_INT_P (operands[4])
5b3e6663
PB
1052 && !const_ok_for_arm (INTVAL (operands[4])))
1053 output_asm_insn (\"cmn\\t%3, #%n4\", operands);
1054 else
1055 output_asm_insn (\"cmp\\t%3, %4\", operands);
1056 switch (which_alternative)
1057 {
1058 case 0:
1059 output_asm_insn (\"it\\t%D5\", operands);
1060 break;
1061 case 1:
1062 output_asm_insn (\"it\\t%d5\", operands);
1063 break;
1064 case 2:
95b97fac
KT
1065 if (arm_restrict_it)
1066 {
1067 output_asm_insn (\"mov\\t%0, %1\", operands);
1068 output_asm_insn (\"it\\t%D5\", operands);
1069 }
1070 else
1071 output_asm_insn (\"ite\\t%d5\", operands);
5b3e6663
PB
1072 break;
1073 default:
1074 abort();
1075 }
95b97fac 1076 if (which_alternative != 0 && !(arm_restrict_it && which_alternative == 2))
5b3e6663
PB
1077 output_asm_insn (\"mov%d5\\t%0, %1\", operands);
1078 if (which_alternative != 1)
1079 output_asm_insn (\"mov%D5\\t%0, %2\", operands);
1080 return \"\";
1081 "
1082 [(set_attr "conds" "clob")
594726e4
JG
1083 (set_attr "length" "10,10,14")
1084 (set_attr "type" "multiple")]
5b3e6663
PB
1085)
1086
1087;; Zero and sign extension instructions.
1088
5b3e6663
PB
1089;; All supported Thumb2 implementations are armv6, so only that case is
1090;; provided.
1091(define_insn "*thumb2_extendqisi_v6"
1092 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1093 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1094 "TARGET_THUMB2 && arm_arch6"
1095 "@
1096 sxtb%?\\t%0, %1
bae4ce0f 1097 ldrsb%?\\t%0, %1"
006bd006 1098 [(set_attr "type" "extend,load_byte")
5b3e6663 1099 (set_attr "predicable" "yes")
88f519b2 1100 (set_attr "pool_range" "*,4094")
5b3e6663
PB
1101 (set_attr "neg_pool_range" "*,250")]
1102)
1103
1104(define_insn "*thumb2_zero_extendhisi2_v6"
1105 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1106 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))]
1107 "TARGET_THUMB2 && arm_arch6"
1108 "@
1109 uxth%?\\t%0, %1
bae4ce0f 1110 ldrh%?\\t%0, %1"
006bd006 1111 [(set_attr "type" "extend,load_byte")
5b3e6663 1112 (set_attr "predicable" "yes")
88f519b2 1113 (set_attr "pool_range" "*,4094")
5b3e6663
PB
1114 (set_attr "neg_pool_range" "*,250")]
1115)
1116
3565ffed 1117(define_insn "thumb2_zero_extendqisi2_v6"
5b3e6663
PB
1118 [(set (match_operand:SI 0 "s_register_operand" "=r,r")
1119 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))]
1120 "TARGET_THUMB2 && arm_arch6"
1121 "@
bae4ce0f
RR
1122 uxtb%?\\t%0, %1
1123 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2"
006bd006 1124 [(set_attr "type" "extend,load_byte")
5b3e6663 1125 (set_attr "predicable" "yes")
88f519b2 1126 (set_attr "pool_range" "*,4094")
5b3e6663
PB
1127 (set_attr "neg_pool_range" "*,250")]
1128)
1129
9a55a2d1
JJ
1130(define_expand "thumb2_casesi_internal"
1131 [(parallel [(set (pc)
1132 (if_then_else
1133 (leu (match_operand:SI 0 "s_register_operand")
1134 (match_operand:SI 1 "arm_rhs_operand"))
1135 (match_dup 4)
1136 (label_ref:SI (match_operand 3 ""))))
1137 (clobber (reg:CC CC_REGNUM))
1138 (clobber (match_scratch:SI 5))
1139 (use (label_ref:SI (match_operand 2 "")))])]
1140 "TARGET_THUMB2 && !flag_pic"
1141{
1142 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
1143 operands[4] = gen_rtx_PLUS (SImode, operands[4],
1144 gen_rtx_LABEL_REF (SImode, operands[2]));
1145 operands[4] = gen_rtx_MEM (SImode, operands[4]);
1146 MEM_READONLY_P (operands[4]) = 1;
1147 MEM_NOTRAP_P (operands[4]) = 1;
1148})
1149
1150(define_insn "*thumb2_casesi_internal"
5b3e6663
PB
1151 [(parallel [(set (pc)
1152 (if_then_else
1153 (leu (match_operand:SI 0 "s_register_operand" "r")
1154 (match_operand:SI 1 "arm_rhs_operand" "rI"))
1155 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
9a55a2d1
JJ
1156 (label_ref:SI (match_operand 2 "" ""))))
1157 (label_ref:SI (match_operand 3 "" ""))))
5b3e6663 1158 (clobber (reg:CC CC_REGNUM))
f72d3365 1159 (clobber (match_scratch:SI 4 "=&r"))
9a55a2d1 1160 (use (label_ref:SI (match_dup 2)))])]
5b3e6663
PB
1161 "TARGET_THUMB2 && !flag_pic"
1162 "* return thumb2_output_casesi(operands);"
1163 [(set_attr "conds" "clob")
594726e4
JG
1164 (set_attr "length" "16")
1165 (set_attr "type" "multiple")]
5b3e6663
PB
1166)
1167
9a55a2d1
JJ
1168(define_expand "thumb2_casesi_internal_pic"
1169 [(parallel [(set (pc)
1170 (if_then_else
1171 (leu (match_operand:SI 0 "s_register_operand")
1172 (match_operand:SI 1 "arm_rhs_operand"))
1173 (match_dup 4)
1174 (label_ref:SI (match_operand 3 ""))))
1175 (clobber (reg:CC CC_REGNUM))
1176 (clobber (match_scratch:SI 5))
1177 (clobber (match_scratch:SI 6))
1178 (use (label_ref:SI (match_operand 2 "")))])]
1179 "TARGET_THUMB2 && flag_pic"
1180{
1181 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4));
1182 operands[4] = gen_rtx_PLUS (SImode, operands[4],
1183 gen_rtx_LABEL_REF (SImode, operands[2]));
1184 operands[4] = gen_rtx_MEM (SImode, operands[4]);
1185 MEM_READONLY_P (operands[4]) = 1;
1186 MEM_NOTRAP_P (operands[4]) = 1;
1187})
1188
1189(define_insn "*thumb2_casesi_internal_pic"
5b3e6663
PB
1190 [(parallel [(set (pc)
1191 (if_then_else
1192 (leu (match_operand:SI 0 "s_register_operand" "r")
1193 (match_operand:SI 1 "arm_rhs_operand" "rI"))
1194 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4))
9a55a2d1
JJ
1195 (label_ref:SI (match_operand 2 "" ""))))
1196 (label_ref:SI (match_operand 3 "" ""))))
5b3e6663 1197 (clobber (reg:CC CC_REGNUM))
f72d3365 1198 (clobber (match_scratch:SI 4 "=&r"))
5b3e6663 1199 (clobber (match_scratch:SI 5 "=r"))
9a55a2d1 1200 (use (label_ref:SI (match_dup 2)))])]
5b3e6663
PB
1201 "TARGET_THUMB2 && flag_pic"
1202 "* return thumb2_output_casesi(operands);"
1203 [(set_attr "conds" "clob")
594726e4
JG
1204 (set_attr "length" "20")
1205 (set_attr "type" "multiple")]
5b3e6663
PB
1206)
1207
7c19c715 1208(define_insn "*thumb2_return"
f79b86a4 1209 [(simple_return)]
de954d6a 1210 "TARGET_THUMB2 && !IS_CMSE_ENTRY (arm_current_func_type ())"
f79b86a4
IB
1211 "* return output_return_instruction (const_true_rtx, true, false, true);"
1212 [(set_attr "type" "branch")
1213 (set_attr "length" "4")]
7c19c715
JB
1214)
1215
de954d6a
AV
1216(define_insn "*thumb2_cmse_entry_return"
1217 [(simple_return)]
1218 "TARGET_THUMB2 && IS_CMSE_ENTRY (arm_current_func_type ())"
1219 "* return output_return_instruction (const_true_rtx, true, false, true);"
1220 [(set_attr "type" "branch")
1221 ; This is a return from a cmse_nonsecure_entry function so code will be
1222 ; added to clear the APSR and potentially the FPSCR if VFP is available, so
1223 ; we adapt the length accordingly.
1224 (set (attr "length")
1225 (if_then_else (match_test "TARGET_HARD_FLOAT")
9f28fe39 1226 (const_int 34)
de954d6a
AV
1227 (const_int 8)))
1228 ; We do not support predicate execution of returns from cmse_nonsecure_entry
1229 ; functions because we need to clear the APSR. Since predicable has to be
1230 ; a constant, we had to duplicate the thumb2_return pattern for CMSE entry
1231 ; functions.
1232 (set_attr "predicable" "no")]
1233)
1234
5b3e6663
PB
1235(define_insn_and_split "thumb2_eh_return"
1236 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")]
1237 VUNSPEC_EH_RETURN)
1238 (clobber (match_scratch:SI 1 "=&r"))]
1239 "TARGET_THUMB2"
1240 "#"
1241 "&& reload_completed"
1242 [(const_int 0)]
1243 "
1244 {
1245 thumb_set_return_address (operands[0], operands[1]);
1246 DONE;
1247 }"
1248)
1249
5b3e6663
PB
1250(define_insn "*thumb2_alusi3_short"
1251 [(set (match_operand:SI 0 "s_register_operand" "=l")
1252 (match_operator:SI 3 "thumb_16bit_operator"
1253 [(match_operand:SI 1 "s_register_operand" "0")
1254 (match_operand:SI 2 "s_register_operand" "l")]))
1255 (clobber (reg:CC CC_REGNUM))]
d1b85efb
PB
1256 "TARGET_THUMB2 && reload_completed
1257 && GET_CODE(operands[3]) != PLUS
1258 && GET_CODE(operands[3]) != MINUS"
5b3e6663
PB
1259 "%I3%!\\t%0, %1, %2"
1260 [(set_attr "predicable" "yes")
594726e4 1261 (set_attr "length" "2")
1d61feeb 1262 (set_attr "type" "alu_sreg")]
5b3e6663
PB
1263)
1264
5b3e6663 1265(define_insn "*thumb2_shiftsi3_short"
23d2a817 1266 [(set (match_operand:SI 0 "low_register_operand" "=l,l")
5b3e6663 1267 (match_operator:SI 3 "shift_operator"
23d2a817
RE
1268 [(match_operand:SI 1 "low_register_operand" "0,l")
1269 (match_operand:SI 2 "low_reg_or_int_operand" "l,M")]))
5b3e6663
PB
1270 (clobber (reg:CC CC_REGNUM))]
1271 "TARGET_THUMB2 && reload_completed
1272 && ((GET_CODE(operands[3]) != ROTATE && GET_CODE(operands[3]) != ROTATERT)
d435a4be 1273 || REG_P (operands[2]))"
5b3e6663
PB
1274 "* return arm_output_shift(operands, 2);"
1275 [(set_attr "predicable" "yes")
1276 (set_attr "shift" "1")
1277 (set_attr "length" "2")
1278 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "")
ae27ce51
QJ
1279 (if_then_else (match_operand 3 "alu_shift_operator_lsl_1_to_4")
1280 (const_string "alu_shift_imm_lsl_1to4")
1281 (const_string "alu_shift_imm_other"))
6e4150e1 1282 (const_string "alu_shift_reg")))]
5b3e6663
PB
1283)
1284
953a18fb
RE
1285(define_insn "*thumb2_mov<mode>_shortim"
1286 [(set (match_operand:QHSI 0 "low_register_operand" "=l")
1287 (match_operand:QHSI 1 "const_int_operand" "I"))
5b3e6663
PB
1288 (clobber (reg:CC CC_REGNUM))]
1289 "TARGET_THUMB2 && reload_completed"
1290 "mov%!\t%0, %1"
1291 [(set_attr "predicable" "yes")
594726e4
JG
1292 (set_attr "length" "2")
1293 (set_attr "type" "mov_imm")]
5b3e6663
PB
1294)
1295
d1b85efb 1296(define_insn "*thumb2_addsi_short"
85f28bf1
JB
1297 [(set (match_operand:SI 0 "low_register_operand" "=l,l")
1298 (plus:SI (match_operand:SI 1 "low_register_operand" "l,0")
1299 (match_operand:SI 2 "low_reg_or_int_operand" "lPt,Ps")))
5b3e6663
PB
1300 (clobber (reg:CC CC_REGNUM))]
1301 "TARGET_THUMB2 && reload_completed"
1302 "*
1303 HOST_WIDE_INT val;
1304
d435a4be 1305 if (CONST_INT_P (operands[2]))
d1b85efb
PB
1306 val = INTVAL(operands[2]);
1307 else
1308 val = 0;
1309
5b3e6663
PB
1310 /* We prefer eg. subs rn, rn, #1 over adds rn, rn, #0xffffffff. */
1311 if (val < 0 && const_ok_for_arm(ARM_SIGN_EXTEND (-val)))
1312 return \"sub%!\\t%0, %1, #%n2\";
1313 else
1314 return \"add%!\\t%0, %1, %2\";
1315 "
1316 [(set_attr "predicable" "yes")
594726e4 1317 (set_attr "length" "2")
544f7fc8
YR
1318 (set_attr_alternative "type"
1319 [(if_then_else (match_operand 2 "const_int_operand" "")
1320 (const_string "alu_imm")
1321 (const_string "alu_sreg"))
1322 (const_string "alu_imm")])]
5b3e6663
PB
1323)
1324
d1b85efb
PB
1325(define_insn "*thumb2_subsi_short"
1326 [(set (match_operand:SI 0 "low_register_operand" "=l")
1327 (minus:SI (match_operand:SI 1 "low_register_operand" "l")
1328 (match_operand:SI 2 "low_register_operand" "l")))
1329 (clobber (reg:CC CC_REGNUM))]
1330 "TARGET_THUMB2 && reload_completed"
1331 "sub%!\\t%0, %1, %2"
1332 [(set_attr "predicable" "yes")
594726e4 1333 (set_attr "length" "2")
1d61feeb 1334 (set_attr "type" "alu_sreg")]
d1b85efb
PB
1335)
1336
e6bfe8a2
RE
1337(define_peephole2
1338 [(set (match_operand:CC 0 "cc_register" "")
1339 (compare:CC (match_operand:SI 1 "low_register_operand" "")
1340 (match_operand:SI 2 "const_int_operand" "")))]
1341 "TARGET_THUMB2
1342 && peep2_reg_dead_p (1, operands[1])
1343 && satisfies_constraint_Pw (operands[2])"
1344 [(parallel
1345 [(set (match_dup 0) (compare:CC (match_dup 1) (match_dup 2)))
1346 (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 3)))])]
1347 "operands[3] = GEN_INT (- INTVAL (operands[2]));"
1348)
1349
1350(define_peephole2
1351 [(match_scratch:SI 3 "l")
1352 (set (match_operand:CC 0 "cc_register" "")
1353 (compare:CC (match_operand:SI 1 "low_register_operand" "")
1354 (match_operand:SI 2 "const_int_operand" "")))]
1355 "TARGET_THUMB2
1356 && satisfies_constraint_Px (operands[2])"
1357 [(parallel
1358 [(set (match_dup 0) (compare:CC (match_dup 1) (match_dup 2)))
1359 (set (match_dup 3) (plus:SI (match_dup 1) (match_dup 4)))])]
1360 "operands[4] = GEN_INT (- INTVAL (operands[2]));"
1361)
1362
ce7b3761 1363(define_insn "thumb2_addsi3_compare0"
54138d95
RH
1364 [(set (reg:CC_NZ CC_REGNUM)
1365 (compare:CC_NZ
dcd8b2ee
JB
1366 (plus:SI (match_operand:SI 1 "s_register_operand" "l, 0, r")
1367 (match_operand:SI 2 "arm_add_operand" "lPt,Ps,rIL"))
1368 (const_int 0)))
1369 (set (match_operand:SI 0 "s_register_operand" "=l,l,r")
1370 (plus:SI (match_dup 1) (match_dup 2)))]
1371 "TARGET_THUMB2"
1372 "*
1373 HOST_WIDE_INT val;
1374
d435a4be 1375 if (CONST_INT_P (operands[2]))
dcd8b2ee
JB
1376 val = INTVAL (operands[2]);
1377 else
1378 val = 0;
1379
1380 if (val < 0 && const_ok_for_arm (ARM_SIGN_EXTEND (-val)))
1381 return \"subs\\t%0, %1, #%n2\";
1382 else
1383 return \"adds\\t%0, %1, %2\";
1384 "
1385 [(set_attr "conds" "set")
594726e4 1386 (set_attr "length" "2,2,4")
544f7fc8
YR
1387 (set_attr_alternative "type"
1388 [(if_then_else (match_operand 2 "const_int_operand" "")
1389 (const_string "alus_imm")
1390 (const_string "alus_sreg"))
1391 (const_string "alus_imm")
1392 (if_then_else (match_operand 2 "const_int_operand" "")
1393 (const_string "alus_imm")
1394 (const_string "alus_sreg"))])]
dcd8b2ee
JB
1395)
1396
1397(define_insn "*thumb2_addsi3_compare0_scratch"
54138d95
RH
1398 [(set (reg:CC_NZ CC_REGNUM)
1399 (compare:CC_NZ
544f7fc8
YR
1400 (plus:SI (match_operand:SI 0 "s_register_operand" "l, r")
1401 (match_operand:SI 1 "arm_add_operand" "lPv,rIL"))
dcd8b2ee
JB
1402 (const_int 0)))]
1403 "TARGET_THUMB2"
1404 "*
1405 HOST_WIDE_INT val;
1406
d435a4be 1407 if (CONST_INT_P (operands[1]))
dcd8b2ee
JB
1408 val = INTVAL (operands[1]);
1409 else
1410 val = 0;
1411
1412 if (val < 0 && const_ok_for_arm (ARM_SIGN_EXTEND (-val)))
1413 return \"cmp\\t%0, #%n1\";
1414 else
1415 return \"cmn\\t%0, %1\";
1416 "
1417 [(set_attr "conds" "set")
544f7fc8 1418 (set_attr "length" "2,4")
b43482db 1419 (set (attr "type") (if_then_else (match_operand 1 "const_int_operand" "")
544f7fc8
YR
1420 (const_string "alus_imm")
1421 (const_string "alus_sreg")))]
dcd8b2ee
JB
1422)
1423
7d31a807
MM
1424(define_insn "*thumb2_mulsi_short"
1425 [(set (match_operand:SI 0 "low_register_operand" "=l")
1426 (mult:SI (match_operand:SI 1 "low_register_operand" "%0")
1427 (match_operand:SI 2 "low_register_operand" "l")))
1428 (clobber (reg:CC CC_REGNUM))]
1429 "TARGET_THUMB2 && optimize_size && reload_completed"
1430 "mul%!\\t%0, %2, %0"
1431 [(set_attr "predicable" "yes")
1432 (set_attr "length" "2")
09485a08 1433 (set_attr "type" "muls")])
7d31a807
MM
1434
1435(define_insn "*thumb2_mulsi_short_compare0"
54138d95
RH
1436 [(set (reg:CC_NZ CC_REGNUM)
1437 (compare:CC_NZ
7d31a807
MM
1438 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1439 (match_operand:SI 2 "register_operand" "l"))
1440 (const_int 0)))
1441 (set (match_operand:SI 0 "register_operand" "=l")
1442 (mult:SI (match_dup 1) (match_dup 2)))]
1443 "TARGET_THUMB2 && optimize_size"
1444 "muls\\t%0, %2, %0"
1445 [(set_attr "length" "2")
09485a08 1446 (set_attr "type" "muls")])
7d31a807
MM
1447
1448(define_insn "*thumb2_mulsi_short_compare0_scratch"
54138d95
RH
1449 [(set (reg:CC_NZ CC_REGNUM)
1450 (compare:CC_NZ
7d31a807
MM
1451 (mult:SI (match_operand:SI 1 "register_operand" "%0")
1452 (match_operand:SI 2 "register_operand" "l"))
1453 (const_int 0)))
3fc604fc 1454 (clobber (match_scratch:SI 0 "=l"))]
7d31a807
MM
1455 "TARGET_THUMB2 && optimize_size"
1456 "muls\\t%0, %2, %0"
1457 [(set_attr "length" "2")
09485a08 1458 (set_attr "type" "muls")])
7d31a807 1459
5b3e6663
PB
1460(define_insn "*thumb2_cbz"
1461 [(set (pc) (if_then_else
1462 (eq (match_operand:SI 0 "s_register_operand" "l,?r")
1463 (const_int 0))
1464 (label_ref (match_operand 1 "" ""))
1465 (pc)))
1466 (clobber (reg:CC CC_REGNUM))]
1467 "TARGET_THUMB2"
1468 "*
98ac6510 1469 if (get_attr_length (insn) == 2)
5b3e6663
PB
1470 return \"cbz\\t%0, %l1\";
1471 else
1472 return \"cmp\\t%0, #0\;beq\\t%l1\";
1473 "
9e64a0bf 1474 [(set (attr "length")
5b3e6663
PB
1475 (if_then_else
1476 (and (ge (minus (match_dup 1) (pc)) (const_int 2))
98ac6510 1477 (le (minus (match_dup 1) (pc)) (const_int 128))
b75b1be2 1478 (not (match_test "which_alternative")))
5b3e6663 1479 (const_int 2)
594726e4
JG
1480 (const_int 8)))
1481 (set_attr "type" "branch,multiple")]
5b3e6663
PB
1482)
1483
1484(define_insn "*thumb2_cbnz"
1485 [(set (pc) (if_then_else
1486 (ne (match_operand:SI 0 "s_register_operand" "l,?r")
1487 (const_int 0))
1488 (label_ref (match_operand 1 "" ""))
1489 (pc)))
1490 (clobber (reg:CC CC_REGNUM))]
1491 "TARGET_THUMB2"
1492 "*
98ac6510 1493 if (get_attr_length (insn) == 2)
5b3e6663
PB
1494 return \"cbnz\\t%0, %l1\";
1495 else
1496 return \"cmp\\t%0, #0\;bne\\t%l1\";
1497 "
9e64a0bf 1498 [(set (attr "length")
5b3e6663
PB
1499 (if_then_else
1500 (and (ge (minus (match_dup 1) (pc)) (const_int 2))
98ac6510 1501 (le (minus (match_dup 1) (pc)) (const_int 128))
b75b1be2 1502 (not (match_test "which_alternative")))
5b3e6663 1503 (const_int 2)
594726e4
JG
1504 (const_int 8)))
1505 (set_attr "type" "branch,multiple")]
5b3e6663 1506)
d1b85efb 1507
d1b85efb
PB
1508(define_insn "*thumb2_one_cmplsi2_short"
1509 [(set (match_operand:SI 0 "low_register_operand" "=l")
1510 (not:SI (match_operand:SI 1 "low_register_operand" "l")))
1511 (clobber (reg:CC CC_REGNUM))]
1512 "TARGET_THUMB2 && reload_completed"
1513 "mvn%!\t%0, %1"
1514 [(set_attr "predicable" "yes")
594726e4
JG
1515 (set_attr "length" "2")
1516 (set_attr "type" "mvn_reg")]
d1b85efb
PB
1517)
1518
d1b85efb
PB
1519(define_insn "*thumb2_negsi2_short"
1520 [(set (match_operand:SI 0 "low_register_operand" "=l")
1521 (neg:SI (match_operand:SI 1 "low_register_operand" "l")))
1522 (clobber (reg:CC CC_REGNUM))]
1523 "TARGET_THUMB2 && reload_completed"
4b04107b 1524 "rsb%!\t%0, %1, #0"
d1b85efb 1525 [(set_attr "predicable" "yes")
594726e4 1526 (set_attr "length" "2")
1d61feeb 1527 (set_attr "type" "alu_sreg")]
d1b85efb
PB
1528)
1529
c29e2982 1530(define_insn "*orsi_notsi_si"
a7994a57
RR
1531 [(set (match_operand:SI 0 "s_register_operand" "=r")
1532 (ior:SI (not:SI (match_operand:SI 2 "s_register_operand" "r"))
64af62c2 1533 (match_operand:SI 1 "s_register_operand" "r")))]
a7994a57
RR
1534 "TARGET_THUMB2"
1535 "orn%?\\t%0, %1, %2"
95b97fac 1536 [(set_attr "predicable" "yes")
594726e4 1537 (set_attr "type" "logic_reg")]
a7994a57
RR
1538)
1539
c29e2982 1540(define_insn "*orsi_not_shiftsi_si"
a7994a57
RR
1541 [(set (match_operand:SI 0 "s_register_operand" "=r")
1542 (ior:SI (not:SI (match_operator:SI 4 "shift_operator"
1543 [(match_operand:SI 2 "s_register_operand" "r")
1544 (match_operand:SI 3 "const_int_operand" "M")]))
1545 (match_operand:SI 1 "s_register_operand" "r")))]
1546 "TARGET_THUMB2"
1547 "orn%?\\t%0, %1, %2%S4"
1548 [(set_attr "predicable" "yes")
1549 (set_attr "shift" "2")
ae27ce51 1550 (set_attr "autodetect_type" "alu_shift_operator4")]
a7994a57
RR
1551)
1552
8850383b 1553(define_peephole2
54138d95
RH
1554 [(set (match_operand:CC_NZ 0 "cc_register" "")
1555 (compare:CC_NZ (zero_extract:SI
8850383b
RE
1556 (match_operand:SI 1 "low_register_operand" "")
1557 (const_int 1)
1558 (match_operand:SI 2 "const_int_operand" ""))
1559 (const_int 0)))
1560 (match_scratch:SI 3 "l")
1561 (set (pc)
54138d95 1562 (if_then_else (match_operator:CC_NZ 4 "equality_operator"
8850383b
RE
1563 [(match_dup 0) (const_int 0)])
1564 (match_operand 5 "" "")
1565 (match_operand 6 "" "")))]
1566 "TARGET_THUMB2
bae7adda
KT
1567 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32)
1568 && peep2_reg_dead_p (2, operands[0])"
8850383b 1569 [(parallel [(set (match_dup 0)
54138d95 1570 (compare:CC_NZ (ashift:SI (match_dup 1) (match_dup 2))
8850383b
RE
1571 (const_int 0)))
1572 (clobber (match_dup 3))])
1573 (set (pc)
1574 (if_then_else (match_op_dup 4 [(match_dup 0) (const_int 0)])
1575 (match_dup 5) (match_dup 6)))]
1576 "
1577 operands[2] = GEN_INT (31 - INTVAL (operands[2]));
1578 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[4]) == NE ? LT : GE,
1579 VOIDmode, operands[0], const0_rtx);
1580 ")
333b67a9 1581
ece53c91 1582(define_peephole2
54138d95
RH
1583 [(set (match_operand:CC_NZ 0 "cc_register" "")
1584 (compare:CC_NZ (zero_extract:SI
ece53c91
WG
1585 (match_operand:SI 1 "low_register_operand" "")
1586 (match_operand:SI 2 "const_int_operand" "")
1587 (const_int 0))
1588 (const_int 0)))
1589 (match_scratch:SI 3 "l")
1590 (set (pc)
54138d95 1591 (if_then_else (match_operator:CC_NZ 4 "equality_operator"
ece53c91
WG
1592 [(match_dup 0) (const_int 0)])
1593 (match_operand 5 "" "")
1594 (match_operand 6 "" "")))]
1595 "TARGET_THUMB2
bae7adda
KT
1596 && (INTVAL (operands[2]) > 0 && INTVAL (operands[2]) < 32)
1597 && peep2_reg_dead_p (2, operands[0])"
ece53c91 1598 [(parallel [(set (match_dup 0)
54138d95
RH
1599 (compare:CC_NZ (ashift:SI (match_dup 1) (match_dup 2))
1600 (const_int 0)))
ece53c91
WG
1601 (clobber (match_dup 3))])
1602 (set (pc)
1603 (if_then_else (match_op_dup 4 [(match_dup 0) (const_int 0)])
1604 (match_dup 5) (match_dup 6)))]
88c1612f
WG
1605 "
1606 operands[2] = GEN_INT (32 - INTVAL (operands[2]));
ece53c91 1607 ")
ce7b3761
RE
1608
1609;; Define the subtract-one-and-jump insns so loop.c
1610;; knows what to generate.
1611(define_expand "doloop_end"
1612 [(use (match_operand 0 "" "")) ; loop pseudo
1d0216c8 1613 (use (match_operand 1 "" ""))] ; label
ce7b3761
RE
1614 "TARGET_32BIT"
1615 "
1616 {
1617 /* Currently SMS relies on the do-loop pattern to recognize loops
1618 where (1) the control part consists of all insns defining and/or
1619 using a certain 'count' register and (2) the loop count can be
1620 adjusted by modifying this register prior to the loop.
1621 ??? The possible introduction of a new block to initialize the
d2ed233c
AC
1622 new IV can potentially affect branch optimizations.
1623
1624 Also used to implement the low over head loops feature, which is part of
1625 the Armv8.1-M Mainline Low Overhead Branch (LOB) extension. */
1626 if (optimize > 0 && (flag_modulo_sched || TARGET_HAVE_LOB))
ce7b3761
RE
1627 {
1628 rtx s0;
1629 rtx bcomp;
1630 rtx loc_ref;
1631 rtx cc_reg;
1632 rtx insn;
1633 rtx cmp;
1634
ce7b3761
RE
1635 if (GET_MODE (operands[0]) != SImode)
1636 FAIL;
1637
1638 s0 = operands [0];
d2ed233c
AC
1639
1640 /* Low over head loop instructions require the first operand to be LR. */
1641 if (TARGET_HAVE_LOB && arm_target_insn_ok_for_lob (operands [1]))
1642 s0 = gen_rtx_REG (SImode, LR_REGNUM);
1643
ce7b3761
RE
1644 if (TARGET_THUMB2)
1645 insn = emit_insn (gen_thumb2_addsi3_compare0 (s0, s0, GEN_INT (-1)));
1646 else
1647 insn = emit_insn (gen_addsi3_compare0 (s0, s0, GEN_INT (-1)));
1648
1649 cmp = XVECEXP (PATTERN (insn), 0, 0);
1650 cc_reg = SET_DEST (cmp);
1651 bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
1d0216c8 1652 loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
f7df4a84 1653 emit_jump_insn (gen_rtx_SET (pc_rtx,
ce7b3761
RE
1654 gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
1655 loc_ref, pc_rtx)));
1656 DONE;
d2ed233c
AC
1657 }
1658 else
1659 FAIL;
ce7b3761
RE
1660 }")
1661
9722215a
MI
1662(define_insn "*clear_apsr"
1663 [(unspec_volatile:SI [(const_int 0)] VUNSPEC_CLRM_APSR)
1664 (clobber (reg:CC CC_REGNUM))]
1665 "TARGET_THUMB2 && TARGET_HAVE_FPCXT_CMSE && use_cmse"
1666 "clrm%?\\t{APSR}"
1667 [(set_attr "predicable" "yes")]
1668)
1669
1670;; The operands are validated through the clear_multiple_operation
1671;; match_parallel predicate rather than through constraints so enable it only
1672;; after reload.
1673(define_insn "*clear_multiple"
1674 [(match_parallel 0 "clear_multiple_operation"
1675 [(set (match_operand:SI 1 "register_operand" "")
1676 (const_int 0))])]
1677 "TARGET_THUMB2 && TARGET_HAVE_FPCXT_CMSE && use_cmse && reload_completed"
1678 {
1679 char pattern[100];
1680 int i, num_saves = XVECLEN (operands[0], 0);
1681
1682 strcpy (pattern, \"clrm%?\\t{\");
1683 for (i = 0; i < num_saves; i++)
1684 {
1685 if (GET_CODE (XVECEXP (operands[0], 0, i)) == UNSPEC_VOLATILE)
1686 {
1687 strcat (pattern, \"APSR\");
1688 ++i;
1689 }
1690 else
1691 strcat (pattern,
1692 reg_names[REGNO (XEXP (XVECEXP (operands[0], 0, i), 0))]);
1693 if (i < num_saves - 1)
1694 strcat (pattern, \", %|\");
1695 }
1696 strcat (pattern, \"}\");
1697 output_asm_insn (pattern, operands);
1698 return \"\";
1699 }
1700 [(set_attr "predicable" "yes")]
1701)
60d616b1
MI
1702
1703(define_insn "thumb2_asrl"
1704 [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
1705 (ashiftrt:DI (match_dup 0)
a968a40c 1706 (match_operand:SI 1 "arm_reg_or_long_shift_imm" "rPg")))]
60d616b1
MI
1707 "TARGET_HAVE_MVE"
1708 "asrl%?\\t%Q0, %R0, %1"
1709 [(set_attr "predicable" "yes")])
1710
1711(define_insn "thumb2_lsll"
1712 [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
1713 (ashift:DI (match_dup 0)
a968a40c 1714 (match_operand:SI 1 "arm_reg_or_long_shift_imm" "rPg")))]
60d616b1
MI
1715 "TARGET_HAVE_MVE"
1716 "lsll%?\\t%Q0, %R0, %1"
1717 [(set_attr "predicable" "yes")])
a968a40c
MI
1718
1719(define_insn "thumb2_lsrl"
1720 [(set (match_operand:DI 0 "arm_general_register_operand" "+r")
1721 (lshiftrt:DI (match_dup 0)
1722 (match_operand:SI 1 "long_shift_imm" "Pg")))]
1723 "TARGET_HAVE_MVE"
1724 "lsrl%?\\t%Q0, %R0, %1"
1725 [(set_attr "predicable" "yes")])
d2ed233c
AC
1726
1727;; Originally expanded by 'doloop_end'.
1728(define_insn "*doloop_end_internal"
38c57034
AC
1729 [(set (pc)
1730 (if_then_else
1731 (ne (reg:SI LR_REGNUM) (const_int 1))
1732 (label_ref (match_operand 0 "" ""))
1733 (pc)))
1734 (set (reg:SI LR_REGNUM)
1735 (plus:SI (reg:SI LR_REGNUM) (const_int -1)))
1736 (clobber (reg:CC CC_REGNUM))]
d2ed233c 1737 "TARGET_32BIT && TARGET_HAVE_LOB"
38c57034
AC
1738 {
1739 if (get_attr_length (insn) == 4)
1740 return "le\t%|lr, %l0";
1741 else
1742 return "subs\t%|lr, #1;bne\t%l0";
1743 }
1744 [(set (attr "length")
1745 (if_then_else
1746 (ltu (minus (pc) (match_dup 0)) (const_int 1024))
1747 (const_int 4)
1748 (const_int 6)))
1749 (set_attr "type" "branch")])
d2ed233c
AC
1750
1751(define_expand "doloop_begin"
1752 [(match_operand 0 "" "")
1753 (match_operand 1 "" "")]
1754 "TARGET_32BIT && TARGET_HAVE_LOB"
1755 {
1756 if (REGNO (operands[0]) == LR_REGNUM)
1757 {
1758 emit_insn (gen_dls_insn (operands[0]));
1759 DONE;
1760 }
1761 else
1762 FAIL;
1763 })
1764
1765(define_insn "dls_insn"
1766 [(set (reg:SI LR_REGNUM)
1767 (unspec:SI [(match_operand:SI 0 "s_register_operand" "r")] UNSPEC_DLS))]
1768 "TARGET_32BIT && TARGET_HAVE_LOB"
1769 "dls\t%|lr, %0")