1;;- Machine description for ARM for GNU compiler 2;; Copyright (C) 1991-2019 Free Software Foundation, Inc. 3;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) 4;; and Martin Simmons (@harleqn.co.uk). 5;; More major hacks by Richard Earnshaw (rearnsha@arm.com). 6 7;; This file is part of GCC. 8 9;; GCC is free software; you can redistribute it and/or modify it 10;; under the terms of the GNU General Public License as published 11;; by the Free Software Foundation; either version 3, or (at your 12;; option) any later version. 13 14;; GCC is distributed in the hope that it will be useful, but WITHOUT 15;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 16;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 17;; License for more details. 18 19;; You should have received a copy of the GNU General Public License 20;; along with GCC; see the file COPYING3. If not see 21;; <http://www.gnu.org/licenses/>. 22 23;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 24 25 26;;--------------------------------------------------------------------------- 27;; Constants 28 29;; Register numbers -- All machine registers should be defined here 30(define_constants 31 [(R0_REGNUM 0) ; First CORE register 32 (R1_REGNUM 1) ; Second CORE register 33 (R4_REGNUM 4) ; Fifth CORE register 34 (IP_REGNUM 12) ; Scratch register 35 (SP_REGNUM 13) ; Stack pointer 36 (LR_REGNUM 14) ; Return address register 37 (PC_REGNUM 15) ; Program counter 38 (LAST_ARM_REGNUM 15) ; 39 (CC_REGNUM 100) ; Condition code pseudo register 40 (VFPCC_REGNUM 101) ; VFP Condition code pseudo register 41 ] 42) 43;; 3rd operand to select_dominance_cc_mode 44(define_constants 45 [(DOM_CC_X_AND_Y 0) 46 (DOM_CC_NX_OR_Y 1) 47 (DOM_CC_X_OR_Y 2) 48 ] 49) 50;; conditional compare combination 51(define_constants 52 [(CMP_CMP 0) 53 (CMN_CMP 1) 54 (CMP_CMN 2) 55 (CMN_CMN 3) 56 (NUM_OF_COND_CMP 4) 57 ] 58) 59 60 61;;--------------------------------------------------------------------------- 62;; Attributes 63 64;; Processor type. This is created automatically from arm-cores.def. 65(include "arm-tune.md") 66 67;; Instruction classification types 68(include "types.md") 69 70; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when 71; generating ARM code. This is used to control the length of some insn 72; patterns that share the same RTL in both ARM and Thumb code. 73(define_attr "is_thumb" "yes,no" 74 (const (if_then_else (symbol_ref "TARGET_THUMB") 75 (const_string "yes") (const_string "no")))) 76 77; IS_ARCH6 is set to 'yes' when we are generating code form ARMv6. 78(define_attr "is_arch6" "no,yes" (const (symbol_ref "arm_arch6"))) 79 80; IS_THUMB1 is set to 'yes' iff we are generating Thumb-1 code. 81(define_attr "is_thumb1" "yes,no" 82 (const (if_then_else (symbol_ref "TARGET_THUMB1") 83 (const_string "yes") (const_string "no")))) 84 85; Mark an instruction as suitable for "short IT" blocks in Thumb-2. 86; The arm_restrict_it flag enables the "short IT" feature which 87; restricts IT blocks to a single 16-bit instruction. 88; This attribute should only be used on 16-bit Thumb-2 instructions 89; which may be predicated (the "predicable" attribute must be set). 90(define_attr "predicable_short_it" "no,yes" (const_string "no")) 91 92; Mark an instruction as suitable for "short IT" blocks in Thumb-2. 93; This attribute should only be used on instructions which may emit 94; an IT block in their expansion which is not a short IT. 95(define_attr "enabled_for_short_it" "no,yes" (const_string "yes")) 96 97;; Operand number of an input operand that is shifted. Zero if the 98;; given instruction does not shift one of its input operands. 99(define_attr "shift" "" (const_int 0)) 100 101;; [For compatibility with AArch64 in pipeline models] 102;; Attribute that specifies whether or not the instruction touches fp 103;; registers. 104(define_attr "fp" "no,yes" (const_string "no")) 105 106; Floating Point Unit. If we only have floating point emulation, then there 107; is no point in scheduling the floating point insns. (Well, for best 108; performance we should try and group them together). 109(define_attr "fpu" "none,vfp" 110 (const (symbol_ref "arm_fpu_attr"))) 111 112; Predicated means that the insn form is conditionally executed based on a 113; predicate. We default to 'no' because no Thumb patterns match this rule 114; and not all ARM insns do. 115(define_attr "predicated" "yes,no" (const_string "no")) 116 117; LENGTH of an instruction (in bytes) 118(define_attr "length" "" 119 (const_int 4)) 120 121; The architecture which supports the instruction (or alternative). 122; This can be "a" for ARM, "t" for either of the Thumbs, "32" for 123; TARGET_32BIT, "t1" or "t2" to specify a specific Thumb mode. "v6" 124; for ARM or Thumb-2 with arm_arch6, and nov6 for ARM without 125; arm_arch6. "v6t2" for Thumb-2 with arm_arch6 and "v8mb" for ARMv8-M 126; Baseline. This attribute is used to compute attribute "enabled", 127; use type "any" to enable an alternative in all cases. 128(define_attr "arch" "any,a,t,32,t1,t2,v6,nov6,v6t2,v8mb,neon_for_64bits,avoid_neon_for_64bits,iwmmxt,iwmmxt2,armv6_or_vfpv3,neon" 129 (const_string "any")) 130 131(define_attr "arch_enabled" "no,yes" 132 (cond [(eq_attr "arch" "any") 133 (const_string "yes") 134 135 (and (eq_attr "arch" "a") 136 (match_test "TARGET_ARM")) 137 (const_string "yes") 138 139 (and (eq_attr "arch" "t") 140 (match_test "TARGET_THUMB")) 141 (const_string "yes") 142 143 (and (eq_attr "arch" "t1") 144 (match_test "TARGET_THUMB1")) 145 (const_string "yes") 146 147 (and (eq_attr "arch" "t2") 148 (match_test "TARGET_THUMB2")) 149 (const_string "yes") 150 151 (and (eq_attr "arch" "32") 152 (match_test "TARGET_32BIT")) 153 (const_string "yes") 154 155 (and (eq_attr "arch" "v6") 156 (match_test "TARGET_32BIT && arm_arch6")) 157 (const_string "yes") 158 159 (and (eq_attr "arch" "nov6") 160 (match_test "TARGET_32BIT && !arm_arch6")) 161 (const_string "yes") 162 163 (and (eq_attr "arch" "v6t2") 164 (match_test "TARGET_32BIT && arm_arch6 && arm_arch_thumb2")) 165 (const_string "yes") 166 167 (and (eq_attr "arch" "v8mb") 168 (match_test "TARGET_THUMB1 && arm_arch8")) 169 (const_string "yes") 170 171 (and (eq_attr "arch" "avoid_neon_for_64bits") 172 (match_test "TARGET_NEON") 173 (not (match_test "TARGET_PREFER_NEON_64BITS"))) 174 (const_string "yes") 175 176 (and (eq_attr "arch" "neon_for_64bits") 177 (match_test "TARGET_NEON") 178 (match_test "TARGET_PREFER_NEON_64BITS")) 179 (const_string "yes") 180 181 (and (eq_attr "arch" "iwmmxt2") 182 (match_test "TARGET_REALLY_IWMMXT2")) 183 (const_string "yes") 184 185 (and (eq_attr "arch" "armv6_or_vfpv3") 186 (match_test "arm_arch6 || TARGET_VFP3")) 187 (const_string "yes") 188 189 (and (eq_attr "arch" "neon") 190 (match_test "TARGET_NEON")) 191 (const_string "yes") 192 ] 193 194 (const_string "no"))) 195 196(define_attr "opt" "any,speed,size" 197 (const_string "any")) 198 199(define_attr "opt_enabled" "no,yes" 200 (cond [(eq_attr "opt" "any") 201 (const_string "yes") 202 203 (and (eq_attr "opt" "speed") 204 (match_test "optimize_function_for_speed_p (cfun)")) 205 (const_string "yes") 206 207 (and (eq_attr "opt" "size") 208 (match_test "optimize_function_for_size_p (cfun)")) 209 (const_string "yes")] 210 (const_string "no"))) 211 212(define_attr "use_literal_pool" "no,yes" 213 (cond [(and (eq_attr "type" "f_loads,f_loadd") 214 (match_test "CONSTANT_P (operands[1])")) 215 (const_string "yes")] 216 (const_string "no"))) 217 218; Enable all alternatives that are both arch_enabled and insn_enabled. 219; FIXME:: opt_enabled has been temporarily removed till the time we have 220; an attribute that allows the use of such alternatives. 221; This depends on caching of speed_p, size_p on a per 222; alternative basis. The problem is that the enabled attribute 223; cannot depend on any state that is not cached or is not constant 224; for a compilation unit. We probably need a generic "hot/cold" 225; alternative which if implemented can help with this. We disable this 226; until such a time as this is implemented and / or the improvements or 227; regressions with removing this attribute are double checked. 228; See ashldi3_neon and <shift>di3_neon in neon.md. 229 230 (define_attr "enabled" "no,yes" 231 (cond [(and (eq_attr "predicable_short_it" "no") 232 (and (eq_attr "predicated" "yes") 233 (match_test "arm_restrict_it"))) 234 (const_string "no") 235 236 (and (eq_attr "enabled_for_short_it" "no") 237 (match_test "arm_restrict_it")) 238 (const_string "no") 239 240 (eq_attr "arch_enabled" "no") 241 (const_string "no")] 242 (const_string "yes"))) 243 244; POOL_RANGE is how far away from a constant pool entry that this insn 245; can be placed. If the distance is zero, then this insn will never 246; reference the pool. 247; Note that for Thumb constant pools the PC value is rounded down to the 248; nearest multiple of four. Therefore, THUMB2_POOL_RANGE (and POOL_RANGE for 249; Thumb insns) should be set to <max_range> - 2. 250; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry 251; before its address. It is set to <max_range> - (8 + <data_size>). 252(define_attr "arm_pool_range" "" (const_int 0)) 253(define_attr "thumb2_pool_range" "" (const_int 0)) 254(define_attr "arm_neg_pool_range" "" (const_int 0)) 255(define_attr "thumb2_neg_pool_range" "" (const_int 0)) 256 257(define_attr "pool_range" "" 258 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_pool_range")] 259 (attr "arm_pool_range"))) 260(define_attr "neg_pool_range" "" 261 (cond [(eq_attr "is_thumb" "yes") (attr "thumb2_neg_pool_range")] 262 (attr "arm_neg_pool_range"))) 263 264; An assembler sequence may clobber the condition codes without us knowing. 265; If such an insn references the pool, then we have no way of knowing how, 266; so use the most conservative value for pool_range. 267(define_asm_attributes 268 [(set_attr "conds" "clob") 269 (set_attr "length" "4") 270 (set_attr "pool_range" "250")]) 271 272; Load scheduling, set from the arm_ld_sched variable 273; initialized by arm_option_override() 274(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched"))) 275 276; condition codes: this one is used by final_prescan_insn to speed up 277; conditionalizing instructions. It saves having to scan the rtl to see if 278; it uses or alters the condition codes. 279; 280; USE means that the condition codes are used by the insn in the process of 281; outputting code, this means (at present) that we can't use the insn in 282; inlined branches 283; 284; SET means that the purpose of the insn is to set the condition codes in a 285; well defined manner. 286; 287; CLOB means that the condition codes are altered in an undefined manner, if 288; they are altered at all 289; 290; UNCONDITIONAL means the instruction cannot be conditionally executed and 291; that the instruction does not use or alter the condition codes. 292; 293; NOCOND means that the instruction does not use or alter the condition 294; codes but can be converted into a conditionally exectuted instruction. 295 296(define_attr "conds" "use,set,clob,unconditional,nocond" 297 (if_then_else 298 (ior (eq_attr "is_thumb1" "yes") 299 (eq_attr "type" "call")) 300 (const_string "clob") 301 (if_then_else (eq_attr "is_neon_type" "no") 302 (const_string "nocond") 303 (const_string "unconditional")))) 304 305; Predicable means that the insn can be conditionally executed based on 306; an automatically added predicate (additional patterns are generated by 307; gen...). We default to 'no' because no Thumb patterns match this rule 308; and not all ARM patterns do. 309(define_attr "predicable" "no,yes" (const_string "no")) 310 311; Only model the write buffer for ARM6 and ARM7. Earlier processors don't 312; have one. Later ones, such as StrongARM, have write-back caches, so don't 313; suffer blockages enough to warrant modelling this (and it can adversely 314; affect the schedule). 315(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_tune_wbuf"))) 316 317; WRITE_CONFLICT implies that a read following an unrelated write is likely 318; to stall the processor. Used with model_wbuf above. 319(define_attr "write_conflict" "no,yes" 320 (if_then_else (eq_attr "type" 321 "block,call,load_4") 322 (const_string "yes") 323 (const_string "no"))) 324 325; Classify the insns into those that take one cycle and those that take more 326; than one on the main cpu execution unit. 327(define_attr "core_cycles" "single,multi" 328 (if_then_else (eq_attr "type" 329 "adc_imm, adc_reg, adcs_imm, adcs_reg, adr, alu_ext, alu_imm, alu_sreg,\ 330 alu_shift_imm, alu_shift_reg, alu_dsp_reg, alus_ext, alus_imm, alus_sreg,\ 331 alus_shift_imm, alus_shift_reg, bfm, csel, rev, logic_imm, logic_reg,\ 332 logic_shift_imm, logic_shift_reg, logics_imm, logics_reg,\ 333 logics_shift_imm, logics_shift_reg, extend, shift_imm, float, fcsel,\ 334 wmmx_wor, wmmx_wxor, wmmx_wand, wmmx_wandn, wmmx_wmov, wmmx_tmcrr,\ 335 wmmx_tmrrc, wmmx_wldr, wmmx_wstr, wmmx_tmcr, wmmx_tmrc, wmmx_wadd,\ 336 wmmx_wsub, wmmx_wmul, wmmx_wmac, wmmx_wavg2, wmmx_tinsr, wmmx_textrm,\ 337 wmmx_wshufh, wmmx_wcmpeq, wmmx_wcmpgt, wmmx_wmax, wmmx_wmin, wmmx_wpack,\ 338 wmmx_wunpckih, wmmx_wunpckil, wmmx_wunpckeh, wmmx_wunpckel, wmmx_wror,\ 339 wmmx_wsra, wmmx_wsrl, wmmx_wsll, wmmx_wmadd, wmmx_tmia, wmmx_tmiaph,\ 340 wmmx_tmiaxy, wmmx_tbcst, wmmx_tmovmsk, wmmx_wacc, wmmx_waligni,\ 341 wmmx_walignr, wmmx_tandc, wmmx_textrc, wmmx_torc, wmmx_torvsc, wmmx_wsad,\ 342 wmmx_wabs, wmmx_wabsdiff, wmmx_waddsubhx, wmmx_wsubaddhx, wmmx_wavg4,\ 343 wmmx_wmulw, wmmx_wqmulm, wmmx_wqmulwm, wmmx_waddbhus, wmmx_wqmiaxy,\ 344 wmmx_wmiaxy, wmmx_wmiawxy, wmmx_wmerge") 345 (const_string "single") 346 (const_string "multi"))) 347 348;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a 349;; distant label. Only applicable to Thumb code. 350(define_attr "far_jump" "yes,no" (const_string "no")) 351 352 353;; The number of machine instructions this pattern expands to. 354;; Used for Thumb-2 conditional execution. 355(define_attr "ce_count" "" (const_int 1)) 356 357;;--------------------------------------------------------------------------- 358;; Unspecs 359 360(include "unspecs.md") 361 362;;--------------------------------------------------------------------------- 363;; Mode iterators 364 365(include "iterators.md") 366 367;;--------------------------------------------------------------------------- 368;; Predicates 369 370(include "predicates.md") 371(include "constraints.md") 372 373;;--------------------------------------------------------------------------- 374;; Pipeline descriptions 375 376(define_attr "tune_cortexr4" "yes,no" 377 (const (if_then_else 378 (eq_attr "tune" "cortexr4,cortexr4f,cortexr5") 379 (const_string "yes") 380 (const_string "no")))) 381 382;; True if the generic scheduling description should be used. 383 384(define_attr "generic_sched" "yes,no" 385 (const (if_then_else 386 (ior (eq_attr "tune" "fa526,fa626,fa606te,fa626te,fmp626,fa726te,\ 387 arm926ejs,arm10e,arm1026ejs,arm1136js,\ 388 arm1136jfs,cortexa5,cortexa7,cortexa8,\ 389 cortexa9,cortexa12,cortexa15,cortexa17,\ 390 cortexa53,cortexa57,cortexm4,cortexm7,\ 391 exynosm1,marvell_pj4,xgene1") 392 (eq_attr "tune_cortexr4" "yes")) 393 (const_string "no") 394 (const_string "yes")))) 395 396(define_attr "generic_vfp" "yes,no" 397 (const (if_then_else 398 (and (eq_attr "fpu" "vfp") 399 (eq_attr "tune" "!arm10e,cortexa5,cortexa7,\ 400 cortexa8,cortexa9,cortexa53,cortexm4,\ 401 cortexm7,marvell_pj4,xgene1") 402 (eq_attr "tune_cortexr4" "no")) 403 (const_string "yes") 404 (const_string "no")))) 405 406(include "marvell-f-iwmmxt.md") 407(include "arm-generic.md") 408(include "arm926ejs.md") 409(include "arm1020e.md") 410(include "arm1026ejs.md") 411(include "arm1136jfs.md") 412(include "fa526.md") 413(include "fa606te.md") 414(include "fa626te.md") 415(include "fmp626.md") 416(include "fa726te.md") 417(include "cortex-a5.md") 418(include "cortex-a7.md") 419(include "cortex-a8.md") 420(include "cortex-a9.md") 421(include "cortex-a15.md") 422(include "cortex-a17.md") 423(include "cortex-a53.md") 424(include "cortex-a57.md") 425(include "cortex-r4.md") 426(include "cortex-r4f.md") 427(include "cortex-m7.md") 428(include "cortex-m4.md") 429(include "cortex-m4-fpu.md") 430(include "exynos-m1.md") 431(include "vfp11.md") 432(include "marvell-pj4.md") 433(include "xgene1.md") 434 435 436;;--------------------------------------------------------------------------- 437;; Insn patterns 438;; 439;; Addition insns. 440 441;; Note: For DImode insns, there is normally no reason why operands should 442;; not be in the same register, what we don't want is for something being 443;; written to partially overlap something that is an input. 444 445(define_expand "adddi3" 446 [(parallel 447 [(set (match_operand:DI 0 "s_register_operand" "") 448 (plus:DI (match_operand:DI 1 "s_register_operand" "") 449 (match_operand:DI 2 "arm_adddi_operand" ""))) 450 (clobber (reg:CC CC_REGNUM))])] 451 "TARGET_EITHER" 452 " 453 if (TARGET_THUMB1) 454 { 455 if (!REG_P (operands[1])) 456 operands[1] = force_reg (DImode, operands[1]); 457 if (!REG_P (operands[2])) 458 operands[2] = force_reg (DImode, operands[2]); 459 } 460 " 461) 462 463(define_insn_and_split "*arm_adddi3" 464 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r,&r,&r") 465 (plus:DI (match_operand:DI 1 "arm_general_register_operand" "%0, 0, r, 0, r") 466 (match_operand:DI 2 "arm_general_adddi_operand" "r, 0, r, Dd, Dd"))) 467 (clobber (reg:CC CC_REGNUM))] 468 "TARGET_32BIT && !TARGET_NEON" 469 "#" 470 "TARGET_32BIT && ((!TARGET_NEON && !TARGET_IWMMXT) || reload_completed)" 471 [(parallel [(set (reg:CC_C CC_REGNUM) 472 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) 473 (match_dup 1))) 474 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 475 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (match_dup 5)) 476 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 477 " 478 { 479 operands[3] = gen_highpart (SImode, operands[0]); 480 operands[0] = gen_lowpart (SImode, operands[0]); 481 operands[4] = gen_highpart (SImode, operands[1]); 482 operands[1] = gen_lowpart (SImode, operands[1]); 483 operands[5] = gen_highpart_mode (SImode, DImode, operands[2]); 484 operands[2] = gen_lowpart (SImode, operands[2]); 485 }" 486 [(set_attr "conds" "clob") 487 (set_attr "length" "8") 488 (set_attr "type" "multiple")] 489) 490 491(define_insn_and_split "*adddi_sesidi_di" 492 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 493 (plus:DI (sign_extend:DI 494 (match_operand:SI 2 "s_register_operand" "r,r")) 495 (match_operand:DI 1 "s_register_operand" "0,r"))) 496 (clobber (reg:CC CC_REGNUM))] 497 "TARGET_32BIT" 498 "#" 499 "TARGET_32BIT && reload_completed" 500 [(parallel [(set (reg:CC_C CC_REGNUM) 501 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) 502 (match_dup 1))) 503 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 504 (set (match_dup 3) (plus:SI (plus:SI (ashiftrt:SI (match_dup 2) 505 (const_int 31)) 506 (match_dup 4)) 507 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 508 " 509 { 510 operands[3] = gen_highpart (SImode, operands[0]); 511 operands[0] = gen_lowpart (SImode, operands[0]); 512 operands[4] = gen_highpart (SImode, operands[1]); 513 operands[1] = gen_lowpart (SImode, operands[1]); 514 operands[2] = gen_lowpart (SImode, operands[2]); 515 }" 516 [(set_attr "conds" "clob") 517 (set_attr "length" "8") 518 (set_attr "type" "multiple")] 519) 520 521(define_insn_and_split "*adddi_zesidi_di" 522 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 523 (plus:DI (zero_extend:DI 524 (match_operand:SI 2 "s_register_operand" "r,r")) 525 (match_operand:DI 1 "s_register_operand" "0,r"))) 526 (clobber (reg:CC CC_REGNUM))] 527 "TARGET_32BIT" 528 "#" 529 "TARGET_32BIT && reload_completed" 530 [(parallel [(set (reg:CC_C CC_REGNUM) 531 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) 532 (match_dup 1))) 533 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 534 (set (match_dup 3) (plus:SI (plus:SI (match_dup 4) (const_int 0)) 535 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 536 " 537 { 538 operands[3] = gen_highpart (SImode, operands[0]); 539 operands[0] = gen_lowpart (SImode, operands[0]); 540 operands[4] = gen_highpart (SImode, operands[1]); 541 operands[1] = gen_lowpart (SImode, operands[1]); 542 operands[2] = gen_lowpart (SImode, operands[2]); 543 }" 544 [(set_attr "conds" "clob") 545 (set_attr "length" "8") 546 (set_attr "type" "multiple")] 547) 548 549(define_expand "addv<mode>4" 550 [(match_operand:SIDI 0 "register_operand") 551 (match_operand:SIDI 1 "register_operand") 552 (match_operand:SIDI 2 "register_operand") 553 (match_operand 3 "")] 554 "TARGET_32BIT" 555{ 556 emit_insn (gen_add<mode>3_compareV (operands[0], operands[1], operands[2])); 557 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); 558 559 DONE; 560}) 561 562(define_expand "uaddv<mode>4" 563 [(match_operand:SIDI 0 "register_operand") 564 (match_operand:SIDI 1 "register_operand") 565 (match_operand:SIDI 2 "register_operand") 566 (match_operand 3 "")] 567 "TARGET_32BIT" 568{ 569 emit_insn (gen_add<mode>3_compareC (operands[0], operands[1], operands[2])); 570 arm_gen_unlikely_cbranch (NE, CC_Cmode, operands[3]); 571 572 DONE; 573}) 574 575(define_expand "addsi3" 576 [(set (match_operand:SI 0 "s_register_operand" "") 577 (plus:SI (match_operand:SI 1 "s_register_operand" "") 578 (match_operand:SI 2 "reg_or_int_operand" "")))] 579 "TARGET_EITHER" 580 " 581 if (TARGET_32BIT && CONST_INT_P (operands[2])) 582 { 583 arm_split_constant (PLUS, SImode, NULL_RTX, 584 INTVAL (operands[2]), operands[0], operands[1], 585 optimize && can_create_pseudo_p ()); 586 DONE; 587 } 588 " 589) 590 591; If there is a scratch available, this will be faster than synthesizing the 592; addition. 593(define_peephole2 594 [(match_scratch:SI 3 "r") 595 (set (match_operand:SI 0 "arm_general_register_operand" "") 596 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "") 597 (match_operand:SI 2 "const_int_operand" "")))] 598 "TARGET_32BIT && 599 !(const_ok_for_arm (INTVAL (operands[2])) 600 || const_ok_for_arm (-INTVAL (operands[2]))) 601 && const_ok_for_arm (~INTVAL (operands[2]))" 602 [(set (match_dup 3) (match_dup 2)) 603 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))] 604 "" 605) 606 607;; The r/r/k alternative is required when reloading the address 608;; (plus (reg rN) (reg sp)) into (reg rN). In this case reload will 609;; put the duplicated register first, and not try the commutative version. 610(define_insn_and_split "*arm_addsi3" 611 [(set (match_operand:SI 0 "s_register_operand" "=rk,l,l ,l ,r ,k ,r,k ,r ,k ,r ,k,k,r ,k ,r") 612 (plus:SI (match_operand:SI 1 "s_register_operand" "%0 ,l,0 ,l ,rk,k ,r,r ,rk,k ,rk,k,r,rk,k ,rk") 613 (match_operand:SI 2 "reg_or_int_operand" "rk ,l,Py,Pd,rI,rI,k,rI,Pj,Pj,L ,L,L,PJ,PJ,?n")))] 614 "TARGET_32BIT" 615 "@ 616 add%?\\t%0, %0, %2 617 add%?\\t%0, %1, %2 618 add%?\\t%0, %1, %2 619 add%?\\t%0, %1, %2 620 add%?\\t%0, %1, %2 621 add%?\\t%0, %1, %2 622 add%?\\t%0, %2, %1 623 add%?\\t%0, %1, %2 624 addw%?\\t%0, %1, %2 625 addw%?\\t%0, %1, %2 626 sub%?\\t%0, %1, #%n2 627 sub%?\\t%0, %1, #%n2 628 sub%?\\t%0, %1, #%n2 629 subw%?\\t%0, %1, #%n2 630 subw%?\\t%0, %1, #%n2 631 #" 632 "TARGET_32BIT 633 && CONST_INT_P (operands[2]) 634 && !const_ok_for_op (INTVAL (operands[2]), PLUS) 635 && (reload_completed || !arm_eliminable_register (operands[1]))" 636 [(clobber (const_int 0))] 637 " 638 arm_split_constant (PLUS, SImode, curr_insn, 639 INTVAL (operands[2]), operands[0], 640 operands[1], 0); 641 DONE; 642 " 643 [(set_attr "length" "2,4,4,4,4,4,4,4,4,4,4,4,4,4,4,16") 644 (set_attr "predicable" "yes") 645 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no,no,no,no,no,no,no,no") 646 (set_attr "arch" "t2,t2,t2,t2,*,*,*,a,t2,t2,*,*,a,t2,t2,*") 647 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") 648 (const_string "alu_imm") 649 (const_string "alu_sreg"))) 650 ] 651) 652 653(define_insn_and_split "adddi3_compareV" 654 [(set (reg:CC_V CC_REGNUM) 655 (ne:CC_V 656 (plus:TI 657 (sign_extend:TI (match_operand:DI 1 "register_operand" "r")) 658 (sign_extend:TI (match_operand:DI 2 "register_operand" "r"))) 659 (sign_extend:TI (plus:DI (match_dup 1) (match_dup 2))))) 660 (set (match_operand:DI 0 "register_operand" "=&r") 661 (plus:DI (match_dup 1) (match_dup 2)))] 662 "TARGET_32BIT" 663 "#" 664 "&& reload_completed" 665 [(parallel [(set (reg:CC_C CC_REGNUM) 666 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) 667 (match_dup 1))) 668 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 669 (parallel [(set (reg:CC_V CC_REGNUM) 670 (ne:CC_V 671 (plus:DI (plus:DI 672 (sign_extend:DI (match_dup 4)) 673 (sign_extend:DI (match_dup 5))) 674 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) 675 (plus:DI (sign_extend:DI 676 (plus:SI (match_dup 4) (match_dup 5))) 677 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) 678 (set (match_dup 3) (plus:SI (plus:SI 679 (match_dup 4) (match_dup 5)) 680 (ltu:SI (reg:CC_C CC_REGNUM) 681 (const_int 0))))])] 682 " 683 { 684 operands[3] = gen_highpart (SImode, operands[0]); 685 operands[0] = gen_lowpart (SImode, operands[0]); 686 operands[4] = gen_highpart (SImode, operands[1]); 687 operands[1] = gen_lowpart (SImode, operands[1]); 688 operands[5] = gen_highpart (SImode, operands[2]); 689 operands[2] = gen_lowpart (SImode, operands[2]); 690 }" 691 [(set_attr "conds" "set") 692 (set_attr "length" "8") 693 (set_attr "type" "multiple")] 694) 695 696(define_insn "addsi3_compareV" 697 [(set (reg:CC_V CC_REGNUM) 698 (ne:CC_V 699 (plus:DI 700 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 701 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) 702 (sign_extend:DI (plus:SI (match_dup 1) (match_dup 2))))) 703 (set (match_operand:SI 0 "register_operand" "=r") 704 (plus:SI (match_dup 1) (match_dup 2)))] 705 "TARGET_32BIT" 706 "adds%?\\t%0, %1, %2" 707 [(set_attr "conds" "set") 708 (set_attr "type" "alus_sreg")] 709) 710 711(define_insn "*addsi3_compareV_upper" 712 [(set (reg:CC_V CC_REGNUM) 713 (ne:CC_V 714 (plus:DI 715 (plus:DI 716 (sign_extend:DI (match_operand:SI 1 "register_operand" "r")) 717 (sign_extend:DI (match_operand:SI 2 "register_operand" "r"))) 718 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) 719 (plus:DI (sign_extend:DI 720 (plus:SI (match_dup 1) (match_dup 2))) 721 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) 722 (set (match_operand:SI 0 "register_operand" "=r") 723 (plus:SI 724 (plus:SI (match_dup 1) (match_dup 2)) 725 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 726 "TARGET_32BIT" 727 "adcs%?\\t%0, %1, %2" 728 [(set_attr "conds" "set") 729 (set_attr "type" "adcs_reg")] 730) 731 732(define_insn_and_split "adddi3_compareC" 733 [(set (reg:CC_C CC_REGNUM) 734 (ne:CC_C 735 (plus:TI 736 (zero_extend:TI (match_operand:DI 1 "register_operand" "r")) 737 (zero_extend:TI (match_operand:DI 2 "register_operand" "r"))) 738 (zero_extend:TI (plus:DI (match_dup 1) (match_dup 2))))) 739 (set (match_operand:DI 0 "register_operand" "=&r") 740 (plus:DI (match_dup 1) (match_dup 2)))] 741 "TARGET_32BIT" 742 "#" 743 "&& reload_completed" 744 [(parallel [(set (reg:CC_C CC_REGNUM) 745 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) 746 (match_dup 1))) 747 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 748 (parallel [(set (reg:CC_C CC_REGNUM) 749 (ne:CC_C 750 (plus:DI (plus:DI 751 (zero_extend:DI (match_dup 4)) 752 (zero_extend:DI (match_dup 5))) 753 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) 754 (plus:DI (zero_extend:DI 755 (plus:SI (match_dup 4) (match_dup 5))) 756 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) 757 (set (match_dup 3) (plus:SI 758 (plus:SI (match_dup 4) (match_dup 5)) 759 (ltu:SI (reg:CC_C CC_REGNUM) 760 (const_int 0))))])] 761 " 762 { 763 operands[3] = gen_highpart (SImode, operands[0]); 764 operands[0] = gen_lowpart (SImode, operands[0]); 765 operands[4] = gen_highpart (SImode, operands[1]); 766 operands[5] = gen_highpart (SImode, operands[2]); 767 operands[1] = gen_lowpart (SImode, operands[1]); 768 operands[2] = gen_lowpart (SImode, operands[2]); 769 }" 770 [(set_attr "conds" "set") 771 (set_attr "length" "8") 772 (set_attr "type" "multiple")] 773) 774 775(define_insn "*addsi3_compareC_upper" 776 [(set (reg:CC_C CC_REGNUM) 777 (ne:CC_C 778 (plus:DI 779 (plus:DI 780 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 781 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) 782 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))) 783 (plus:DI (zero_extend:DI 784 (plus:SI (match_dup 1) (match_dup 2))) 785 (ltu:DI (reg:CC_C CC_REGNUM) (const_int 0))))) 786 (set (match_operand:SI 0 "register_operand" "=r") 787 (plus:SI 788 (plus:SI (match_dup 1) (match_dup 2)) 789 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 790 "TARGET_32BIT" 791 "adcs%?\\t%0, %1, %2" 792 [(set_attr "conds" "set") 793 (set_attr "type" "adcs_reg")] 794) 795 796(define_insn "addsi3_compareC" 797 [(set (reg:CC_C CC_REGNUM) 798 (ne:CC_C 799 (plus:DI 800 (zero_extend:DI (match_operand:SI 1 "register_operand" "r")) 801 (zero_extend:DI (match_operand:SI 2 "register_operand" "r"))) 802 (zero_extend:DI 803 (plus:SI (match_dup 1) (match_dup 2))))) 804 (set (match_operand:SI 0 "register_operand" "=r") 805 (plus:SI (match_dup 1) (match_dup 2)))] 806 "TARGET_32BIT" 807 "adds%?\\t%0, %1, %2" 808 [(set_attr "conds" "set") 809 (set_attr "type" "alus_sreg")] 810) 811 812(define_insn "addsi3_compare0" 813 [(set (reg:CC_NOOV CC_REGNUM) 814 (compare:CC_NOOV 815 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r,r") 816 (match_operand:SI 2 "arm_add_operand" "I,L,r")) 817 (const_int 0))) 818 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 819 (plus:SI (match_dup 1) (match_dup 2)))] 820 "TARGET_ARM" 821 "@ 822 adds%?\\t%0, %1, %2 823 subs%?\\t%0, %1, #%n2 824 adds%?\\t%0, %1, %2" 825 [(set_attr "conds" "set") 826 (set_attr "type" "alus_imm,alus_imm,alus_sreg")] 827) 828 829(define_insn "*addsi3_compare0_scratch" 830 [(set (reg:CC_NOOV CC_REGNUM) 831 (compare:CC_NOOV 832 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r, r") 833 (match_operand:SI 1 "arm_add_operand" "I,L, r")) 834 (const_int 0)))] 835 "TARGET_ARM" 836 "@ 837 cmn%?\\t%0, %1 838 cmp%?\\t%0, #%n1 839 cmn%?\\t%0, %1" 840 [(set_attr "conds" "set") 841 (set_attr "predicable" "yes") 842 (set_attr "type" "alus_imm,alus_imm,alus_sreg")] 843) 844 845(define_insn "*compare_negsi_si" 846 [(set (reg:CC_Z CC_REGNUM) 847 (compare:CC_Z 848 (neg:SI (match_operand:SI 0 "s_register_operand" "l,r")) 849 (match_operand:SI 1 "s_register_operand" "l,r")))] 850 "TARGET_32BIT" 851 "cmn%?\\t%1, %0" 852 [(set_attr "conds" "set") 853 (set_attr "predicable" "yes") 854 (set_attr "arch" "t2,*") 855 (set_attr "length" "2,4") 856 (set_attr "predicable_short_it" "yes,no") 857 (set_attr "type" "alus_sreg")] 858) 859 860;; This is the canonicalization of subsi3_compare when the 861;; addend is a constant. 862(define_insn "cmpsi2_addneg" 863 [(set (reg:CC CC_REGNUM) 864 (compare:CC 865 (match_operand:SI 1 "s_register_operand" "r,r") 866 (match_operand:SI 2 "arm_addimm_operand" "I,L"))) 867 (set (match_operand:SI 0 "s_register_operand" "=r,r") 868 (plus:SI (match_dup 1) 869 (match_operand:SI 3 "arm_addimm_operand" "L,I")))] 870 "TARGET_32BIT 871 && (INTVAL (operands[2]) 872 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))" 873{ 874 /* For 0 and INT_MIN it is essential that we use subs, as adds will result 875 in different condition codes (like cmn rather than like cmp), so that 876 alternative comes first. Both alternatives can match for any 0x??000000 877 where except for 0 and INT_MIN it doesn't matter what we choose, and also 878 for -1 and 1 with TARGET_THUMB2, in that case prefer instruction with #1 879 as it is shorter. */ 880 if (which_alternative == 0 && operands[3] != const1_rtx) 881 return "subs%?\\t%0, %1, #%n3"; 882 else 883 return "adds%?\\t%0, %1, %3"; 884} 885 [(set_attr "conds" "set") 886 (set_attr "type" "alus_sreg")] 887) 888 889;; Convert the sequence 890;; sub rd, rn, #1 891;; cmn rd, #1 (equivalent to cmp rd, #-1) 892;; bne dest 893;; into 894;; subs rd, rn, #1 895;; bcs dest ((unsigned)rn >= 1) 896;; similarly for the beq variant using bcc. 897;; This is a common looping idiom (while (n--)) 898(define_peephole2 899 [(set (match_operand:SI 0 "arm_general_register_operand" "") 900 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "") 901 (const_int -1))) 902 (set (match_operand 2 "cc_register" "") 903 (compare (match_dup 0) (const_int -1))) 904 (set (pc) 905 (if_then_else (match_operator 3 "equality_operator" 906 [(match_dup 2) (const_int 0)]) 907 (match_operand 4 "" "") 908 (match_operand 5 "" "")))] 909 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])" 910 [(parallel[ 911 (set (match_dup 2) 912 (compare:CC 913 (match_dup 1) (const_int 1))) 914 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))]) 915 (set (pc) 916 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)]) 917 (match_dup 4) 918 (match_dup 5)))] 919 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM); 920 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE 921 ? GEU : LTU), 922 VOIDmode, 923 operands[2], const0_rtx);" 924) 925 926;; The next four insns work because they compare the result with one of 927;; the operands, and we know that the use of the condition code is 928;; either GEU or LTU, so we can use the carry flag from the addition 929;; instead of doing the compare a second time. 930(define_insn "*addsi3_compare_op1" 931 [(set (reg:CC_C CC_REGNUM) 932 (compare:CC_C 933 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 934 (match_operand:SI 2 "arm_add_operand" "I,L,r")) 935 (match_dup 1))) 936 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 937 (plus:SI (match_dup 1) (match_dup 2)))] 938 "TARGET_32BIT" 939 "@ 940 adds%?\\t%0, %1, %2 941 subs%?\\t%0, %1, #%n2 942 adds%?\\t%0, %1, %2" 943 [(set_attr "conds" "set") 944 (set_attr "type" "alus_imm,alus_imm,alus_sreg")] 945) 946 947(define_insn "*addsi3_compare_op2" 948 [(set (reg:CC_C CC_REGNUM) 949 (compare:CC_C 950 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 951 (match_operand:SI 2 "arm_add_operand" "I,L,r")) 952 (match_dup 2))) 953 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 954 (plus:SI (match_dup 1) (match_dup 2)))] 955 "TARGET_32BIT" 956 "@ 957 adds%?\\t%0, %1, %2 958 subs%?\\t%0, %1, #%n2 959 adds%?\\t%0, %1, %2" 960 [(set_attr "conds" "set") 961 (set_attr "type" "alus_imm,alus_imm,alus_sreg")] 962) 963 964(define_insn "*compare_addsi2_op0" 965 [(set (reg:CC_C CC_REGNUM) 966 (compare:CC_C 967 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r") 968 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r")) 969 (match_dup 0)))] 970 "TARGET_32BIT" 971 "@ 972 cmp%?\\t%0, #%n1 973 cmn%?\\t%0, %1 974 cmn%?\\t%0, %1 975 cmp%?\\t%0, #%n1 976 cmn%?\\t%0, %1" 977 [(set_attr "conds" "set") 978 (set_attr "predicable" "yes") 979 (set_attr "arch" "t2,t2,*,*,*") 980 (set_attr "predicable_short_it" "yes,yes,no,no,no") 981 (set_attr "length" "2,2,4,4,4") 982 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")] 983) 984 985(define_insn "*compare_addsi2_op1" 986 [(set (reg:CC_C CC_REGNUM) 987 (compare:CC_C 988 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r") 989 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r")) 990 (match_dup 1)))] 991 "TARGET_32BIT" 992 "@ 993 cmp%?\\t%0, #%n1 994 cmn%?\\t%0, %1 995 cmn%?\\t%0, %1 996 cmp%?\\t%0, #%n1 997 cmn%?\\t%0, %1" 998 [(set_attr "conds" "set") 999 (set_attr "predicable" "yes") 1000 (set_attr "arch" "t2,t2,*,*,*") 1001 (set_attr "predicable_short_it" "yes,yes,no,no,no") 1002 (set_attr "length" "2,2,4,4,4") 1003 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")] 1004 ) 1005 1006(define_insn "*addsi3_carryin_<optab>" 1007 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r") 1008 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r") 1009 (match_operand:SI 2 "arm_not_operand" "0,rI,K")) 1010 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))] 1011 "TARGET_32BIT" 1012 "@ 1013 adc%?\\t%0, %1, %2 1014 adc%?\\t%0, %1, %2 1015 sbc%?\\t%0, %1, #%B2" 1016 [(set_attr "conds" "use") 1017 (set_attr "predicable" "yes") 1018 (set_attr "arch" "t2,*,*") 1019 (set_attr "length" "4") 1020 (set_attr "predicable_short_it" "yes,no,no") 1021 (set_attr "type" "adc_reg,adc_reg,adc_imm")] 1022) 1023 1024(define_insn "*addsi3_carryin_alt2_<optab>" 1025 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r") 1026 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0)) 1027 (match_operand:SI 1 "s_register_operand" "%l,r,r")) 1028 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))] 1029 "TARGET_32BIT" 1030 "@ 1031 adc%?\\t%0, %1, %2 1032 adc%?\\t%0, %1, %2 1033 sbc%?\\t%0, %1, #%B2" 1034 [(set_attr "conds" "use") 1035 (set_attr "predicable" "yes") 1036 (set_attr "arch" "t2,*,*") 1037 (set_attr "length" "4") 1038 (set_attr "predicable_short_it" "yes,no,no") 1039 (set_attr "type" "adc_reg,adc_reg,adc_imm")] 1040) 1041 1042(define_insn "*addsi3_carryin_shift_<optab>" 1043 [(set (match_operand:SI 0 "s_register_operand" "=r") 1044 (plus:SI (plus:SI 1045 (match_operator:SI 2 "shift_operator" 1046 [(match_operand:SI 3 "s_register_operand" "r") 1047 (match_operand:SI 4 "reg_or_int_operand" "rM")]) 1048 (match_operand:SI 1 "s_register_operand" "r")) 1049 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))] 1050 "TARGET_32BIT" 1051 "adc%?\\t%0, %1, %3%S2" 1052 [(set_attr "conds" "use") 1053 (set_attr "predicable" "yes") 1054 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") 1055 (const_string "alu_shift_imm") 1056 (const_string "alu_shift_reg")))] 1057) 1058 1059(define_insn "*addsi3_carryin_clobercc_<optab>" 1060 [(set (match_operand:SI 0 "s_register_operand" "=r") 1061 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r") 1062 (match_operand:SI 2 "arm_rhs_operand" "rI")) 1063 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0)))) 1064 (clobber (reg:CC CC_REGNUM))] 1065 "TARGET_32BIT" 1066 "adcs%?\\t%0, %1, %2" 1067 [(set_attr "conds" "set") 1068 (set_attr "type" "adcs_reg")] 1069) 1070 1071(define_expand "subv<mode>4" 1072 [(match_operand:SIDI 0 "register_operand") 1073 (match_operand:SIDI 1 "register_operand") 1074 (match_operand:SIDI 2 "register_operand") 1075 (match_operand 3 "")] 1076 "TARGET_32BIT" 1077{ 1078 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2])); 1079 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); 1080 1081 DONE; 1082}) 1083 1084(define_expand "usubv<mode>4" 1085 [(match_operand:SIDI 0 "register_operand") 1086 (match_operand:SIDI 1 "register_operand") 1087 (match_operand:SIDI 2 "register_operand") 1088 (match_operand 3 "")] 1089 "TARGET_32BIT" 1090{ 1091 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2])); 1092 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]); 1093 1094 DONE; 1095}) 1096 1097(define_insn_and_split "subdi3_compare1" 1098 [(set (reg:CC CC_REGNUM) 1099 (compare:CC 1100 (match_operand:DI 1 "register_operand" "r") 1101 (match_operand:DI 2 "register_operand" "r"))) 1102 (set (match_operand:DI 0 "register_operand" "=&r") 1103 (minus:DI (match_dup 1) (match_dup 2)))] 1104 "TARGET_32BIT" 1105 "#" 1106 "&& reload_completed" 1107 [(parallel [(set (reg:CC CC_REGNUM) 1108 (compare:CC (match_dup 1) (match_dup 2))) 1109 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 1110 (parallel [(set (reg:CC CC_REGNUM) 1111 (compare:CC (match_dup 4) (match_dup 5))) 1112 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5)) 1113 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])] 1114 { 1115 operands[3] = gen_highpart (SImode, operands[0]); 1116 operands[0] = gen_lowpart (SImode, operands[0]); 1117 operands[4] = gen_highpart (SImode, operands[1]); 1118 operands[1] = gen_lowpart (SImode, operands[1]); 1119 operands[5] = gen_highpart (SImode, operands[2]); 1120 operands[2] = gen_lowpart (SImode, operands[2]); 1121 } 1122 [(set_attr "conds" "set") 1123 (set_attr "length" "8") 1124 (set_attr "type" "multiple")] 1125) 1126 1127(define_insn "subsi3_compare1" 1128 [(set (reg:CC CC_REGNUM) 1129 (compare:CC 1130 (match_operand:SI 1 "register_operand" "r") 1131 (match_operand:SI 2 "register_operand" "r"))) 1132 (set (match_operand:SI 0 "register_operand" "=r") 1133 (minus:SI (match_dup 1) (match_dup 2)))] 1134 "TARGET_32BIT" 1135 "subs%?\\t%0, %1, %2" 1136 [(set_attr "conds" "set") 1137 (set_attr "type" "alus_sreg")] 1138) 1139 1140(define_insn "*subsi3_carryin" 1141 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 1142 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz") 1143 (match_operand:SI 2 "s_register_operand" "r,r,r")) 1144 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1145 "TARGET_32BIT" 1146 "@ 1147 sbc%?\\t%0, %1, %2 1148 rsc%?\\t%0, %2, %1 1149 sbc%?\\t%0, %2, %2, lsl #1" 1150 [(set_attr "conds" "use") 1151 (set_attr "arch" "*,a,t2") 1152 (set_attr "predicable" "yes") 1153 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")] 1154) 1155 1156(define_insn "*subsi3_carryin_const" 1157 [(set (match_operand:SI 0 "s_register_operand" "=r") 1158 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") 1159 (match_operand:SI 2 "arm_neg_immediate_operand" "L")) 1160 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1161 "TARGET_32BIT" 1162 "sbc\\t%0, %1, #%n2" 1163 [(set_attr "conds" "use") 1164 (set_attr "type" "adc_imm")] 1165) 1166 1167(define_insn "*subsi3_carryin_const0" 1168 [(set (match_operand:SI 0 "s_register_operand" "=r") 1169 (minus:SI (match_operand:SI 1 "s_register_operand" "r") 1170 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1171 "TARGET_32BIT" 1172 "sbc\\t%0, %1, #0" 1173 [(set_attr "conds" "use") 1174 (set_attr "type" "adc_imm")] 1175) 1176 1177(define_insn "*subsi3_carryin_compare" 1178 [(set (reg:CC CC_REGNUM) 1179 (compare:CC (match_operand:SI 1 "s_register_operand" "r") 1180 (match_operand:SI 2 "s_register_operand" "r"))) 1181 (set (match_operand:SI 0 "s_register_operand" "=r") 1182 (minus:SI (minus:SI (match_dup 1) 1183 (match_dup 2)) 1184 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1185 "TARGET_32BIT" 1186 "sbcs\\t%0, %1, %2" 1187 [(set_attr "conds" "set") 1188 (set_attr "type" "adcs_reg")] 1189) 1190 1191(define_insn "*subsi3_carryin_compare_const" 1192 [(set (reg:CC CC_REGNUM) 1193 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r") 1194 (match_operand:SI 2 "const_int_I_operand" "I"))) 1195 (set (match_operand:SI 0 "s_register_operand" "=r") 1196 (minus:SI (plus:SI (match_dup 1) 1197 (match_operand:SI 3 "arm_neg_immediate_operand" "L")) 1198 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1199 "TARGET_32BIT 1200 && (INTVAL (operands[2]) 1201 == trunc_int_for_mode (-INTVAL (operands[3]), SImode))" 1202 "sbcs\\t%0, %1, #%n3" 1203 [(set_attr "conds" "set") 1204 (set_attr "type" "adcs_imm")] 1205) 1206 1207(define_insn "*subsi3_carryin_compare_const0" 1208 [(set (reg:CC CC_REGNUM) 1209 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r") 1210 (const_int 0))) 1211 (set (match_operand:SI 0 "s_register_operand" "=r") 1212 (minus:SI (match_dup 1) 1213 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1214 "TARGET_32BIT" 1215 "sbcs\\t%0, %1, #0" 1216 [(set_attr "conds" "set") 1217 (set_attr "type" "adcs_imm")] 1218) 1219 1220(define_insn "*subsi3_carryin_shift" 1221 [(set (match_operand:SI 0 "s_register_operand" "=r") 1222 (minus:SI (minus:SI 1223 (match_operand:SI 1 "s_register_operand" "r") 1224 (match_operator:SI 2 "shift_operator" 1225 [(match_operand:SI 3 "s_register_operand" "r") 1226 (match_operand:SI 4 "reg_or_int_operand" "rM")])) 1227 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1228 "TARGET_32BIT" 1229 "sbc%?\\t%0, %1, %3%S2" 1230 [(set_attr "conds" "use") 1231 (set_attr "predicable" "yes") 1232 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") 1233 (const_string "alu_shift_imm") 1234 (const_string "alu_shift_reg")))] 1235) 1236 1237(define_insn "*rsbsi3_carryin_shift" 1238 [(set (match_operand:SI 0 "s_register_operand" "=r") 1239 (minus:SI (minus:SI 1240 (match_operator:SI 2 "shift_operator" 1241 [(match_operand:SI 3 "s_register_operand" "r") 1242 (match_operand:SI 4 "reg_or_int_operand" "rM")]) 1243 (match_operand:SI 1 "s_register_operand" "r")) 1244 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1245 "TARGET_ARM" 1246 "rsc%?\\t%0, %1, %3%S2" 1247 [(set_attr "conds" "use") 1248 (set_attr "predicable" "yes") 1249 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") 1250 (const_string "alu_shift_imm") 1251 (const_string "alu_shift_reg")))] 1252) 1253 1254; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant. 1255(define_split 1256 [(set (match_operand:SI 0 "s_register_operand" "") 1257 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "") 1258 (match_operand:SI 2 "s_register_operand" "")) 1259 (const_int -1))) 1260 (clobber (match_operand:SI 3 "s_register_operand" ""))] 1261 "TARGET_32BIT" 1262 [(set (match_dup 3) (match_dup 1)) 1263 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))] 1264 " 1265 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1)); 1266") 1267 1268(define_expand "addsf3" 1269 [(set (match_operand:SF 0 "s_register_operand" "") 1270 (plus:SF (match_operand:SF 1 "s_register_operand" "") 1271 (match_operand:SF 2 "s_register_operand" "")))] 1272 "TARGET_32BIT && TARGET_HARD_FLOAT" 1273 " 1274") 1275 1276(define_expand "adddf3" 1277 [(set (match_operand:DF 0 "s_register_operand" "") 1278 (plus:DF (match_operand:DF 1 "s_register_operand" "") 1279 (match_operand:DF 2 "s_register_operand" "")))] 1280 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 1281 " 1282") 1283 1284(define_expand "subdi3" 1285 [(parallel 1286 [(set (match_operand:DI 0 "s_register_operand" "") 1287 (minus:DI (match_operand:DI 1 "s_register_operand" "") 1288 (match_operand:DI 2 "s_register_operand" ""))) 1289 (clobber (reg:CC CC_REGNUM))])] 1290 "TARGET_EITHER" 1291 " 1292 if (TARGET_THUMB1) 1293 { 1294 if (!REG_P (operands[1])) 1295 operands[1] = force_reg (DImode, operands[1]); 1296 if (!REG_P (operands[2])) 1297 operands[2] = force_reg (DImode, operands[2]); 1298 } 1299 " 1300) 1301 1302(define_insn_and_split "*arm_subdi3" 1303 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r") 1304 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0") 1305 (match_operand:DI 2 "arm_general_register_operand" "r,0,0"))) 1306 (clobber (reg:CC CC_REGNUM))] 1307 "TARGET_32BIT && !TARGET_NEON" 1308 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2" 1309 "&& (!TARGET_IWMMXT || reload_completed)" 1310 [(parallel [(set (reg:CC CC_REGNUM) 1311 (compare:CC (match_dup 1) (match_dup 2))) 1312 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 1313 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5)) 1314 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1315 { 1316 operands[3] = gen_highpart (SImode, operands[0]); 1317 operands[0] = gen_lowpart (SImode, operands[0]); 1318 operands[4] = gen_highpart (SImode, operands[1]); 1319 operands[1] = gen_lowpart (SImode, operands[1]); 1320 operands[5] = gen_highpart (SImode, operands[2]); 1321 operands[2] = gen_lowpart (SImode, operands[2]); 1322 } 1323 [(set_attr "conds" "clob") 1324 (set_attr "length" "8") 1325 (set_attr "type" "multiple")] 1326) 1327 1328(define_insn_and_split "*subdi_di_zesidi" 1329 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1330 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r") 1331 (zero_extend:DI 1332 (match_operand:SI 2 "s_register_operand" "r,r")))) 1333 (clobber (reg:CC CC_REGNUM))] 1334 "TARGET_32BIT" 1335 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0" 1336 "&& reload_completed" 1337 [(parallel [(set (reg:CC CC_REGNUM) 1338 (compare:CC (match_dup 1) (match_dup 2))) 1339 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 1340 (set (match_dup 3) (minus:SI (match_dup 4) 1341 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1342 { 1343 operands[3] = gen_highpart (SImode, operands[0]); 1344 operands[0] = gen_lowpart (SImode, operands[0]); 1345 operands[4] = gen_highpart (SImode, operands[1]); 1346 operands[1] = gen_lowpart (SImode, operands[1]); 1347 } 1348 [(set_attr "conds" "clob") 1349 (set_attr "length" "8") 1350 (set_attr "type" "multiple")] 1351) 1352 1353(define_insn_and_split "*subdi_di_sesidi" 1354 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1355 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r") 1356 (sign_extend:DI 1357 (match_operand:SI 2 "s_register_operand" "r,r")))) 1358 (clobber (reg:CC CC_REGNUM))] 1359 "TARGET_32BIT" 1360 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31" 1361 "&& reload_completed" 1362 [(parallel [(set (reg:CC CC_REGNUM) 1363 (compare:CC (match_dup 1) (match_dup 2))) 1364 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 1365 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) 1366 (ashiftrt:SI (match_dup 2) 1367 (const_int 31))) 1368 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1369 { 1370 operands[3] = gen_highpart (SImode, operands[0]); 1371 operands[0] = gen_lowpart (SImode, operands[0]); 1372 operands[4] = gen_highpart (SImode, operands[1]); 1373 operands[1] = gen_lowpart (SImode, operands[1]); 1374 } 1375 [(set_attr "conds" "clob") 1376 (set_attr "length" "8") 1377 (set_attr "type" "multiple")] 1378) 1379 1380(define_insn_and_split "*subdi_zesidi_di" 1381 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1382 (minus:DI (zero_extend:DI 1383 (match_operand:SI 2 "s_register_operand" "r,r")) 1384 (match_operand:DI 1 "s_register_operand" "0,r"))) 1385 (clobber (reg:CC CC_REGNUM))] 1386 "TARGET_ARM" 1387 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0" 1388 ; is equivalent to: 1389 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0" 1390 "&& reload_completed" 1391 [(parallel [(set (reg:CC CC_REGNUM) 1392 (compare:CC (match_dup 2) (match_dup 1))) 1393 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))]) 1394 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4)) 1395 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1396 { 1397 operands[3] = gen_highpart (SImode, operands[0]); 1398 operands[0] = gen_lowpart (SImode, operands[0]); 1399 operands[4] = gen_highpart (SImode, operands[1]); 1400 operands[1] = gen_lowpart (SImode, operands[1]); 1401 } 1402 [(set_attr "conds" "clob") 1403 (set_attr "length" "8") 1404 (set_attr "type" "multiple")] 1405) 1406 1407(define_insn_and_split "*subdi_sesidi_di" 1408 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1409 (minus:DI (sign_extend:DI 1410 (match_operand:SI 2 "s_register_operand" "r,r")) 1411 (match_operand:DI 1 "s_register_operand" "0,r"))) 1412 (clobber (reg:CC CC_REGNUM))] 1413 "TARGET_ARM" 1414 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31" 1415 ; is equivalent to: 1416 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31" 1417 "&& reload_completed" 1418 [(parallel [(set (reg:CC CC_REGNUM) 1419 (compare:CC (match_dup 2) (match_dup 1))) 1420 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))]) 1421 (set (match_dup 3) (minus:SI (minus:SI 1422 (ashiftrt:SI (match_dup 2) 1423 (const_int 31)) 1424 (match_dup 4)) 1425 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1426 { 1427 operands[3] = gen_highpart (SImode, operands[0]); 1428 operands[0] = gen_lowpart (SImode, operands[0]); 1429 operands[4] = gen_highpart (SImode, operands[1]); 1430 operands[1] = gen_lowpart (SImode, operands[1]); 1431 } 1432 [(set_attr "conds" "clob") 1433 (set_attr "length" "8") 1434 (set_attr "type" "multiple")] 1435) 1436 1437(define_insn_and_split "*subdi_zesidi_zesidi" 1438 [(set (match_operand:DI 0 "s_register_operand" "=r") 1439 (minus:DI (zero_extend:DI 1440 (match_operand:SI 1 "s_register_operand" "r")) 1441 (zero_extend:DI 1442 (match_operand:SI 2 "s_register_operand" "r")))) 1443 (clobber (reg:CC CC_REGNUM))] 1444 "TARGET_32BIT" 1445 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1" 1446 "&& reload_completed" 1447 [(parallel [(set (reg:CC CC_REGNUM) 1448 (compare:CC (match_dup 1) (match_dup 2))) 1449 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 1450 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1)) 1451 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1452 { 1453 operands[3] = gen_highpart (SImode, operands[0]); 1454 operands[0] = gen_lowpart (SImode, operands[0]); 1455 } 1456 [(set_attr "conds" "clob") 1457 (set_attr "length" "8") 1458 (set_attr "type" "multiple")] 1459) 1460 1461(define_expand "subsi3" 1462 [(set (match_operand:SI 0 "s_register_operand" "") 1463 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "") 1464 (match_operand:SI 2 "s_register_operand" "")))] 1465 "TARGET_EITHER" 1466 " 1467 if (CONST_INT_P (operands[1])) 1468 { 1469 if (TARGET_32BIT) 1470 { 1471 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS)) 1472 operands[1] = force_reg (SImode, operands[1]); 1473 else 1474 { 1475 arm_split_constant (MINUS, SImode, NULL_RTX, 1476 INTVAL (operands[1]), operands[0], 1477 operands[2], 1478 optimize && can_create_pseudo_p ()); 1479 DONE; 1480 } 1481 } 1482 else /* TARGET_THUMB1 */ 1483 operands[1] = force_reg (SImode, operands[1]); 1484 } 1485 " 1486) 1487 1488; ??? Check Thumb-2 split length 1489(define_insn_and_split "*arm_subsi3_insn" 1490 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r") 1491 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n") 1492 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))] 1493 "TARGET_32BIT" 1494 "@ 1495 sub%?\\t%0, %1, %2 1496 sub%?\\t%0, %2 1497 sub%?\\t%0, %1, %2 1498 rsb%?\\t%0, %2, %1 1499 rsb%?\\t%0, %2, %1 1500 sub%?\\t%0, %1, %2 1501 sub%?\\t%0, %1, %2 1502 sub%?\\t%0, %1, %2 1503 #" 1504 "&& (CONST_INT_P (operands[1]) 1505 && !const_ok_for_arm (INTVAL (operands[1])))" 1506 [(clobber (const_int 0))] 1507 " 1508 arm_split_constant (MINUS, SImode, curr_insn, 1509 INTVAL (operands[1]), operands[0], operands[2], 0); 1510 DONE; 1511 " 1512 [(set_attr "length" "4,4,4,4,4,4,4,4,16") 1513 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*") 1514 (set_attr "predicable" "yes") 1515 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no") 1516 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")] 1517) 1518 1519(define_peephole2 1520 [(match_scratch:SI 3 "r") 1521 (set (match_operand:SI 0 "arm_general_register_operand" "") 1522 (minus:SI (match_operand:SI 1 "const_int_operand" "") 1523 (match_operand:SI 2 "arm_general_register_operand" "")))] 1524 "TARGET_32BIT 1525 && !const_ok_for_arm (INTVAL (operands[1])) 1526 && const_ok_for_arm (~INTVAL (operands[1]))" 1527 [(set (match_dup 3) (match_dup 1)) 1528 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))] 1529 "" 1530) 1531 1532(define_insn "subsi3_compare0" 1533 [(set (reg:CC_NOOV CC_REGNUM) 1534 (compare:CC_NOOV 1535 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I") 1536 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")) 1537 (const_int 0))) 1538 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 1539 (minus:SI (match_dup 1) (match_dup 2)))] 1540 "TARGET_32BIT" 1541 "@ 1542 subs%?\\t%0, %1, %2 1543 subs%?\\t%0, %1, %2 1544 rsbs%?\\t%0, %2, %1" 1545 [(set_attr "conds" "set") 1546 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")] 1547) 1548 1549(define_insn "subsi3_compare" 1550 [(set (reg:CC CC_REGNUM) 1551 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I") 1552 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))) 1553 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 1554 (minus:SI (match_dup 1) (match_dup 2)))] 1555 "TARGET_32BIT" 1556 "@ 1557 subs%?\\t%0, %1, %2 1558 subs%?\\t%0, %1, %2 1559 rsbs%?\\t%0, %2, %1" 1560 [(set_attr "conds" "set") 1561 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")] 1562) 1563 1564(define_expand "subsf3" 1565 [(set (match_operand:SF 0 "s_register_operand" "") 1566 (minus:SF (match_operand:SF 1 "s_register_operand" "") 1567 (match_operand:SF 2 "s_register_operand" "")))] 1568 "TARGET_32BIT && TARGET_HARD_FLOAT" 1569 " 1570") 1571 1572(define_expand "subdf3" 1573 [(set (match_operand:DF 0 "s_register_operand" "") 1574 (minus:DF (match_operand:DF 1 "s_register_operand" "") 1575 (match_operand:DF 2 "s_register_operand" "")))] 1576 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 1577 " 1578") 1579 1580 1581;; Multiplication insns 1582 1583(define_expand "mulhi3" 1584 [(set (match_operand:HI 0 "s_register_operand" "") 1585 (mult:HI (match_operand:HI 1 "s_register_operand" "") 1586 (match_operand:HI 2 "s_register_operand" "")))] 1587 "TARGET_DSP_MULTIPLY" 1588 " 1589 { 1590 rtx result = gen_reg_rtx (SImode); 1591 emit_insn (gen_mulhisi3 (result, operands[1], operands[2])); 1592 emit_move_insn (operands[0], gen_lowpart (HImode, result)); 1593 DONE; 1594 }" 1595) 1596 1597(define_expand "mulsi3" 1598 [(set (match_operand:SI 0 "s_register_operand" "") 1599 (mult:SI (match_operand:SI 2 "s_register_operand" "") 1600 (match_operand:SI 1 "s_register_operand" "")))] 1601 "TARGET_EITHER" 1602 "" 1603) 1604 1605;; Use `&' and then `0' to prevent the operands 0 and 1 being the same 1606(define_insn "*arm_mulsi3" 1607 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1608 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") 1609 (match_operand:SI 1 "s_register_operand" "%0,r")))] 1610 "TARGET_32BIT && !arm_arch6" 1611 "mul%?\\t%0, %2, %1" 1612 [(set_attr "type" "mul") 1613 (set_attr "predicable" "yes")] 1614) 1615 1616(define_insn "*arm_mulsi3_v6" 1617 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") 1618 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r") 1619 (match_operand:SI 2 "s_register_operand" "l,0,r")))] 1620 "TARGET_32BIT && arm_arch6" 1621 "mul%?\\t%0, %1, %2" 1622 [(set_attr "type" "mul") 1623 (set_attr "predicable" "yes") 1624 (set_attr "arch" "t2,t2,*") 1625 (set_attr "length" "4") 1626 (set_attr "predicable_short_it" "yes,yes,no")] 1627) 1628 1629(define_insn "*mulsi3_compare0" 1630 [(set (reg:CC_NOOV CC_REGNUM) 1631 (compare:CC_NOOV (mult:SI 1632 (match_operand:SI 2 "s_register_operand" "r,r") 1633 (match_operand:SI 1 "s_register_operand" "%0,r")) 1634 (const_int 0))) 1635 (set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1636 (mult:SI (match_dup 2) (match_dup 1)))] 1637 "TARGET_ARM && !arm_arch6" 1638 "muls%?\\t%0, %2, %1" 1639 [(set_attr "conds" "set") 1640 (set_attr "type" "muls")] 1641) 1642 1643(define_insn "*mulsi3_compare0_v6" 1644 [(set (reg:CC_NOOV CC_REGNUM) 1645 (compare:CC_NOOV (mult:SI 1646 (match_operand:SI 2 "s_register_operand" "r") 1647 (match_operand:SI 1 "s_register_operand" "r")) 1648 (const_int 0))) 1649 (set (match_operand:SI 0 "s_register_operand" "=r") 1650 (mult:SI (match_dup 2) (match_dup 1)))] 1651 "TARGET_ARM && arm_arch6 && optimize_size" 1652 "muls%?\\t%0, %2, %1" 1653 [(set_attr "conds" "set") 1654 (set_attr "type" "muls")] 1655) 1656 1657(define_insn "*mulsi_compare0_scratch" 1658 [(set (reg:CC_NOOV CC_REGNUM) 1659 (compare:CC_NOOV (mult:SI 1660 (match_operand:SI 2 "s_register_operand" "r,r") 1661 (match_operand:SI 1 "s_register_operand" "%0,r")) 1662 (const_int 0))) 1663 (clobber (match_scratch:SI 0 "=&r,&r"))] 1664 "TARGET_ARM && !arm_arch6" 1665 "muls%?\\t%0, %2, %1" 1666 [(set_attr "conds" "set") 1667 (set_attr "type" "muls")] 1668) 1669 1670(define_insn "*mulsi_compare0_scratch_v6" 1671 [(set (reg:CC_NOOV CC_REGNUM) 1672 (compare:CC_NOOV (mult:SI 1673 (match_operand:SI 2 "s_register_operand" "r") 1674 (match_operand:SI 1 "s_register_operand" "r")) 1675 (const_int 0))) 1676 (clobber (match_scratch:SI 0 "=r"))] 1677 "TARGET_ARM && arm_arch6 && optimize_size" 1678 "muls%?\\t%0, %2, %1" 1679 [(set_attr "conds" "set") 1680 (set_attr "type" "muls")] 1681) 1682 1683;; Unnamed templates to match MLA instruction. 1684 1685(define_insn "*mulsi3addsi" 1686 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") 1687 (plus:SI 1688 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r") 1689 (match_operand:SI 1 "s_register_operand" "%0,r,0,r")) 1690 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))] 1691 "TARGET_32BIT && !arm_arch6" 1692 "mla%?\\t%0, %2, %1, %3" 1693 [(set_attr "type" "mla") 1694 (set_attr "predicable" "yes")] 1695) 1696 1697(define_insn "*mulsi3addsi_v6" 1698 [(set (match_operand:SI 0 "s_register_operand" "=r") 1699 (plus:SI 1700 (mult:SI (match_operand:SI 2 "s_register_operand" "r") 1701 (match_operand:SI 1 "s_register_operand" "r")) 1702 (match_operand:SI 3 "s_register_operand" "r")))] 1703 "TARGET_32BIT && arm_arch6" 1704 "mla%?\\t%0, %2, %1, %3" 1705 [(set_attr "type" "mla") 1706 (set_attr "predicable" "yes")] 1707) 1708 1709(define_insn "*mulsi3addsi_compare0" 1710 [(set (reg:CC_NOOV CC_REGNUM) 1711 (compare:CC_NOOV 1712 (plus:SI (mult:SI 1713 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 1714 (match_operand:SI 1 "s_register_operand" "%0,r,0,r")) 1715 (match_operand:SI 3 "s_register_operand" "r,r,0,0")) 1716 (const_int 0))) 1717 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") 1718 (plus:SI (mult:SI (match_dup 2) (match_dup 1)) 1719 (match_dup 3)))] 1720 "TARGET_ARM && arm_arch6" 1721 "mlas%?\\t%0, %2, %1, %3" 1722 [(set_attr "conds" "set") 1723 (set_attr "type" "mlas")] 1724) 1725 1726(define_insn "*mulsi3addsi_compare0_v6" 1727 [(set (reg:CC_NOOV CC_REGNUM) 1728 (compare:CC_NOOV 1729 (plus:SI (mult:SI 1730 (match_operand:SI 2 "s_register_operand" "r") 1731 (match_operand:SI 1 "s_register_operand" "r")) 1732 (match_operand:SI 3 "s_register_operand" "r")) 1733 (const_int 0))) 1734 (set (match_operand:SI 0 "s_register_operand" "=r") 1735 (plus:SI (mult:SI (match_dup 2) (match_dup 1)) 1736 (match_dup 3)))] 1737 "TARGET_ARM && arm_arch6 && optimize_size" 1738 "mlas%?\\t%0, %2, %1, %3" 1739 [(set_attr "conds" "set") 1740 (set_attr "type" "mlas")] 1741) 1742 1743(define_insn "*mulsi3addsi_compare0_scratch" 1744 [(set (reg:CC_NOOV CC_REGNUM) 1745 (compare:CC_NOOV 1746 (plus:SI (mult:SI 1747 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 1748 (match_operand:SI 1 "s_register_operand" "%0,r,0,r")) 1749 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")) 1750 (const_int 0))) 1751 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))] 1752 "TARGET_ARM && !arm_arch6" 1753 "mlas%?\\t%0, %2, %1, %3" 1754 [(set_attr "conds" "set") 1755 (set_attr "type" "mlas")] 1756) 1757 1758(define_insn "*mulsi3addsi_compare0_scratch_v6" 1759 [(set (reg:CC_NOOV CC_REGNUM) 1760 (compare:CC_NOOV 1761 (plus:SI (mult:SI 1762 (match_operand:SI 2 "s_register_operand" "r") 1763 (match_operand:SI 1 "s_register_operand" "r")) 1764 (match_operand:SI 3 "s_register_operand" "r")) 1765 (const_int 0))) 1766 (clobber (match_scratch:SI 0 "=r"))] 1767 "TARGET_ARM && arm_arch6 && optimize_size" 1768 "mlas%?\\t%0, %2, %1, %3" 1769 [(set_attr "conds" "set") 1770 (set_attr "type" "mlas")] 1771) 1772 1773(define_insn "*mulsi3subsi" 1774 [(set (match_operand:SI 0 "s_register_operand" "=r") 1775 (minus:SI 1776 (match_operand:SI 3 "s_register_operand" "r") 1777 (mult:SI (match_operand:SI 2 "s_register_operand" "r") 1778 (match_operand:SI 1 "s_register_operand" "r"))))] 1779 "TARGET_32BIT && arm_arch_thumb2" 1780 "mls%?\\t%0, %2, %1, %3" 1781 [(set_attr "type" "mla") 1782 (set_attr "predicable" "yes")] 1783) 1784 1785(define_expand "maddsidi4" 1786 [(set (match_operand:DI 0 "s_register_operand" "") 1787 (plus:DI 1788 (mult:DI 1789 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1790 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))) 1791 (match_operand:DI 3 "s_register_operand" "")))] 1792 "TARGET_32BIT" 1793 "") 1794 1795(define_insn "*mulsidi3adddi" 1796 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1797 (plus:DI 1798 (mult:DI 1799 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r")) 1800 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r"))) 1801 (match_operand:DI 1 "s_register_operand" "0")))] 1802 "TARGET_32BIT && !arm_arch6" 1803 "smlal%?\\t%Q0, %R0, %3, %2" 1804 [(set_attr "type" "smlal") 1805 (set_attr "predicable" "yes")] 1806) 1807 1808(define_insn "*mulsidi3adddi_v6" 1809 [(set (match_operand:DI 0 "s_register_operand" "=r") 1810 (plus:DI 1811 (mult:DI 1812 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")) 1813 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r"))) 1814 (match_operand:DI 1 "s_register_operand" "0")))] 1815 "TARGET_32BIT && arm_arch6" 1816 "smlal%?\\t%Q0, %R0, %3, %2" 1817 [(set_attr "type" "smlal") 1818 (set_attr "predicable" "yes")] 1819) 1820 1821;; 32x32->64 widening multiply. 1822;; As with mulsi3, the only difference between the v3-5 and v6+ 1823;; versions of these patterns is the requirement that the output not 1824;; overlap the inputs, but that still means we have to have a named 1825;; expander and two different starred insns. 1826 1827(define_expand "mulsidi3" 1828 [(set (match_operand:DI 0 "s_register_operand" "") 1829 (mult:DI 1830 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1831 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))] 1832 "TARGET_32BIT" 1833 "" 1834) 1835 1836(define_insn "*mulsidi3_nov6" 1837 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1838 (mult:DI 1839 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r")) 1840 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] 1841 "TARGET_32BIT && !arm_arch6" 1842 "smull%?\\t%Q0, %R0, %1, %2" 1843 [(set_attr "type" "smull") 1844 (set_attr "predicable" "yes")] 1845) 1846 1847(define_insn "*mulsidi3_v6" 1848 [(set (match_operand:DI 0 "s_register_operand" "=r") 1849 (mult:DI 1850 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")) 1851 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] 1852 "TARGET_32BIT && arm_arch6" 1853 "smull%?\\t%Q0, %R0, %1, %2" 1854 [(set_attr "type" "smull") 1855 (set_attr "predicable" "yes")] 1856) 1857 1858(define_expand "umulsidi3" 1859 [(set (match_operand:DI 0 "s_register_operand" "") 1860 (mult:DI 1861 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1862 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))] 1863 "TARGET_32BIT" 1864 "" 1865) 1866 1867(define_insn "*umulsidi3_nov6" 1868 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1869 (mult:DI 1870 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r")) 1871 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] 1872 "TARGET_32BIT && !arm_arch6" 1873 "umull%?\\t%Q0, %R0, %1, %2" 1874 [(set_attr "type" "umull") 1875 (set_attr "predicable" "yes")] 1876) 1877 1878(define_insn "*umulsidi3_v6" 1879 [(set (match_operand:DI 0 "s_register_operand" "=r") 1880 (mult:DI 1881 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")) 1882 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] 1883 "TARGET_32BIT && arm_arch6" 1884 "umull%?\\t%Q0, %R0, %1, %2" 1885 [(set_attr "type" "umull") 1886 (set_attr "predicable" "yes")] 1887) 1888 1889(define_expand "umaddsidi4" 1890 [(set (match_operand:DI 0 "s_register_operand" "") 1891 (plus:DI 1892 (mult:DI 1893 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1894 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))) 1895 (match_operand:DI 3 "s_register_operand" "")))] 1896 "TARGET_32BIT" 1897 "") 1898 1899(define_insn "*umulsidi3adddi" 1900 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1901 (plus:DI 1902 (mult:DI 1903 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r")) 1904 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r"))) 1905 (match_operand:DI 1 "s_register_operand" "0")))] 1906 "TARGET_32BIT && !arm_arch6" 1907 "umlal%?\\t%Q0, %R0, %3, %2" 1908 [(set_attr "type" "umlal") 1909 (set_attr "predicable" "yes")] 1910) 1911 1912(define_insn "*umulsidi3adddi_v6" 1913 [(set (match_operand:DI 0 "s_register_operand" "=r") 1914 (plus:DI 1915 (mult:DI 1916 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")) 1917 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r"))) 1918 (match_operand:DI 1 "s_register_operand" "0")))] 1919 "TARGET_32BIT && arm_arch6" 1920 "umlal%?\\t%Q0, %R0, %3, %2" 1921 [(set_attr "type" "umlal") 1922 (set_attr "predicable" "yes")] 1923) 1924 1925(define_expand "smulsi3_highpart" 1926 [(parallel 1927 [(set (match_operand:SI 0 "s_register_operand" "") 1928 (truncate:SI 1929 (lshiftrt:DI 1930 (mult:DI 1931 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1932 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))) 1933 (const_int 32)))) 1934 (clobber (match_scratch:SI 3 ""))])] 1935 "TARGET_32BIT" 1936 "" 1937) 1938 1939(define_insn "*smulsi3_highpart_nov6" 1940 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1941 (truncate:SI 1942 (lshiftrt:DI 1943 (mult:DI 1944 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r")) 1945 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r"))) 1946 (const_int 32)))) 1947 (clobber (match_scratch:SI 3 "=&r,&r"))] 1948 "TARGET_32BIT && !arm_arch6" 1949 "smull%?\\t%3, %0, %2, %1" 1950 [(set_attr "type" "smull") 1951 (set_attr "predicable" "yes")] 1952) 1953 1954(define_insn "*smulsi3_highpart_v6" 1955 [(set (match_operand:SI 0 "s_register_operand" "=r") 1956 (truncate:SI 1957 (lshiftrt:DI 1958 (mult:DI 1959 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")) 1960 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))) 1961 (const_int 32)))) 1962 (clobber (match_scratch:SI 3 "=r"))] 1963 "TARGET_32BIT && arm_arch6" 1964 "smull%?\\t%3, %0, %2, %1" 1965 [(set_attr "type" "smull") 1966 (set_attr "predicable" "yes")] 1967) 1968 1969(define_expand "umulsi3_highpart" 1970 [(parallel 1971 [(set (match_operand:SI 0 "s_register_operand" "") 1972 (truncate:SI 1973 (lshiftrt:DI 1974 (mult:DI 1975 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1976 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))) 1977 (const_int 32)))) 1978 (clobber (match_scratch:SI 3 ""))])] 1979 "TARGET_32BIT" 1980 "" 1981) 1982 1983(define_insn "*umulsi3_highpart_nov6" 1984 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1985 (truncate:SI 1986 (lshiftrt:DI 1987 (mult:DI 1988 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r")) 1989 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r"))) 1990 (const_int 32)))) 1991 (clobber (match_scratch:SI 3 "=&r,&r"))] 1992 "TARGET_32BIT && !arm_arch6" 1993 "umull%?\\t%3, %0, %2, %1" 1994 [(set_attr "type" "umull") 1995 (set_attr "predicable" "yes")] 1996) 1997 1998(define_insn "*umulsi3_highpart_v6" 1999 [(set (match_operand:SI 0 "s_register_operand" "=r") 2000 (truncate:SI 2001 (lshiftrt:DI 2002 (mult:DI 2003 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")) 2004 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))) 2005 (const_int 32)))) 2006 (clobber (match_scratch:SI 3 "=r"))] 2007 "TARGET_32BIT && arm_arch6" 2008 "umull%?\\t%3, %0, %2, %1" 2009 [(set_attr "type" "umull") 2010 (set_attr "predicable" "yes")] 2011) 2012 2013(define_insn "mulhisi3" 2014 [(set (match_operand:SI 0 "s_register_operand" "=r") 2015 (mult:SI (sign_extend:SI 2016 (match_operand:HI 1 "s_register_operand" "%r")) 2017 (sign_extend:SI 2018 (match_operand:HI 2 "s_register_operand" "r"))))] 2019 "TARGET_DSP_MULTIPLY" 2020 "smulbb%?\\t%0, %1, %2" 2021 [(set_attr "type" "smulxy") 2022 (set_attr "predicable" "yes")] 2023) 2024 2025(define_insn "*mulhisi3tb" 2026 [(set (match_operand:SI 0 "s_register_operand" "=r") 2027 (mult:SI (ashiftrt:SI 2028 (match_operand:SI 1 "s_register_operand" "r") 2029 (const_int 16)) 2030 (sign_extend:SI 2031 (match_operand:HI 2 "s_register_operand" "r"))))] 2032 "TARGET_DSP_MULTIPLY" 2033 "smultb%?\\t%0, %1, %2" 2034 [(set_attr "type" "smulxy") 2035 (set_attr "predicable" "yes")] 2036) 2037 2038(define_insn "*mulhisi3bt" 2039 [(set (match_operand:SI 0 "s_register_operand" "=r") 2040 (mult:SI (sign_extend:SI 2041 (match_operand:HI 1 "s_register_operand" "r")) 2042 (ashiftrt:SI 2043 (match_operand:SI 2 "s_register_operand" "r") 2044 (const_int 16))))] 2045 "TARGET_DSP_MULTIPLY" 2046 "smulbt%?\\t%0, %1, %2" 2047 [(set_attr "type" "smulxy") 2048 (set_attr "predicable" "yes")] 2049) 2050 2051(define_insn "*mulhisi3tt" 2052 [(set (match_operand:SI 0 "s_register_operand" "=r") 2053 (mult:SI (ashiftrt:SI 2054 (match_operand:SI 1 "s_register_operand" "r") 2055 (const_int 16)) 2056 (ashiftrt:SI 2057 (match_operand:SI 2 "s_register_operand" "r") 2058 (const_int 16))))] 2059 "TARGET_DSP_MULTIPLY" 2060 "smultt%?\\t%0, %1, %2" 2061 [(set_attr "type" "smulxy") 2062 (set_attr "predicable" "yes")] 2063) 2064 2065(define_insn "maddhisi4" 2066 [(set (match_operand:SI 0 "s_register_operand" "=r") 2067 (plus:SI (mult:SI (sign_extend:SI 2068 (match_operand:HI 1 "s_register_operand" "r")) 2069 (sign_extend:SI 2070 (match_operand:HI 2 "s_register_operand" "r"))) 2071 (match_operand:SI 3 "s_register_operand" "r")))] 2072 "TARGET_DSP_MULTIPLY" 2073 "smlabb%?\\t%0, %1, %2, %3" 2074 [(set_attr "type" "smlaxy") 2075 (set_attr "predicable" "yes")] 2076) 2077 2078;; Note: there is no maddhisi4ibt because this one is canonical form 2079(define_insn "*maddhisi4tb" 2080 [(set (match_operand:SI 0 "s_register_operand" "=r") 2081 (plus:SI (mult:SI (ashiftrt:SI 2082 (match_operand:SI 1 "s_register_operand" "r") 2083 (const_int 16)) 2084 (sign_extend:SI 2085 (match_operand:HI 2 "s_register_operand" "r"))) 2086 (match_operand:SI 3 "s_register_operand" "r")))] 2087 "TARGET_DSP_MULTIPLY" 2088 "smlatb%?\\t%0, %1, %2, %3" 2089 [(set_attr "type" "smlaxy") 2090 (set_attr "predicable" "yes")] 2091) 2092 2093(define_insn "*maddhisi4tt" 2094 [(set (match_operand:SI 0 "s_register_operand" "=r") 2095 (plus:SI (mult:SI (ashiftrt:SI 2096 (match_operand:SI 1 "s_register_operand" "r") 2097 (const_int 16)) 2098 (ashiftrt:SI 2099 (match_operand:SI 2 "s_register_operand" "r") 2100 (const_int 16))) 2101 (match_operand:SI 3 "s_register_operand" "r")))] 2102 "TARGET_DSP_MULTIPLY" 2103 "smlatt%?\\t%0, %1, %2, %3" 2104 [(set_attr "type" "smlaxy") 2105 (set_attr "predicable" "yes")] 2106) 2107 2108(define_insn "maddhidi4" 2109 [(set (match_operand:DI 0 "s_register_operand" "=r") 2110 (plus:DI 2111 (mult:DI (sign_extend:DI 2112 (match_operand:HI 1 "s_register_operand" "r")) 2113 (sign_extend:DI 2114 (match_operand:HI 2 "s_register_operand" "r"))) 2115 (match_operand:DI 3 "s_register_operand" "0")))] 2116 "TARGET_DSP_MULTIPLY" 2117 "smlalbb%?\\t%Q0, %R0, %1, %2" 2118 [(set_attr "type" "smlalxy") 2119 (set_attr "predicable" "yes")]) 2120 2121;; Note: there is no maddhidi4ibt because this one is canonical form 2122(define_insn "*maddhidi4tb" 2123 [(set (match_operand:DI 0 "s_register_operand" "=r") 2124 (plus:DI 2125 (mult:DI (sign_extend:DI 2126 (ashiftrt:SI 2127 (match_operand:SI 1 "s_register_operand" "r") 2128 (const_int 16))) 2129 (sign_extend:DI 2130 (match_operand:HI 2 "s_register_operand" "r"))) 2131 (match_operand:DI 3 "s_register_operand" "0")))] 2132 "TARGET_DSP_MULTIPLY" 2133 "smlaltb%?\\t%Q0, %R0, %1, %2" 2134 [(set_attr "type" "smlalxy") 2135 (set_attr "predicable" "yes")]) 2136 2137(define_insn "*maddhidi4tt" 2138 [(set (match_operand:DI 0 "s_register_operand" "=r") 2139 (plus:DI 2140 (mult:DI (sign_extend:DI 2141 (ashiftrt:SI 2142 (match_operand:SI 1 "s_register_operand" "r") 2143 (const_int 16))) 2144 (sign_extend:DI 2145 (ashiftrt:SI 2146 (match_operand:SI 2 "s_register_operand" "r") 2147 (const_int 16)))) 2148 (match_operand:DI 3 "s_register_operand" "0")))] 2149 "TARGET_DSP_MULTIPLY" 2150 "smlaltt%?\\t%Q0, %R0, %1, %2" 2151 [(set_attr "type" "smlalxy") 2152 (set_attr "predicable" "yes")]) 2153 2154(define_expand "mulsf3" 2155 [(set (match_operand:SF 0 "s_register_operand" "") 2156 (mult:SF (match_operand:SF 1 "s_register_operand" "") 2157 (match_operand:SF 2 "s_register_operand" "")))] 2158 "TARGET_32BIT && TARGET_HARD_FLOAT" 2159 " 2160") 2161 2162(define_expand "muldf3" 2163 [(set (match_operand:DF 0 "s_register_operand" "") 2164 (mult:DF (match_operand:DF 1 "s_register_operand" "") 2165 (match_operand:DF 2 "s_register_operand" "")))] 2166 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 2167 " 2168") 2169 2170;; Division insns 2171 2172(define_expand "divsf3" 2173 [(set (match_operand:SF 0 "s_register_operand" "") 2174 (div:SF (match_operand:SF 1 "s_register_operand" "") 2175 (match_operand:SF 2 "s_register_operand" "")))] 2176 "TARGET_32BIT && TARGET_HARD_FLOAT" 2177 "") 2178 2179(define_expand "divdf3" 2180 [(set (match_operand:DF 0 "s_register_operand" "") 2181 (div:DF (match_operand:DF 1 "s_register_operand" "") 2182 (match_operand:DF 2 "s_register_operand" "")))] 2183 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 2184 "") 2185 2186;; Boolean and,ior,xor insns 2187 2188;; Split up double word logical operations 2189 2190;; Split up simple DImode logical operations. Simply perform the logical 2191;; operation on the upper and lower halves of the registers. 2192(define_split 2193 [(set (match_operand:DI 0 "s_register_operand" "") 2194 (match_operator:DI 6 "logical_binary_operator" 2195 [(match_operand:DI 1 "s_register_operand" "") 2196 (match_operand:DI 2 "s_register_operand" "")]))] 2197 "TARGET_32BIT && reload_completed 2198 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0]))) 2199 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))" 2200 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) 2201 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))] 2202 " 2203 { 2204 operands[3] = gen_highpart (SImode, operands[0]); 2205 operands[0] = gen_lowpart (SImode, operands[0]); 2206 operands[4] = gen_highpart (SImode, operands[1]); 2207 operands[1] = gen_lowpart (SImode, operands[1]); 2208 operands[5] = gen_highpart (SImode, operands[2]); 2209 operands[2] = gen_lowpart (SImode, operands[2]); 2210 }" 2211) 2212 2213(define_split 2214 [(set (match_operand:DI 0 "s_register_operand" "") 2215 (match_operator:DI 6 "logical_binary_operator" 2216 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" "")) 2217 (match_operand:DI 1 "s_register_operand" "")]))] 2218 "TARGET_32BIT && reload_completed" 2219 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) 2220 (set (match_dup 3) (match_op_dup:SI 6 2221 [(ashiftrt:SI (match_dup 2) (const_int 31)) 2222 (match_dup 4)]))] 2223 " 2224 { 2225 operands[3] = gen_highpart (SImode, operands[0]); 2226 operands[0] = gen_lowpart (SImode, operands[0]); 2227 operands[4] = gen_highpart (SImode, operands[1]); 2228 operands[1] = gen_lowpart (SImode, operands[1]); 2229 operands[5] = gen_highpart (SImode, operands[2]); 2230 operands[2] = gen_lowpart (SImode, operands[2]); 2231 }" 2232) 2233 2234;; The zero extend of operand 2 means we can just copy the high part of 2235;; operand1 into operand0. 2236(define_split 2237 [(set (match_operand:DI 0 "s_register_operand" "") 2238 (ior:DI 2239 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")) 2240 (match_operand:DI 1 "s_register_operand" "")))] 2241 "TARGET_32BIT && operands[0] != operands[1] && reload_completed" 2242 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2))) 2243 (set (match_dup 3) (match_dup 4))] 2244 " 2245 { 2246 operands[4] = gen_highpart (SImode, operands[1]); 2247 operands[3] = gen_highpart (SImode, operands[0]); 2248 operands[0] = gen_lowpart (SImode, operands[0]); 2249 operands[1] = gen_lowpart (SImode, operands[1]); 2250 }" 2251) 2252 2253;; The zero extend of operand 2 means we can just copy the high part of 2254;; operand1 into operand0. 2255(define_split 2256 [(set (match_operand:DI 0 "s_register_operand" "") 2257 (xor:DI 2258 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")) 2259 (match_operand:DI 1 "s_register_operand" "")))] 2260 "TARGET_32BIT && operands[0] != operands[1] && reload_completed" 2261 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2))) 2262 (set (match_dup 3) (match_dup 4))] 2263 " 2264 { 2265 operands[4] = gen_highpart (SImode, operands[1]); 2266 operands[3] = gen_highpart (SImode, operands[0]); 2267 operands[0] = gen_lowpart (SImode, operands[0]); 2268 operands[1] = gen_lowpart (SImode, operands[1]); 2269 }" 2270) 2271 2272(define_expand "anddi3" 2273 [(set (match_operand:DI 0 "s_register_operand" "") 2274 (and:DI (match_operand:DI 1 "s_register_operand" "") 2275 (match_operand:DI 2 "neon_inv_logic_op2" "")))] 2276 "TARGET_32BIT" 2277 " 2278 if (!TARGET_NEON && !TARGET_IWMMXT) 2279 { 2280 rtx low = simplify_gen_binary (AND, SImode, 2281 gen_lowpart (SImode, operands[1]), 2282 gen_lowpart (SImode, operands[2])); 2283 rtx high = simplify_gen_binary (AND, SImode, 2284 gen_highpart (SImode, operands[1]), 2285 gen_highpart_mode (SImode, DImode, 2286 operands[2])); 2287 2288 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); 2289 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); 2290 2291 DONE; 2292 } 2293 /* Otherwise expand pattern as above. */ 2294 " 2295) 2296 2297(define_insn_and_split "*anddi3_insn" 2298 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w") 2299 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0") 2300 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))] 2301 "TARGET_32BIT && !TARGET_IWMMXT" 2302{ 2303 switch (which_alternative) 2304 { 2305 case 0: /* fall through */ 2306 case 6: return "vand\t%P0, %P1, %P2"; 2307 case 1: /* fall through */ 2308 case 7: return neon_output_logic_immediate ("vand", &operands[2], 2309 DImode, 1, VALID_NEON_QREG_MODE (DImode)); 2310 case 2: 2311 case 3: 2312 case 4: 2313 case 5: /* fall through */ 2314 return "#"; 2315 default: gcc_unreachable (); 2316 } 2317} 2318 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed 2319 && !(IS_VFP_REGNUM (REGNO (operands[0])))" 2320 [(set (match_dup 3) (match_dup 4)) 2321 (set (match_dup 5) (match_dup 6))] 2322 " 2323 { 2324 operands[3] = gen_lowpart (SImode, operands[0]); 2325 operands[5] = gen_highpart (SImode, operands[0]); 2326 2327 operands[4] = simplify_gen_binary (AND, SImode, 2328 gen_lowpart (SImode, operands[1]), 2329 gen_lowpart (SImode, operands[2])); 2330 operands[6] = simplify_gen_binary (AND, SImode, 2331 gen_highpart (SImode, operands[1]), 2332 gen_highpart_mode (SImode, DImode, operands[2])); 2333 2334 }" 2335 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\ 2336 multiple,multiple,neon_logic,neon_logic") 2337 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*, 2338 avoid_neon_for_64bits,avoid_neon_for_64bits") 2339 (set_attr "length" "*,*,8,8,8,8,*,*") 2340 ] 2341) 2342 2343(define_insn_and_split "*anddi_zesidi_di" 2344 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2345 (and:DI (zero_extend:DI 2346 (match_operand:SI 2 "s_register_operand" "r,r")) 2347 (match_operand:DI 1 "s_register_operand" "0,r")))] 2348 "TARGET_32BIT" 2349 "#" 2350 "TARGET_32BIT && reload_completed" 2351 ; The zero extend of operand 2 clears the high word of the output 2352 ; operand. 2353 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2))) 2354 (set (match_dup 3) (const_int 0))] 2355 " 2356 { 2357 operands[3] = gen_highpart (SImode, operands[0]); 2358 operands[0] = gen_lowpart (SImode, operands[0]); 2359 operands[1] = gen_lowpart (SImode, operands[1]); 2360 }" 2361 [(set_attr "length" "8") 2362 (set_attr "type" "multiple")] 2363) 2364 2365(define_insn "*anddi_sesdi_di" 2366 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2367 (and:DI (sign_extend:DI 2368 (match_operand:SI 2 "s_register_operand" "r,r")) 2369 (match_operand:DI 1 "s_register_operand" "0,r")))] 2370 "TARGET_32BIT" 2371 "#" 2372 [(set_attr "length" "8") 2373 (set_attr "type" "multiple")] 2374) 2375 2376(define_expand "andsi3" 2377 [(set (match_operand:SI 0 "s_register_operand" "") 2378 (and:SI (match_operand:SI 1 "s_register_operand" "") 2379 (match_operand:SI 2 "reg_or_int_operand" "")))] 2380 "TARGET_EITHER" 2381 " 2382 if (TARGET_32BIT) 2383 { 2384 if (CONST_INT_P (operands[2])) 2385 { 2386 if (INTVAL (operands[2]) == 255 && arm_arch6) 2387 { 2388 operands[1] = convert_to_mode (QImode, operands[1], 1); 2389 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0], 2390 operands[1])); 2391 DONE; 2392 } 2393 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND)) 2394 operands[2] = force_reg (SImode, operands[2]); 2395 else 2396 { 2397 arm_split_constant (AND, SImode, NULL_RTX, 2398 INTVAL (operands[2]), operands[0], 2399 operands[1], 2400 optimize && can_create_pseudo_p ()); 2401 2402 DONE; 2403 } 2404 } 2405 } 2406 else /* TARGET_THUMB1 */ 2407 { 2408 if (!CONST_INT_P (operands[2])) 2409 { 2410 rtx tmp = force_reg (SImode, operands[2]); 2411 if (rtx_equal_p (operands[0], operands[1])) 2412 operands[2] = tmp; 2413 else 2414 { 2415 operands[2] = operands[1]; 2416 operands[1] = tmp; 2417 } 2418 } 2419 else 2420 { 2421 int i; 2422 2423 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256) 2424 { 2425 operands[2] = force_reg (SImode, 2426 GEN_INT (~INTVAL (operands[2]))); 2427 2428 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1])); 2429 2430 DONE; 2431 } 2432 2433 for (i = 9; i <= 31; i++) 2434 { 2435 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2])) 2436 { 2437 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i), 2438 const0_rtx)); 2439 DONE; 2440 } 2441 else if ((HOST_WIDE_INT_1 << i) - 1 2442 == ~INTVAL (operands[2])) 2443 { 2444 rtx shift = GEN_INT (i); 2445 rtx reg = gen_reg_rtx (SImode); 2446 2447 emit_insn (gen_lshrsi3 (reg, operands[1], shift)); 2448 emit_insn (gen_ashlsi3 (operands[0], reg, shift)); 2449 2450 DONE; 2451 } 2452 } 2453 2454 operands[2] = force_reg (SImode, operands[2]); 2455 } 2456 } 2457 " 2458) 2459 2460; ??? Check split length for Thumb-2 2461(define_insn_and_split "*arm_andsi3_insn" 2462 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r") 2463 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r") 2464 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))] 2465 "TARGET_32BIT" 2466 "@ 2467 and%?\\t%0, %1, %2 2468 and%?\\t%0, %1, %2 2469 bic%?\\t%0, %1, #%B2 2470 and%?\\t%0, %1, %2 2471 #" 2472 "TARGET_32BIT 2473 && CONST_INT_P (operands[2]) 2474 && !(const_ok_for_arm (INTVAL (operands[2])) 2475 || const_ok_for_arm (~INTVAL (operands[2])))" 2476 [(clobber (const_int 0))] 2477 " 2478 arm_split_constant (AND, SImode, curr_insn, 2479 INTVAL (operands[2]), operands[0], operands[1], 0); 2480 DONE; 2481 " 2482 [(set_attr "length" "4,4,4,4,16") 2483 (set_attr "predicable" "yes") 2484 (set_attr "predicable_short_it" "no,yes,no,no,no") 2485 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")] 2486) 2487 2488(define_insn "*andsi3_compare0" 2489 [(set (reg:CC_NOOV CC_REGNUM) 2490 (compare:CC_NOOV 2491 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 2492 (match_operand:SI 2 "arm_not_operand" "I,K,r")) 2493 (const_int 0))) 2494 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 2495 (and:SI (match_dup 1) (match_dup 2)))] 2496 "TARGET_32BIT" 2497 "@ 2498 ands%?\\t%0, %1, %2 2499 bics%?\\t%0, %1, #%B2 2500 ands%?\\t%0, %1, %2" 2501 [(set_attr "conds" "set") 2502 (set_attr "type" "logics_imm,logics_imm,logics_reg")] 2503) 2504 2505(define_insn "*andsi3_compare0_scratch" 2506 [(set (reg:CC_NOOV CC_REGNUM) 2507 (compare:CC_NOOV 2508 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r") 2509 (match_operand:SI 1 "arm_not_operand" "I,K,r")) 2510 (const_int 0))) 2511 (clobber (match_scratch:SI 2 "=X,r,X"))] 2512 "TARGET_32BIT" 2513 "@ 2514 tst%?\\t%0, %1 2515 bics%?\\t%2, %0, #%B1 2516 tst%?\\t%0, %1" 2517 [(set_attr "conds" "set") 2518 (set_attr "type" "logics_imm,logics_imm,logics_reg")] 2519) 2520 2521(define_insn "*zeroextractsi_compare0_scratch" 2522 [(set (reg:CC_NOOV CC_REGNUM) 2523 (compare:CC_NOOV (zero_extract:SI 2524 (match_operand:SI 0 "s_register_operand" "r") 2525 (match_operand 1 "const_int_operand" "n") 2526 (match_operand 2 "const_int_operand" "n")) 2527 (const_int 0)))] 2528 "TARGET_32BIT 2529 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32 2530 && INTVAL (operands[1]) > 0 2531 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8 2532 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)" 2533 "* 2534 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1) 2535 << INTVAL (operands[2])); 2536 output_asm_insn (\"tst%?\\t%0, %1\", operands); 2537 return \"\"; 2538 " 2539 [(set_attr "conds" "set") 2540 (set_attr "predicable" "yes") 2541 (set_attr "type" "logics_imm")] 2542) 2543 2544(define_insn_and_split "*ne_zeroextractsi" 2545 [(set (match_operand:SI 0 "s_register_operand" "=r") 2546 (ne:SI (zero_extract:SI 2547 (match_operand:SI 1 "s_register_operand" "r") 2548 (match_operand:SI 2 "const_int_operand" "n") 2549 (match_operand:SI 3 "const_int_operand" "n")) 2550 (const_int 0))) 2551 (clobber (reg:CC CC_REGNUM))] 2552 "TARGET_32BIT 2553 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 2554 && INTVAL (operands[2]) > 0 2555 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 2556 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)" 2557 "#" 2558 "TARGET_32BIT 2559 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 2560 && INTVAL (operands[2]) > 0 2561 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 2562 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)" 2563 [(parallel [(set (reg:CC_NOOV CC_REGNUM) 2564 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2)) 2565 (const_int 0))) 2566 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))]) 2567 (set (match_dup 0) 2568 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) 2569 (match_dup 0) (const_int 1)))] 2570 " 2571 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1) 2572 << INTVAL (operands[3])); 2573 " 2574 [(set_attr "conds" "clob") 2575 (set (attr "length") 2576 (if_then_else (eq_attr "is_thumb" "yes") 2577 (const_int 12) 2578 (const_int 8))) 2579 (set_attr "type" "multiple")] 2580) 2581 2582(define_insn_and_split "*ne_zeroextractsi_shifted" 2583 [(set (match_operand:SI 0 "s_register_operand" "=r") 2584 (ne:SI (zero_extract:SI 2585 (match_operand:SI 1 "s_register_operand" "r") 2586 (match_operand:SI 2 "const_int_operand" "n") 2587 (const_int 0)) 2588 (const_int 0))) 2589 (clobber (reg:CC CC_REGNUM))] 2590 "TARGET_ARM" 2591 "#" 2592 "TARGET_ARM" 2593 [(parallel [(set (reg:CC_NOOV CC_REGNUM) 2594 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2)) 2595 (const_int 0))) 2596 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))]) 2597 (set (match_dup 0) 2598 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) 2599 (match_dup 0) (const_int 1)))] 2600 " 2601 operands[2] = GEN_INT (32 - INTVAL (operands[2])); 2602 " 2603 [(set_attr "conds" "clob") 2604 (set_attr "length" "8") 2605 (set_attr "type" "multiple")] 2606) 2607 2608(define_insn_and_split "*ite_ne_zeroextractsi" 2609 [(set (match_operand:SI 0 "s_register_operand" "=r") 2610 (if_then_else:SI (ne (zero_extract:SI 2611 (match_operand:SI 1 "s_register_operand" "r") 2612 (match_operand:SI 2 "const_int_operand" "n") 2613 (match_operand:SI 3 "const_int_operand" "n")) 2614 (const_int 0)) 2615 (match_operand:SI 4 "arm_not_operand" "rIK") 2616 (const_int 0))) 2617 (clobber (reg:CC CC_REGNUM))] 2618 "TARGET_ARM 2619 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 2620 && INTVAL (operands[2]) > 0 2621 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 2622 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32) 2623 && !reg_overlap_mentioned_p (operands[0], operands[4])" 2624 "#" 2625 "TARGET_ARM 2626 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 2627 && INTVAL (operands[2]) > 0 2628 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 2629 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32) 2630 && !reg_overlap_mentioned_p (operands[0], operands[4])" 2631 [(parallel [(set (reg:CC_NOOV CC_REGNUM) 2632 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2)) 2633 (const_int 0))) 2634 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))]) 2635 (set (match_dup 0) 2636 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) 2637 (match_dup 0) (match_dup 4)))] 2638 " 2639 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1) 2640 << INTVAL (operands[3])); 2641 " 2642 [(set_attr "conds" "clob") 2643 (set_attr "length" "8") 2644 (set_attr "type" "multiple")] 2645) 2646 2647(define_insn_and_split "*ite_ne_zeroextractsi_shifted" 2648 [(set (match_operand:SI 0 "s_register_operand" "=r") 2649 (if_then_else:SI (ne (zero_extract:SI 2650 (match_operand:SI 1 "s_register_operand" "r") 2651 (match_operand:SI 2 "const_int_operand" "n") 2652 (const_int 0)) 2653 (const_int 0)) 2654 (match_operand:SI 3 "arm_not_operand" "rIK") 2655 (const_int 0))) 2656 (clobber (reg:CC CC_REGNUM))] 2657 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])" 2658 "#" 2659 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])" 2660 [(parallel [(set (reg:CC_NOOV CC_REGNUM) 2661 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2)) 2662 (const_int 0))) 2663 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))]) 2664 (set (match_dup 0) 2665 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) 2666 (match_dup 0) (match_dup 3)))] 2667 " 2668 operands[2] = GEN_INT (32 - INTVAL (operands[2])); 2669 " 2670 [(set_attr "conds" "clob") 2671 (set_attr "length" "8") 2672 (set_attr "type" "multiple")] 2673) 2674 2675;; ??? Use Thumb-2 has bitfield insert/extract instructions. 2676(define_split 2677 [(set (match_operand:SI 0 "s_register_operand" "") 2678 (match_operator:SI 1 "shiftable_operator" 2679 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "") 2680 (match_operand:SI 3 "const_int_operand" "") 2681 (match_operand:SI 4 "const_int_operand" "")) 2682 (match_operand:SI 5 "s_register_operand" "")])) 2683 (clobber (match_operand:SI 6 "s_register_operand" ""))] 2684 "TARGET_ARM" 2685 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3))) 2686 (set (match_dup 0) 2687 (match_op_dup 1 2688 [(lshiftrt:SI (match_dup 6) (match_dup 4)) 2689 (match_dup 5)]))] 2690 "{ 2691 HOST_WIDE_INT temp = INTVAL (operands[3]); 2692 2693 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4])); 2694 operands[4] = GEN_INT (32 - temp); 2695 }" 2696) 2697 2698(define_split 2699 [(set (match_operand:SI 0 "s_register_operand" "") 2700 (match_operator:SI 1 "shiftable_operator" 2701 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "") 2702 (match_operand:SI 3 "const_int_operand" "") 2703 (match_operand:SI 4 "const_int_operand" "")) 2704 (match_operand:SI 5 "s_register_operand" "")])) 2705 (clobber (match_operand:SI 6 "s_register_operand" ""))] 2706 "TARGET_ARM" 2707 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3))) 2708 (set (match_dup 0) 2709 (match_op_dup 1 2710 [(ashiftrt:SI (match_dup 6) (match_dup 4)) 2711 (match_dup 5)]))] 2712 "{ 2713 HOST_WIDE_INT temp = INTVAL (operands[3]); 2714 2715 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4])); 2716 operands[4] = GEN_INT (32 - temp); 2717 }" 2718) 2719 2720;;; ??? This pattern is bogus. If operand3 has bits outside the range 2721;;; represented by the bitfield, then this will produce incorrect results. 2722;;; Somewhere, the value needs to be truncated. On targets like the m68k, 2723;;; which have a real bit-field insert instruction, the truncation happens 2724;;; in the bit-field insert instruction itself. Since arm does not have a 2725;;; bit-field insert instruction, we would have to emit code here to truncate 2726;;; the value before we insert. This loses some of the advantage of having 2727;;; this insv pattern, so this pattern needs to be reevalutated. 2728 2729(define_expand "insv" 2730 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "") 2731 (match_operand 1 "general_operand" "") 2732 (match_operand 2 "general_operand" "")) 2733 (match_operand 3 "reg_or_int_operand" ""))] 2734 "TARGET_ARM || arm_arch_thumb2" 2735 " 2736 { 2737 int start_bit = INTVAL (operands[2]); 2738 int width = INTVAL (operands[1]); 2739 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1; 2740 rtx target, subtarget; 2741 2742 if (arm_arch_thumb2) 2743 { 2744 if (unaligned_access && MEM_P (operands[0]) 2745 && s_register_operand (operands[3], GET_MODE (operands[3])) 2746 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0) 2747 { 2748 rtx base_addr; 2749 2750 if (BYTES_BIG_ENDIAN) 2751 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width 2752 - start_bit; 2753 2754 if (width == 32) 2755 { 2756 base_addr = adjust_address (operands[0], SImode, 2757 start_bit / BITS_PER_UNIT); 2758 emit_insn (gen_unaligned_storesi (base_addr, operands[3])); 2759 } 2760 else 2761 { 2762 rtx tmp = gen_reg_rtx (HImode); 2763 2764 base_addr = adjust_address (operands[0], HImode, 2765 start_bit / BITS_PER_UNIT); 2766 emit_move_insn (tmp, gen_lowpart (HImode, operands[3])); 2767 emit_insn (gen_unaligned_storehi (base_addr, tmp)); 2768 } 2769 DONE; 2770 } 2771 else if (s_register_operand (operands[0], GET_MODE (operands[0]))) 2772 { 2773 bool use_bfi = TRUE; 2774 2775 if (CONST_INT_P (operands[3])) 2776 { 2777 HOST_WIDE_INT val = INTVAL (operands[3]) & mask; 2778 2779 if (val == 0) 2780 { 2781 emit_insn (gen_insv_zero (operands[0], operands[1], 2782 operands[2])); 2783 DONE; 2784 } 2785 2786 /* See if the set can be done with a single orr instruction. */ 2787 if (val == mask && const_ok_for_arm (val << start_bit)) 2788 use_bfi = FALSE; 2789 } 2790 2791 if (use_bfi) 2792 { 2793 if (!REG_P (operands[3])) 2794 operands[3] = force_reg (SImode, operands[3]); 2795 2796 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2], 2797 operands[3])); 2798 DONE; 2799 } 2800 } 2801 else 2802 FAIL; 2803 } 2804 2805 if (!s_register_operand (operands[0], GET_MODE (operands[0]))) 2806 FAIL; 2807 2808 target = copy_rtx (operands[0]); 2809 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 2810 subreg as the final target. */ 2811 if (GET_CODE (target) == SUBREG) 2812 { 2813 subtarget = gen_reg_rtx (SImode); 2814 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target))) 2815 < GET_MODE_SIZE (SImode)) 2816 target = SUBREG_REG (target); 2817 } 2818 else 2819 subtarget = target; 2820 2821 if (CONST_INT_P (operands[3])) 2822 { 2823 /* Since we are inserting a known constant, we may be able to 2824 reduce the number of bits that we have to clear so that 2825 the mask becomes simple. */ 2826 /* ??? This code does not check to see if the new mask is actually 2827 simpler. It may not be. */ 2828 rtx op1 = gen_reg_rtx (SImode); 2829 /* ??? Truncate operand3 to fit in the bitfield. See comment before 2830 start of this pattern. */ 2831 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]); 2832 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit); 2833 2834 emit_insn (gen_andsi3 (op1, operands[0], 2835 gen_int_mode (~mask2, SImode))); 2836 emit_insn (gen_iorsi3 (subtarget, op1, 2837 gen_int_mode (op3_value << start_bit, SImode))); 2838 } 2839 else if (start_bit == 0 2840 && !(const_ok_for_arm (mask) 2841 || const_ok_for_arm (~mask))) 2842 { 2843 /* A Trick, since we are setting the bottom bits in the word, 2844 we can shift operand[3] up, operand[0] down, OR them together 2845 and rotate the result back again. This takes 3 insns, and 2846 the third might be mergeable into another op. */ 2847 /* The shift up copes with the possibility that operand[3] is 2848 wider than the bitfield. */ 2849 rtx op0 = gen_reg_rtx (SImode); 2850 rtx op1 = gen_reg_rtx (SImode); 2851 2852 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width))); 2853 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1])); 2854 emit_insn (gen_iorsi3 (op1, op1, op0)); 2855 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1])); 2856 } 2857 else if ((width + start_bit == 32) 2858 && !(const_ok_for_arm (mask) 2859 || const_ok_for_arm (~mask))) 2860 { 2861 /* Similar trick, but slightly less efficient. */ 2862 2863 rtx op0 = gen_reg_rtx (SImode); 2864 rtx op1 = gen_reg_rtx (SImode); 2865 2866 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width))); 2867 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1])); 2868 emit_insn (gen_lshrsi3 (op1, op1, operands[1])); 2869 emit_insn (gen_iorsi3 (subtarget, op1, op0)); 2870 } 2871 else 2872 { 2873 rtx op0 = gen_int_mode (mask, SImode); 2874 rtx op1 = gen_reg_rtx (SImode); 2875 rtx op2 = gen_reg_rtx (SImode); 2876 2877 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask))) 2878 { 2879 rtx tmp = gen_reg_rtx (SImode); 2880 2881 emit_insn (gen_movsi (tmp, op0)); 2882 op0 = tmp; 2883 } 2884 2885 /* Mask out any bits in operand[3] that are not needed. */ 2886 emit_insn (gen_andsi3 (op1, operands[3], op0)); 2887 2888 if (CONST_INT_P (op0) 2889 && (const_ok_for_arm (mask << start_bit) 2890 || const_ok_for_arm (~(mask << start_bit)))) 2891 { 2892 op0 = gen_int_mode (~(mask << start_bit), SImode); 2893 emit_insn (gen_andsi3 (op2, operands[0], op0)); 2894 } 2895 else 2896 { 2897 if (CONST_INT_P (op0)) 2898 { 2899 rtx tmp = gen_reg_rtx (SImode); 2900 2901 emit_insn (gen_movsi (tmp, op0)); 2902 op0 = tmp; 2903 } 2904 2905 if (start_bit != 0) 2906 emit_insn (gen_ashlsi3 (op0, op0, operands[2])); 2907 2908 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0)); 2909 } 2910 2911 if (start_bit != 0) 2912 emit_insn (gen_ashlsi3 (op1, op1, operands[2])); 2913 2914 emit_insn (gen_iorsi3 (subtarget, op1, op2)); 2915 } 2916 2917 if (subtarget != target) 2918 { 2919 /* If TARGET is still a SUBREG, then it must be wider than a word, 2920 so we must be careful only to set the subword we were asked to. */ 2921 if (GET_CODE (target) == SUBREG) 2922 emit_move_insn (target, subtarget); 2923 else 2924 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget)); 2925 } 2926 2927 DONE; 2928 }" 2929) 2930 2931(define_insn "insv_zero" 2932 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") 2933 (match_operand:SI 1 "const_int_M_operand" "M") 2934 (match_operand:SI 2 "const_int_M_operand" "M")) 2935 (const_int 0))] 2936 "arm_arch_thumb2" 2937 "bfc%?\t%0, %2, %1" 2938 [(set_attr "length" "4") 2939 (set_attr "predicable" "yes") 2940 (set_attr "type" "bfm")] 2941) 2942 2943(define_insn "insv_t2" 2944 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") 2945 (match_operand:SI 1 "const_int_M_operand" "M") 2946 (match_operand:SI 2 "const_int_M_operand" "M")) 2947 (match_operand:SI 3 "s_register_operand" "r"))] 2948 "arm_arch_thumb2" 2949 "bfi%?\t%0, %3, %2, %1" 2950 [(set_attr "length" "4") 2951 (set_attr "predicable" "yes") 2952 (set_attr "type" "bfm")] 2953) 2954 2955; constants for op 2 will never be given to these patterns. 2956(define_insn_and_split "*anddi_notdi_di" 2957 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2958 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r")) 2959 (match_operand:DI 2 "s_register_operand" "r,0")))] 2960 "TARGET_32BIT" 2961 "#" 2962 "TARGET_32BIT && reload_completed 2963 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0]))) 2964 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))" 2965 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2))) 2966 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))] 2967 " 2968 { 2969 operands[3] = gen_highpart (SImode, operands[0]); 2970 operands[0] = gen_lowpart (SImode, operands[0]); 2971 operands[4] = gen_highpart (SImode, operands[1]); 2972 operands[1] = gen_lowpart (SImode, operands[1]); 2973 operands[5] = gen_highpart (SImode, operands[2]); 2974 operands[2] = gen_lowpart (SImode, operands[2]); 2975 }" 2976 [(set_attr "length" "8") 2977 (set_attr "predicable" "yes") 2978 (set_attr "type" "multiple")] 2979) 2980 2981(define_insn_and_split "*anddi_notzesidi_di" 2982 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2983 (and:DI (not:DI (zero_extend:DI 2984 (match_operand:SI 2 "s_register_operand" "r,r"))) 2985 (match_operand:DI 1 "s_register_operand" "0,?r")))] 2986 "TARGET_32BIT" 2987 "@ 2988 bic%?\\t%Q0, %Q1, %2 2989 #" 2990 ; (not (zero_extend ...)) allows us to just copy the high word from 2991 ; operand1 to operand0. 2992 "TARGET_32BIT 2993 && reload_completed 2994 && operands[0] != operands[1]" 2995 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1))) 2996 (set (match_dup 3) (match_dup 4))] 2997 " 2998 { 2999 operands[3] = gen_highpart (SImode, operands[0]); 3000 operands[0] = gen_lowpart (SImode, operands[0]); 3001 operands[4] = gen_highpart (SImode, operands[1]); 3002 operands[1] = gen_lowpart (SImode, operands[1]); 3003 }" 3004 [(set_attr "length" "4,8") 3005 (set_attr "predicable" "yes") 3006 (set_attr "type" "multiple")] 3007) 3008 3009(define_insn_and_split "*anddi_notdi_zesidi" 3010 [(set (match_operand:DI 0 "s_register_operand" "=r") 3011 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r")) 3012 (zero_extend:DI 3013 (match_operand:SI 1 "s_register_operand" "r"))))] 3014 "TARGET_32BIT" 3015 "#" 3016 "TARGET_32BIT && reload_completed" 3017 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1))) 3018 (set (match_dup 3) (const_int 0))] 3019 " 3020 { 3021 operands[3] = gen_highpart (SImode, operands[0]); 3022 operands[0] = gen_lowpart (SImode, operands[0]); 3023 operands[2] = gen_lowpart (SImode, operands[2]); 3024 }" 3025 [(set_attr "length" "8") 3026 (set_attr "predicable" "yes") 3027 (set_attr "type" "multiple")] 3028) 3029 3030(define_insn_and_split "*anddi_notsesidi_di" 3031 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 3032 (and:DI (not:DI (sign_extend:DI 3033 (match_operand:SI 2 "s_register_operand" "r,r"))) 3034 (match_operand:DI 1 "s_register_operand" "0,r")))] 3035 "TARGET_32BIT" 3036 "#" 3037 "TARGET_32BIT && reload_completed" 3038 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1))) 3039 (set (match_dup 3) (and:SI (not:SI 3040 (ashiftrt:SI (match_dup 2) (const_int 31))) 3041 (match_dup 4)))] 3042 " 3043 { 3044 operands[3] = gen_highpart (SImode, operands[0]); 3045 operands[0] = gen_lowpart (SImode, operands[0]); 3046 operands[4] = gen_highpart (SImode, operands[1]); 3047 operands[1] = gen_lowpart (SImode, operands[1]); 3048 }" 3049 [(set_attr "length" "8") 3050 (set_attr "predicable" "yes") 3051 (set_attr "type" "multiple")] 3052) 3053 3054(define_insn "andsi_notsi_si" 3055 [(set (match_operand:SI 0 "s_register_operand" "=r") 3056 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) 3057 (match_operand:SI 1 "s_register_operand" "r")))] 3058 "TARGET_32BIT" 3059 "bic%?\\t%0, %1, %2" 3060 [(set_attr "predicable" "yes") 3061 (set_attr "type" "logic_reg")] 3062) 3063 3064(define_insn "andsi_not_shiftsi_si" 3065 [(set (match_operand:SI 0 "s_register_operand" "=r") 3066 (and:SI (not:SI (match_operator:SI 4 "shift_operator" 3067 [(match_operand:SI 2 "s_register_operand" "r") 3068 (match_operand:SI 3 "arm_rhs_operand" "rM")])) 3069 (match_operand:SI 1 "s_register_operand" "r")))] 3070 "TARGET_ARM" 3071 "bic%?\\t%0, %1, %2%S4" 3072 [(set_attr "predicable" "yes") 3073 (set_attr "shift" "2") 3074 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") 3075 (const_string "logic_shift_imm") 3076 (const_string "logic_shift_reg")))] 3077) 3078 3079;; Shifted bics pattern used to set up CC status register and not reusing 3080;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2 3081;; does not support shift by register. 3082(define_insn "andsi_not_shiftsi_si_scc_no_reuse" 3083 [(set (reg:CC_NOOV CC_REGNUM) 3084 (compare:CC_NOOV 3085 (and:SI (not:SI (match_operator:SI 0 "shift_operator" 3086 [(match_operand:SI 1 "s_register_operand" "r") 3087 (match_operand:SI 2 "arm_rhs_operand" "rM")])) 3088 (match_operand:SI 3 "s_register_operand" "r")) 3089 (const_int 0))) 3090 (clobber (match_scratch:SI 4 "=r"))] 3091 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))" 3092 "bics%?\\t%4, %3, %1%S0" 3093 [(set_attr "predicable" "yes") 3094 (set_attr "conds" "set") 3095 (set_attr "shift" "1") 3096 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") 3097 (const_string "logic_shift_imm") 3098 (const_string "logic_shift_reg")))] 3099) 3100 3101;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also 3102;; getting reused later. 3103(define_insn "andsi_not_shiftsi_si_scc" 3104 [(parallel [(set (reg:CC_NOOV CC_REGNUM) 3105 (compare:CC_NOOV 3106 (and:SI (not:SI (match_operator:SI 0 "shift_operator" 3107 [(match_operand:SI 1 "s_register_operand" "r") 3108 (match_operand:SI 2 "arm_rhs_operand" "rM")])) 3109 (match_operand:SI 3 "s_register_operand" "r")) 3110 (const_int 0))) 3111 (set (match_operand:SI 4 "s_register_operand" "=r") 3112 (and:SI (not:SI (match_op_dup 0 3113 [(match_dup 1) 3114 (match_dup 2)])) 3115 (match_dup 3)))])] 3116 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))" 3117 "bics%?\\t%4, %3, %1%S0" 3118 [(set_attr "predicable" "yes") 3119 (set_attr "conds" "set") 3120 (set_attr "shift" "1") 3121 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") 3122 (const_string "logic_shift_imm") 3123 (const_string "logic_shift_reg")))] 3124) 3125 3126(define_insn "*andsi_notsi_si_compare0" 3127 [(set (reg:CC_NOOV CC_REGNUM) 3128 (compare:CC_NOOV 3129 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) 3130 (match_operand:SI 1 "s_register_operand" "r")) 3131 (const_int 0))) 3132 (set (match_operand:SI 0 "s_register_operand" "=r") 3133 (and:SI (not:SI (match_dup 2)) (match_dup 1)))] 3134 "TARGET_32BIT" 3135 "bics\\t%0, %1, %2" 3136 [(set_attr "conds" "set") 3137 (set_attr "type" "logics_shift_reg")] 3138) 3139 3140(define_insn "*andsi_notsi_si_compare0_scratch" 3141 [(set (reg:CC_NOOV CC_REGNUM) 3142 (compare:CC_NOOV 3143 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) 3144 (match_operand:SI 1 "s_register_operand" "r")) 3145 (const_int 0))) 3146 (clobber (match_scratch:SI 0 "=r"))] 3147 "TARGET_32BIT" 3148 "bics\\t%0, %1, %2" 3149 [(set_attr "conds" "set") 3150 (set_attr "type" "logics_shift_reg")] 3151) 3152 3153(define_expand "iordi3" 3154 [(set (match_operand:DI 0 "s_register_operand" "") 3155 (ior:DI (match_operand:DI 1 "s_register_operand" "") 3156 (match_operand:DI 2 "neon_logic_op2" "")))] 3157 "TARGET_32BIT" 3158 " 3159 if (!TARGET_NEON && !TARGET_IWMMXT) 3160 { 3161 rtx low = simplify_gen_binary (IOR, SImode, 3162 gen_lowpart (SImode, operands[1]), 3163 gen_lowpart (SImode, operands[2])); 3164 rtx high = simplify_gen_binary (IOR, SImode, 3165 gen_highpart (SImode, operands[1]), 3166 gen_highpart_mode (SImode, DImode, 3167 operands[2])); 3168 3169 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); 3170 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); 3171 3172 DONE; 3173 } 3174 /* Otherwise expand pattern as above. */ 3175 " 3176) 3177 3178(define_insn_and_split "*iordi3_insn" 3179 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w") 3180 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0") 3181 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))] 3182 "TARGET_32BIT && !TARGET_IWMMXT" 3183 { 3184 switch (which_alternative) 3185 { 3186 case 0: /* fall through */ 3187 case 6: return "vorr\t%P0, %P1, %P2"; 3188 case 1: /* fall through */ 3189 case 7: return neon_output_logic_immediate ("vorr", &operands[2], 3190 DImode, 0, VALID_NEON_QREG_MODE (DImode)); 3191 case 2: 3192 case 3: 3193 case 4: 3194 case 5: 3195 return "#"; 3196 default: gcc_unreachable (); 3197 } 3198 } 3199 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed 3200 && !(IS_VFP_REGNUM (REGNO (operands[0])))" 3201 [(set (match_dup 3) (match_dup 4)) 3202 (set (match_dup 5) (match_dup 6))] 3203 " 3204 { 3205 operands[3] = gen_lowpart (SImode, operands[0]); 3206 operands[5] = gen_highpart (SImode, operands[0]); 3207 3208 operands[4] = simplify_gen_binary (IOR, SImode, 3209 gen_lowpart (SImode, operands[1]), 3210 gen_lowpart (SImode, operands[2])); 3211 operands[6] = simplify_gen_binary (IOR, SImode, 3212 gen_highpart (SImode, operands[1]), 3213 gen_highpart_mode (SImode, DImode, operands[2])); 3214 3215 }" 3216 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\ 3217 multiple,neon_logic,neon_logic") 3218 (set_attr "length" "*,*,8,8,8,8,*,*") 3219 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")] 3220) 3221 3222(define_insn "*iordi_zesidi_di" 3223 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 3224 (ior:DI (zero_extend:DI 3225 (match_operand:SI 2 "s_register_operand" "r,r")) 3226 (match_operand:DI 1 "s_register_operand" "0,?r")))] 3227 "TARGET_32BIT" 3228 "@ 3229 orr%?\\t%Q0, %Q1, %2 3230 #" 3231 [(set_attr "length" "4,8") 3232 (set_attr "predicable" "yes") 3233 (set_attr "type" "logic_reg,multiple")] 3234) 3235 3236(define_insn "*iordi_sesidi_di" 3237 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 3238 (ior:DI (sign_extend:DI 3239 (match_operand:SI 2 "s_register_operand" "r,r")) 3240 (match_operand:DI 1 "s_register_operand" "0,r")))] 3241 "TARGET_32BIT" 3242 "#" 3243 [(set_attr "length" "8") 3244 (set_attr "predicable" "yes") 3245 (set_attr "type" "multiple")] 3246) 3247 3248(define_expand "iorsi3" 3249 [(set (match_operand:SI 0 "s_register_operand" "") 3250 (ior:SI (match_operand:SI 1 "s_register_operand" "") 3251 (match_operand:SI 2 "reg_or_int_operand" "")))] 3252 "TARGET_EITHER" 3253 " 3254 if (CONST_INT_P (operands[2])) 3255 { 3256 if (TARGET_32BIT) 3257 { 3258 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR)) 3259 operands[2] = force_reg (SImode, operands[2]); 3260 else 3261 { 3262 arm_split_constant (IOR, SImode, NULL_RTX, 3263 INTVAL (operands[2]), operands[0], 3264 operands[1], 3265 optimize && can_create_pseudo_p ()); 3266 DONE; 3267 } 3268 } 3269 else /* TARGET_THUMB1 */ 3270 { 3271 rtx tmp = force_reg (SImode, operands[2]); 3272 if (rtx_equal_p (operands[0], operands[1])) 3273 operands[2] = tmp; 3274 else 3275 { 3276 operands[2] = operands[1]; 3277 operands[1] = tmp; 3278 } 3279 } 3280 } 3281 " 3282) 3283 3284(define_insn_and_split "*iorsi3_insn" 3285 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r") 3286 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r") 3287 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))] 3288 "TARGET_32BIT" 3289 "@ 3290 orr%?\\t%0, %1, %2 3291 orr%?\\t%0, %1, %2 3292 orn%?\\t%0, %1, #%B2 3293 orr%?\\t%0, %1, %2 3294 #" 3295 "TARGET_32BIT 3296 && CONST_INT_P (operands[2]) 3297 && !(const_ok_for_arm (INTVAL (operands[2])) 3298 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))" 3299 [(clobber (const_int 0))] 3300{ 3301 arm_split_constant (IOR, SImode, curr_insn, 3302 INTVAL (operands[2]), operands[0], operands[1], 0); 3303 DONE; 3304} 3305 [(set_attr "length" "4,4,4,4,16") 3306 (set_attr "arch" "32,t2,t2,32,32") 3307 (set_attr "predicable" "yes") 3308 (set_attr "predicable_short_it" "no,yes,no,no,no") 3309 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")] 3310) 3311 3312(define_peephole2 3313 [(match_scratch:SI 3 "r") 3314 (set (match_operand:SI 0 "arm_general_register_operand" "") 3315 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "") 3316 (match_operand:SI 2 "const_int_operand" "")))] 3317 "TARGET_ARM 3318 && !const_ok_for_arm (INTVAL (operands[2])) 3319 && const_ok_for_arm (~INTVAL (operands[2]))" 3320 [(set (match_dup 3) (match_dup 2)) 3321 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))] 3322 "" 3323) 3324 3325(define_insn "*iorsi3_compare0" 3326 [(set (reg:CC_NOOV CC_REGNUM) 3327 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r") 3328 (match_operand:SI 2 "arm_rhs_operand" "I,r")) 3329 (const_int 0))) 3330 (set (match_operand:SI 0 "s_register_operand" "=r,r") 3331 (ior:SI (match_dup 1) (match_dup 2)))] 3332 "TARGET_32BIT" 3333 "orrs%?\\t%0, %1, %2" 3334 [(set_attr "conds" "set") 3335 (set_attr "type" "logics_imm,logics_reg")] 3336) 3337 3338(define_insn "*iorsi3_compare0_scratch" 3339 [(set (reg:CC_NOOV CC_REGNUM) 3340 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r") 3341 (match_operand:SI 2 "arm_rhs_operand" "I,r")) 3342 (const_int 0))) 3343 (clobber (match_scratch:SI 0 "=r,r"))] 3344 "TARGET_32BIT" 3345 "orrs%?\\t%0, %1, %2" 3346 [(set_attr "conds" "set") 3347 (set_attr "type" "logics_imm,logics_reg")] 3348) 3349 3350(define_expand "xordi3" 3351 [(set (match_operand:DI 0 "s_register_operand" "") 3352 (xor:DI (match_operand:DI 1 "s_register_operand" "") 3353 (match_operand:DI 2 "arm_xordi_operand" "")))] 3354 "TARGET_32BIT" 3355 { 3356 /* The iWMMXt pattern for xordi3 accepts only register operands but we want 3357 to reuse this expander for all TARGET_32BIT targets so just force the 3358 constants into a register. Unlike for the anddi3 and iordi3 there are 3359 no NEON instructions that take an immediate. */ 3360 if (TARGET_IWMMXT && !REG_P (operands[2])) 3361 operands[2] = force_reg (DImode, operands[2]); 3362 if (!TARGET_NEON && !TARGET_IWMMXT) 3363 { 3364 rtx low = simplify_gen_binary (XOR, SImode, 3365 gen_lowpart (SImode, operands[1]), 3366 gen_lowpart (SImode, operands[2])); 3367 rtx high = simplify_gen_binary (XOR, SImode, 3368 gen_highpart (SImode, operands[1]), 3369 gen_highpart_mode (SImode, DImode, 3370 operands[2])); 3371 3372 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); 3373 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); 3374 3375 DONE; 3376 } 3377 /* Otherwise expand pattern as above. */ 3378 } 3379) 3380 3381(define_insn_and_split "*xordi3_insn" 3382 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w") 3383 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w") 3384 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))] 3385 "TARGET_32BIT && !TARGET_IWMMXT" 3386{ 3387 switch (which_alternative) 3388 { 3389 case 1: 3390 case 2: 3391 case 3: 3392 case 4: /* fall through */ 3393 return "#"; 3394 case 0: /* fall through */ 3395 case 5: return "veor\t%P0, %P1, %P2"; 3396 default: gcc_unreachable (); 3397 } 3398} 3399 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed 3400 && !(IS_VFP_REGNUM (REGNO (operands[0])))" 3401 [(set (match_dup 3) (match_dup 4)) 3402 (set (match_dup 5) (match_dup 6))] 3403 " 3404 { 3405 operands[3] = gen_lowpart (SImode, operands[0]); 3406 operands[5] = gen_highpart (SImode, operands[0]); 3407 3408 operands[4] = simplify_gen_binary (XOR, SImode, 3409 gen_lowpart (SImode, operands[1]), 3410 gen_lowpart (SImode, operands[2])); 3411 operands[6] = simplify_gen_binary (XOR, SImode, 3412 gen_highpart (SImode, operands[1]), 3413 gen_highpart_mode (SImode, DImode, operands[2])); 3414 3415 }" 3416 [(set_attr "length" "*,8,8,8,8,*") 3417 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic") 3418 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")] 3419) 3420 3421(define_insn "*xordi_zesidi_di" 3422 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 3423 (xor:DI (zero_extend:DI 3424 (match_operand:SI 2 "s_register_operand" "r,r")) 3425 (match_operand:DI 1 "s_register_operand" "0,?r")))] 3426 "TARGET_32BIT" 3427 "@ 3428 eor%?\\t%Q0, %Q1, %2 3429 #" 3430 [(set_attr "length" "4,8") 3431 (set_attr "predicable" "yes") 3432 (set_attr "type" "logic_reg")] 3433) 3434 3435(define_insn "*xordi_sesidi_di" 3436 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 3437 (xor:DI (sign_extend:DI 3438 (match_operand:SI 2 "s_register_operand" "r,r")) 3439 (match_operand:DI 1 "s_register_operand" "0,r")))] 3440 "TARGET_32BIT" 3441 "#" 3442 [(set_attr "length" "8") 3443 (set_attr "predicable" "yes") 3444 (set_attr "type" "multiple")] 3445) 3446 3447(define_expand "xorsi3" 3448 [(set (match_operand:SI 0 "s_register_operand" "") 3449 (xor:SI (match_operand:SI 1 "s_register_operand" "") 3450 (match_operand:SI 2 "reg_or_int_operand" "")))] 3451 "TARGET_EITHER" 3452 "if (CONST_INT_P (operands[2])) 3453 { 3454 if (TARGET_32BIT) 3455 { 3456 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR)) 3457 operands[2] = force_reg (SImode, operands[2]); 3458 else 3459 { 3460 arm_split_constant (XOR, SImode, NULL_RTX, 3461 INTVAL (operands[2]), operands[0], 3462 operands[1], 3463 optimize && can_create_pseudo_p ()); 3464 DONE; 3465 } 3466 } 3467 else /* TARGET_THUMB1 */ 3468 { 3469 rtx tmp = force_reg (SImode, operands[2]); 3470 if (rtx_equal_p (operands[0], operands[1])) 3471 operands[2] = tmp; 3472 else 3473 { 3474 operands[2] = operands[1]; 3475 operands[1] = tmp; 3476 } 3477 } 3478 }" 3479) 3480 3481(define_insn_and_split "*arm_xorsi3" 3482 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r") 3483 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r") 3484 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))] 3485 "TARGET_32BIT" 3486 "@ 3487 eor%?\\t%0, %1, %2 3488 eor%?\\t%0, %1, %2 3489 eor%?\\t%0, %1, %2 3490 #" 3491 "TARGET_32BIT 3492 && CONST_INT_P (operands[2]) 3493 && !const_ok_for_arm (INTVAL (operands[2]))" 3494 [(clobber (const_int 0))] 3495{ 3496 arm_split_constant (XOR, SImode, curr_insn, 3497 INTVAL (operands[2]), operands[0], operands[1], 0); 3498 DONE; 3499} 3500 [(set_attr "length" "4,4,4,16") 3501 (set_attr "predicable" "yes") 3502 (set_attr "predicable_short_it" "no,yes,no,no") 3503 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")] 3504) 3505 3506(define_insn "*xorsi3_compare0" 3507 [(set (reg:CC_NOOV CC_REGNUM) 3508 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r") 3509 (match_operand:SI 2 "arm_rhs_operand" "I,r")) 3510 (const_int 0))) 3511 (set (match_operand:SI 0 "s_register_operand" "=r,r") 3512 (xor:SI (match_dup 1) (match_dup 2)))] 3513 "TARGET_32BIT" 3514 "eors%?\\t%0, %1, %2" 3515 [(set_attr "conds" "set") 3516 (set_attr "type" "logics_imm,logics_reg")] 3517) 3518 3519(define_insn "*xorsi3_compare0_scratch" 3520 [(set (reg:CC_NOOV CC_REGNUM) 3521 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r") 3522 (match_operand:SI 1 "arm_rhs_operand" "I,r")) 3523 (const_int 0)))] 3524 "TARGET_32BIT" 3525 "teq%?\\t%0, %1" 3526 [(set_attr "conds" "set") 3527 (set_attr "type" "logics_imm,logics_reg")] 3528) 3529 3530; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 3531; (NOT D) we can sometimes merge the final NOT into one of the following 3532; insns. 3533 3534(define_split 3535 [(set (match_operand:SI 0 "s_register_operand" "") 3536 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "")) 3537 (not:SI (match_operand:SI 2 "arm_rhs_operand" ""))) 3538 (match_operand:SI 3 "arm_rhs_operand" ""))) 3539 (clobber (match_operand:SI 4 "s_register_operand" ""))] 3540 "TARGET_32BIT" 3541 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2)) 3542 (not:SI (match_dup 3)))) 3543 (set (match_dup 0) (not:SI (match_dup 4)))] 3544 "" 3545) 3546 3547(define_insn_and_split "*andsi_iorsi3_notsi" 3548 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r") 3549 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r") 3550 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")) 3551 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))] 3552 "TARGET_32BIT" 3553 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3" 3554 "&& reload_completed" 3555 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2))) 3556 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))] 3557 { 3558 /* If operands[3] is a constant make sure to fold the NOT into it 3559 to avoid creating a NOT of a CONST_INT. */ 3560 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode); 3561 if (CONST_INT_P (not_rtx)) 3562 { 3563 operands[4] = operands[0]; 3564 operands[5] = not_rtx; 3565 } 3566 else 3567 { 3568 operands[5] = operands[0]; 3569 operands[4] = not_rtx; 3570 } 3571 } 3572 [(set_attr "length" "8") 3573 (set_attr "ce_count" "2") 3574 (set_attr "predicable" "yes") 3575 (set_attr "type" "multiple")] 3576) 3577 3578; ??? Are these four splitters still beneficial when the Thumb-2 bitfield 3579; insns are available? 3580(define_split 3581 [(set (match_operand:SI 0 "s_register_operand" "") 3582 (match_operator:SI 1 "logical_binary_operator" 3583 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "") 3584 (match_operand:SI 3 "const_int_operand" "") 3585 (match_operand:SI 4 "const_int_operand" "")) 3586 (match_operator:SI 9 "logical_binary_operator" 3587 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "") 3588 (match_operand:SI 6 "const_int_operand" "")) 3589 (match_operand:SI 7 "s_register_operand" "")])])) 3590 (clobber (match_operand:SI 8 "s_register_operand" ""))] 3591 "TARGET_32BIT 3592 && GET_CODE (operands[1]) == GET_CODE (operands[9]) 3593 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])" 3594 [(set (match_dup 8) 3595 (match_op_dup 1 3596 [(ashift:SI (match_dup 2) (match_dup 4)) 3597 (match_dup 5)])) 3598 (set (match_dup 0) 3599 (match_op_dup 1 3600 [(lshiftrt:SI (match_dup 8) (match_dup 6)) 3601 (match_dup 7)]))] 3602 " 3603 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4]))); 3604") 3605 3606(define_split 3607 [(set (match_operand:SI 0 "s_register_operand" "") 3608 (match_operator:SI 1 "logical_binary_operator" 3609 [(match_operator:SI 9 "logical_binary_operator" 3610 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "") 3611 (match_operand:SI 6 "const_int_operand" "")) 3612 (match_operand:SI 7 "s_register_operand" "")]) 3613 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "") 3614 (match_operand:SI 3 "const_int_operand" "") 3615 (match_operand:SI 4 "const_int_operand" ""))])) 3616 (clobber (match_operand:SI 8 "s_register_operand" ""))] 3617 "TARGET_32BIT 3618 && GET_CODE (operands[1]) == GET_CODE (operands[9]) 3619 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])" 3620 [(set (match_dup 8) 3621 (match_op_dup 1 3622 [(ashift:SI (match_dup 2) (match_dup 4)) 3623 (match_dup 5)])) 3624 (set (match_dup 0) 3625 (match_op_dup 1 3626 [(lshiftrt:SI (match_dup 8) (match_dup 6)) 3627 (match_dup 7)]))] 3628 " 3629 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4]))); 3630") 3631 3632(define_split 3633 [(set (match_operand:SI 0 "s_register_operand" "") 3634 (match_operator:SI 1 "logical_binary_operator" 3635 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "") 3636 (match_operand:SI 3 "const_int_operand" "") 3637 (match_operand:SI 4 "const_int_operand" "")) 3638 (match_operator:SI 9 "logical_binary_operator" 3639 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "") 3640 (match_operand:SI 6 "const_int_operand" "")) 3641 (match_operand:SI 7 "s_register_operand" "")])])) 3642 (clobber (match_operand:SI 8 "s_register_operand" ""))] 3643 "TARGET_32BIT 3644 && GET_CODE (operands[1]) == GET_CODE (operands[9]) 3645 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])" 3646 [(set (match_dup 8) 3647 (match_op_dup 1 3648 [(ashift:SI (match_dup 2) (match_dup 4)) 3649 (match_dup 5)])) 3650 (set (match_dup 0) 3651 (match_op_dup 1 3652 [(ashiftrt:SI (match_dup 8) (match_dup 6)) 3653 (match_dup 7)]))] 3654 " 3655 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4]))); 3656") 3657 3658(define_split 3659 [(set (match_operand:SI 0 "s_register_operand" "") 3660 (match_operator:SI 1 "logical_binary_operator" 3661 [(match_operator:SI 9 "logical_binary_operator" 3662 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "") 3663 (match_operand:SI 6 "const_int_operand" "")) 3664 (match_operand:SI 7 "s_register_operand" "")]) 3665 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "") 3666 (match_operand:SI 3 "const_int_operand" "") 3667 (match_operand:SI 4 "const_int_operand" ""))])) 3668 (clobber (match_operand:SI 8 "s_register_operand" ""))] 3669 "TARGET_32BIT 3670 && GET_CODE (operands[1]) == GET_CODE (operands[9]) 3671 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])" 3672 [(set (match_dup 8) 3673 (match_op_dup 1 3674 [(ashift:SI (match_dup 2) (match_dup 4)) 3675 (match_dup 5)])) 3676 (set (match_dup 0) 3677 (match_op_dup 1 3678 [(ashiftrt:SI (match_dup 8) (match_dup 6)) 3679 (match_dup 7)]))] 3680 " 3681 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4]))); 3682") 3683 3684 3685;; Minimum and maximum insns 3686 3687(define_expand "smaxsi3" 3688 [(parallel [ 3689 (set (match_operand:SI 0 "s_register_operand" "") 3690 (smax:SI (match_operand:SI 1 "s_register_operand" "") 3691 (match_operand:SI 2 "arm_rhs_operand" ""))) 3692 (clobber (reg:CC CC_REGNUM))])] 3693 "TARGET_32BIT" 3694 " 3695 if (operands[2] == const0_rtx || operands[2] == constm1_rtx) 3696 { 3697 /* No need for a clobber of the condition code register here. */ 3698 emit_insn (gen_rtx_SET (operands[0], 3699 gen_rtx_SMAX (SImode, operands[1], 3700 operands[2]))); 3701 DONE; 3702 } 3703") 3704 3705(define_insn "*smax_0" 3706 [(set (match_operand:SI 0 "s_register_operand" "=r") 3707 (smax:SI (match_operand:SI 1 "s_register_operand" "r") 3708 (const_int 0)))] 3709 "TARGET_32BIT" 3710 "bic%?\\t%0, %1, %1, asr #31" 3711 [(set_attr "predicable" "yes") 3712 (set_attr "type" "logic_shift_reg")] 3713) 3714 3715(define_insn "*smax_m1" 3716 [(set (match_operand:SI 0 "s_register_operand" "=r") 3717 (smax:SI (match_operand:SI 1 "s_register_operand" "r") 3718 (const_int -1)))] 3719 "TARGET_32BIT" 3720 "orr%?\\t%0, %1, %1, asr #31" 3721 [(set_attr "predicable" "yes") 3722 (set_attr "type" "logic_shift_reg")] 3723) 3724 3725(define_insn_and_split "*arm_smax_insn" 3726 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 3727 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r") 3728 (match_operand:SI 2 "arm_rhs_operand" "rI,rI"))) 3729 (clobber (reg:CC CC_REGNUM))] 3730 "TARGET_ARM" 3731 "#" 3732 ; cmp\\t%1, %2\;movlt\\t%0, %2 3733 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2" 3734 "TARGET_ARM" 3735 [(set (reg:CC CC_REGNUM) 3736 (compare:CC (match_dup 1) (match_dup 2))) 3737 (set (match_dup 0) 3738 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0)) 3739 (match_dup 1) 3740 (match_dup 2)))] 3741 "" 3742 [(set_attr "conds" "clob") 3743 (set_attr "length" "8,12") 3744 (set_attr "type" "multiple")] 3745) 3746 3747(define_expand "sminsi3" 3748 [(parallel [ 3749 (set (match_operand:SI 0 "s_register_operand" "") 3750 (smin:SI (match_operand:SI 1 "s_register_operand" "") 3751 (match_operand:SI 2 "arm_rhs_operand" ""))) 3752 (clobber (reg:CC CC_REGNUM))])] 3753 "TARGET_32BIT" 3754 " 3755 if (operands[2] == const0_rtx) 3756 { 3757 /* No need for a clobber of the condition code register here. */ 3758 emit_insn (gen_rtx_SET (operands[0], 3759 gen_rtx_SMIN (SImode, operands[1], 3760 operands[2]))); 3761 DONE; 3762 } 3763") 3764 3765(define_insn "*smin_0" 3766 [(set (match_operand:SI 0 "s_register_operand" "=r") 3767 (smin:SI (match_operand:SI 1 "s_register_operand" "r") 3768 (const_int 0)))] 3769 "TARGET_32BIT" 3770 "and%?\\t%0, %1, %1, asr #31" 3771 [(set_attr "predicable" "yes") 3772 (set_attr "type" "logic_shift_reg")] 3773) 3774 3775(define_insn_and_split "*arm_smin_insn" 3776 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 3777 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r") 3778 (match_operand:SI 2 "arm_rhs_operand" "rI,rI"))) 3779 (clobber (reg:CC CC_REGNUM))] 3780 "TARGET_ARM" 3781 "#" 3782 ; cmp\\t%1, %2\;movge\\t%0, %2 3783 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2" 3784 "TARGET_ARM" 3785 [(set (reg:CC CC_REGNUM) 3786 (compare:CC (match_dup 1) (match_dup 2))) 3787 (set (match_dup 0) 3788 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0)) 3789 (match_dup 1) 3790 (match_dup 2)))] 3791 "" 3792 [(set_attr "conds" "clob") 3793 (set_attr "length" "8,12") 3794 (set_attr "type" "multiple,multiple")] 3795) 3796 3797(define_expand "umaxsi3" 3798 [(parallel [ 3799 (set (match_operand:SI 0 "s_register_operand" "") 3800 (umax:SI (match_operand:SI 1 "s_register_operand" "") 3801 (match_operand:SI 2 "arm_rhs_operand" ""))) 3802 (clobber (reg:CC CC_REGNUM))])] 3803 "TARGET_32BIT" 3804 "" 3805) 3806 3807(define_insn_and_split "*arm_umaxsi3" 3808 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 3809 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") 3810 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 3811 (clobber (reg:CC CC_REGNUM))] 3812 "TARGET_ARM" 3813 "#" 3814 ; cmp\\t%1, %2\;movcc\\t%0, %2 3815 ; cmp\\t%1, %2\;movcs\\t%0, %1 3816 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2" 3817 "TARGET_ARM" 3818 [(set (reg:CC CC_REGNUM) 3819 (compare:CC (match_dup 1) (match_dup 2))) 3820 (set (match_dup 0) 3821 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0)) 3822 (match_dup 1) 3823 (match_dup 2)))] 3824 "" 3825 [(set_attr "conds" "clob") 3826 (set_attr "length" "8,8,12") 3827 (set_attr "type" "store_4")] 3828) 3829 3830(define_expand "uminsi3" 3831 [(parallel [ 3832 (set (match_operand:SI 0 "s_register_operand" "") 3833 (umin:SI (match_operand:SI 1 "s_register_operand" "") 3834 (match_operand:SI 2 "arm_rhs_operand" ""))) 3835 (clobber (reg:CC CC_REGNUM))])] 3836 "TARGET_32BIT" 3837 "" 3838) 3839 3840(define_insn_and_split "*arm_uminsi3" 3841 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 3842 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") 3843 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 3844 (clobber (reg:CC CC_REGNUM))] 3845 "TARGET_ARM" 3846 "#" 3847 ; cmp\\t%1, %2\;movcs\\t%0, %2 3848 ; cmp\\t%1, %2\;movcc\\t%0, %1 3849 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2" 3850 "TARGET_ARM" 3851 [(set (reg:CC CC_REGNUM) 3852 (compare:CC (match_dup 1) (match_dup 2))) 3853 (set (match_dup 0) 3854 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)) 3855 (match_dup 1) 3856 (match_dup 2)))] 3857 "" 3858 [(set_attr "conds" "clob") 3859 (set_attr "length" "8,8,12") 3860 (set_attr "type" "store_4")] 3861) 3862 3863(define_insn "*store_minmaxsi" 3864 [(set (match_operand:SI 0 "memory_operand" "=m") 3865 (match_operator:SI 3 "minmax_operator" 3866 [(match_operand:SI 1 "s_register_operand" "r") 3867 (match_operand:SI 2 "s_register_operand" "r")])) 3868 (clobber (reg:CC CC_REGNUM))] 3869 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it" 3870 "* 3871 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode, 3872 operands[1], operands[2]); 3873 output_asm_insn (\"cmp\\t%1, %2\", operands); 3874 if (TARGET_THUMB2) 3875 output_asm_insn (\"ite\t%d3\", operands); 3876 output_asm_insn (\"str%d3\\t%1, %0\", operands); 3877 output_asm_insn (\"str%D3\\t%2, %0\", operands); 3878 return \"\"; 3879 " 3880 [(set_attr "conds" "clob") 3881 (set (attr "length") 3882 (if_then_else (eq_attr "is_thumb" "yes") 3883 (const_int 14) 3884 (const_int 12))) 3885 (set_attr "type" "store_4")] 3886) 3887 3888; Reject the frame pointer in operand[1], since reloading this after 3889; it has been eliminated can cause carnage. 3890(define_insn "*minmax_arithsi" 3891 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 3892 (match_operator:SI 4 "shiftable_operator" 3893 [(match_operator:SI 5 "minmax_operator" 3894 [(match_operand:SI 2 "s_register_operand" "r,r") 3895 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 3896 (match_operand:SI 1 "s_register_operand" "0,?r")])) 3897 (clobber (reg:CC CC_REGNUM))] 3898 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it" 3899 "* 3900 { 3901 enum rtx_code code = GET_CODE (operands[4]); 3902 bool need_else; 3903 3904 if (which_alternative != 0 || operands[3] != const0_rtx 3905 || (code != PLUS && code != IOR && code != XOR)) 3906 need_else = true; 3907 else 3908 need_else = false; 3909 3910 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode, 3911 operands[2], operands[3]); 3912 output_asm_insn (\"cmp\\t%2, %3\", operands); 3913 if (TARGET_THUMB2) 3914 { 3915 if (need_else) 3916 output_asm_insn (\"ite\\t%d5\", operands); 3917 else 3918 output_asm_insn (\"it\\t%d5\", operands); 3919 } 3920 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands); 3921 if (need_else) 3922 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands); 3923 return \"\"; 3924 }" 3925 [(set_attr "conds" "clob") 3926 (set (attr "length") 3927 (if_then_else (eq_attr "is_thumb" "yes") 3928 (const_int 14) 3929 (const_int 12))) 3930 (set_attr "type" "multiple")] 3931) 3932 3933; Reject the frame pointer in operand[1], since reloading this after 3934; it has been eliminated can cause carnage. 3935(define_insn_and_split "*minmax_arithsi_non_canon" 3936 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 3937 (minus:SI 3938 (match_operand:SI 1 "s_register_operand" "0,?Ts") 3939 (match_operator:SI 4 "minmax_operator" 3940 [(match_operand:SI 2 "s_register_operand" "Ts,Ts") 3941 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")]))) 3942 (clobber (reg:CC CC_REGNUM))] 3943 "TARGET_32BIT && !arm_eliminable_register (operands[1]) 3944 && !(arm_restrict_it && CONST_INT_P (operands[3]))" 3945 "#" 3946 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed" 3947 [(set (reg:CC CC_REGNUM) 3948 (compare:CC (match_dup 2) (match_dup 3))) 3949 3950 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)]) 3951 (set (match_dup 0) 3952 (minus:SI (match_dup 1) 3953 (match_dup 2)))) 3954 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)]) 3955 (set (match_dup 0) 3956 (match_dup 6)))] 3957 { 3958 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 3959 operands[2], operands[3]); 3960 enum rtx_code rc = minmax_code (operands[4]); 3961 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, 3962 operands[2], operands[3]); 3963 3964 if (mode == CCFPmode || mode == CCFPEmode) 3965 rc = reverse_condition_maybe_unordered (rc); 3966 else 3967 rc = reverse_condition (rc); 3968 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]); 3969 if (CONST_INT_P (operands[3])) 3970 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3])); 3971 else 3972 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]); 3973 } 3974 [(set_attr "conds" "clob") 3975 (set (attr "length") 3976 (if_then_else (eq_attr "is_thumb" "yes") 3977 (const_int 14) 3978 (const_int 12))) 3979 (set_attr "type" "multiple")] 3980) 3981 3982(define_code_iterator SAT [smin smax]) 3983(define_code_iterator SATrev [smin smax]) 3984(define_code_attr SATlo [(smin "1") (smax "2")]) 3985(define_code_attr SAThi [(smin "2") (smax "1")]) 3986 3987(define_insn "*satsi_<SAT:code>" 3988 [(set (match_operand:SI 0 "s_register_operand" "=r") 3989 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r") 3990 (match_operand:SI 1 "const_int_operand" "i")) 3991 (match_operand:SI 2 "const_int_operand" "i")))] 3992 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE> 3993 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)" 3994{ 3995 int mask; 3996 bool signed_sat; 3997 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], 3998 &mask, &signed_sat)) 3999 gcc_unreachable (); 4000 4001 operands[1] = GEN_INT (mask); 4002 if (signed_sat) 4003 return "ssat%?\t%0, %1, %3"; 4004 else 4005 return "usat%?\t%0, %1, %3"; 4006} 4007 [(set_attr "predicable" "yes") 4008 (set_attr "type" "alus_imm")] 4009) 4010 4011(define_insn "*satsi_<SAT:code>_shift" 4012 [(set (match_operand:SI 0 "s_register_operand" "=r") 4013 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator" 4014 [(match_operand:SI 4 "s_register_operand" "r") 4015 (match_operand:SI 5 "const_int_operand" "i")]) 4016 (match_operand:SI 1 "const_int_operand" "i")) 4017 (match_operand:SI 2 "const_int_operand" "i")))] 4018 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE> 4019 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)" 4020{ 4021 int mask; 4022 bool signed_sat; 4023 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], 4024 &mask, &signed_sat)) 4025 gcc_unreachable (); 4026 4027 operands[1] = GEN_INT (mask); 4028 if (signed_sat) 4029 return "ssat%?\t%0, %1, %4%S3"; 4030 else 4031 return "usat%?\t%0, %1, %4%S3"; 4032} 4033 [(set_attr "predicable" "yes") 4034 (set_attr "shift" "3") 4035 (set_attr "type" "logic_shift_reg")]) 4036 4037;; Shift and rotation insns 4038 4039(define_expand "ashldi3" 4040 [(set (match_operand:DI 0 "s_register_operand" "") 4041 (ashift:DI (match_operand:DI 1 "s_register_operand" "") 4042 (match_operand:SI 2 "general_operand" "")))] 4043 "TARGET_32BIT" 4044 " 4045 if (TARGET_NEON) 4046 { 4047 /* Delay the decision whether to use NEON or core-regs until 4048 register allocation. */ 4049 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2])); 4050 DONE; 4051 } 4052 else 4053 { 4054 /* Only the NEON case can handle in-memory shift counts. */ 4055 if (!reg_or_int_operand (operands[2], SImode)) 4056 operands[2] = force_reg (SImode, operands[2]); 4057 } 4058 4059 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT) 4060 ; /* No special preparation statements; expand pattern as above. */ 4061 else 4062 { 4063 rtx scratch1, scratch2; 4064 4065 /* Ideally we should use iwmmxt here if we could know that operands[1] 4066 ends up already living in an iwmmxt register. Otherwise it's 4067 cheaper to have the alternate code being generated than moving 4068 values to iwmmxt regs and back. */ 4069 4070 /* Expand operation using core-registers. 4071 'FAIL' would achieve the same thing, but this is a bit smarter. */ 4072 scratch1 = gen_reg_rtx (SImode); 4073 scratch2 = gen_reg_rtx (SImode); 4074 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1], 4075 operands[2], scratch1, scratch2); 4076 DONE; 4077 } 4078 " 4079) 4080 4081(define_expand "ashlsi3" 4082 [(set (match_operand:SI 0 "s_register_operand" "") 4083 (ashift:SI (match_operand:SI 1 "s_register_operand" "") 4084 (match_operand:SI 2 "arm_rhs_operand" "")))] 4085 "TARGET_EITHER" 4086 " 4087 if (CONST_INT_P (operands[2]) 4088 && (UINTVAL (operands[2])) > 31) 4089 { 4090 emit_insn (gen_movsi (operands[0], const0_rtx)); 4091 DONE; 4092 } 4093 " 4094) 4095 4096(define_expand "ashrdi3" 4097 [(set (match_operand:DI 0 "s_register_operand" "") 4098 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "") 4099 (match_operand:SI 2 "reg_or_int_operand" "")))] 4100 "TARGET_32BIT" 4101 " 4102 if (TARGET_NEON) 4103 { 4104 /* Delay the decision whether to use NEON or core-regs until 4105 register allocation. */ 4106 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2])); 4107 DONE; 4108 } 4109 4110 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT) 4111 ; /* No special preparation statements; expand pattern as above. */ 4112 else 4113 { 4114 rtx scratch1, scratch2; 4115 4116 /* Ideally we should use iwmmxt here if we could know that operands[1] 4117 ends up already living in an iwmmxt register. Otherwise it's 4118 cheaper to have the alternate code being generated than moving 4119 values to iwmmxt regs and back. */ 4120 4121 /* Expand operation using core-registers. 4122 'FAIL' would achieve the same thing, but this is a bit smarter. */ 4123 scratch1 = gen_reg_rtx (SImode); 4124 scratch2 = gen_reg_rtx (SImode); 4125 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1], 4126 operands[2], scratch1, scratch2); 4127 DONE; 4128 } 4129 " 4130) 4131 4132(define_expand "ashrsi3" 4133 [(set (match_operand:SI 0 "s_register_operand" "") 4134 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "") 4135 (match_operand:SI 2 "arm_rhs_operand" "")))] 4136 "TARGET_EITHER" 4137 " 4138 if (CONST_INT_P (operands[2]) 4139 && UINTVAL (operands[2]) > 31) 4140 operands[2] = GEN_INT (31); 4141 " 4142) 4143 4144(define_expand "lshrdi3" 4145 [(set (match_operand:DI 0 "s_register_operand" "") 4146 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "") 4147 (match_operand:SI 2 "reg_or_int_operand" "")))] 4148 "TARGET_32BIT" 4149 " 4150 if (TARGET_NEON) 4151 { 4152 /* Delay the decision whether to use NEON or core-regs until 4153 register allocation. */ 4154 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2])); 4155 DONE; 4156 } 4157 4158 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT) 4159 ; /* No special preparation statements; expand pattern as above. */ 4160 else 4161 { 4162 rtx scratch1, scratch2; 4163 4164 /* Ideally we should use iwmmxt here if we could know that operands[1] 4165 ends up already living in an iwmmxt register. Otherwise it's 4166 cheaper to have the alternate code being generated than moving 4167 values to iwmmxt regs and back. */ 4168 4169 /* Expand operation using core-registers. 4170 'FAIL' would achieve the same thing, but this is a bit smarter. */ 4171 scratch1 = gen_reg_rtx (SImode); 4172 scratch2 = gen_reg_rtx (SImode); 4173 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1], 4174 operands[2], scratch1, scratch2); 4175 DONE; 4176 } 4177 " 4178) 4179 4180(define_expand "lshrsi3" 4181 [(set (match_operand:SI 0 "s_register_operand" "") 4182 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "") 4183 (match_operand:SI 2 "arm_rhs_operand" "")))] 4184 "TARGET_EITHER" 4185 " 4186 if (CONST_INT_P (operands[2]) 4187 && (UINTVAL (operands[2])) > 31) 4188 { 4189 emit_insn (gen_movsi (operands[0], const0_rtx)); 4190 DONE; 4191 } 4192 " 4193) 4194 4195(define_expand "rotlsi3" 4196 [(set (match_operand:SI 0 "s_register_operand" "") 4197 (rotatert:SI (match_operand:SI 1 "s_register_operand" "") 4198 (match_operand:SI 2 "reg_or_int_operand" "")))] 4199 "TARGET_32BIT" 4200 " 4201 if (CONST_INT_P (operands[2])) 4202 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32); 4203 else 4204 { 4205 rtx reg = gen_reg_rtx (SImode); 4206 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2])); 4207 operands[2] = reg; 4208 } 4209 " 4210) 4211 4212(define_expand "rotrsi3" 4213 [(set (match_operand:SI 0 "s_register_operand" "") 4214 (rotatert:SI (match_operand:SI 1 "s_register_operand" "") 4215 (match_operand:SI 2 "arm_rhs_operand" "")))] 4216 "TARGET_EITHER" 4217 " 4218 if (TARGET_32BIT) 4219 { 4220 if (CONST_INT_P (operands[2]) 4221 && UINTVAL (operands[2]) > 31) 4222 operands[2] = GEN_INT (INTVAL (operands[2]) % 32); 4223 } 4224 else /* TARGET_THUMB1 */ 4225 { 4226 if (CONST_INT_P (operands [2])) 4227 operands [2] = force_reg (SImode, operands[2]); 4228 } 4229 " 4230) 4231 4232(define_insn "*arm_shiftsi3" 4233 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r") 4234 (match_operator:SI 3 "shift_operator" 4235 [(match_operand:SI 1 "s_register_operand" "0,l,r,r") 4236 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))] 4237 "TARGET_32BIT" 4238 "* return arm_output_shift(operands, 0);" 4239 [(set_attr "predicable" "yes") 4240 (set_attr "arch" "t2,t2,*,*") 4241 (set_attr "predicable_short_it" "yes,yes,no,no") 4242 (set_attr "length" "4") 4243 (set_attr "shift" "1") 4244 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")] 4245) 4246 4247(define_insn "*shiftsi3_compare0" 4248 [(set (reg:CC_NOOV CC_REGNUM) 4249 (compare:CC_NOOV (match_operator:SI 3 "shift_operator" 4250 [(match_operand:SI 1 "s_register_operand" "r,r") 4251 (match_operand:SI 2 "arm_rhs_operand" "M,r")]) 4252 (const_int 0))) 4253 (set (match_operand:SI 0 "s_register_operand" "=r,r") 4254 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))] 4255 "TARGET_32BIT" 4256 "* return arm_output_shift(operands, 1);" 4257 [(set_attr "conds" "set") 4258 (set_attr "shift" "1") 4259 (set_attr "type" "alus_shift_imm,alus_shift_reg")] 4260) 4261 4262(define_insn "*shiftsi3_compare0_scratch" 4263 [(set (reg:CC_NOOV CC_REGNUM) 4264 (compare:CC_NOOV (match_operator:SI 3 "shift_operator" 4265 [(match_operand:SI 1 "s_register_operand" "r,r") 4266 (match_operand:SI 2 "arm_rhs_operand" "M,r")]) 4267 (const_int 0))) 4268 (clobber (match_scratch:SI 0 "=r,r"))] 4269 "TARGET_32BIT" 4270 "* return arm_output_shift(operands, 1);" 4271 [(set_attr "conds" "set") 4272 (set_attr "shift" "1") 4273 (set_attr "type" "shift_imm,shift_reg")] 4274) 4275 4276(define_insn "*not_shiftsi" 4277 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 4278 (not:SI (match_operator:SI 3 "shift_operator" 4279 [(match_operand:SI 1 "s_register_operand" "r,r") 4280 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))] 4281 "TARGET_32BIT" 4282 "mvn%?\\t%0, %1%S3" 4283 [(set_attr "predicable" "yes") 4284 (set_attr "shift" "1") 4285 (set_attr "arch" "32,a") 4286 (set_attr "type" "mvn_shift,mvn_shift_reg")]) 4287 4288(define_insn "*not_shiftsi_compare0" 4289 [(set (reg:CC_NOOV CC_REGNUM) 4290 (compare:CC_NOOV 4291 (not:SI (match_operator:SI 3 "shift_operator" 4292 [(match_operand:SI 1 "s_register_operand" "r,r") 4293 (match_operand:SI 2 "shift_amount_operand" "M,rM")])) 4294 (const_int 0))) 4295 (set (match_operand:SI 0 "s_register_operand" "=r,r") 4296 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))] 4297 "TARGET_32BIT" 4298 "mvns%?\\t%0, %1%S3" 4299 [(set_attr "conds" "set") 4300 (set_attr "shift" "1") 4301 (set_attr "arch" "32,a") 4302 (set_attr "type" "mvn_shift,mvn_shift_reg")]) 4303 4304(define_insn "*not_shiftsi_compare0_scratch" 4305 [(set (reg:CC_NOOV CC_REGNUM) 4306 (compare:CC_NOOV 4307 (not:SI (match_operator:SI 3 "shift_operator" 4308 [(match_operand:SI 1 "s_register_operand" "r,r") 4309 (match_operand:SI 2 "shift_amount_operand" "M,rM")])) 4310 (const_int 0))) 4311 (clobber (match_scratch:SI 0 "=r,r"))] 4312 "TARGET_32BIT" 4313 "mvns%?\\t%0, %1%S3" 4314 [(set_attr "conds" "set") 4315 (set_attr "shift" "1") 4316 (set_attr "arch" "32,a") 4317 (set_attr "type" "mvn_shift,mvn_shift_reg")]) 4318 4319;; We don't really have extzv, but defining this using shifts helps 4320;; to reduce register pressure later on. 4321 4322(define_expand "extzv" 4323 [(set (match_operand 0 "s_register_operand" "") 4324 (zero_extract (match_operand 1 "nonimmediate_operand" "") 4325 (match_operand 2 "const_int_operand" "") 4326 (match_operand 3 "const_int_operand" "")))] 4327 "TARGET_THUMB1 || arm_arch_thumb2" 4328 " 4329 { 4330 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]); 4331 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]); 4332 4333 if (arm_arch_thumb2) 4334 { 4335 HOST_WIDE_INT width = INTVAL (operands[2]); 4336 HOST_WIDE_INT bitpos = INTVAL (operands[3]); 4337 4338 if (unaligned_access && MEM_P (operands[1]) 4339 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0) 4340 { 4341 rtx base_addr; 4342 4343 if (BYTES_BIG_ENDIAN) 4344 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width 4345 - bitpos; 4346 4347 if (width == 32) 4348 { 4349 base_addr = adjust_address (operands[1], SImode, 4350 bitpos / BITS_PER_UNIT); 4351 emit_insn (gen_unaligned_loadsi (operands[0], base_addr)); 4352 } 4353 else 4354 { 4355 rtx dest = operands[0]; 4356 rtx tmp = gen_reg_rtx (SImode); 4357 4358 /* We may get a paradoxical subreg here. Strip it off. */ 4359 if (GET_CODE (dest) == SUBREG 4360 && GET_MODE (dest) == SImode 4361 && GET_MODE (SUBREG_REG (dest)) == HImode) 4362 dest = SUBREG_REG (dest); 4363 4364 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width) 4365 FAIL; 4366 4367 base_addr = adjust_address (operands[1], HImode, 4368 bitpos / BITS_PER_UNIT); 4369 emit_insn (gen_unaligned_loadhiu (tmp, base_addr)); 4370 emit_move_insn (gen_lowpart (SImode, dest), tmp); 4371 } 4372 DONE; 4373 } 4374 else if (s_register_operand (operands[1], GET_MODE (operands[1]))) 4375 { 4376 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2], 4377 operands[3])); 4378 DONE; 4379 } 4380 else 4381 FAIL; 4382 } 4383 4384 if (!s_register_operand (operands[1], GET_MODE (operands[1]))) 4385 FAIL; 4386 4387 operands[3] = GEN_INT (rshift); 4388 4389 if (lshift == 0) 4390 { 4391 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3])); 4392 DONE; 4393 } 4394 4395 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift), 4396 operands[3], gen_reg_rtx (SImode))); 4397 DONE; 4398 }" 4399) 4400 4401;; Helper for extzv, for the Thumb-1 register-shifts case. 4402 4403(define_expand "extzv_t1" 4404 [(set (match_operand:SI 4 "s_register_operand" "") 4405 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 4406 (match_operand:SI 2 "const_int_operand" ""))) 4407 (set (match_operand:SI 0 "s_register_operand" "") 4408 (lshiftrt:SI (match_dup 4) 4409 (match_operand:SI 3 "const_int_operand" "")))] 4410 "TARGET_THUMB1" 4411 "") 4412 4413(define_expand "extv" 4414 [(set (match_operand 0 "s_register_operand" "") 4415 (sign_extract (match_operand 1 "nonimmediate_operand" "") 4416 (match_operand 2 "const_int_operand" "") 4417 (match_operand 3 "const_int_operand" "")))] 4418 "arm_arch_thumb2" 4419{ 4420 HOST_WIDE_INT width = INTVAL (operands[2]); 4421 HOST_WIDE_INT bitpos = INTVAL (operands[3]); 4422 4423 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32) 4424 && (bitpos % BITS_PER_UNIT) == 0) 4425 { 4426 rtx base_addr; 4427 4428 if (BYTES_BIG_ENDIAN) 4429 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos; 4430 4431 if (width == 32) 4432 { 4433 base_addr = adjust_address (operands[1], SImode, 4434 bitpos / BITS_PER_UNIT); 4435 emit_insn (gen_unaligned_loadsi (operands[0], base_addr)); 4436 } 4437 else 4438 { 4439 rtx dest = operands[0]; 4440 rtx tmp = gen_reg_rtx (SImode); 4441 4442 /* We may get a paradoxical subreg here. Strip it off. */ 4443 if (GET_CODE (dest) == SUBREG 4444 && GET_MODE (dest) == SImode 4445 && GET_MODE (SUBREG_REG (dest)) == HImode) 4446 dest = SUBREG_REG (dest); 4447 4448 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width) 4449 FAIL; 4450 4451 base_addr = adjust_address (operands[1], HImode, 4452 bitpos / BITS_PER_UNIT); 4453 emit_insn (gen_unaligned_loadhis (tmp, base_addr)); 4454 emit_move_insn (gen_lowpart (SImode, dest), tmp); 4455 } 4456 4457 DONE; 4458 } 4459 else if (!s_register_operand (operands[1], GET_MODE (operands[1]))) 4460 FAIL; 4461 else if (GET_MODE (operands[0]) == SImode 4462 && GET_MODE (operands[1]) == SImode) 4463 { 4464 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2], 4465 operands[3])); 4466 DONE; 4467 } 4468 4469 FAIL; 4470}) 4471 4472; Helper to expand register forms of extv with the proper modes. 4473 4474(define_expand "extv_regsi" 4475 [(set (match_operand:SI 0 "s_register_operand" "") 4476 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "") 4477 (match_operand 2 "const_int_operand" "") 4478 (match_operand 3 "const_int_operand" "")))] 4479 "" 4480{ 4481}) 4482 4483; ARMv6+ unaligned load/store instructions (used for packed structure accesses). 4484 4485(define_insn "unaligned_loadsi" 4486 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 4487 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")] 4488 UNSPEC_UNALIGNED_LOAD))] 4489 "unaligned_access" 4490 "ldr%?\t%0, %1\t@ unaligned" 4491 [(set_attr "arch" "t2,any") 4492 (set_attr "length" "2,4") 4493 (set_attr "predicable" "yes") 4494 (set_attr "predicable_short_it" "yes,no") 4495 (set_attr "type" "load_4")]) 4496 4497(define_insn "unaligned_loadhis" 4498 [(set (match_operand:SI 0 "s_register_operand" "=r") 4499 (sign_extend:SI 4500 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")] 4501 UNSPEC_UNALIGNED_LOAD)))] 4502 "unaligned_access" 4503 "ldrsh%?\t%0, %1\t@ unaligned" 4504 [(set_attr "predicable" "yes") 4505 (set_attr "type" "load_byte")]) 4506 4507(define_insn "unaligned_loadhiu" 4508 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 4509 (zero_extend:SI 4510 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")] 4511 UNSPEC_UNALIGNED_LOAD)))] 4512 "unaligned_access" 4513 "ldrh%?\t%0, %1\t@ unaligned" 4514 [(set_attr "arch" "t2,any") 4515 (set_attr "length" "2,4") 4516 (set_attr "predicable" "yes") 4517 (set_attr "predicable_short_it" "yes,no") 4518 (set_attr "type" "load_byte")]) 4519 4520(define_insn "unaligned_storesi" 4521 [(set (match_operand:SI 0 "memory_operand" "=Uw,m") 4522 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")] 4523 UNSPEC_UNALIGNED_STORE))] 4524 "unaligned_access" 4525 "str%?\t%1, %0\t@ unaligned" 4526 [(set_attr "arch" "t2,any") 4527 (set_attr "length" "2,4") 4528 (set_attr "predicable" "yes") 4529 (set_attr "predicable_short_it" "yes,no") 4530 (set_attr "type" "store_4")]) 4531 4532(define_insn "unaligned_storehi" 4533 [(set (match_operand:HI 0 "memory_operand" "=Uw,m") 4534 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")] 4535 UNSPEC_UNALIGNED_STORE))] 4536 "unaligned_access" 4537 "strh%?\t%1, %0\t@ unaligned" 4538 [(set_attr "arch" "t2,any") 4539 (set_attr "length" "2,4") 4540 (set_attr "predicable" "yes") 4541 (set_attr "predicable_short_it" "yes,no") 4542 (set_attr "type" "store_4")]) 4543 4544 4545(define_insn "*extv_reg" 4546 [(set (match_operand:SI 0 "s_register_operand" "=r") 4547 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 4548 (match_operand:SI 2 "const_int_operand" "n") 4549 (match_operand:SI 3 "const_int_operand" "n")))] 4550 "arm_arch_thumb2 4551 && IN_RANGE (INTVAL (operands[3]), 0, 31) 4552 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))" 4553 "sbfx%?\t%0, %1, %3, %2" 4554 [(set_attr "length" "4") 4555 (set_attr "predicable" "yes") 4556 (set_attr "type" "bfm")] 4557) 4558 4559(define_insn "extzv_t2" 4560 [(set (match_operand:SI 0 "s_register_operand" "=r") 4561 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") 4562 (match_operand:SI 2 "const_int_operand" "n") 4563 (match_operand:SI 3 "const_int_operand" "n")))] 4564 "arm_arch_thumb2 4565 && IN_RANGE (INTVAL (operands[3]), 0, 31) 4566 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))" 4567 "ubfx%?\t%0, %1, %3, %2" 4568 [(set_attr "length" "4") 4569 (set_attr "predicable" "yes") 4570 (set_attr "type" "bfm")] 4571) 4572 4573 4574;; Division instructions 4575(define_insn "divsi3" 4576 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 4577 (div:SI (match_operand:SI 1 "s_register_operand" "r,r") 4578 (match_operand:SI 2 "s_register_operand" "r,r")))] 4579 "TARGET_IDIV" 4580 "@ 4581 sdiv%?\t%0, %1, %2 4582 sdiv\t%0, %1, %2" 4583 [(set_attr "arch" "32,v8mb") 4584 (set_attr "predicable" "yes") 4585 (set_attr "type" "sdiv")] 4586) 4587 4588(define_insn "udivsi3" 4589 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 4590 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r") 4591 (match_operand:SI 2 "s_register_operand" "r,r")))] 4592 "TARGET_IDIV" 4593 "@ 4594 udiv%?\t%0, %1, %2 4595 udiv\t%0, %1, %2" 4596 [(set_attr "arch" "32,v8mb") 4597 (set_attr "predicable" "yes") 4598 (set_attr "type" "udiv")] 4599) 4600 4601 4602;; Unary arithmetic insns 4603 4604(define_expand "negvsi3" 4605 [(match_operand:SI 0 "register_operand") 4606 (match_operand:SI 1 "register_operand") 4607 (match_operand 2 "")] 4608 "TARGET_32BIT" 4609{ 4610 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1])); 4611 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); 4612 4613 DONE; 4614}) 4615 4616(define_expand "negvdi3" 4617 [(match_operand:DI 0 "register_operand") 4618 (match_operand:DI 1 "register_operand") 4619 (match_operand 2 "")] 4620 "TARGET_ARM" 4621{ 4622 emit_insn (gen_negdi2_compare (operands[0], operands[1])); 4623 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); 4624 4625 DONE; 4626}) 4627 4628 4629(define_insn_and_split "negdi2_compare" 4630 [(set (reg:CC CC_REGNUM) 4631 (compare:CC 4632 (const_int 0) 4633 (match_operand:DI 1 "register_operand" "0,r"))) 4634 (set (match_operand:DI 0 "register_operand" "=r,&r") 4635 (minus:DI (const_int 0) (match_dup 1)))] 4636 "TARGET_ARM" 4637 "#" 4638 "&& reload_completed" 4639 [(parallel [(set (reg:CC CC_REGNUM) 4640 (compare:CC (const_int 0) (match_dup 1))) 4641 (set (match_dup 0) (minus:SI (const_int 0) 4642 (match_dup 1)))]) 4643 (parallel [(set (reg:CC CC_REGNUM) 4644 (compare:CC (const_int 0) (match_dup 3))) 4645 (set (match_dup 2) 4646 (minus:SI 4647 (minus:SI (const_int 0) (match_dup 3)) 4648 (ltu:SI (reg:CC_C CC_REGNUM) 4649 (const_int 0))))])] 4650 { 4651 operands[2] = gen_highpart (SImode, operands[0]); 4652 operands[0] = gen_lowpart (SImode, operands[0]); 4653 operands[3] = gen_highpart (SImode, operands[1]); 4654 operands[1] = gen_lowpart (SImode, operands[1]); 4655 } 4656 [(set_attr "conds" "set") 4657 (set_attr "length" "8") 4658 (set_attr "type" "multiple")] 4659) 4660 4661(define_expand "negdi2" 4662 [(parallel 4663 [(set (match_operand:DI 0 "s_register_operand" "") 4664 (neg:DI (match_operand:DI 1 "s_register_operand" ""))) 4665 (clobber (reg:CC CC_REGNUM))])] 4666 "TARGET_EITHER" 4667 { 4668 if (TARGET_NEON) 4669 { 4670 emit_insn (gen_negdi2_neon (operands[0], operands[1])); 4671 DONE; 4672 } 4673 } 4674) 4675 4676;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). 4677;; The first alternative allows the common case of a *full* overlap. 4678(define_insn_and_split "*negdi2_insn" 4679 [(set (match_operand:DI 0 "s_register_operand" "=r,&r") 4680 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r"))) 4681 (clobber (reg:CC CC_REGNUM))] 4682 "TARGET_32BIT" 4683 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM) 4684 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2) 4685 "&& reload_completed" 4686 [(parallel [(set (reg:CC CC_REGNUM) 4687 (compare:CC (const_int 0) (match_dup 1))) 4688 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) 4689 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) 4690 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 4691 { 4692 operands[2] = gen_highpart (SImode, operands[0]); 4693 operands[0] = gen_lowpart (SImode, operands[0]); 4694 operands[3] = gen_highpart (SImode, operands[1]); 4695 operands[1] = gen_lowpart (SImode, operands[1]); 4696 } 4697 [(set_attr "conds" "clob") 4698 (set_attr "length" "8") 4699 (set_attr "type" "multiple")] 4700) 4701 4702(define_insn "*negsi2_carryin_compare" 4703 [(set (reg:CC CC_REGNUM) 4704 (compare:CC (const_int 0) 4705 (match_operand:SI 1 "s_register_operand" "r"))) 4706 (set (match_operand:SI 0 "s_register_operand" "=r") 4707 (minus:SI (minus:SI (const_int 0) 4708 (match_dup 1)) 4709 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 4710 "TARGET_ARM" 4711 "rscs\\t%0, %1, #0" 4712 [(set_attr "conds" "set") 4713 (set_attr "type" "alus_imm")] 4714) 4715 4716(define_expand "negsi2" 4717 [(set (match_operand:SI 0 "s_register_operand" "") 4718 (neg:SI (match_operand:SI 1 "s_register_operand" "")))] 4719 "TARGET_EITHER" 4720 "" 4721) 4722 4723(define_insn "*arm_negsi2" 4724 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 4725 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))] 4726 "TARGET_32BIT" 4727 "rsb%?\\t%0, %1, #0" 4728 [(set_attr "predicable" "yes") 4729 (set_attr "predicable_short_it" "yes,no") 4730 (set_attr "arch" "t2,*") 4731 (set_attr "length" "4") 4732 (set_attr "type" "alu_sreg")] 4733) 4734 4735(define_expand "negsf2" 4736 [(set (match_operand:SF 0 "s_register_operand" "") 4737 (neg:SF (match_operand:SF 1 "s_register_operand" "")))] 4738 "TARGET_32BIT && TARGET_HARD_FLOAT" 4739 "" 4740) 4741 4742(define_expand "negdf2" 4743 [(set (match_operand:DF 0 "s_register_operand" "") 4744 (neg:DF (match_operand:DF 1 "s_register_operand" "")))] 4745 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 4746 "") 4747 4748(define_insn_and_split "*zextendsidi_negsi" 4749 [(set (match_operand:DI 0 "s_register_operand" "=r") 4750 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))] 4751 "TARGET_32BIT" 4752 "#" 4753 "" 4754 [(set (match_dup 2) 4755 (neg:SI (match_dup 1))) 4756 (set (match_dup 3) 4757 (const_int 0))] 4758 { 4759 operands[2] = gen_lowpart (SImode, operands[0]); 4760 operands[3] = gen_highpart (SImode, operands[0]); 4761 } 4762 [(set_attr "length" "8") 4763 (set_attr "type" "multiple")] 4764) 4765 4766;; Negate an extended 32-bit value. 4767(define_insn_and_split "*negdi_extendsidi" 4768 [(set (match_operand:DI 0 "s_register_operand" "=l,r") 4769 (neg:DI (sign_extend:DI 4770 (match_operand:SI 1 "s_register_operand" "l,r")))) 4771 (clobber (reg:CC CC_REGNUM))] 4772 "TARGET_32BIT" 4773 "#" 4774 "&& reload_completed" 4775 [(const_int 0)] 4776 { 4777 rtx low = gen_lowpart (SImode, operands[0]); 4778 rtx high = gen_highpart (SImode, operands[0]); 4779 4780 if (reg_overlap_mentioned_p (low, operands[1])) 4781 { 4782 /* Input overlaps the low word of the output. Use: 4783 asr Rhi, Rin, #31 4784 rsbs Rlo, Rin, #0 4785 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */ 4786 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM); 4787 4788 emit_insn (gen_rtx_SET (high, 4789 gen_rtx_ASHIFTRT (SImode, operands[1], 4790 GEN_INT (31)))); 4791 4792 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1])); 4793 if (TARGET_ARM) 4794 emit_insn (gen_rtx_SET (high, 4795 gen_rtx_MINUS (SImode, 4796 gen_rtx_MINUS (SImode, 4797 const0_rtx, 4798 high), 4799 gen_rtx_LTU (SImode, 4800 cc_reg, 4801 const0_rtx)))); 4802 else 4803 { 4804 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1)); 4805 emit_insn (gen_rtx_SET (high, 4806 gen_rtx_MINUS (SImode, 4807 gen_rtx_MINUS (SImode, 4808 high, 4809 two_x), 4810 gen_rtx_LTU (SImode, 4811 cc_reg, 4812 const0_rtx)))); 4813 } 4814 } 4815 else 4816 { 4817 /* No overlap, or overlap on high word. Use: 4818 rsb Rlo, Rin, #0 4819 bic Rhi, Rlo, Rin 4820 asr Rhi, Rhi, #31 4821 Flags not needed for this sequence. */ 4822 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1]))); 4823 emit_insn (gen_rtx_SET (high, 4824 gen_rtx_AND (SImode, 4825 gen_rtx_NOT (SImode, operands[1]), 4826 low))); 4827 emit_insn (gen_rtx_SET (high, 4828 gen_rtx_ASHIFTRT (SImode, high, 4829 GEN_INT (31)))); 4830 } 4831 DONE; 4832 } 4833 [(set_attr "length" "12") 4834 (set_attr "arch" "t2,*") 4835 (set_attr "type" "multiple")] 4836) 4837 4838(define_insn_and_split "*negdi_zero_extendsidi" 4839 [(set (match_operand:DI 0 "s_register_operand" "=r,&r") 4840 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r")))) 4841 (clobber (reg:CC CC_REGNUM))] 4842 "TARGET_32BIT" 4843 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0" 4844 ;; Don't care what register is input to sbc, 4845 ;; since we just need to propagate the carry. 4846 "&& reload_completed" 4847 [(parallel [(set (reg:CC CC_REGNUM) 4848 (compare:CC (const_int 0) (match_dup 1))) 4849 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) 4850 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2)) 4851 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 4852 { 4853 operands[2] = gen_highpart (SImode, operands[0]); 4854 operands[0] = gen_lowpart (SImode, operands[0]); 4855 } 4856 [(set_attr "conds" "clob") 4857 (set_attr "length" "8") 4858 (set_attr "type" "multiple")] ;; length in thumb is 4 4859) 4860 4861;; abssi2 doesn't really clobber the condition codes if a different register 4862;; is being set. To keep things simple, assume during rtl manipulations that 4863;; it does, but tell the final scan operator the truth. Similarly for 4864;; (neg (abs...)) 4865 4866(define_expand "abssi2" 4867 [(parallel 4868 [(set (match_operand:SI 0 "s_register_operand" "") 4869 (abs:SI (match_operand:SI 1 "s_register_operand" ""))) 4870 (clobber (match_dup 2))])] 4871 "TARGET_EITHER" 4872 " 4873 if (TARGET_THUMB1) 4874 operands[2] = gen_rtx_SCRATCH (SImode); 4875 else 4876 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM); 4877") 4878 4879(define_insn_and_split "*arm_abssi2" 4880 [(set (match_operand:SI 0 "s_register_operand" "=r,&r") 4881 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))) 4882 (clobber (reg:CC CC_REGNUM))] 4883 "TARGET_ARM" 4884 "#" 4885 "&& reload_completed" 4886 [(const_int 0)] 4887 { 4888 /* if (which_alternative == 0) */ 4889 if (REGNO(operands[0]) == REGNO(operands[1])) 4890 { 4891 /* Emit the pattern: 4892 cmp\\t%0, #0\;rsblt\\t%0, %0, #0 4893 [(set (reg:CC CC_REGNUM) 4894 (compare:CC (match_dup 0) (const_int 0))) 4895 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0)) 4896 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))] 4897 */ 4898 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM), 4899 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); 4900 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 4901 (gen_rtx_LT (SImode, 4902 gen_rtx_REG (CCmode, CC_REGNUM), 4903 const0_rtx)), 4904 (gen_rtx_SET (operands[0], 4905 (gen_rtx_MINUS (SImode, 4906 const0_rtx, 4907 operands[1])))))); 4908 DONE; 4909 } 4910 else 4911 { 4912 /* Emit the pattern: 4913 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31 4914 [(set (match_dup 0) 4915 (xor:SI (match_dup 1) 4916 (ashiftrt:SI (match_dup 1) (const_int 31)))) 4917 (set (match_dup 0) 4918 (minus:SI (match_dup 0) 4919 (ashiftrt:SI (match_dup 1) (const_int 31))))] 4920 */ 4921 emit_insn (gen_rtx_SET (operands[0], 4922 gen_rtx_XOR (SImode, 4923 gen_rtx_ASHIFTRT (SImode, 4924 operands[1], 4925 GEN_INT (31)), 4926 operands[1]))); 4927 emit_insn (gen_rtx_SET (operands[0], 4928 gen_rtx_MINUS (SImode, 4929 operands[0], 4930 gen_rtx_ASHIFTRT (SImode, 4931 operands[1], 4932 GEN_INT (31))))); 4933 DONE; 4934 } 4935 } 4936 [(set_attr "conds" "clob,*") 4937 (set_attr "shift" "1") 4938 (set_attr "predicable" "no, yes") 4939 (set_attr "length" "8") 4940 (set_attr "type" "multiple")] 4941) 4942 4943(define_insn_and_split "*arm_neg_abssi2" 4944 [(set (match_operand:SI 0 "s_register_operand" "=r,&r") 4945 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))) 4946 (clobber (reg:CC CC_REGNUM))] 4947 "TARGET_ARM" 4948 "#" 4949 "&& reload_completed" 4950 [(const_int 0)] 4951 { 4952 /* if (which_alternative == 0) */ 4953 if (REGNO (operands[0]) == REGNO (operands[1])) 4954 { 4955 /* Emit the pattern: 4956 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0 4957 */ 4958 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM), 4959 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); 4960 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 4961 gen_rtx_GT (SImode, 4962 gen_rtx_REG (CCmode, CC_REGNUM), 4963 const0_rtx), 4964 gen_rtx_SET (operands[0], 4965 (gen_rtx_MINUS (SImode, 4966 const0_rtx, 4967 operands[1]))))); 4968 } 4969 else 4970 { 4971 /* Emit the pattern: 4972 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31 4973 */ 4974 emit_insn (gen_rtx_SET (operands[0], 4975 gen_rtx_XOR (SImode, 4976 gen_rtx_ASHIFTRT (SImode, 4977 operands[1], 4978 GEN_INT (31)), 4979 operands[1]))); 4980 emit_insn (gen_rtx_SET (operands[0], 4981 gen_rtx_MINUS (SImode, 4982 gen_rtx_ASHIFTRT (SImode, 4983 operands[1], 4984 GEN_INT (31)), 4985 operands[0]))); 4986 } 4987 DONE; 4988 } 4989 [(set_attr "conds" "clob,*") 4990 (set_attr "shift" "1") 4991 (set_attr "predicable" "no, yes") 4992 (set_attr "length" "8") 4993 (set_attr "type" "multiple")] 4994) 4995 4996(define_expand "abssf2" 4997 [(set (match_operand:SF 0 "s_register_operand" "") 4998 (abs:SF (match_operand:SF 1 "s_register_operand" "")))] 4999 "TARGET_32BIT && TARGET_HARD_FLOAT" 5000 "") 5001 5002(define_expand "absdf2" 5003 [(set (match_operand:DF 0 "s_register_operand" "") 5004 (abs:DF (match_operand:DF 1 "s_register_operand" "")))] 5005 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5006 "") 5007 5008(define_expand "sqrtsf2" 5009 [(set (match_operand:SF 0 "s_register_operand" "") 5010 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))] 5011 "TARGET_32BIT && TARGET_HARD_FLOAT" 5012 "") 5013 5014(define_expand "sqrtdf2" 5015 [(set (match_operand:DF 0 "s_register_operand" "") 5016 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))] 5017 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 5018 "") 5019 5020(define_expand "one_cmpldi2" 5021 [(set (match_operand:DI 0 "s_register_operand" "") 5022 (not:DI (match_operand:DI 1 "s_register_operand" "")))] 5023 "TARGET_32BIT" 5024 " 5025 if (!TARGET_NEON && !TARGET_IWMMXT) 5026 { 5027 rtx low = simplify_gen_unary (NOT, SImode, 5028 gen_lowpart (SImode, operands[1]), 5029 SImode); 5030 rtx high = simplify_gen_unary (NOT, SImode, 5031 gen_highpart_mode (SImode, DImode, 5032 operands[1]), 5033 SImode); 5034 5035 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); 5036 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); 5037 5038 DONE; 5039 } 5040 /* Otherwise expand pattern as above. */ 5041 " 5042) 5043 5044(define_insn_and_split "*one_cmpldi2_insn" 5045 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w") 5046 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))] 5047 "TARGET_32BIT" 5048 "@ 5049 vmvn\t%P0, %P1 5050 # 5051 # 5052 vmvn\t%P0, %P1" 5053 "TARGET_32BIT && reload_completed 5054 && arm_general_register_operand (operands[0], DImode)" 5055 [(set (match_dup 0) (not:SI (match_dup 1))) 5056 (set (match_dup 2) (not:SI (match_dup 3)))] 5057 " 5058 { 5059 operands[2] = gen_highpart (SImode, operands[0]); 5060 operands[0] = gen_lowpart (SImode, operands[0]); 5061 operands[3] = gen_highpart (SImode, operands[1]); 5062 operands[1] = gen_lowpart (SImode, operands[1]); 5063 }" 5064 [(set_attr "length" "*,8,8,*") 5065 (set_attr "predicable" "no,yes,yes,no") 5066 (set_attr "type" "neon_move,multiple,multiple,neon_move") 5067 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")] 5068) 5069 5070(define_expand "one_cmplsi2" 5071 [(set (match_operand:SI 0 "s_register_operand" "") 5072 (not:SI (match_operand:SI 1 "s_register_operand" "")))] 5073 "TARGET_EITHER" 5074 "" 5075) 5076 5077(define_insn "*arm_one_cmplsi2" 5078 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 5079 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))] 5080 "TARGET_32BIT" 5081 "mvn%?\\t%0, %1" 5082 [(set_attr "predicable" "yes") 5083 (set_attr "predicable_short_it" "yes,no") 5084 (set_attr "arch" "t2,*") 5085 (set_attr "length" "4") 5086 (set_attr "type" "mvn_reg")] 5087) 5088 5089(define_insn "*notsi_compare0" 5090 [(set (reg:CC_NOOV CC_REGNUM) 5091 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) 5092 (const_int 0))) 5093 (set (match_operand:SI 0 "s_register_operand" "=r") 5094 (not:SI (match_dup 1)))] 5095 "TARGET_32BIT" 5096 "mvns%?\\t%0, %1" 5097 [(set_attr "conds" "set") 5098 (set_attr "type" "mvn_reg")] 5099) 5100 5101(define_insn "*notsi_compare0_scratch" 5102 [(set (reg:CC_NOOV CC_REGNUM) 5103 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) 5104 (const_int 0))) 5105 (clobber (match_scratch:SI 0 "=r"))] 5106 "TARGET_32BIT" 5107 "mvns%?\\t%0, %1" 5108 [(set_attr "conds" "set") 5109 (set_attr "type" "mvn_reg")] 5110) 5111 5112;; Fixed <--> Floating conversion insns 5113 5114(define_expand "floatsihf2" 5115 [(set (match_operand:HF 0 "general_operand" "") 5116 (float:HF (match_operand:SI 1 "general_operand" "")))] 5117 "TARGET_EITHER" 5118 " 5119 { 5120 rtx op1 = gen_reg_rtx (SFmode); 5121 expand_float (op1, operands[1], 0); 5122 op1 = convert_to_mode (HFmode, op1, 0); 5123 emit_move_insn (operands[0], op1); 5124 DONE; 5125 }" 5126) 5127 5128(define_expand "floatdihf2" 5129 [(set (match_operand:HF 0 "general_operand" "") 5130 (float:HF (match_operand:DI 1 "general_operand" "")))] 5131 "TARGET_EITHER" 5132 " 5133 { 5134 rtx op1 = gen_reg_rtx (SFmode); 5135 expand_float (op1, operands[1], 0); 5136 op1 = convert_to_mode (HFmode, op1, 0); 5137 emit_move_insn (operands[0], op1); 5138 DONE; 5139 }" 5140) 5141 5142(define_expand "floatsisf2" 5143 [(set (match_operand:SF 0 "s_register_operand" "") 5144 (float:SF (match_operand:SI 1 "s_register_operand" "")))] 5145 "TARGET_32BIT && TARGET_HARD_FLOAT" 5146 " 5147") 5148 5149(define_expand "floatsidf2" 5150 [(set (match_operand:DF 0 "s_register_operand" "") 5151 (float:DF (match_operand:SI 1 "s_register_operand" "")))] 5152 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5153 " 5154") 5155 5156(define_expand "fix_trunchfsi2" 5157 [(set (match_operand:SI 0 "general_operand" "") 5158 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))] 5159 "TARGET_EITHER" 5160 " 5161 { 5162 rtx op1 = convert_to_mode (SFmode, operands[1], 0); 5163 expand_fix (operands[0], op1, 0); 5164 DONE; 5165 }" 5166) 5167 5168(define_expand "fix_trunchfdi2" 5169 [(set (match_operand:DI 0 "general_operand" "") 5170 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))] 5171 "TARGET_EITHER" 5172 " 5173 { 5174 rtx op1 = convert_to_mode (SFmode, operands[1], 0); 5175 expand_fix (operands[0], op1, 0); 5176 DONE; 5177 }" 5178) 5179 5180(define_expand "fix_truncsfsi2" 5181 [(set (match_operand:SI 0 "s_register_operand" "") 5182 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))] 5183 "TARGET_32BIT && TARGET_HARD_FLOAT" 5184 " 5185") 5186 5187(define_expand "fix_truncdfsi2" 5188 [(set (match_operand:SI 0 "s_register_operand" "") 5189 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))] 5190 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5191 " 5192") 5193 5194;; Truncation insns 5195 5196(define_expand "truncdfsf2" 5197 [(set (match_operand:SF 0 "s_register_operand" "") 5198 (float_truncate:SF 5199 (match_operand:DF 1 "s_register_operand" "")))] 5200 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5201 "" 5202) 5203 5204;; DFmode to HFmode conversions on targets without a single-step hardware 5205;; instruction for it would have to go through SFmode. This is dangerous 5206;; as it introduces double rounding. 5207;; 5208;; Disable this pattern unless we are in an unsafe math mode, or we have 5209;; a single-step instruction. 5210 5211(define_expand "truncdfhf2" 5212 [(set (match_operand:HF 0 "s_register_operand" "") 5213 (float_truncate:HF 5214 (match_operand:DF 1 "s_register_operand" "")))] 5215 "(TARGET_EITHER && flag_unsafe_math_optimizations) 5216 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)" 5217{ 5218 /* We don't have a direct instruction for this, so we must be in 5219 an unsafe math mode, and going via SFmode. */ 5220 5221 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE)) 5222 { 5223 rtx op1; 5224 op1 = convert_to_mode (SFmode, operands[1], 0); 5225 op1 = convert_to_mode (HFmode, op1, 0); 5226 emit_move_insn (operands[0], op1); 5227 DONE; 5228 } 5229 /* Otherwise, we will pick this up as a single instruction with 5230 no intermediary rounding. */ 5231} 5232) 5233 5234;; Zero and sign extension instructions. 5235 5236(define_insn "zero_extend<mode>di2" 5237 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w") 5238 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>" 5239 "<qhs_zextenddi_cstr>")))] 5240 "TARGET_32BIT <qhs_zextenddi_cond>" 5241 "#" 5242 [(set_attr "length" "8,4,8,8") 5243 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits") 5244 (set_attr "ce_count" "2") 5245 (set_attr "predicable" "yes") 5246 (set_attr "type" "multiple,mov_reg,multiple,multiple")] 5247) 5248 5249(define_insn "extend<mode>di2" 5250 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w") 5251 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>" 5252 "<qhs_extenddi_cstr>")))] 5253 "TARGET_32BIT <qhs_sextenddi_cond>" 5254 "#" 5255 [(set_attr "length" "8,4,8,8,8") 5256 (set_attr "ce_count" "2") 5257 (set_attr "shift" "1") 5258 (set_attr "predicable" "yes") 5259 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits") 5260 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")] 5261) 5262 5263;; Splits for all extensions to DImode 5264(define_split 5265 [(set (match_operand:DI 0 "s_register_operand" "") 5266 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))] 5267 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))" 5268 [(set (match_dup 0) (match_dup 1))] 5269{ 5270 rtx lo_part = gen_lowpart (SImode, operands[0]); 5271 machine_mode src_mode = GET_MODE (operands[1]); 5272 5273 if (REG_P (operands[0]) 5274 && !reg_overlap_mentioned_p (operands[0], operands[1])) 5275 emit_clobber (operands[0]); 5276 if (!REG_P (lo_part) || src_mode != SImode 5277 || !rtx_equal_p (lo_part, operands[1])) 5278 { 5279 if (src_mode == SImode) 5280 emit_move_insn (lo_part, operands[1]); 5281 else 5282 emit_insn (gen_rtx_SET (lo_part, 5283 gen_rtx_ZERO_EXTEND (SImode, operands[1]))); 5284 operands[1] = lo_part; 5285 } 5286 operands[0] = gen_highpart (SImode, operands[0]); 5287 operands[1] = const0_rtx; 5288}) 5289 5290(define_split 5291 [(set (match_operand:DI 0 "s_register_operand" "") 5292 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))] 5293 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))" 5294 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))] 5295{ 5296 rtx lo_part = gen_lowpart (SImode, operands[0]); 5297 machine_mode src_mode = GET_MODE (operands[1]); 5298 5299 if (REG_P (operands[0]) 5300 && !reg_overlap_mentioned_p (operands[0], operands[1])) 5301 emit_clobber (operands[0]); 5302 5303 if (!REG_P (lo_part) || src_mode != SImode 5304 || !rtx_equal_p (lo_part, operands[1])) 5305 { 5306 if (src_mode == SImode) 5307 emit_move_insn (lo_part, operands[1]); 5308 else 5309 emit_insn (gen_rtx_SET (lo_part, 5310 gen_rtx_SIGN_EXTEND (SImode, operands[1]))); 5311 operands[1] = lo_part; 5312 } 5313 operands[0] = gen_highpart (SImode, operands[0]); 5314}) 5315 5316(define_expand "zero_extendhisi2" 5317 [(set (match_operand:SI 0 "s_register_operand" "") 5318 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 5319 "TARGET_EITHER" 5320{ 5321 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1])) 5322 { 5323 emit_insn (gen_movhi_bytes (operands[0], operands[1])); 5324 DONE; 5325 } 5326 if (!arm_arch6 && !MEM_P (operands[1])) 5327 { 5328 rtx t = gen_lowpart (SImode, operands[1]); 5329 rtx tmp = gen_reg_rtx (SImode); 5330 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16))); 5331 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16))); 5332 DONE; 5333 } 5334}) 5335 5336(define_split 5337 [(set (match_operand:SI 0 "s_register_operand" "") 5338 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))] 5339 "!TARGET_THUMB2 && !arm_arch6" 5340 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 5341 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))] 5342{ 5343 operands[2] = gen_lowpart (SImode, operands[1]); 5344}) 5345 5346(define_insn "*arm_zero_extendhisi2" 5347 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5348 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 5349 "TARGET_ARM && arm_arch4 && !arm_arch6" 5350 "@ 5351 # 5352 ldrh%?\\t%0, %1" 5353 [(set_attr "type" "alu_shift_reg,load_byte") 5354 (set_attr "predicable" "yes")] 5355) 5356 5357(define_insn "*arm_zero_extendhisi2_v6" 5358 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5359 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))] 5360 "TARGET_ARM && arm_arch6" 5361 "@ 5362 uxth%?\\t%0, %1 5363 ldrh%?\\t%0, %1" 5364 [(set_attr "predicable" "yes") 5365 (set_attr "type" "extend,load_byte")] 5366) 5367 5368(define_insn "*arm_zero_extendhisi2addsi" 5369 [(set (match_operand:SI 0 "s_register_operand" "=r") 5370 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r")) 5371 (match_operand:SI 2 "s_register_operand" "r")))] 5372 "TARGET_INT_SIMD" 5373 "uxtah%?\\t%0, %2, %1" 5374 [(set_attr "type" "alu_shift_reg") 5375 (set_attr "predicable" "yes")] 5376) 5377 5378(define_expand "zero_extendqisi2" 5379 [(set (match_operand:SI 0 "s_register_operand" "") 5380 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 5381 "TARGET_EITHER" 5382{ 5383 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1])) 5384 { 5385 emit_insn (gen_andsi3 (operands[0], 5386 gen_lowpart (SImode, operands[1]), 5387 GEN_INT (255))); 5388 DONE; 5389 } 5390 if (!arm_arch6 && !MEM_P (operands[1])) 5391 { 5392 rtx t = gen_lowpart (SImode, operands[1]); 5393 rtx tmp = gen_reg_rtx (SImode); 5394 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24))); 5395 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24))); 5396 DONE; 5397 } 5398}) 5399 5400(define_split 5401 [(set (match_operand:SI 0 "s_register_operand" "") 5402 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))] 5403 "!arm_arch6" 5404 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24))) 5405 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))] 5406{ 5407 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0); 5408 if (TARGET_ARM) 5409 { 5410 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255))); 5411 DONE; 5412 } 5413}) 5414 5415(define_insn "*arm_zero_extendqisi2" 5416 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5417 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 5418 "TARGET_ARM && !arm_arch6" 5419 "@ 5420 # 5421 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2" 5422 [(set_attr "length" "8,4") 5423 (set_attr "type" "alu_shift_reg,load_byte") 5424 (set_attr "predicable" "yes")] 5425) 5426 5427(define_insn "*arm_zero_extendqisi2_v6" 5428 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5429 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))] 5430 "TARGET_ARM && arm_arch6" 5431 "@ 5432 uxtb%?\\t%0, %1 5433 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2" 5434 [(set_attr "type" "extend,load_byte") 5435 (set_attr "predicable" "yes")] 5436) 5437 5438(define_insn "*arm_zero_extendqisi2addsi" 5439 [(set (match_operand:SI 0 "s_register_operand" "=r") 5440 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r")) 5441 (match_operand:SI 2 "s_register_operand" "r")))] 5442 "TARGET_INT_SIMD" 5443 "uxtab%?\\t%0, %2, %1" 5444 [(set_attr "predicable" "yes") 5445 (set_attr "type" "alu_shift_reg")] 5446) 5447 5448(define_split 5449 [(set (match_operand:SI 0 "s_register_operand" "") 5450 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0))) 5451 (clobber (match_operand:SI 2 "s_register_operand" ""))] 5452 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN" 5453 [(set (match_dup 2) (match_dup 1)) 5454 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))] 5455 "" 5456) 5457 5458(define_split 5459 [(set (match_operand:SI 0 "s_register_operand" "") 5460 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3))) 5461 (clobber (match_operand:SI 2 "s_register_operand" ""))] 5462 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN" 5463 [(set (match_dup 2) (match_dup 1)) 5464 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))] 5465 "" 5466) 5467 5468 5469(define_split 5470 [(set (match_operand:SI 0 "s_register_operand" "") 5471 (IOR_XOR:SI (and:SI (ashift:SI 5472 (match_operand:SI 1 "s_register_operand" "") 5473 (match_operand:SI 2 "const_int_operand" "")) 5474 (match_operand:SI 3 "const_int_operand" "")) 5475 (zero_extend:SI 5476 (match_operator 5 "subreg_lowpart_operator" 5477 [(match_operand:SI 4 "s_register_operand" "")]))))] 5478 "TARGET_32BIT 5479 && (UINTVAL (operands[3]) 5480 == (GET_MODE_MASK (GET_MODE (operands[5])) 5481 & (GET_MODE_MASK (GET_MODE (operands[5])) 5482 << (INTVAL (operands[2])))))" 5483 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2)) 5484 (match_dup 4))) 5485 (set (match_dup 0) (zero_extend:SI (match_dup 5)))] 5486 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);" 5487) 5488 5489(define_insn "*compareqi_eq0" 5490 [(set (reg:CC_Z CC_REGNUM) 5491 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r") 5492 (const_int 0)))] 5493 "TARGET_32BIT" 5494 "tst%?\\t%0, #255" 5495 [(set_attr "conds" "set") 5496 (set_attr "predicable" "yes") 5497 (set_attr "type" "logic_imm")] 5498) 5499 5500(define_expand "extendhisi2" 5501 [(set (match_operand:SI 0 "s_register_operand" "") 5502 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 5503 "TARGET_EITHER" 5504{ 5505 if (TARGET_THUMB1) 5506 { 5507 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1])); 5508 DONE; 5509 } 5510 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4) 5511 { 5512 emit_insn (gen_extendhisi2_mem (operands[0], operands[1])); 5513 DONE; 5514 } 5515 5516 if (!arm_arch6 && !MEM_P (operands[1])) 5517 { 5518 rtx t = gen_lowpart (SImode, operands[1]); 5519 rtx tmp = gen_reg_rtx (SImode); 5520 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16))); 5521 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16))); 5522 DONE; 5523 } 5524}) 5525 5526(define_split 5527 [(parallel 5528 [(set (match_operand:SI 0 "register_operand" "") 5529 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))) 5530 (clobber (match_scratch:SI 2 ""))])] 5531 "!arm_arch6" 5532 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 5533 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))] 5534{ 5535 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 5536}) 5537 5538;; This pattern will only be used when ldsh is not available 5539(define_expand "extendhisi2_mem" 5540 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" ""))) 5541 (set (match_dup 3) 5542 (zero_extend:SI (match_dup 7))) 5543 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24))) 5544 (set (match_operand:SI 0 "" "") 5545 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))] 5546 "TARGET_ARM" 5547 " 5548 { 5549 rtx mem1, mem2; 5550 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 5551 5552 mem1 = change_address (operands[1], QImode, addr); 5553 mem2 = change_address (operands[1], QImode, 5554 plus_constant (Pmode, addr, 1)); 5555 operands[0] = gen_lowpart (SImode, operands[0]); 5556 operands[1] = mem1; 5557 operands[2] = gen_reg_rtx (SImode); 5558 operands[3] = gen_reg_rtx (SImode); 5559 operands[6] = gen_reg_rtx (SImode); 5560 operands[7] = mem2; 5561 5562 if (BYTES_BIG_ENDIAN) 5563 { 5564 operands[4] = operands[2]; 5565 operands[5] = operands[3]; 5566 } 5567 else 5568 { 5569 operands[4] = operands[3]; 5570 operands[5] = operands[2]; 5571 } 5572 }" 5573) 5574 5575(define_split 5576 [(set (match_operand:SI 0 "register_operand" "") 5577 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 5578 "!arm_arch6" 5579 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 5580 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))] 5581{ 5582 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 5583}) 5584 5585(define_insn "*arm_extendhisi2" 5586 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5587 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))] 5588 "TARGET_ARM && arm_arch4 && !arm_arch6" 5589 "@ 5590 # 5591 ldrsh%?\\t%0, %1" 5592 [(set_attr "length" "8,4") 5593 (set_attr "type" "alu_shift_reg,load_byte") 5594 (set_attr "predicable" "yes")] 5595) 5596 5597;; ??? Check Thumb-2 pool range 5598(define_insn "*arm_extendhisi2_v6" 5599 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5600 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))] 5601 "TARGET_32BIT && arm_arch6" 5602 "@ 5603 sxth%?\\t%0, %1 5604 ldrsh%?\\t%0, %1" 5605 [(set_attr "type" "extend,load_byte") 5606 (set_attr "predicable" "yes")] 5607) 5608 5609(define_insn "*arm_extendhisi2addsi" 5610 [(set (match_operand:SI 0 "s_register_operand" "=r") 5611 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r")) 5612 (match_operand:SI 2 "s_register_operand" "r")))] 5613 "TARGET_INT_SIMD" 5614 "sxtah%?\\t%0, %2, %1" 5615 [(set_attr "type" "alu_shift_reg")] 5616) 5617 5618(define_expand "extendqihi2" 5619 [(set (match_dup 2) 5620 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "") 5621 (const_int 24))) 5622 (set (match_operand:HI 0 "s_register_operand" "") 5623 (ashiftrt:SI (match_dup 2) 5624 (const_int 24)))] 5625 "TARGET_ARM" 5626 " 5627 { 5628 if (arm_arch4 && MEM_P (operands[1])) 5629 { 5630 emit_insn (gen_rtx_SET (operands[0], 5631 gen_rtx_SIGN_EXTEND (HImode, operands[1]))); 5632 DONE; 5633 } 5634 if (!s_register_operand (operands[1], QImode)) 5635 operands[1] = copy_to_mode_reg (QImode, operands[1]); 5636 operands[0] = gen_lowpart (SImode, operands[0]); 5637 operands[1] = gen_lowpart (SImode, operands[1]); 5638 operands[2] = gen_reg_rtx (SImode); 5639 }" 5640) 5641 5642(define_insn "*arm_extendqihi_insn" 5643 [(set (match_operand:HI 0 "s_register_operand" "=r") 5644 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))] 5645 "TARGET_ARM && arm_arch4" 5646 "ldrsb%?\\t%0, %1" 5647 [(set_attr "type" "load_byte") 5648 (set_attr "predicable" "yes")] 5649) 5650 5651(define_expand "extendqisi2" 5652 [(set (match_operand:SI 0 "s_register_operand" "") 5653 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))] 5654 "TARGET_EITHER" 5655{ 5656 if (!arm_arch4 && MEM_P (operands[1])) 5657 operands[1] = copy_to_mode_reg (QImode, operands[1]); 5658 5659 if (!arm_arch6 && !MEM_P (operands[1])) 5660 { 5661 rtx t = gen_lowpart (SImode, operands[1]); 5662 rtx tmp = gen_reg_rtx (SImode); 5663 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24))); 5664 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24))); 5665 DONE; 5666 } 5667}) 5668 5669(define_split 5670 [(set (match_operand:SI 0 "register_operand" "") 5671 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] 5672 "!arm_arch6" 5673 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24))) 5674 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))] 5675{ 5676 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0); 5677}) 5678 5679(define_insn "*arm_extendqisi" 5680 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5681 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))] 5682 "TARGET_ARM && arm_arch4 && !arm_arch6" 5683 "@ 5684 # 5685 ldrsb%?\\t%0, %1" 5686 [(set_attr "length" "8,4") 5687 (set_attr "type" "alu_shift_reg,load_byte") 5688 (set_attr "predicable" "yes")] 5689) 5690 5691(define_insn "*arm_extendqisi_v6" 5692 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5693 (sign_extend:SI 5694 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))] 5695 "TARGET_ARM && arm_arch6" 5696 "@ 5697 sxtb%?\\t%0, %1 5698 ldrsb%?\\t%0, %1" 5699 [(set_attr "type" "extend,load_byte") 5700 (set_attr "predicable" "yes")] 5701) 5702 5703(define_insn "*arm_extendqisi2addsi" 5704 [(set (match_operand:SI 0 "s_register_operand" "=r") 5705 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r")) 5706 (match_operand:SI 2 "s_register_operand" "r")))] 5707 "TARGET_INT_SIMD" 5708 "sxtab%?\\t%0, %2, %1" 5709 [(set_attr "type" "alu_shift_reg") 5710 (set_attr "predicable" "yes")] 5711) 5712 5713(define_expand "extendsfdf2" 5714 [(set (match_operand:DF 0 "s_register_operand" "") 5715 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))] 5716 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5717 "" 5718) 5719 5720;; HFmode -> DFmode conversions where we don't have an instruction for it 5721;; must go through SFmode. 5722;; 5723;; This is always safe for an extend. 5724 5725(define_expand "extendhfdf2" 5726 [(set (match_operand:DF 0 "s_register_operand" "") 5727 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))] 5728 "TARGET_EITHER" 5729{ 5730 /* We don't have a direct instruction for this, so go via SFmode. */ 5731 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE)) 5732 { 5733 rtx op1; 5734 op1 = convert_to_mode (SFmode, operands[1], 0); 5735 op1 = convert_to_mode (DFmode, op1, 0); 5736 emit_insn (gen_movdf (operands[0], op1)); 5737 DONE; 5738 } 5739 /* Otherwise, we're done producing RTL and will pick up the correct 5740 pattern to do this with one rounding-step in a single instruction. */ 5741} 5742) 5743 5744;; Move insns (including loads and stores) 5745 5746;; XXX Just some ideas about movti. 5747;; I don't think these are a good idea on the arm, there just aren't enough 5748;; registers 5749;;(define_expand "loadti" 5750;; [(set (match_operand:TI 0 "s_register_operand" "") 5751;; (mem:TI (match_operand:SI 1 "address_operand" "")))] 5752;; "" "") 5753 5754;;(define_expand "storeti" 5755;; [(set (mem:TI (match_operand:TI 0 "address_operand" "")) 5756;; (match_operand:TI 1 "s_register_operand" ""))] 5757;; "" "") 5758 5759;;(define_expand "movti" 5760;; [(set (match_operand:TI 0 "general_operand" "") 5761;; (match_operand:TI 1 "general_operand" ""))] 5762;; "" 5763;; " 5764;;{ 5765;; rtx insn; 5766;; 5767;; if (MEM_P (operands[0]) && MEM_P (operands[1])) 5768;; operands[1] = copy_to_reg (operands[1]); 5769;; if (MEM_P (operands[0])) 5770;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]); 5771;; else if (MEM_P (operands[1])) 5772;; insn = gen_loadti (operands[0], XEXP (operands[1], 0)); 5773;; else 5774;; FAIL; 5775;; 5776;; emit_insn (insn); 5777;; DONE; 5778;;}") 5779 5780;; Recognize garbage generated above. 5781 5782;;(define_insn "" 5783;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m") 5784;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))] 5785;; "" 5786;; "* 5787;; { 5788;; register mem = (which_alternative < 3); 5789;; register const char *template; 5790;; 5791;; operands[mem] = XEXP (operands[mem], 0); 5792;; switch (which_alternative) 5793;; { 5794;; case 0: template = \"ldmdb\\t%1!, %M0\"; break; 5795;; case 1: template = \"ldmia\\t%1!, %M0\"; break; 5796;; case 2: template = \"ldmia\\t%1, %M0\"; break; 5797;; case 3: template = \"stmdb\\t%0!, %M1\"; break; 5798;; case 4: template = \"stmia\\t%0!, %M1\"; break; 5799;; case 5: template = \"stmia\\t%0, %M1\"; break; 5800;; } 5801;; output_asm_insn (template, operands); 5802;; return \"\"; 5803;; }") 5804 5805(define_expand "movdi" 5806 [(set (match_operand:DI 0 "general_operand" "") 5807 (match_operand:DI 1 "general_operand" ""))] 5808 "TARGET_EITHER" 5809 " 5810 if (can_create_pseudo_p ()) 5811 { 5812 if (!REG_P (operands[0])) 5813 operands[1] = force_reg (DImode, operands[1]); 5814 } 5815 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM 5816 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode)) 5817 { 5818 /* Avoid LDRD's into an odd-numbered register pair in ARM state 5819 when expanding function calls. */ 5820 gcc_assert (can_create_pseudo_p ()); 5821 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1])) 5822 { 5823 /* Perform load into legal reg pair first, then move. */ 5824 rtx reg = gen_reg_rtx (DImode); 5825 emit_insn (gen_movdi (reg, operands[1])); 5826 operands[1] = reg; 5827 } 5828 emit_move_insn (gen_lowpart (SImode, operands[0]), 5829 gen_lowpart (SImode, operands[1])); 5830 emit_move_insn (gen_highpart (SImode, operands[0]), 5831 gen_highpart (SImode, operands[1])); 5832 DONE; 5833 } 5834 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM 5835 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode)) 5836 { 5837 /* Avoid STRD's from an odd-numbered register pair in ARM state 5838 when expanding function prologue. */ 5839 gcc_assert (can_create_pseudo_p ()); 5840 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) 5841 ? gen_reg_rtx (DImode) 5842 : operands[0]; 5843 emit_move_insn (gen_lowpart (SImode, split_dest), 5844 gen_lowpart (SImode, operands[1])); 5845 emit_move_insn (gen_highpart (SImode, split_dest), 5846 gen_highpart (SImode, operands[1])); 5847 if (split_dest != operands[0]) 5848 emit_insn (gen_movdi (operands[0], split_dest)); 5849 DONE; 5850 } 5851 " 5852) 5853 5854(define_insn "*arm_movdi" 5855 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, r, m") 5856 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,r"))] 5857 "TARGET_32BIT 5858 && !(TARGET_HARD_FLOAT) 5859 && !TARGET_IWMMXT 5860 && ( register_operand (operands[0], DImode) 5861 || register_operand (operands[1], DImode))" 5862 "* 5863 switch (which_alternative) 5864 { 5865 case 0: 5866 case 1: 5867 case 2: 5868 return \"#\"; 5869 case 3: 5870 /* Cannot load it directly, split to load it via MOV / MOVT. */ 5871 if (!MEM_P (operands[1]) && arm_disable_literal_pool) 5872 return \"#\"; 5873 /* Fall through. */ 5874 default: 5875 return output_move_double (operands, true, NULL); 5876 } 5877 " 5878 [(set_attr "length" "8,12,16,8,8") 5879 (set_attr "type" "multiple,multiple,multiple,load_8,store_8") 5880 (set_attr "arm_pool_range" "*,*,*,1020,*") 5881 (set_attr "arm_neg_pool_range" "*,*,*,1004,*") 5882 (set_attr "thumb2_pool_range" "*,*,*,4094,*") 5883 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")] 5884) 5885 5886(define_split 5887 [(set (match_operand:ANY64 0 "arm_general_register_operand" "") 5888 (match_operand:ANY64 1 "immediate_operand" ""))] 5889 "TARGET_32BIT 5890 && reload_completed 5891 && (arm_disable_literal_pool 5892 || (arm_const_double_inline_cost (operands[1]) 5893 <= arm_max_const_double_inline_cost ()))" 5894 [(const_int 0)] 5895 " 5896 arm_split_constant (SET, SImode, curr_insn, 5897 INTVAL (gen_lowpart (SImode, operands[1])), 5898 gen_lowpart (SImode, operands[0]), NULL_RTX, 0); 5899 arm_split_constant (SET, SImode, curr_insn, 5900 INTVAL (gen_highpart_mode (SImode, 5901 GET_MODE (operands[0]), 5902 operands[1])), 5903 gen_highpart (SImode, operands[0]), NULL_RTX, 0); 5904 DONE; 5905 " 5906) 5907 5908; If optimizing for size, or if we have load delay slots, then 5909; we want to split the constant into two separate operations. 5910; In both cases this may split a trivial part into a single data op 5911; leaving a single complex constant to load. We can also get longer 5912; offsets in a LDR which means we get better chances of sharing the pool 5913; entries. Finally, we can normally do a better job of scheduling 5914; LDR instructions than we can with LDM. 5915; This pattern will only match if the one above did not. 5916(define_split 5917 [(set (match_operand:ANY64 0 "arm_general_register_operand" "") 5918 (match_operand:ANY64 1 "const_double_operand" ""))] 5919 "TARGET_ARM && reload_completed 5920 && arm_const_double_by_parts (operands[1])" 5921 [(set (match_dup 0) (match_dup 1)) 5922 (set (match_dup 2) (match_dup 3))] 5923 " 5924 operands[2] = gen_highpart (SImode, operands[0]); 5925 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]), 5926 operands[1]); 5927 operands[0] = gen_lowpart (SImode, operands[0]); 5928 operands[1] = gen_lowpart (SImode, operands[1]); 5929 " 5930) 5931 5932(define_split 5933 [(set (match_operand:ANY64 0 "arm_general_register_operand" "") 5934 (match_operand:ANY64 1 "arm_general_register_operand" ""))] 5935 "TARGET_EITHER && reload_completed" 5936 [(set (match_dup 0) (match_dup 1)) 5937 (set (match_dup 2) (match_dup 3))] 5938 " 5939 operands[2] = gen_highpart (SImode, operands[0]); 5940 operands[3] = gen_highpart (SImode, operands[1]); 5941 operands[0] = gen_lowpart (SImode, operands[0]); 5942 operands[1] = gen_lowpart (SImode, operands[1]); 5943 5944 /* Handle a partial overlap. */ 5945 if (rtx_equal_p (operands[0], operands[3])) 5946 { 5947 rtx tmp0 = operands[0]; 5948 rtx tmp1 = operands[1]; 5949 5950 operands[0] = operands[2]; 5951 operands[1] = operands[3]; 5952 operands[2] = tmp0; 5953 operands[3] = tmp1; 5954 } 5955 " 5956) 5957 5958;; We can't actually do base+index doubleword loads if the index and 5959;; destination overlap. Split here so that we at least have chance to 5960;; schedule. 5961(define_split 5962 [(set (match_operand:DI 0 "s_register_operand" "") 5963 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "") 5964 (match_operand:SI 2 "s_register_operand" ""))))] 5965 "TARGET_LDRD 5966 && reg_overlap_mentioned_p (operands[0], operands[1]) 5967 && reg_overlap_mentioned_p (operands[0], operands[2])" 5968 [(set (match_dup 4) 5969 (plus:SI (match_dup 1) 5970 (match_dup 2))) 5971 (set (match_dup 0) 5972 (mem:DI (match_dup 4)))] 5973 " 5974 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0])); 5975 " 5976) 5977 5978(define_expand "movsi" 5979 [(set (match_operand:SI 0 "general_operand" "") 5980 (match_operand:SI 1 "general_operand" ""))] 5981 "TARGET_EITHER" 5982 " 5983 { 5984 rtx base, offset, tmp; 5985 5986 if (TARGET_32BIT || TARGET_HAVE_MOVT) 5987 { 5988 /* Everything except mem = const or mem = mem can be done easily. */ 5989 if (MEM_P (operands[0])) 5990 operands[1] = force_reg (SImode, operands[1]); 5991 if (arm_general_register_operand (operands[0], SImode) 5992 && CONST_INT_P (operands[1]) 5993 && !(const_ok_for_arm (INTVAL (operands[1])) 5994 || const_ok_for_arm (~INTVAL (operands[1])))) 5995 { 5996 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET)) 5997 { 5998 emit_insn (gen_rtx_SET (operands[0], operands[1])); 5999 DONE; 6000 } 6001 else 6002 { 6003 arm_split_constant (SET, SImode, NULL_RTX, 6004 INTVAL (operands[1]), operands[0], NULL_RTX, 6005 optimize && can_create_pseudo_p ()); 6006 DONE; 6007 } 6008 } 6009 } 6010 else /* Target doesn't have MOVT... */ 6011 { 6012 if (can_create_pseudo_p ()) 6013 { 6014 if (!REG_P (operands[0])) 6015 operands[1] = force_reg (SImode, operands[1]); 6016 } 6017 } 6018 6019 split_const (operands[1], &base, &offset); 6020 if (INTVAL (offset) != 0 6021 && targetm.cannot_force_const_mem (SImode, operands[1])) 6022 { 6023 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; 6024 emit_move_insn (tmp, base); 6025 emit_insn (gen_addsi3 (operands[0], tmp, offset)); 6026 DONE; 6027 } 6028 6029 tmp = can_create_pseudo_p () ? NULL_RTX : operands[0]; 6030 6031 /* Recognize the case where operand[1] is a reference to thread-local 6032 data and load its address to a register. Offsets have been split off 6033 already. */ 6034 if (arm_tls_referenced_p (operands[1])) 6035 operands[1] = legitimize_tls_address (operands[1], tmp); 6036 else if (flag_pic 6037 && (CONSTANT_P (operands[1]) 6038 || symbol_mentioned_p (operands[1]) 6039 || label_mentioned_p (operands[1]))) 6040 operands[1] = 6041 legitimize_pic_address (operands[1], SImode, tmp, NULL_RTX, false); 6042 } 6043 " 6044) 6045 6046;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and 6047;; LO_SUM adds in the high bits. Fortunately these are opaque operations 6048;; so this does not matter. 6049(define_insn "*arm_movt" 6050 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r") 6051 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6052 (match_operand:SI 2 "general_operand" "i,i")))] 6053 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])" 6054 "@ 6055 movt%?\t%0, #:upper16:%c2 6056 movt\t%0, #:upper16:%c2" 6057 [(set_attr "arch" "32,v8mb") 6058 (set_attr "predicable" "yes") 6059 (set_attr "length" "4") 6060 (set_attr "type" "alu_sreg")] 6061) 6062 6063(define_insn "*arm_movsi_insn" 6064 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m") 6065 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))] 6066 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT 6067 && ( register_operand (operands[0], SImode) 6068 || register_operand (operands[1], SImode))" 6069 "@ 6070 mov%?\\t%0, %1 6071 mov%?\\t%0, %1 6072 mvn%?\\t%0, #%B1 6073 movw%?\\t%0, %1 6074 ldr%?\\t%0, %1 6075 str%?\\t%1, %0" 6076 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4") 6077 (set_attr "predicable" "yes") 6078 (set_attr "arch" "*,*,*,v6t2,*,*") 6079 (set_attr "pool_range" "*,*,*,*,4096,*") 6080 (set_attr "neg_pool_range" "*,*,*,*,4084,*")] 6081) 6082 6083(define_split 6084 [(set (match_operand:SI 0 "arm_general_register_operand" "") 6085 (match_operand:SI 1 "const_int_operand" ""))] 6086 "(TARGET_32BIT || TARGET_HAVE_MOVT) 6087 && (!(const_ok_for_arm (INTVAL (operands[1])) 6088 || const_ok_for_arm (~INTVAL (operands[1]))))" 6089 [(clobber (const_int 0))] 6090 " 6091 arm_split_constant (SET, SImode, NULL_RTX, 6092 INTVAL (operands[1]), operands[0], NULL_RTX, 0); 6093 DONE; 6094 " 6095) 6096 6097;; A normal way to do (symbol + offset) requires three instructions at least 6098;; (depends on how big the offset is) as below: 6099;; movw r0, #:lower16:g 6100;; movw r0, #:upper16:g 6101;; adds r0, #4 6102;; 6103;; A better way would be: 6104;; movw r0, #:lower16:g+4 6105;; movw r0, #:upper16:g+4 6106;; 6107;; The limitation of this way is that the length of offset should be a 16-bit 6108;; signed value, because current assembler only supports REL type relocation for 6109;; such case. If the more powerful RELA type is supported in future, we should 6110;; update this pattern to go with better way. 6111(define_split 6112 [(set (match_operand:SI 0 "arm_general_register_operand" "") 6113 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "") 6114 (match_operand:SI 2 "const_int_operand" ""))))] 6115 "TARGET_THUMB 6116 && TARGET_HAVE_MOVT 6117 && arm_disable_literal_pool 6118 && reload_completed 6119 && GET_CODE (operands[1]) == SYMBOL_REF" 6120 [(clobber (const_int 0))] 6121 " 6122 int offset = INTVAL (operands[2]); 6123 6124 if (offset < -0x8000 || offset > 0x7fff) 6125 { 6126 arm_emit_movpair (operands[0], operands[1]); 6127 emit_insn (gen_rtx_SET (operands[0], 6128 gen_rtx_PLUS (SImode, operands[0], operands[2]))); 6129 } 6130 else 6131 { 6132 rtx op = gen_rtx_CONST (SImode, 6133 gen_rtx_PLUS (SImode, operands[1], operands[2])); 6134 arm_emit_movpair (operands[0], op); 6135 } 6136 " 6137) 6138 6139;; Split symbol_refs at the later stage (after cprop), instead of generating 6140;; movt/movw pair directly at expand. Otherwise corresponding high_sum 6141;; and lo_sum would be merged back into memory load at cprop. However, 6142;; if the default is to prefer movt/movw rather than a load from the constant 6143;; pool, the performance is better. 6144(define_split 6145 [(set (match_operand:SI 0 "arm_general_register_operand" "") 6146 (match_operand:SI 1 "general_operand" ""))] 6147 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF 6148 && !target_word_relocations 6149 && !arm_tls_referenced_p (operands[1])" 6150 [(clobber (const_int 0))] 6151{ 6152 arm_emit_movpair (operands[0], operands[1]); 6153 DONE; 6154}) 6155 6156;; When generating pic, we need to load the symbol offset into a register. 6157;; So that the optimizer does not confuse this with a normal symbol load 6158;; we use an unspec. The offset will be loaded from a constant pool entry, 6159;; since that is the only type of relocation we can use. 6160 6161;; Wrap calculation of the whole PIC address in a single pattern for the 6162;; benefit of optimizers, particularly, PRE and HOIST. Calculation of 6163;; a PIC address involves two loads from memory, so we want to CSE it 6164;; as often as possible. 6165;; This pattern will be split into one of the pic_load_addr_* patterns 6166;; and a move after GCSE optimizations. 6167;; 6168;; Note: Update arm.c: legitimize_pic_address() when changing this pattern. 6169(define_expand "calculate_pic_address" 6170 [(set (match_operand:SI 0 "register_operand" "") 6171 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "") 6172 (unspec:SI [(match_operand:SI 2 "" "")] 6173 UNSPEC_PIC_SYM))))] 6174 "flag_pic" 6175) 6176 6177;; Split calculate_pic_address into pic_load_addr_* and a move. 6178(define_split 6179 [(set (match_operand:SI 0 "register_operand" "") 6180 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "") 6181 (unspec:SI [(match_operand:SI 2 "" "")] 6182 UNSPEC_PIC_SYM))))] 6183 "flag_pic" 6184 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM)) 6185 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))] 6186 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];" 6187) 6188 6189;; operand1 is the memory address to go into 6190;; pic_load_addr_32bit. 6191;; operand2 is the PIC label to be emitted 6192;; from pic_add_dot_plus_eight. 6193;; We do this to allow hoisting of the entire insn. 6194(define_insn_and_split "pic_load_addr_unified" 6195 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l") 6196 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 6197 (match_operand:SI 2 "" "")] 6198 UNSPEC_PIC_UNIFIED))] 6199 "flag_pic" 6200 "#" 6201 "&& reload_completed" 6202 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM)) 6203 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3) 6204 (match_dup 2)] UNSPEC_PIC_BASE))] 6205 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);" 6206 [(set_attr "type" "load_4,load_4,load_4") 6207 (set_attr "pool_range" "4096,4094,1022") 6208 (set_attr "neg_pool_range" "4084,0,0") 6209 (set_attr "arch" "a,t2,t1") 6210 (set_attr "length" "8,6,4")] 6211) 6212 6213;; The rather odd constraints on the following are to force reload to leave 6214;; the insn alone, and to force the minipool generation pass to then move 6215;; the GOT symbol to memory. 6216 6217(define_insn "pic_load_addr_32bit" 6218 [(set (match_operand:SI 0 "s_register_operand" "=r") 6219 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))] 6220 "TARGET_32BIT && flag_pic" 6221 "ldr%?\\t%0, %1" 6222 [(set_attr "type" "load_4") 6223 (set (attr "pool_range") 6224 (if_then_else (eq_attr "is_thumb" "no") 6225 (const_int 4096) 6226 (const_int 4094))) 6227 (set (attr "neg_pool_range") 6228 (if_then_else (eq_attr "is_thumb" "no") 6229 (const_int 4084) 6230 (const_int 0)))] 6231) 6232 6233(define_insn "pic_load_addr_thumb1" 6234 [(set (match_operand:SI 0 "s_register_operand" "=l") 6235 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))] 6236 "TARGET_THUMB1 && flag_pic" 6237 "ldr\\t%0, %1" 6238 [(set_attr "type" "load_4") 6239 (set (attr "pool_range") (const_int 1018))] 6240) 6241 6242(define_insn "pic_add_dot_plus_four" 6243 [(set (match_operand:SI 0 "register_operand" "=r") 6244 (unspec:SI [(match_operand:SI 1 "register_operand" "0") 6245 (const_int 4) 6246 (match_operand 2 "" "")] 6247 UNSPEC_PIC_BASE))] 6248 "TARGET_THUMB" 6249 "* 6250 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\", 6251 INTVAL (operands[2])); 6252 return \"add\\t%0, %|pc\"; 6253 " 6254 [(set_attr "length" "2") 6255 (set_attr "type" "alu_sreg")] 6256) 6257 6258(define_insn "pic_add_dot_plus_eight" 6259 [(set (match_operand:SI 0 "register_operand" "=r") 6260 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 6261 (const_int 8) 6262 (match_operand 2 "" "")] 6263 UNSPEC_PIC_BASE))] 6264 "TARGET_ARM" 6265 "* 6266 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\", 6267 INTVAL (operands[2])); 6268 return \"add%?\\t%0, %|pc, %1\"; 6269 " 6270 [(set_attr "predicable" "yes") 6271 (set_attr "type" "alu_sreg")] 6272) 6273 6274(define_insn "tls_load_dot_plus_eight" 6275 [(set (match_operand:SI 0 "register_operand" "=r") 6276 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r") 6277 (const_int 8) 6278 (match_operand 2 "" "")] 6279 UNSPEC_PIC_BASE)))] 6280 "TARGET_ARM" 6281 "* 6282 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\", 6283 INTVAL (operands[2])); 6284 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\"; 6285 " 6286 [(set_attr "predicable" "yes") 6287 (set_attr "type" "load_4")] 6288) 6289 6290;; PIC references to local variables can generate pic_add_dot_plus_eight 6291;; followed by a load. These sequences can be crunched down to 6292;; tls_load_dot_plus_eight by a peephole. 6293 6294(define_peephole2 6295 [(set (match_operand:SI 0 "register_operand" "") 6296 (unspec:SI [(match_operand:SI 3 "register_operand" "") 6297 (const_int 8) 6298 (match_operand 1 "" "")] 6299 UNSPEC_PIC_BASE)) 6300 (set (match_operand:SI 2 "arm_general_register_operand" "") 6301 (mem:SI (match_dup 0)))] 6302 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])" 6303 [(set (match_dup 2) 6304 (mem:SI (unspec:SI [(match_dup 3) 6305 (const_int 8) 6306 (match_dup 1)] 6307 UNSPEC_PIC_BASE)))] 6308 "" 6309) 6310 6311(define_insn "pic_offset_arm" 6312 [(set (match_operand:SI 0 "register_operand" "=r") 6313 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 6314 (unspec:SI [(match_operand:SI 2 "" "X")] 6315 UNSPEC_PIC_OFFSET))))] 6316 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic" 6317 "ldr%?\\t%0, [%1,%2]" 6318 [(set_attr "type" "load_4")] 6319) 6320 6321(define_expand "builtin_setjmp_receiver" 6322 [(label_ref (match_operand 0 "" ""))] 6323 "flag_pic" 6324 " 6325{ 6326 /* r3 is clobbered by set/longjmp, so we can use it as a scratch 6327 register. */ 6328 if (arm_pic_register != INVALID_REGNUM) 6329 arm_load_pic_register (1UL << 3, NULL_RTX); 6330 DONE; 6331}") 6332 6333;; If copying one reg to another we can set the condition codes according to 6334;; its value. Such a move is common after a return from subroutine and the 6335;; result is being tested against zero. 6336 6337(define_insn "*movsi_compare0" 6338 [(set (reg:CC CC_REGNUM) 6339 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r") 6340 (const_int 0))) 6341 (set (match_operand:SI 0 "s_register_operand" "=r,r") 6342 (match_dup 1))] 6343 "TARGET_32BIT" 6344 "@ 6345 cmp%?\\t%0, #0 6346 subs%?\\t%0, %1, #0" 6347 [(set_attr "conds" "set") 6348 (set_attr "type" "alus_imm,alus_imm")] 6349) 6350 6351;; Subroutine to store a half word from a register into memory. 6352;; Operand 0 is the source register (HImode) 6353;; Operand 1 is the destination address in a register (SImode) 6354 6355;; In both this routine and the next, we must be careful not to spill 6356;; a memory address of reg+large_const into a separate PLUS insn, since this 6357;; can generate unrecognizable rtl. 6358 6359(define_expand "storehi" 6360 [;; store the low byte 6361 (set (match_operand 1 "" "") (match_dup 3)) 6362 ;; extract the high byte 6363 (set (match_dup 2) 6364 (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) 6365 ;; store the high byte 6366 (set (match_dup 4) (match_dup 5))] 6367 "TARGET_ARM" 6368 " 6369 { 6370 rtx op1 = operands[1]; 6371 rtx addr = XEXP (op1, 0); 6372 enum rtx_code code = GET_CODE (addr); 6373 6374 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1))) 6375 || code == MINUS) 6376 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr)); 6377 6378 operands[4] = adjust_address (op1, QImode, 1); 6379 operands[1] = adjust_address (operands[1], QImode, 0); 6380 operands[3] = gen_lowpart (QImode, operands[0]); 6381 operands[0] = gen_lowpart (SImode, operands[0]); 6382 operands[2] = gen_reg_rtx (SImode); 6383 operands[5] = gen_lowpart (QImode, operands[2]); 6384 }" 6385) 6386 6387(define_expand "storehi_bigend" 6388 [(set (match_dup 4) (match_dup 3)) 6389 (set (match_dup 2) 6390 (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) 6391 (set (match_operand 1 "" "") (match_dup 5))] 6392 "TARGET_ARM" 6393 " 6394 { 6395 rtx op1 = operands[1]; 6396 rtx addr = XEXP (op1, 0); 6397 enum rtx_code code = GET_CODE (addr); 6398 6399 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1))) 6400 || code == MINUS) 6401 op1 = replace_equiv_address (op1, force_reg (SImode, addr)); 6402 6403 operands[4] = adjust_address (op1, QImode, 1); 6404 operands[1] = adjust_address (operands[1], QImode, 0); 6405 operands[3] = gen_lowpart (QImode, operands[0]); 6406 operands[0] = gen_lowpart (SImode, operands[0]); 6407 operands[2] = gen_reg_rtx (SImode); 6408 operands[5] = gen_lowpart (QImode, operands[2]); 6409 }" 6410) 6411 6412;; Subroutine to store a half word integer constant into memory. 6413(define_expand "storeinthi" 6414 [(set (match_operand 0 "" "") 6415 (match_operand 1 "" "")) 6416 (set (match_dup 3) (match_dup 2))] 6417 "TARGET_ARM" 6418 " 6419 { 6420 HOST_WIDE_INT value = INTVAL (operands[1]); 6421 rtx addr = XEXP (operands[0], 0); 6422 rtx op0 = operands[0]; 6423 enum rtx_code code = GET_CODE (addr); 6424 6425 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1))) 6426 || code == MINUS) 6427 op0 = replace_equiv_address (op0, force_reg (SImode, addr)); 6428 6429 operands[1] = gen_reg_rtx (SImode); 6430 if (BYTES_BIG_ENDIAN) 6431 { 6432 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255))); 6433 if ((value & 255) == ((value >> 8) & 255)) 6434 operands[2] = operands[1]; 6435 else 6436 { 6437 operands[2] = gen_reg_rtx (SImode); 6438 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255))); 6439 } 6440 } 6441 else 6442 { 6443 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255))); 6444 if ((value & 255) == ((value >> 8) & 255)) 6445 operands[2] = operands[1]; 6446 else 6447 { 6448 operands[2] = gen_reg_rtx (SImode); 6449 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255))); 6450 } 6451 } 6452 6453 operands[3] = adjust_address (op0, QImode, 1); 6454 operands[0] = adjust_address (operands[0], QImode, 0); 6455 operands[2] = gen_lowpart (QImode, operands[2]); 6456 operands[1] = gen_lowpart (QImode, operands[1]); 6457 }" 6458) 6459 6460(define_expand "storehi_single_op" 6461 [(set (match_operand:HI 0 "memory_operand" "") 6462 (match_operand:HI 1 "general_operand" ""))] 6463 "TARGET_32BIT && arm_arch4" 6464 " 6465 if (!s_register_operand (operands[1], HImode)) 6466 operands[1] = copy_to_mode_reg (HImode, operands[1]); 6467 " 6468) 6469 6470(define_expand "movhi" 6471 [(set (match_operand:HI 0 "general_operand" "") 6472 (match_operand:HI 1 "general_operand" ""))] 6473 "TARGET_EITHER" 6474 " 6475 if (TARGET_ARM) 6476 { 6477 if (can_create_pseudo_p ()) 6478 { 6479 if (MEM_P (operands[0])) 6480 { 6481 if (arm_arch4) 6482 { 6483 emit_insn (gen_storehi_single_op (operands[0], operands[1])); 6484 DONE; 6485 } 6486 if (CONST_INT_P (operands[1])) 6487 emit_insn (gen_storeinthi (operands[0], operands[1])); 6488 else 6489 { 6490 if (MEM_P (operands[1])) 6491 operands[1] = force_reg (HImode, operands[1]); 6492 if (BYTES_BIG_ENDIAN) 6493 emit_insn (gen_storehi_bigend (operands[1], operands[0])); 6494 else 6495 emit_insn (gen_storehi (operands[1], operands[0])); 6496 } 6497 DONE; 6498 } 6499 /* Sign extend a constant, and keep it in an SImode reg. */ 6500 else if (CONST_INT_P (operands[1])) 6501 { 6502 rtx reg = gen_reg_rtx (SImode); 6503 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff; 6504 6505 /* If the constant is already valid, leave it alone. */ 6506 if (!const_ok_for_arm (val)) 6507 { 6508 /* If setting all the top bits will make the constant 6509 loadable in a single instruction, then set them. 6510 Otherwise, sign extend the number. */ 6511 6512 if (const_ok_for_arm (~(val | ~0xffff))) 6513 val |= ~0xffff; 6514 else if (val & 0x8000) 6515 val |= ~0xffff; 6516 } 6517 6518 emit_insn (gen_movsi (reg, GEN_INT (val))); 6519 operands[1] = gen_lowpart (HImode, reg); 6520 } 6521 else if (arm_arch4 && optimize && can_create_pseudo_p () 6522 && MEM_P (operands[1])) 6523 { 6524 rtx reg = gen_reg_rtx (SImode); 6525 6526 emit_insn (gen_zero_extendhisi2 (reg, operands[1])); 6527 operands[1] = gen_lowpart (HImode, reg); 6528 } 6529 else if (!arm_arch4) 6530 { 6531 if (MEM_P (operands[1])) 6532 { 6533 rtx base; 6534 rtx offset = const0_rtx; 6535 rtx reg = gen_reg_rtx (SImode); 6536 6537 if ((REG_P (base = XEXP (operands[1], 0)) 6538 || (GET_CODE (base) == PLUS 6539 && (CONST_INT_P (offset = XEXP (base, 1))) 6540 && ((INTVAL(offset) & 1) != 1) 6541 && REG_P (base = XEXP (base, 0)))) 6542 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32) 6543 { 6544 rtx new_rtx; 6545 6546 new_rtx = widen_memory_access (operands[1], SImode, 6547 ((INTVAL (offset) & ~3) 6548 - INTVAL (offset))); 6549 emit_insn (gen_movsi (reg, new_rtx)); 6550 if (((INTVAL (offset) & 2) != 0) 6551 ^ (BYTES_BIG_ENDIAN ? 1 : 0)) 6552 { 6553 rtx reg2 = gen_reg_rtx (SImode); 6554 6555 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16))); 6556 reg = reg2; 6557 } 6558 } 6559 else 6560 emit_insn (gen_movhi_bytes (reg, operands[1])); 6561 6562 operands[1] = gen_lowpart (HImode, reg); 6563 } 6564 } 6565 } 6566 /* Handle loading a large integer during reload. */ 6567 else if (CONST_INT_P (operands[1]) 6568 && !const_ok_for_arm (INTVAL (operands[1])) 6569 && !const_ok_for_arm (~INTVAL (operands[1]))) 6570 { 6571 /* Writing a constant to memory needs a scratch, which should 6572 be handled with SECONDARY_RELOADs. */ 6573 gcc_assert (REG_P (operands[0])); 6574 6575 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); 6576 emit_insn (gen_movsi (operands[0], operands[1])); 6577 DONE; 6578 } 6579 } 6580 else if (TARGET_THUMB2) 6581 { 6582 /* Thumb-2 can do everything except mem=mem and mem=const easily. */ 6583 if (can_create_pseudo_p ()) 6584 { 6585 if (!REG_P (operands[0])) 6586 operands[1] = force_reg (HImode, operands[1]); 6587 /* Zero extend a constant, and keep it in an SImode reg. */ 6588 else if (CONST_INT_P (operands[1])) 6589 { 6590 rtx reg = gen_reg_rtx (SImode); 6591 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff; 6592 6593 emit_insn (gen_movsi (reg, GEN_INT (val))); 6594 operands[1] = gen_lowpart (HImode, reg); 6595 } 6596 } 6597 } 6598 else /* TARGET_THUMB1 */ 6599 { 6600 if (can_create_pseudo_p ()) 6601 { 6602 if (CONST_INT_P (operands[1])) 6603 { 6604 rtx reg = gen_reg_rtx (SImode); 6605 6606 emit_insn (gen_movsi (reg, operands[1])); 6607 operands[1] = gen_lowpart (HImode, reg); 6608 } 6609 6610 /* ??? We shouldn't really get invalid addresses here, but this can 6611 happen if we are passed a SP (never OK for HImode/QImode) or 6612 virtual register (also rejected as illegitimate for HImode/QImode) 6613 relative address. */ 6614 /* ??? This should perhaps be fixed elsewhere, for instance, in 6615 fixup_stack_1, by checking for other kinds of invalid addresses, 6616 e.g. a bare reference to a virtual register. This may confuse the 6617 alpha though, which must handle this case differently. */ 6618 if (MEM_P (operands[0]) 6619 && !memory_address_p (GET_MODE (operands[0]), 6620 XEXP (operands[0], 0))) 6621 operands[0] 6622 = replace_equiv_address (operands[0], 6623 copy_to_reg (XEXP (operands[0], 0))); 6624 6625 if (MEM_P (operands[1]) 6626 && !memory_address_p (GET_MODE (operands[1]), 6627 XEXP (operands[1], 0))) 6628 operands[1] 6629 = replace_equiv_address (operands[1], 6630 copy_to_reg (XEXP (operands[1], 0))); 6631 6632 if (MEM_P (operands[1]) && optimize > 0) 6633 { 6634 rtx reg = gen_reg_rtx (SImode); 6635 6636 emit_insn (gen_zero_extendhisi2 (reg, operands[1])); 6637 operands[1] = gen_lowpart (HImode, reg); 6638 } 6639 6640 if (MEM_P (operands[0])) 6641 operands[1] = force_reg (HImode, operands[1]); 6642 } 6643 else if (CONST_INT_P (operands[1]) 6644 && !satisfies_constraint_I (operands[1])) 6645 { 6646 /* Handle loading a large integer during reload. */ 6647 6648 /* Writing a constant to memory needs a scratch, which should 6649 be handled with SECONDARY_RELOADs. */ 6650 gcc_assert (REG_P (operands[0])); 6651 6652 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); 6653 emit_insn (gen_movsi (operands[0], operands[1])); 6654 DONE; 6655 } 6656 } 6657 " 6658) 6659 6660(define_expand "movhi_bytes" 6661 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" ""))) 6662 (set (match_dup 3) 6663 (zero_extend:SI (match_dup 6))) 6664 (set (match_operand:SI 0 "" "") 6665 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))] 6666 "TARGET_ARM" 6667 " 6668 { 6669 rtx mem1, mem2; 6670 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 6671 6672 mem1 = change_address (operands[1], QImode, addr); 6673 mem2 = change_address (operands[1], QImode, 6674 plus_constant (Pmode, addr, 1)); 6675 operands[0] = gen_lowpart (SImode, operands[0]); 6676 operands[1] = mem1; 6677 operands[2] = gen_reg_rtx (SImode); 6678 operands[3] = gen_reg_rtx (SImode); 6679 operands[6] = mem2; 6680 6681 if (BYTES_BIG_ENDIAN) 6682 { 6683 operands[4] = operands[2]; 6684 operands[5] = operands[3]; 6685 } 6686 else 6687 { 6688 operands[4] = operands[3]; 6689 operands[5] = operands[2]; 6690 } 6691 }" 6692) 6693 6694(define_expand "movhi_bigend" 6695 [(set (match_dup 2) 6696 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0) 6697 (const_int 16))) 6698 (set (match_dup 3) 6699 (ashiftrt:SI (match_dup 2) (const_int 16))) 6700 (set (match_operand:HI 0 "s_register_operand" "") 6701 (match_dup 4))] 6702 "TARGET_ARM" 6703 " 6704 operands[2] = gen_reg_rtx (SImode); 6705 operands[3] = gen_reg_rtx (SImode); 6706 operands[4] = gen_lowpart (HImode, operands[3]); 6707 " 6708) 6709 6710;; Pattern to recognize insn generated default case above 6711(define_insn "*movhi_insn_arch4" 6712 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r") 6713 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))] 6714 "TARGET_ARM 6715 && arm_arch4 && !TARGET_HARD_FLOAT 6716 && (register_operand (operands[0], HImode) 6717 || register_operand (operands[1], HImode))" 6718 "@ 6719 mov%?\\t%0, %1\\t%@ movhi 6720 mvn%?\\t%0, #%B1\\t%@ movhi 6721 movw%?\\t%0, %L1\\t%@ movhi 6722 strh%?\\t%1, %0\\t%@ movhi 6723 ldrh%?\\t%0, %1\\t%@ movhi" 6724 [(set_attr "predicable" "yes") 6725 (set_attr "pool_range" "*,*,*,*,256") 6726 (set_attr "neg_pool_range" "*,*,*,*,244") 6727 (set_attr "arch" "*,*,v6t2,*,*") 6728 (set_attr_alternative "type" 6729 [(if_then_else (match_operand 1 "const_int_operand" "") 6730 (const_string "mov_imm" ) 6731 (const_string "mov_reg")) 6732 (const_string "mvn_imm") 6733 (const_string "mov_imm") 6734 (const_string "store_4") 6735 (const_string "load_4")])] 6736) 6737 6738(define_insn "*movhi_bytes" 6739 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r") 6740 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))] 6741 "TARGET_ARM && !TARGET_HARD_FLOAT" 6742 "@ 6743 mov%?\\t%0, %1\\t%@ movhi 6744 mov%?\\t%0, %1\\t%@ movhi 6745 mvn%?\\t%0, #%B1\\t%@ movhi" 6746 [(set_attr "predicable" "yes") 6747 (set_attr "type" "mov_imm,mov_reg,mvn_imm")] 6748) 6749 6750;; We use a DImode scratch because we may occasionally need an additional 6751;; temporary if the address isn't offsettable -- push_reload doesn't seem 6752;; to take any notice of the "o" constraints on reload_memory_operand operand. 6753(define_expand "reload_outhi" 6754 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o") 6755 (match_operand:HI 1 "s_register_operand" "r") 6756 (match_operand:DI 2 "s_register_operand" "=&l")])] 6757 "TARGET_EITHER" 6758 "if (TARGET_ARM) 6759 arm_reload_out_hi (operands); 6760 else 6761 thumb_reload_out_hi (operands); 6762 DONE; 6763 " 6764) 6765 6766(define_expand "reload_inhi" 6767 [(parallel [(match_operand:HI 0 "s_register_operand" "=r") 6768 (match_operand:HI 1 "arm_reload_memory_operand" "o") 6769 (match_operand:DI 2 "s_register_operand" "=&r")])] 6770 "TARGET_EITHER" 6771 " 6772 if (TARGET_ARM) 6773 arm_reload_in_hi (operands); 6774 else 6775 thumb_reload_out_hi (operands); 6776 DONE; 6777") 6778 6779(define_expand "movqi" 6780 [(set (match_operand:QI 0 "general_operand" "") 6781 (match_operand:QI 1 "general_operand" ""))] 6782 "TARGET_EITHER" 6783 " 6784 /* Everything except mem = const or mem = mem can be done easily */ 6785 6786 if (can_create_pseudo_p ()) 6787 { 6788 if (CONST_INT_P (operands[1])) 6789 { 6790 rtx reg = gen_reg_rtx (SImode); 6791 6792 /* For thumb we want an unsigned immediate, then we are more likely 6793 to be able to use a movs insn. */ 6794 if (TARGET_THUMB) 6795 operands[1] = GEN_INT (INTVAL (operands[1]) & 255); 6796 6797 emit_insn (gen_movsi (reg, operands[1])); 6798 operands[1] = gen_lowpart (QImode, reg); 6799 } 6800 6801 if (TARGET_THUMB) 6802 { 6803 /* ??? We shouldn't really get invalid addresses here, but this can 6804 happen if we are passed a SP (never OK for HImode/QImode) or 6805 virtual register (also rejected as illegitimate for HImode/QImode) 6806 relative address. */ 6807 /* ??? This should perhaps be fixed elsewhere, for instance, in 6808 fixup_stack_1, by checking for other kinds of invalid addresses, 6809 e.g. a bare reference to a virtual register. This may confuse the 6810 alpha though, which must handle this case differently. */ 6811 if (MEM_P (operands[0]) 6812 && !memory_address_p (GET_MODE (operands[0]), 6813 XEXP (operands[0], 0))) 6814 operands[0] 6815 = replace_equiv_address (operands[0], 6816 copy_to_reg (XEXP (operands[0], 0))); 6817 if (MEM_P (operands[1]) 6818 && !memory_address_p (GET_MODE (operands[1]), 6819 XEXP (operands[1], 0))) 6820 operands[1] 6821 = replace_equiv_address (operands[1], 6822 copy_to_reg (XEXP (operands[1], 0))); 6823 } 6824 6825 if (MEM_P (operands[1]) && optimize > 0) 6826 { 6827 rtx reg = gen_reg_rtx (SImode); 6828 6829 emit_insn (gen_zero_extendqisi2 (reg, operands[1])); 6830 operands[1] = gen_lowpart (QImode, reg); 6831 } 6832 6833 if (MEM_P (operands[0])) 6834 operands[1] = force_reg (QImode, operands[1]); 6835 } 6836 else if (TARGET_THUMB 6837 && CONST_INT_P (operands[1]) 6838 && !satisfies_constraint_I (operands[1])) 6839 { 6840 /* Handle loading a large integer during reload. */ 6841 6842 /* Writing a constant to memory needs a scratch, which should 6843 be handled with SECONDARY_RELOADs. */ 6844 gcc_assert (REG_P (operands[0])); 6845 6846 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); 6847 emit_insn (gen_movsi (operands[0], operands[1])); 6848 DONE; 6849 } 6850 " 6851) 6852 6853(define_insn "*arm_movqi_insn" 6854 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m") 6855 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))] 6856 "TARGET_32BIT 6857 && ( register_operand (operands[0], QImode) 6858 || register_operand (operands[1], QImode))" 6859 "@ 6860 mov%?\\t%0, %1 6861 mov%?\\t%0, %1 6862 mov%?\\t%0, %1 6863 mov%?\\t%0, %1 6864 mvn%?\\t%0, #%B1 6865 ldrb%?\\t%0, %1 6866 strb%?\\t%1, %0 6867 ldrb%?\\t%0, %1 6868 strb%?\\t%1, %0" 6869 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4") 6870 (set_attr "predicable" "yes") 6871 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no") 6872 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any") 6873 (set_attr "length" "2,4,4,2,4,2,2,4,4")] 6874) 6875 6876;; HFmode moves 6877(define_expand "movhf" 6878 [(set (match_operand:HF 0 "general_operand" "") 6879 (match_operand:HF 1 "general_operand" ""))] 6880 "TARGET_EITHER" 6881 " 6882 if (TARGET_32BIT) 6883 { 6884 if (MEM_P (operands[0])) 6885 operands[1] = force_reg (HFmode, operands[1]); 6886 } 6887 else /* TARGET_THUMB1 */ 6888 { 6889 if (can_create_pseudo_p ()) 6890 { 6891 if (!REG_P (operands[0])) 6892 operands[1] = force_reg (HFmode, operands[1]); 6893 } 6894 } 6895 " 6896) 6897 6898(define_insn "*arm32_movhf" 6899 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r") 6900 (match_operand:HF 1 "general_operand" " m,r,r,F"))] 6901 "TARGET_32BIT && !TARGET_HARD_FLOAT 6902 && ( s_register_operand (operands[0], HFmode) 6903 || s_register_operand (operands[1], HFmode))" 6904 "* 6905 switch (which_alternative) 6906 { 6907 case 0: /* ARM register from memory */ 6908 return \"ldrh%?\\t%0, %1\\t%@ __fp16\"; 6909 case 1: /* memory from ARM register */ 6910 return \"strh%?\\t%1, %0\\t%@ __fp16\"; 6911 case 2: /* ARM register from ARM register */ 6912 return \"mov%?\\t%0, %1\\t%@ __fp16\"; 6913 case 3: /* ARM register from constant */ 6914 { 6915 long bits; 6916 rtx ops[4]; 6917 6918 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), 6919 HFmode); 6920 ops[0] = operands[0]; 6921 ops[1] = GEN_INT (bits); 6922 ops[2] = GEN_INT (bits & 0xff00); 6923 ops[3] = GEN_INT (bits & 0x00ff); 6924 6925 if (arm_arch_thumb2) 6926 output_asm_insn (\"movw%?\\t%0, %1\", ops); 6927 else 6928 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops); 6929 return \"\"; 6930 } 6931 default: 6932 gcc_unreachable (); 6933 } 6934 " 6935 [(set_attr "conds" "unconditional") 6936 (set_attr "type" "load_4,store_4,mov_reg,multiple") 6937 (set_attr "length" "4,4,4,8") 6938 (set_attr "predicable" "yes")] 6939) 6940 6941(define_expand "movsf" 6942 [(set (match_operand:SF 0 "general_operand" "") 6943 (match_operand:SF 1 "general_operand" ""))] 6944 "TARGET_EITHER" 6945 " 6946 if (TARGET_32BIT) 6947 { 6948 if (MEM_P (operands[0])) 6949 operands[1] = force_reg (SFmode, operands[1]); 6950 } 6951 else /* TARGET_THUMB1 */ 6952 { 6953 if (can_create_pseudo_p ()) 6954 { 6955 if (!REG_P (operands[0])) 6956 operands[1] = force_reg (SFmode, operands[1]); 6957 } 6958 } 6959 6960 /* Cannot load it directly, generate a load with clobber so that it can be 6961 loaded via GPR with MOV / MOVT. */ 6962 if (arm_disable_literal_pool 6963 && (REG_P (operands[0]) || SUBREG_P (operands[0])) 6964 && CONST_DOUBLE_P (operands[1]) 6965 && TARGET_HARD_FLOAT 6966 && !vfp3_const_double_rtx (operands[1])) 6967 { 6968 rtx clobreg = gen_reg_rtx (SFmode); 6969 emit_insn (gen_no_literal_pool_sf_immediate (operands[0], operands[1], 6970 clobreg)); 6971 DONE; 6972 } 6973 " 6974) 6975 6976;; Transform a floating-point move of a constant into a core register into 6977;; an SImode operation. 6978(define_split 6979 [(set (match_operand:SF 0 "arm_general_register_operand" "") 6980 (match_operand:SF 1 "immediate_operand" ""))] 6981 "TARGET_EITHER 6982 && reload_completed 6983 && CONST_DOUBLE_P (operands[1])" 6984 [(set (match_dup 2) (match_dup 3))] 6985 " 6986 operands[2] = gen_lowpart (SImode, operands[0]); 6987 operands[3] = gen_lowpart (SImode, operands[1]); 6988 if (operands[2] == 0 || operands[3] == 0) 6989 FAIL; 6990 " 6991) 6992 6993(define_insn "*arm_movsf_soft_insn" 6994 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m") 6995 (match_operand:SF 1 "general_operand" "r,mE,r"))] 6996 "TARGET_32BIT 6997 && TARGET_SOFT_FLOAT 6998 && (!MEM_P (operands[0]) 6999 || register_operand (operands[1], SFmode))" 7000{ 7001 switch (which_alternative) 7002 { 7003 case 0: return \"mov%?\\t%0, %1\"; 7004 case 1: 7005 /* Cannot load it directly, split to load it via MOV / MOVT. */ 7006 if (!MEM_P (operands[1]) && arm_disable_literal_pool) 7007 return \"#\"; 7008 return \"ldr%?\\t%0, %1\\t%@ float\"; 7009 case 2: return \"str%?\\t%1, %0\\t%@ float\"; 7010 default: gcc_unreachable (); 7011 } 7012} 7013 [(set_attr "predicable" "yes") 7014 (set_attr "type" "mov_reg,load_4,store_4") 7015 (set_attr "arm_pool_range" "*,4096,*") 7016 (set_attr "thumb2_pool_range" "*,4094,*") 7017 (set_attr "arm_neg_pool_range" "*,4084,*") 7018 (set_attr "thumb2_neg_pool_range" "*,0,*")] 7019) 7020 7021;; Splitter for the above. 7022(define_split 7023 [(set (match_operand:SF 0 "s_register_operand") 7024 (match_operand:SF 1 "const_double_operand"))] 7025 "arm_disable_literal_pool && TARGET_SOFT_FLOAT" 7026 [(const_int 0)] 7027{ 7028 long buf; 7029 real_to_target (&buf, CONST_DOUBLE_REAL_VALUE (operands[1]), SFmode); 7030 rtx cst = gen_int_mode (buf, SImode); 7031 emit_move_insn (simplify_gen_subreg (SImode, operands[0], SFmode, 0), cst); 7032 DONE; 7033} 7034) 7035 7036(define_expand "movdf" 7037 [(set (match_operand:DF 0 "general_operand" "") 7038 (match_operand:DF 1 "general_operand" ""))] 7039 "TARGET_EITHER" 7040 " 7041 if (TARGET_32BIT) 7042 { 7043 if (MEM_P (operands[0])) 7044 operands[1] = force_reg (DFmode, operands[1]); 7045 } 7046 else /* TARGET_THUMB */ 7047 { 7048 if (can_create_pseudo_p ()) 7049 { 7050 if (!REG_P (operands[0])) 7051 operands[1] = force_reg (DFmode, operands[1]); 7052 } 7053 } 7054 7055 /* Cannot load it directly, generate a load with clobber so that it can be 7056 loaded via GPR with MOV / MOVT. */ 7057 if (arm_disable_literal_pool 7058 && (REG_P (operands[0]) || SUBREG_P (operands[0])) 7059 && CONSTANT_P (operands[1]) 7060 && TARGET_HARD_FLOAT 7061 && !arm_const_double_rtx (operands[1]) 7062 && !(TARGET_VFP_DOUBLE && vfp3_const_double_rtx (operands[1]))) 7063 { 7064 rtx clobreg = gen_reg_rtx (DFmode); 7065 emit_insn (gen_no_literal_pool_df_immediate (operands[0], operands[1], 7066 clobreg)); 7067 DONE; 7068 } 7069 " 7070) 7071 7072;; Reloading a df mode value stored in integer regs to memory can require a 7073;; scratch reg. 7074(define_expand "reload_outdf" 7075 [(match_operand:DF 0 "arm_reload_memory_operand" "=o") 7076 (match_operand:DF 1 "s_register_operand" "r") 7077 (match_operand:SI 2 "s_register_operand" "=&r")] 7078 "TARGET_THUMB2" 7079 " 7080 { 7081 enum rtx_code code = GET_CODE (XEXP (operands[0], 0)); 7082 7083 if (code == REG) 7084 operands[2] = XEXP (operands[0], 0); 7085 else if (code == POST_INC || code == PRE_DEC) 7086 { 7087 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0); 7088 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0); 7089 emit_insn (gen_movdi (operands[0], operands[1])); 7090 DONE; 7091 } 7092 else if (code == PRE_INC) 7093 { 7094 rtx reg = XEXP (XEXP (operands[0], 0), 0); 7095 7096 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8))); 7097 operands[2] = reg; 7098 } 7099 else if (code == POST_DEC) 7100 operands[2] = XEXP (XEXP (operands[0], 0), 0); 7101 else 7102 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0), 7103 XEXP (XEXP (operands[0], 0), 1))); 7104 7105 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]), 7106 operands[1])); 7107 7108 if (code == POST_DEC) 7109 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8))); 7110 7111 DONE; 7112 }" 7113) 7114 7115(define_insn "*movdf_soft_insn" 7116 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,r,m") 7117 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,r"))] 7118 "TARGET_32BIT && TARGET_SOFT_FLOAT 7119 && ( register_operand (operands[0], DFmode) 7120 || register_operand (operands[1], DFmode))" 7121 "* 7122 switch (which_alternative) 7123 { 7124 case 0: 7125 case 1: 7126 case 2: 7127 return \"#\"; 7128 case 3: 7129 /* Cannot load it directly, split to load it via MOV / MOVT. */ 7130 if (!MEM_P (operands[1]) && arm_disable_literal_pool) 7131 return \"#\"; 7132 /* Fall through. */ 7133 default: 7134 return output_move_double (operands, true, NULL); 7135 } 7136 " 7137 [(set_attr "length" "8,12,16,8,8") 7138 (set_attr "type" "multiple,multiple,multiple,load_8,store_8") 7139 (set_attr "arm_pool_range" "*,*,*,1020,*") 7140 (set_attr "thumb2_pool_range" "*,*,*,1018,*") 7141 (set_attr "arm_neg_pool_range" "*,*,*,1004,*") 7142 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")] 7143) 7144 7145;; Splitter for the above. 7146(define_split 7147 [(set (match_operand:DF 0 "s_register_operand") 7148 (match_operand:DF 1 "const_double_operand"))] 7149 "arm_disable_literal_pool && TARGET_SOFT_FLOAT" 7150 [(const_int 0)] 7151{ 7152 long buf[2]; 7153 int order = BYTES_BIG_ENDIAN ? 1 : 0; 7154 real_to_target (buf, CONST_DOUBLE_REAL_VALUE (operands[1]), DFmode); 7155 unsigned HOST_WIDE_INT ival = zext_hwi (buf[order], 32); 7156 ival |= (zext_hwi (buf[1 - order], 32) << 32); 7157 rtx cst = gen_int_mode (ival, DImode); 7158 emit_move_insn (simplify_gen_subreg (DImode, operands[0], DFmode, 0), cst); 7159 DONE; 7160} 7161) 7162 7163 7164;; load- and store-multiple insns 7165;; The arm can load/store any set of registers, provided that they are in 7166;; ascending order, but these expanders assume a contiguous set. 7167 7168(define_expand "load_multiple" 7169 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 7170 (match_operand:SI 1 "" "")) 7171 (use (match_operand:SI 2 "" ""))])] 7172 "TARGET_32BIT" 7173{ 7174 HOST_WIDE_INT offset = 0; 7175 7176 /* Support only fixed point registers. */ 7177 if (!CONST_INT_P (operands[2]) 7178 || INTVAL (operands[2]) > MAX_LDM_STM_OPS 7179 || INTVAL (operands[2]) < 2 7180 || !MEM_P (operands[1]) 7181 || !REG_P (operands[0]) 7182 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1) 7183 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM) 7184 FAIL; 7185 7186 operands[3] 7187 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]), 7188 INTVAL (operands[2]), 7189 force_reg (SImode, XEXP (operands[1], 0)), 7190 FALSE, operands[1], &offset); 7191}) 7192 7193(define_expand "store_multiple" 7194 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 7195 (match_operand:SI 1 "" "")) 7196 (use (match_operand:SI 2 "" ""))])] 7197 "TARGET_32BIT" 7198{ 7199 HOST_WIDE_INT offset = 0; 7200 7201 /* Support only fixed point registers. */ 7202 if (!CONST_INT_P (operands[2]) 7203 || INTVAL (operands[2]) > MAX_LDM_STM_OPS 7204 || INTVAL (operands[2]) < 2 7205 || !REG_P (operands[1]) 7206 || !MEM_P (operands[0]) 7207 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1) 7208 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM) 7209 FAIL; 7210 7211 operands[3] 7212 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]), 7213 INTVAL (operands[2]), 7214 force_reg (SImode, XEXP (operands[0], 0)), 7215 FALSE, operands[0], &offset); 7216}) 7217 7218 7219(define_expand "setmemsi" 7220 [(match_operand:BLK 0 "general_operand" "") 7221 (match_operand:SI 1 "const_int_operand" "") 7222 (match_operand:SI 2 "const_int_operand" "") 7223 (match_operand:SI 3 "const_int_operand" "")] 7224 "TARGET_32BIT" 7225{ 7226 if (arm_gen_setmem (operands)) 7227 DONE; 7228 7229 FAIL; 7230}) 7231 7232 7233;; Move a block of memory if it is word aligned and MORE than 2 words long. 7234;; We could let this apply for blocks of less than this, but it clobbers so 7235;; many registers that there is then probably a better way. 7236 7237(define_expand "movmemqi" 7238 [(match_operand:BLK 0 "general_operand" "") 7239 (match_operand:BLK 1 "general_operand" "") 7240 (match_operand:SI 2 "const_int_operand" "") 7241 (match_operand:SI 3 "const_int_operand" "")] 7242 "" 7243 " 7244 if (TARGET_32BIT) 7245 { 7246 if (TARGET_LDRD && current_tune->prefer_ldrd_strd 7247 && !optimize_function_for_size_p (cfun)) 7248 { 7249 if (gen_movmem_ldrd_strd (operands)) 7250 DONE; 7251 FAIL; 7252 } 7253 7254 if (arm_gen_movmemqi (operands)) 7255 DONE; 7256 FAIL; 7257 } 7258 else /* TARGET_THUMB1 */ 7259 { 7260 if ( INTVAL (operands[3]) != 4 7261 || INTVAL (operands[2]) > 48) 7262 FAIL; 7263 7264 thumb_expand_movmemqi (operands); 7265 DONE; 7266 } 7267 " 7268) 7269 7270 7271;; Compare & branch insns 7272;; The range calculations are based as follows: 7273;; For forward branches, the address calculation returns the address of 7274;; the next instruction. This is 2 beyond the branch instruction. 7275;; For backward branches, the address calculation returns the address of 7276;; the first instruction in this pattern (cmp). This is 2 before the branch 7277;; instruction for the shortest sequence, and 4 before the branch instruction 7278;; if we have to jump around an unconditional branch. 7279;; To the basic branch range the PC offset must be added (this is +4). 7280;; So for forward branches we have 7281;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4). 7282;; And for backward branches we have 7283;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4). 7284;; 7285;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048). 7286;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256). 7287 7288(define_expand "cbranchsi4" 7289 [(set (pc) (if_then_else 7290 (match_operator 0 "expandable_comparison_operator" 7291 [(match_operand:SI 1 "s_register_operand" "") 7292 (match_operand:SI 2 "nonmemory_operand" "")]) 7293 (label_ref (match_operand 3 "" "")) 7294 (pc)))] 7295 "TARGET_EITHER" 7296 " 7297 if (!TARGET_THUMB1) 7298 { 7299 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2])) 7300 FAIL; 7301 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7302 operands[3])); 7303 DONE; 7304 } 7305 if (thumb1_cmpneg_operand (operands[2], SImode)) 7306 { 7307 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2], 7308 operands[3], operands[0])); 7309 DONE; 7310 } 7311 if (!thumb1_cmp_operand (operands[2], SImode)) 7312 operands[2] = force_reg (SImode, operands[2]); 7313 ") 7314 7315(define_expand "cbranchsf4" 7316 [(set (pc) (if_then_else 7317 (match_operator 0 "expandable_comparison_operator" 7318 [(match_operand:SF 1 "s_register_operand" "") 7319 (match_operand:SF 2 "vfp_compare_operand" "")]) 7320 (label_ref (match_operand 3 "" "")) 7321 (pc)))] 7322 "TARGET_32BIT && TARGET_HARD_FLOAT" 7323 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7324 operands[3])); DONE;" 7325) 7326 7327(define_expand "cbranchdf4" 7328 [(set (pc) (if_then_else 7329 (match_operator 0 "expandable_comparison_operator" 7330 [(match_operand:DF 1 "s_register_operand" "") 7331 (match_operand:DF 2 "vfp_compare_operand" "")]) 7332 (label_ref (match_operand 3 "" "")) 7333 (pc)))] 7334 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 7335 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7336 operands[3])); DONE;" 7337) 7338 7339(define_expand "cbranchdi4" 7340 [(set (pc) (if_then_else 7341 (match_operator 0 "expandable_comparison_operator" 7342 [(match_operand:DI 1 "s_register_operand" "") 7343 (match_operand:DI 2 "cmpdi_operand" "")]) 7344 (label_ref (match_operand 3 "" "")) 7345 (pc)))] 7346 "TARGET_32BIT" 7347 "{ 7348 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2])) 7349 FAIL; 7350 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7351 operands[3])); 7352 DONE; 7353 }" 7354) 7355 7356;; Comparison and test insns 7357 7358(define_insn "*arm_cmpsi_insn" 7359 [(set (reg:CC CC_REGNUM) 7360 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r") 7361 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))] 7362 "TARGET_32BIT" 7363 "@ 7364 cmp%?\\t%0, %1 7365 cmp%?\\t%0, %1 7366 cmp%?\\t%0, %1 7367 cmp%?\\t%0, %1 7368 cmn%?\\t%0, #%n1" 7369 [(set_attr "conds" "set") 7370 (set_attr "arch" "t2,t2,any,any,any") 7371 (set_attr "length" "2,2,4,4,4") 7372 (set_attr "predicable" "yes") 7373 (set_attr "predicable_short_it" "yes,yes,yes,no,no") 7374 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")] 7375) 7376 7377(define_insn "*cmpsi_shiftsi" 7378 [(set (reg:CC CC_REGNUM) 7379 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r") 7380 (match_operator:SI 3 "shift_operator" 7381 [(match_operand:SI 1 "s_register_operand" "r,r,r") 7382 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))] 7383 "TARGET_32BIT" 7384 "cmp\\t%0, %1%S3" 7385 [(set_attr "conds" "set") 7386 (set_attr "shift" "1") 7387 (set_attr "arch" "32,a,a") 7388 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 7389 7390(define_insn "*cmpsi_shiftsi_swp" 7391 [(set (reg:CC_SWP CC_REGNUM) 7392 (compare:CC_SWP (match_operator:SI 3 "shift_operator" 7393 [(match_operand:SI 1 "s_register_operand" "r,r,r") 7394 (match_operand:SI 2 "shift_amount_operand" "M,r,M")]) 7395 (match_operand:SI 0 "s_register_operand" "r,r,r")))] 7396 "TARGET_32BIT" 7397 "cmp%?\\t%0, %1%S3" 7398 [(set_attr "conds" "set") 7399 (set_attr "shift" "1") 7400 (set_attr "arch" "32,a,a") 7401 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 7402 7403(define_insn "*arm_cmpsi_negshiftsi_si" 7404 [(set (reg:CC_Z CC_REGNUM) 7405 (compare:CC_Z 7406 (neg:SI (match_operator:SI 1 "shift_operator" 7407 [(match_operand:SI 2 "s_register_operand" "r") 7408 (match_operand:SI 3 "reg_or_int_operand" "rM")])) 7409 (match_operand:SI 0 "s_register_operand" "r")))] 7410 "TARGET_ARM" 7411 "cmn%?\\t%0, %2%S1" 7412 [(set_attr "conds" "set") 7413 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") 7414 (const_string "alus_shift_imm") 7415 (const_string "alus_shift_reg"))) 7416 (set_attr "predicable" "yes")] 7417) 7418 7419;; DImode comparisons. The generic code generates branches that 7420;; if-conversion cannot reduce to a conditional compare, so we do 7421;; that directly. 7422 7423(define_insn_and_split "*arm_cmpdi_insn" 7424 [(set (reg:CC_NCV CC_REGNUM) 7425 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r") 7426 (match_operand:DI 1 "arm_di_operand" "rDi"))) 7427 (clobber (match_scratch:SI 2 "=r"))] 7428 "TARGET_32BIT" 7429 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1" 7430 "&& reload_completed" 7431 [(set (reg:CC CC_REGNUM) 7432 (compare:CC (match_dup 0) (match_dup 1))) 7433 (parallel [(set (reg:CC CC_REGNUM) 7434 (compare:CC (match_dup 3) (match_dup 4))) 7435 (set (match_dup 2) 7436 (minus:SI (match_dup 5) 7437 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])] 7438 { 7439 operands[3] = gen_highpart (SImode, operands[0]); 7440 operands[0] = gen_lowpart (SImode, operands[0]); 7441 if (CONST_INT_P (operands[1])) 7442 { 7443 operands[4] = gen_highpart_mode (SImode, DImode, operands[1]); 7444 if (operands[4] == const0_rtx) 7445 operands[5] = operands[3]; 7446 else 7447 operands[5] = gen_rtx_PLUS (SImode, operands[3], 7448 gen_int_mode (-UINTVAL (operands[4]), 7449 SImode)); 7450 } 7451 else 7452 { 7453 operands[4] = gen_highpart (SImode, operands[1]); 7454 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]); 7455 } 7456 operands[1] = gen_lowpart (SImode, operands[1]); 7457 operands[2] = gen_lowpart (SImode, operands[2]); 7458 } 7459 [(set_attr "conds" "set") 7460 (set_attr "length" "8") 7461 (set_attr "type" "multiple")] 7462) 7463 7464(define_insn_and_split "*arm_cmpdi_unsigned" 7465 [(set (reg:CC_CZ CC_REGNUM) 7466 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r") 7467 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))] 7468 7469 "TARGET_32BIT" 7470 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1" 7471 "&& reload_completed" 7472 [(set (reg:CC CC_REGNUM) 7473 (compare:CC (match_dup 2) (match_dup 3))) 7474 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0)) 7475 (set (reg:CC CC_REGNUM) 7476 (compare:CC (match_dup 0) (match_dup 1))))] 7477 { 7478 operands[2] = gen_highpart (SImode, operands[0]); 7479 operands[0] = gen_lowpart (SImode, operands[0]); 7480 if (CONST_INT_P (operands[1])) 7481 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]); 7482 else 7483 operands[3] = gen_highpart (SImode, operands[1]); 7484 operands[1] = gen_lowpart (SImode, operands[1]); 7485 } 7486 [(set_attr "conds" "set") 7487 (set_attr "enabled_for_short_it" "yes,yes,no,*") 7488 (set_attr "arch" "t2,t2,t2,a") 7489 (set_attr "length" "6,6,10,8") 7490 (set_attr "type" "multiple")] 7491) 7492 7493(define_insn "*arm_cmpdi_zero" 7494 [(set (reg:CC_Z CC_REGNUM) 7495 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r") 7496 (const_int 0))) 7497 (clobber (match_scratch:SI 1 "=r"))] 7498 "TARGET_32BIT" 7499 "orrs%?\\t%1, %Q0, %R0" 7500 [(set_attr "conds" "set") 7501 (set_attr "type" "logics_reg")] 7502) 7503 7504; This insn allows redundant compares to be removed by cse, nothing should 7505; ever appear in the output file since (set (reg x) (reg x)) is a no-op that 7506; is deleted later on. The match_dup will match the mode here, so that 7507; mode changes of the condition codes aren't lost by this even though we don't 7508; specify what they are. 7509 7510(define_insn "*deleted_compare" 7511 [(set (match_operand 0 "cc_register" "") (match_dup 0))] 7512 "TARGET_32BIT" 7513 "\\t%@ deleted compare" 7514 [(set_attr "conds" "set") 7515 (set_attr "length" "0") 7516 (set_attr "type" "no_insn")] 7517) 7518 7519 7520;; Conditional branch insns 7521 7522(define_expand "cbranch_cc" 7523 [(set (pc) 7524 (if_then_else (match_operator 0 "" [(match_operand 1 "" "") 7525 (match_operand 2 "" "")]) 7526 (label_ref (match_operand 3 "" "")) 7527 (pc)))] 7528 "TARGET_32BIT" 7529 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]), 7530 operands[1], operands[2], NULL_RTX); 7531 operands[2] = const0_rtx;" 7532) 7533 7534;; 7535;; Patterns to match conditional branch insns. 7536;; 7537 7538(define_insn "arm_cond_branch" 7539 [(set (pc) 7540 (if_then_else (match_operator 1 "arm_comparison_operator" 7541 [(match_operand 2 "cc_register" "") (const_int 0)]) 7542 (label_ref (match_operand 0 "" "")) 7543 (pc)))] 7544 "TARGET_32BIT" 7545 "* 7546 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 7547 { 7548 arm_ccfsm_state += 2; 7549 return \"\"; 7550 } 7551 return \"b%d1\\t%l0\"; 7552 " 7553 [(set_attr "conds" "use") 7554 (set_attr "type" "branch") 7555 (set (attr "length") 7556 (if_then_else 7557 (and (match_test "TARGET_THUMB2") 7558 (and (ge (minus (match_dup 0) (pc)) (const_int -250)) 7559 (le (minus (match_dup 0) (pc)) (const_int 256)))) 7560 (const_int 2) 7561 (const_int 4)))] 7562) 7563 7564(define_insn "*arm_cond_branch_reversed" 7565 [(set (pc) 7566 (if_then_else (match_operator 1 "arm_comparison_operator" 7567 [(match_operand 2 "cc_register" "") (const_int 0)]) 7568 (pc) 7569 (label_ref (match_operand 0 "" ""))))] 7570 "TARGET_32BIT" 7571 "* 7572 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 7573 { 7574 arm_ccfsm_state += 2; 7575 return \"\"; 7576 } 7577 return \"b%D1\\t%l0\"; 7578 " 7579 [(set_attr "conds" "use") 7580 (set_attr "type" "branch") 7581 (set (attr "length") 7582 (if_then_else 7583 (and (match_test "TARGET_THUMB2") 7584 (and (ge (minus (match_dup 0) (pc)) (const_int -250)) 7585 (le (minus (match_dup 0) (pc)) (const_int 256)))) 7586 (const_int 2) 7587 (const_int 4)))] 7588) 7589 7590 7591 7592; scc insns 7593 7594(define_expand "cstore_cc" 7595 [(set (match_operand:SI 0 "s_register_operand" "") 7596 (match_operator:SI 1 "" [(match_operand 2 "" "") 7597 (match_operand 3 "" "")]))] 7598 "TARGET_32BIT" 7599 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]), 7600 operands[2], operands[3], NULL_RTX); 7601 operands[3] = const0_rtx;" 7602) 7603 7604(define_insn_and_split "*mov_scc" 7605 [(set (match_operand:SI 0 "s_register_operand" "=r") 7606 (match_operator:SI 1 "arm_comparison_operator_mode" 7607 [(match_operand 2 "cc_register" "") (const_int 0)]))] 7608 "TARGET_ARM" 7609 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1" 7610 "TARGET_ARM" 7611 [(set (match_dup 0) 7612 (if_then_else:SI (match_dup 1) 7613 (const_int 1) 7614 (const_int 0)))] 7615 "" 7616 [(set_attr "conds" "use") 7617 (set_attr "length" "8") 7618 (set_attr "type" "multiple")] 7619) 7620 7621(define_insn_and_split "*mov_negscc" 7622 [(set (match_operand:SI 0 "s_register_operand" "=r") 7623 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode" 7624 [(match_operand 2 "cc_register" "") (const_int 0)])))] 7625 "TARGET_ARM" 7626 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" 7627 "TARGET_ARM" 7628 [(set (match_dup 0) 7629 (if_then_else:SI (match_dup 1) 7630 (match_dup 3) 7631 (const_int 0)))] 7632 { 7633 operands[3] = GEN_INT (~0); 7634 } 7635 [(set_attr "conds" "use") 7636 (set_attr "length" "8") 7637 (set_attr "type" "multiple")] 7638) 7639 7640(define_insn_and_split "*mov_notscc" 7641 [(set (match_operand:SI 0 "s_register_operand" "=r") 7642 (not:SI (match_operator:SI 1 "arm_comparison_operator" 7643 [(match_operand 2 "cc_register" "") (const_int 0)])))] 7644 "TARGET_ARM" 7645 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1" 7646 "TARGET_ARM" 7647 [(set (match_dup 0) 7648 (if_then_else:SI (match_dup 1) 7649 (match_dup 3) 7650 (match_dup 4)))] 7651 { 7652 operands[3] = GEN_INT (~1); 7653 operands[4] = GEN_INT (~0); 7654 } 7655 [(set_attr "conds" "use") 7656 (set_attr "length" "8") 7657 (set_attr "type" "multiple")] 7658) 7659 7660(define_expand "cstoresi4" 7661 [(set (match_operand:SI 0 "s_register_operand" "") 7662 (match_operator:SI 1 "expandable_comparison_operator" 7663 [(match_operand:SI 2 "s_register_operand" "") 7664 (match_operand:SI 3 "reg_or_int_operand" "")]))] 7665 "TARGET_32BIT || TARGET_THUMB1" 7666 "{ 7667 rtx op3, scratch, scratch2; 7668 7669 if (!TARGET_THUMB1) 7670 { 7671 if (!arm_add_operand (operands[3], SImode)) 7672 operands[3] = force_reg (SImode, operands[3]); 7673 emit_insn (gen_cstore_cc (operands[0], operands[1], 7674 operands[2], operands[3])); 7675 DONE; 7676 } 7677 7678 if (operands[3] == const0_rtx) 7679 { 7680 switch (GET_CODE (operands[1])) 7681 { 7682 case EQ: 7683 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2])); 7684 break; 7685 7686 case NE: 7687 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2])); 7688 break; 7689 7690 case LE: 7691 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx, 7692 NULL_RTX, 0, OPTAB_WIDEN); 7693 scratch = expand_binop (SImode, ior_optab, operands[2], scratch, 7694 NULL_RTX, 0, OPTAB_WIDEN); 7695 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), 7696 operands[0], 1, OPTAB_WIDEN); 7697 break; 7698 7699 case GE: 7700 scratch = expand_unop (SImode, one_cmpl_optab, operands[2], 7701 NULL_RTX, 1); 7702 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), 7703 NULL_RTX, 1, OPTAB_WIDEN); 7704 break; 7705 7706 case GT: 7707 scratch = expand_binop (SImode, ashr_optab, operands[2], 7708 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN); 7709 scratch = expand_binop (SImode, sub_optab, scratch, operands[2], 7710 NULL_RTX, 0, OPTAB_WIDEN); 7711 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0], 7712 0, OPTAB_WIDEN); 7713 break; 7714 7715 /* LT is handled by generic code. No need for unsigned with 0. */ 7716 default: 7717 FAIL; 7718 } 7719 DONE; 7720 } 7721 7722 switch (GET_CODE (operands[1])) 7723 { 7724 case EQ: 7725 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3], 7726 NULL_RTX, 0, OPTAB_WIDEN); 7727 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch)); 7728 break; 7729 7730 case NE: 7731 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3], 7732 NULL_RTX, 0, OPTAB_WIDEN); 7733 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch)); 7734 break; 7735 7736 case LE: 7737 op3 = force_reg (SImode, operands[3]); 7738 7739 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31), 7740 NULL_RTX, 1, OPTAB_WIDEN); 7741 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31), 7742 NULL_RTX, 0, OPTAB_WIDEN); 7743 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2, 7744 op3, operands[2])); 7745 break; 7746 7747 case GE: 7748 op3 = operands[3]; 7749 if (!thumb1_cmp_operand (op3, SImode)) 7750 op3 = force_reg (SImode, op3); 7751 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31), 7752 NULL_RTX, 0, OPTAB_WIDEN); 7753 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31), 7754 NULL_RTX, 1, OPTAB_WIDEN); 7755 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2, 7756 operands[2], op3)); 7757 break; 7758 7759 case LEU: 7760 op3 = force_reg (SImode, operands[3]); 7761 scratch = force_reg (SImode, const0_rtx); 7762 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch, 7763 op3, operands[2])); 7764 break; 7765 7766 case GEU: 7767 op3 = operands[3]; 7768 if (!thumb1_cmp_operand (op3, SImode)) 7769 op3 = force_reg (SImode, op3); 7770 scratch = force_reg (SImode, const0_rtx); 7771 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch, 7772 operands[2], op3)); 7773 break; 7774 7775 case LTU: 7776 op3 = operands[3]; 7777 if (!thumb1_cmp_operand (op3, SImode)) 7778 op3 = force_reg (SImode, op3); 7779 scratch = gen_reg_rtx (SImode); 7780 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3)); 7781 break; 7782 7783 case GTU: 7784 op3 = force_reg (SImode, operands[3]); 7785 scratch = gen_reg_rtx (SImode); 7786 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2])); 7787 break; 7788 7789 /* No good sequences for GT, LT. */ 7790 default: 7791 FAIL; 7792 } 7793 DONE; 7794}") 7795 7796(define_expand "cstorehf4" 7797 [(set (match_operand:SI 0 "s_register_operand") 7798 (match_operator:SI 1 "expandable_comparison_operator" 7799 [(match_operand:HF 2 "s_register_operand") 7800 (match_operand:HF 3 "vfp_compare_operand")]))] 7801 "TARGET_VFP_FP16INST" 7802 { 7803 if (!arm_validize_comparison (&operands[1], 7804 &operands[2], 7805 &operands[3])) 7806 FAIL; 7807 7808 emit_insn (gen_cstore_cc (operands[0], operands[1], 7809 operands[2], operands[3])); 7810 DONE; 7811 } 7812) 7813 7814(define_expand "cstoresf4" 7815 [(set (match_operand:SI 0 "s_register_operand" "") 7816 (match_operator:SI 1 "expandable_comparison_operator" 7817 [(match_operand:SF 2 "s_register_operand" "") 7818 (match_operand:SF 3 "vfp_compare_operand" "")]))] 7819 "TARGET_32BIT && TARGET_HARD_FLOAT" 7820 "emit_insn (gen_cstore_cc (operands[0], operands[1], 7821 operands[2], operands[3])); DONE;" 7822) 7823 7824(define_expand "cstoredf4" 7825 [(set (match_operand:SI 0 "s_register_operand" "") 7826 (match_operator:SI 1 "expandable_comparison_operator" 7827 [(match_operand:DF 2 "s_register_operand" "") 7828 (match_operand:DF 3 "vfp_compare_operand" "")]))] 7829 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 7830 "emit_insn (gen_cstore_cc (operands[0], operands[1], 7831 operands[2], operands[3])); DONE;" 7832) 7833 7834(define_expand "cstoredi4" 7835 [(set (match_operand:SI 0 "s_register_operand" "") 7836 (match_operator:SI 1 "expandable_comparison_operator" 7837 [(match_operand:DI 2 "s_register_operand" "") 7838 (match_operand:DI 3 "cmpdi_operand" "")]))] 7839 "TARGET_32BIT" 7840 "{ 7841 if (!arm_validize_comparison (&operands[1], 7842 &operands[2], 7843 &operands[3])) 7844 FAIL; 7845 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2], 7846 operands[3])); 7847 DONE; 7848 }" 7849) 7850 7851 7852;; Conditional move insns 7853 7854(define_expand "movsicc" 7855 [(set (match_operand:SI 0 "s_register_operand" "") 7856 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "") 7857 (match_operand:SI 2 "arm_not_operand" "") 7858 (match_operand:SI 3 "arm_not_operand" "")))] 7859 "TARGET_32BIT" 7860 " 7861 { 7862 enum rtx_code code; 7863 rtx ccreg; 7864 7865 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7866 &XEXP (operands[1], 1))) 7867 FAIL; 7868 7869 code = GET_CODE (operands[1]); 7870 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7871 XEXP (operands[1], 1), NULL_RTX); 7872 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7873 }" 7874) 7875 7876(define_expand "movhfcc" 7877 [(set (match_operand:HF 0 "s_register_operand") 7878 (if_then_else:HF (match_operand 1 "arm_cond_move_operator") 7879 (match_operand:HF 2 "s_register_operand") 7880 (match_operand:HF 3 "s_register_operand")))] 7881 "TARGET_VFP_FP16INST" 7882 " 7883 { 7884 enum rtx_code code = GET_CODE (operands[1]); 7885 rtx ccreg; 7886 7887 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7888 &XEXP (operands[1], 1))) 7889 FAIL; 7890 7891 code = GET_CODE (operands[1]); 7892 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7893 XEXP (operands[1], 1), NULL_RTX); 7894 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7895 }" 7896) 7897 7898(define_expand "movsfcc" 7899 [(set (match_operand:SF 0 "s_register_operand" "") 7900 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "") 7901 (match_operand:SF 2 "s_register_operand" "") 7902 (match_operand:SF 3 "s_register_operand" "")))] 7903 "TARGET_32BIT && TARGET_HARD_FLOAT" 7904 " 7905 { 7906 enum rtx_code code = GET_CODE (operands[1]); 7907 rtx ccreg; 7908 7909 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7910 &XEXP (operands[1], 1))) 7911 FAIL; 7912 7913 code = GET_CODE (operands[1]); 7914 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7915 XEXP (operands[1], 1), NULL_RTX); 7916 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7917 }" 7918) 7919 7920(define_expand "movdfcc" 7921 [(set (match_operand:DF 0 "s_register_operand" "") 7922 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "") 7923 (match_operand:DF 2 "s_register_operand" "") 7924 (match_operand:DF 3 "s_register_operand" "")))] 7925 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 7926 " 7927 { 7928 enum rtx_code code = GET_CODE (operands[1]); 7929 rtx ccreg; 7930 7931 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7932 &XEXP (operands[1], 1))) 7933 FAIL; 7934 code = GET_CODE (operands[1]); 7935 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7936 XEXP (operands[1], 1), NULL_RTX); 7937 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7938 }" 7939) 7940 7941(define_insn "*cmov<mode>" 7942 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>") 7943 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator" 7944 [(match_operand 2 "cc_register" "") (const_int 0)]) 7945 (match_operand:SDF 3 "s_register_operand" 7946 "<F_constraint>") 7947 (match_operand:SDF 4 "s_register_operand" 7948 "<F_constraint>")))] 7949 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>" 7950 "* 7951 { 7952 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]); 7953 switch (code) 7954 { 7955 case ARM_GE: 7956 case ARM_GT: 7957 case ARM_EQ: 7958 case ARM_VS: 7959 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\"; 7960 case ARM_LT: 7961 case ARM_LE: 7962 case ARM_NE: 7963 case ARM_VC: 7964 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\"; 7965 default: 7966 gcc_unreachable (); 7967 } 7968 return \"\"; 7969 }" 7970 [(set_attr "conds" "use") 7971 (set_attr "type" "fcsel")] 7972) 7973 7974(define_insn "*cmovhf" 7975 [(set (match_operand:HF 0 "s_register_operand" "=t") 7976 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator" 7977 [(match_operand 2 "cc_register" "") (const_int 0)]) 7978 (match_operand:HF 3 "s_register_operand" "t") 7979 (match_operand:HF 4 "s_register_operand" "t")))] 7980 "TARGET_VFP_FP16INST" 7981 "* 7982 { 7983 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]); 7984 switch (code) 7985 { 7986 case ARM_GE: 7987 case ARM_GT: 7988 case ARM_EQ: 7989 case ARM_VS: 7990 return \"vsel%d1.f16\\t%0, %3, %4\"; 7991 case ARM_LT: 7992 case ARM_LE: 7993 case ARM_NE: 7994 case ARM_VC: 7995 return \"vsel%D1.f16\\t%0, %4, %3\"; 7996 default: 7997 gcc_unreachable (); 7998 } 7999 return \"\"; 8000 }" 8001 [(set_attr "conds" "use") 8002 (set_attr "type" "fcsel")] 8003) 8004 8005(define_insn_and_split "*movsicc_insn" 8006 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") 8007 (if_then_else:SI 8008 (match_operator 3 "arm_comparison_operator" 8009 [(match_operand 4 "cc_register" "") (const_int 0)]) 8010 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K") 8011 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))] 8012 "TARGET_ARM" 8013 "@ 8014 mov%D3\\t%0, %2 8015 mvn%D3\\t%0, #%B2 8016 mov%d3\\t%0, %1 8017 mvn%d3\\t%0, #%B1 8018 # 8019 # 8020 # 8021 #" 8022 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2 8023 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 8024 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 8025 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2" 8026 "&& reload_completed" 8027 [(const_int 0)] 8028 { 8029 enum rtx_code rev_code; 8030 machine_mode mode; 8031 rtx rev_cond; 8032 8033 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 8034 operands[3], 8035 gen_rtx_SET (operands[0], operands[1]))); 8036 8037 rev_code = GET_CODE (operands[3]); 8038 mode = GET_MODE (operands[4]); 8039 if (mode == CCFPmode || mode == CCFPEmode) 8040 rev_code = reverse_condition_maybe_unordered (rev_code); 8041 else 8042 rev_code = reverse_condition (rev_code); 8043 8044 rev_cond = gen_rtx_fmt_ee (rev_code, 8045 VOIDmode, 8046 operands[4], 8047 const0_rtx); 8048 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 8049 rev_cond, 8050 gen_rtx_SET (operands[0], operands[2]))); 8051 DONE; 8052 } 8053 [(set_attr "length" "4,4,4,4,8,8,8,8") 8054 (set_attr "conds" "use") 8055 (set_attr_alternative "type" 8056 [(if_then_else (match_operand 2 "const_int_operand" "") 8057 (const_string "mov_imm") 8058 (const_string "mov_reg")) 8059 (const_string "mvn_imm") 8060 (if_then_else (match_operand 1 "const_int_operand" "") 8061 (const_string "mov_imm") 8062 (const_string "mov_reg")) 8063 (const_string "mvn_imm") 8064 (const_string "multiple") 8065 (const_string "multiple") 8066 (const_string "multiple") 8067 (const_string "multiple")])] 8068) 8069 8070(define_insn "*movsfcc_soft_insn" 8071 [(set (match_operand:SF 0 "s_register_operand" "=r,r") 8072 (if_then_else:SF (match_operator 3 "arm_comparison_operator" 8073 [(match_operand 4 "cc_register" "") (const_int 0)]) 8074 (match_operand:SF 1 "s_register_operand" "0,r") 8075 (match_operand:SF 2 "s_register_operand" "r,0")))] 8076 "TARGET_ARM && TARGET_SOFT_FLOAT" 8077 "@ 8078 mov%D3\\t%0, %2 8079 mov%d3\\t%0, %1" 8080 [(set_attr "conds" "use") 8081 (set_attr "type" "mov_reg")] 8082) 8083 8084 8085;; Jump and linkage insns 8086 8087(define_expand "jump" 8088 [(set (pc) 8089 (label_ref (match_operand 0 "" "")))] 8090 "TARGET_EITHER" 8091 "" 8092) 8093 8094(define_insn "*arm_jump" 8095 [(set (pc) 8096 (label_ref (match_operand 0 "" "")))] 8097 "TARGET_32BIT" 8098 "* 8099 { 8100 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 8101 { 8102 arm_ccfsm_state += 2; 8103 return \"\"; 8104 } 8105 return \"b%?\\t%l0\"; 8106 } 8107 " 8108 [(set_attr "predicable" "yes") 8109 (set (attr "length") 8110 (if_then_else 8111 (and (match_test "TARGET_THUMB2") 8112 (and (ge (minus (match_dup 0) (pc)) (const_int -2044)) 8113 (le (minus (match_dup 0) (pc)) (const_int 2048)))) 8114 (const_int 2) 8115 (const_int 4))) 8116 (set_attr "type" "branch")] 8117) 8118 8119(define_expand "call" 8120 [(parallel [(call (match_operand 0 "memory_operand" "") 8121 (match_operand 1 "general_operand" "")) 8122 (use (match_operand 2 "" "")) 8123 (clobber (reg:SI LR_REGNUM))])] 8124 "TARGET_EITHER" 8125 " 8126 { 8127 rtx callee, pat; 8128 tree addr = MEM_EXPR (operands[0]); 8129 8130 /* In an untyped call, we can get NULL for operand 2. */ 8131 if (operands[2] == NULL_RTX) 8132 operands[2] = const0_rtx; 8133 8134 /* Decide if we should generate indirect calls by loading the 8135 32-bit address of the callee into a register before performing the 8136 branch and link. */ 8137 callee = XEXP (operands[0], 0); 8138 if (GET_CODE (callee) == SYMBOL_REF 8139 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee)) 8140 : !REG_P (callee)) 8141 XEXP (operands[0], 0) = force_reg (Pmode, callee); 8142 8143 if (detect_cmse_nonsecure_call (addr)) 8144 { 8145 pat = gen_nonsecure_call_internal (operands[0], operands[1], 8146 operands[2]); 8147 emit_call_insn (pat); 8148 } 8149 else 8150 { 8151 pat = gen_call_internal (operands[0], operands[1], operands[2]); 8152 arm_emit_call_insn (pat, XEXP (operands[0], 0), false); 8153 } 8154 DONE; 8155 }" 8156) 8157 8158(define_expand "call_internal" 8159 [(parallel [(call (match_operand 0 "memory_operand" "") 8160 (match_operand 1 "general_operand" "")) 8161 (use (match_operand 2 "" "")) 8162 (clobber (reg:SI LR_REGNUM))])]) 8163 8164(define_expand "nonsecure_call_internal" 8165 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")] 8166 UNSPEC_NONSECURE_MEM) 8167 (match_operand 1 "general_operand" "")) 8168 (use (match_operand 2 "" "")) 8169 (clobber (reg:SI LR_REGNUM))])] 8170 "use_cmse" 8171 " 8172 { 8173 rtx tmp; 8174 tmp = copy_to_suggested_reg (XEXP (operands[0], 0), 8175 gen_rtx_REG (SImode, R4_REGNUM), 8176 SImode); 8177 8178 operands[0] = replace_equiv_address (operands[0], tmp); 8179 }") 8180 8181(define_insn "*call_reg_armv5" 8182 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) 8183 (match_operand 1 "" "")) 8184 (use (match_operand 2 "" "")) 8185 (clobber (reg:SI LR_REGNUM))] 8186 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)" 8187 "blx%?\\t%0" 8188 [(set_attr "type" "call")] 8189) 8190 8191(define_insn "*call_reg_arm" 8192 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) 8193 (match_operand 1 "" "")) 8194 (use (match_operand 2 "" "")) 8195 (clobber (reg:SI LR_REGNUM))] 8196 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)" 8197 "* 8198 return output_call (operands); 8199 " 8200 ;; length is worst case, normally it is only two 8201 [(set_attr "length" "12") 8202 (set_attr "type" "call")] 8203) 8204 8205 8206(define_expand "call_value" 8207 [(parallel [(set (match_operand 0 "" "") 8208 (call (match_operand 1 "memory_operand" "") 8209 (match_operand 2 "general_operand" ""))) 8210 (use (match_operand 3 "" "")) 8211 (clobber (reg:SI LR_REGNUM))])] 8212 "TARGET_EITHER" 8213 " 8214 { 8215 rtx pat, callee; 8216 tree addr = MEM_EXPR (operands[1]); 8217 8218 /* In an untyped call, we can get NULL for operand 2. */ 8219 if (operands[3] == 0) 8220 operands[3] = const0_rtx; 8221 8222 /* Decide if we should generate indirect calls by loading the 8223 32-bit address of the callee into a register before performing the 8224 branch and link. */ 8225 callee = XEXP (operands[1], 0); 8226 if (GET_CODE (callee) == SYMBOL_REF 8227 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee)) 8228 : !REG_P (callee)) 8229 XEXP (operands[1], 0) = force_reg (Pmode, callee); 8230 8231 if (detect_cmse_nonsecure_call (addr)) 8232 { 8233 pat = gen_nonsecure_call_value_internal (operands[0], operands[1], 8234 operands[2], operands[3]); 8235 emit_call_insn (pat); 8236 } 8237 else 8238 { 8239 pat = gen_call_value_internal (operands[0], operands[1], 8240 operands[2], operands[3]); 8241 arm_emit_call_insn (pat, XEXP (operands[1], 0), false); 8242 } 8243 DONE; 8244 }" 8245) 8246 8247(define_expand "call_value_internal" 8248 [(parallel [(set (match_operand 0 "" "") 8249 (call (match_operand 1 "memory_operand" "") 8250 (match_operand 2 "general_operand" ""))) 8251 (use (match_operand 3 "" "")) 8252 (clobber (reg:SI LR_REGNUM))])]) 8253 8254(define_expand "nonsecure_call_value_internal" 8255 [(parallel [(set (match_operand 0 "" "") 8256 (call (unspec:SI [(match_operand 1 "memory_operand" "")] 8257 UNSPEC_NONSECURE_MEM) 8258 (match_operand 2 "general_operand" ""))) 8259 (use (match_operand 3 "" "")) 8260 (clobber (reg:SI LR_REGNUM))])] 8261 "use_cmse" 8262 " 8263 { 8264 rtx tmp; 8265 tmp = copy_to_suggested_reg (XEXP (operands[1], 0), 8266 gen_rtx_REG (SImode, R4_REGNUM), 8267 SImode); 8268 8269 operands[1] = replace_equiv_address (operands[1], tmp); 8270 }") 8271 8272(define_insn "*call_value_reg_armv5" 8273 [(set (match_operand 0 "" "") 8274 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r")) 8275 (match_operand 2 "" ""))) 8276 (use (match_operand 3 "" "")) 8277 (clobber (reg:SI LR_REGNUM))] 8278 "TARGET_ARM && arm_arch5t && !SIBLING_CALL_P (insn)" 8279 "blx%?\\t%1" 8280 [(set_attr "type" "call")] 8281) 8282 8283(define_insn "*call_value_reg_arm" 8284 [(set (match_operand 0 "" "") 8285 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r")) 8286 (match_operand 2 "" ""))) 8287 (use (match_operand 3 "" "")) 8288 (clobber (reg:SI LR_REGNUM))] 8289 "TARGET_ARM && !arm_arch5t && !SIBLING_CALL_P (insn)" 8290 "* 8291 return output_call (&operands[1]); 8292 " 8293 [(set_attr "length" "12") 8294 (set_attr "type" "call")] 8295) 8296 8297;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses 8298;; The 'a' causes the operand to be treated as an address, i.e. no '#' output. 8299 8300(define_insn "*call_symbol" 8301 [(call (mem:SI (match_operand:SI 0 "" "")) 8302 (match_operand 1 "" "")) 8303 (use (match_operand 2 "" "")) 8304 (clobber (reg:SI LR_REGNUM))] 8305 "TARGET_32BIT 8306 && !SIBLING_CALL_P (insn) 8307 && (GET_CODE (operands[0]) == SYMBOL_REF) 8308 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))" 8309 "* 8310 { 8311 rtx op = operands[0]; 8312 8313 /* Switch mode now when possible. */ 8314 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op)) 8315 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op))) 8316 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\"; 8317 8318 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\"; 8319 }" 8320 [(set_attr "type" "call")] 8321) 8322 8323(define_insn "*call_value_symbol" 8324 [(set (match_operand 0 "" "") 8325 (call (mem:SI (match_operand:SI 1 "" "")) 8326 (match_operand:SI 2 "" ""))) 8327 (use (match_operand 3 "" "")) 8328 (clobber (reg:SI LR_REGNUM))] 8329 "TARGET_32BIT 8330 && !SIBLING_CALL_P (insn) 8331 && (GET_CODE (operands[1]) == SYMBOL_REF) 8332 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" 8333 "* 8334 { 8335 rtx op = operands[1]; 8336 8337 /* Switch mode now when possible. */ 8338 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op)) 8339 && arm_arch5t && arm_change_mode_p (SYMBOL_REF_DECL (op))) 8340 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\"; 8341 8342 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\"; 8343 }" 8344 [(set_attr "type" "call")] 8345) 8346 8347(define_expand "sibcall_internal" 8348 [(parallel [(call (match_operand 0 "memory_operand" "") 8349 (match_operand 1 "general_operand" "")) 8350 (return) 8351 (use (match_operand 2 "" ""))])]) 8352 8353;; We may also be able to do sibcalls for Thumb, but it's much harder... 8354(define_expand "sibcall" 8355 [(parallel [(call (match_operand 0 "memory_operand" "") 8356 (match_operand 1 "general_operand" "")) 8357 (return) 8358 (use (match_operand 2 "" ""))])] 8359 "TARGET_32BIT" 8360 " 8361 { 8362 rtx pat; 8363 8364 if ((!REG_P (XEXP (operands[0], 0)) 8365 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF) 8366 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF 8367 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0))))) 8368 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); 8369 8370 if (operands[2] == NULL_RTX) 8371 operands[2] = const0_rtx; 8372 8373 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]); 8374 arm_emit_call_insn (pat, operands[0], true); 8375 DONE; 8376 }" 8377) 8378 8379(define_expand "sibcall_value_internal" 8380 [(parallel [(set (match_operand 0 "" "") 8381 (call (match_operand 1 "memory_operand" "") 8382 (match_operand 2 "general_operand" ""))) 8383 (return) 8384 (use (match_operand 3 "" ""))])]) 8385 8386(define_expand "sibcall_value" 8387 [(parallel [(set (match_operand 0 "" "") 8388 (call (match_operand 1 "memory_operand" "") 8389 (match_operand 2 "general_operand" ""))) 8390 (return) 8391 (use (match_operand 3 "" ""))])] 8392 "TARGET_32BIT" 8393 " 8394 { 8395 rtx pat; 8396 8397 if ((!REG_P (XEXP (operands[1], 0)) 8398 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF) 8399 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF 8400 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0))))) 8401 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); 8402 8403 if (operands[3] == NULL_RTX) 8404 operands[3] = const0_rtx; 8405 8406 pat = gen_sibcall_value_internal (operands[0], operands[1], 8407 operands[2], operands[3]); 8408 arm_emit_call_insn (pat, operands[1], true); 8409 DONE; 8410 }" 8411) 8412 8413(define_insn "*sibcall_insn" 8414 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US")) 8415 (match_operand 1 "" "")) 8416 (return) 8417 (use (match_operand 2 "" ""))] 8418 "TARGET_32BIT && SIBLING_CALL_P (insn)" 8419 "* 8420 if (which_alternative == 1) 8421 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\"; 8422 else 8423 { 8424 if (arm_arch5t || arm_arch4t) 8425 return \"bx%?\\t%0\\t%@ indirect register sibling call\"; 8426 else 8427 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\"; 8428 } 8429 " 8430 [(set_attr "type" "call")] 8431) 8432 8433(define_insn "*sibcall_value_insn" 8434 [(set (match_operand 0 "" "") 8435 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US")) 8436 (match_operand 2 "" ""))) 8437 (return) 8438 (use (match_operand 3 "" ""))] 8439 "TARGET_32BIT && SIBLING_CALL_P (insn)" 8440 "* 8441 if (which_alternative == 1) 8442 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\"; 8443 else 8444 { 8445 if (arm_arch5t || arm_arch4t) 8446 return \"bx%?\\t%1\"; 8447 else 8448 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \"; 8449 } 8450 " 8451 [(set_attr "type" "call")] 8452) 8453 8454(define_expand "<return_str>return" 8455 [(RETURNS)] 8456 "(TARGET_ARM || (TARGET_THUMB2 8457 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL 8458 && !IS_STACKALIGN (arm_current_func_type ()))) 8459 <return_cond_false>" 8460 " 8461 { 8462 if (TARGET_THUMB2) 8463 { 8464 thumb2_expand_return (<return_simple_p>); 8465 DONE; 8466 } 8467 } 8468 " 8469) 8470 8471;; Often the return insn will be the same as loading from memory, so set attr 8472(define_insn "*arm_return" 8473 [(return)] 8474 "TARGET_ARM && USE_RETURN_INSN (FALSE)" 8475 "* 8476 { 8477 if (arm_ccfsm_state == 2) 8478 { 8479 arm_ccfsm_state += 2; 8480 return \"\"; 8481 } 8482 return output_return_instruction (const_true_rtx, true, false, false); 8483 }" 8484 [(set_attr "type" "load_4") 8485 (set_attr "length" "12") 8486 (set_attr "predicable" "yes")] 8487) 8488 8489(define_insn "*cond_<return_str>return" 8490 [(set (pc) 8491 (if_then_else (match_operator 0 "arm_comparison_operator" 8492 [(match_operand 1 "cc_register" "") (const_int 0)]) 8493 (RETURNS) 8494 (pc)))] 8495 "TARGET_ARM <return_cond_true>" 8496 "* 8497 { 8498 if (arm_ccfsm_state == 2) 8499 { 8500 arm_ccfsm_state += 2; 8501 return \"\"; 8502 } 8503 return output_return_instruction (operands[0], true, false, 8504 <return_simple_p>); 8505 }" 8506 [(set_attr "conds" "use") 8507 (set_attr "length" "12") 8508 (set_attr "type" "load_4")] 8509) 8510 8511(define_insn "*cond_<return_str>return_inverted" 8512 [(set (pc) 8513 (if_then_else (match_operator 0 "arm_comparison_operator" 8514 [(match_operand 1 "cc_register" "") (const_int 0)]) 8515 (pc) 8516 (RETURNS)))] 8517 "TARGET_ARM <return_cond_true>" 8518 "* 8519 { 8520 if (arm_ccfsm_state == 2) 8521 { 8522 arm_ccfsm_state += 2; 8523 return \"\"; 8524 } 8525 return output_return_instruction (operands[0], true, true, 8526 <return_simple_p>); 8527 }" 8528 [(set_attr "conds" "use") 8529 (set_attr "length" "12") 8530 (set_attr "type" "load_4")] 8531) 8532 8533(define_insn "*arm_simple_return" 8534 [(simple_return)] 8535 "TARGET_ARM" 8536 "* 8537 { 8538 if (arm_ccfsm_state == 2) 8539 { 8540 arm_ccfsm_state += 2; 8541 return \"\"; 8542 } 8543 return output_return_instruction (const_true_rtx, true, false, true); 8544 }" 8545 [(set_attr "type" "branch") 8546 (set_attr "length" "4") 8547 (set_attr "predicable" "yes")] 8548) 8549 8550;; Generate a sequence of instructions to determine if the processor is 8551;; in 26-bit or 32-bit mode, and return the appropriate return address 8552;; mask. 8553 8554(define_expand "return_addr_mask" 8555 [(set (match_dup 1) 8556 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH) 8557 (const_int 0))) 8558 (set (match_operand:SI 0 "s_register_operand" "") 8559 (if_then_else:SI (eq (match_dup 1) (const_int 0)) 8560 (const_int -1) 8561 (const_int 67108860)))] ; 0x03fffffc 8562 "TARGET_ARM" 8563 " 8564 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM); 8565 ") 8566 8567(define_insn "*check_arch2" 8568 [(set (match_operand:CC_NOOV 0 "cc_register" "") 8569 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH) 8570 (const_int 0)))] 8571 "TARGET_ARM" 8572 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc" 8573 [(set_attr "length" "8") 8574 (set_attr "conds" "set") 8575 (set_attr "type" "multiple")] 8576) 8577 8578;; Call subroutine returning any type. 8579 8580(define_expand "untyped_call" 8581 [(parallel [(call (match_operand 0 "" "") 8582 (const_int 0)) 8583 (match_operand 1 "" "") 8584 (match_operand 2 "" "")])] 8585 "TARGET_EITHER" 8586 " 8587 { 8588 int i; 8589 rtx par = gen_rtx_PARALLEL (VOIDmode, 8590 rtvec_alloc (XVECLEN (operands[2], 0))); 8591 rtx addr = gen_reg_rtx (Pmode); 8592 rtx mem; 8593 int size = 0; 8594 8595 emit_move_insn (addr, XEXP (operands[1], 0)); 8596 mem = change_address (operands[1], BLKmode, addr); 8597 8598 for (i = 0; i < XVECLEN (operands[2], 0); i++) 8599 { 8600 rtx src = SET_SRC (XVECEXP (operands[2], 0, i)); 8601 8602 /* Default code only uses r0 as a return value, but we could 8603 be using anything up to 4 registers. */ 8604 if (REGNO (src) == R0_REGNUM) 8605 src = gen_rtx_REG (TImode, R0_REGNUM); 8606 8607 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src, 8608 GEN_INT (size)); 8609 size += GET_MODE_SIZE (GET_MODE (src)); 8610 } 8611 8612 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL)); 8613 8614 size = 0; 8615 8616 for (i = 0; i < XVECLEN (par, 0); i++) 8617 { 8618 HOST_WIDE_INT offset = 0; 8619 rtx reg = XEXP (XVECEXP (par, 0, i), 0); 8620 8621 if (size != 0) 8622 emit_move_insn (addr, plus_constant (Pmode, addr, size)); 8623 8624 mem = change_address (mem, GET_MODE (reg), NULL); 8625 if (REGNO (reg) == R0_REGNUM) 8626 { 8627 /* On thumb we have to use a write-back instruction. */ 8628 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr, 8629 TARGET_THUMB ? TRUE : FALSE, mem, &offset)); 8630 size = TARGET_ARM ? 16 : 0; 8631 } 8632 else 8633 { 8634 emit_move_insn (mem, reg); 8635 size = GET_MODE_SIZE (GET_MODE (reg)); 8636 } 8637 } 8638 8639 /* The optimizer does not know that the call sets the function value 8640 registers we stored in the result block. We avoid problems by 8641 claiming that all hard registers are used and clobbered at this 8642 point. */ 8643 emit_insn (gen_blockage ()); 8644 8645 DONE; 8646 }" 8647) 8648 8649(define_expand "untyped_return" 8650 [(match_operand:BLK 0 "memory_operand" "") 8651 (match_operand 1 "" "")] 8652 "TARGET_EITHER" 8653 " 8654 { 8655 int i; 8656 rtx addr = gen_reg_rtx (Pmode); 8657 rtx mem; 8658 int size = 0; 8659 8660 emit_move_insn (addr, XEXP (operands[0], 0)); 8661 mem = change_address (operands[0], BLKmode, addr); 8662 8663 for (i = 0; i < XVECLEN (operands[1], 0); i++) 8664 { 8665 HOST_WIDE_INT offset = 0; 8666 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i)); 8667 8668 if (size != 0) 8669 emit_move_insn (addr, plus_constant (Pmode, addr, size)); 8670 8671 mem = change_address (mem, GET_MODE (reg), NULL); 8672 if (REGNO (reg) == R0_REGNUM) 8673 { 8674 /* On thumb we have to use a write-back instruction. */ 8675 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr, 8676 TARGET_THUMB ? TRUE : FALSE, mem, &offset)); 8677 size = TARGET_ARM ? 16 : 0; 8678 } 8679 else 8680 { 8681 emit_move_insn (reg, mem); 8682 size = GET_MODE_SIZE (GET_MODE (reg)); 8683 } 8684 } 8685 8686 /* Emit USE insns before the return. */ 8687 for (i = 0; i < XVECLEN (operands[1], 0); i++) 8688 emit_use (SET_DEST (XVECEXP (operands[1], 0, i))); 8689 8690 /* Construct the return. */ 8691 expand_naked_return (); 8692 8693 DONE; 8694 }" 8695) 8696 8697;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 8698;; all of memory. This blocks insns from being moved across this point. 8699 8700(define_insn "blockage" 8701 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)] 8702 "TARGET_EITHER" 8703 "" 8704 [(set_attr "length" "0") 8705 (set_attr "type" "block")] 8706) 8707 8708;; Since we hard code r0 here use the 'o' constraint to prevent 8709;; provoking undefined behaviour in the hardware with putting out 8710;; auto-increment operations with potentially r0 as the base register. 8711(define_insn "probe_stack" 8712 [(set (match_operand:SI 0 "memory_operand" "=o") 8713 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))] 8714 "TARGET_32BIT" 8715 "str%?\\tr0, %0" 8716 [(set_attr "type" "store_4") 8717 (set_attr "predicable" "yes")] 8718) 8719 8720(define_insn "probe_stack_range" 8721 [(set (match_operand:SI 0 "register_operand" "=r") 8722 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0") 8723 (match_operand:SI 2 "register_operand" "r")] 8724 VUNSPEC_PROBE_STACK_RANGE))] 8725 "TARGET_32BIT" 8726{ 8727 return output_probe_stack_range (operands[0], operands[2]); 8728} 8729 [(set_attr "type" "multiple") 8730 (set_attr "conds" "clob")] 8731) 8732 8733;; Named patterns for stack smashing protection. 8734(define_expand "stack_protect_combined_set" 8735 [(parallel 8736 [(set (match_operand:SI 0 "memory_operand" "") 8737 (unspec:SI [(match_operand:SI 1 "guard_operand" "")] 8738 UNSPEC_SP_SET)) 8739 (clobber (match_scratch:SI 2 "")) 8740 (clobber (match_scratch:SI 3 ""))])] 8741 "" 8742 "" 8743) 8744 8745;; Use a separate insn from the above expand to be able to have the mem outside 8746;; the operand #1 when register allocation comes. This is needed to avoid LRA 8747;; try to reload the guard since we need to control how PIC access is done in 8748;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling 8749;; legitimize_pic_address ()). 8750(define_insn_and_split "*stack_protect_combined_set_insn" 8751 [(set (match_operand:SI 0 "memory_operand" "=m,m") 8752 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))] 8753 UNSPEC_SP_SET)) 8754 (clobber (match_scratch:SI 2 "=&l,&r")) 8755 (clobber (match_scratch:SI 3 "=&l,&r"))] 8756 "" 8757 "#" 8758 "reload_completed" 8759 [(parallel [(set (match_dup 0) (unspec:SI [(mem:SI (match_dup 2))] 8760 UNSPEC_SP_SET)) 8761 (clobber (match_dup 2))])] 8762 " 8763{ 8764 if (flag_pic) 8765 { 8766 /* Forces recomputing of GOT base now. */ 8767 legitimize_pic_address (operands[1], SImode, operands[2], operands[3], 8768 true /*compute_now*/); 8769 } 8770 else 8771 { 8772 if (address_operand (operands[1], SImode)) 8773 operands[2] = operands[1]; 8774 else 8775 { 8776 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0); 8777 emit_move_insn (operands[2], mem); 8778 } 8779 } 8780}" 8781 [(set_attr "arch" "t1,32")] 8782) 8783 8784(define_insn "*stack_protect_set_insn" 8785 [(set (match_operand:SI 0 "memory_operand" "=m,m") 8786 (unspec:SI [(mem:SI (match_operand:SI 1 "register_operand" "+&l,&r"))] 8787 UNSPEC_SP_SET)) 8788 (clobber (match_dup 1))] 8789 "" 8790 "@ 8791 ldr\\t%1, [%1]\;str\\t%1, %0\;movs\t%1,#0 8792 ldr\\t%1, [%1]\;str\\t%1, %0\;mov\t%1,#0" 8793 [(set_attr "length" "8,12") 8794 (set_attr "conds" "clob,nocond") 8795 (set_attr "type" "multiple") 8796 (set_attr "arch" "t1,32")] 8797) 8798 8799(define_expand "stack_protect_combined_test" 8800 [(parallel 8801 [(set (pc) 8802 (if_then_else 8803 (eq (match_operand:SI 0 "memory_operand" "") 8804 (unspec:SI [(match_operand:SI 1 "guard_operand" "")] 8805 UNSPEC_SP_TEST)) 8806 (label_ref (match_operand 2)) 8807 (pc))) 8808 (clobber (match_scratch:SI 3 "")) 8809 (clobber (match_scratch:SI 4 "")) 8810 (clobber (reg:CC CC_REGNUM))])] 8811 "" 8812 "" 8813) 8814 8815;; Use a separate insn from the above expand to be able to have the mem outside 8816;; the operand #1 when register allocation comes. This is needed to avoid LRA 8817;; try to reload the guard since we need to control how PIC access is done in 8818;; the -fpic/-fPIC case (see COMPUTE_NOW parameter when calling 8819;; legitimize_pic_address ()). 8820(define_insn_and_split "*stack_protect_combined_test_insn" 8821 [(set (pc) 8822 (if_then_else 8823 (eq (match_operand:SI 0 "memory_operand" "m,m") 8824 (unspec:SI [(mem:SI (match_operand:SI 1 "guard_addr_operand" "X,X"))] 8825 UNSPEC_SP_TEST)) 8826 (label_ref (match_operand 2)) 8827 (pc))) 8828 (clobber (match_scratch:SI 3 "=&l,&r")) 8829 (clobber (match_scratch:SI 4 "=&l,&r")) 8830 (clobber (reg:CC CC_REGNUM))] 8831 "" 8832 "#" 8833 "reload_completed" 8834 [(const_int 0)] 8835{ 8836 rtx eq; 8837 8838 if (flag_pic) 8839 { 8840 /* Forces recomputing of GOT base now. */ 8841 legitimize_pic_address (operands[1], SImode, operands[3], operands[4], 8842 true /*compute_now*/); 8843 } 8844 else 8845 { 8846 if (address_operand (operands[1], SImode)) 8847 operands[3] = operands[1]; 8848 else 8849 { 8850 rtx mem = XEXP (force_const_mem (SImode, operands[1]), 0); 8851 emit_move_insn (operands[3], mem); 8852 } 8853 } 8854 if (TARGET_32BIT) 8855 { 8856 emit_insn (gen_arm_stack_protect_test_insn (operands[4], operands[0], 8857 operands[3])); 8858 rtx cc_reg = gen_rtx_REG (CC_Zmode, CC_REGNUM); 8859 eq = gen_rtx_EQ (CC_Zmode, cc_reg, const0_rtx); 8860 emit_jump_insn (gen_arm_cond_branch (operands[2], eq, cc_reg)); 8861 } 8862 else 8863 { 8864 emit_insn (gen_thumb1_stack_protect_test_insn (operands[4], operands[0], 8865 operands[3])); 8866 eq = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx); 8867 emit_jump_insn (gen_cbranchsi4 (eq, operands[4], const0_rtx, 8868 operands[2])); 8869 } 8870 DONE; 8871} 8872 [(set_attr "arch" "t1,32")] 8873) 8874 8875(define_insn "arm_stack_protect_test_insn" 8876 [(set (reg:CC_Z CC_REGNUM) 8877 (compare:CC_Z (unspec:SI [(match_operand:SI 1 "memory_operand" "m,m") 8878 (mem:SI (match_operand:SI 2 "register_operand" "+l,r"))] 8879 UNSPEC_SP_TEST) 8880 (const_int 0))) 8881 (clobber (match_operand:SI 0 "register_operand" "=&l,&r")) 8882 (clobber (match_dup 2))] 8883 "TARGET_32BIT" 8884 "ldr\t%0, [%2]\;ldr\t%2, %1\;eors\t%0, %2, %0" 8885 [(set_attr "length" "8,12") 8886 (set_attr "conds" "set") 8887 (set_attr "type" "multiple") 8888 (set_attr "arch" "t,32")] 8889) 8890 8891(define_expand "casesi" 8892 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on 8893 (match_operand:SI 1 "const_int_operand" "") ; lower bound 8894 (match_operand:SI 2 "const_int_operand" "") ; total range 8895 (match_operand:SI 3 "" "") ; table label 8896 (match_operand:SI 4 "" "")] ; Out of range label 8897 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code" 8898 " 8899 { 8900 enum insn_code code; 8901 if (operands[1] != const0_rtx) 8902 { 8903 rtx reg = gen_reg_rtx (SImode); 8904 8905 emit_insn (gen_addsi3 (reg, operands[0], 8906 gen_int_mode (-INTVAL (operands[1]), 8907 SImode))); 8908 operands[0] = reg; 8909 } 8910 8911 if (TARGET_ARM) 8912 code = CODE_FOR_arm_casesi_internal; 8913 else if (TARGET_THUMB1) 8914 code = CODE_FOR_thumb1_casesi_internal_pic; 8915 else if (flag_pic) 8916 code = CODE_FOR_thumb2_casesi_internal_pic; 8917 else 8918 code = CODE_FOR_thumb2_casesi_internal; 8919 8920 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode)) 8921 operands[2] = force_reg (SImode, operands[2]); 8922 8923 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2], 8924 operands[3], operands[4])); 8925 DONE; 8926 }" 8927) 8928 8929;; The USE in this pattern is needed to tell flow analysis that this is 8930;; a CASESI insn. It has no other purpose. 8931(define_expand "arm_casesi_internal" 8932 [(parallel [(set (pc) 8933 (if_then_else 8934 (leu (match_operand:SI 0 "s_register_operand") 8935 (match_operand:SI 1 "arm_rhs_operand")) 8936 (match_dup 4) 8937 (label_ref:SI (match_operand 3 "")))) 8938 (clobber (reg:CC CC_REGNUM)) 8939 (use (label_ref:SI (match_operand 2 "")))])] 8940 "TARGET_ARM" 8941{ 8942 operands[4] = gen_rtx_MULT (SImode, operands[0], GEN_INT (4)); 8943 operands[4] = gen_rtx_PLUS (SImode, operands[4], 8944 gen_rtx_LABEL_REF (SImode, operands[2])); 8945 operands[4] = gen_rtx_MEM (SImode, operands[4]); 8946 MEM_READONLY_P (operands[4]) = 1; 8947 MEM_NOTRAP_P (operands[4]) = 1; 8948}) 8949 8950(define_insn "*arm_casesi_internal" 8951 [(parallel [(set (pc) 8952 (if_then_else 8953 (leu (match_operand:SI 0 "s_register_operand" "r") 8954 (match_operand:SI 1 "arm_rhs_operand" "rI")) 8955 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) 8956 (label_ref:SI (match_operand 2 "" "")))) 8957 (label_ref:SI (match_operand 3 "" "")))) 8958 (clobber (reg:CC CC_REGNUM)) 8959 (use (label_ref:SI (match_dup 2)))])] 8960 "TARGET_ARM" 8961 "* 8962 if (flag_pic) 8963 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\"; 8964 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\"; 8965 " 8966 [(set_attr "conds" "clob") 8967 (set_attr "length" "12") 8968 (set_attr "type" "multiple")] 8969) 8970 8971(define_expand "indirect_jump" 8972 [(set (pc) 8973 (match_operand:SI 0 "s_register_operand" ""))] 8974 "TARGET_EITHER" 8975 " 8976 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the 8977 address and use bx. */ 8978 if (TARGET_THUMB2) 8979 { 8980 rtx tmp; 8981 tmp = gen_reg_rtx (SImode); 8982 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1))); 8983 operands[0] = tmp; 8984 } 8985 " 8986) 8987 8988;; NB Never uses BX. 8989(define_insn "*arm_indirect_jump" 8990 [(set (pc) 8991 (match_operand:SI 0 "s_register_operand" "r"))] 8992 "TARGET_ARM" 8993 "mov%?\\t%|pc, %0\\t%@ indirect register jump" 8994 [(set_attr "predicable" "yes") 8995 (set_attr "type" "branch")] 8996) 8997 8998(define_insn "*load_indirect_jump" 8999 [(set (pc) 9000 (match_operand:SI 0 "memory_operand" "m"))] 9001 "TARGET_ARM" 9002 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump" 9003 [(set_attr "type" "load_4") 9004 (set_attr "pool_range" "4096") 9005 (set_attr "neg_pool_range" "4084") 9006 (set_attr "predicable" "yes")] 9007) 9008 9009 9010;; Misc insns 9011 9012(define_insn "nop" 9013 [(const_int 0)] 9014 "TARGET_EITHER" 9015 "nop" 9016 [(set (attr "length") 9017 (if_then_else (eq_attr "is_thumb" "yes") 9018 (const_int 2) 9019 (const_int 4))) 9020 (set_attr "type" "mov_reg")] 9021) 9022 9023(define_insn "trap" 9024 [(trap_if (const_int 1) (const_int 0))] 9025 "" 9026 "* 9027 if (TARGET_ARM) 9028 return \".inst\\t0xe7f000f0\"; 9029 else 9030 return \".inst\\t0xdeff\"; 9031 " 9032 [(set (attr "length") 9033 (if_then_else (eq_attr "is_thumb" "yes") 9034 (const_int 2) 9035 (const_int 4))) 9036 (set_attr "type" "trap") 9037 (set_attr "conds" "unconditional")] 9038) 9039 9040 9041;; Patterns to allow combination of arithmetic, cond code and shifts 9042 9043(define_insn "*<arith_shift_insn>_multsi" 9044 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9045 (SHIFTABLE_OPS:SI 9046 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") 9047 (match_operand:SI 3 "power_of_two_operand" "")) 9048 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))] 9049 "TARGET_32BIT" 9050 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3" 9051 [(set_attr "predicable" "yes") 9052 (set_attr "shift" "2") 9053 (set_attr "arch" "a,t2") 9054 (set_attr "type" "alu_shift_imm")]) 9055 9056(define_insn "*<arith_shift_insn>_shiftsi" 9057 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 9058 (SHIFTABLE_OPS:SI 9059 (match_operator:SI 2 "shift_nomul_operator" 9060 [(match_operand:SI 3 "s_register_operand" "r,r,r") 9061 (match_operand:SI 4 "shift_amount_operand" "M,M,r")]) 9062 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))] 9063 "TARGET_32BIT && GET_CODE (operands[2]) != MULT" 9064 "<arith_shift_insn>%?\\t%0, %1, %3%S2" 9065 [(set_attr "predicable" "yes") 9066 (set_attr "shift" "3") 9067 (set_attr "arch" "a,t2,a") 9068 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")]) 9069 9070(define_split 9071 [(set (match_operand:SI 0 "s_register_operand" "") 9072 (match_operator:SI 1 "shiftable_operator" 9073 [(match_operator:SI 2 "shiftable_operator" 9074 [(match_operator:SI 3 "shift_operator" 9075 [(match_operand:SI 4 "s_register_operand" "") 9076 (match_operand:SI 5 "reg_or_int_operand" "")]) 9077 (match_operand:SI 6 "s_register_operand" "")]) 9078 (match_operand:SI 7 "arm_rhs_operand" "")])) 9079 (clobber (match_operand:SI 8 "s_register_operand" ""))] 9080 "TARGET_32BIT" 9081 [(set (match_dup 8) 9082 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)]) 9083 (match_dup 6)])) 9084 (set (match_dup 0) 9085 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))] 9086 "") 9087 9088(define_insn "*arith_shiftsi_compare0" 9089 [(set (reg:CC_NOOV CC_REGNUM) 9090 (compare:CC_NOOV 9091 (match_operator:SI 1 "shiftable_operator" 9092 [(match_operator:SI 3 "shift_operator" 9093 [(match_operand:SI 4 "s_register_operand" "r,r") 9094 (match_operand:SI 5 "shift_amount_operand" "M,r")]) 9095 (match_operand:SI 2 "s_register_operand" "r,r")]) 9096 (const_int 0))) 9097 (set (match_operand:SI 0 "s_register_operand" "=r,r") 9098 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)]) 9099 (match_dup 2)]))] 9100 "TARGET_32BIT" 9101 "%i1s%?\\t%0, %2, %4%S3" 9102 [(set_attr "conds" "set") 9103 (set_attr "shift" "4") 9104 (set_attr "arch" "32,a") 9105 (set_attr "type" "alus_shift_imm,alus_shift_reg")]) 9106 9107(define_insn "*arith_shiftsi_compare0_scratch" 9108 [(set (reg:CC_NOOV CC_REGNUM) 9109 (compare:CC_NOOV 9110 (match_operator:SI 1 "shiftable_operator" 9111 [(match_operator:SI 3 "shift_operator" 9112 [(match_operand:SI 4 "s_register_operand" "r,r") 9113 (match_operand:SI 5 "shift_amount_operand" "M,r")]) 9114 (match_operand:SI 2 "s_register_operand" "r,r")]) 9115 (const_int 0))) 9116 (clobber (match_scratch:SI 0 "=r,r"))] 9117 "TARGET_32BIT" 9118 "%i1s%?\\t%0, %2, %4%S3" 9119 [(set_attr "conds" "set") 9120 (set_attr "shift" "4") 9121 (set_attr "arch" "32,a") 9122 (set_attr "type" "alus_shift_imm,alus_shift_reg")]) 9123 9124(define_insn "*sub_shiftsi" 9125 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9126 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r") 9127 (match_operator:SI 2 "shift_operator" 9128 [(match_operand:SI 3 "s_register_operand" "r,r") 9129 (match_operand:SI 4 "shift_amount_operand" "M,r")])))] 9130 "TARGET_32BIT" 9131 "sub%?\\t%0, %1, %3%S2" 9132 [(set_attr "predicable" "yes") 9133 (set_attr "predicable_short_it" "no") 9134 (set_attr "shift" "3") 9135 (set_attr "arch" "32,a") 9136 (set_attr "type" "alus_shift_imm,alus_shift_reg")]) 9137 9138(define_insn "*sub_shiftsi_compare0" 9139 [(set (reg:CC_NOOV CC_REGNUM) 9140 (compare:CC_NOOV 9141 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 9142 (match_operator:SI 2 "shift_operator" 9143 [(match_operand:SI 3 "s_register_operand" "r,r,r") 9144 (match_operand:SI 4 "shift_amount_operand" "M,r,M")])) 9145 (const_int 0))) 9146 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 9147 (minus:SI (match_dup 1) 9148 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))] 9149 "TARGET_32BIT" 9150 "subs%?\\t%0, %1, %3%S2" 9151 [(set_attr "conds" "set") 9152 (set_attr "shift" "3") 9153 (set_attr "arch" "32,a,a") 9154 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 9155 9156(define_insn "*sub_shiftsi_compare0_scratch" 9157 [(set (reg:CC_NOOV CC_REGNUM) 9158 (compare:CC_NOOV 9159 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 9160 (match_operator:SI 2 "shift_operator" 9161 [(match_operand:SI 3 "s_register_operand" "r,r,r") 9162 (match_operand:SI 4 "shift_amount_operand" "M,r,M")])) 9163 (const_int 0))) 9164 (clobber (match_scratch:SI 0 "=r,r,r"))] 9165 "TARGET_32BIT" 9166 "subs%?\\t%0, %1, %3%S2" 9167 [(set_attr "conds" "set") 9168 (set_attr "shift" "3") 9169 (set_attr "arch" "32,a,a") 9170 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 9171 9172 9173(define_insn_and_split "*and_scc" 9174 [(set (match_operand:SI 0 "s_register_operand" "=r") 9175 (and:SI (match_operator:SI 1 "arm_comparison_operator" 9176 [(match_operand 2 "cc_register" "") (const_int 0)]) 9177 (match_operand:SI 3 "s_register_operand" "r")))] 9178 "TARGET_ARM" 9179 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1" 9180 "&& reload_completed" 9181 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0))) 9182 (cond_exec (match_dup 4) (set (match_dup 0) 9183 (and:SI (match_dup 3) (const_int 1))))] 9184 { 9185 machine_mode mode = GET_MODE (operands[2]); 9186 enum rtx_code rc = GET_CODE (operands[1]); 9187 9188 /* Note that operands[4] is the same as operands[1], 9189 but with VOIDmode as the result. */ 9190 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 9191 if (mode == CCFPmode || mode == CCFPEmode) 9192 rc = reverse_condition_maybe_unordered (rc); 9193 else 9194 rc = reverse_condition (rc); 9195 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 9196 } 9197 [(set_attr "conds" "use") 9198 (set_attr "type" "multiple") 9199 (set_attr "length" "8")] 9200) 9201 9202(define_insn_and_split "*ior_scc" 9203 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9204 (ior:SI (match_operator:SI 1 "arm_comparison_operator" 9205 [(match_operand 2 "cc_register" "") (const_int 0)]) 9206 (match_operand:SI 3 "s_register_operand" "0,?r")))] 9207 "TARGET_ARM" 9208 "@ 9209 orr%d1\\t%0, %3, #1 9210 #" 9211 "&& reload_completed 9212 && REGNO (operands [0]) != REGNO (operands[3])" 9213 ;; && which_alternative == 1 9214 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1 9215 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3))) 9216 (cond_exec (match_dup 4) (set (match_dup 0) 9217 (ior:SI (match_dup 3) (const_int 1))))] 9218 { 9219 machine_mode mode = GET_MODE (operands[2]); 9220 enum rtx_code rc = GET_CODE (operands[1]); 9221 9222 /* Note that operands[4] is the same as operands[1], 9223 but with VOIDmode as the result. */ 9224 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 9225 if (mode == CCFPmode || mode == CCFPEmode) 9226 rc = reverse_condition_maybe_unordered (rc); 9227 else 9228 rc = reverse_condition (rc); 9229 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 9230 } 9231 [(set_attr "conds" "use") 9232 (set_attr "length" "4,8") 9233 (set_attr "type" "logic_imm,multiple")] 9234) 9235 9236; A series of splitters for the compare_scc pattern below. Note that 9237; order is important. 9238(define_split 9239 [(set (match_operand:SI 0 "s_register_operand" "") 9240 (lt:SI (match_operand:SI 1 "s_register_operand" "") 9241 (const_int 0))) 9242 (clobber (reg:CC CC_REGNUM))] 9243 "TARGET_32BIT && reload_completed" 9244 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))]) 9245 9246(define_split 9247 [(set (match_operand:SI 0 "s_register_operand" "") 9248 (ge:SI (match_operand:SI 1 "s_register_operand" "") 9249 (const_int 0))) 9250 (clobber (reg:CC CC_REGNUM))] 9251 "TARGET_32BIT && reload_completed" 9252 [(set (match_dup 0) (not:SI (match_dup 1))) 9253 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))]) 9254 9255(define_split 9256 [(set (match_operand:SI 0 "s_register_operand" "") 9257 (eq:SI (match_operand:SI 1 "s_register_operand" "") 9258 (const_int 0))) 9259 (clobber (reg:CC CC_REGNUM))] 9260 "arm_arch5t && TARGET_32BIT" 9261 [(set (match_dup 0) (clz:SI (match_dup 1))) 9262 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))] 9263) 9264 9265(define_split 9266 [(set (match_operand:SI 0 "s_register_operand" "") 9267 (eq:SI (match_operand:SI 1 "s_register_operand" "") 9268 (const_int 0))) 9269 (clobber (reg:CC CC_REGNUM))] 9270 "TARGET_32BIT && reload_completed" 9271 [(parallel 9272 [(set (reg:CC CC_REGNUM) 9273 (compare:CC (const_int 1) (match_dup 1))) 9274 (set (match_dup 0) 9275 (minus:SI (const_int 1) (match_dup 1)))]) 9276 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0)) 9277 (set (match_dup 0) (const_int 0)))]) 9278 9279(define_split 9280 [(set (match_operand:SI 0 "s_register_operand" "") 9281 (ne:SI (match_operand:SI 1 "s_register_operand" "") 9282 (match_operand:SI 2 "const_int_operand" ""))) 9283 (clobber (reg:CC CC_REGNUM))] 9284 "TARGET_32BIT && reload_completed" 9285 [(parallel 9286 [(set (reg:CC CC_REGNUM) 9287 (compare:CC (match_dup 1) (match_dup 2))) 9288 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]) 9289 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0)) 9290 (set (match_dup 0) (const_int 1)))] 9291{ 9292 operands[3] = gen_int_mode (-INTVAL (operands[2]), SImode); 9293}) 9294 9295(define_split 9296 [(set (match_operand:SI 0 "s_register_operand" "") 9297 (ne:SI (match_operand:SI 1 "s_register_operand" "") 9298 (match_operand:SI 2 "arm_add_operand" ""))) 9299 (clobber (reg:CC CC_REGNUM))] 9300 "TARGET_32BIT && reload_completed" 9301 [(parallel 9302 [(set (reg:CC_NOOV CC_REGNUM) 9303 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2)) 9304 (const_int 0))) 9305 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 9306 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0)) 9307 (set (match_dup 0) (const_int 1)))]) 9308 9309(define_insn_and_split "*compare_scc" 9310 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 9311 (match_operator:SI 1 "arm_comparison_operator" 9312 [(match_operand:SI 2 "s_register_operand" "r,r") 9313 (match_operand:SI 3 "arm_add_operand" "rI,L")])) 9314 (clobber (reg:CC CC_REGNUM))] 9315 "TARGET_32BIT" 9316 "#" 9317 "&& reload_completed" 9318 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3))) 9319 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0))) 9320 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))] 9321{ 9322 rtx tmp1; 9323 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 9324 operands[2], operands[3]); 9325 enum rtx_code rc = GET_CODE (operands[1]); 9326 9327 tmp1 = gen_rtx_REG (mode, CC_REGNUM); 9328 9329 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx); 9330 if (mode == CCFPmode || mode == CCFPEmode) 9331 rc = reverse_condition_maybe_unordered (rc); 9332 else 9333 rc = reverse_condition (rc); 9334 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx); 9335} 9336 [(set_attr "type" "multiple")] 9337) 9338 9339;; Attempt to improve the sequence generated by the compare_scc splitters 9340;; not to use conditional execution. 9341 9342;; Rd = (eq (reg1) (const_int0)) // ARMv5 9343;; clz Rd, reg1 9344;; lsr Rd, Rd, #5 9345(define_peephole2 9346 [(set (reg:CC CC_REGNUM) 9347 (compare:CC (match_operand:SI 1 "register_operand" "") 9348 (const_int 0))) 9349 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9350 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9351 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9352 (set (match_dup 0) (const_int 1)))] 9353 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)" 9354 [(set (match_dup 0) (clz:SI (match_dup 1))) 9355 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))] 9356) 9357 9358;; Rd = (eq (reg1) (const_int0)) // !ARMv5 9359;; negs Rd, reg1 9360;; adc Rd, Rd, reg1 9361(define_peephole2 9362 [(set (reg:CC CC_REGNUM) 9363 (compare:CC (match_operand:SI 1 "register_operand" "") 9364 (const_int 0))) 9365 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9366 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9367 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9368 (set (match_dup 0) (const_int 1))) 9369 (match_scratch:SI 2 "r")] 9370 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)" 9371 [(parallel 9372 [(set (reg:CC CC_REGNUM) 9373 (compare:CC (const_int 0) (match_dup 1))) 9374 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))]) 9375 (set (match_dup 0) 9376 (plus:SI (plus:SI (match_dup 1) (match_dup 2)) 9377 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))] 9378) 9379 9380;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed. 9381;; sub Rd, Reg1, reg2 9382;; clz Rd, Rd 9383;; lsr Rd, Rd, #5 9384(define_peephole2 9385 [(set (reg:CC CC_REGNUM) 9386 (compare:CC (match_operand:SI 1 "register_operand" "") 9387 (match_operand:SI 2 "arm_rhs_operand" ""))) 9388 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9389 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9390 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9391 (set (match_dup 0) (const_int 1)))] 9392 "arm_arch5t && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM) 9393 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())" 9394 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2))) 9395 (set (match_dup 0) (clz:SI (match_dup 0))) 9396 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))] 9397) 9398 9399 9400;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size. 9401;; sub T1, Reg1, reg2 9402;; negs Rd, T1 9403;; adc Rd, Rd, T1 9404(define_peephole2 9405 [(set (reg:CC CC_REGNUM) 9406 (compare:CC (match_operand:SI 1 "register_operand" "") 9407 (match_operand:SI 2 "arm_rhs_operand" ""))) 9408 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9409 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9410 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9411 (set (match_dup 0) (const_int 1))) 9412 (match_scratch:SI 3 "r")] 9413 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)" 9414 [(set (match_dup 3) (match_dup 4)) 9415 (parallel 9416 [(set (reg:CC CC_REGNUM) 9417 (compare:CC (const_int 0) (match_dup 3))) 9418 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))]) 9419 (set (match_dup 0) 9420 (plus:SI (plus:SI (match_dup 0) (match_dup 3)) 9421 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))] 9422 " 9423 if (CONST_INT_P (operands[2])) 9424 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2])); 9425 else 9426 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]); 9427 ") 9428 9429(define_insn "*cond_move" 9430 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 9431 (if_then_else:SI (match_operator 3 "equality_operator" 9432 [(match_operator 4 "arm_comparison_operator" 9433 [(match_operand 5 "cc_register" "") (const_int 0)]) 9434 (const_int 0)]) 9435 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") 9436 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))] 9437 "TARGET_ARM" 9438 "* 9439 if (GET_CODE (operands[3]) == NE) 9440 { 9441 if (which_alternative != 1) 9442 output_asm_insn (\"mov%D4\\t%0, %2\", operands); 9443 if (which_alternative != 0) 9444 output_asm_insn (\"mov%d4\\t%0, %1\", operands); 9445 return \"\"; 9446 } 9447 if (which_alternative != 0) 9448 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 9449 if (which_alternative != 1) 9450 output_asm_insn (\"mov%d4\\t%0, %2\", operands); 9451 return \"\"; 9452 " 9453 [(set_attr "conds" "use") 9454 (set_attr_alternative "type" 9455 [(if_then_else (match_operand 2 "const_int_operand" "") 9456 (const_string "mov_imm") 9457 (const_string "mov_reg")) 9458 (if_then_else (match_operand 1 "const_int_operand" "") 9459 (const_string "mov_imm") 9460 (const_string "mov_reg")) 9461 (const_string "multiple")]) 9462 (set_attr "length" "4,4,8")] 9463) 9464 9465(define_insn "*cond_arith" 9466 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9467 (match_operator:SI 5 "shiftable_operator" 9468 [(match_operator:SI 4 "arm_comparison_operator" 9469 [(match_operand:SI 2 "s_register_operand" "r,r") 9470 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 9471 (match_operand:SI 1 "s_register_operand" "0,?r")])) 9472 (clobber (reg:CC CC_REGNUM))] 9473 "TARGET_ARM" 9474 "* 9475 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) 9476 return \"%i5\\t%0, %1, %2, lsr #31\"; 9477 9478 output_asm_insn (\"cmp\\t%2, %3\", operands); 9479 if (GET_CODE (operands[5]) == AND) 9480 output_asm_insn (\"mov%D4\\t%0, #0\", operands); 9481 else if (GET_CODE (operands[5]) == MINUS) 9482 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands); 9483 else if (which_alternative != 0) 9484 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 9485 return \"%i5%d4\\t%0, %1, #1\"; 9486 " 9487 [(set_attr "conds" "clob") 9488 (set_attr "length" "12") 9489 (set_attr "type" "multiple")] 9490) 9491 9492(define_insn "*cond_sub" 9493 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9494 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") 9495 (match_operator:SI 4 "arm_comparison_operator" 9496 [(match_operand:SI 2 "s_register_operand" "r,r") 9497 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) 9498 (clobber (reg:CC CC_REGNUM))] 9499 "TARGET_ARM" 9500 "* 9501 output_asm_insn (\"cmp\\t%2, %3\", operands); 9502 if (which_alternative != 0) 9503 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 9504 return \"sub%d4\\t%0, %1, #1\"; 9505 " 9506 [(set_attr "conds" "clob") 9507 (set_attr "length" "8,12") 9508 (set_attr "type" "multiple")] 9509) 9510 9511(define_insn "*cmp_ite0" 9512 [(set (match_operand 6 "dominant_cc_register" "") 9513 (compare 9514 (if_then_else:SI 9515 (match_operator 4 "arm_comparison_operator" 9516 [(match_operand:SI 0 "s_register_operand" 9517 "l,l,l,r,r,r,r,r,r") 9518 (match_operand:SI 1 "arm_add_operand" 9519 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9520 (match_operator:SI 5 "arm_comparison_operator" 9521 [(match_operand:SI 2 "s_register_operand" 9522 "l,r,r,l,l,r,r,r,r") 9523 (match_operand:SI 3 "arm_add_operand" 9524 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]) 9525 (const_int 0)) 9526 (const_int 0)))] 9527 "TARGET_32BIT" 9528 "* 9529 { 9530 static const char * const cmp1[NUM_OF_COND_CMP][2] = 9531 { 9532 {\"cmp%d5\\t%0, %1\", 9533 \"cmp%d4\\t%2, %3\"}, 9534 {\"cmn%d5\\t%0, #%n1\", 9535 \"cmp%d4\\t%2, %3\"}, 9536 {\"cmp%d5\\t%0, %1\", 9537 \"cmn%d4\\t%2, #%n3\"}, 9538 {\"cmn%d5\\t%0, #%n1\", 9539 \"cmn%d4\\t%2, #%n3\"} 9540 }; 9541 static const char * const cmp2[NUM_OF_COND_CMP][2] = 9542 { 9543 {\"cmp\\t%2, %3\", 9544 \"cmp\\t%0, %1\"}, 9545 {\"cmp\\t%2, %3\", 9546 \"cmn\\t%0, #%n1\"}, 9547 {\"cmn\\t%2, #%n3\", 9548 \"cmp\\t%0, %1\"}, 9549 {\"cmn\\t%2, #%n3\", 9550 \"cmn\\t%0, #%n1\"} 9551 }; 9552 static const char * const ite[2] = 9553 { 9554 \"it\\t%d5\", 9555 \"it\\t%d4\" 9556 }; 9557 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9558 CMP_CMP, CMN_CMP, CMP_CMP, 9559 CMN_CMP, CMP_CMN, CMN_CMN}; 9560 int swap = 9561 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 9562 9563 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9564 if (TARGET_THUMB2) { 9565 output_asm_insn (ite[swap], operands); 9566 } 9567 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9568 return \"\"; 9569 }" 9570 [(set_attr "conds" "set") 9571 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9572 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9573 (set_attr "type" "multiple") 9574 (set_attr_alternative "length" 9575 [(const_int 6) 9576 (const_int 8) 9577 (const_int 8) 9578 (const_int 8) 9579 (const_int 8) 9580 (if_then_else (eq_attr "is_thumb" "no") 9581 (const_int 8) 9582 (const_int 10)) 9583 (if_then_else (eq_attr "is_thumb" "no") 9584 (const_int 8) 9585 (const_int 10)) 9586 (if_then_else (eq_attr "is_thumb" "no") 9587 (const_int 8) 9588 (const_int 10)) 9589 (if_then_else (eq_attr "is_thumb" "no") 9590 (const_int 8) 9591 (const_int 10))])] 9592) 9593 9594(define_insn "*cmp_ite1" 9595 [(set (match_operand 6 "dominant_cc_register" "") 9596 (compare 9597 (if_then_else:SI 9598 (match_operator 4 "arm_comparison_operator" 9599 [(match_operand:SI 0 "s_register_operand" 9600 "l,l,l,r,r,r,r,r,r") 9601 (match_operand:SI 1 "arm_add_operand" 9602 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9603 (match_operator:SI 5 "arm_comparison_operator" 9604 [(match_operand:SI 2 "s_register_operand" 9605 "l,r,r,l,l,r,r,r,r") 9606 (match_operand:SI 3 "arm_add_operand" 9607 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]) 9608 (const_int 1)) 9609 (const_int 0)))] 9610 "TARGET_32BIT" 9611 "* 9612 { 9613 static const char * const cmp1[NUM_OF_COND_CMP][2] = 9614 { 9615 {\"cmp\\t%0, %1\", 9616 \"cmp\\t%2, %3\"}, 9617 {\"cmn\\t%0, #%n1\", 9618 \"cmp\\t%2, %3\"}, 9619 {\"cmp\\t%0, %1\", 9620 \"cmn\\t%2, #%n3\"}, 9621 {\"cmn\\t%0, #%n1\", 9622 \"cmn\\t%2, #%n3\"} 9623 }; 9624 static const char * const cmp2[NUM_OF_COND_CMP][2] = 9625 { 9626 {\"cmp%d4\\t%2, %3\", 9627 \"cmp%D5\\t%0, %1\"}, 9628 {\"cmp%d4\\t%2, %3\", 9629 \"cmn%D5\\t%0, #%n1\"}, 9630 {\"cmn%d4\\t%2, #%n3\", 9631 \"cmp%D5\\t%0, %1\"}, 9632 {\"cmn%d4\\t%2, #%n3\", 9633 \"cmn%D5\\t%0, #%n1\"} 9634 }; 9635 static const char * const ite[2] = 9636 { 9637 \"it\\t%d4\", 9638 \"it\\t%D5\" 9639 }; 9640 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9641 CMP_CMP, CMN_CMP, CMP_CMP, 9642 CMN_CMP, CMP_CMN, CMN_CMN}; 9643 int swap = 9644 comparison_dominates_p (GET_CODE (operands[5]), 9645 reverse_condition (GET_CODE (operands[4]))); 9646 9647 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9648 if (TARGET_THUMB2) { 9649 output_asm_insn (ite[swap], operands); 9650 } 9651 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9652 return \"\"; 9653 }" 9654 [(set_attr "conds" "set") 9655 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9656 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9657 (set_attr_alternative "length" 9658 [(const_int 6) 9659 (const_int 8) 9660 (const_int 8) 9661 (const_int 8) 9662 (const_int 8) 9663 (if_then_else (eq_attr "is_thumb" "no") 9664 (const_int 8) 9665 (const_int 10)) 9666 (if_then_else (eq_attr "is_thumb" "no") 9667 (const_int 8) 9668 (const_int 10)) 9669 (if_then_else (eq_attr "is_thumb" "no") 9670 (const_int 8) 9671 (const_int 10)) 9672 (if_then_else (eq_attr "is_thumb" "no") 9673 (const_int 8) 9674 (const_int 10))]) 9675 (set_attr "type" "multiple")] 9676) 9677 9678(define_insn "*cmp_and" 9679 [(set (match_operand 6 "dominant_cc_register" "") 9680 (compare 9681 (and:SI 9682 (match_operator 4 "arm_comparison_operator" 9683 [(match_operand:SI 0 "s_register_operand" 9684 "l,l,l,r,r,r,r,r,r") 9685 (match_operand:SI 1 "arm_add_operand" 9686 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9687 (match_operator:SI 5 "arm_comparison_operator" 9688 [(match_operand:SI 2 "s_register_operand" 9689 "l,r,r,l,l,r,r,r,r") 9690 (match_operand:SI 3 "arm_add_operand" 9691 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])) 9692 (const_int 0)))] 9693 "TARGET_32BIT" 9694 "* 9695 { 9696 static const char *const cmp1[NUM_OF_COND_CMP][2] = 9697 { 9698 {\"cmp%d5\\t%0, %1\", 9699 \"cmp%d4\\t%2, %3\"}, 9700 {\"cmn%d5\\t%0, #%n1\", 9701 \"cmp%d4\\t%2, %3\"}, 9702 {\"cmp%d5\\t%0, %1\", 9703 \"cmn%d4\\t%2, #%n3\"}, 9704 {\"cmn%d5\\t%0, #%n1\", 9705 \"cmn%d4\\t%2, #%n3\"} 9706 }; 9707 static const char *const cmp2[NUM_OF_COND_CMP][2] = 9708 { 9709 {\"cmp\\t%2, %3\", 9710 \"cmp\\t%0, %1\"}, 9711 {\"cmp\\t%2, %3\", 9712 \"cmn\\t%0, #%n1\"}, 9713 {\"cmn\\t%2, #%n3\", 9714 \"cmp\\t%0, %1\"}, 9715 {\"cmn\\t%2, #%n3\", 9716 \"cmn\\t%0, #%n1\"} 9717 }; 9718 static const char *const ite[2] = 9719 { 9720 \"it\\t%d5\", 9721 \"it\\t%d4\" 9722 }; 9723 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9724 CMP_CMP, CMN_CMP, CMP_CMP, 9725 CMN_CMP, CMP_CMN, CMN_CMN}; 9726 int swap = 9727 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 9728 9729 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9730 if (TARGET_THUMB2) { 9731 output_asm_insn (ite[swap], operands); 9732 } 9733 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9734 return \"\"; 9735 }" 9736 [(set_attr "conds" "set") 9737 (set_attr "predicable" "no") 9738 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9739 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9740 (set_attr_alternative "length" 9741 [(const_int 6) 9742 (const_int 8) 9743 (const_int 8) 9744 (const_int 8) 9745 (const_int 8) 9746 (if_then_else (eq_attr "is_thumb" "no") 9747 (const_int 8) 9748 (const_int 10)) 9749 (if_then_else (eq_attr "is_thumb" "no") 9750 (const_int 8) 9751 (const_int 10)) 9752 (if_then_else (eq_attr "is_thumb" "no") 9753 (const_int 8) 9754 (const_int 10)) 9755 (if_then_else (eq_attr "is_thumb" "no") 9756 (const_int 8) 9757 (const_int 10))]) 9758 (set_attr "type" "multiple")] 9759) 9760 9761(define_insn "*cmp_ior" 9762 [(set (match_operand 6 "dominant_cc_register" "") 9763 (compare 9764 (ior:SI 9765 (match_operator 4 "arm_comparison_operator" 9766 [(match_operand:SI 0 "s_register_operand" 9767 "l,l,l,r,r,r,r,r,r") 9768 (match_operand:SI 1 "arm_add_operand" 9769 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9770 (match_operator:SI 5 "arm_comparison_operator" 9771 [(match_operand:SI 2 "s_register_operand" 9772 "l,r,r,l,l,r,r,r,r") 9773 (match_operand:SI 3 "arm_add_operand" 9774 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])) 9775 (const_int 0)))] 9776 "TARGET_32BIT" 9777 "* 9778 { 9779 static const char *const cmp1[NUM_OF_COND_CMP][2] = 9780 { 9781 {\"cmp\\t%0, %1\", 9782 \"cmp\\t%2, %3\"}, 9783 {\"cmn\\t%0, #%n1\", 9784 \"cmp\\t%2, %3\"}, 9785 {\"cmp\\t%0, %1\", 9786 \"cmn\\t%2, #%n3\"}, 9787 {\"cmn\\t%0, #%n1\", 9788 \"cmn\\t%2, #%n3\"} 9789 }; 9790 static const char *const cmp2[NUM_OF_COND_CMP][2] = 9791 { 9792 {\"cmp%D4\\t%2, %3\", 9793 \"cmp%D5\\t%0, %1\"}, 9794 {\"cmp%D4\\t%2, %3\", 9795 \"cmn%D5\\t%0, #%n1\"}, 9796 {\"cmn%D4\\t%2, #%n3\", 9797 \"cmp%D5\\t%0, %1\"}, 9798 {\"cmn%D4\\t%2, #%n3\", 9799 \"cmn%D5\\t%0, #%n1\"} 9800 }; 9801 static const char *const ite[2] = 9802 { 9803 \"it\\t%D4\", 9804 \"it\\t%D5\" 9805 }; 9806 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9807 CMP_CMP, CMN_CMP, CMP_CMP, 9808 CMN_CMP, CMP_CMN, CMN_CMN}; 9809 int swap = 9810 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 9811 9812 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9813 if (TARGET_THUMB2) { 9814 output_asm_insn (ite[swap], operands); 9815 } 9816 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9817 return \"\"; 9818 } 9819 " 9820 [(set_attr "conds" "set") 9821 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9822 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9823 (set_attr_alternative "length" 9824 [(const_int 6) 9825 (const_int 8) 9826 (const_int 8) 9827 (const_int 8) 9828 (const_int 8) 9829 (if_then_else (eq_attr "is_thumb" "no") 9830 (const_int 8) 9831 (const_int 10)) 9832 (if_then_else (eq_attr "is_thumb" "no") 9833 (const_int 8) 9834 (const_int 10)) 9835 (if_then_else (eq_attr "is_thumb" "no") 9836 (const_int 8) 9837 (const_int 10)) 9838 (if_then_else (eq_attr "is_thumb" "no") 9839 (const_int 8) 9840 (const_int 10))]) 9841 (set_attr "type" "multiple")] 9842) 9843 9844(define_insn_and_split "*ior_scc_scc" 9845 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 9846 (ior:SI (match_operator:SI 3 "arm_comparison_operator" 9847 [(match_operand:SI 1 "s_register_operand" "l,r") 9848 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9849 (match_operator:SI 6 "arm_comparison_operator" 9850 [(match_operand:SI 4 "s_register_operand" "l,r") 9851 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))) 9852 (clobber (reg:CC CC_REGNUM))] 9853 "TARGET_32BIT 9854 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y) 9855 != CCmode)" 9856 "#" 9857 "TARGET_32BIT && reload_completed" 9858 [(set (match_dup 7) 9859 (compare 9860 (ior:SI 9861 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9862 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9863 (const_int 0))) 9864 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] 9865 "operands[7] 9866 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], 9867 DOM_CC_X_OR_Y), 9868 CC_REGNUM);" 9869 [(set_attr "conds" "clob") 9870 (set_attr "enabled_for_short_it" "yes,no") 9871 (set_attr "length" "16") 9872 (set_attr "type" "multiple")] 9873) 9874 9875; If the above pattern is followed by a CMP insn, then the compare is 9876; redundant, since we can rework the conditional instruction that follows. 9877(define_insn_and_split "*ior_scc_scc_cmp" 9878 [(set (match_operand 0 "dominant_cc_register" "") 9879 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator" 9880 [(match_operand:SI 1 "s_register_operand" "l,r") 9881 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9882 (match_operator:SI 6 "arm_comparison_operator" 9883 [(match_operand:SI 4 "s_register_operand" "l,r") 9884 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])) 9885 (const_int 0))) 9886 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts") 9887 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9888 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] 9889 "TARGET_32BIT" 9890 "#" 9891 "TARGET_32BIT && reload_completed" 9892 [(set (match_dup 0) 9893 (compare 9894 (ior:SI 9895 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9896 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9897 (const_int 0))) 9898 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] 9899 "" 9900 [(set_attr "conds" "set") 9901 (set_attr "enabled_for_short_it" "yes,no") 9902 (set_attr "length" "16") 9903 (set_attr "type" "multiple")] 9904) 9905 9906(define_insn_and_split "*and_scc_scc" 9907 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 9908 (and:SI (match_operator:SI 3 "arm_comparison_operator" 9909 [(match_operand:SI 1 "s_register_operand" "l,r") 9910 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9911 (match_operator:SI 6 "arm_comparison_operator" 9912 [(match_operand:SI 4 "s_register_operand" "l,r") 9913 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))) 9914 (clobber (reg:CC CC_REGNUM))] 9915 "TARGET_32BIT 9916 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) 9917 != CCmode)" 9918 "#" 9919 "TARGET_32BIT && reload_completed 9920 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) 9921 != CCmode)" 9922 [(set (match_dup 7) 9923 (compare 9924 (and:SI 9925 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9926 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9927 (const_int 0))) 9928 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] 9929 "operands[7] 9930 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], 9931 DOM_CC_X_AND_Y), 9932 CC_REGNUM);" 9933 [(set_attr "conds" "clob") 9934 (set_attr "enabled_for_short_it" "yes,no") 9935 (set_attr "length" "16") 9936 (set_attr "type" "multiple")] 9937) 9938 9939; If the above pattern is followed by a CMP insn, then the compare is 9940; redundant, since we can rework the conditional instruction that follows. 9941(define_insn_and_split "*and_scc_scc_cmp" 9942 [(set (match_operand 0 "dominant_cc_register" "") 9943 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator" 9944 [(match_operand:SI 1 "s_register_operand" "l,r") 9945 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9946 (match_operator:SI 6 "arm_comparison_operator" 9947 [(match_operand:SI 4 "s_register_operand" "l,r") 9948 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])) 9949 (const_int 0))) 9950 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts") 9951 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9952 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] 9953 "TARGET_32BIT" 9954 "#" 9955 "TARGET_32BIT && reload_completed" 9956 [(set (match_dup 0) 9957 (compare 9958 (and:SI 9959 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9960 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9961 (const_int 0))) 9962 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] 9963 "" 9964 [(set_attr "conds" "set") 9965 (set_attr "enabled_for_short_it" "yes,no") 9966 (set_attr "length" "16") 9967 (set_attr "type" "multiple")] 9968) 9969 9970;; If there is no dominance in the comparison, then we can still save an 9971;; instruction in the AND case, since we can know that the second compare 9972;; need only zero the value if false (if true, then the value is already 9973;; correct). 9974(define_insn_and_split "*and_scc_scc_nodom" 9975 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts") 9976 (and:SI (match_operator:SI 3 "arm_comparison_operator" 9977 [(match_operand:SI 1 "s_register_operand" "r,r,0") 9978 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")]) 9979 (match_operator:SI 6 "arm_comparison_operator" 9980 [(match_operand:SI 4 "s_register_operand" "r,r,r") 9981 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")]))) 9982 (clobber (reg:CC CC_REGNUM))] 9983 "TARGET_32BIT 9984 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) 9985 == CCmode)" 9986 "#" 9987 "TARGET_32BIT && reload_completed" 9988 [(parallel [(set (match_dup 0) 9989 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 9990 (clobber (reg:CC CC_REGNUM))]) 9991 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)])) 9992 (set (match_dup 0) 9993 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)]) 9994 (match_dup 0) 9995 (const_int 0)))] 9996 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]), 9997 operands[4], operands[5]), 9998 CC_REGNUM); 9999 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4], 10000 operands[5]);" 10001 [(set_attr "conds" "clob") 10002 (set_attr "length" "20") 10003 (set_attr "type" "multiple")] 10004) 10005 10006(define_split 10007 [(set (reg:CC_NOOV CC_REGNUM) 10008 (compare:CC_NOOV (ior:SI 10009 (and:SI (match_operand:SI 0 "s_register_operand" "") 10010 (const_int 1)) 10011 (match_operator:SI 1 "arm_comparison_operator" 10012 [(match_operand:SI 2 "s_register_operand" "") 10013 (match_operand:SI 3 "arm_add_operand" "")])) 10014 (const_int 0))) 10015 (clobber (match_operand:SI 4 "s_register_operand" ""))] 10016 "TARGET_ARM" 10017 [(set (match_dup 4) 10018 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) 10019 (match_dup 0))) 10020 (set (reg:CC_NOOV CC_REGNUM) 10021 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1)) 10022 (const_int 0)))] 10023 "") 10024 10025(define_split 10026 [(set (reg:CC_NOOV CC_REGNUM) 10027 (compare:CC_NOOV (ior:SI 10028 (match_operator:SI 1 "arm_comparison_operator" 10029 [(match_operand:SI 2 "s_register_operand" "") 10030 (match_operand:SI 3 "arm_add_operand" "")]) 10031 (and:SI (match_operand:SI 0 "s_register_operand" "") 10032 (const_int 1))) 10033 (const_int 0))) 10034 (clobber (match_operand:SI 4 "s_register_operand" ""))] 10035 "TARGET_ARM" 10036 [(set (match_dup 4) 10037 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) 10038 (match_dup 0))) 10039 (set (reg:CC_NOOV CC_REGNUM) 10040 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1)) 10041 (const_int 0)))] 10042 "") 10043;; ??? The conditional patterns above need checking for Thumb-2 usefulness 10044 10045(define_insn_and_split "*negscc" 10046 [(set (match_operand:SI 0 "s_register_operand" "=r") 10047 (neg:SI (match_operator 3 "arm_comparison_operator" 10048 [(match_operand:SI 1 "s_register_operand" "r") 10049 (match_operand:SI 2 "arm_rhs_operand" "rI")]))) 10050 (clobber (reg:CC CC_REGNUM))] 10051 "TARGET_ARM" 10052 "#" 10053 "&& reload_completed" 10054 [(const_int 0)] 10055 { 10056 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); 10057 10058 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx) 10059 { 10060 /* Emit mov\\t%0, %1, asr #31 */ 10061 emit_insn (gen_rtx_SET (operands[0], 10062 gen_rtx_ASHIFTRT (SImode, 10063 operands[1], 10064 GEN_INT (31)))); 10065 DONE; 10066 } 10067 else if (GET_CODE (operands[3]) == NE) 10068 { 10069 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */ 10070 if (CONST_INT_P (operands[2])) 10071 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2], 10072 gen_int_mode (-INTVAL (operands[2]), 10073 SImode))); 10074 else 10075 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2])); 10076 10077 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 10078 gen_rtx_NE (SImode, 10079 cc_reg, 10080 const0_rtx), 10081 gen_rtx_SET (operands[0], 10082 GEN_INT (~0)))); 10083 DONE; 10084 } 10085 else 10086 { 10087 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */ 10088 emit_insn (gen_rtx_SET (cc_reg, 10089 gen_rtx_COMPARE (CCmode, operands[1], operands[2]))); 10090 enum rtx_code rc = GET_CODE (operands[3]); 10091 10092 rc = reverse_condition (rc); 10093 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 10094 gen_rtx_fmt_ee (rc, 10095 VOIDmode, 10096 cc_reg, 10097 const0_rtx), 10098 gen_rtx_SET (operands[0], const0_rtx))); 10099 rc = GET_CODE (operands[3]); 10100 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 10101 gen_rtx_fmt_ee (rc, 10102 VOIDmode, 10103 cc_reg, 10104 const0_rtx), 10105 gen_rtx_SET (operands[0], 10106 GEN_INT (~0)))); 10107 DONE; 10108 } 10109 FAIL; 10110 } 10111 [(set_attr "conds" "clob") 10112 (set_attr "length" "12") 10113 (set_attr "type" "multiple")] 10114) 10115 10116(define_insn_and_split "movcond_addsi" 10117 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") 10118 (if_then_else:SI 10119 (match_operator 5 "comparison_operator" 10120 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r") 10121 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")) 10122 (const_int 0)]) 10123 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r") 10124 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r"))) 10125 (clobber (reg:CC CC_REGNUM))] 10126 "TARGET_32BIT" 10127 "#" 10128 "&& reload_completed" 10129 [(set (reg:CC_NOOV CC_REGNUM) 10130 (compare:CC_NOOV 10131 (plus:SI (match_dup 3) 10132 (match_dup 4)) 10133 (const_int 0))) 10134 (set (match_dup 0) (match_dup 1)) 10135 (cond_exec (match_dup 6) 10136 (set (match_dup 0) (match_dup 2)))] 10137 " 10138 { 10139 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]), 10140 operands[3], operands[4]); 10141 enum rtx_code rc = GET_CODE (operands[5]); 10142 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 10143 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode)); 10144 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0])) 10145 rc = reverse_condition (rc); 10146 else 10147 std::swap (operands[1], operands[2]); 10148 10149 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 10150 } 10151 " 10152 [(set_attr "conds" "clob") 10153 (set_attr "enabled_for_short_it" "no,yes,yes") 10154 (set_attr "type" "multiple")] 10155) 10156 10157(define_insn "movcond" 10158 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10159 (if_then_else:SI 10160 (match_operator 5 "arm_comparison_operator" 10161 [(match_operand:SI 3 "s_register_operand" "r,r,r") 10162 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")]) 10163 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") 10164 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 10165 (clobber (reg:CC CC_REGNUM))] 10166 "TARGET_ARM" 10167 "* 10168 if (GET_CODE (operands[5]) == LT 10169 && (operands[4] == const0_rtx)) 10170 { 10171 if (which_alternative != 1 && REG_P (operands[1])) 10172 { 10173 if (operands[2] == const0_rtx) 10174 return \"and\\t%0, %1, %3, asr #31\"; 10175 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\"; 10176 } 10177 else if (which_alternative != 0 && REG_P (operands[2])) 10178 { 10179 if (operands[1] == const0_rtx) 10180 return \"bic\\t%0, %2, %3, asr #31\"; 10181 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\"; 10182 } 10183 /* The only case that falls through to here is when both ops 1 & 2 10184 are constants. */ 10185 } 10186 10187 if (GET_CODE (operands[5]) == GE 10188 && (operands[4] == const0_rtx)) 10189 { 10190 if (which_alternative != 1 && REG_P (operands[1])) 10191 { 10192 if (operands[2] == const0_rtx) 10193 return \"bic\\t%0, %1, %3, asr #31\"; 10194 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\"; 10195 } 10196 else if (which_alternative != 0 && REG_P (operands[2])) 10197 { 10198 if (operands[1] == const0_rtx) 10199 return \"and\\t%0, %2, %3, asr #31\"; 10200 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\"; 10201 } 10202 /* The only case that falls through to here is when both ops 1 & 2 10203 are constants. */ 10204 } 10205 if (CONST_INT_P (operands[4]) 10206 && !const_ok_for_arm (INTVAL (operands[4]))) 10207 output_asm_insn (\"cmn\\t%3, #%n4\", operands); 10208 else 10209 output_asm_insn (\"cmp\\t%3, %4\", operands); 10210 if (which_alternative != 0) 10211 output_asm_insn (\"mov%d5\\t%0, %1\", operands); 10212 if (which_alternative != 1) 10213 output_asm_insn (\"mov%D5\\t%0, %2\", operands); 10214 return \"\"; 10215 " 10216 [(set_attr "conds" "clob") 10217 (set_attr "length" "8,8,12") 10218 (set_attr "type" "multiple")] 10219) 10220 10221;; ??? The patterns below need checking for Thumb-2 usefulness. 10222 10223(define_insn "*ifcompare_plus_move" 10224 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10225 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 10226 [(match_operand:SI 4 "s_register_operand" "r,r") 10227 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10228 (plus:SI 10229 (match_operand:SI 2 "s_register_operand" "r,r") 10230 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")) 10231 (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) 10232 (clobber (reg:CC CC_REGNUM))] 10233 "TARGET_ARM" 10234 "#" 10235 [(set_attr "conds" "clob") 10236 (set_attr "length" "8,12") 10237 (set_attr "type" "multiple")] 10238) 10239 10240(define_insn "*if_plus_move" 10241 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") 10242 (if_then_else:SI 10243 (match_operator 4 "arm_comparison_operator" 10244 [(match_operand 5 "cc_register" "") (const_int 0)]) 10245 (plus:SI 10246 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 10247 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")) 10248 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))] 10249 "TARGET_ARM" 10250 "@ 10251 add%d4\\t%0, %2, %3 10252 sub%d4\\t%0, %2, #%n3 10253 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1 10254 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1" 10255 [(set_attr "conds" "use") 10256 (set_attr "length" "4,4,8,8") 10257 (set_attr_alternative "type" 10258 [(if_then_else (match_operand 3 "const_int_operand" "") 10259 (const_string "alu_imm" ) 10260 (const_string "alu_sreg")) 10261 (const_string "alu_imm") 10262 (const_string "multiple") 10263 (const_string "multiple")])] 10264) 10265 10266(define_insn "*ifcompare_move_plus" 10267 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10268 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 10269 [(match_operand:SI 4 "s_register_operand" "r,r") 10270 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10271 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 10272 (plus:SI 10273 (match_operand:SI 2 "s_register_operand" "r,r") 10274 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")))) 10275 (clobber (reg:CC CC_REGNUM))] 10276 "TARGET_ARM" 10277 "#" 10278 [(set_attr "conds" "clob") 10279 (set_attr "length" "8,12") 10280 (set_attr "type" "multiple")] 10281) 10282 10283(define_insn "*if_move_plus" 10284 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") 10285 (if_then_else:SI 10286 (match_operator 4 "arm_comparison_operator" 10287 [(match_operand 5 "cc_register" "") (const_int 0)]) 10288 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI") 10289 (plus:SI 10290 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 10291 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))] 10292 "TARGET_ARM" 10293 "@ 10294 add%D4\\t%0, %2, %3 10295 sub%D4\\t%0, %2, #%n3 10296 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1 10297 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1" 10298 [(set_attr "conds" "use") 10299 (set_attr "length" "4,4,8,8") 10300 (set_attr_alternative "type" 10301 [(if_then_else (match_operand 3 "const_int_operand" "") 10302 (const_string "alu_imm" ) 10303 (const_string "alu_sreg")) 10304 (const_string "alu_imm") 10305 (const_string "multiple") 10306 (const_string "multiple")])] 10307) 10308 10309(define_insn "*ifcompare_arith_arith" 10310 [(set (match_operand:SI 0 "s_register_operand" "=r") 10311 (if_then_else:SI (match_operator 9 "arm_comparison_operator" 10312 [(match_operand:SI 5 "s_register_operand" "r") 10313 (match_operand:SI 6 "arm_add_operand" "rIL")]) 10314 (match_operator:SI 8 "shiftable_operator" 10315 [(match_operand:SI 1 "s_register_operand" "r") 10316 (match_operand:SI 2 "arm_rhs_operand" "rI")]) 10317 (match_operator:SI 7 "shiftable_operator" 10318 [(match_operand:SI 3 "s_register_operand" "r") 10319 (match_operand:SI 4 "arm_rhs_operand" "rI")]))) 10320 (clobber (reg:CC CC_REGNUM))] 10321 "TARGET_ARM" 10322 "#" 10323 [(set_attr "conds" "clob") 10324 (set_attr "length" "12") 10325 (set_attr "type" "multiple")] 10326) 10327 10328(define_insn "*if_arith_arith" 10329 [(set (match_operand:SI 0 "s_register_operand" "=r") 10330 (if_then_else:SI (match_operator 5 "arm_comparison_operator" 10331 [(match_operand 8 "cc_register" "") (const_int 0)]) 10332 (match_operator:SI 6 "shiftable_operator" 10333 [(match_operand:SI 1 "s_register_operand" "r") 10334 (match_operand:SI 2 "arm_rhs_operand" "rI")]) 10335 (match_operator:SI 7 "shiftable_operator" 10336 [(match_operand:SI 3 "s_register_operand" "r") 10337 (match_operand:SI 4 "arm_rhs_operand" "rI")])))] 10338 "TARGET_ARM" 10339 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4" 10340 [(set_attr "conds" "use") 10341 (set_attr "length" "8") 10342 (set_attr "type" "multiple")] 10343) 10344 10345(define_insn "*ifcompare_arith_move" 10346 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10347 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 10348 [(match_operand:SI 2 "s_register_operand" "r,r") 10349 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")]) 10350 (match_operator:SI 7 "shiftable_operator" 10351 [(match_operand:SI 4 "s_register_operand" "r,r") 10352 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")]) 10353 (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) 10354 (clobber (reg:CC CC_REGNUM))] 10355 "TARGET_ARM" 10356 "* 10357 /* If we have an operation where (op x 0) is the identity operation and 10358 the conditional operator is LT or GE and we are comparing against zero and 10359 everything is in registers then we can do this in two instructions. */ 10360 if (operands[3] == const0_rtx 10361 && GET_CODE (operands[7]) != AND 10362 && REG_P (operands[5]) 10363 && REG_P (operands[1]) 10364 && REGNO (operands[1]) == REGNO (operands[4]) 10365 && REGNO (operands[4]) != REGNO (operands[0])) 10366 { 10367 if (GET_CODE (operands[6]) == LT) 10368 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; 10369 else if (GET_CODE (operands[6]) == GE) 10370 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; 10371 } 10372 if (CONST_INT_P (operands[3]) 10373 && !const_ok_for_arm (INTVAL (operands[3]))) 10374 output_asm_insn (\"cmn\\t%2, #%n3\", operands); 10375 else 10376 output_asm_insn (\"cmp\\t%2, %3\", operands); 10377 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands); 10378 if (which_alternative != 0) 10379 return \"mov%D6\\t%0, %1\"; 10380 return \"\"; 10381 " 10382 [(set_attr "conds" "clob") 10383 (set_attr "length" "8,12") 10384 (set_attr "type" "multiple")] 10385) 10386 10387(define_insn "*if_arith_move" 10388 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10389 (if_then_else:SI (match_operator 4 "arm_comparison_operator" 10390 [(match_operand 6 "cc_register" "") (const_int 0)]) 10391 (match_operator:SI 5 "shiftable_operator" 10392 [(match_operand:SI 2 "s_register_operand" "r,r") 10393 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 10394 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))] 10395 "TARGET_ARM" 10396 "@ 10397 %I5%d4\\t%0, %2, %3 10398 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1" 10399 [(set_attr "conds" "use") 10400 (set_attr "length" "4,8") 10401 (set_attr_alternative "type" 10402 [(if_then_else (match_operand 3 "const_int_operand" "") 10403 (const_string "alu_shift_imm" ) 10404 (const_string "alu_shift_reg")) 10405 (const_string "multiple")])] 10406) 10407 10408(define_insn "*ifcompare_move_arith" 10409 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10410 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 10411 [(match_operand:SI 4 "s_register_operand" "r,r") 10412 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10413 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 10414 (match_operator:SI 7 "shiftable_operator" 10415 [(match_operand:SI 2 "s_register_operand" "r,r") 10416 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) 10417 (clobber (reg:CC CC_REGNUM))] 10418 "TARGET_ARM" 10419 "* 10420 /* If we have an operation where (op x 0) is the identity operation and 10421 the conditional operator is LT or GE and we are comparing against zero and 10422 everything is in registers then we can do this in two instructions */ 10423 if (operands[5] == const0_rtx 10424 && GET_CODE (operands[7]) != AND 10425 && REG_P (operands[3]) 10426 && REG_P (operands[1]) 10427 && REGNO (operands[1]) == REGNO (operands[2]) 10428 && REGNO (operands[2]) != REGNO (operands[0])) 10429 { 10430 if (GET_CODE (operands[6]) == GE) 10431 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; 10432 else if (GET_CODE (operands[6]) == LT) 10433 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; 10434 } 10435 10436 if (CONST_INT_P (operands[5]) 10437 && !const_ok_for_arm (INTVAL (operands[5]))) 10438 output_asm_insn (\"cmn\\t%4, #%n5\", operands); 10439 else 10440 output_asm_insn (\"cmp\\t%4, %5\", operands); 10441 10442 if (which_alternative != 0) 10443 output_asm_insn (\"mov%d6\\t%0, %1\", operands); 10444 return \"%I7%D6\\t%0, %2, %3\"; 10445 " 10446 [(set_attr "conds" "clob") 10447 (set_attr "length" "8,12") 10448 (set_attr "type" "multiple")] 10449) 10450 10451(define_insn "*if_move_arith" 10452 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10453 (if_then_else:SI 10454 (match_operator 4 "arm_comparison_operator" 10455 [(match_operand 6 "cc_register" "") (const_int 0)]) 10456 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 10457 (match_operator:SI 5 "shiftable_operator" 10458 [(match_operand:SI 2 "s_register_operand" "r,r") 10459 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))] 10460 "TARGET_ARM" 10461 "@ 10462 %I5%D4\\t%0, %2, %3 10463 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1" 10464 [(set_attr "conds" "use") 10465 (set_attr "length" "4,8") 10466 (set_attr_alternative "type" 10467 [(if_then_else (match_operand 3 "const_int_operand" "") 10468 (const_string "alu_shift_imm" ) 10469 (const_string "alu_shift_reg")) 10470 (const_string "multiple")])] 10471) 10472 10473(define_insn "*ifcompare_move_not" 10474 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10475 (if_then_else:SI 10476 (match_operator 5 "arm_comparison_operator" 10477 [(match_operand:SI 3 "s_register_operand" "r,r") 10478 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10479 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 10480 (not:SI 10481 (match_operand:SI 2 "s_register_operand" "r,r")))) 10482 (clobber (reg:CC CC_REGNUM))] 10483 "TARGET_ARM" 10484 "#" 10485 [(set_attr "conds" "clob") 10486 (set_attr "length" "8,12") 10487 (set_attr "type" "multiple")] 10488) 10489 10490(define_insn "*if_move_not" 10491 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10492 (if_then_else:SI 10493 (match_operator 4 "arm_comparison_operator" 10494 [(match_operand 3 "cc_register" "") (const_int 0)]) 10495 (match_operand:SI 1 "arm_not_operand" "0,?rI,K") 10496 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))] 10497 "TARGET_ARM" 10498 "@ 10499 mvn%D4\\t%0, %2 10500 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2 10501 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2" 10502 [(set_attr "conds" "use") 10503 (set_attr "type" "mvn_reg") 10504 (set_attr "length" "4,8,8") 10505 (set_attr "type" "mvn_reg,multiple,multiple")] 10506) 10507 10508(define_insn "*ifcompare_not_move" 10509 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10510 (if_then_else:SI 10511 (match_operator 5 "arm_comparison_operator" 10512 [(match_operand:SI 3 "s_register_operand" "r,r") 10513 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10514 (not:SI 10515 (match_operand:SI 2 "s_register_operand" "r,r")) 10516 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 10517 (clobber (reg:CC CC_REGNUM))] 10518 "TARGET_ARM" 10519 "#" 10520 [(set_attr "conds" "clob") 10521 (set_attr "length" "8,12") 10522 (set_attr "type" "multiple")] 10523) 10524 10525(define_insn "*if_not_move" 10526 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10527 (if_then_else:SI 10528 (match_operator 4 "arm_comparison_operator" 10529 [(match_operand 3 "cc_register" "") (const_int 0)]) 10530 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r")) 10531 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] 10532 "TARGET_ARM" 10533 "@ 10534 mvn%d4\\t%0, %2 10535 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2 10536 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2" 10537 [(set_attr "conds" "use") 10538 (set_attr "type" "mvn_reg,multiple,multiple") 10539 (set_attr "length" "4,8,8")] 10540) 10541 10542(define_insn "*ifcompare_shift_move" 10543 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10544 (if_then_else:SI 10545 (match_operator 6 "arm_comparison_operator" 10546 [(match_operand:SI 4 "s_register_operand" "r,r") 10547 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10548 (match_operator:SI 7 "shift_operator" 10549 [(match_operand:SI 2 "s_register_operand" "r,r") 10550 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]) 10551 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 10552 (clobber (reg:CC CC_REGNUM))] 10553 "TARGET_ARM" 10554 "#" 10555 [(set_attr "conds" "clob") 10556 (set_attr "length" "8,12") 10557 (set_attr "type" "multiple")] 10558) 10559 10560(define_insn "*if_shift_move" 10561 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10562 (if_then_else:SI 10563 (match_operator 5 "arm_comparison_operator" 10564 [(match_operand 6 "cc_register" "") (const_int 0)]) 10565 (match_operator:SI 4 "shift_operator" 10566 [(match_operand:SI 2 "s_register_operand" "r,r,r") 10567 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")]) 10568 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] 10569 "TARGET_ARM" 10570 "@ 10571 mov%d5\\t%0, %2%S4 10572 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4 10573 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4" 10574 [(set_attr "conds" "use") 10575 (set_attr "shift" "2") 10576 (set_attr "length" "4,8,8") 10577 (set_attr_alternative "type" 10578 [(if_then_else (match_operand 3 "const_int_operand" "") 10579 (const_string "mov_shift" ) 10580 (const_string "mov_shift_reg")) 10581 (const_string "multiple") 10582 (const_string "multiple")])] 10583) 10584 10585(define_insn "*ifcompare_move_shift" 10586 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10587 (if_then_else:SI 10588 (match_operator 6 "arm_comparison_operator" 10589 [(match_operand:SI 4 "s_register_operand" "r,r") 10590 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10591 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 10592 (match_operator:SI 7 "shift_operator" 10593 [(match_operand:SI 2 "s_register_operand" "r,r") 10594 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]))) 10595 (clobber (reg:CC CC_REGNUM))] 10596 "TARGET_ARM" 10597 "#" 10598 [(set_attr "conds" "clob") 10599 (set_attr "length" "8,12") 10600 (set_attr "type" "multiple")] 10601) 10602 10603(define_insn "*if_move_shift" 10604 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10605 (if_then_else:SI 10606 (match_operator 5 "arm_comparison_operator" 10607 [(match_operand 6 "cc_register" "") (const_int 0)]) 10608 (match_operand:SI 1 "arm_not_operand" "0,?rI,K") 10609 (match_operator:SI 4 "shift_operator" 10610 [(match_operand:SI 2 "s_register_operand" "r,r,r") 10611 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))] 10612 "TARGET_ARM" 10613 "@ 10614 mov%D5\\t%0, %2%S4 10615 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4 10616 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4" 10617 [(set_attr "conds" "use") 10618 (set_attr "shift" "2") 10619 (set_attr "length" "4,8,8") 10620 (set_attr_alternative "type" 10621 [(if_then_else (match_operand 3 "const_int_operand" "") 10622 (const_string "mov_shift" ) 10623 (const_string "mov_shift_reg")) 10624 (const_string "multiple") 10625 (const_string "multiple")])] 10626) 10627 10628(define_insn "*ifcompare_shift_shift" 10629 [(set (match_operand:SI 0 "s_register_operand" "=r") 10630 (if_then_else:SI 10631 (match_operator 7 "arm_comparison_operator" 10632 [(match_operand:SI 5 "s_register_operand" "r") 10633 (match_operand:SI 6 "arm_add_operand" "rIL")]) 10634 (match_operator:SI 8 "shift_operator" 10635 [(match_operand:SI 1 "s_register_operand" "r") 10636 (match_operand:SI 2 "arm_rhs_operand" "rM")]) 10637 (match_operator:SI 9 "shift_operator" 10638 [(match_operand:SI 3 "s_register_operand" "r") 10639 (match_operand:SI 4 "arm_rhs_operand" "rM")]))) 10640 (clobber (reg:CC CC_REGNUM))] 10641 "TARGET_ARM" 10642 "#" 10643 [(set_attr "conds" "clob") 10644 (set_attr "length" "12") 10645 (set_attr "type" "multiple")] 10646) 10647 10648(define_insn "*if_shift_shift" 10649 [(set (match_operand:SI 0 "s_register_operand" "=r") 10650 (if_then_else:SI 10651 (match_operator 5 "arm_comparison_operator" 10652 [(match_operand 8 "cc_register" "") (const_int 0)]) 10653 (match_operator:SI 6 "shift_operator" 10654 [(match_operand:SI 1 "s_register_operand" "r") 10655 (match_operand:SI 2 "arm_rhs_operand" "rM")]) 10656 (match_operator:SI 7 "shift_operator" 10657 [(match_operand:SI 3 "s_register_operand" "r") 10658 (match_operand:SI 4 "arm_rhs_operand" "rM")])))] 10659 "TARGET_ARM" 10660 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7" 10661 [(set_attr "conds" "use") 10662 (set_attr "shift" "1") 10663 (set_attr "length" "8") 10664 (set (attr "type") (if_then_else 10665 (and (match_operand 2 "const_int_operand" "") 10666 (match_operand 4 "const_int_operand" "")) 10667 (const_string "mov_shift") 10668 (const_string "mov_shift_reg")))] 10669) 10670 10671(define_insn "*ifcompare_not_arith" 10672 [(set (match_operand:SI 0 "s_register_operand" "=r") 10673 (if_then_else:SI 10674 (match_operator 6 "arm_comparison_operator" 10675 [(match_operand:SI 4 "s_register_operand" "r") 10676 (match_operand:SI 5 "arm_add_operand" "rIL")]) 10677 (not:SI (match_operand:SI 1 "s_register_operand" "r")) 10678 (match_operator:SI 7 "shiftable_operator" 10679 [(match_operand:SI 2 "s_register_operand" "r") 10680 (match_operand:SI 3 "arm_rhs_operand" "rI")]))) 10681 (clobber (reg:CC CC_REGNUM))] 10682 "TARGET_ARM" 10683 "#" 10684 [(set_attr "conds" "clob") 10685 (set_attr "length" "12") 10686 (set_attr "type" "multiple")] 10687) 10688 10689(define_insn "*if_not_arith" 10690 [(set (match_operand:SI 0 "s_register_operand" "=r") 10691 (if_then_else:SI 10692 (match_operator 5 "arm_comparison_operator" 10693 [(match_operand 4 "cc_register" "") (const_int 0)]) 10694 (not:SI (match_operand:SI 1 "s_register_operand" "r")) 10695 (match_operator:SI 6 "shiftable_operator" 10696 [(match_operand:SI 2 "s_register_operand" "r") 10697 (match_operand:SI 3 "arm_rhs_operand" "rI")])))] 10698 "TARGET_ARM" 10699 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3" 10700 [(set_attr "conds" "use") 10701 (set_attr "type" "mvn_reg") 10702 (set_attr "length" "8")] 10703) 10704 10705(define_insn "*ifcompare_arith_not" 10706 [(set (match_operand:SI 0 "s_register_operand" "=r") 10707 (if_then_else:SI 10708 (match_operator 6 "arm_comparison_operator" 10709 [(match_operand:SI 4 "s_register_operand" "r") 10710 (match_operand:SI 5 "arm_add_operand" "rIL")]) 10711 (match_operator:SI 7 "shiftable_operator" 10712 [(match_operand:SI 2 "s_register_operand" "r") 10713 (match_operand:SI 3 "arm_rhs_operand" "rI")]) 10714 (not:SI (match_operand:SI 1 "s_register_operand" "r")))) 10715 (clobber (reg:CC CC_REGNUM))] 10716 "TARGET_ARM" 10717 "#" 10718 [(set_attr "conds" "clob") 10719 (set_attr "length" "12") 10720 (set_attr "type" "multiple")] 10721) 10722 10723(define_insn "*if_arith_not" 10724 [(set (match_operand:SI 0 "s_register_operand" "=r") 10725 (if_then_else:SI 10726 (match_operator 5 "arm_comparison_operator" 10727 [(match_operand 4 "cc_register" "") (const_int 0)]) 10728 (match_operator:SI 6 "shiftable_operator" 10729 [(match_operand:SI 2 "s_register_operand" "r") 10730 (match_operand:SI 3 "arm_rhs_operand" "rI")]) 10731 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))] 10732 "TARGET_ARM" 10733 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3" 10734 [(set_attr "conds" "use") 10735 (set_attr "type" "multiple") 10736 (set_attr "length" "8")] 10737) 10738 10739(define_insn "*ifcompare_neg_move" 10740 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10741 (if_then_else:SI 10742 (match_operator 5 "arm_comparison_operator" 10743 [(match_operand:SI 3 "s_register_operand" "r,r") 10744 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10745 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")) 10746 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 10747 (clobber (reg:CC CC_REGNUM))] 10748 "TARGET_ARM" 10749 "#" 10750 [(set_attr "conds" "clob") 10751 (set_attr "length" "8,12") 10752 (set_attr "type" "multiple")] 10753) 10754 10755(define_insn_and_split "*if_neg_move" 10756 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 10757 (if_then_else:SI 10758 (match_operator 4 "arm_comparison_operator" 10759 [(match_operand 3 "cc_register" "") (const_int 0)]) 10760 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r")) 10761 (match_operand:SI 1 "s_register_operand" "0,0")))] 10762 "TARGET_32BIT" 10763 "#" 10764 "&& reload_completed" 10765 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)]) 10766 (set (match_dup 0) (neg:SI (match_dup 2))))] 10767 "" 10768 [(set_attr "conds" "use") 10769 (set_attr "length" "4") 10770 (set_attr "arch" "t2,32") 10771 (set_attr "enabled_for_short_it" "yes,no") 10772 (set_attr "type" "logic_shift_imm")] 10773) 10774 10775(define_insn "*ifcompare_move_neg" 10776 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10777 (if_then_else:SI 10778 (match_operator 5 "arm_comparison_operator" 10779 [(match_operand:SI 3 "s_register_operand" "r,r") 10780 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10781 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 10782 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")))) 10783 (clobber (reg:CC CC_REGNUM))] 10784 "TARGET_ARM" 10785 "#" 10786 [(set_attr "conds" "clob") 10787 (set_attr "length" "8,12") 10788 (set_attr "type" "multiple")] 10789) 10790 10791(define_insn_and_split "*if_move_neg" 10792 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 10793 (if_then_else:SI 10794 (match_operator 4 "arm_comparison_operator" 10795 [(match_operand 3 "cc_register" "") (const_int 0)]) 10796 (match_operand:SI 1 "s_register_operand" "0,0") 10797 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))] 10798 "TARGET_32BIT" 10799 "#" 10800 "&& reload_completed" 10801 [(cond_exec (match_dup 5) 10802 (set (match_dup 0) (neg:SI (match_dup 2))))] 10803 { 10804 machine_mode mode = GET_MODE (operands[3]); 10805 rtx_code rc = GET_CODE (operands[4]); 10806 10807 if (mode == CCFPmode || mode == CCFPEmode) 10808 rc = reverse_condition_maybe_unordered (rc); 10809 else 10810 rc = reverse_condition (rc); 10811 10812 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx); 10813 } 10814 [(set_attr "conds" "use") 10815 (set_attr "length" "4") 10816 (set_attr "arch" "t2,32") 10817 (set_attr "enabled_for_short_it" "yes,no") 10818 (set_attr "type" "logic_shift_imm")] 10819) 10820 10821(define_insn "*arith_adjacentmem" 10822 [(set (match_operand:SI 0 "s_register_operand" "=r") 10823 (match_operator:SI 1 "shiftable_operator" 10824 [(match_operand:SI 2 "memory_operand" "m") 10825 (match_operand:SI 3 "memory_operand" "m")])) 10826 (clobber (match_scratch:SI 4 "=r"))] 10827 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])" 10828 "* 10829 { 10830 rtx ldm[3]; 10831 rtx arith[4]; 10832 rtx base_reg; 10833 HOST_WIDE_INT val1 = 0, val2 = 0; 10834 10835 if (REGNO (operands[0]) > REGNO (operands[4])) 10836 { 10837 ldm[1] = operands[4]; 10838 ldm[2] = operands[0]; 10839 } 10840 else 10841 { 10842 ldm[1] = operands[0]; 10843 ldm[2] = operands[4]; 10844 } 10845 10846 base_reg = XEXP (operands[2], 0); 10847 10848 if (!REG_P (base_reg)) 10849 { 10850 val1 = INTVAL (XEXP (base_reg, 1)); 10851 base_reg = XEXP (base_reg, 0); 10852 } 10853 10854 if (!REG_P (XEXP (operands[3], 0))) 10855 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1)); 10856 10857 arith[0] = operands[0]; 10858 arith[3] = operands[1]; 10859 10860 if (val1 < val2) 10861 { 10862 arith[1] = ldm[1]; 10863 arith[2] = ldm[2]; 10864 } 10865 else 10866 { 10867 arith[1] = ldm[2]; 10868 arith[2] = ldm[1]; 10869 } 10870 10871 ldm[0] = base_reg; 10872 if (val1 !=0 && val2 != 0) 10873 { 10874 rtx ops[3]; 10875 10876 if (val1 == 4 || val2 == 4) 10877 /* Other val must be 8, since we know they are adjacent and neither 10878 is zero. */ 10879 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm); 10880 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1)) 10881 { 10882 ldm[0] = ops[0] = operands[4]; 10883 ops[1] = base_reg; 10884 ops[2] = GEN_INT (val1); 10885 output_add_immediate (ops); 10886 if (val1 < val2) 10887 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm); 10888 else 10889 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm); 10890 } 10891 else 10892 { 10893 /* Offset is out of range for a single add, so use two ldr. */ 10894 ops[0] = ldm[1]; 10895 ops[1] = base_reg; 10896 ops[2] = GEN_INT (val1); 10897 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops); 10898 ops[0] = ldm[2]; 10899 ops[2] = GEN_INT (val2); 10900 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops); 10901 } 10902 } 10903 else if (val1 != 0) 10904 { 10905 if (val1 < val2) 10906 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm); 10907 else 10908 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm); 10909 } 10910 else 10911 { 10912 if (val1 < val2) 10913 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm); 10914 else 10915 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm); 10916 } 10917 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith); 10918 return \"\"; 10919 }" 10920 [(set_attr "length" "12") 10921 (set_attr "predicable" "yes") 10922 (set_attr "type" "load_4")] 10923) 10924 10925; This pattern is never tried by combine, so do it as a peephole 10926 10927(define_peephole2 10928 [(set (match_operand:SI 0 "arm_general_register_operand" "") 10929 (match_operand:SI 1 "arm_general_register_operand" "")) 10930 (set (reg:CC CC_REGNUM) 10931 (compare:CC (match_dup 1) (const_int 0)))] 10932 "TARGET_ARM" 10933 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0))) 10934 (set (match_dup 0) (match_dup 1))])] 10935 "" 10936) 10937 10938(define_split 10939 [(set (match_operand:SI 0 "s_register_operand" "") 10940 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "") 10941 (const_int 0)) 10942 (neg:SI (match_operator:SI 2 "arm_comparison_operator" 10943 [(match_operand:SI 3 "s_register_operand" "") 10944 (match_operand:SI 4 "arm_rhs_operand" "")])))) 10945 (clobber (match_operand:SI 5 "s_register_operand" ""))] 10946 "TARGET_ARM" 10947 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31)))) 10948 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) 10949 (match_dup 5)))] 10950 "" 10951) 10952 10953;; This split can be used because CC_Z mode implies that the following 10954;; branch will be an equality, or an unsigned inequality, so the sign 10955;; extension is not needed. 10956 10957(define_split 10958 [(set (reg:CC_Z CC_REGNUM) 10959 (compare:CC_Z 10960 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0) 10961 (const_int 24)) 10962 (match_operand 1 "const_int_operand" ""))) 10963 (clobber (match_scratch:SI 2 ""))] 10964 "TARGET_ARM 10965 && ((UINTVAL (operands[1])) 10966 == ((UINTVAL (operands[1])) >> 24) << 24)" 10967 [(set (match_dup 2) (zero_extend:SI (match_dup 0))) 10968 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))] 10969 " 10970 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24); 10971 " 10972) 10973;; ??? Check the patterns above for Thumb-2 usefulness 10974 10975(define_expand "prologue" 10976 [(clobber (const_int 0))] 10977 "TARGET_EITHER" 10978 "if (TARGET_32BIT) 10979 arm_expand_prologue (); 10980 else 10981 thumb1_expand_prologue (); 10982 DONE; 10983 " 10984) 10985 10986(define_expand "epilogue" 10987 [(clobber (const_int 0))] 10988 "TARGET_EITHER" 10989 " 10990 if (crtl->calls_eh_return) 10991 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2))); 10992 if (TARGET_THUMB1) 10993 { 10994 thumb1_expand_epilogue (); 10995 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, 10996 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE)); 10997 } 10998 else if (HAVE_return) 10999 { 11000 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence, 11001 no need for explicit testing again. */ 11002 emit_jump_insn (gen_return ()); 11003 } 11004 else if (TARGET_32BIT) 11005 { 11006 arm_expand_epilogue (true); 11007 } 11008 DONE; 11009 " 11010) 11011 11012;; Note - although unspec_volatile's USE all hard registers, 11013;; USEs are ignored after relaod has completed. Thus we need 11014;; to add an unspec of the link register to ensure that flow 11015;; does not think that it is unused by the sibcall branch that 11016;; will replace the standard function epilogue. 11017(define_expand "sibcall_epilogue" 11018 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE) 11019 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])] 11020 "TARGET_32BIT" 11021 " 11022 arm_expand_epilogue (false); 11023 DONE; 11024 " 11025) 11026 11027(define_expand "eh_epilogue" 11028 [(use (match_operand:SI 0 "register_operand" "")) 11029 (use (match_operand:SI 1 "register_operand" "")) 11030 (use (match_operand:SI 2 "register_operand" ""))] 11031 "TARGET_EITHER" 11032 " 11033 { 11034 cfun->machine->eh_epilogue_sp_ofs = operands[1]; 11035 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2) 11036 { 11037 rtx ra = gen_rtx_REG (Pmode, 2); 11038 11039 emit_move_insn (ra, operands[2]); 11040 operands[2] = ra; 11041 } 11042 /* This is a hack -- we may have crystalized the function type too 11043 early. */ 11044 cfun->machine->func_type = 0; 11045 }" 11046) 11047 11048;; This split is only used during output to reduce the number of patterns 11049;; that need assembler instructions adding to them. We allowed the setting 11050;; of the conditions to be implicit during rtl generation so that 11051;; the conditional compare patterns would work. However this conflicts to 11052;; some extent with the conditional data operations, so we have to split them 11053;; up again here. 11054 11055;; ??? Need to audit these splitters for Thumb-2. Why isn't normal 11056;; conditional execution sufficient? 11057 11058(define_split 11059 [(set (match_operand:SI 0 "s_register_operand" "") 11060 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 11061 [(match_operand 2 "" "") (match_operand 3 "" "")]) 11062 (match_dup 0) 11063 (match_operand 4 "" ""))) 11064 (clobber (reg:CC CC_REGNUM))] 11065 "TARGET_ARM && reload_completed" 11066 [(set (match_dup 5) (match_dup 6)) 11067 (cond_exec (match_dup 7) 11068 (set (match_dup 0) (match_dup 4)))] 11069 " 11070 { 11071 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 11072 operands[2], operands[3]); 11073 enum rtx_code rc = GET_CODE (operands[1]); 11074 11075 operands[5] = gen_rtx_REG (mode, CC_REGNUM); 11076 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 11077 if (mode == CCFPmode || mode == CCFPEmode) 11078 rc = reverse_condition_maybe_unordered (rc); 11079 else 11080 rc = reverse_condition (rc); 11081 11082 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx); 11083 }" 11084) 11085 11086(define_split 11087 [(set (match_operand:SI 0 "s_register_operand" "") 11088 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 11089 [(match_operand 2 "" "") (match_operand 3 "" "")]) 11090 (match_operand 4 "" "") 11091 (match_dup 0))) 11092 (clobber (reg:CC CC_REGNUM))] 11093 "TARGET_ARM && reload_completed" 11094 [(set (match_dup 5) (match_dup 6)) 11095 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)]) 11096 (set (match_dup 0) (match_dup 4)))] 11097 " 11098 { 11099 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 11100 operands[2], operands[3]); 11101 11102 operands[5] = gen_rtx_REG (mode, CC_REGNUM); 11103 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 11104 }" 11105) 11106 11107(define_split 11108 [(set (match_operand:SI 0 "s_register_operand" "") 11109 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 11110 [(match_operand 2 "" "") (match_operand 3 "" "")]) 11111 (match_operand 4 "" "") 11112 (match_operand 5 "" ""))) 11113 (clobber (reg:CC CC_REGNUM))] 11114 "TARGET_ARM && reload_completed" 11115 [(set (match_dup 6) (match_dup 7)) 11116 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) 11117 (set (match_dup 0) (match_dup 4))) 11118 (cond_exec (match_dup 8) 11119 (set (match_dup 0) (match_dup 5)))] 11120 " 11121 { 11122 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 11123 operands[2], operands[3]); 11124 enum rtx_code rc = GET_CODE (operands[1]); 11125 11126 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 11127 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 11128 if (mode == CCFPmode || mode == CCFPEmode) 11129 rc = reverse_condition_maybe_unordered (rc); 11130 else 11131 rc = reverse_condition (rc); 11132 11133 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 11134 }" 11135) 11136 11137(define_split 11138 [(set (match_operand:SI 0 "s_register_operand" "") 11139 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 11140 [(match_operand:SI 2 "s_register_operand" "") 11141 (match_operand:SI 3 "arm_add_operand" "")]) 11142 (match_operand:SI 4 "arm_rhs_operand" "") 11143 (not:SI 11144 (match_operand:SI 5 "s_register_operand" "")))) 11145 (clobber (reg:CC CC_REGNUM))] 11146 "TARGET_ARM && reload_completed" 11147 [(set (match_dup 6) (match_dup 7)) 11148 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) 11149 (set (match_dup 0) (match_dup 4))) 11150 (cond_exec (match_dup 8) 11151 (set (match_dup 0) (not:SI (match_dup 5))))] 11152 " 11153 { 11154 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 11155 operands[2], operands[3]); 11156 enum rtx_code rc = GET_CODE (operands[1]); 11157 11158 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 11159 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 11160 if (mode == CCFPmode || mode == CCFPEmode) 11161 rc = reverse_condition_maybe_unordered (rc); 11162 else 11163 rc = reverse_condition (rc); 11164 11165 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 11166 }" 11167) 11168 11169(define_insn "*cond_move_not" 11170 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 11171 (if_then_else:SI (match_operator 4 "arm_comparison_operator" 11172 [(match_operand 3 "cc_register" "") (const_int 0)]) 11173 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 11174 (not:SI 11175 (match_operand:SI 2 "s_register_operand" "r,r"))))] 11176 "TARGET_ARM" 11177 "@ 11178 mvn%D4\\t%0, %2 11179 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2" 11180 [(set_attr "conds" "use") 11181 (set_attr "type" "mvn_reg,multiple") 11182 (set_attr "length" "4,8")] 11183) 11184 11185;; The next two patterns occur when an AND operation is followed by a 11186;; scc insn sequence 11187 11188(define_insn "*sign_extract_onebit" 11189 [(set (match_operand:SI 0 "s_register_operand" "=r") 11190 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 11191 (const_int 1) 11192 (match_operand:SI 2 "const_int_operand" "n"))) 11193 (clobber (reg:CC CC_REGNUM))] 11194 "TARGET_ARM" 11195 "* 11196 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 11197 output_asm_insn (\"ands\\t%0, %1, %2\", operands); 11198 return \"mvnne\\t%0, #0\"; 11199 " 11200 [(set_attr "conds" "clob") 11201 (set_attr "length" "8") 11202 (set_attr "type" "multiple")] 11203) 11204 11205(define_insn "*not_signextract_onebit" 11206 [(set (match_operand:SI 0 "s_register_operand" "=r") 11207 (not:SI 11208 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 11209 (const_int 1) 11210 (match_operand:SI 2 "const_int_operand" "n")))) 11211 (clobber (reg:CC CC_REGNUM))] 11212 "TARGET_ARM" 11213 "* 11214 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 11215 output_asm_insn (\"tst\\t%1, %2\", operands); 11216 output_asm_insn (\"mvneq\\t%0, #0\", operands); 11217 return \"movne\\t%0, #0\"; 11218 " 11219 [(set_attr "conds" "clob") 11220 (set_attr "length" "12") 11221 (set_attr "type" "multiple")] 11222) 11223;; ??? The above patterns need auditing for Thumb-2 11224 11225;; Push multiple registers to the stack. Registers are in parallel (use ...) 11226;; expressions. For simplicity, the first register is also in the unspec 11227;; part. 11228;; To avoid the usage of GNU extension, the length attribute is computed 11229;; in a C function arm_attr_length_push_multi. 11230(define_insn "*push_multi" 11231 [(match_parallel 2 "multi_register_push" 11232 [(set (match_operand:BLK 0 "push_mult_memory_operand" "") 11233 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")] 11234 UNSPEC_PUSH_MULT))])] 11235 "" 11236 "* 11237 { 11238 int num_saves = XVECLEN (operands[2], 0); 11239 11240 /* For the StrongARM at least it is faster to 11241 use STR to store only a single register. 11242 In Thumb mode always use push, and the assembler will pick 11243 something appropriate. */ 11244 if (num_saves == 1 && TARGET_ARM) 11245 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands); 11246 else 11247 { 11248 int i; 11249 char pattern[100]; 11250 11251 if (TARGET_32BIT) 11252 strcpy (pattern, \"push%?\\t{%1\"); 11253 else 11254 strcpy (pattern, \"push\\t{%1\"); 11255 11256 for (i = 1; i < num_saves; i++) 11257 { 11258 strcat (pattern, \", %|\"); 11259 strcat (pattern, 11260 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]); 11261 } 11262 11263 strcat (pattern, \"}\"); 11264 output_asm_insn (pattern, operands); 11265 } 11266 11267 return \"\"; 11268 }" 11269 [(set_attr "type" "store_16") 11270 (set (attr "length") 11271 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))] 11272) 11273 11274(define_insn "stack_tie" 11275 [(set (mem:BLK (scratch)) 11276 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk") 11277 (match_operand:SI 1 "s_register_operand" "rk")] 11278 UNSPEC_PRLG_STK))] 11279 "" 11280 "" 11281 [(set_attr "length" "0") 11282 (set_attr "type" "block")] 11283) 11284 11285;; Pop (as used in epilogue RTL) 11286;; 11287(define_insn "*load_multiple_with_writeback" 11288 [(match_parallel 0 "load_multiple_operation" 11289 [(set (match_operand:SI 1 "s_register_operand" "+rk") 11290 (plus:SI (match_dup 1) 11291 (match_operand:SI 2 "const_int_I_operand" "I"))) 11292 (set (match_operand:SI 3 "s_register_operand" "=rk") 11293 (mem:SI (match_dup 1))) 11294 ])] 11295 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11296 "* 11297 { 11298 arm_output_multireg_pop (operands, /*return_pc=*/false, 11299 /*cond=*/const_true_rtx, 11300 /*reverse=*/false, 11301 /*update=*/true); 11302 return \"\"; 11303 } 11304 " 11305 [(set_attr "type" "load_16") 11306 (set_attr "predicable" "yes") 11307 (set (attr "length") 11308 (symbol_ref "arm_attr_length_pop_multi (operands, 11309 /*return_pc=*/false, 11310 /*write_back_p=*/true)"))] 11311) 11312 11313;; Pop with return (as used in epilogue RTL) 11314;; 11315;; This instruction is generated when the registers are popped at the end of 11316;; epilogue. Here, instead of popping the value into LR and then generating 11317;; jump to LR, value is popped into PC directly. Hence, the pattern is combined 11318;; with (return). 11319(define_insn "*pop_multiple_with_writeback_and_return" 11320 [(match_parallel 0 "pop_multiple_return" 11321 [(return) 11322 (set (match_operand:SI 1 "s_register_operand" "+rk") 11323 (plus:SI (match_dup 1) 11324 (match_operand:SI 2 "const_int_I_operand" "I"))) 11325 (set (match_operand:SI 3 "s_register_operand" "=rk") 11326 (mem:SI (match_dup 1))) 11327 ])] 11328 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11329 "* 11330 { 11331 arm_output_multireg_pop (operands, /*return_pc=*/true, 11332 /*cond=*/const_true_rtx, 11333 /*reverse=*/false, 11334 /*update=*/true); 11335 return \"\"; 11336 } 11337 " 11338 [(set_attr "type" "load_16") 11339 (set_attr "predicable" "yes") 11340 (set (attr "length") 11341 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true, 11342 /*write_back_p=*/true)"))] 11343) 11344 11345(define_insn "*pop_multiple_with_return" 11346 [(match_parallel 0 "pop_multiple_return" 11347 [(return) 11348 (set (match_operand:SI 2 "s_register_operand" "=rk") 11349 (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) 11350 ])] 11351 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11352 "* 11353 { 11354 arm_output_multireg_pop (operands, /*return_pc=*/true, 11355 /*cond=*/const_true_rtx, 11356 /*reverse=*/false, 11357 /*update=*/false); 11358 return \"\"; 11359 } 11360 " 11361 [(set_attr "type" "load_16") 11362 (set_attr "predicable" "yes") 11363 (set (attr "length") 11364 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true, 11365 /*write_back_p=*/false)"))] 11366) 11367 11368;; Load into PC and return 11369(define_insn "*ldr_with_return" 11370 [(return) 11371 (set (reg:SI PC_REGNUM) 11372 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))] 11373 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11374 "ldr%?\t%|pc, [%0], #4" 11375 [(set_attr "type" "load_4") 11376 (set_attr "predicable" "yes")] 11377) 11378;; Pop for floating point registers (as used in epilogue RTL) 11379(define_insn "*vfp_pop_multiple_with_writeback" 11380 [(match_parallel 0 "pop_multiple_fp" 11381 [(set (match_operand:SI 1 "s_register_operand" "+rk") 11382 (plus:SI (match_dup 1) 11383 (match_operand:SI 2 "const_int_I_operand" "I"))) 11384 (set (match_operand:DF 3 "vfp_hard_register_operand" "") 11385 (mem:DF (match_dup 1)))])] 11386 "TARGET_32BIT && TARGET_HARD_FLOAT" 11387 "* 11388 { 11389 int num_regs = XVECLEN (operands[0], 0); 11390 char pattern[100]; 11391 rtx op_list[2]; 11392 strcpy (pattern, \"vldm\\t\"); 11393 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]); 11394 strcat (pattern, \"!, {\"); 11395 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0); 11396 strcat (pattern, \"%P0\"); 11397 if ((num_regs - 1) > 1) 11398 { 11399 strcat (pattern, \"-%P1\"); 11400 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0); 11401 } 11402 11403 strcat (pattern, \"}\"); 11404 output_asm_insn (pattern, op_list); 11405 return \"\"; 11406 } 11407 " 11408 [(set_attr "type" "load_16") 11409 (set_attr "conds" "unconditional") 11410 (set_attr "predicable" "no")] 11411) 11412 11413;; Special patterns for dealing with the constant pool 11414 11415(define_insn "align_4" 11416 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)] 11417 "TARGET_EITHER" 11418 "* 11419 assemble_align (32); 11420 return \"\"; 11421 " 11422 [(set_attr "type" "no_insn")] 11423) 11424 11425(define_insn "align_8" 11426 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)] 11427 "TARGET_EITHER" 11428 "* 11429 assemble_align (64); 11430 return \"\"; 11431 " 11432 [(set_attr "type" "no_insn")] 11433) 11434 11435(define_insn "consttable_end" 11436 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)] 11437 "TARGET_EITHER" 11438 "* 11439 making_const_table = FALSE; 11440 return \"\"; 11441 " 11442 [(set_attr "type" "no_insn")] 11443) 11444 11445(define_insn "consttable_1" 11446 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)] 11447 "TARGET_EITHER" 11448 "* 11449 making_const_table = TRUE; 11450 assemble_integer (operands[0], 1, BITS_PER_WORD, 1); 11451 assemble_zeros (3); 11452 return \"\"; 11453 " 11454 [(set_attr "length" "4") 11455 (set_attr "type" "no_insn")] 11456) 11457 11458(define_insn "consttable_2" 11459 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)] 11460 "TARGET_EITHER" 11461 "* 11462 { 11463 rtx x = operands[0]; 11464 making_const_table = TRUE; 11465 switch (GET_MODE_CLASS (GET_MODE (x))) 11466 { 11467 case MODE_FLOAT: 11468 arm_emit_fp16_const (x); 11469 break; 11470 default: 11471 assemble_integer (operands[0], 2, BITS_PER_WORD, 1); 11472 assemble_zeros (2); 11473 break; 11474 } 11475 return \"\"; 11476 }" 11477 [(set_attr "length" "4") 11478 (set_attr "type" "no_insn")] 11479) 11480 11481(define_insn "consttable_4" 11482 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)] 11483 "TARGET_EITHER" 11484 "* 11485 { 11486 rtx x = operands[0]; 11487 making_const_table = TRUE; 11488 scalar_float_mode float_mode; 11489 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode)) 11490 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD); 11491 else 11492 { 11493 /* XXX: Sometimes gcc does something really dumb and ends up with 11494 a HIGH in a constant pool entry, usually because it's trying to 11495 load into a VFP register. We know this will always be used in 11496 combination with a LO_SUM which ignores the high bits, so just 11497 strip off the HIGH. */ 11498 if (GET_CODE (x) == HIGH) 11499 x = XEXP (x, 0); 11500 assemble_integer (x, 4, BITS_PER_WORD, 1); 11501 mark_symbol_refs_as_used (x); 11502 } 11503 return \"\"; 11504 }" 11505 [(set_attr "length" "4") 11506 (set_attr "type" "no_insn")] 11507) 11508 11509(define_insn "consttable_8" 11510 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)] 11511 "TARGET_EITHER" 11512 "* 11513 { 11514 making_const_table = TRUE; 11515 scalar_float_mode float_mode; 11516 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode)) 11517 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]), 11518 float_mode, BITS_PER_WORD); 11519 else 11520 assemble_integer (operands[0], 8, BITS_PER_WORD, 1); 11521 return \"\"; 11522 }" 11523 [(set_attr "length" "8") 11524 (set_attr "type" "no_insn")] 11525) 11526 11527(define_insn "consttable_16" 11528 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)] 11529 "TARGET_EITHER" 11530 "* 11531 { 11532 making_const_table = TRUE; 11533 scalar_float_mode float_mode; 11534 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode)) 11535 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]), 11536 float_mode, BITS_PER_WORD); 11537 else 11538 assemble_integer (operands[0], 16, BITS_PER_WORD, 1); 11539 return \"\"; 11540 }" 11541 [(set_attr "length" "16") 11542 (set_attr "type" "no_insn")] 11543) 11544 11545;; V5 Instructions, 11546 11547(define_insn "clzsi2" 11548 [(set (match_operand:SI 0 "s_register_operand" "=r") 11549 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))] 11550 "TARGET_32BIT && arm_arch5t" 11551 "clz%?\\t%0, %1" 11552 [(set_attr "predicable" "yes") 11553 (set_attr "type" "clz")]) 11554 11555(define_insn "rbitsi2" 11556 [(set (match_operand:SI 0 "s_register_operand" "=r") 11557 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))] 11558 "TARGET_32BIT && arm_arch_thumb2" 11559 "rbit%?\\t%0, %1" 11560 [(set_attr "predicable" "yes") 11561 (set_attr "type" "clz")]) 11562 11563;; Keep this as a CTZ expression until after reload and then split 11564;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely 11565;; to fold with any other expression. 11566 11567(define_insn_and_split "ctzsi2" 11568 [(set (match_operand:SI 0 "s_register_operand" "=r") 11569 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))] 11570 "TARGET_32BIT && arm_arch_thumb2" 11571 "#" 11572 "&& reload_completed" 11573 [(const_int 0)] 11574 " 11575 emit_insn (gen_rbitsi2 (operands[0], operands[1])); 11576 emit_insn (gen_clzsi2 (operands[0], operands[0])); 11577 DONE; 11578") 11579 11580;; V5E instructions. 11581 11582(define_insn "prefetch" 11583 [(prefetch (match_operand:SI 0 "address_operand" "p") 11584 (match_operand:SI 1 "" "") 11585 (match_operand:SI 2 "" ""))] 11586 "TARGET_32BIT && arm_arch5te" 11587 "pld\\t%a0" 11588 [(set_attr "type" "load_4")] 11589) 11590 11591;; General predication pattern 11592 11593(define_cond_exec 11594 [(match_operator 0 "arm_comparison_operator" 11595 [(match_operand 1 "cc_register" "") 11596 (const_int 0)])] 11597 "TARGET_32BIT 11598 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))" 11599 "" 11600[(set_attr "predicated" "yes")] 11601) 11602 11603(define_insn "force_register_use" 11604 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)] 11605 "" 11606 "%@ %0 needed" 11607 [(set_attr "length" "0") 11608 (set_attr "type" "no_insn")] 11609) 11610 11611 11612;; Patterns for exception handling 11613 11614(define_expand "eh_return" 11615 [(use (match_operand 0 "general_operand" ""))] 11616 "TARGET_EITHER" 11617 " 11618 { 11619 if (TARGET_32BIT) 11620 emit_insn (gen_arm_eh_return (operands[0])); 11621 else 11622 emit_insn (gen_thumb_eh_return (operands[0])); 11623 DONE; 11624 }" 11625) 11626 11627;; We can't expand this before we know where the link register is stored. 11628(define_insn_and_split "arm_eh_return" 11629 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")] 11630 VUNSPEC_EH_RETURN) 11631 (clobber (match_scratch:SI 1 "=&r"))] 11632 "TARGET_ARM" 11633 "#" 11634 "&& reload_completed" 11635 [(const_int 0)] 11636 " 11637 { 11638 arm_set_return_address (operands[0], operands[1]); 11639 DONE; 11640 }" 11641) 11642 11643 11644;; TLS support 11645 11646(define_insn "load_tp_hard" 11647 [(set (match_operand:SI 0 "register_operand" "=r") 11648 (unspec:SI [(const_int 0)] UNSPEC_TLS))] 11649 "TARGET_HARD_TP" 11650 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard" 11651 [(set_attr "predicable" "yes") 11652 (set_attr "type" "mrs")] 11653) 11654 11655;; Doesn't clobber R1-R3. Must use r0 for the first operand. 11656(define_insn "load_tp_soft" 11657 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS)) 11658 (clobber (reg:SI LR_REGNUM)) 11659 (clobber (reg:SI IP_REGNUM)) 11660 (clobber (reg:CC CC_REGNUM))] 11661 "TARGET_SOFT_TP" 11662 "bl\\t__aeabi_read_tp\\t@ load_tp_soft" 11663 [(set_attr "conds" "clob") 11664 (set_attr "type" "branch")] 11665) 11666 11667;; tls descriptor call 11668(define_insn "tlscall" 11669 [(set (reg:SI R0_REGNUM) 11670 (unspec:SI [(reg:SI R0_REGNUM) 11671 (match_operand:SI 0 "" "X") 11672 (match_operand 1 "" "")] UNSPEC_TLS)) 11673 (clobber (reg:SI R1_REGNUM)) 11674 (clobber (reg:SI LR_REGNUM)) 11675 (clobber (reg:SI CC_REGNUM))] 11676 "TARGET_GNU2_TLS" 11677 { 11678 targetm.asm_out.internal_label (asm_out_file, "LPIC", 11679 INTVAL (operands[1])); 11680 return "bl\\t%c0(tlscall)"; 11681 } 11682 [(set_attr "conds" "clob") 11683 (set_attr "length" "4") 11684 (set_attr "type" "branch")] 11685) 11686 11687;; For thread pointer builtin 11688(define_expand "get_thread_pointersi" 11689 [(match_operand:SI 0 "s_register_operand" "=r")] 11690 "" 11691 " 11692 { 11693 arm_load_tp (operands[0]); 11694 DONE; 11695 }") 11696 11697;; 11698 11699;; We only care about the lower 16 bits of the constant 11700;; being inserted into the upper 16 bits of the register. 11701(define_insn "*arm_movtas_ze" 11702 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r") 11703 (const_int 16) 11704 (const_int 16)) 11705 (match_operand:SI 1 "const_int_operand" ""))] 11706 "TARGET_HAVE_MOVT" 11707 "@ 11708 movt%?\t%0, %L1 11709 movt\t%0, %L1" 11710 [(set_attr "arch" "32,v8mb") 11711 (set_attr "predicable" "yes") 11712 (set_attr "length" "4") 11713 (set_attr "type" "alu_sreg")] 11714) 11715 11716(define_insn "*arm_rev" 11717 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") 11718 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))] 11719 "arm_arch6" 11720 "@ 11721 rev\t%0, %1 11722 rev%?\t%0, %1 11723 rev%?\t%0, %1" 11724 [(set_attr "arch" "t1,t2,32") 11725 (set_attr "length" "2,2,4") 11726 (set_attr "predicable" "no,yes,yes") 11727 (set_attr "type" "rev")] 11728) 11729 11730(define_expand "arm_legacy_rev" 11731 [(set (match_operand:SI 2 "s_register_operand" "") 11732 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "") 11733 (const_int 16)) 11734 (match_dup 1))) 11735 (set (match_dup 2) 11736 (lshiftrt:SI (match_dup 2) 11737 (const_int 8))) 11738 (set (match_operand:SI 3 "s_register_operand" "") 11739 (rotatert:SI (match_dup 1) 11740 (const_int 8))) 11741 (set (match_dup 2) 11742 (and:SI (match_dup 2) 11743 (const_int -65281))) 11744 (set (match_operand:SI 0 "s_register_operand" "") 11745 (xor:SI (match_dup 3) 11746 (match_dup 2)))] 11747 "TARGET_32BIT" 11748 "" 11749) 11750 11751;; Reuse temporaries to keep register pressure down. 11752(define_expand "thumb_legacy_rev" 11753 [(set (match_operand:SI 2 "s_register_operand" "") 11754 (ashift:SI (match_operand:SI 1 "s_register_operand" "") 11755 (const_int 24))) 11756 (set (match_operand:SI 3 "s_register_operand" "") 11757 (lshiftrt:SI (match_dup 1) 11758 (const_int 24))) 11759 (set (match_dup 3) 11760 (ior:SI (match_dup 3) 11761 (match_dup 2))) 11762 (set (match_operand:SI 4 "s_register_operand" "") 11763 (const_int 16)) 11764 (set (match_operand:SI 5 "s_register_operand" "") 11765 (rotatert:SI (match_dup 1) 11766 (match_dup 4))) 11767 (set (match_dup 2) 11768 (ashift:SI (match_dup 5) 11769 (const_int 24))) 11770 (set (match_dup 5) 11771 (lshiftrt:SI (match_dup 5) 11772 (const_int 24))) 11773 (set (match_dup 5) 11774 (ior:SI (match_dup 5) 11775 (match_dup 2))) 11776 (set (match_dup 5) 11777 (rotatert:SI (match_dup 5) 11778 (match_dup 4))) 11779 (set (match_operand:SI 0 "s_register_operand" "") 11780 (ior:SI (match_dup 5) 11781 (match_dup 3)))] 11782 "TARGET_THUMB" 11783 "" 11784) 11785 11786;; ARM-specific expansion of signed mod by power of 2 11787;; using conditional negate. 11788;; For r0 % n where n is a power of 2 produce: 11789;; rsbs r1, r0, #0 11790;; and r0, r0, #(n - 1) 11791;; and r1, r1, #(n - 1) 11792;; rsbpl r0, r1, #0 11793 11794(define_expand "modsi3" 11795 [(match_operand:SI 0 "register_operand" "") 11796 (match_operand:SI 1 "register_operand" "") 11797 (match_operand:SI 2 "const_int_operand" "")] 11798 "TARGET_32BIT" 11799 { 11800 HOST_WIDE_INT val = INTVAL (operands[2]); 11801 11802 if (val <= 0 11803 || exact_log2 (val) <= 0) 11804 FAIL; 11805 11806 rtx mask = GEN_INT (val - 1); 11807 11808 /* In the special case of x0 % 2 we can do the even shorter: 11809 cmp r0, #0 11810 and r0, r0, #1 11811 rsblt r0, r0, #0. */ 11812 11813 if (val == 2) 11814 { 11815 rtx cc_reg = arm_gen_compare_reg (LT, 11816 operands[1], const0_rtx, NULL_RTX); 11817 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx); 11818 rtx masked = gen_reg_rtx (SImode); 11819 11820 emit_insn (gen_andsi3 (masked, operands[1], mask)); 11821 emit_move_insn (operands[0], 11822 gen_rtx_IF_THEN_ELSE (SImode, cond, 11823 gen_rtx_NEG (SImode, 11824 masked), 11825 masked)); 11826 DONE; 11827 } 11828 11829 rtx neg_op = gen_reg_rtx (SImode); 11830 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx, 11831 operands[1])); 11832 11833 /* Extract the condition register and mode. */ 11834 rtx cmp = XVECEXP (PATTERN (insn), 0, 0); 11835 rtx cc_reg = SET_DEST (cmp); 11836 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx); 11837 11838 emit_insn (gen_andsi3 (operands[0], operands[1], mask)); 11839 11840 rtx masked_neg = gen_reg_rtx (SImode); 11841 emit_insn (gen_andsi3 (masked_neg, neg_op, mask)); 11842 11843 /* We want a conditional negate here, but emitting COND_EXEC rtxes 11844 during expand does not always work. Do an IF_THEN_ELSE instead. */ 11845 emit_move_insn (operands[0], 11846 gen_rtx_IF_THEN_ELSE (SImode, cond, 11847 gen_rtx_NEG (SImode, masked_neg), 11848 operands[0])); 11849 11850 11851 DONE; 11852 } 11853) 11854 11855(define_expand "bswapsi2" 11856 [(set (match_operand:SI 0 "s_register_operand" "=r") 11857 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))] 11858"TARGET_EITHER && (arm_arch6 || !optimize_size)" 11859" 11860 if (!arm_arch6) 11861 { 11862 rtx op2 = gen_reg_rtx (SImode); 11863 rtx op3 = gen_reg_rtx (SImode); 11864 11865 if (TARGET_THUMB) 11866 { 11867 rtx op4 = gen_reg_rtx (SImode); 11868 rtx op5 = gen_reg_rtx (SImode); 11869 11870 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1], 11871 op2, op3, op4, op5)); 11872 } 11873 else 11874 { 11875 emit_insn (gen_arm_legacy_rev (operands[0], operands[1], 11876 op2, op3)); 11877 } 11878 11879 DONE; 11880 } 11881 " 11882) 11883 11884;; bswap16 patterns: use revsh and rev16 instructions for the signed 11885;; and unsigned variants, respectively. For rev16, expose 11886;; byte-swapping in the lower 16 bits only. 11887(define_insn "*arm_revsh" 11888 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") 11889 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))] 11890 "arm_arch6" 11891 "@ 11892 revsh\t%0, %1 11893 revsh%?\t%0, %1 11894 revsh%?\t%0, %1" 11895 [(set_attr "arch" "t1,t2,32") 11896 (set_attr "length" "2,2,4") 11897 (set_attr "type" "rev")] 11898) 11899 11900(define_insn "*arm_rev16" 11901 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r") 11902 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))] 11903 "arm_arch6" 11904 "@ 11905 rev16\t%0, %1 11906 rev16%?\t%0, %1 11907 rev16%?\t%0, %1" 11908 [(set_attr "arch" "t1,t2,32") 11909 (set_attr "length" "2,2,4") 11910 (set_attr "type" "rev")] 11911) 11912 11913;; There are no canonicalisation rules for the position of the lshiftrt, ashift 11914;; operations within an IOR/AND RTX, therefore we have two patterns matching 11915;; each valid permutation. 11916 11917(define_insn "arm_rev16si2" 11918 [(set (match_operand:SI 0 "register_operand" "=l,l,r") 11919 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r") 11920 (const_int 8)) 11921 (match_operand:SI 3 "const_int_operand" "n,n,n")) 11922 (and:SI (lshiftrt:SI (match_dup 1) 11923 (const_int 8)) 11924 (match_operand:SI 2 "const_int_operand" "n,n,n"))))] 11925 "arm_arch6 11926 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode) 11927 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)" 11928 "rev16\\t%0, %1" 11929 [(set_attr "arch" "t1,t2,32") 11930 (set_attr "length" "2,2,4") 11931 (set_attr "type" "rev")] 11932) 11933 11934(define_insn "arm_rev16si2_alt" 11935 [(set (match_operand:SI 0 "register_operand" "=l,l,r") 11936 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r") 11937 (const_int 8)) 11938 (match_operand:SI 2 "const_int_operand" "n,n,n")) 11939 (and:SI (ashift:SI (match_dup 1) 11940 (const_int 8)) 11941 (match_operand:SI 3 "const_int_operand" "n,n,n"))))] 11942 "arm_arch6 11943 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode) 11944 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)" 11945 "rev16\\t%0, %1" 11946 [(set_attr "arch" "t1,t2,32") 11947 (set_attr "length" "2,2,4") 11948 (set_attr "type" "rev")] 11949) 11950 11951(define_expand "bswaphi2" 11952 [(set (match_operand:HI 0 "s_register_operand" "=r") 11953 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))] 11954"arm_arch6" 11955"" 11956) 11957 11958;; Patterns for LDRD/STRD in Thumb2 mode 11959 11960(define_insn "*thumb2_ldrd" 11961 [(set (match_operand:SI 0 "s_register_operand" "=r") 11962 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk") 11963 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do")))) 11964 (set (match_operand:SI 3 "s_register_operand" "=r") 11965 (mem:SI (plus:SI (match_dup 1) 11966 (match_operand:SI 4 "const_int_operand" ""))))] 11967 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11968 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4])) 11969 && (operands_ok_ldrd_strd (operands[0], operands[3], 11970 operands[1], INTVAL (operands[2]), 11971 false, true))" 11972 "ldrd%?\t%0, %3, [%1, %2]" 11973 [(set_attr "type" "load_8") 11974 (set_attr "predicable" "yes")]) 11975 11976(define_insn "*thumb2_ldrd_base" 11977 [(set (match_operand:SI 0 "s_register_operand" "=r") 11978 (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) 11979 (set (match_operand:SI 2 "s_register_operand" "=r") 11980 (mem:SI (plus:SI (match_dup 1) 11981 (const_int 4))))] 11982 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11983 && (operands_ok_ldrd_strd (operands[0], operands[2], 11984 operands[1], 0, false, true))" 11985 "ldrd%?\t%0, %2, [%1]" 11986 [(set_attr "type" "load_8") 11987 (set_attr "predicable" "yes")]) 11988 11989(define_insn "*thumb2_ldrd_base_neg" 11990 [(set (match_operand:SI 0 "s_register_operand" "=r") 11991 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk") 11992 (const_int -4)))) 11993 (set (match_operand:SI 2 "s_register_operand" "=r") 11994 (mem:SI (match_dup 1)))] 11995 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11996 && (operands_ok_ldrd_strd (operands[0], operands[2], 11997 operands[1], -4, false, true))" 11998 "ldrd%?\t%0, %2, [%1, #-4]" 11999 [(set_attr "type" "load_8") 12000 (set_attr "predicable" "yes")]) 12001 12002(define_insn "*thumb2_strd" 12003 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk") 12004 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do"))) 12005 (match_operand:SI 2 "s_register_operand" "r")) 12006 (set (mem:SI (plus:SI (match_dup 0) 12007 (match_operand:SI 3 "const_int_operand" ""))) 12008 (match_operand:SI 4 "s_register_operand" "r"))] 12009 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 12010 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3])) 12011 && (operands_ok_ldrd_strd (operands[2], operands[4], 12012 operands[0], INTVAL (operands[1]), 12013 false, false))" 12014 "strd%?\t%2, %4, [%0, %1]" 12015 [(set_attr "type" "store_8") 12016 (set_attr "predicable" "yes")]) 12017 12018(define_insn "*thumb2_strd_base" 12019 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk")) 12020 (match_operand:SI 1 "s_register_operand" "r")) 12021 (set (mem:SI (plus:SI (match_dup 0) 12022 (const_int 4))) 12023 (match_operand:SI 2 "s_register_operand" "r"))] 12024 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 12025 && (operands_ok_ldrd_strd (operands[1], operands[2], 12026 operands[0], 0, false, false))" 12027 "strd%?\t%1, %2, [%0]" 12028 [(set_attr "type" "store_8") 12029 (set_attr "predicable" "yes")]) 12030 12031(define_insn "*thumb2_strd_base_neg" 12032 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk") 12033 (const_int -4))) 12034 (match_operand:SI 1 "s_register_operand" "r")) 12035 (set (mem:SI (match_dup 0)) 12036 (match_operand:SI 2 "s_register_operand" "r"))] 12037 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 12038 && (operands_ok_ldrd_strd (operands[1], operands[2], 12039 operands[0], -4, false, false))" 12040 "strd%?\t%1, %2, [%0, #-4]" 12041 [(set_attr "type" "store_8") 12042 (set_attr "predicable" "yes")]) 12043 12044;; ARMv8 CRC32 instructions. 12045(define_insn "<crc_variant>" 12046 [(set (match_operand:SI 0 "s_register_operand" "=r") 12047 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r") 12048 (match_operand:<crc_mode> 2 "s_register_operand" "r")] 12049 CRC))] 12050 "TARGET_CRC32" 12051 "<crc_variant>\\t%0, %1, %2" 12052 [(set_attr "type" "crc") 12053 (set_attr "conds" "unconditional")] 12054) 12055 12056;; Load the load/store double peephole optimizations. 12057(include "ldrdstrd.md") 12058 12059;; Load the load/store multiple patterns 12060(include "ldmstm.md") 12061 12062;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers 12063;; large lists without explicit writeback generated for APCS_FRAME epilogue. 12064;; The operands are validated through the load_multiple_operation 12065;; match_parallel predicate rather than through constraints so enable it only 12066;; after reload. 12067(define_insn "*load_multiple" 12068 [(match_parallel 0 "load_multiple_operation" 12069 [(set (match_operand:SI 2 "s_register_operand" "=rk") 12070 (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) 12071 ])] 12072 "TARGET_32BIT && reload_completed" 12073 "* 12074 { 12075 arm_output_multireg_pop (operands, /*return_pc=*/false, 12076 /*cond=*/const_true_rtx, 12077 /*reverse=*/false, 12078 /*update=*/false); 12079 return \"\"; 12080 } 12081 " 12082 [(set_attr "predicable" "yes")] 12083) 12084 12085(define_expand "copysignsf3" 12086 [(match_operand:SF 0 "register_operand") 12087 (match_operand:SF 1 "register_operand") 12088 (match_operand:SF 2 "register_operand")] 12089 "TARGET_SOFT_FLOAT && arm_arch_thumb2" 12090 "{ 12091 emit_move_insn (operands[0], operands[2]); 12092 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0), 12093 GEN_INT (31), GEN_INT (0), 12094 simplify_gen_subreg (SImode, operands[1], SFmode, 0))); 12095 DONE; 12096 }" 12097) 12098 12099(define_expand "copysigndf3" 12100 [(match_operand:DF 0 "register_operand") 12101 (match_operand:DF 1 "register_operand") 12102 (match_operand:DF 2 "register_operand")] 12103 "TARGET_SOFT_FLOAT && arm_arch_thumb2" 12104 "{ 12105 rtx op0_low = gen_lowpart (SImode, operands[0]); 12106 rtx op0_high = gen_highpart (SImode, operands[0]); 12107 rtx op1_low = gen_lowpart (SImode, operands[1]); 12108 rtx op1_high = gen_highpart (SImode, operands[1]); 12109 rtx op2_high = gen_highpart (SImode, operands[2]); 12110 12111 rtx scratch1 = gen_reg_rtx (SImode); 12112 rtx scratch2 = gen_reg_rtx (SImode); 12113 emit_move_insn (scratch1, op2_high); 12114 emit_move_insn (scratch2, op1_high); 12115 12116 emit_insn(gen_rtx_SET(scratch1, 12117 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31)))); 12118 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1)); 12119 emit_move_insn (op0_low, op1_low); 12120 emit_move_insn (op0_high, scratch2); 12121 12122 DONE; 12123 }" 12124) 12125 12126;; movmisalign patterns for HImode and SImode. 12127(define_expand "movmisalign<mode>" 12128 [(match_operand:HSI 0 "general_operand") 12129 (match_operand:HSI 1 "general_operand")] 12130 "unaligned_access" 12131{ 12132 /* This pattern is not permitted to fail during expansion: if both arguments 12133 are non-registers (e.g. memory := constant), force operand 1 into a 12134 register. */ 12135 rtx (* gen_unaligned_load)(rtx, rtx); 12136 rtx tmp_dest = operands[0]; 12137 if (!s_register_operand (operands[0], <MODE>mode) 12138 && !s_register_operand (operands[1], <MODE>mode)) 12139 operands[1] = force_reg (<MODE>mode, operands[1]); 12140 12141 if (<MODE>mode == HImode) 12142 { 12143 gen_unaligned_load = gen_unaligned_loadhiu; 12144 tmp_dest = gen_reg_rtx (SImode); 12145 } 12146 else 12147 gen_unaligned_load = gen_unaligned_loadsi; 12148 12149 if (MEM_P (operands[1])) 12150 { 12151 emit_insn (gen_unaligned_load (tmp_dest, operands[1])); 12152 if (<MODE>mode == HImode) 12153 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest)); 12154 } 12155 else 12156 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1])); 12157 12158 DONE; 12159}) 12160 12161(define_insn "<cdp>" 12162 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 12163 (match_operand:SI 1 "immediate_operand" "n") 12164 (match_operand:SI 2 "immediate_operand" "n") 12165 (match_operand:SI 3 "immediate_operand" "n") 12166 (match_operand:SI 4 "immediate_operand" "n") 12167 (match_operand:SI 5 "immediate_operand" "n")] CDPI)] 12168 "arm_coproc_builtin_available (VUNSPEC_<CDP>)" 12169{ 12170 arm_const_bounds (operands[0], 0, 16); 12171 arm_const_bounds (operands[1], 0, 16); 12172 arm_const_bounds (operands[2], 0, (1 << 5)); 12173 arm_const_bounds (operands[3], 0, (1 << 5)); 12174 arm_const_bounds (operands[4], 0, (1 << 5)); 12175 arm_const_bounds (operands[5], 0, 8); 12176 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5"; 12177} 12178 [(set_attr "length" "4") 12179 (set_attr "type" "coproc")]) 12180 12181(define_insn "*ldc" 12182 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 12183 (match_operand:SI 1 "immediate_operand" "n") 12184 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)] 12185 "arm_coproc_builtin_available (VUNSPEC_<LDC>)" 12186{ 12187 arm_const_bounds (operands[0], 0, 16); 12188 arm_const_bounds (operands[1], 0, (1 << 5)); 12189 return "<ldc>\\tp%c0, CR%c1, %2"; 12190} 12191 [(set_attr "length" "4") 12192 (set_attr "type" "coproc")]) 12193 12194(define_insn "*stc" 12195 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 12196 (match_operand:SI 1 "immediate_operand" "n") 12197 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)] 12198 "arm_coproc_builtin_available (VUNSPEC_<STC>)" 12199{ 12200 arm_const_bounds (operands[0], 0, 16); 12201 arm_const_bounds (operands[1], 0, (1 << 5)); 12202 return "<stc>\\tp%c0, CR%c1, %2"; 12203} 12204 [(set_attr "length" "4") 12205 (set_attr "type" "coproc")]) 12206 12207(define_expand "<ldc>" 12208 [(unspec_volatile [(match_operand:SI 0 "immediate_operand") 12209 (match_operand:SI 1 "immediate_operand") 12210 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)] 12211 "arm_coproc_builtin_available (VUNSPEC_<LDC>)") 12212 12213(define_expand "<stc>" 12214 [(unspec_volatile [(match_operand:SI 0 "immediate_operand") 12215 (match_operand:SI 1 "immediate_operand") 12216 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)] 12217 "arm_coproc_builtin_available (VUNSPEC_<STC>)") 12218 12219(define_insn "<mcr>" 12220 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 12221 (match_operand:SI 1 "immediate_operand" "n") 12222 (match_operand:SI 2 "s_register_operand" "r") 12223 (match_operand:SI 3 "immediate_operand" "n") 12224 (match_operand:SI 4 "immediate_operand" "n") 12225 (match_operand:SI 5 "immediate_operand" "n")] MCRI) 12226 (use (match_dup 2))] 12227 "arm_coproc_builtin_available (VUNSPEC_<MCR>)" 12228{ 12229 arm_const_bounds (operands[0], 0, 16); 12230 arm_const_bounds (operands[1], 0, 8); 12231 arm_const_bounds (operands[3], 0, (1 << 5)); 12232 arm_const_bounds (operands[4], 0, (1 << 5)); 12233 arm_const_bounds (operands[5], 0, 8); 12234 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5"; 12235} 12236 [(set_attr "length" "4") 12237 (set_attr "type" "coproc")]) 12238 12239(define_insn "<mrc>" 12240 [(set (match_operand:SI 0 "s_register_operand" "=r") 12241 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n") 12242 (match_operand:SI 2 "immediate_operand" "n") 12243 (match_operand:SI 3 "immediate_operand" "n") 12244 (match_operand:SI 4 "immediate_operand" "n") 12245 (match_operand:SI 5 "immediate_operand" "n")] MRCI))] 12246 "arm_coproc_builtin_available (VUNSPEC_<MRC>)" 12247{ 12248 arm_const_bounds (operands[1], 0, 16); 12249 arm_const_bounds (operands[2], 0, 8); 12250 arm_const_bounds (operands[3], 0, (1 << 5)); 12251 arm_const_bounds (operands[4], 0, (1 << 5)); 12252 arm_const_bounds (operands[5], 0, 8); 12253 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5"; 12254} 12255 [(set_attr "length" "4") 12256 (set_attr "type" "coproc")]) 12257 12258(define_insn "<mcrr>" 12259 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 12260 (match_operand:SI 1 "immediate_operand" "n") 12261 (match_operand:DI 2 "s_register_operand" "r") 12262 (match_operand:SI 3 "immediate_operand" "n")] MCRRI) 12263 (use (match_dup 2))] 12264 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)" 12265{ 12266 arm_const_bounds (operands[0], 0, 16); 12267 arm_const_bounds (operands[1], 0, 8); 12268 arm_const_bounds (operands[3], 0, (1 << 5)); 12269 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3"; 12270} 12271 [(set_attr "length" "4") 12272 (set_attr "type" "coproc")]) 12273 12274(define_insn "<mrrc>" 12275 [(set (match_operand:DI 0 "s_register_operand" "=r") 12276 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n") 12277 (match_operand:SI 2 "immediate_operand" "n") 12278 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))] 12279 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)" 12280{ 12281 arm_const_bounds (operands[1], 0, 16); 12282 arm_const_bounds (operands[2], 0, 8); 12283 arm_const_bounds (operands[3], 0, (1 << 5)); 12284 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3"; 12285} 12286 [(set_attr "length" "4") 12287 (set_attr "type" "coproc")]) 12288 12289(define_expand "speculation_barrier" 12290 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)] 12291 "TARGET_EITHER" 12292 " 12293 /* For thumb1 (except Armv8 derivatives), and for pre-Armv7 we don't 12294 have a usable barrier (and probably don't need one in practice). 12295 But to be safe if such code is run on later architectures, call a 12296 helper function in libgcc that will do the thing for the active 12297 system. */ 12298 if (!(arm_arch7 || arm_arch8)) 12299 { 12300 arm_emit_speculation_barrier_function (); 12301 DONE; 12302 } 12303 " 12304) 12305 12306;; Generate a hard speculation barrier when we have not enabled speculation 12307;; tracking. 12308(define_insn "*speculation_barrier_insn" 12309 [(unspec_volatile [(const_int 0)] VUNSPEC_SPECULATION_BARRIER)] 12310 "arm_arch7 || arm_arch8" 12311 "isb\;dsb\\tsy" 12312 [(set_attr "type" "block") 12313 (set_attr "length" "8")] 12314) 12315 12316;; Vector bits common to IWMMXT and Neon 12317(include "vec-common.md") 12318;; Load the Intel Wireless Multimedia Extension patterns 12319(include "iwmmxt.md") 12320;; Load the VFP co-processor patterns 12321(include "vfp.md") 12322;; Thumb-1 patterns 12323(include "thumb1.md") 12324;; Thumb-2 patterns 12325(include "thumb2.md") 12326;; Neon patterns 12327(include "neon.md") 12328;; Crypto patterns 12329(include "crypto.md") 12330;; Synchronization Primitives 12331(include "sync.md") 12332;; Fixed-point patterns 12333(include "arm-fixed.md") 12334