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