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