1;;- Machine description for ARM for GNU compiler 2;; Copyright (C) 1991-2018 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 can not 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,arm1020e,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" "!arm1020e,arm1022e,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 addsi3_compare0_for_combiner 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" "L,I"))) 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" "I,L")))] 870 "TARGET_32BIT && INTVAL (operands[2]) == -INTVAL (operands[3])" 871 "@ 872 adds%?\\t%0, %1, %3 873 subs%?\\t%0, %1, #%n3" 874 [(set_attr "conds" "set") 875 (set_attr "type" "alus_sreg")] 876) 877 878;; Convert the sequence 879;; sub rd, rn, #1 880;; cmn rd, #1 (equivalent to cmp rd, #-1) 881;; bne dest 882;; into 883;; subs rd, rn, #1 884;; bcs dest ((unsigned)rn >= 1) 885;; similarly for the beq variant using bcc. 886;; This is a common looping idiom (while (n--)) 887(define_peephole2 888 [(set (match_operand:SI 0 "arm_general_register_operand" "") 889 (plus:SI (match_operand:SI 1 "arm_general_register_operand" "") 890 (const_int -1))) 891 (set (match_operand 2 "cc_register" "") 892 (compare (match_dup 0) (const_int -1))) 893 (set (pc) 894 (if_then_else (match_operator 3 "equality_operator" 895 [(match_dup 2) (const_int 0)]) 896 (match_operand 4 "" "") 897 (match_operand 5 "" "")))] 898 "TARGET_32BIT && peep2_reg_dead_p (3, operands[2])" 899 [(parallel[ 900 (set (match_dup 2) 901 (compare:CC 902 (match_dup 1) (const_int 1))) 903 (set (match_dup 0) (plus:SI (match_dup 1) (const_int -1)))]) 904 (set (pc) 905 (if_then_else (match_op_dup 3 [(match_dup 2) (const_int 0)]) 906 (match_dup 4) 907 (match_dup 5)))] 908 "operands[2] = gen_rtx_REG (CCmode, CC_REGNUM); 909 operands[3] = gen_rtx_fmt_ee ((GET_CODE (operands[3]) == NE 910 ? GEU : LTU), 911 VOIDmode, 912 operands[2], const0_rtx);" 913) 914 915;; The next four insns work because they compare the result with one of 916;; the operands, and we know that the use of the condition code is 917;; either GEU or LTU, so we can use the carry flag from the addition 918;; instead of doing the compare a second time. 919(define_insn "*addsi3_compare_op1" 920 [(set (reg:CC_C CC_REGNUM) 921 (compare:CC_C 922 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 923 (match_operand:SI 2 "arm_add_operand" "I,L,r")) 924 (match_dup 1))) 925 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 926 (plus:SI (match_dup 1) (match_dup 2)))] 927 "TARGET_32BIT" 928 "@ 929 adds%?\\t%0, %1, %2 930 subs%?\\t%0, %1, #%n2 931 adds%?\\t%0, %1, %2" 932 [(set_attr "conds" "set") 933 (set_attr "type" "alus_imm,alus_imm,alus_sreg")] 934) 935 936(define_insn "*addsi3_compare_op2" 937 [(set (reg:CC_C CC_REGNUM) 938 (compare:CC_C 939 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 940 (match_operand:SI 2 "arm_add_operand" "I,L,r")) 941 (match_dup 2))) 942 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 943 (plus:SI (match_dup 1) (match_dup 2)))] 944 "TARGET_32BIT" 945 "@ 946 adds%?\\t%0, %1, %2 947 subs%?\\t%0, %1, #%n2 948 adds%?\\t%0, %1, %2" 949 [(set_attr "conds" "set") 950 (set_attr "type" "alus_imm,alus_imm,alus_sreg")] 951) 952 953(define_insn "*compare_addsi2_op0" 954 [(set (reg:CC_C CC_REGNUM) 955 (compare:CC_C 956 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r") 957 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r")) 958 (match_dup 0)))] 959 "TARGET_32BIT" 960 "@ 961 cmp%?\\t%0, #%n1 962 cmn%?\\t%0, %1 963 cmn%?\\t%0, %1 964 cmp%?\\t%0, #%n1 965 cmn%?\\t%0, %1" 966 [(set_attr "conds" "set") 967 (set_attr "predicable" "yes") 968 (set_attr "arch" "t2,t2,*,*,*") 969 (set_attr "predicable_short_it" "yes,yes,no,no,no") 970 (set_attr "length" "2,2,4,4,4") 971 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")] 972) 973 974(define_insn "*compare_addsi2_op1" 975 [(set (reg:CC_C CC_REGNUM) 976 (compare:CC_C 977 (plus:SI (match_operand:SI 0 "s_register_operand" "l,l,r,r,r") 978 (match_operand:SI 1 "arm_add_operand" "Pv,l,I,L,r")) 979 (match_dup 1)))] 980 "TARGET_32BIT" 981 "@ 982 cmp%?\\t%0, #%n1 983 cmn%?\\t%0, %1 984 cmn%?\\t%0, %1 985 cmp%?\\t%0, #%n1 986 cmn%?\\t%0, %1" 987 [(set_attr "conds" "set") 988 (set_attr "predicable" "yes") 989 (set_attr "arch" "t2,t2,*,*,*") 990 (set_attr "predicable_short_it" "yes,yes,no,no,no") 991 (set_attr "length" "2,2,4,4,4") 992 (set_attr "type" "alus_imm,alus_sreg,alus_imm,alus_imm,alus_sreg")] 993 ) 994 995(define_insn "*addsi3_carryin_<optab>" 996 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r") 997 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%l,r,r") 998 (match_operand:SI 2 "arm_not_operand" "0,rI,K")) 999 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))] 1000 "TARGET_32BIT" 1001 "@ 1002 adc%?\\t%0, %1, %2 1003 adc%?\\t%0, %1, %2 1004 sbc%?\\t%0, %1, #%B2" 1005 [(set_attr "conds" "use") 1006 (set_attr "predicable" "yes") 1007 (set_attr "arch" "t2,*,*") 1008 (set_attr "length" "4") 1009 (set_attr "predicable_short_it" "yes,no,no") 1010 (set_attr "type" "adc_reg,adc_reg,adc_imm")] 1011) 1012 1013(define_insn "*addsi3_carryin_alt2_<optab>" 1014 [(set (match_operand:SI 0 "s_register_operand" "=l,r,r") 1015 (plus:SI (plus:SI (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0)) 1016 (match_operand:SI 1 "s_register_operand" "%l,r,r")) 1017 (match_operand:SI 2 "arm_rhs_operand" "l,rI,K")))] 1018 "TARGET_32BIT" 1019 "@ 1020 adc%?\\t%0, %1, %2 1021 adc%?\\t%0, %1, %2 1022 sbc%?\\t%0, %1, #%B2" 1023 [(set_attr "conds" "use") 1024 (set_attr "predicable" "yes") 1025 (set_attr "arch" "t2,*,*") 1026 (set_attr "length" "4") 1027 (set_attr "predicable_short_it" "yes,no,no") 1028 (set_attr "type" "adc_reg,adc_reg,adc_imm")] 1029) 1030 1031(define_insn "*addsi3_carryin_shift_<optab>" 1032 [(set (match_operand:SI 0 "s_register_operand" "=r") 1033 (plus:SI (plus:SI 1034 (match_operator:SI 2 "shift_operator" 1035 [(match_operand:SI 3 "s_register_operand" "r") 1036 (match_operand:SI 4 "reg_or_int_operand" "rM")]) 1037 (match_operand:SI 1 "s_register_operand" "r")) 1038 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0))))] 1039 "TARGET_32BIT" 1040 "adc%?\\t%0, %1, %3%S2" 1041 [(set_attr "conds" "use") 1042 (set_attr "predicable" "yes") 1043 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") 1044 (const_string "alu_shift_imm") 1045 (const_string "alu_shift_reg")))] 1046) 1047 1048(define_insn "*addsi3_carryin_clobercc_<optab>" 1049 [(set (match_operand:SI 0 "s_register_operand" "=r") 1050 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%r") 1051 (match_operand:SI 2 "arm_rhs_operand" "rI")) 1052 (LTUGEU:SI (reg:<cnb> CC_REGNUM) (const_int 0)))) 1053 (clobber (reg:CC CC_REGNUM))] 1054 "TARGET_32BIT" 1055 "adcs%?\\t%0, %1, %2" 1056 [(set_attr "conds" "set") 1057 (set_attr "type" "adcs_reg")] 1058) 1059 1060(define_expand "subv<mode>4" 1061 [(match_operand:SIDI 0 "register_operand") 1062 (match_operand:SIDI 1 "register_operand") 1063 (match_operand:SIDI 2 "register_operand") 1064 (match_operand 3 "")] 1065 "TARGET_32BIT" 1066{ 1067 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2])); 1068 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]); 1069 1070 DONE; 1071}) 1072 1073(define_expand "usubv<mode>4" 1074 [(match_operand:SIDI 0 "register_operand") 1075 (match_operand:SIDI 1 "register_operand") 1076 (match_operand:SIDI 2 "register_operand") 1077 (match_operand 3 "")] 1078 "TARGET_32BIT" 1079{ 1080 emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2])); 1081 arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]); 1082 1083 DONE; 1084}) 1085 1086(define_insn_and_split "subdi3_compare1" 1087 [(set (reg:CC CC_REGNUM) 1088 (compare:CC 1089 (match_operand:DI 1 "register_operand" "r") 1090 (match_operand:DI 2 "register_operand" "r"))) 1091 (set (match_operand:DI 0 "register_operand" "=&r") 1092 (minus:DI (match_dup 1) (match_dup 2)))] 1093 "TARGET_32BIT" 1094 "#" 1095 "&& reload_completed" 1096 [(parallel [(set (reg:CC CC_REGNUM) 1097 (compare:CC (match_dup 1) (match_dup 2))) 1098 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 1099 (parallel [(set (reg:CC CC_REGNUM) 1100 (compare:CC (match_dup 4) (match_dup 5))) 1101 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5)) 1102 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])] 1103 { 1104 operands[3] = gen_highpart (SImode, operands[0]); 1105 operands[0] = gen_lowpart (SImode, operands[0]); 1106 operands[4] = gen_highpart (SImode, operands[1]); 1107 operands[1] = gen_lowpart (SImode, operands[1]); 1108 operands[5] = gen_highpart (SImode, operands[2]); 1109 operands[2] = gen_lowpart (SImode, operands[2]); 1110 } 1111 [(set_attr "conds" "set") 1112 (set_attr "length" "8") 1113 (set_attr "type" "multiple")] 1114) 1115 1116(define_insn "subsi3_compare1" 1117 [(set (reg:CC CC_REGNUM) 1118 (compare:CC 1119 (match_operand:SI 1 "register_operand" "r") 1120 (match_operand:SI 2 "register_operand" "r"))) 1121 (set (match_operand:SI 0 "register_operand" "=r") 1122 (minus:SI (match_dup 1) (match_dup 2)))] 1123 "TARGET_32BIT" 1124 "subs%?\\t%0, %1, %2" 1125 [(set_attr "conds" "set") 1126 (set_attr "type" "alus_sreg")] 1127) 1128 1129(define_insn "*subsi3_carryin" 1130 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 1131 (minus:SI (minus:SI (match_operand:SI 1 "reg_or_int_operand" "r,I,Pz") 1132 (match_operand:SI 2 "s_register_operand" "r,r,r")) 1133 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1134 "TARGET_32BIT" 1135 "@ 1136 sbc%?\\t%0, %1, %2 1137 rsc%?\\t%0, %2, %1 1138 sbc%?\\t%0, %2, %2, lsl #1" 1139 [(set_attr "conds" "use") 1140 (set_attr "arch" "*,a,t2") 1141 (set_attr "predicable" "yes") 1142 (set_attr "type" "adc_reg,adc_imm,alu_shift_imm")] 1143) 1144 1145(define_insn "*subsi3_carryin_const" 1146 [(set (match_operand:SI 0 "s_register_operand" "=r") 1147 (minus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") 1148 (match_operand:SI 2 "arm_not_immediate_operand" "K")) 1149 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1150 "TARGET_32BIT" 1151 "sbc\\t%0, %1, #%B2" 1152 [(set_attr "conds" "use") 1153 (set_attr "type" "adc_imm")] 1154) 1155 1156(define_insn "*subsi3_carryin_compare" 1157 [(set (reg:CC CC_REGNUM) 1158 (compare:CC (match_operand:SI 1 "s_register_operand" "r") 1159 (match_operand:SI 2 "s_register_operand" "r"))) 1160 (set (match_operand:SI 0 "s_register_operand" "=r") 1161 (minus:SI (minus:SI (match_dup 1) 1162 (match_dup 2)) 1163 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1164 "TARGET_32BIT" 1165 "sbcs\\t%0, %1, %2" 1166 [(set_attr "conds" "set") 1167 (set_attr "type" "adcs_reg")] 1168) 1169 1170(define_insn "*subsi3_carryin_compare_const" 1171 [(set (reg:CC CC_REGNUM) 1172 (compare:CC (match_operand:SI 1 "reg_or_int_operand" "r") 1173 (match_operand:SI 2 "arm_not_operand" "K"))) 1174 (set (match_operand:SI 0 "s_register_operand" "=r") 1175 (minus:SI (plus:SI (match_dup 1) 1176 (match_dup 2)) 1177 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1178 "TARGET_32BIT" 1179 "sbcs\\t%0, %1, #%B2" 1180 [(set_attr "conds" "set") 1181 (set_attr "type" "adcs_imm")] 1182) 1183 1184(define_insn "*subsi3_carryin_shift" 1185 [(set (match_operand:SI 0 "s_register_operand" "=r") 1186 (minus:SI (minus:SI 1187 (match_operand:SI 1 "s_register_operand" "r") 1188 (match_operator:SI 2 "shift_operator" 1189 [(match_operand:SI 3 "s_register_operand" "r") 1190 (match_operand:SI 4 "reg_or_int_operand" "rM")])) 1191 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1192 "TARGET_32BIT" 1193 "sbc%?\\t%0, %1, %3%S2" 1194 [(set_attr "conds" "use") 1195 (set_attr "predicable" "yes") 1196 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") 1197 (const_string "alu_shift_imm") 1198 (const_string "alu_shift_reg")))] 1199) 1200 1201(define_insn "*rsbsi3_carryin_shift" 1202 [(set (match_operand:SI 0 "s_register_operand" "=r") 1203 (minus:SI (minus:SI 1204 (match_operator:SI 2 "shift_operator" 1205 [(match_operand:SI 3 "s_register_operand" "r") 1206 (match_operand:SI 4 "reg_or_int_operand" "rM")]) 1207 (match_operand:SI 1 "s_register_operand" "r")) 1208 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1209 "TARGET_ARM" 1210 "rsc%?\\t%0, %1, %3%S2" 1211 [(set_attr "conds" "use") 1212 (set_attr "predicable" "yes") 1213 (set (attr "type") (if_then_else (match_operand 4 "const_int_operand" "") 1214 (const_string "alu_shift_imm") 1215 (const_string "alu_shift_reg")))] 1216) 1217 1218; transform ((x << y) - 1) to ~(~(x-1) << y) Where X is a constant. 1219(define_split 1220 [(set (match_operand:SI 0 "s_register_operand" "") 1221 (plus:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "") 1222 (match_operand:SI 2 "s_register_operand" "")) 1223 (const_int -1))) 1224 (clobber (match_operand:SI 3 "s_register_operand" ""))] 1225 "TARGET_32BIT" 1226 [(set (match_dup 3) (match_dup 1)) 1227 (set (match_dup 0) (not:SI (ashift:SI (match_dup 3) (match_dup 2))))] 1228 " 1229 operands[1] = GEN_INT (~(INTVAL (operands[1]) - 1)); 1230") 1231 1232(define_expand "addsf3" 1233 [(set (match_operand:SF 0 "s_register_operand" "") 1234 (plus:SF (match_operand:SF 1 "s_register_operand" "") 1235 (match_operand:SF 2 "s_register_operand" "")))] 1236 "TARGET_32BIT && TARGET_HARD_FLOAT" 1237 " 1238") 1239 1240(define_expand "adddf3" 1241 [(set (match_operand:DF 0 "s_register_operand" "") 1242 (plus:DF (match_operand:DF 1 "s_register_operand" "") 1243 (match_operand:DF 2 "s_register_operand" "")))] 1244 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 1245 " 1246") 1247 1248(define_expand "subdi3" 1249 [(parallel 1250 [(set (match_operand:DI 0 "s_register_operand" "") 1251 (minus:DI (match_operand:DI 1 "s_register_operand" "") 1252 (match_operand:DI 2 "s_register_operand" ""))) 1253 (clobber (reg:CC CC_REGNUM))])] 1254 "TARGET_EITHER" 1255 " 1256 if (TARGET_THUMB1) 1257 { 1258 if (!REG_P (operands[1])) 1259 operands[1] = force_reg (DImode, operands[1]); 1260 if (!REG_P (operands[2])) 1261 operands[2] = force_reg (DImode, operands[2]); 1262 } 1263 " 1264) 1265 1266(define_insn_and_split "*arm_subdi3" 1267 [(set (match_operand:DI 0 "arm_general_register_operand" "=&r,&r,&r") 1268 (minus:DI (match_operand:DI 1 "arm_general_register_operand" "0,r,0") 1269 (match_operand:DI 2 "arm_general_register_operand" "r,0,0"))) 1270 (clobber (reg:CC CC_REGNUM))] 1271 "TARGET_32BIT && !TARGET_NEON" 1272 "#" ; "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2" 1273 "&& (!TARGET_IWMMXT || reload_completed)" 1274 [(parallel [(set (reg:CC CC_REGNUM) 1275 (compare:CC (match_dup 1) (match_dup 2))) 1276 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 1277 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) (match_dup 5)) 1278 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1279 { 1280 operands[3] = gen_highpart (SImode, operands[0]); 1281 operands[0] = gen_lowpart (SImode, operands[0]); 1282 operands[4] = gen_highpart (SImode, operands[1]); 1283 operands[1] = gen_lowpart (SImode, operands[1]); 1284 operands[5] = gen_highpart (SImode, operands[2]); 1285 operands[2] = gen_lowpart (SImode, operands[2]); 1286 } 1287 [(set_attr "conds" "clob") 1288 (set_attr "length" "8") 1289 (set_attr "type" "multiple")] 1290) 1291 1292(define_insn_and_split "*subdi_di_zesidi" 1293 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1294 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r") 1295 (zero_extend:DI 1296 (match_operand:SI 2 "s_register_operand" "r,r")))) 1297 (clobber (reg:CC CC_REGNUM))] 1298 "TARGET_32BIT" 1299 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0" 1300 "&& reload_completed" 1301 [(parallel [(set (reg:CC CC_REGNUM) 1302 (compare:CC (match_dup 1) (match_dup 2))) 1303 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 1304 (set (match_dup 3) (minus:SI (plus:SI (match_dup 4) (match_dup 5)) 1305 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1306 { 1307 operands[3] = gen_highpart (SImode, operands[0]); 1308 operands[0] = gen_lowpart (SImode, operands[0]); 1309 operands[4] = gen_highpart (SImode, operands[1]); 1310 operands[1] = gen_lowpart (SImode, operands[1]); 1311 operands[5] = GEN_INT (~0); 1312 } 1313 [(set_attr "conds" "clob") 1314 (set_attr "length" "8") 1315 (set_attr "type" "multiple")] 1316) 1317 1318(define_insn_and_split "*subdi_di_sesidi" 1319 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1320 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r") 1321 (sign_extend:DI 1322 (match_operand:SI 2 "s_register_operand" "r,r")))) 1323 (clobber (reg:CC CC_REGNUM))] 1324 "TARGET_32BIT" 1325 "#" ; "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31" 1326 "&& reload_completed" 1327 [(parallel [(set (reg:CC CC_REGNUM) 1328 (compare:CC (match_dup 1) (match_dup 2))) 1329 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 1330 (set (match_dup 3) (minus:SI (minus:SI (match_dup 4) 1331 (ashiftrt:SI (match_dup 2) 1332 (const_int 31))) 1333 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1334 { 1335 operands[3] = gen_highpart (SImode, operands[0]); 1336 operands[0] = gen_lowpart (SImode, operands[0]); 1337 operands[4] = gen_highpart (SImode, operands[1]); 1338 operands[1] = gen_lowpart (SImode, operands[1]); 1339 } 1340 [(set_attr "conds" "clob") 1341 (set_attr "length" "8") 1342 (set_attr "type" "multiple")] 1343) 1344 1345(define_insn_and_split "*subdi_zesidi_di" 1346 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1347 (minus:DI (zero_extend:DI 1348 (match_operand:SI 2 "s_register_operand" "r,r")) 1349 (match_operand:DI 1 "s_register_operand" "0,r"))) 1350 (clobber (reg:CC CC_REGNUM))] 1351 "TARGET_ARM" 1352 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0" 1353 ; is equivalent to: 1354 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, #0" 1355 "&& reload_completed" 1356 [(parallel [(set (reg:CC CC_REGNUM) 1357 (compare:CC (match_dup 2) (match_dup 1))) 1358 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))]) 1359 (set (match_dup 3) (minus:SI (minus:SI (const_int 0) (match_dup 4)) 1360 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1361 { 1362 operands[3] = gen_highpart (SImode, operands[0]); 1363 operands[0] = gen_lowpart (SImode, operands[0]); 1364 operands[4] = gen_highpart (SImode, operands[1]); 1365 operands[1] = gen_lowpart (SImode, operands[1]); 1366 } 1367 [(set_attr "conds" "clob") 1368 (set_attr "length" "8") 1369 (set_attr "type" "multiple")] 1370) 1371 1372(define_insn_and_split "*subdi_sesidi_di" 1373 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1374 (minus:DI (sign_extend:DI 1375 (match_operand:SI 2 "s_register_operand" "r,r")) 1376 (match_operand:DI 1 "s_register_operand" "0,r"))) 1377 (clobber (reg:CC CC_REGNUM))] 1378 "TARGET_ARM" 1379 "#" ; "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31" 1380 ; is equivalent to: 1381 ; "subs\\t%Q0, %2, %Q1\;rsc\\t%R0, %R1, %2, asr #31" 1382 "&& reload_completed" 1383 [(parallel [(set (reg:CC CC_REGNUM) 1384 (compare:CC (match_dup 2) (match_dup 1))) 1385 (set (match_dup 0) (minus:SI (match_dup 2) (match_dup 1)))]) 1386 (set (match_dup 3) (minus:SI (minus:SI 1387 (ashiftrt:SI (match_dup 2) 1388 (const_int 31)) 1389 (match_dup 4)) 1390 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1391 { 1392 operands[3] = gen_highpart (SImode, operands[0]); 1393 operands[0] = gen_lowpart (SImode, operands[0]); 1394 operands[4] = gen_highpart (SImode, operands[1]); 1395 operands[1] = gen_lowpart (SImode, operands[1]); 1396 } 1397 [(set_attr "conds" "clob") 1398 (set_attr "length" "8") 1399 (set_attr "type" "multiple")] 1400) 1401 1402(define_insn_and_split "*subdi_zesidi_zesidi" 1403 [(set (match_operand:DI 0 "s_register_operand" "=r") 1404 (minus:DI (zero_extend:DI 1405 (match_operand:SI 1 "s_register_operand" "r")) 1406 (zero_extend:DI 1407 (match_operand:SI 2 "s_register_operand" "r")))) 1408 (clobber (reg:CC CC_REGNUM))] 1409 "TARGET_32BIT" 1410 "#" ; "subs\\t%Q0, %1, %2\;sbc\\t%R0, %1, %1" 1411 "&& reload_completed" 1412 [(parallel [(set (reg:CC CC_REGNUM) 1413 (compare:CC (match_dup 1) (match_dup 2))) 1414 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 1415 (set (match_dup 3) (minus:SI (minus:SI (match_dup 1) (match_dup 1)) 1416 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 1417 { 1418 operands[3] = gen_highpart (SImode, operands[0]); 1419 operands[0] = gen_lowpart (SImode, operands[0]); 1420 } 1421 [(set_attr "conds" "clob") 1422 (set_attr "length" "8") 1423 (set_attr "type" "multiple")] 1424) 1425 1426(define_expand "subsi3" 1427 [(set (match_operand:SI 0 "s_register_operand" "") 1428 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "") 1429 (match_operand:SI 2 "s_register_operand" "")))] 1430 "TARGET_EITHER" 1431 " 1432 if (CONST_INT_P (operands[1])) 1433 { 1434 if (TARGET_32BIT) 1435 { 1436 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), MINUS)) 1437 operands[1] = force_reg (SImode, operands[1]); 1438 else 1439 { 1440 arm_split_constant (MINUS, SImode, NULL_RTX, 1441 INTVAL (operands[1]), operands[0], 1442 operands[2], 1443 optimize && can_create_pseudo_p ()); 1444 DONE; 1445 } 1446 } 1447 else /* TARGET_THUMB1 */ 1448 operands[1] = force_reg (SImode, operands[1]); 1449 } 1450 " 1451) 1452 1453; ??? Check Thumb-2 split length 1454(define_insn_and_split "*arm_subsi3_insn" 1455 [(set (match_operand:SI 0 "s_register_operand" "=l,l ,l ,l ,r,r,r,rk,r") 1456 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "l ,0 ,l ,Pz,I,r,r,k ,?n") 1457 (match_operand:SI 2 "reg_or_int_operand" "l ,Py,Pd,l ,r,I,r,r ,r")))] 1458 "TARGET_32BIT" 1459 "@ 1460 sub%?\\t%0, %1, %2 1461 sub%?\\t%0, %2 1462 sub%?\\t%0, %1, %2 1463 rsb%?\\t%0, %2, %1 1464 rsb%?\\t%0, %2, %1 1465 sub%?\\t%0, %1, %2 1466 sub%?\\t%0, %1, %2 1467 sub%?\\t%0, %1, %2 1468 #" 1469 "&& (CONST_INT_P (operands[1]) 1470 && !const_ok_for_arm (INTVAL (operands[1])))" 1471 [(clobber (const_int 0))] 1472 " 1473 arm_split_constant (MINUS, SImode, curr_insn, 1474 INTVAL (operands[1]), operands[0], operands[2], 0); 1475 DONE; 1476 " 1477 [(set_attr "length" "4,4,4,4,4,4,4,4,16") 1478 (set_attr "arch" "t2,t2,t2,t2,*,*,*,*,*") 1479 (set_attr "predicable" "yes") 1480 (set_attr "predicable_short_it" "yes,yes,yes,yes,no,no,no,no,no") 1481 (set_attr "type" "alu_sreg,alu_sreg,alu_sreg,alu_sreg,alu_imm,alu_imm,alu_sreg,alu_sreg,multiple")] 1482) 1483 1484(define_peephole2 1485 [(match_scratch:SI 3 "r") 1486 (set (match_operand:SI 0 "arm_general_register_operand" "") 1487 (minus:SI (match_operand:SI 1 "const_int_operand" "") 1488 (match_operand:SI 2 "arm_general_register_operand" "")))] 1489 "TARGET_32BIT 1490 && !const_ok_for_arm (INTVAL (operands[1])) 1491 && const_ok_for_arm (~INTVAL (operands[1]))" 1492 [(set (match_dup 3) (match_dup 1)) 1493 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))] 1494 "" 1495) 1496 1497(define_insn "subsi3_compare0" 1498 [(set (reg:CC_NOOV CC_REGNUM) 1499 (compare:CC_NOOV 1500 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I") 1501 (match_operand:SI 2 "arm_rhs_operand" "I,r,r")) 1502 (const_int 0))) 1503 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 1504 (minus:SI (match_dup 1) (match_dup 2)))] 1505 "TARGET_32BIT" 1506 "@ 1507 subs%?\\t%0, %1, %2 1508 subs%?\\t%0, %1, %2 1509 rsbs%?\\t%0, %2, %1" 1510 [(set_attr "conds" "set") 1511 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")] 1512) 1513 1514(define_insn "subsi3_compare" 1515 [(set (reg:CC CC_REGNUM) 1516 (compare:CC (match_operand:SI 1 "arm_rhs_operand" "r,r,I") 1517 (match_operand:SI 2 "arm_rhs_operand" "I,r,r"))) 1518 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 1519 (minus:SI (match_dup 1) (match_dup 2)))] 1520 "TARGET_32BIT" 1521 "@ 1522 subs%?\\t%0, %1, %2 1523 subs%?\\t%0, %1, %2 1524 rsbs%?\\t%0, %2, %1" 1525 [(set_attr "conds" "set") 1526 (set_attr "type" "alus_imm,alus_sreg,alus_sreg")] 1527) 1528 1529(define_expand "subsf3" 1530 [(set (match_operand:SF 0 "s_register_operand" "") 1531 (minus:SF (match_operand:SF 1 "s_register_operand" "") 1532 (match_operand:SF 2 "s_register_operand" "")))] 1533 "TARGET_32BIT && TARGET_HARD_FLOAT" 1534 " 1535") 1536 1537(define_expand "subdf3" 1538 [(set (match_operand:DF 0 "s_register_operand" "") 1539 (minus:DF (match_operand:DF 1 "s_register_operand" "") 1540 (match_operand:DF 2 "s_register_operand" "")))] 1541 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 1542 " 1543") 1544 1545 1546;; Multiplication insns 1547 1548(define_expand "mulhi3" 1549 [(set (match_operand:HI 0 "s_register_operand" "") 1550 (mult:HI (match_operand:HI 1 "s_register_operand" "") 1551 (match_operand:HI 2 "s_register_operand" "")))] 1552 "TARGET_DSP_MULTIPLY" 1553 " 1554 { 1555 rtx result = gen_reg_rtx (SImode); 1556 emit_insn (gen_mulhisi3 (result, operands[1], operands[2])); 1557 emit_move_insn (operands[0], gen_lowpart (HImode, result)); 1558 DONE; 1559 }" 1560) 1561 1562(define_expand "mulsi3" 1563 [(set (match_operand:SI 0 "s_register_operand" "") 1564 (mult:SI (match_operand:SI 2 "s_register_operand" "") 1565 (match_operand:SI 1 "s_register_operand" "")))] 1566 "TARGET_EITHER" 1567 "" 1568) 1569 1570;; Use `&' and then `0' to prevent the operands 0 and 1 being the same 1571(define_insn "*arm_mulsi3" 1572 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1573 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") 1574 (match_operand:SI 1 "s_register_operand" "%0,r")))] 1575 "TARGET_32BIT && !arm_arch6" 1576 "mul%?\\t%0, %2, %1" 1577 [(set_attr "type" "mul") 1578 (set_attr "predicable" "yes")] 1579) 1580 1581(define_insn "*arm_mulsi3_v6" 1582 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") 1583 (mult:SI (match_operand:SI 1 "s_register_operand" "0,l,r") 1584 (match_operand:SI 2 "s_register_operand" "l,0,r")))] 1585 "TARGET_32BIT && arm_arch6" 1586 "mul%?\\t%0, %1, %2" 1587 [(set_attr "type" "mul") 1588 (set_attr "predicable" "yes") 1589 (set_attr "arch" "t2,t2,*") 1590 (set_attr "length" "4") 1591 (set_attr "predicable_short_it" "yes,yes,no")] 1592) 1593 1594(define_insn "*mulsi3_compare0" 1595 [(set (reg:CC_NOOV CC_REGNUM) 1596 (compare:CC_NOOV (mult:SI 1597 (match_operand:SI 2 "s_register_operand" "r,r") 1598 (match_operand:SI 1 "s_register_operand" "%0,r")) 1599 (const_int 0))) 1600 (set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1601 (mult:SI (match_dup 2) (match_dup 1)))] 1602 "TARGET_ARM && !arm_arch6" 1603 "muls%?\\t%0, %2, %1" 1604 [(set_attr "conds" "set") 1605 (set_attr "type" "muls")] 1606) 1607 1608(define_insn "*mulsi3_compare0_v6" 1609 [(set (reg:CC_NOOV CC_REGNUM) 1610 (compare:CC_NOOV (mult:SI 1611 (match_operand:SI 2 "s_register_operand" "r") 1612 (match_operand:SI 1 "s_register_operand" "r")) 1613 (const_int 0))) 1614 (set (match_operand:SI 0 "s_register_operand" "=r") 1615 (mult:SI (match_dup 2) (match_dup 1)))] 1616 "TARGET_ARM && arm_arch6 && optimize_size" 1617 "muls%?\\t%0, %2, %1" 1618 [(set_attr "conds" "set") 1619 (set_attr "type" "muls")] 1620) 1621 1622(define_insn "*mulsi_compare0_scratch" 1623 [(set (reg:CC_NOOV CC_REGNUM) 1624 (compare:CC_NOOV (mult:SI 1625 (match_operand:SI 2 "s_register_operand" "r,r") 1626 (match_operand:SI 1 "s_register_operand" "%0,r")) 1627 (const_int 0))) 1628 (clobber (match_scratch:SI 0 "=&r,&r"))] 1629 "TARGET_ARM && !arm_arch6" 1630 "muls%?\\t%0, %2, %1" 1631 [(set_attr "conds" "set") 1632 (set_attr "type" "muls")] 1633) 1634 1635(define_insn "*mulsi_compare0_scratch_v6" 1636 [(set (reg:CC_NOOV CC_REGNUM) 1637 (compare:CC_NOOV (mult:SI 1638 (match_operand:SI 2 "s_register_operand" "r") 1639 (match_operand:SI 1 "s_register_operand" "r")) 1640 (const_int 0))) 1641 (clobber (match_scratch:SI 0 "=r"))] 1642 "TARGET_ARM && arm_arch6 && optimize_size" 1643 "muls%?\\t%0, %2, %1" 1644 [(set_attr "conds" "set") 1645 (set_attr "type" "muls")] 1646) 1647 1648;; Unnamed templates to match MLA instruction. 1649 1650(define_insn "*mulsi3addsi" 1651 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") 1652 (plus:SI 1653 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r") 1654 (match_operand:SI 1 "s_register_operand" "%0,r,0,r")) 1655 (match_operand:SI 3 "s_register_operand" "r,r,0,0")))] 1656 "TARGET_32BIT && !arm_arch6" 1657 "mla%?\\t%0, %2, %1, %3" 1658 [(set_attr "type" "mla") 1659 (set_attr "predicable" "yes")] 1660) 1661 1662(define_insn "*mulsi3addsi_v6" 1663 [(set (match_operand:SI 0 "s_register_operand" "=r") 1664 (plus:SI 1665 (mult:SI (match_operand:SI 2 "s_register_operand" "r") 1666 (match_operand:SI 1 "s_register_operand" "r")) 1667 (match_operand:SI 3 "s_register_operand" "r")))] 1668 "TARGET_32BIT && arm_arch6" 1669 "mla%?\\t%0, %2, %1, %3" 1670 [(set_attr "type" "mla") 1671 (set_attr "predicable" "yes")] 1672) 1673 1674(define_insn "*mulsi3addsi_compare0" 1675 [(set (reg:CC_NOOV CC_REGNUM) 1676 (compare:CC_NOOV 1677 (plus:SI (mult:SI 1678 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 1679 (match_operand:SI 1 "s_register_operand" "%0,r,0,r")) 1680 (match_operand:SI 3 "s_register_operand" "r,r,0,0")) 1681 (const_int 0))) 1682 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") 1683 (plus:SI (mult:SI (match_dup 2) (match_dup 1)) 1684 (match_dup 3)))] 1685 "TARGET_ARM && arm_arch6" 1686 "mlas%?\\t%0, %2, %1, %3" 1687 [(set_attr "conds" "set") 1688 (set_attr "type" "mlas")] 1689) 1690 1691(define_insn "*mulsi3addsi_compare0_v6" 1692 [(set (reg:CC_NOOV CC_REGNUM) 1693 (compare:CC_NOOV 1694 (plus:SI (mult:SI 1695 (match_operand:SI 2 "s_register_operand" "r") 1696 (match_operand:SI 1 "s_register_operand" "r")) 1697 (match_operand:SI 3 "s_register_operand" "r")) 1698 (const_int 0))) 1699 (set (match_operand:SI 0 "s_register_operand" "=r") 1700 (plus:SI (mult:SI (match_dup 2) (match_dup 1)) 1701 (match_dup 3)))] 1702 "TARGET_ARM && arm_arch6 && optimize_size" 1703 "mlas%?\\t%0, %2, %1, %3" 1704 [(set_attr "conds" "set") 1705 (set_attr "type" "mlas")] 1706) 1707 1708(define_insn "*mulsi3addsi_compare0_scratch" 1709 [(set (reg:CC_NOOV CC_REGNUM) 1710 (compare:CC_NOOV 1711 (plus:SI (mult:SI 1712 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 1713 (match_operand:SI 1 "s_register_operand" "%0,r,0,r")) 1714 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")) 1715 (const_int 0))) 1716 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))] 1717 "TARGET_ARM && !arm_arch6" 1718 "mlas%?\\t%0, %2, %1, %3" 1719 [(set_attr "conds" "set") 1720 (set_attr "type" "mlas")] 1721) 1722 1723(define_insn "*mulsi3addsi_compare0_scratch_v6" 1724 [(set (reg:CC_NOOV CC_REGNUM) 1725 (compare:CC_NOOV 1726 (plus:SI (mult:SI 1727 (match_operand:SI 2 "s_register_operand" "r") 1728 (match_operand:SI 1 "s_register_operand" "r")) 1729 (match_operand:SI 3 "s_register_operand" "r")) 1730 (const_int 0))) 1731 (clobber (match_scratch:SI 0 "=r"))] 1732 "TARGET_ARM && arm_arch6 && optimize_size" 1733 "mlas%?\\t%0, %2, %1, %3" 1734 [(set_attr "conds" "set") 1735 (set_attr "type" "mlas")] 1736) 1737 1738(define_insn "*mulsi3subsi" 1739 [(set (match_operand:SI 0 "s_register_operand" "=r") 1740 (minus:SI 1741 (match_operand:SI 3 "s_register_operand" "r") 1742 (mult:SI (match_operand:SI 2 "s_register_operand" "r") 1743 (match_operand:SI 1 "s_register_operand" "r"))))] 1744 "TARGET_32BIT && arm_arch_thumb2" 1745 "mls%?\\t%0, %2, %1, %3" 1746 [(set_attr "type" "mla") 1747 (set_attr "predicable" "yes")] 1748) 1749 1750(define_expand "maddsidi4" 1751 [(set (match_operand:DI 0 "s_register_operand" "") 1752 (plus:DI 1753 (mult:DI 1754 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1755 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))) 1756 (match_operand:DI 3 "s_register_operand" "")))] 1757 "TARGET_32BIT && arm_arch3m" 1758 "") 1759 1760(define_insn "*mulsidi3adddi" 1761 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1762 (plus:DI 1763 (mult:DI 1764 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r")) 1765 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r"))) 1766 (match_operand:DI 1 "s_register_operand" "0")))] 1767 "TARGET_32BIT && arm_arch3m && !arm_arch6" 1768 "smlal%?\\t%Q0, %R0, %3, %2" 1769 [(set_attr "type" "smlal") 1770 (set_attr "predicable" "yes")] 1771) 1772 1773(define_insn "*mulsidi3adddi_v6" 1774 [(set (match_operand:DI 0 "s_register_operand" "=r") 1775 (plus:DI 1776 (mult:DI 1777 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r")) 1778 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r"))) 1779 (match_operand:DI 1 "s_register_operand" "0")))] 1780 "TARGET_32BIT && arm_arch6" 1781 "smlal%?\\t%Q0, %R0, %3, %2" 1782 [(set_attr "type" "smlal") 1783 (set_attr "predicable" "yes")] 1784) 1785 1786;; 32x32->64 widening multiply. 1787;; As with mulsi3, the only difference between the v3-5 and v6+ 1788;; versions of these patterns is the requirement that the output not 1789;; overlap the inputs, but that still means we have to have a named 1790;; expander and two different starred insns. 1791 1792(define_expand "mulsidi3" 1793 [(set (match_operand:DI 0 "s_register_operand" "") 1794 (mult:DI 1795 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1796 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))))] 1797 "TARGET_32BIT && arm_arch3m" 1798 "" 1799) 1800 1801(define_insn "*mulsidi3_nov6" 1802 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1803 (mult:DI 1804 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r")) 1805 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] 1806 "TARGET_32BIT && arm_arch3m && !arm_arch6" 1807 "smull%?\\t%Q0, %R0, %1, %2" 1808 [(set_attr "type" "smull") 1809 (set_attr "predicable" "yes")] 1810) 1811 1812(define_insn "*mulsidi3_v6" 1813 [(set (match_operand:DI 0 "s_register_operand" "=r") 1814 (mult:DI 1815 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")) 1816 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] 1817 "TARGET_32BIT && arm_arch6" 1818 "smull%?\\t%Q0, %R0, %1, %2" 1819 [(set_attr "type" "smull") 1820 (set_attr "predicable" "yes")] 1821) 1822 1823(define_expand "umulsidi3" 1824 [(set (match_operand:DI 0 "s_register_operand" "") 1825 (mult:DI 1826 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1827 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))))] 1828 "TARGET_32BIT && arm_arch3m" 1829 "" 1830) 1831 1832(define_insn "*umulsidi3_nov6" 1833 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1834 (mult:DI 1835 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r")) 1836 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] 1837 "TARGET_32BIT && arm_arch3m && !arm_arch6" 1838 "umull%?\\t%Q0, %R0, %1, %2" 1839 [(set_attr "type" "umull") 1840 (set_attr "predicable" "yes")] 1841) 1842 1843(define_insn "*umulsidi3_v6" 1844 [(set (match_operand:DI 0 "s_register_operand" "=r") 1845 (mult:DI 1846 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")) 1847 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] 1848 "TARGET_32BIT && arm_arch6" 1849 "umull%?\\t%Q0, %R0, %1, %2" 1850 [(set_attr "type" "umull") 1851 (set_attr "predicable" "yes")] 1852) 1853 1854(define_expand "umaddsidi4" 1855 [(set (match_operand:DI 0 "s_register_operand" "") 1856 (plus:DI 1857 (mult:DI 1858 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1859 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))) 1860 (match_operand:DI 3 "s_register_operand" "")))] 1861 "TARGET_32BIT && arm_arch3m" 1862 "") 1863 1864(define_insn "*umulsidi3adddi" 1865 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1866 (plus:DI 1867 (mult:DI 1868 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r")) 1869 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r"))) 1870 (match_operand:DI 1 "s_register_operand" "0")))] 1871 "TARGET_32BIT && arm_arch3m && !arm_arch6" 1872 "umlal%?\\t%Q0, %R0, %3, %2" 1873 [(set_attr "type" "umlal") 1874 (set_attr "predicable" "yes")] 1875) 1876 1877(define_insn "*umulsidi3adddi_v6" 1878 [(set (match_operand:DI 0 "s_register_operand" "=r") 1879 (plus:DI 1880 (mult:DI 1881 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r")) 1882 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r"))) 1883 (match_operand:DI 1 "s_register_operand" "0")))] 1884 "TARGET_32BIT && arm_arch6" 1885 "umlal%?\\t%Q0, %R0, %3, %2" 1886 [(set_attr "type" "umlal") 1887 (set_attr "predicable" "yes")] 1888) 1889 1890(define_expand "smulsi3_highpart" 1891 [(parallel 1892 [(set (match_operand:SI 0 "s_register_operand" "") 1893 (truncate:SI 1894 (lshiftrt:DI 1895 (mult:DI 1896 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1897 (sign_extend:DI (match_operand:SI 2 "s_register_operand" ""))) 1898 (const_int 32)))) 1899 (clobber (match_scratch:SI 3 ""))])] 1900 "TARGET_32BIT && arm_arch3m" 1901 "" 1902) 1903 1904(define_insn "*smulsi3_highpart_nov6" 1905 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1906 (truncate:SI 1907 (lshiftrt:DI 1908 (mult:DI 1909 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r")) 1910 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r"))) 1911 (const_int 32)))) 1912 (clobber (match_scratch:SI 3 "=&r,&r"))] 1913 "TARGET_32BIT && arm_arch3m && !arm_arch6" 1914 "smull%?\\t%3, %0, %2, %1" 1915 [(set_attr "type" "smull") 1916 (set_attr "predicable" "yes")] 1917) 1918 1919(define_insn "*smulsi3_highpart_v6" 1920 [(set (match_operand:SI 0 "s_register_operand" "=r") 1921 (truncate:SI 1922 (lshiftrt:DI 1923 (mult:DI 1924 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")) 1925 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))) 1926 (const_int 32)))) 1927 (clobber (match_scratch:SI 3 "=r"))] 1928 "TARGET_32BIT && arm_arch6" 1929 "smull%?\\t%3, %0, %2, %1" 1930 [(set_attr "type" "smull") 1931 (set_attr "predicable" "yes")] 1932) 1933 1934(define_expand "umulsi3_highpart" 1935 [(parallel 1936 [(set (match_operand:SI 0 "s_register_operand" "") 1937 (truncate:SI 1938 (lshiftrt:DI 1939 (mult:DI 1940 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "")) 1941 (zero_extend:DI (match_operand:SI 2 "s_register_operand" ""))) 1942 (const_int 32)))) 1943 (clobber (match_scratch:SI 3 ""))])] 1944 "TARGET_32BIT && arm_arch3m" 1945 "" 1946) 1947 1948(define_insn "*umulsi3_highpart_nov6" 1949 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1950 (truncate:SI 1951 (lshiftrt:DI 1952 (mult:DI 1953 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%0,r")) 1954 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r"))) 1955 (const_int 32)))) 1956 (clobber (match_scratch:SI 3 "=&r,&r"))] 1957 "TARGET_32BIT && arm_arch3m && !arm_arch6" 1958 "umull%?\\t%3, %0, %2, %1" 1959 [(set_attr "type" "umull") 1960 (set_attr "predicable" "yes")] 1961) 1962 1963(define_insn "*umulsi3_highpart_v6" 1964 [(set (match_operand:SI 0 "s_register_operand" "=r") 1965 (truncate:SI 1966 (lshiftrt:DI 1967 (mult:DI 1968 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")) 1969 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))) 1970 (const_int 32)))) 1971 (clobber (match_scratch:SI 3 "=r"))] 1972 "TARGET_32BIT && arm_arch6" 1973 "umull%?\\t%3, %0, %2, %1" 1974 [(set_attr "type" "umull") 1975 (set_attr "predicable" "yes")] 1976) 1977 1978(define_insn "mulhisi3" 1979 [(set (match_operand:SI 0 "s_register_operand" "=r") 1980 (mult:SI (sign_extend:SI 1981 (match_operand:HI 1 "s_register_operand" "%r")) 1982 (sign_extend:SI 1983 (match_operand:HI 2 "s_register_operand" "r"))))] 1984 "TARGET_DSP_MULTIPLY" 1985 "smulbb%?\\t%0, %1, %2" 1986 [(set_attr "type" "smulxy") 1987 (set_attr "predicable" "yes")] 1988) 1989 1990(define_insn "*mulhisi3tb" 1991 [(set (match_operand:SI 0 "s_register_operand" "=r") 1992 (mult:SI (ashiftrt:SI 1993 (match_operand:SI 1 "s_register_operand" "r") 1994 (const_int 16)) 1995 (sign_extend:SI 1996 (match_operand:HI 2 "s_register_operand" "r"))))] 1997 "TARGET_DSP_MULTIPLY" 1998 "smultb%?\\t%0, %1, %2" 1999 [(set_attr "type" "smulxy") 2000 (set_attr "predicable" "yes")] 2001) 2002 2003(define_insn "*mulhisi3bt" 2004 [(set (match_operand:SI 0 "s_register_operand" "=r") 2005 (mult:SI (sign_extend:SI 2006 (match_operand:HI 1 "s_register_operand" "r")) 2007 (ashiftrt:SI 2008 (match_operand:SI 2 "s_register_operand" "r") 2009 (const_int 16))))] 2010 "TARGET_DSP_MULTIPLY" 2011 "smulbt%?\\t%0, %1, %2" 2012 [(set_attr "type" "smulxy") 2013 (set_attr "predicable" "yes")] 2014) 2015 2016(define_insn "*mulhisi3tt" 2017 [(set (match_operand:SI 0 "s_register_operand" "=r") 2018 (mult:SI (ashiftrt:SI 2019 (match_operand:SI 1 "s_register_operand" "r") 2020 (const_int 16)) 2021 (ashiftrt:SI 2022 (match_operand:SI 2 "s_register_operand" "r") 2023 (const_int 16))))] 2024 "TARGET_DSP_MULTIPLY" 2025 "smultt%?\\t%0, %1, %2" 2026 [(set_attr "type" "smulxy") 2027 (set_attr "predicable" "yes")] 2028) 2029 2030(define_insn "maddhisi4" 2031 [(set (match_operand:SI 0 "s_register_operand" "=r") 2032 (plus:SI (mult:SI (sign_extend:SI 2033 (match_operand:HI 1 "s_register_operand" "r")) 2034 (sign_extend:SI 2035 (match_operand:HI 2 "s_register_operand" "r"))) 2036 (match_operand:SI 3 "s_register_operand" "r")))] 2037 "TARGET_DSP_MULTIPLY" 2038 "smlabb%?\\t%0, %1, %2, %3" 2039 [(set_attr "type" "smlaxy") 2040 (set_attr "predicable" "yes")] 2041) 2042 2043;; Note: there is no maddhisi4ibt because this one is canonical form 2044(define_insn "*maddhisi4tb" 2045 [(set (match_operand:SI 0 "s_register_operand" "=r") 2046 (plus:SI (mult:SI (ashiftrt:SI 2047 (match_operand:SI 1 "s_register_operand" "r") 2048 (const_int 16)) 2049 (sign_extend:SI 2050 (match_operand:HI 2 "s_register_operand" "r"))) 2051 (match_operand:SI 3 "s_register_operand" "r")))] 2052 "TARGET_DSP_MULTIPLY" 2053 "smlatb%?\\t%0, %1, %2, %3" 2054 [(set_attr "type" "smlaxy") 2055 (set_attr "predicable" "yes")] 2056) 2057 2058(define_insn "*maddhisi4tt" 2059 [(set (match_operand:SI 0 "s_register_operand" "=r") 2060 (plus:SI (mult:SI (ashiftrt:SI 2061 (match_operand:SI 1 "s_register_operand" "r") 2062 (const_int 16)) 2063 (ashiftrt:SI 2064 (match_operand:SI 2 "s_register_operand" "r") 2065 (const_int 16))) 2066 (match_operand:SI 3 "s_register_operand" "r")))] 2067 "TARGET_DSP_MULTIPLY" 2068 "smlatt%?\\t%0, %1, %2, %3" 2069 [(set_attr "type" "smlaxy") 2070 (set_attr "predicable" "yes")] 2071) 2072 2073(define_insn "maddhidi4" 2074 [(set (match_operand:DI 0 "s_register_operand" "=r") 2075 (plus:DI 2076 (mult:DI (sign_extend:DI 2077 (match_operand:HI 1 "s_register_operand" "r")) 2078 (sign_extend:DI 2079 (match_operand:HI 2 "s_register_operand" "r"))) 2080 (match_operand:DI 3 "s_register_operand" "0")))] 2081 "TARGET_DSP_MULTIPLY" 2082 "smlalbb%?\\t%Q0, %R0, %1, %2" 2083 [(set_attr "type" "smlalxy") 2084 (set_attr "predicable" "yes")]) 2085 2086;; Note: there is no maddhidi4ibt because this one is canonical form 2087(define_insn "*maddhidi4tb" 2088 [(set (match_operand:DI 0 "s_register_operand" "=r") 2089 (plus:DI 2090 (mult:DI (sign_extend:DI 2091 (ashiftrt:SI 2092 (match_operand:SI 1 "s_register_operand" "r") 2093 (const_int 16))) 2094 (sign_extend:DI 2095 (match_operand:HI 2 "s_register_operand" "r"))) 2096 (match_operand:DI 3 "s_register_operand" "0")))] 2097 "TARGET_DSP_MULTIPLY" 2098 "smlaltb%?\\t%Q0, %R0, %1, %2" 2099 [(set_attr "type" "smlalxy") 2100 (set_attr "predicable" "yes")]) 2101 2102(define_insn "*maddhidi4tt" 2103 [(set (match_operand:DI 0 "s_register_operand" "=r") 2104 (plus:DI 2105 (mult:DI (sign_extend:DI 2106 (ashiftrt:SI 2107 (match_operand:SI 1 "s_register_operand" "r") 2108 (const_int 16))) 2109 (sign_extend:DI 2110 (ashiftrt:SI 2111 (match_operand:SI 2 "s_register_operand" "r") 2112 (const_int 16)))) 2113 (match_operand:DI 3 "s_register_operand" "0")))] 2114 "TARGET_DSP_MULTIPLY" 2115 "smlaltt%?\\t%Q0, %R0, %1, %2" 2116 [(set_attr "type" "smlalxy") 2117 (set_attr "predicable" "yes")]) 2118 2119(define_expand "mulsf3" 2120 [(set (match_operand:SF 0 "s_register_operand" "") 2121 (mult:SF (match_operand:SF 1 "s_register_operand" "") 2122 (match_operand:SF 2 "s_register_operand" "")))] 2123 "TARGET_32BIT && TARGET_HARD_FLOAT" 2124 " 2125") 2126 2127(define_expand "muldf3" 2128 [(set (match_operand:DF 0 "s_register_operand" "") 2129 (mult:DF (match_operand:DF 1 "s_register_operand" "") 2130 (match_operand:DF 2 "s_register_operand" "")))] 2131 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 2132 " 2133") 2134 2135;; Division insns 2136 2137(define_expand "divsf3" 2138 [(set (match_operand:SF 0 "s_register_operand" "") 2139 (div:SF (match_operand:SF 1 "s_register_operand" "") 2140 (match_operand:SF 2 "s_register_operand" "")))] 2141 "TARGET_32BIT && TARGET_HARD_FLOAT" 2142 "") 2143 2144(define_expand "divdf3" 2145 [(set (match_operand:DF 0 "s_register_operand" "") 2146 (div:DF (match_operand:DF 1 "s_register_operand" "") 2147 (match_operand:DF 2 "s_register_operand" "")))] 2148 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 2149 "") 2150 2151;; Boolean and,ior,xor insns 2152 2153;; Split up double word logical operations 2154 2155;; Split up simple DImode logical operations. Simply perform the logical 2156;; operation on the upper and lower halves of the registers. 2157(define_split 2158 [(set (match_operand:DI 0 "s_register_operand" "") 2159 (match_operator:DI 6 "logical_binary_operator" 2160 [(match_operand:DI 1 "s_register_operand" "") 2161 (match_operand:DI 2 "s_register_operand" "")]))] 2162 "TARGET_32BIT && reload_completed 2163 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0]))) 2164 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))" 2165 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) 2166 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))] 2167 " 2168 { 2169 operands[3] = gen_highpart (SImode, operands[0]); 2170 operands[0] = gen_lowpart (SImode, operands[0]); 2171 operands[4] = gen_highpart (SImode, operands[1]); 2172 operands[1] = gen_lowpart (SImode, operands[1]); 2173 operands[5] = gen_highpart (SImode, operands[2]); 2174 operands[2] = gen_lowpart (SImode, operands[2]); 2175 }" 2176) 2177 2178(define_split 2179 [(set (match_operand:DI 0 "s_register_operand" "") 2180 (match_operator:DI 6 "logical_binary_operator" 2181 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" "")) 2182 (match_operand:DI 1 "s_register_operand" "")]))] 2183 "TARGET_32BIT && reload_completed" 2184 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) 2185 (set (match_dup 3) (match_op_dup:SI 6 2186 [(ashiftrt:SI (match_dup 2) (const_int 31)) 2187 (match_dup 4)]))] 2188 " 2189 { 2190 operands[3] = gen_highpart (SImode, operands[0]); 2191 operands[0] = gen_lowpart (SImode, operands[0]); 2192 operands[4] = gen_highpart (SImode, operands[1]); 2193 operands[1] = gen_lowpart (SImode, operands[1]); 2194 operands[5] = gen_highpart (SImode, operands[2]); 2195 operands[2] = gen_lowpart (SImode, operands[2]); 2196 }" 2197) 2198 2199;; The zero extend of operand 2 means we can just copy the high part of 2200;; operand1 into operand0. 2201(define_split 2202 [(set (match_operand:DI 0 "s_register_operand" "") 2203 (ior:DI 2204 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")) 2205 (match_operand:DI 1 "s_register_operand" "")))] 2206 "TARGET_32BIT && operands[0] != operands[1] && reload_completed" 2207 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2))) 2208 (set (match_dup 3) (match_dup 4))] 2209 " 2210 { 2211 operands[4] = gen_highpart (SImode, operands[1]); 2212 operands[3] = gen_highpart (SImode, operands[0]); 2213 operands[0] = gen_lowpart (SImode, operands[0]); 2214 operands[1] = gen_lowpart (SImode, operands[1]); 2215 }" 2216) 2217 2218;; The zero extend of operand 2 means we can just copy the high part of 2219;; operand1 into operand0. 2220(define_split 2221 [(set (match_operand:DI 0 "s_register_operand" "") 2222 (xor:DI 2223 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")) 2224 (match_operand:DI 1 "s_register_operand" "")))] 2225 "TARGET_32BIT && operands[0] != operands[1] && reload_completed" 2226 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2))) 2227 (set (match_dup 3) (match_dup 4))] 2228 " 2229 { 2230 operands[4] = gen_highpart (SImode, operands[1]); 2231 operands[3] = gen_highpart (SImode, operands[0]); 2232 operands[0] = gen_lowpart (SImode, operands[0]); 2233 operands[1] = gen_lowpart (SImode, operands[1]); 2234 }" 2235) 2236 2237(define_expand "anddi3" 2238 [(set (match_operand:DI 0 "s_register_operand" "") 2239 (and:DI (match_operand:DI 1 "s_register_operand" "") 2240 (match_operand:DI 2 "neon_inv_logic_op2" "")))] 2241 "TARGET_32BIT" 2242 " 2243 if (!TARGET_NEON && !TARGET_IWMMXT) 2244 { 2245 rtx low = simplify_gen_binary (AND, SImode, 2246 gen_lowpart (SImode, operands[1]), 2247 gen_lowpart (SImode, operands[2])); 2248 rtx high = simplify_gen_binary (AND, SImode, 2249 gen_highpart (SImode, operands[1]), 2250 gen_highpart_mode (SImode, DImode, 2251 operands[2])); 2252 2253 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); 2254 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); 2255 2256 DONE; 2257 } 2258 /* Otherwise expand pattern as above. */ 2259 " 2260) 2261 2262(define_insn_and_split "*anddi3_insn" 2263 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w") 2264 (and:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0") 2265 (match_operand:DI 2 "arm_anddi_operand_neon" "w ,DL,r ,r ,De,De,w ,DL")))] 2266 "TARGET_32BIT && !TARGET_IWMMXT" 2267{ 2268 switch (which_alternative) 2269 { 2270 case 0: /* fall through */ 2271 case 6: return "vand\t%P0, %P1, %P2"; 2272 case 1: /* fall through */ 2273 case 7: return neon_output_logic_immediate ("vand", &operands[2], 2274 DImode, 1, VALID_NEON_QREG_MODE (DImode)); 2275 case 2: 2276 case 3: 2277 case 4: 2278 case 5: /* fall through */ 2279 return "#"; 2280 default: gcc_unreachable (); 2281 } 2282} 2283 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed 2284 && !(IS_VFP_REGNUM (REGNO (operands[0])))" 2285 [(set (match_dup 3) (match_dup 4)) 2286 (set (match_dup 5) (match_dup 6))] 2287 " 2288 { 2289 operands[3] = gen_lowpart (SImode, operands[0]); 2290 operands[5] = gen_highpart (SImode, operands[0]); 2291 2292 operands[4] = simplify_gen_binary (AND, SImode, 2293 gen_lowpart (SImode, operands[1]), 2294 gen_lowpart (SImode, operands[2])); 2295 operands[6] = simplify_gen_binary (AND, SImode, 2296 gen_highpart (SImode, operands[1]), 2297 gen_highpart_mode (SImode, DImode, operands[2])); 2298 2299 }" 2300 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,\ 2301 multiple,multiple,neon_logic,neon_logic") 2302 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*, 2303 avoid_neon_for_64bits,avoid_neon_for_64bits") 2304 (set_attr "length" "*,*,8,8,8,8,*,*") 2305 ] 2306) 2307 2308(define_insn_and_split "*anddi_zesidi_di" 2309 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2310 (and:DI (zero_extend:DI 2311 (match_operand:SI 2 "s_register_operand" "r,r")) 2312 (match_operand:DI 1 "s_register_operand" "0,r")))] 2313 "TARGET_32BIT" 2314 "#" 2315 "TARGET_32BIT && reload_completed" 2316 ; The zero extend of operand 2 clears the high word of the output 2317 ; operand. 2318 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2))) 2319 (set (match_dup 3) (const_int 0))] 2320 " 2321 { 2322 operands[3] = gen_highpart (SImode, operands[0]); 2323 operands[0] = gen_lowpart (SImode, operands[0]); 2324 operands[1] = gen_lowpart (SImode, operands[1]); 2325 }" 2326 [(set_attr "length" "8") 2327 (set_attr "type" "multiple")] 2328) 2329 2330(define_insn "*anddi_sesdi_di" 2331 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2332 (and:DI (sign_extend:DI 2333 (match_operand:SI 2 "s_register_operand" "r,r")) 2334 (match_operand:DI 1 "s_register_operand" "0,r")))] 2335 "TARGET_32BIT" 2336 "#" 2337 [(set_attr "length" "8") 2338 (set_attr "type" "multiple")] 2339) 2340 2341(define_expand "andsi3" 2342 [(set (match_operand:SI 0 "s_register_operand" "") 2343 (and:SI (match_operand:SI 1 "s_register_operand" "") 2344 (match_operand:SI 2 "reg_or_int_operand" "")))] 2345 "TARGET_EITHER" 2346 " 2347 if (TARGET_32BIT) 2348 { 2349 if (CONST_INT_P (operands[2])) 2350 { 2351 if (INTVAL (operands[2]) == 255 && arm_arch6) 2352 { 2353 operands[1] = convert_to_mode (QImode, operands[1], 1); 2354 emit_insn (gen_thumb2_zero_extendqisi2_v6 (operands[0], 2355 operands[1])); 2356 DONE; 2357 } 2358 else if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), AND)) 2359 operands[2] = force_reg (SImode, operands[2]); 2360 else 2361 { 2362 arm_split_constant (AND, SImode, NULL_RTX, 2363 INTVAL (operands[2]), operands[0], 2364 operands[1], 2365 optimize && can_create_pseudo_p ()); 2366 2367 DONE; 2368 } 2369 } 2370 } 2371 else /* TARGET_THUMB1 */ 2372 { 2373 if (!CONST_INT_P (operands[2])) 2374 { 2375 rtx tmp = force_reg (SImode, operands[2]); 2376 if (rtx_equal_p (operands[0], operands[1])) 2377 operands[2] = tmp; 2378 else 2379 { 2380 operands[2] = operands[1]; 2381 operands[1] = tmp; 2382 } 2383 } 2384 else 2385 { 2386 int i; 2387 2388 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256) 2389 { 2390 operands[2] = force_reg (SImode, 2391 GEN_INT (~INTVAL (operands[2]))); 2392 2393 emit_insn (gen_thumb1_bicsi3 (operands[0], operands[2], operands[1])); 2394 2395 DONE; 2396 } 2397 2398 for (i = 9; i <= 31; i++) 2399 { 2400 if ((HOST_WIDE_INT_1 << i) - 1 == INTVAL (operands[2])) 2401 { 2402 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i), 2403 const0_rtx)); 2404 DONE; 2405 } 2406 else if ((HOST_WIDE_INT_1 << i) - 1 2407 == ~INTVAL (operands[2])) 2408 { 2409 rtx shift = GEN_INT (i); 2410 rtx reg = gen_reg_rtx (SImode); 2411 2412 emit_insn (gen_lshrsi3 (reg, operands[1], shift)); 2413 emit_insn (gen_ashlsi3 (operands[0], reg, shift)); 2414 2415 DONE; 2416 } 2417 } 2418 2419 operands[2] = force_reg (SImode, operands[2]); 2420 } 2421 } 2422 " 2423) 2424 2425; ??? Check split length for Thumb-2 2426(define_insn_and_split "*arm_andsi3_insn" 2427 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r") 2428 (and:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r") 2429 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))] 2430 "TARGET_32BIT" 2431 "@ 2432 and%?\\t%0, %1, %2 2433 and%?\\t%0, %1, %2 2434 bic%?\\t%0, %1, #%B2 2435 and%?\\t%0, %1, %2 2436 #" 2437 "TARGET_32BIT 2438 && CONST_INT_P (operands[2]) 2439 && !(const_ok_for_arm (INTVAL (operands[2])) 2440 || const_ok_for_arm (~INTVAL (operands[2])))" 2441 [(clobber (const_int 0))] 2442 " 2443 arm_split_constant (AND, SImode, curr_insn, 2444 INTVAL (operands[2]), operands[0], operands[1], 0); 2445 DONE; 2446 " 2447 [(set_attr "length" "4,4,4,4,16") 2448 (set_attr "predicable" "yes") 2449 (set_attr "predicable_short_it" "no,yes,no,no,no") 2450 (set_attr "type" "logic_imm,logic_imm,logic_reg,logic_reg,logic_imm")] 2451) 2452 2453(define_insn "*andsi3_compare0" 2454 [(set (reg:CC_NOOV CC_REGNUM) 2455 (compare:CC_NOOV 2456 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 2457 (match_operand:SI 2 "arm_not_operand" "I,K,r")) 2458 (const_int 0))) 2459 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 2460 (and:SI (match_dup 1) (match_dup 2)))] 2461 "TARGET_32BIT" 2462 "@ 2463 ands%?\\t%0, %1, %2 2464 bics%?\\t%0, %1, #%B2 2465 ands%?\\t%0, %1, %2" 2466 [(set_attr "conds" "set") 2467 (set_attr "type" "logics_imm,logics_imm,logics_reg")] 2468) 2469 2470(define_insn "*andsi3_compare0_scratch" 2471 [(set (reg:CC_NOOV CC_REGNUM) 2472 (compare:CC_NOOV 2473 (and:SI (match_operand:SI 0 "s_register_operand" "r,r,r") 2474 (match_operand:SI 1 "arm_not_operand" "I,K,r")) 2475 (const_int 0))) 2476 (clobber (match_scratch:SI 2 "=X,r,X"))] 2477 "TARGET_32BIT" 2478 "@ 2479 tst%?\\t%0, %1 2480 bics%?\\t%2, %0, #%B1 2481 tst%?\\t%0, %1" 2482 [(set_attr "conds" "set") 2483 (set_attr "type" "logics_imm,logics_imm,logics_reg")] 2484) 2485 2486(define_insn "*zeroextractsi_compare0_scratch" 2487 [(set (reg:CC_NOOV CC_REGNUM) 2488 (compare:CC_NOOV (zero_extract:SI 2489 (match_operand:SI 0 "s_register_operand" "r") 2490 (match_operand 1 "const_int_operand" "n") 2491 (match_operand 2 "const_int_operand" "n")) 2492 (const_int 0)))] 2493 "TARGET_32BIT 2494 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32 2495 && INTVAL (operands[1]) > 0 2496 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8 2497 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)" 2498 "* 2499 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1) 2500 << INTVAL (operands[2])); 2501 output_asm_insn (\"tst%?\\t%0, %1\", operands); 2502 return \"\"; 2503 " 2504 [(set_attr "conds" "set") 2505 (set_attr "predicable" "yes") 2506 (set_attr "type" "logics_imm")] 2507) 2508 2509(define_insn_and_split "*ne_zeroextractsi" 2510 [(set (match_operand:SI 0 "s_register_operand" "=r") 2511 (ne:SI (zero_extract:SI 2512 (match_operand:SI 1 "s_register_operand" "r") 2513 (match_operand:SI 2 "const_int_operand" "n") 2514 (match_operand:SI 3 "const_int_operand" "n")) 2515 (const_int 0))) 2516 (clobber (reg:CC CC_REGNUM))] 2517 "TARGET_32BIT 2518 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 2519 && INTVAL (operands[2]) > 0 2520 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 2521 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)" 2522 "#" 2523 "TARGET_32BIT 2524 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 2525 && INTVAL (operands[2]) > 0 2526 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 2527 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)" 2528 [(parallel [(set (reg:CC_NOOV CC_REGNUM) 2529 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2)) 2530 (const_int 0))) 2531 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))]) 2532 (set (match_dup 0) 2533 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) 2534 (match_dup 0) (const_int 1)))] 2535 " 2536 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1) 2537 << INTVAL (operands[3])); 2538 " 2539 [(set_attr "conds" "clob") 2540 (set (attr "length") 2541 (if_then_else (eq_attr "is_thumb" "yes") 2542 (const_int 12) 2543 (const_int 8))) 2544 (set_attr "type" "multiple")] 2545) 2546 2547(define_insn_and_split "*ne_zeroextractsi_shifted" 2548 [(set (match_operand:SI 0 "s_register_operand" "=r") 2549 (ne:SI (zero_extract:SI 2550 (match_operand:SI 1 "s_register_operand" "r") 2551 (match_operand:SI 2 "const_int_operand" "n") 2552 (const_int 0)) 2553 (const_int 0))) 2554 (clobber (reg:CC CC_REGNUM))] 2555 "TARGET_ARM" 2556 "#" 2557 "TARGET_ARM" 2558 [(parallel [(set (reg:CC_NOOV CC_REGNUM) 2559 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2)) 2560 (const_int 0))) 2561 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))]) 2562 (set (match_dup 0) 2563 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) 2564 (match_dup 0) (const_int 1)))] 2565 " 2566 operands[2] = GEN_INT (32 - INTVAL (operands[2])); 2567 " 2568 [(set_attr "conds" "clob") 2569 (set_attr "length" "8") 2570 (set_attr "type" "multiple")] 2571) 2572 2573(define_insn_and_split "*ite_ne_zeroextractsi" 2574 [(set (match_operand:SI 0 "s_register_operand" "=r") 2575 (if_then_else:SI (ne (zero_extract:SI 2576 (match_operand:SI 1 "s_register_operand" "r") 2577 (match_operand:SI 2 "const_int_operand" "n") 2578 (match_operand:SI 3 "const_int_operand" "n")) 2579 (const_int 0)) 2580 (match_operand:SI 4 "arm_not_operand" "rIK") 2581 (const_int 0))) 2582 (clobber (reg:CC CC_REGNUM))] 2583 "TARGET_ARM 2584 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 2585 && INTVAL (operands[2]) > 0 2586 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 2587 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32) 2588 && !reg_overlap_mentioned_p (operands[0], operands[4])" 2589 "#" 2590 "TARGET_ARM 2591 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 2592 && INTVAL (operands[2]) > 0 2593 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 2594 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32) 2595 && !reg_overlap_mentioned_p (operands[0], operands[4])" 2596 [(parallel [(set (reg:CC_NOOV CC_REGNUM) 2597 (compare:CC_NOOV (and:SI (match_dup 1) (match_dup 2)) 2598 (const_int 0))) 2599 (set (match_dup 0) (and:SI (match_dup 1) (match_dup 2)))]) 2600 (set (match_dup 0) 2601 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) 2602 (match_dup 0) (match_dup 4)))] 2603 " 2604 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1) 2605 << INTVAL (operands[3])); 2606 " 2607 [(set_attr "conds" "clob") 2608 (set_attr "length" "8") 2609 (set_attr "type" "multiple")] 2610) 2611 2612(define_insn_and_split "*ite_ne_zeroextractsi_shifted" 2613 [(set (match_operand:SI 0 "s_register_operand" "=r") 2614 (if_then_else:SI (ne (zero_extract:SI 2615 (match_operand:SI 1 "s_register_operand" "r") 2616 (match_operand:SI 2 "const_int_operand" "n") 2617 (const_int 0)) 2618 (const_int 0)) 2619 (match_operand:SI 3 "arm_not_operand" "rIK") 2620 (const_int 0))) 2621 (clobber (reg:CC CC_REGNUM))] 2622 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])" 2623 "#" 2624 "TARGET_ARM && !reg_overlap_mentioned_p (operands[0], operands[3])" 2625 [(parallel [(set (reg:CC_NOOV CC_REGNUM) 2626 (compare:CC_NOOV (ashift:SI (match_dup 1) (match_dup 2)) 2627 (const_int 0))) 2628 (set (match_dup 0) (ashift:SI (match_dup 1) (match_dup 2)))]) 2629 (set (match_dup 0) 2630 (if_then_else:SI (eq (reg:CC_NOOV CC_REGNUM) (const_int 0)) 2631 (match_dup 0) (match_dup 3)))] 2632 " 2633 operands[2] = GEN_INT (32 - INTVAL (operands[2])); 2634 " 2635 [(set_attr "conds" "clob") 2636 (set_attr "length" "8") 2637 (set_attr "type" "multiple")] 2638) 2639 2640;; ??? Use Thumb-2 has bitfield insert/extract instructions. 2641(define_split 2642 [(set (match_operand:SI 0 "s_register_operand" "") 2643 (match_operator:SI 1 "shiftable_operator" 2644 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "") 2645 (match_operand:SI 3 "const_int_operand" "") 2646 (match_operand:SI 4 "const_int_operand" "")) 2647 (match_operand:SI 5 "s_register_operand" "")])) 2648 (clobber (match_operand:SI 6 "s_register_operand" ""))] 2649 "TARGET_ARM" 2650 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3))) 2651 (set (match_dup 0) 2652 (match_op_dup 1 2653 [(lshiftrt:SI (match_dup 6) (match_dup 4)) 2654 (match_dup 5)]))] 2655 "{ 2656 HOST_WIDE_INT temp = INTVAL (operands[3]); 2657 2658 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4])); 2659 operands[4] = GEN_INT (32 - temp); 2660 }" 2661) 2662 2663(define_split 2664 [(set (match_operand:SI 0 "s_register_operand" "") 2665 (match_operator:SI 1 "shiftable_operator" 2666 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "") 2667 (match_operand:SI 3 "const_int_operand" "") 2668 (match_operand:SI 4 "const_int_operand" "")) 2669 (match_operand:SI 5 "s_register_operand" "")])) 2670 (clobber (match_operand:SI 6 "s_register_operand" ""))] 2671 "TARGET_ARM" 2672 [(set (match_dup 6) (ashift:SI (match_dup 2) (match_dup 3))) 2673 (set (match_dup 0) 2674 (match_op_dup 1 2675 [(ashiftrt:SI (match_dup 6) (match_dup 4)) 2676 (match_dup 5)]))] 2677 "{ 2678 HOST_WIDE_INT temp = INTVAL (operands[3]); 2679 2680 operands[3] = GEN_INT (32 - temp - INTVAL (operands[4])); 2681 operands[4] = GEN_INT (32 - temp); 2682 }" 2683) 2684 2685;;; ??? This pattern is bogus. If operand3 has bits outside the range 2686;;; represented by the bitfield, then this will produce incorrect results. 2687;;; Somewhere, the value needs to be truncated. On targets like the m68k, 2688;;; which have a real bit-field insert instruction, the truncation happens 2689;;; in the bit-field insert instruction itself. Since arm does not have a 2690;;; bit-field insert instruction, we would have to emit code here to truncate 2691;;; the value before we insert. This loses some of the advantage of having 2692;;; this insv pattern, so this pattern needs to be reevalutated. 2693 2694(define_expand "insv" 2695 [(set (zero_extract (match_operand 0 "nonimmediate_operand" "") 2696 (match_operand 1 "general_operand" "") 2697 (match_operand 2 "general_operand" "")) 2698 (match_operand 3 "reg_or_int_operand" ""))] 2699 "TARGET_ARM || arm_arch_thumb2" 2700 " 2701 { 2702 int start_bit = INTVAL (operands[2]); 2703 int width = INTVAL (operands[1]); 2704 HOST_WIDE_INT mask = (HOST_WIDE_INT_1 << width) - 1; 2705 rtx target, subtarget; 2706 2707 if (arm_arch_thumb2) 2708 { 2709 if (unaligned_access && MEM_P (operands[0]) 2710 && s_register_operand (operands[3], GET_MODE (operands[3])) 2711 && (width == 16 || width == 32) && (start_bit % BITS_PER_UNIT) == 0) 2712 { 2713 rtx base_addr; 2714 2715 if (BYTES_BIG_ENDIAN) 2716 start_bit = GET_MODE_BITSIZE (GET_MODE (operands[3])) - width 2717 - start_bit; 2718 2719 if (width == 32) 2720 { 2721 base_addr = adjust_address (operands[0], SImode, 2722 start_bit / BITS_PER_UNIT); 2723 emit_insn (gen_unaligned_storesi (base_addr, operands[3])); 2724 } 2725 else 2726 { 2727 rtx tmp = gen_reg_rtx (HImode); 2728 2729 base_addr = adjust_address (operands[0], HImode, 2730 start_bit / BITS_PER_UNIT); 2731 emit_move_insn (tmp, gen_lowpart (HImode, operands[3])); 2732 emit_insn (gen_unaligned_storehi (base_addr, tmp)); 2733 } 2734 DONE; 2735 } 2736 else if (s_register_operand (operands[0], GET_MODE (operands[0]))) 2737 { 2738 bool use_bfi = TRUE; 2739 2740 if (CONST_INT_P (operands[3])) 2741 { 2742 HOST_WIDE_INT val = INTVAL (operands[3]) & mask; 2743 2744 if (val == 0) 2745 { 2746 emit_insn (gen_insv_zero (operands[0], operands[1], 2747 operands[2])); 2748 DONE; 2749 } 2750 2751 /* See if the set can be done with a single orr instruction. */ 2752 if (val == mask && const_ok_for_arm (val << start_bit)) 2753 use_bfi = FALSE; 2754 } 2755 2756 if (use_bfi) 2757 { 2758 if (!REG_P (operands[3])) 2759 operands[3] = force_reg (SImode, operands[3]); 2760 2761 emit_insn (gen_insv_t2 (operands[0], operands[1], operands[2], 2762 operands[3])); 2763 DONE; 2764 } 2765 } 2766 else 2767 FAIL; 2768 } 2769 2770 if (!s_register_operand (operands[0], GET_MODE (operands[0]))) 2771 FAIL; 2772 2773 target = copy_rtx (operands[0]); 2774 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 2775 subreg as the final target. */ 2776 if (GET_CODE (target) == SUBREG) 2777 { 2778 subtarget = gen_reg_rtx (SImode); 2779 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target))) 2780 < GET_MODE_SIZE (SImode)) 2781 target = SUBREG_REG (target); 2782 } 2783 else 2784 subtarget = target; 2785 2786 if (CONST_INT_P (operands[3])) 2787 { 2788 /* Since we are inserting a known constant, we may be able to 2789 reduce the number of bits that we have to clear so that 2790 the mask becomes simple. */ 2791 /* ??? This code does not check to see if the new mask is actually 2792 simpler. It may not be. */ 2793 rtx op1 = gen_reg_rtx (SImode); 2794 /* ??? Truncate operand3 to fit in the bitfield. See comment before 2795 start of this pattern. */ 2796 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]); 2797 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit); 2798 2799 emit_insn (gen_andsi3 (op1, operands[0], 2800 gen_int_mode (~mask2, SImode))); 2801 emit_insn (gen_iorsi3 (subtarget, op1, 2802 gen_int_mode (op3_value << start_bit, SImode))); 2803 } 2804 else if (start_bit == 0 2805 && !(const_ok_for_arm (mask) 2806 || const_ok_for_arm (~mask))) 2807 { 2808 /* A Trick, since we are setting the bottom bits in the word, 2809 we can shift operand[3] up, operand[0] down, OR them together 2810 and rotate the result back again. This takes 3 insns, and 2811 the third might be mergeable into another op. */ 2812 /* The shift up copes with the possibility that operand[3] is 2813 wider than the bitfield. */ 2814 rtx op0 = gen_reg_rtx (SImode); 2815 rtx op1 = gen_reg_rtx (SImode); 2816 2817 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width))); 2818 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1])); 2819 emit_insn (gen_iorsi3 (op1, op1, op0)); 2820 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1])); 2821 } 2822 else if ((width + start_bit == 32) 2823 && !(const_ok_for_arm (mask) 2824 || const_ok_for_arm (~mask))) 2825 { 2826 /* Similar trick, but slightly less efficient. */ 2827 2828 rtx op0 = gen_reg_rtx (SImode); 2829 rtx op1 = gen_reg_rtx (SImode); 2830 2831 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width))); 2832 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1])); 2833 emit_insn (gen_lshrsi3 (op1, op1, operands[1])); 2834 emit_insn (gen_iorsi3 (subtarget, op1, op0)); 2835 } 2836 else 2837 { 2838 rtx op0 = gen_int_mode (mask, SImode); 2839 rtx op1 = gen_reg_rtx (SImode); 2840 rtx op2 = gen_reg_rtx (SImode); 2841 2842 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask))) 2843 { 2844 rtx tmp = gen_reg_rtx (SImode); 2845 2846 emit_insn (gen_movsi (tmp, op0)); 2847 op0 = tmp; 2848 } 2849 2850 /* Mask out any bits in operand[3] that are not needed. */ 2851 emit_insn (gen_andsi3 (op1, operands[3], op0)); 2852 2853 if (CONST_INT_P (op0) 2854 && (const_ok_for_arm (mask << start_bit) 2855 || const_ok_for_arm (~(mask << start_bit)))) 2856 { 2857 op0 = gen_int_mode (~(mask << start_bit), SImode); 2858 emit_insn (gen_andsi3 (op2, operands[0], op0)); 2859 } 2860 else 2861 { 2862 if (CONST_INT_P (op0)) 2863 { 2864 rtx tmp = gen_reg_rtx (SImode); 2865 2866 emit_insn (gen_movsi (tmp, op0)); 2867 op0 = tmp; 2868 } 2869 2870 if (start_bit != 0) 2871 emit_insn (gen_ashlsi3 (op0, op0, operands[2])); 2872 2873 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0)); 2874 } 2875 2876 if (start_bit != 0) 2877 emit_insn (gen_ashlsi3 (op1, op1, operands[2])); 2878 2879 emit_insn (gen_iorsi3 (subtarget, op1, op2)); 2880 } 2881 2882 if (subtarget != target) 2883 { 2884 /* If TARGET is still a SUBREG, then it must be wider than a word, 2885 so we must be careful only to set the subword we were asked to. */ 2886 if (GET_CODE (target) == SUBREG) 2887 emit_move_insn (target, subtarget); 2888 else 2889 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget)); 2890 } 2891 2892 DONE; 2893 }" 2894) 2895 2896(define_insn "insv_zero" 2897 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") 2898 (match_operand:SI 1 "const_int_M_operand" "M") 2899 (match_operand:SI 2 "const_int_M_operand" "M")) 2900 (const_int 0))] 2901 "arm_arch_thumb2" 2902 "bfc%?\t%0, %2, %1" 2903 [(set_attr "length" "4") 2904 (set_attr "predicable" "yes") 2905 (set_attr "type" "bfm")] 2906) 2907 2908(define_insn "insv_t2" 2909 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r") 2910 (match_operand:SI 1 "const_int_M_operand" "M") 2911 (match_operand:SI 2 "const_int_M_operand" "M")) 2912 (match_operand:SI 3 "s_register_operand" "r"))] 2913 "arm_arch_thumb2" 2914 "bfi%?\t%0, %3, %2, %1" 2915 [(set_attr "length" "4") 2916 (set_attr "predicable" "yes") 2917 (set_attr "type" "bfm")] 2918) 2919 2920; constants for op 2 will never be given to these patterns. 2921(define_insn_and_split "*anddi_notdi_di" 2922 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2923 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "0,r")) 2924 (match_operand:DI 2 "s_register_operand" "r,0")))] 2925 "TARGET_32BIT" 2926 "#" 2927 "TARGET_32BIT && reload_completed 2928 && ! (TARGET_NEON && IS_VFP_REGNUM (REGNO (operands[0]))) 2929 && ! IS_IWMMXT_REGNUM (REGNO (operands[0]))" 2930 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2))) 2931 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))] 2932 " 2933 { 2934 operands[3] = gen_highpart (SImode, operands[0]); 2935 operands[0] = gen_lowpart (SImode, operands[0]); 2936 operands[4] = gen_highpart (SImode, operands[1]); 2937 operands[1] = gen_lowpart (SImode, operands[1]); 2938 operands[5] = gen_highpart (SImode, operands[2]); 2939 operands[2] = gen_lowpart (SImode, operands[2]); 2940 }" 2941 [(set_attr "length" "8") 2942 (set_attr "predicable" "yes") 2943 (set_attr "type" "multiple")] 2944) 2945 2946(define_insn_and_split "*anddi_notzesidi_di" 2947 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2948 (and:DI (not:DI (zero_extend:DI 2949 (match_operand:SI 2 "s_register_operand" "r,r"))) 2950 (match_operand:DI 1 "s_register_operand" "0,?r")))] 2951 "TARGET_32BIT" 2952 "@ 2953 bic%?\\t%Q0, %Q1, %2 2954 #" 2955 ; (not (zero_extend ...)) allows us to just copy the high word from 2956 ; operand1 to operand0. 2957 "TARGET_32BIT 2958 && reload_completed 2959 && operands[0] != operands[1]" 2960 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1))) 2961 (set (match_dup 3) (match_dup 4))] 2962 " 2963 { 2964 operands[3] = gen_highpart (SImode, operands[0]); 2965 operands[0] = gen_lowpart (SImode, operands[0]); 2966 operands[4] = gen_highpart (SImode, operands[1]); 2967 operands[1] = gen_lowpart (SImode, operands[1]); 2968 }" 2969 [(set_attr "length" "4,8") 2970 (set_attr "predicable" "yes") 2971 (set_attr "type" "multiple")] 2972) 2973 2974(define_insn_and_split "*anddi_notdi_zesidi" 2975 [(set (match_operand:DI 0 "s_register_operand" "=r") 2976 (and:DI (not:DI (match_operand:DI 2 "s_register_operand" "r")) 2977 (zero_extend:DI 2978 (match_operand:SI 1 "s_register_operand" "r"))))] 2979 "TARGET_32BIT" 2980 "#" 2981 "TARGET_32BIT && reload_completed" 2982 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1))) 2983 (set (match_dup 3) (const_int 0))] 2984 " 2985 { 2986 operands[3] = gen_highpart (SImode, operands[0]); 2987 operands[0] = gen_lowpart (SImode, operands[0]); 2988 operands[2] = gen_lowpart (SImode, operands[2]); 2989 }" 2990 [(set_attr "length" "8") 2991 (set_attr "predicable" "yes") 2992 (set_attr "type" "multiple")] 2993) 2994 2995(define_insn_and_split "*anddi_notsesidi_di" 2996 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2997 (and:DI (not:DI (sign_extend:DI 2998 (match_operand:SI 2 "s_register_operand" "r,r"))) 2999 (match_operand:DI 1 "s_register_operand" "0,r")))] 3000 "TARGET_32BIT" 3001 "#" 3002 "TARGET_32BIT && reload_completed" 3003 [(set (match_dup 0) (and:SI (not:SI (match_dup 2)) (match_dup 1))) 3004 (set (match_dup 3) (and:SI (not:SI 3005 (ashiftrt:SI (match_dup 2) (const_int 31))) 3006 (match_dup 4)))] 3007 " 3008 { 3009 operands[3] = gen_highpart (SImode, operands[0]); 3010 operands[0] = gen_lowpart (SImode, operands[0]); 3011 operands[4] = gen_highpart (SImode, operands[1]); 3012 operands[1] = gen_lowpart (SImode, operands[1]); 3013 }" 3014 [(set_attr "length" "8") 3015 (set_attr "predicable" "yes") 3016 (set_attr "type" "multiple")] 3017) 3018 3019(define_insn "andsi_notsi_si" 3020 [(set (match_operand:SI 0 "s_register_operand" "=r") 3021 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) 3022 (match_operand:SI 1 "s_register_operand" "r")))] 3023 "TARGET_32BIT" 3024 "bic%?\\t%0, %1, %2" 3025 [(set_attr "predicable" "yes") 3026 (set_attr "type" "logic_reg")] 3027) 3028 3029(define_insn "andsi_not_shiftsi_si" 3030 [(set (match_operand:SI 0 "s_register_operand" "=r") 3031 (and:SI (not:SI (match_operator:SI 4 "shift_operator" 3032 [(match_operand:SI 2 "s_register_operand" "r") 3033 (match_operand:SI 3 "arm_rhs_operand" "rM")])) 3034 (match_operand:SI 1 "s_register_operand" "r")))] 3035 "TARGET_ARM" 3036 "bic%?\\t%0, %1, %2%S4" 3037 [(set_attr "predicable" "yes") 3038 (set_attr "shift" "2") 3039 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") 3040 (const_string "logic_shift_imm") 3041 (const_string "logic_shift_reg")))] 3042) 3043 3044;; Shifted bics pattern used to set up CC status register and not reusing 3045;; bics output. Pattern restricts Thumb2 shift operand as bics for Thumb2 3046;; does not support shift by register. 3047(define_insn "andsi_not_shiftsi_si_scc_no_reuse" 3048 [(set (reg:CC_NOOV CC_REGNUM) 3049 (compare:CC_NOOV 3050 (and:SI (not:SI (match_operator:SI 0 "shift_operator" 3051 [(match_operand:SI 1 "s_register_operand" "r") 3052 (match_operand:SI 2 "arm_rhs_operand" "rM")])) 3053 (match_operand:SI 3 "s_register_operand" "r")) 3054 (const_int 0))) 3055 (clobber (match_scratch:SI 4 "=r"))] 3056 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))" 3057 "bics%?\\t%4, %3, %1%S0" 3058 [(set_attr "predicable" "yes") 3059 (set_attr "conds" "set") 3060 (set_attr "shift" "1") 3061 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") 3062 (const_string "logic_shift_imm") 3063 (const_string "logic_shift_reg")))] 3064) 3065 3066;; Same as andsi_not_shiftsi_si_scc_no_reuse, but the bics result is also 3067;; getting reused later. 3068(define_insn "andsi_not_shiftsi_si_scc" 3069 [(parallel [(set (reg:CC_NOOV CC_REGNUM) 3070 (compare:CC_NOOV 3071 (and:SI (not:SI (match_operator:SI 0 "shift_operator" 3072 [(match_operand:SI 1 "s_register_operand" "r") 3073 (match_operand:SI 2 "arm_rhs_operand" "rM")])) 3074 (match_operand:SI 3 "s_register_operand" "r")) 3075 (const_int 0))) 3076 (set (match_operand:SI 4 "s_register_operand" "=r") 3077 (and:SI (not:SI (match_op_dup 0 3078 [(match_dup 1) 3079 (match_dup 2)])) 3080 (match_dup 3)))])] 3081 "TARGET_ARM || (TARGET_THUMB2 && CONST_INT_P (operands[2]))" 3082 "bics%?\\t%4, %3, %1%S0" 3083 [(set_attr "predicable" "yes") 3084 (set_attr "conds" "set") 3085 (set_attr "shift" "1") 3086 (set (attr "type") (if_then_else (match_operand 2 "const_int_operand" "") 3087 (const_string "logic_shift_imm") 3088 (const_string "logic_shift_reg")))] 3089) 3090 3091(define_insn "*andsi_notsi_si_compare0" 3092 [(set (reg:CC_NOOV CC_REGNUM) 3093 (compare:CC_NOOV 3094 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) 3095 (match_operand:SI 1 "s_register_operand" "r")) 3096 (const_int 0))) 3097 (set (match_operand:SI 0 "s_register_operand" "=r") 3098 (and:SI (not:SI (match_dup 2)) (match_dup 1)))] 3099 "TARGET_32BIT" 3100 "bics\\t%0, %1, %2" 3101 [(set_attr "conds" "set") 3102 (set_attr "type" "logics_shift_reg")] 3103) 3104 3105(define_insn "*andsi_notsi_si_compare0_scratch" 3106 [(set (reg:CC_NOOV CC_REGNUM) 3107 (compare:CC_NOOV 3108 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) 3109 (match_operand:SI 1 "s_register_operand" "r")) 3110 (const_int 0))) 3111 (clobber (match_scratch:SI 0 "=r"))] 3112 "TARGET_32BIT" 3113 "bics\\t%0, %1, %2" 3114 [(set_attr "conds" "set") 3115 (set_attr "type" "logics_shift_reg")] 3116) 3117 3118(define_expand "iordi3" 3119 [(set (match_operand:DI 0 "s_register_operand" "") 3120 (ior:DI (match_operand:DI 1 "s_register_operand" "") 3121 (match_operand:DI 2 "neon_logic_op2" "")))] 3122 "TARGET_32BIT" 3123 " 3124 if (!TARGET_NEON && !TARGET_IWMMXT) 3125 { 3126 rtx low = simplify_gen_binary (IOR, SImode, 3127 gen_lowpart (SImode, operands[1]), 3128 gen_lowpart (SImode, operands[2])); 3129 rtx high = simplify_gen_binary (IOR, SImode, 3130 gen_highpart (SImode, operands[1]), 3131 gen_highpart_mode (SImode, DImode, 3132 operands[2])); 3133 3134 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); 3135 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); 3136 3137 DONE; 3138 } 3139 /* Otherwise expand pattern as above. */ 3140 " 3141) 3142 3143(define_insn_and_split "*iordi3_insn" 3144 [(set (match_operand:DI 0 "s_register_operand" "=w,w ,&r,&r,&r,&r,?w,?w") 3145 (ior:DI (match_operand:DI 1 "s_register_operand" "%w,0 ,0 ,r ,0 ,r ,w ,0") 3146 (match_operand:DI 2 "arm_iordi_operand_neon" "w ,Dl,r ,r ,Df,Df,w ,Dl")))] 3147 "TARGET_32BIT && !TARGET_IWMMXT" 3148 { 3149 switch (which_alternative) 3150 { 3151 case 0: /* fall through */ 3152 case 6: return "vorr\t%P0, %P1, %P2"; 3153 case 1: /* fall through */ 3154 case 7: return neon_output_logic_immediate ("vorr", &operands[2], 3155 DImode, 0, VALID_NEON_QREG_MODE (DImode)); 3156 case 2: 3157 case 3: 3158 case 4: 3159 case 5: 3160 return "#"; 3161 default: gcc_unreachable (); 3162 } 3163 } 3164 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed 3165 && !(IS_VFP_REGNUM (REGNO (operands[0])))" 3166 [(set (match_dup 3) (match_dup 4)) 3167 (set (match_dup 5) (match_dup 6))] 3168 " 3169 { 3170 operands[3] = gen_lowpart (SImode, operands[0]); 3171 operands[5] = gen_highpart (SImode, operands[0]); 3172 3173 operands[4] = simplify_gen_binary (IOR, SImode, 3174 gen_lowpart (SImode, operands[1]), 3175 gen_lowpart (SImode, operands[2])); 3176 operands[6] = simplify_gen_binary (IOR, SImode, 3177 gen_highpart (SImode, operands[1]), 3178 gen_highpart_mode (SImode, DImode, operands[2])); 3179 3180 }" 3181 [(set_attr "type" "neon_logic,neon_logic,multiple,multiple,multiple,\ 3182 multiple,neon_logic,neon_logic") 3183 (set_attr "length" "*,*,8,8,8,8,*,*") 3184 (set_attr "arch" "neon_for_64bits,neon_for_64bits,*,*,*,*,avoid_neon_for_64bits,avoid_neon_for_64bits")] 3185) 3186 3187(define_insn "*iordi_zesidi_di" 3188 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 3189 (ior:DI (zero_extend:DI 3190 (match_operand:SI 2 "s_register_operand" "r,r")) 3191 (match_operand:DI 1 "s_register_operand" "0,?r")))] 3192 "TARGET_32BIT" 3193 "@ 3194 orr%?\\t%Q0, %Q1, %2 3195 #" 3196 [(set_attr "length" "4,8") 3197 (set_attr "predicable" "yes") 3198 (set_attr "type" "logic_reg,multiple")] 3199) 3200 3201(define_insn "*iordi_sesidi_di" 3202 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 3203 (ior:DI (sign_extend:DI 3204 (match_operand:SI 2 "s_register_operand" "r,r")) 3205 (match_operand:DI 1 "s_register_operand" "0,r")))] 3206 "TARGET_32BIT" 3207 "#" 3208 [(set_attr "length" "8") 3209 (set_attr "predicable" "yes") 3210 (set_attr "type" "multiple")] 3211) 3212 3213(define_expand "iorsi3" 3214 [(set (match_operand:SI 0 "s_register_operand" "") 3215 (ior:SI (match_operand:SI 1 "s_register_operand" "") 3216 (match_operand:SI 2 "reg_or_int_operand" "")))] 3217 "TARGET_EITHER" 3218 " 3219 if (CONST_INT_P (operands[2])) 3220 { 3221 if (TARGET_32BIT) 3222 { 3223 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), IOR)) 3224 operands[2] = force_reg (SImode, operands[2]); 3225 else 3226 { 3227 arm_split_constant (IOR, SImode, NULL_RTX, 3228 INTVAL (operands[2]), operands[0], 3229 operands[1], 3230 optimize && can_create_pseudo_p ()); 3231 DONE; 3232 } 3233 } 3234 else /* TARGET_THUMB1 */ 3235 { 3236 rtx tmp = force_reg (SImode, operands[2]); 3237 if (rtx_equal_p (operands[0], operands[1])) 3238 operands[2] = tmp; 3239 else 3240 { 3241 operands[2] = operands[1]; 3242 operands[1] = tmp; 3243 } 3244 } 3245 } 3246 " 3247) 3248 3249(define_insn_and_split "*iorsi3_insn" 3250 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r,r") 3251 (ior:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r,r") 3252 (match_operand:SI 2 "reg_or_int_operand" "I,l,K,r,?n")))] 3253 "TARGET_32BIT" 3254 "@ 3255 orr%?\\t%0, %1, %2 3256 orr%?\\t%0, %1, %2 3257 orn%?\\t%0, %1, #%B2 3258 orr%?\\t%0, %1, %2 3259 #" 3260 "TARGET_32BIT 3261 && CONST_INT_P (operands[2]) 3262 && !(const_ok_for_arm (INTVAL (operands[2])) 3263 || (TARGET_THUMB2 && const_ok_for_arm (~INTVAL (operands[2]))))" 3264 [(clobber (const_int 0))] 3265{ 3266 arm_split_constant (IOR, SImode, curr_insn, 3267 INTVAL (operands[2]), operands[0], operands[1], 0); 3268 DONE; 3269} 3270 [(set_attr "length" "4,4,4,4,16") 3271 (set_attr "arch" "32,t2,t2,32,32") 3272 (set_attr "predicable" "yes") 3273 (set_attr "predicable_short_it" "no,yes,no,no,no") 3274 (set_attr "type" "logic_imm,logic_reg,logic_imm,logic_reg,logic_reg")] 3275) 3276 3277(define_peephole2 3278 [(match_scratch:SI 3 "r") 3279 (set (match_operand:SI 0 "arm_general_register_operand" "") 3280 (ior:SI (match_operand:SI 1 "arm_general_register_operand" "") 3281 (match_operand:SI 2 "const_int_operand" "")))] 3282 "TARGET_ARM 3283 && !const_ok_for_arm (INTVAL (operands[2])) 3284 && const_ok_for_arm (~INTVAL (operands[2]))" 3285 [(set (match_dup 3) (match_dup 2)) 3286 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))] 3287 "" 3288) 3289 3290(define_insn "*iorsi3_compare0" 3291 [(set (reg:CC_NOOV CC_REGNUM) 3292 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r") 3293 (match_operand:SI 2 "arm_rhs_operand" "I,r")) 3294 (const_int 0))) 3295 (set (match_operand:SI 0 "s_register_operand" "=r,r") 3296 (ior:SI (match_dup 1) (match_dup 2)))] 3297 "TARGET_32BIT" 3298 "orrs%?\\t%0, %1, %2" 3299 [(set_attr "conds" "set") 3300 (set_attr "type" "logics_imm,logics_reg")] 3301) 3302 3303(define_insn "*iorsi3_compare0_scratch" 3304 [(set (reg:CC_NOOV CC_REGNUM) 3305 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r,r") 3306 (match_operand:SI 2 "arm_rhs_operand" "I,r")) 3307 (const_int 0))) 3308 (clobber (match_scratch:SI 0 "=r,r"))] 3309 "TARGET_32BIT" 3310 "orrs%?\\t%0, %1, %2" 3311 [(set_attr "conds" "set") 3312 (set_attr "type" "logics_imm,logics_reg")] 3313) 3314 3315(define_expand "xordi3" 3316 [(set (match_operand:DI 0 "s_register_operand" "") 3317 (xor:DI (match_operand:DI 1 "s_register_operand" "") 3318 (match_operand:DI 2 "arm_xordi_operand" "")))] 3319 "TARGET_32BIT" 3320 { 3321 /* The iWMMXt pattern for xordi3 accepts only register operands but we want 3322 to reuse this expander for all TARGET_32BIT targets so just force the 3323 constants into a register. Unlike for the anddi3 and iordi3 there are 3324 no NEON instructions that take an immediate. */ 3325 if (TARGET_IWMMXT && !REG_P (operands[2])) 3326 operands[2] = force_reg (DImode, operands[2]); 3327 if (!TARGET_NEON && !TARGET_IWMMXT) 3328 { 3329 rtx low = simplify_gen_binary (XOR, SImode, 3330 gen_lowpart (SImode, operands[1]), 3331 gen_lowpart (SImode, operands[2])); 3332 rtx high = simplify_gen_binary (XOR, SImode, 3333 gen_highpart (SImode, operands[1]), 3334 gen_highpart_mode (SImode, DImode, 3335 operands[2])); 3336 3337 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); 3338 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); 3339 3340 DONE; 3341 } 3342 /* Otherwise expand pattern as above. */ 3343 } 3344) 3345 3346(define_insn_and_split "*xordi3_insn" 3347 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,&r,&r,?w") 3348 (xor:DI (match_operand:DI 1 "s_register_operand" "%w ,0,r ,0 ,r ,w") 3349 (match_operand:DI 2 "arm_xordi_operand" "w ,r ,r ,Dg,Dg,w")))] 3350 "TARGET_32BIT && !TARGET_IWMMXT" 3351{ 3352 switch (which_alternative) 3353 { 3354 case 1: 3355 case 2: 3356 case 3: 3357 case 4: /* fall through */ 3358 return "#"; 3359 case 0: /* fall through */ 3360 case 5: return "veor\t%P0, %P1, %P2"; 3361 default: gcc_unreachable (); 3362 } 3363} 3364 "TARGET_32BIT && !TARGET_IWMMXT && reload_completed 3365 && !(IS_VFP_REGNUM (REGNO (operands[0])))" 3366 [(set (match_dup 3) (match_dup 4)) 3367 (set (match_dup 5) (match_dup 6))] 3368 " 3369 { 3370 operands[3] = gen_lowpart (SImode, operands[0]); 3371 operands[5] = gen_highpart (SImode, operands[0]); 3372 3373 operands[4] = simplify_gen_binary (XOR, SImode, 3374 gen_lowpart (SImode, operands[1]), 3375 gen_lowpart (SImode, operands[2])); 3376 operands[6] = simplify_gen_binary (XOR, SImode, 3377 gen_highpart (SImode, operands[1]), 3378 gen_highpart_mode (SImode, DImode, operands[2])); 3379 3380 }" 3381 [(set_attr "length" "*,8,8,8,8,*") 3382 (set_attr "type" "neon_logic,multiple,multiple,multiple,multiple,neon_logic") 3383 (set_attr "arch" "neon_for_64bits,*,*,*,*,avoid_neon_for_64bits")] 3384) 3385 3386(define_insn "*xordi_zesidi_di" 3387 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 3388 (xor:DI (zero_extend:DI 3389 (match_operand:SI 2 "s_register_operand" "r,r")) 3390 (match_operand:DI 1 "s_register_operand" "0,?r")))] 3391 "TARGET_32BIT" 3392 "@ 3393 eor%?\\t%Q0, %Q1, %2 3394 #" 3395 [(set_attr "length" "4,8") 3396 (set_attr "predicable" "yes") 3397 (set_attr "type" "logic_reg")] 3398) 3399 3400(define_insn "*xordi_sesidi_di" 3401 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 3402 (xor:DI (sign_extend:DI 3403 (match_operand:SI 2 "s_register_operand" "r,r")) 3404 (match_operand:DI 1 "s_register_operand" "0,r")))] 3405 "TARGET_32BIT" 3406 "#" 3407 [(set_attr "length" "8") 3408 (set_attr "predicable" "yes") 3409 (set_attr "type" "multiple")] 3410) 3411 3412(define_expand "xorsi3" 3413 [(set (match_operand:SI 0 "s_register_operand" "") 3414 (xor:SI (match_operand:SI 1 "s_register_operand" "") 3415 (match_operand:SI 2 "reg_or_int_operand" "")))] 3416 "TARGET_EITHER" 3417 "if (CONST_INT_P (operands[2])) 3418 { 3419 if (TARGET_32BIT) 3420 { 3421 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[2]), XOR)) 3422 operands[2] = force_reg (SImode, operands[2]); 3423 else 3424 { 3425 arm_split_constant (XOR, SImode, NULL_RTX, 3426 INTVAL (operands[2]), operands[0], 3427 operands[1], 3428 optimize && can_create_pseudo_p ()); 3429 DONE; 3430 } 3431 } 3432 else /* TARGET_THUMB1 */ 3433 { 3434 rtx tmp = force_reg (SImode, operands[2]); 3435 if (rtx_equal_p (operands[0], operands[1])) 3436 operands[2] = tmp; 3437 else 3438 { 3439 operands[2] = operands[1]; 3440 operands[1] = tmp; 3441 } 3442 } 3443 }" 3444) 3445 3446(define_insn_and_split "*arm_xorsi3" 3447 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r,r") 3448 (xor:SI (match_operand:SI 1 "s_register_operand" "%r,0,r,r") 3449 (match_operand:SI 2 "reg_or_int_operand" "I,l,r,?n")))] 3450 "TARGET_32BIT" 3451 "@ 3452 eor%?\\t%0, %1, %2 3453 eor%?\\t%0, %1, %2 3454 eor%?\\t%0, %1, %2 3455 #" 3456 "TARGET_32BIT 3457 && CONST_INT_P (operands[2]) 3458 && !const_ok_for_arm (INTVAL (operands[2]))" 3459 [(clobber (const_int 0))] 3460{ 3461 arm_split_constant (XOR, SImode, curr_insn, 3462 INTVAL (operands[2]), operands[0], operands[1], 0); 3463 DONE; 3464} 3465 [(set_attr "length" "4,4,4,16") 3466 (set_attr "predicable" "yes") 3467 (set_attr "predicable_short_it" "no,yes,no,no") 3468 (set_attr "type" "logic_imm,logic_reg,logic_reg,multiple")] 3469) 3470 3471(define_insn "*xorsi3_compare0" 3472 [(set (reg:CC_NOOV CC_REGNUM) 3473 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r,r") 3474 (match_operand:SI 2 "arm_rhs_operand" "I,r")) 3475 (const_int 0))) 3476 (set (match_operand:SI 0 "s_register_operand" "=r,r") 3477 (xor:SI (match_dup 1) (match_dup 2)))] 3478 "TARGET_32BIT" 3479 "eors%?\\t%0, %1, %2" 3480 [(set_attr "conds" "set") 3481 (set_attr "type" "logics_imm,logics_reg")] 3482) 3483 3484(define_insn "*xorsi3_compare0_scratch" 3485 [(set (reg:CC_NOOV CC_REGNUM) 3486 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r,r") 3487 (match_operand:SI 1 "arm_rhs_operand" "I,r")) 3488 (const_int 0)))] 3489 "TARGET_32BIT" 3490 "teq%?\\t%0, %1" 3491 [(set_attr "conds" "set") 3492 (set_attr "type" "logics_imm,logics_reg")] 3493) 3494 3495; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 3496; (NOT D) we can sometimes merge the final NOT into one of the following 3497; insns. 3498 3499(define_split 3500 [(set (match_operand:SI 0 "s_register_operand" "") 3501 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "")) 3502 (not:SI (match_operand:SI 2 "arm_rhs_operand" ""))) 3503 (match_operand:SI 3 "arm_rhs_operand" ""))) 3504 (clobber (match_operand:SI 4 "s_register_operand" ""))] 3505 "TARGET_32BIT" 3506 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2)) 3507 (not:SI (match_dup 3)))) 3508 (set (match_dup 0) (not:SI (match_dup 4)))] 3509 "" 3510) 3511 3512(define_insn_and_split "*andsi_iorsi3_notsi" 3513 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r") 3514 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "%0,r,r") 3515 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")) 3516 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))] 3517 "TARGET_32BIT" 3518 "#" ; "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3" 3519 "&& reload_completed" 3520 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2))) 3521 (set (match_dup 0) (and:SI (match_dup 4) (match_dup 5)))] 3522 { 3523 /* If operands[3] is a constant make sure to fold the NOT into it 3524 to avoid creating a NOT of a CONST_INT. */ 3525 rtx not_rtx = simplify_gen_unary (NOT, SImode, operands[3], SImode); 3526 if (CONST_INT_P (not_rtx)) 3527 { 3528 operands[4] = operands[0]; 3529 operands[5] = not_rtx; 3530 } 3531 else 3532 { 3533 operands[5] = operands[0]; 3534 operands[4] = not_rtx; 3535 } 3536 } 3537 [(set_attr "length" "8") 3538 (set_attr "ce_count" "2") 3539 (set_attr "predicable" "yes") 3540 (set_attr "type" "multiple")] 3541) 3542 3543; ??? Are these four splitters still beneficial when the Thumb-2 bitfield 3544; insns are available? 3545(define_split 3546 [(set (match_operand:SI 0 "s_register_operand" "") 3547 (match_operator:SI 1 "logical_binary_operator" 3548 [(zero_extract:SI (match_operand:SI 2 "s_register_operand" "") 3549 (match_operand:SI 3 "const_int_operand" "") 3550 (match_operand:SI 4 "const_int_operand" "")) 3551 (match_operator:SI 9 "logical_binary_operator" 3552 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "") 3553 (match_operand:SI 6 "const_int_operand" "")) 3554 (match_operand:SI 7 "s_register_operand" "")])])) 3555 (clobber (match_operand:SI 8 "s_register_operand" ""))] 3556 "TARGET_32BIT 3557 && GET_CODE (operands[1]) == GET_CODE (operands[9]) 3558 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])" 3559 [(set (match_dup 8) 3560 (match_op_dup 1 3561 [(ashift:SI (match_dup 2) (match_dup 4)) 3562 (match_dup 5)])) 3563 (set (match_dup 0) 3564 (match_op_dup 1 3565 [(lshiftrt:SI (match_dup 8) (match_dup 6)) 3566 (match_dup 7)]))] 3567 " 3568 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4]))); 3569") 3570 3571(define_split 3572 [(set (match_operand:SI 0 "s_register_operand" "") 3573 (match_operator:SI 1 "logical_binary_operator" 3574 [(match_operator:SI 9 "logical_binary_operator" 3575 [(lshiftrt:SI (match_operand:SI 5 "s_register_operand" "") 3576 (match_operand:SI 6 "const_int_operand" "")) 3577 (match_operand:SI 7 "s_register_operand" "")]) 3578 (zero_extract:SI (match_operand:SI 2 "s_register_operand" "") 3579 (match_operand:SI 3 "const_int_operand" "") 3580 (match_operand:SI 4 "const_int_operand" ""))])) 3581 (clobber (match_operand:SI 8 "s_register_operand" ""))] 3582 "TARGET_32BIT 3583 && GET_CODE (operands[1]) == GET_CODE (operands[9]) 3584 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])" 3585 [(set (match_dup 8) 3586 (match_op_dup 1 3587 [(ashift:SI (match_dup 2) (match_dup 4)) 3588 (match_dup 5)])) 3589 (set (match_dup 0) 3590 (match_op_dup 1 3591 [(lshiftrt:SI (match_dup 8) (match_dup 6)) 3592 (match_dup 7)]))] 3593 " 3594 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4]))); 3595") 3596 3597(define_split 3598 [(set (match_operand:SI 0 "s_register_operand" "") 3599 (match_operator:SI 1 "logical_binary_operator" 3600 [(sign_extract:SI (match_operand:SI 2 "s_register_operand" "") 3601 (match_operand:SI 3 "const_int_operand" "") 3602 (match_operand:SI 4 "const_int_operand" "")) 3603 (match_operator:SI 9 "logical_binary_operator" 3604 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "") 3605 (match_operand:SI 6 "const_int_operand" "")) 3606 (match_operand:SI 7 "s_register_operand" "")])])) 3607 (clobber (match_operand:SI 8 "s_register_operand" ""))] 3608 "TARGET_32BIT 3609 && GET_CODE (operands[1]) == GET_CODE (operands[9]) 3610 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])" 3611 [(set (match_dup 8) 3612 (match_op_dup 1 3613 [(ashift:SI (match_dup 2) (match_dup 4)) 3614 (match_dup 5)])) 3615 (set (match_dup 0) 3616 (match_op_dup 1 3617 [(ashiftrt:SI (match_dup 8) (match_dup 6)) 3618 (match_dup 7)]))] 3619 " 3620 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4]))); 3621") 3622 3623(define_split 3624 [(set (match_operand:SI 0 "s_register_operand" "") 3625 (match_operator:SI 1 "logical_binary_operator" 3626 [(match_operator:SI 9 "logical_binary_operator" 3627 [(ashiftrt:SI (match_operand:SI 5 "s_register_operand" "") 3628 (match_operand:SI 6 "const_int_operand" "")) 3629 (match_operand:SI 7 "s_register_operand" "")]) 3630 (sign_extract:SI (match_operand:SI 2 "s_register_operand" "") 3631 (match_operand:SI 3 "const_int_operand" "") 3632 (match_operand:SI 4 "const_int_operand" ""))])) 3633 (clobber (match_operand:SI 8 "s_register_operand" ""))] 3634 "TARGET_32BIT 3635 && GET_CODE (operands[1]) == GET_CODE (operands[9]) 3636 && INTVAL (operands[3]) == 32 - INTVAL (operands[6])" 3637 [(set (match_dup 8) 3638 (match_op_dup 1 3639 [(ashift:SI (match_dup 2) (match_dup 4)) 3640 (match_dup 5)])) 3641 (set (match_dup 0) 3642 (match_op_dup 1 3643 [(ashiftrt:SI (match_dup 8) (match_dup 6)) 3644 (match_dup 7)]))] 3645 " 3646 operands[4] = GEN_INT (32 - (INTVAL (operands[3]) + INTVAL (operands[4]))); 3647") 3648 3649 3650;; Minimum and maximum insns 3651 3652(define_expand "smaxsi3" 3653 [(parallel [ 3654 (set (match_operand:SI 0 "s_register_operand" "") 3655 (smax:SI (match_operand:SI 1 "s_register_operand" "") 3656 (match_operand:SI 2 "arm_rhs_operand" ""))) 3657 (clobber (reg:CC CC_REGNUM))])] 3658 "TARGET_32BIT" 3659 " 3660 if (operands[2] == const0_rtx || operands[2] == constm1_rtx) 3661 { 3662 /* No need for a clobber of the condition code register here. */ 3663 emit_insn (gen_rtx_SET (operands[0], 3664 gen_rtx_SMAX (SImode, operands[1], 3665 operands[2]))); 3666 DONE; 3667 } 3668") 3669 3670(define_insn "*smax_0" 3671 [(set (match_operand:SI 0 "s_register_operand" "=r") 3672 (smax:SI (match_operand:SI 1 "s_register_operand" "r") 3673 (const_int 0)))] 3674 "TARGET_32BIT" 3675 "bic%?\\t%0, %1, %1, asr #31" 3676 [(set_attr "predicable" "yes") 3677 (set_attr "type" "logic_shift_reg")] 3678) 3679 3680(define_insn "*smax_m1" 3681 [(set (match_operand:SI 0 "s_register_operand" "=r") 3682 (smax:SI (match_operand:SI 1 "s_register_operand" "r") 3683 (const_int -1)))] 3684 "TARGET_32BIT" 3685 "orr%?\\t%0, %1, %1, asr #31" 3686 [(set_attr "predicable" "yes") 3687 (set_attr "type" "logic_shift_reg")] 3688) 3689 3690(define_insn_and_split "*arm_smax_insn" 3691 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 3692 (smax:SI (match_operand:SI 1 "s_register_operand" "%0,?r") 3693 (match_operand:SI 2 "arm_rhs_operand" "rI,rI"))) 3694 (clobber (reg:CC CC_REGNUM))] 3695 "TARGET_ARM" 3696 "#" 3697 ; cmp\\t%1, %2\;movlt\\t%0, %2 3698 ; cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2" 3699 "TARGET_ARM" 3700 [(set (reg:CC CC_REGNUM) 3701 (compare:CC (match_dup 1) (match_dup 2))) 3702 (set (match_dup 0) 3703 (if_then_else:SI (ge:SI (reg:CC CC_REGNUM) (const_int 0)) 3704 (match_dup 1) 3705 (match_dup 2)))] 3706 "" 3707 [(set_attr "conds" "clob") 3708 (set_attr "length" "8,12") 3709 (set_attr "type" "multiple")] 3710) 3711 3712(define_expand "sminsi3" 3713 [(parallel [ 3714 (set (match_operand:SI 0 "s_register_operand" "") 3715 (smin:SI (match_operand:SI 1 "s_register_operand" "") 3716 (match_operand:SI 2 "arm_rhs_operand" ""))) 3717 (clobber (reg:CC CC_REGNUM))])] 3718 "TARGET_32BIT" 3719 " 3720 if (operands[2] == const0_rtx) 3721 { 3722 /* No need for a clobber of the condition code register here. */ 3723 emit_insn (gen_rtx_SET (operands[0], 3724 gen_rtx_SMIN (SImode, operands[1], 3725 operands[2]))); 3726 DONE; 3727 } 3728") 3729 3730(define_insn "*smin_0" 3731 [(set (match_operand:SI 0 "s_register_operand" "=r") 3732 (smin:SI (match_operand:SI 1 "s_register_operand" "r") 3733 (const_int 0)))] 3734 "TARGET_32BIT" 3735 "and%?\\t%0, %1, %1, asr #31" 3736 [(set_attr "predicable" "yes") 3737 (set_attr "type" "logic_shift_reg")] 3738) 3739 3740(define_insn_and_split "*arm_smin_insn" 3741 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 3742 (smin:SI (match_operand:SI 1 "s_register_operand" "%0,?r") 3743 (match_operand:SI 2 "arm_rhs_operand" "rI,rI"))) 3744 (clobber (reg:CC CC_REGNUM))] 3745 "TARGET_ARM" 3746 "#" 3747 ; cmp\\t%1, %2\;movge\\t%0, %2 3748 ; cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2" 3749 "TARGET_ARM" 3750 [(set (reg:CC CC_REGNUM) 3751 (compare:CC (match_dup 1) (match_dup 2))) 3752 (set (match_dup 0) 3753 (if_then_else:SI (lt:SI (reg:CC CC_REGNUM) (const_int 0)) 3754 (match_dup 1) 3755 (match_dup 2)))] 3756 "" 3757 [(set_attr "conds" "clob") 3758 (set_attr "length" "8,12") 3759 (set_attr "type" "multiple,multiple")] 3760) 3761 3762(define_expand "umaxsi3" 3763 [(parallel [ 3764 (set (match_operand:SI 0 "s_register_operand" "") 3765 (umax:SI (match_operand:SI 1 "s_register_operand" "") 3766 (match_operand:SI 2 "arm_rhs_operand" ""))) 3767 (clobber (reg:CC CC_REGNUM))])] 3768 "TARGET_32BIT" 3769 "" 3770) 3771 3772(define_insn_and_split "*arm_umaxsi3" 3773 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 3774 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") 3775 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 3776 (clobber (reg:CC CC_REGNUM))] 3777 "TARGET_ARM" 3778 "#" 3779 ; cmp\\t%1, %2\;movcc\\t%0, %2 3780 ; cmp\\t%1, %2\;movcs\\t%0, %1 3781 ; cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2" 3782 "TARGET_ARM" 3783 [(set (reg:CC CC_REGNUM) 3784 (compare:CC (match_dup 1) (match_dup 2))) 3785 (set (match_dup 0) 3786 (if_then_else:SI (geu:SI (reg:CC CC_REGNUM) (const_int 0)) 3787 (match_dup 1) 3788 (match_dup 2)))] 3789 "" 3790 [(set_attr "conds" "clob") 3791 (set_attr "length" "8,8,12") 3792 (set_attr "type" "store_4")] 3793) 3794 3795(define_expand "uminsi3" 3796 [(parallel [ 3797 (set (match_operand:SI 0 "s_register_operand" "") 3798 (umin:SI (match_operand:SI 1 "s_register_operand" "") 3799 (match_operand:SI 2 "arm_rhs_operand" ""))) 3800 (clobber (reg:CC CC_REGNUM))])] 3801 "TARGET_32BIT" 3802 "" 3803) 3804 3805(define_insn_and_split "*arm_uminsi3" 3806 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 3807 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") 3808 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 3809 (clobber (reg:CC CC_REGNUM))] 3810 "TARGET_ARM" 3811 "#" 3812 ; cmp\\t%1, %2\;movcs\\t%0, %2 3813 ; cmp\\t%1, %2\;movcc\\t%0, %1 3814 ; cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2" 3815 "TARGET_ARM" 3816 [(set (reg:CC CC_REGNUM) 3817 (compare:CC (match_dup 1) (match_dup 2))) 3818 (set (match_dup 0) 3819 (if_then_else:SI (ltu:SI (reg:CC CC_REGNUM) (const_int 0)) 3820 (match_dup 1) 3821 (match_dup 2)))] 3822 "" 3823 [(set_attr "conds" "clob") 3824 (set_attr "length" "8,8,12") 3825 (set_attr "type" "store_4")] 3826) 3827 3828(define_insn "*store_minmaxsi" 3829 [(set (match_operand:SI 0 "memory_operand" "=m") 3830 (match_operator:SI 3 "minmax_operator" 3831 [(match_operand:SI 1 "s_register_operand" "r") 3832 (match_operand:SI 2 "s_register_operand" "r")])) 3833 (clobber (reg:CC CC_REGNUM))] 3834 "TARGET_32BIT && optimize_function_for_size_p (cfun) && !arm_restrict_it" 3835 "* 3836 operands[3] = gen_rtx_fmt_ee (minmax_code (operands[3]), SImode, 3837 operands[1], operands[2]); 3838 output_asm_insn (\"cmp\\t%1, %2\", operands); 3839 if (TARGET_THUMB2) 3840 output_asm_insn (\"ite\t%d3\", operands); 3841 output_asm_insn (\"str%d3\\t%1, %0\", operands); 3842 output_asm_insn (\"str%D3\\t%2, %0\", operands); 3843 return \"\"; 3844 " 3845 [(set_attr "conds" "clob") 3846 (set (attr "length") 3847 (if_then_else (eq_attr "is_thumb" "yes") 3848 (const_int 14) 3849 (const_int 12))) 3850 (set_attr "type" "store_4")] 3851) 3852 3853; Reject the frame pointer in operand[1], since reloading this after 3854; it has been eliminated can cause carnage. 3855(define_insn "*minmax_arithsi" 3856 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 3857 (match_operator:SI 4 "shiftable_operator" 3858 [(match_operator:SI 5 "minmax_operator" 3859 [(match_operand:SI 2 "s_register_operand" "r,r") 3860 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 3861 (match_operand:SI 1 "s_register_operand" "0,?r")])) 3862 (clobber (reg:CC CC_REGNUM))] 3863 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && !arm_restrict_it" 3864 "* 3865 { 3866 enum rtx_code code = GET_CODE (operands[4]); 3867 bool need_else; 3868 3869 if (which_alternative != 0 || operands[3] != const0_rtx 3870 || (code != PLUS && code != IOR && code != XOR)) 3871 need_else = true; 3872 else 3873 need_else = false; 3874 3875 operands[5] = gen_rtx_fmt_ee (minmax_code (operands[5]), SImode, 3876 operands[2], operands[3]); 3877 output_asm_insn (\"cmp\\t%2, %3\", operands); 3878 if (TARGET_THUMB2) 3879 { 3880 if (need_else) 3881 output_asm_insn (\"ite\\t%d5\", operands); 3882 else 3883 output_asm_insn (\"it\\t%d5\", operands); 3884 } 3885 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands); 3886 if (need_else) 3887 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands); 3888 return \"\"; 3889 }" 3890 [(set_attr "conds" "clob") 3891 (set (attr "length") 3892 (if_then_else (eq_attr "is_thumb" "yes") 3893 (const_int 14) 3894 (const_int 12))) 3895 (set_attr "type" "multiple")] 3896) 3897 3898; Reject the frame pointer in operand[1], since reloading this after 3899; it has been eliminated can cause carnage. 3900(define_insn_and_split "*minmax_arithsi_non_canon" 3901 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 3902 (minus:SI 3903 (match_operand:SI 1 "s_register_operand" "0,?Ts") 3904 (match_operator:SI 4 "minmax_operator" 3905 [(match_operand:SI 2 "s_register_operand" "Ts,Ts") 3906 (match_operand:SI 3 "arm_rhs_operand" "TsI,TsI")]))) 3907 (clobber (reg:CC CC_REGNUM))] 3908 "TARGET_32BIT && !arm_eliminable_register (operands[1]) 3909 && !(arm_restrict_it && CONST_INT_P (operands[3]))" 3910 "#" 3911 "TARGET_32BIT && !arm_eliminable_register (operands[1]) && reload_completed" 3912 [(set (reg:CC CC_REGNUM) 3913 (compare:CC (match_dup 2) (match_dup 3))) 3914 3915 (cond_exec (match_op_dup 4 [(reg:CC CC_REGNUM) (const_int 0)]) 3916 (set (match_dup 0) 3917 (minus:SI (match_dup 1) 3918 (match_dup 2)))) 3919 (cond_exec (match_op_dup 5 [(reg:CC CC_REGNUM) (const_int 0)]) 3920 (set (match_dup 0) 3921 (match_dup 6)))] 3922 { 3923 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 3924 operands[2], operands[3]); 3925 enum rtx_code rc = minmax_code (operands[4]); 3926 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, 3927 operands[2], operands[3]); 3928 3929 if (mode == CCFPmode || mode == CCFPEmode) 3930 rc = reverse_condition_maybe_unordered (rc); 3931 else 3932 rc = reverse_condition (rc); 3933 operands[5] = gen_rtx_fmt_ee (rc, SImode, operands[2], operands[3]); 3934 if (CONST_INT_P (operands[3])) 3935 operands[6] = plus_constant (SImode, operands[1], -INTVAL (operands[3])); 3936 else 3937 operands[6] = gen_rtx_MINUS (SImode, operands[1], operands[3]); 3938 } 3939 [(set_attr "conds" "clob") 3940 (set (attr "length") 3941 (if_then_else (eq_attr "is_thumb" "yes") 3942 (const_int 14) 3943 (const_int 12))) 3944 (set_attr "type" "multiple")] 3945) 3946 3947(define_code_iterator SAT [smin smax]) 3948(define_code_iterator SATrev [smin smax]) 3949(define_code_attr SATlo [(smin "1") (smax "2")]) 3950(define_code_attr SAThi [(smin "2") (smax "1")]) 3951 3952(define_insn "*satsi_<SAT:code>" 3953 [(set (match_operand:SI 0 "s_register_operand" "=r") 3954 (SAT:SI (SATrev:SI (match_operand:SI 3 "s_register_operand" "r") 3955 (match_operand:SI 1 "const_int_operand" "i")) 3956 (match_operand:SI 2 "const_int_operand" "i")))] 3957 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE> 3958 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)" 3959{ 3960 int mask; 3961 bool signed_sat; 3962 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], 3963 &mask, &signed_sat)) 3964 gcc_unreachable (); 3965 3966 operands[1] = GEN_INT (mask); 3967 if (signed_sat) 3968 return "ssat%?\t%0, %1, %3"; 3969 else 3970 return "usat%?\t%0, %1, %3"; 3971} 3972 [(set_attr "predicable" "yes") 3973 (set_attr "type" "alus_imm")] 3974) 3975 3976(define_insn "*satsi_<SAT:code>_shift" 3977 [(set (match_operand:SI 0 "s_register_operand" "=r") 3978 (SAT:SI (SATrev:SI (match_operator:SI 3 "sat_shift_operator" 3979 [(match_operand:SI 4 "s_register_operand" "r") 3980 (match_operand:SI 5 "const_int_operand" "i")]) 3981 (match_operand:SI 1 "const_int_operand" "i")) 3982 (match_operand:SI 2 "const_int_operand" "i")))] 3983 "TARGET_32BIT && arm_arch6 && <SAT:CODE> != <SATrev:CODE> 3984 && arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], NULL, NULL)" 3985{ 3986 int mask; 3987 bool signed_sat; 3988 if (!arm_sat_operator_match (operands[<SAT:SATlo>], operands[<SAT:SAThi>], 3989 &mask, &signed_sat)) 3990 gcc_unreachable (); 3991 3992 operands[1] = GEN_INT (mask); 3993 if (signed_sat) 3994 return "ssat%?\t%0, %1, %4%S3"; 3995 else 3996 return "usat%?\t%0, %1, %4%S3"; 3997} 3998 [(set_attr "predicable" "yes") 3999 (set_attr "shift" "3") 4000 (set_attr "type" "logic_shift_reg")]) 4001 4002;; Shift and rotation insns 4003 4004(define_expand "ashldi3" 4005 [(set (match_operand:DI 0 "s_register_operand" "") 4006 (ashift:DI (match_operand:DI 1 "s_register_operand" "") 4007 (match_operand:SI 2 "general_operand" "")))] 4008 "TARGET_32BIT" 4009 " 4010 if (TARGET_NEON) 4011 { 4012 /* Delay the decision whether to use NEON or core-regs until 4013 register allocation. */ 4014 emit_insn (gen_ashldi3_neon (operands[0], operands[1], operands[2])); 4015 DONE; 4016 } 4017 else 4018 { 4019 /* Only the NEON case can handle in-memory shift counts. */ 4020 if (!reg_or_int_operand (operands[2], SImode)) 4021 operands[2] = force_reg (SImode, operands[2]); 4022 } 4023 4024 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT) 4025 ; /* No special preparation statements; expand pattern as above. */ 4026 else 4027 { 4028 rtx scratch1, scratch2; 4029 4030 /* Ideally we should use iwmmxt here if we could know that operands[1] 4031 ends up already living in an iwmmxt register. Otherwise it's 4032 cheaper to have the alternate code being generated than moving 4033 values to iwmmxt regs and back. */ 4034 4035 /* Expand operation using core-registers. 4036 'FAIL' would achieve the same thing, but this is a bit smarter. */ 4037 scratch1 = gen_reg_rtx (SImode); 4038 scratch2 = gen_reg_rtx (SImode); 4039 arm_emit_coreregs_64bit_shift (ASHIFT, operands[0], operands[1], 4040 operands[2], scratch1, scratch2); 4041 DONE; 4042 } 4043 " 4044) 4045 4046(define_expand "ashlsi3" 4047 [(set (match_operand:SI 0 "s_register_operand" "") 4048 (ashift:SI (match_operand:SI 1 "s_register_operand" "") 4049 (match_operand:SI 2 "arm_rhs_operand" "")))] 4050 "TARGET_EITHER" 4051 " 4052 if (CONST_INT_P (operands[2]) 4053 && (UINTVAL (operands[2])) > 31) 4054 { 4055 emit_insn (gen_movsi (operands[0], const0_rtx)); 4056 DONE; 4057 } 4058 " 4059) 4060 4061(define_expand "ashrdi3" 4062 [(set (match_operand:DI 0 "s_register_operand" "") 4063 (ashiftrt:DI (match_operand:DI 1 "s_register_operand" "") 4064 (match_operand:SI 2 "reg_or_int_operand" "")))] 4065 "TARGET_32BIT" 4066 " 4067 if (TARGET_NEON) 4068 { 4069 /* Delay the decision whether to use NEON or core-regs until 4070 register allocation. */ 4071 emit_insn (gen_ashrdi3_neon (operands[0], operands[1], operands[2])); 4072 DONE; 4073 } 4074 4075 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT) 4076 ; /* No special preparation statements; expand pattern as above. */ 4077 else 4078 { 4079 rtx scratch1, scratch2; 4080 4081 /* Ideally we should use iwmmxt here if we could know that operands[1] 4082 ends up already living in an iwmmxt register. Otherwise it's 4083 cheaper to have the alternate code being generated than moving 4084 values to iwmmxt regs and back. */ 4085 4086 /* Expand operation using core-registers. 4087 'FAIL' would achieve the same thing, but this is a bit smarter. */ 4088 scratch1 = gen_reg_rtx (SImode); 4089 scratch2 = gen_reg_rtx (SImode); 4090 arm_emit_coreregs_64bit_shift (ASHIFTRT, operands[0], operands[1], 4091 operands[2], scratch1, scratch2); 4092 DONE; 4093 } 4094 " 4095) 4096 4097(define_expand "ashrsi3" 4098 [(set (match_operand:SI 0 "s_register_operand" "") 4099 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "") 4100 (match_operand:SI 2 "arm_rhs_operand" "")))] 4101 "TARGET_EITHER" 4102 " 4103 if (CONST_INT_P (operands[2]) 4104 && UINTVAL (operands[2]) > 31) 4105 operands[2] = GEN_INT (31); 4106 " 4107) 4108 4109(define_expand "lshrdi3" 4110 [(set (match_operand:DI 0 "s_register_operand" "") 4111 (lshiftrt:DI (match_operand:DI 1 "s_register_operand" "") 4112 (match_operand:SI 2 "reg_or_int_operand" "")))] 4113 "TARGET_32BIT" 4114 " 4115 if (TARGET_NEON) 4116 { 4117 /* Delay the decision whether to use NEON or core-regs until 4118 register allocation. */ 4119 emit_insn (gen_lshrdi3_neon (operands[0], operands[1], operands[2])); 4120 DONE; 4121 } 4122 4123 if (!CONST_INT_P (operands[2]) && TARGET_REALLY_IWMMXT) 4124 ; /* No special preparation statements; expand pattern as above. */ 4125 else 4126 { 4127 rtx scratch1, scratch2; 4128 4129 /* Ideally we should use iwmmxt here if we could know that operands[1] 4130 ends up already living in an iwmmxt register. Otherwise it's 4131 cheaper to have the alternate code being generated than moving 4132 values to iwmmxt regs and back. */ 4133 4134 /* Expand operation using core-registers. 4135 'FAIL' would achieve the same thing, but this is a bit smarter. */ 4136 scratch1 = gen_reg_rtx (SImode); 4137 scratch2 = gen_reg_rtx (SImode); 4138 arm_emit_coreregs_64bit_shift (LSHIFTRT, operands[0], operands[1], 4139 operands[2], scratch1, scratch2); 4140 DONE; 4141 } 4142 " 4143) 4144 4145(define_expand "lshrsi3" 4146 [(set (match_operand:SI 0 "s_register_operand" "") 4147 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "") 4148 (match_operand:SI 2 "arm_rhs_operand" "")))] 4149 "TARGET_EITHER" 4150 " 4151 if (CONST_INT_P (operands[2]) 4152 && (UINTVAL (operands[2])) > 31) 4153 { 4154 emit_insn (gen_movsi (operands[0], const0_rtx)); 4155 DONE; 4156 } 4157 " 4158) 4159 4160(define_expand "rotlsi3" 4161 [(set (match_operand:SI 0 "s_register_operand" "") 4162 (rotatert:SI (match_operand:SI 1 "s_register_operand" "") 4163 (match_operand:SI 2 "reg_or_int_operand" "")))] 4164 "TARGET_32BIT" 4165 " 4166 if (CONST_INT_P (operands[2])) 4167 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32); 4168 else 4169 { 4170 rtx reg = gen_reg_rtx (SImode); 4171 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2])); 4172 operands[2] = reg; 4173 } 4174 " 4175) 4176 4177(define_expand "rotrsi3" 4178 [(set (match_operand:SI 0 "s_register_operand" "") 4179 (rotatert:SI (match_operand:SI 1 "s_register_operand" "") 4180 (match_operand:SI 2 "arm_rhs_operand" "")))] 4181 "TARGET_EITHER" 4182 " 4183 if (TARGET_32BIT) 4184 { 4185 if (CONST_INT_P (operands[2]) 4186 && UINTVAL (operands[2]) > 31) 4187 operands[2] = GEN_INT (INTVAL (operands[2]) % 32); 4188 } 4189 else /* TARGET_THUMB1 */ 4190 { 4191 if (CONST_INT_P (operands [2])) 4192 operands [2] = force_reg (SImode, operands[2]); 4193 } 4194 " 4195) 4196 4197(define_insn "*arm_shiftsi3" 4198 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r,r") 4199 (match_operator:SI 3 "shift_operator" 4200 [(match_operand:SI 1 "s_register_operand" "0,l,r,r") 4201 (match_operand:SI 2 "reg_or_int_operand" "l,M,M,r")]))] 4202 "TARGET_32BIT" 4203 "* return arm_output_shift(operands, 0);" 4204 [(set_attr "predicable" "yes") 4205 (set_attr "arch" "t2,t2,*,*") 4206 (set_attr "predicable_short_it" "yes,yes,no,no") 4207 (set_attr "length" "4") 4208 (set_attr "shift" "1") 4209 (set_attr "type" "alu_shift_reg,alu_shift_imm,alu_shift_imm,alu_shift_reg")] 4210) 4211 4212(define_insn "*shiftsi3_compare0" 4213 [(set (reg:CC_NOOV CC_REGNUM) 4214 (compare:CC_NOOV (match_operator:SI 3 "shift_operator" 4215 [(match_operand:SI 1 "s_register_operand" "r,r") 4216 (match_operand:SI 2 "arm_rhs_operand" "M,r")]) 4217 (const_int 0))) 4218 (set (match_operand:SI 0 "s_register_operand" "=r,r") 4219 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))] 4220 "TARGET_32BIT" 4221 "* return arm_output_shift(operands, 1);" 4222 [(set_attr "conds" "set") 4223 (set_attr "shift" "1") 4224 (set_attr "type" "alus_shift_imm,alus_shift_reg")] 4225) 4226 4227(define_insn "*shiftsi3_compare0_scratch" 4228 [(set (reg:CC_NOOV CC_REGNUM) 4229 (compare:CC_NOOV (match_operator:SI 3 "shift_operator" 4230 [(match_operand:SI 1 "s_register_operand" "r,r") 4231 (match_operand:SI 2 "arm_rhs_operand" "M,r")]) 4232 (const_int 0))) 4233 (clobber (match_scratch:SI 0 "=r,r"))] 4234 "TARGET_32BIT" 4235 "* return arm_output_shift(operands, 1);" 4236 [(set_attr "conds" "set") 4237 (set_attr "shift" "1") 4238 (set_attr "type" "shift_imm,shift_reg")] 4239) 4240 4241(define_insn "*not_shiftsi" 4242 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 4243 (not:SI (match_operator:SI 3 "shift_operator" 4244 [(match_operand:SI 1 "s_register_operand" "r,r") 4245 (match_operand:SI 2 "shift_amount_operand" "M,rM")])))] 4246 "TARGET_32BIT" 4247 "mvn%?\\t%0, %1%S3" 4248 [(set_attr "predicable" "yes") 4249 (set_attr "shift" "1") 4250 (set_attr "arch" "32,a") 4251 (set_attr "type" "mvn_shift,mvn_shift_reg")]) 4252 4253(define_insn "*not_shiftsi_compare0" 4254 [(set (reg:CC_NOOV CC_REGNUM) 4255 (compare:CC_NOOV 4256 (not:SI (match_operator:SI 3 "shift_operator" 4257 [(match_operand:SI 1 "s_register_operand" "r,r") 4258 (match_operand:SI 2 "shift_amount_operand" "M,rM")])) 4259 (const_int 0))) 4260 (set (match_operand:SI 0 "s_register_operand" "=r,r") 4261 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))] 4262 "TARGET_32BIT" 4263 "mvns%?\\t%0, %1%S3" 4264 [(set_attr "conds" "set") 4265 (set_attr "shift" "1") 4266 (set_attr "arch" "32,a") 4267 (set_attr "type" "mvn_shift,mvn_shift_reg")]) 4268 4269(define_insn "*not_shiftsi_compare0_scratch" 4270 [(set (reg:CC_NOOV CC_REGNUM) 4271 (compare:CC_NOOV 4272 (not:SI (match_operator:SI 3 "shift_operator" 4273 [(match_operand:SI 1 "s_register_operand" "r,r") 4274 (match_operand:SI 2 "shift_amount_operand" "M,rM")])) 4275 (const_int 0))) 4276 (clobber (match_scratch:SI 0 "=r,r"))] 4277 "TARGET_32BIT" 4278 "mvns%?\\t%0, %1%S3" 4279 [(set_attr "conds" "set") 4280 (set_attr "shift" "1") 4281 (set_attr "arch" "32,a") 4282 (set_attr "type" "mvn_shift,mvn_shift_reg")]) 4283 4284;; We don't really have extzv, but defining this using shifts helps 4285;; to reduce register pressure later on. 4286 4287(define_expand "extzv" 4288 [(set (match_operand 0 "s_register_operand" "") 4289 (zero_extract (match_operand 1 "nonimmediate_operand" "") 4290 (match_operand 2 "const_int_operand" "") 4291 (match_operand 3 "const_int_operand" "")))] 4292 "TARGET_THUMB1 || arm_arch_thumb2" 4293 " 4294 { 4295 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]); 4296 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]); 4297 4298 if (arm_arch_thumb2) 4299 { 4300 HOST_WIDE_INT width = INTVAL (operands[2]); 4301 HOST_WIDE_INT bitpos = INTVAL (operands[3]); 4302 4303 if (unaligned_access && MEM_P (operands[1]) 4304 && (width == 16 || width == 32) && (bitpos % BITS_PER_UNIT) == 0) 4305 { 4306 rtx base_addr; 4307 4308 if (BYTES_BIG_ENDIAN) 4309 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width 4310 - bitpos; 4311 4312 if (width == 32) 4313 { 4314 base_addr = adjust_address (operands[1], SImode, 4315 bitpos / BITS_PER_UNIT); 4316 emit_insn (gen_unaligned_loadsi (operands[0], base_addr)); 4317 } 4318 else 4319 { 4320 rtx dest = operands[0]; 4321 rtx tmp = gen_reg_rtx (SImode); 4322 4323 /* We may get a paradoxical subreg here. Strip it off. */ 4324 if (GET_CODE (dest) == SUBREG 4325 && GET_MODE (dest) == SImode 4326 && GET_MODE (SUBREG_REG (dest)) == HImode) 4327 dest = SUBREG_REG (dest); 4328 4329 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width) 4330 FAIL; 4331 4332 base_addr = adjust_address (operands[1], HImode, 4333 bitpos / BITS_PER_UNIT); 4334 emit_insn (gen_unaligned_loadhiu (tmp, base_addr)); 4335 emit_move_insn (gen_lowpart (SImode, dest), tmp); 4336 } 4337 DONE; 4338 } 4339 else if (s_register_operand (operands[1], GET_MODE (operands[1]))) 4340 { 4341 emit_insn (gen_extzv_t2 (operands[0], operands[1], operands[2], 4342 operands[3])); 4343 DONE; 4344 } 4345 else 4346 FAIL; 4347 } 4348 4349 if (!s_register_operand (operands[1], GET_MODE (operands[1]))) 4350 FAIL; 4351 4352 operands[3] = GEN_INT (rshift); 4353 4354 if (lshift == 0) 4355 { 4356 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3])); 4357 DONE; 4358 } 4359 4360 emit_insn (gen_extzv_t1 (operands[0], operands[1], GEN_INT (lshift), 4361 operands[3], gen_reg_rtx (SImode))); 4362 DONE; 4363 }" 4364) 4365 4366;; Helper for extzv, for the Thumb-1 register-shifts case. 4367 4368(define_expand "extzv_t1" 4369 [(set (match_operand:SI 4 "s_register_operand" "") 4370 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "") 4371 (match_operand:SI 2 "const_int_operand" ""))) 4372 (set (match_operand:SI 0 "s_register_operand" "") 4373 (lshiftrt:SI (match_dup 4) 4374 (match_operand:SI 3 "const_int_operand" "")))] 4375 "TARGET_THUMB1" 4376 "") 4377 4378(define_expand "extv" 4379 [(set (match_operand 0 "s_register_operand" "") 4380 (sign_extract (match_operand 1 "nonimmediate_operand" "") 4381 (match_operand 2 "const_int_operand" "") 4382 (match_operand 3 "const_int_operand" "")))] 4383 "arm_arch_thumb2" 4384{ 4385 HOST_WIDE_INT width = INTVAL (operands[2]); 4386 HOST_WIDE_INT bitpos = INTVAL (operands[3]); 4387 4388 if (unaligned_access && MEM_P (operands[1]) && (width == 16 || width == 32) 4389 && (bitpos % BITS_PER_UNIT) == 0) 4390 { 4391 rtx base_addr; 4392 4393 if (BYTES_BIG_ENDIAN) 4394 bitpos = GET_MODE_BITSIZE (GET_MODE (operands[0])) - width - bitpos; 4395 4396 if (width == 32) 4397 { 4398 base_addr = adjust_address (operands[1], SImode, 4399 bitpos / BITS_PER_UNIT); 4400 emit_insn (gen_unaligned_loadsi (operands[0], base_addr)); 4401 } 4402 else 4403 { 4404 rtx dest = operands[0]; 4405 rtx tmp = gen_reg_rtx (SImode); 4406 4407 /* We may get a paradoxical subreg here. Strip it off. */ 4408 if (GET_CODE (dest) == SUBREG 4409 && GET_MODE (dest) == SImode 4410 && GET_MODE (SUBREG_REG (dest)) == HImode) 4411 dest = SUBREG_REG (dest); 4412 4413 if (GET_MODE_BITSIZE (GET_MODE (dest)) != width) 4414 FAIL; 4415 4416 base_addr = adjust_address (operands[1], HImode, 4417 bitpos / BITS_PER_UNIT); 4418 emit_insn (gen_unaligned_loadhis (tmp, base_addr)); 4419 emit_move_insn (gen_lowpart (SImode, dest), tmp); 4420 } 4421 4422 DONE; 4423 } 4424 else if (!s_register_operand (operands[1], GET_MODE (operands[1]))) 4425 FAIL; 4426 else if (GET_MODE (operands[0]) == SImode 4427 && GET_MODE (operands[1]) == SImode) 4428 { 4429 emit_insn (gen_extv_regsi (operands[0], operands[1], operands[2], 4430 operands[3])); 4431 DONE; 4432 } 4433 4434 FAIL; 4435}) 4436 4437; Helper to expand register forms of extv with the proper modes. 4438 4439(define_expand "extv_regsi" 4440 [(set (match_operand:SI 0 "s_register_operand" "") 4441 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "") 4442 (match_operand 2 "const_int_operand" "") 4443 (match_operand 3 "const_int_operand" "")))] 4444 "" 4445{ 4446}) 4447 4448; ARMv6+ unaligned load/store instructions (used for packed structure accesses). 4449 4450(define_insn "unaligned_loadsi" 4451 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") 4452 (unspec:SI [(match_operand:SI 1 "memory_operand" "m,Uw,m")] 4453 UNSPEC_UNALIGNED_LOAD))] 4454 "unaligned_access" 4455 "@ 4456 ldr\t%0, %1\t@ unaligned 4457 ldr%?\t%0, %1\t@ unaligned 4458 ldr%?\t%0, %1\t@ unaligned" 4459 [(set_attr "arch" "t1,t2,32") 4460 (set_attr "length" "2,2,4") 4461 (set_attr "predicable" "no,yes,yes") 4462 (set_attr "predicable_short_it" "no,yes,no") 4463 (set_attr "type" "load_4")]) 4464 4465;; The 16-bit Thumb1 variant of ldrsh requires two registers in the 4466;; address (there's no immediate format). That's tricky to support 4467;; here and we don't really need this pattern for that case, so only 4468;; enable for 32-bit ISAs. 4469(define_insn "unaligned_loadhis" 4470 [(set (match_operand:SI 0 "s_register_operand" "=r") 4471 (sign_extend:SI 4472 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")] 4473 UNSPEC_UNALIGNED_LOAD)))] 4474 "unaligned_access && TARGET_32BIT" 4475 "ldrsh%?\t%0, %1\t@ unaligned" 4476 [(set_attr "predicable" "yes") 4477 (set_attr "type" "load_byte")]) 4478 4479(define_insn "unaligned_loadhiu" 4480 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") 4481 (zero_extend:SI 4482 (unspec:HI [(match_operand:HI 1 "memory_operand" "m,Uw,m")] 4483 UNSPEC_UNALIGNED_LOAD)))] 4484 "unaligned_access" 4485 "@ 4486 ldrh\t%0, %1\t@ unaligned 4487 ldrh%?\t%0, %1\t@ unaligned 4488 ldrh%?\t%0, %1\t@ unaligned" 4489 [(set_attr "arch" "t1,t2,32") 4490 (set_attr "length" "2,2,4") 4491 (set_attr "predicable" "no,yes,yes") 4492 (set_attr "predicable_short_it" "no,yes,no") 4493 (set_attr "type" "load_byte")]) 4494 4495(define_insn "unaligned_storesi" 4496 [(set (match_operand:SI 0 "memory_operand" "=m,Uw,m") 4497 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,l,r")] 4498 UNSPEC_UNALIGNED_STORE))] 4499 "unaligned_access" 4500 "@ 4501 str\t%1, %0\t@ unaligned 4502 str%?\t%1, %0\t@ unaligned 4503 str%?\t%1, %0\t@ unaligned" 4504 [(set_attr "arch" "t1,t2,32") 4505 (set_attr "length" "2,2,4") 4506 (set_attr "predicable" "no,yes,yes") 4507 (set_attr "predicable_short_it" "no,yes,no") 4508 (set_attr "type" "store_4")]) 4509 4510(define_insn "unaligned_storehi" 4511 [(set (match_operand:HI 0 "memory_operand" "=m,Uw,m") 4512 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,l,r")] 4513 UNSPEC_UNALIGNED_STORE))] 4514 "unaligned_access" 4515 "@ 4516 strh\t%1, %0\t@ unaligned 4517 strh%?\t%1, %0\t@ unaligned 4518 strh%?\t%1, %0\t@ unaligned" 4519 [(set_attr "arch" "t1,t2,32") 4520 (set_attr "length" "2,2,4") 4521 (set_attr "predicable" "no,yes,yes") 4522 (set_attr "predicable_short_it" "no,yes,no") 4523 (set_attr "type" "store_4")]) 4524 4525 4526(define_insn "*extv_reg" 4527 [(set (match_operand:SI 0 "s_register_operand" "=r") 4528 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 4529 (match_operand:SI 2 "const_int_operand" "n") 4530 (match_operand:SI 3 "const_int_operand" "n")))] 4531 "arm_arch_thumb2 4532 && IN_RANGE (INTVAL (operands[3]), 0, 31) 4533 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))" 4534 "sbfx%?\t%0, %1, %3, %2" 4535 [(set_attr "length" "4") 4536 (set_attr "predicable" "yes") 4537 (set_attr "type" "bfm")] 4538) 4539 4540(define_insn "extzv_t2" 4541 [(set (match_operand:SI 0 "s_register_operand" "=r") 4542 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") 4543 (match_operand:SI 2 "const_int_operand" "n") 4544 (match_operand:SI 3 "const_int_operand" "n")))] 4545 "arm_arch_thumb2 4546 && IN_RANGE (INTVAL (operands[3]), 0, 31) 4547 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))" 4548 "ubfx%?\t%0, %1, %3, %2" 4549 [(set_attr "length" "4") 4550 (set_attr "predicable" "yes") 4551 (set_attr "type" "bfm")] 4552) 4553 4554 4555;; Division instructions 4556(define_insn "divsi3" 4557 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 4558 (div:SI (match_operand:SI 1 "s_register_operand" "r,r") 4559 (match_operand:SI 2 "s_register_operand" "r,r")))] 4560 "TARGET_IDIV" 4561 "@ 4562 sdiv%?\t%0, %1, %2 4563 sdiv\t%0, %1, %2" 4564 [(set_attr "arch" "32,v8mb") 4565 (set_attr "predicable" "yes") 4566 (set_attr "type" "sdiv")] 4567) 4568 4569(define_insn "udivsi3" 4570 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 4571 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r") 4572 (match_operand:SI 2 "s_register_operand" "r,r")))] 4573 "TARGET_IDIV" 4574 "@ 4575 udiv%?\t%0, %1, %2 4576 udiv\t%0, %1, %2" 4577 [(set_attr "arch" "32,v8mb") 4578 (set_attr "predicable" "yes") 4579 (set_attr "type" "udiv")] 4580) 4581 4582 4583;; Unary arithmetic insns 4584 4585(define_expand "negvsi3" 4586 [(match_operand:SI 0 "register_operand") 4587 (match_operand:SI 1 "register_operand") 4588 (match_operand 2 "")] 4589 "TARGET_32BIT" 4590{ 4591 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1])); 4592 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); 4593 4594 DONE; 4595}) 4596 4597(define_expand "negvdi3" 4598 [(match_operand:DI 0 "register_operand") 4599 (match_operand:DI 1 "register_operand") 4600 (match_operand 2 "")] 4601 "TARGET_ARM" 4602{ 4603 emit_insn (gen_negdi2_compare (operands[0], operands[1])); 4604 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); 4605 4606 DONE; 4607}) 4608 4609 4610(define_insn_and_split "negdi2_compare" 4611 [(set (reg:CC CC_REGNUM) 4612 (compare:CC 4613 (const_int 0) 4614 (match_operand:DI 1 "register_operand" "0,r"))) 4615 (set (match_operand:DI 0 "register_operand" "=r,&r") 4616 (minus:DI (const_int 0) (match_dup 1)))] 4617 "TARGET_ARM" 4618 "#" 4619 "&& reload_completed" 4620 [(parallel [(set (reg:CC CC_REGNUM) 4621 (compare:CC (const_int 0) (match_dup 1))) 4622 (set (match_dup 0) (minus:SI (const_int 0) 4623 (match_dup 1)))]) 4624 (parallel [(set (reg:CC CC_REGNUM) 4625 (compare:CC (const_int 0) (match_dup 3))) 4626 (set (match_dup 2) 4627 (minus:SI 4628 (minus:SI (const_int 0) (match_dup 3)) 4629 (ltu:SI (reg:CC_C CC_REGNUM) 4630 (const_int 0))))])] 4631 { 4632 operands[2] = gen_highpart (SImode, operands[0]); 4633 operands[0] = gen_lowpart (SImode, operands[0]); 4634 operands[3] = gen_highpart (SImode, operands[1]); 4635 operands[1] = gen_lowpart (SImode, operands[1]); 4636 } 4637 [(set_attr "conds" "set") 4638 (set_attr "length" "8") 4639 (set_attr "type" "multiple")] 4640) 4641 4642(define_expand "negdi2" 4643 [(parallel 4644 [(set (match_operand:DI 0 "s_register_operand" "") 4645 (neg:DI (match_operand:DI 1 "s_register_operand" ""))) 4646 (clobber (reg:CC CC_REGNUM))])] 4647 "TARGET_EITHER" 4648 { 4649 if (TARGET_NEON) 4650 { 4651 emit_insn (gen_negdi2_neon (operands[0], operands[1])); 4652 DONE; 4653 } 4654 } 4655) 4656 4657;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). 4658;; The first alternative allows the common case of a *full* overlap. 4659(define_insn_and_split "*negdi2_insn" 4660 [(set (match_operand:DI 0 "s_register_operand" "=r,&r") 4661 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r"))) 4662 (clobber (reg:CC CC_REGNUM))] 4663 "TARGET_32BIT" 4664 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM) 4665 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2) 4666 "&& reload_completed" 4667 [(parallel [(set (reg:CC CC_REGNUM) 4668 (compare:CC (const_int 0) (match_dup 1))) 4669 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) 4670 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) 4671 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 4672 { 4673 operands[2] = gen_highpart (SImode, operands[0]); 4674 operands[0] = gen_lowpart (SImode, operands[0]); 4675 operands[3] = gen_highpart (SImode, operands[1]); 4676 operands[1] = gen_lowpart (SImode, operands[1]); 4677 } 4678 [(set_attr "conds" "clob") 4679 (set_attr "length" "8") 4680 (set_attr "type" "multiple")] 4681) 4682 4683(define_insn "*negsi2_carryin_compare" 4684 [(set (reg:CC CC_REGNUM) 4685 (compare:CC (const_int 0) 4686 (match_operand:SI 1 "s_register_operand" "r"))) 4687 (set (match_operand:SI 0 "s_register_operand" "=r") 4688 (minus:SI (minus:SI (const_int 0) 4689 (match_dup 1)) 4690 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 4691 "TARGET_ARM" 4692 "rscs\\t%0, %1, #0" 4693 [(set_attr "conds" "set") 4694 (set_attr "type" "alus_imm")] 4695) 4696 4697(define_expand "negsi2" 4698 [(set (match_operand:SI 0 "s_register_operand" "") 4699 (neg:SI (match_operand:SI 1 "s_register_operand" "")))] 4700 "TARGET_EITHER" 4701 "" 4702) 4703 4704(define_insn "*arm_negsi2" 4705 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 4706 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))] 4707 "TARGET_32BIT" 4708 "rsb%?\\t%0, %1, #0" 4709 [(set_attr "predicable" "yes") 4710 (set_attr "predicable_short_it" "yes,no") 4711 (set_attr "arch" "t2,*") 4712 (set_attr "length" "4") 4713 (set_attr "type" "alu_sreg")] 4714) 4715 4716(define_expand "negsf2" 4717 [(set (match_operand:SF 0 "s_register_operand" "") 4718 (neg:SF (match_operand:SF 1 "s_register_operand" "")))] 4719 "TARGET_32BIT && TARGET_HARD_FLOAT" 4720 "" 4721) 4722 4723(define_expand "negdf2" 4724 [(set (match_operand:DF 0 "s_register_operand" "") 4725 (neg:DF (match_operand:DF 1 "s_register_operand" "")))] 4726 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 4727 "") 4728 4729(define_insn_and_split "*zextendsidi_negsi" 4730 [(set (match_operand:DI 0 "s_register_operand" "=r") 4731 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))] 4732 "TARGET_32BIT" 4733 "#" 4734 "" 4735 [(set (match_dup 2) 4736 (neg:SI (match_dup 1))) 4737 (set (match_dup 3) 4738 (const_int 0))] 4739 { 4740 operands[2] = gen_lowpart (SImode, operands[0]); 4741 operands[3] = gen_highpart (SImode, operands[0]); 4742 } 4743 [(set_attr "length" "8") 4744 (set_attr "type" "multiple")] 4745) 4746 4747;; Negate an extended 32-bit value. 4748(define_insn_and_split "*negdi_extendsidi" 4749 [(set (match_operand:DI 0 "s_register_operand" "=l,r") 4750 (neg:DI (sign_extend:DI 4751 (match_operand:SI 1 "s_register_operand" "l,r")))) 4752 (clobber (reg:CC CC_REGNUM))] 4753 "TARGET_32BIT" 4754 "#" 4755 "&& reload_completed" 4756 [(const_int 0)] 4757 { 4758 rtx low = gen_lowpart (SImode, operands[0]); 4759 rtx high = gen_highpart (SImode, operands[0]); 4760 4761 if (reg_overlap_mentioned_p (low, operands[1])) 4762 { 4763 /* Input overlaps the low word of the output. Use: 4764 asr Rhi, Rin, #31 4765 rsbs Rlo, Rin, #0 4766 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */ 4767 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM); 4768 4769 emit_insn (gen_rtx_SET (high, 4770 gen_rtx_ASHIFTRT (SImode, operands[1], 4771 GEN_INT (31)))); 4772 4773 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1])); 4774 if (TARGET_ARM) 4775 emit_insn (gen_rtx_SET (high, 4776 gen_rtx_MINUS (SImode, 4777 gen_rtx_MINUS (SImode, 4778 const0_rtx, 4779 high), 4780 gen_rtx_LTU (SImode, 4781 cc_reg, 4782 const0_rtx)))); 4783 else 4784 { 4785 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1)); 4786 emit_insn (gen_rtx_SET (high, 4787 gen_rtx_MINUS (SImode, 4788 gen_rtx_MINUS (SImode, 4789 high, 4790 two_x), 4791 gen_rtx_LTU (SImode, 4792 cc_reg, 4793 const0_rtx)))); 4794 } 4795 } 4796 else 4797 { 4798 /* No overlap, or overlap on high word. Use: 4799 rsb Rlo, Rin, #0 4800 bic Rhi, Rlo, Rin 4801 asr Rhi, Rhi, #31 4802 Flags not needed for this sequence. */ 4803 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1]))); 4804 emit_insn (gen_rtx_SET (high, 4805 gen_rtx_AND (SImode, 4806 gen_rtx_NOT (SImode, operands[1]), 4807 low))); 4808 emit_insn (gen_rtx_SET (high, 4809 gen_rtx_ASHIFTRT (SImode, high, 4810 GEN_INT (31)))); 4811 } 4812 DONE; 4813 } 4814 [(set_attr "length" "12") 4815 (set_attr "arch" "t2,*") 4816 (set_attr "type" "multiple")] 4817) 4818 4819(define_insn_and_split "*negdi_zero_extendsidi" 4820 [(set (match_operand:DI 0 "s_register_operand" "=r,&r") 4821 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r")))) 4822 (clobber (reg:CC CC_REGNUM))] 4823 "TARGET_32BIT" 4824 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0" 4825 ;; Don't care what register is input to sbc, 4826 ;; since we just need to propagate the carry. 4827 "&& reload_completed" 4828 [(parallel [(set (reg:CC CC_REGNUM) 4829 (compare:CC (const_int 0) (match_dup 1))) 4830 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) 4831 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2)) 4832 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 4833 { 4834 operands[2] = gen_highpart (SImode, operands[0]); 4835 operands[0] = gen_lowpart (SImode, operands[0]); 4836 } 4837 [(set_attr "conds" "clob") 4838 (set_attr "length" "8") 4839 (set_attr "type" "multiple")] ;; length in thumb is 4 4840) 4841 4842;; abssi2 doesn't really clobber the condition codes if a different register 4843;; is being set. To keep things simple, assume during rtl manipulations that 4844;; it does, but tell the final scan operator the truth. Similarly for 4845;; (neg (abs...)) 4846 4847(define_expand "abssi2" 4848 [(parallel 4849 [(set (match_operand:SI 0 "s_register_operand" "") 4850 (abs:SI (match_operand:SI 1 "s_register_operand" ""))) 4851 (clobber (match_dup 2))])] 4852 "TARGET_EITHER" 4853 " 4854 if (TARGET_THUMB1) 4855 operands[2] = gen_rtx_SCRATCH (SImode); 4856 else 4857 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM); 4858") 4859 4860(define_insn_and_split "*arm_abssi2" 4861 [(set (match_operand:SI 0 "s_register_operand" "=r,&r") 4862 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))) 4863 (clobber (reg:CC CC_REGNUM))] 4864 "TARGET_ARM" 4865 "#" 4866 "&& reload_completed" 4867 [(const_int 0)] 4868 { 4869 /* if (which_alternative == 0) */ 4870 if (REGNO(operands[0]) == REGNO(operands[1])) 4871 { 4872 /* Emit the pattern: 4873 cmp\\t%0, #0\;rsblt\\t%0, %0, #0 4874 [(set (reg:CC CC_REGNUM) 4875 (compare:CC (match_dup 0) (const_int 0))) 4876 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0)) 4877 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))] 4878 */ 4879 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM), 4880 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); 4881 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 4882 (gen_rtx_LT (SImode, 4883 gen_rtx_REG (CCmode, CC_REGNUM), 4884 const0_rtx)), 4885 (gen_rtx_SET (operands[0], 4886 (gen_rtx_MINUS (SImode, 4887 const0_rtx, 4888 operands[1])))))); 4889 DONE; 4890 } 4891 else 4892 { 4893 /* Emit the pattern: 4894 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31 4895 [(set (match_dup 0) 4896 (xor:SI (match_dup 1) 4897 (ashiftrt:SI (match_dup 1) (const_int 31)))) 4898 (set (match_dup 0) 4899 (minus:SI (match_dup 0) 4900 (ashiftrt:SI (match_dup 1) (const_int 31))))] 4901 */ 4902 emit_insn (gen_rtx_SET (operands[0], 4903 gen_rtx_XOR (SImode, 4904 gen_rtx_ASHIFTRT (SImode, 4905 operands[1], 4906 GEN_INT (31)), 4907 operands[1]))); 4908 emit_insn (gen_rtx_SET (operands[0], 4909 gen_rtx_MINUS (SImode, 4910 operands[0], 4911 gen_rtx_ASHIFTRT (SImode, 4912 operands[1], 4913 GEN_INT (31))))); 4914 DONE; 4915 } 4916 } 4917 [(set_attr "conds" "clob,*") 4918 (set_attr "shift" "1") 4919 (set_attr "predicable" "no, yes") 4920 (set_attr "length" "8") 4921 (set_attr "type" "multiple")] 4922) 4923 4924(define_insn_and_split "*arm_neg_abssi2" 4925 [(set (match_operand:SI 0 "s_register_operand" "=r,&r") 4926 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))) 4927 (clobber (reg:CC CC_REGNUM))] 4928 "TARGET_ARM" 4929 "#" 4930 "&& reload_completed" 4931 [(const_int 0)] 4932 { 4933 /* if (which_alternative == 0) */ 4934 if (REGNO (operands[0]) == REGNO (operands[1])) 4935 { 4936 /* Emit the pattern: 4937 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0 4938 */ 4939 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM), 4940 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); 4941 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 4942 gen_rtx_GT (SImode, 4943 gen_rtx_REG (CCmode, CC_REGNUM), 4944 const0_rtx), 4945 gen_rtx_SET (operands[0], 4946 (gen_rtx_MINUS (SImode, 4947 const0_rtx, 4948 operands[1]))))); 4949 } 4950 else 4951 { 4952 /* Emit the pattern: 4953 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31 4954 */ 4955 emit_insn (gen_rtx_SET (operands[0], 4956 gen_rtx_XOR (SImode, 4957 gen_rtx_ASHIFTRT (SImode, 4958 operands[1], 4959 GEN_INT (31)), 4960 operands[1]))); 4961 emit_insn (gen_rtx_SET (operands[0], 4962 gen_rtx_MINUS (SImode, 4963 gen_rtx_ASHIFTRT (SImode, 4964 operands[1], 4965 GEN_INT (31)), 4966 operands[0]))); 4967 } 4968 DONE; 4969 } 4970 [(set_attr "conds" "clob,*") 4971 (set_attr "shift" "1") 4972 (set_attr "predicable" "no, yes") 4973 (set_attr "length" "8") 4974 (set_attr "type" "multiple")] 4975) 4976 4977(define_expand "abssf2" 4978 [(set (match_operand:SF 0 "s_register_operand" "") 4979 (abs:SF (match_operand:SF 1 "s_register_operand" "")))] 4980 "TARGET_32BIT && TARGET_HARD_FLOAT" 4981 "") 4982 4983(define_expand "absdf2" 4984 [(set (match_operand:DF 0 "s_register_operand" "") 4985 (abs:DF (match_operand:DF 1 "s_register_operand" "")))] 4986 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 4987 "") 4988 4989(define_expand "sqrtsf2" 4990 [(set (match_operand:SF 0 "s_register_operand" "") 4991 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))] 4992 "TARGET_32BIT && TARGET_HARD_FLOAT" 4993 "") 4994 4995(define_expand "sqrtdf2" 4996 [(set (match_operand:DF 0 "s_register_operand" "") 4997 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))] 4998 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 4999 "") 5000 5001(define_expand "one_cmpldi2" 5002 [(set (match_operand:DI 0 "s_register_operand" "") 5003 (not:DI (match_operand:DI 1 "s_register_operand" "")))] 5004 "TARGET_32BIT" 5005 " 5006 if (!TARGET_NEON && !TARGET_IWMMXT) 5007 { 5008 rtx low = simplify_gen_unary (NOT, SImode, 5009 gen_lowpart (SImode, operands[1]), 5010 SImode); 5011 rtx high = simplify_gen_unary (NOT, SImode, 5012 gen_highpart_mode (SImode, DImode, 5013 operands[1]), 5014 SImode); 5015 5016 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); 5017 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); 5018 5019 DONE; 5020 } 5021 /* Otherwise expand pattern as above. */ 5022 " 5023) 5024 5025(define_insn_and_split "*one_cmpldi2_insn" 5026 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w") 5027 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))] 5028 "TARGET_32BIT" 5029 "@ 5030 vmvn\t%P0, %P1 5031 # 5032 # 5033 vmvn\t%P0, %P1" 5034 "TARGET_32BIT && reload_completed 5035 && arm_general_register_operand (operands[0], DImode)" 5036 [(set (match_dup 0) (not:SI (match_dup 1))) 5037 (set (match_dup 2) (not:SI (match_dup 3)))] 5038 " 5039 { 5040 operands[2] = gen_highpart (SImode, operands[0]); 5041 operands[0] = gen_lowpart (SImode, operands[0]); 5042 operands[3] = gen_highpart (SImode, operands[1]); 5043 operands[1] = gen_lowpart (SImode, operands[1]); 5044 }" 5045 [(set_attr "length" "*,8,8,*") 5046 (set_attr "predicable" "no,yes,yes,no") 5047 (set_attr "type" "neon_move,multiple,multiple,neon_move") 5048 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")] 5049) 5050 5051(define_expand "one_cmplsi2" 5052 [(set (match_operand:SI 0 "s_register_operand" "") 5053 (not:SI (match_operand:SI 1 "s_register_operand" "")))] 5054 "TARGET_EITHER" 5055 "" 5056) 5057 5058(define_insn "*arm_one_cmplsi2" 5059 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 5060 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))] 5061 "TARGET_32BIT" 5062 "mvn%?\\t%0, %1" 5063 [(set_attr "predicable" "yes") 5064 (set_attr "predicable_short_it" "yes,no") 5065 (set_attr "arch" "t2,*") 5066 (set_attr "length" "4") 5067 (set_attr "type" "mvn_reg")] 5068) 5069 5070(define_insn "*notsi_compare0" 5071 [(set (reg:CC_NOOV CC_REGNUM) 5072 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) 5073 (const_int 0))) 5074 (set (match_operand:SI 0 "s_register_operand" "=r") 5075 (not:SI (match_dup 1)))] 5076 "TARGET_32BIT" 5077 "mvns%?\\t%0, %1" 5078 [(set_attr "conds" "set") 5079 (set_attr "type" "mvn_reg")] 5080) 5081 5082(define_insn "*notsi_compare0_scratch" 5083 [(set (reg:CC_NOOV CC_REGNUM) 5084 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) 5085 (const_int 0))) 5086 (clobber (match_scratch:SI 0 "=r"))] 5087 "TARGET_32BIT" 5088 "mvns%?\\t%0, %1" 5089 [(set_attr "conds" "set") 5090 (set_attr "type" "mvn_reg")] 5091) 5092 5093;; Fixed <--> Floating conversion insns 5094 5095(define_expand "floatsihf2" 5096 [(set (match_operand:HF 0 "general_operand" "") 5097 (float:HF (match_operand:SI 1 "general_operand" "")))] 5098 "TARGET_EITHER" 5099 " 5100 { 5101 rtx op1 = gen_reg_rtx (SFmode); 5102 expand_float (op1, operands[1], 0); 5103 op1 = convert_to_mode (HFmode, op1, 0); 5104 emit_move_insn (operands[0], op1); 5105 DONE; 5106 }" 5107) 5108 5109(define_expand "floatdihf2" 5110 [(set (match_operand:HF 0 "general_operand" "") 5111 (float:HF (match_operand:DI 1 "general_operand" "")))] 5112 "TARGET_EITHER" 5113 " 5114 { 5115 rtx op1 = gen_reg_rtx (SFmode); 5116 expand_float (op1, operands[1], 0); 5117 op1 = convert_to_mode (HFmode, op1, 0); 5118 emit_move_insn (operands[0], op1); 5119 DONE; 5120 }" 5121) 5122 5123(define_expand "floatsisf2" 5124 [(set (match_operand:SF 0 "s_register_operand" "") 5125 (float:SF (match_operand:SI 1 "s_register_operand" "")))] 5126 "TARGET_32BIT && TARGET_HARD_FLOAT" 5127 " 5128") 5129 5130(define_expand "floatsidf2" 5131 [(set (match_operand:DF 0 "s_register_operand" "") 5132 (float:DF (match_operand:SI 1 "s_register_operand" "")))] 5133 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5134 " 5135") 5136 5137(define_expand "fix_trunchfsi2" 5138 [(set (match_operand:SI 0 "general_operand" "") 5139 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))] 5140 "TARGET_EITHER" 5141 " 5142 { 5143 rtx op1 = convert_to_mode (SFmode, operands[1], 0); 5144 expand_fix (operands[0], op1, 0); 5145 DONE; 5146 }" 5147) 5148 5149(define_expand "fix_trunchfdi2" 5150 [(set (match_operand:DI 0 "general_operand" "") 5151 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))] 5152 "TARGET_EITHER" 5153 " 5154 { 5155 rtx op1 = convert_to_mode (SFmode, operands[1], 0); 5156 expand_fix (operands[0], op1, 0); 5157 DONE; 5158 }" 5159) 5160 5161(define_expand "fix_truncsfsi2" 5162 [(set (match_operand:SI 0 "s_register_operand" "") 5163 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))] 5164 "TARGET_32BIT && TARGET_HARD_FLOAT" 5165 " 5166") 5167 5168(define_expand "fix_truncdfsi2" 5169 [(set (match_operand:SI 0 "s_register_operand" "") 5170 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))] 5171 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5172 " 5173") 5174 5175;; Truncation insns 5176 5177(define_expand "truncdfsf2" 5178 [(set (match_operand:SF 0 "s_register_operand" "") 5179 (float_truncate:SF 5180 (match_operand:DF 1 "s_register_operand" "")))] 5181 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5182 "" 5183) 5184 5185;; DFmode to HFmode conversions on targets without a single-step hardware 5186;; instruction for it would have to go through SFmode. This is dangerous 5187;; as it introduces double rounding. 5188;; 5189;; Disable this pattern unless we are in an unsafe math mode, or we have 5190;; a single-step instruction. 5191 5192(define_expand "truncdfhf2" 5193 [(set (match_operand:HF 0 "s_register_operand" "") 5194 (float_truncate:HF 5195 (match_operand:DF 1 "s_register_operand" "")))] 5196 "(TARGET_EITHER && flag_unsafe_math_optimizations) 5197 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)" 5198{ 5199 /* We don't have a direct instruction for this, so we must be in 5200 an unsafe math mode, and going via SFmode. */ 5201 5202 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE)) 5203 { 5204 rtx op1; 5205 op1 = convert_to_mode (SFmode, operands[1], 0); 5206 op1 = convert_to_mode (HFmode, op1, 0); 5207 emit_move_insn (operands[0], op1); 5208 DONE; 5209 } 5210 /* Otherwise, we will pick this up as a single instruction with 5211 no intermediary rounding. */ 5212} 5213) 5214 5215;; Zero and sign extension instructions. 5216 5217(define_insn "zero_extend<mode>di2" 5218 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w") 5219 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>" 5220 "<qhs_zextenddi_cstr>")))] 5221 "TARGET_32BIT <qhs_zextenddi_cond>" 5222 "#" 5223 [(set_attr "length" "8,4,8,8") 5224 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits") 5225 (set_attr "ce_count" "2") 5226 (set_attr "predicable" "yes") 5227 (set_attr "type" "multiple,mov_reg,multiple,multiple")] 5228) 5229 5230(define_insn "extend<mode>di2" 5231 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w") 5232 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>" 5233 "<qhs_extenddi_cstr>")))] 5234 "TARGET_32BIT <qhs_sextenddi_cond>" 5235 "#" 5236 [(set_attr "length" "8,4,8,8,8") 5237 (set_attr "ce_count" "2") 5238 (set_attr "shift" "1") 5239 (set_attr "predicable" "yes") 5240 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits") 5241 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")] 5242) 5243 5244;; Splits for all extensions to DImode 5245(define_split 5246 [(set (match_operand:DI 0 "s_register_operand" "") 5247 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))] 5248 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))" 5249 [(set (match_dup 0) (match_dup 1))] 5250{ 5251 rtx lo_part = gen_lowpart (SImode, operands[0]); 5252 machine_mode src_mode = GET_MODE (operands[1]); 5253 5254 if (REG_P (operands[0]) 5255 && !reg_overlap_mentioned_p (operands[0], operands[1])) 5256 emit_clobber (operands[0]); 5257 if (!REG_P (lo_part) || src_mode != SImode 5258 || !rtx_equal_p (lo_part, operands[1])) 5259 { 5260 if (src_mode == SImode) 5261 emit_move_insn (lo_part, operands[1]); 5262 else 5263 emit_insn (gen_rtx_SET (lo_part, 5264 gen_rtx_ZERO_EXTEND (SImode, operands[1]))); 5265 operands[1] = lo_part; 5266 } 5267 operands[0] = gen_highpart (SImode, operands[0]); 5268 operands[1] = const0_rtx; 5269}) 5270 5271(define_split 5272 [(set (match_operand:DI 0 "s_register_operand" "") 5273 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))] 5274 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))" 5275 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))] 5276{ 5277 rtx lo_part = gen_lowpart (SImode, operands[0]); 5278 machine_mode src_mode = GET_MODE (operands[1]); 5279 5280 if (REG_P (operands[0]) 5281 && !reg_overlap_mentioned_p (operands[0], operands[1])) 5282 emit_clobber (operands[0]); 5283 5284 if (!REG_P (lo_part) || src_mode != SImode 5285 || !rtx_equal_p (lo_part, operands[1])) 5286 { 5287 if (src_mode == SImode) 5288 emit_move_insn (lo_part, operands[1]); 5289 else 5290 emit_insn (gen_rtx_SET (lo_part, 5291 gen_rtx_SIGN_EXTEND (SImode, operands[1]))); 5292 operands[1] = lo_part; 5293 } 5294 operands[0] = gen_highpart (SImode, operands[0]); 5295}) 5296 5297(define_expand "zero_extendhisi2" 5298 [(set (match_operand:SI 0 "s_register_operand" "") 5299 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 5300 "TARGET_EITHER" 5301{ 5302 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1])) 5303 { 5304 emit_insn (gen_movhi_bytes (operands[0], operands[1])); 5305 DONE; 5306 } 5307 if (!arm_arch6 && !MEM_P (operands[1])) 5308 { 5309 rtx t = gen_lowpart (SImode, operands[1]); 5310 rtx tmp = gen_reg_rtx (SImode); 5311 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16))); 5312 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16))); 5313 DONE; 5314 } 5315}) 5316 5317(define_split 5318 [(set (match_operand:SI 0 "s_register_operand" "") 5319 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))] 5320 "!TARGET_THUMB2 && !arm_arch6" 5321 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 5322 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))] 5323{ 5324 operands[2] = gen_lowpart (SImode, operands[1]); 5325}) 5326 5327(define_insn "*arm_zero_extendhisi2" 5328 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5329 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 5330 "TARGET_ARM && arm_arch4 && !arm_arch6" 5331 "@ 5332 # 5333 ldrh%?\\t%0, %1" 5334 [(set_attr "type" "alu_shift_reg,load_byte") 5335 (set_attr "predicable" "yes")] 5336) 5337 5338(define_insn "*arm_zero_extendhisi2_v6" 5339 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5340 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))] 5341 "TARGET_ARM && arm_arch6" 5342 "@ 5343 uxth%?\\t%0, %1 5344 ldrh%?\\t%0, %1" 5345 [(set_attr "predicable" "yes") 5346 (set_attr "type" "extend,load_byte")] 5347) 5348 5349(define_insn "*arm_zero_extendhisi2addsi" 5350 [(set (match_operand:SI 0 "s_register_operand" "=r") 5351 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r")) 5352 (match_operand:SI 2 "s_register_operand" "r")))] 5353 "TARGET_INT_SIMD" 5354 "uxtah%?\\t%0, %2, %1" 5355 [(set_attr "type" "alu_shift_reg") 5356 (set_attr "predicable" "yes")] 5357) 5358 5359(define_expand "zero_extendqisi2" 5360 [(set (match_operand:SI 0 "s_register_operand" "") 5361 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 5362 "TARGET_EITHER" 5363{ 5364 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1])) 5365 { 5366 emit_insn (gen_andsi3 (operands[0], 5367 gen_lowpart (SImode, operands[1]), 5368 GEN_INT (255))); 5369 DONE; 5370 } 5371 if (!arm_arch6 && !MEM_P (operands[1])) 5372 { 5373 rtx t = gen_lowpart (SImode, operands[1]); 5374 rtx tmp = gen_reg_rtx (SImode); 5375 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24))); 5376 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24))); 5377 DONE; 5378 } 5379}) 5380 5381(define_split 5382 [(set (match_operand:SI 0 "s_register_operand" "") 5383 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))] 5384 "!arm_arch6" 5385 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24))) 5386 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))] 5387{ 5388 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0); 5389 if (TARGET_ARM) 5390 { 5391 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255))); 5392 DONE; 5393 } 5394}) 5395 5396(define_insn "*arm_zero_extendqisi2" 5397 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5398 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 5399 "TARGET_ARM && !arm_arch6" 5400 "@ 5401 # 5402 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2" 5403 [(set_attr "length" "8,4") 5404 (set_attr "type" "alu_shift_reg,load_byte") 5405 (set_attr "predicable" "yes")] 5406) 5407 5408(define_insn "*arm_zero_extendqisi2_v6" 5409 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5410 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))] 5411 "TARGET_ARM && arm_arch6" 5412 "@ 5413 uxtb%?\\t%0, %1 5414 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2" 5415 [(set_attr "type" "extend,load_byte") 5416 (set_attr "predicable" "yes")] 5417) 5418 5419(define_insn "*arm_zero_extendqisi2addsi" 5420 [(set (match_operand:SI 0 "s_register_operand" "=r") 5421 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r")) 5422 (match_operand:SI 2 "s_register_operand" "r")))] 5423 "TARGET_INT_SIMD" 5424 "uxtab%?\\t%0, %2, %1" 5425 [(set_attr "predicable" "yes") 5426 (set_attr "type" "alu_shift_reg")] 5427) 5428 5429(define_split 5430 [(set (match_operand:SI 0 "s_register_operand" "") 5431 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0))) 5432 (clobber (match_operand:SI 2 "s_register_operand" ""))] 5433 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN" 5434 [(set (match_dup 2) (match_dup 1)) 5435 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))] 5436 "" 5437) 5438 5439(define_split 5440 [(set (match_operand:SI 0 "s_register_operand" "") 5441 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3))) 5442 (clobber (match_operand:SI 2 "s_register_operand" ""))] 5443 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN" 5444 [(set (match_dup 2) (match_dup 1)) 5445 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))] 5446 "" 5447) 5448 5449 5450(define_split 5451 [(set (match_operand:SI 0 "s_register_operand" "") 5452 (IOR_XOR:SI (and:SI (ashift:SI 5453 (match_operand:SI 1 "s_register_operand" "") 5454 (match_operand:SI 2 "const_int_operand" "")) 5455 (match_operand:SI 3 "const_int_operand" "")) 5456 (zero_extend:SI 5457 (match_operator 5 "subreg_lowpart_operator" 5458 [(match_operand:SI 4 "s_register_operand" "")]))))] 5459 "TARGET_32BIT 5460 && (UINTVAL (operands[3]) 5461 == (GET_MODE_MASK (GET_MODE (operands[5])) 5462 & (GET_MODE_MASK (GET_MODE (operands[5])) 5463 << (INTVAL (operands[2])))))" 5464 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2)) 5465 (match_dup 4))) 5466 (set (match_dup 0) (zero_extend:SI (match_dup 5)))] 5467 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);" 5468) 5469 5470(define_insn "*compareqi_eq0" 5471 [(set (reg:CC_Z CC_REGNUM) 5472 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r") 5473 (const_int 0)))] 5474 "TARGET_32BIT" 5475 "tst%?\\t%0, #255" 5476 [(set_attr "conds" "set") 5477 (set_attr "predicable" "yes") 5478 (set_attr "type" "logic_imm")] 5479) 5480 5481(define_expand "extendhisi2" 5482 [(set (match_operand:SI 0 "s_register_operand" "") 5483 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 5484 "TARGET_EITHER" 5485{ 5486 if (TARGET_THUMB1) 5487 { 5488 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1])); 5489 DONE; 5490 } 5491 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4) 5492 { 5493 emit_insn (gen_extendhisi2_mem (operands[0], operands[1])); 5494 DONE; 5495 } 5496 5497 if (!arm_arch6 && !MEM_P (operands[1])) 5498 { 5499 rtx t = gen_lowpart (SImode, operands[1]); 5500 rtx tmp = gen_reg_rtx (SImode); 5501 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16))); 5502 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16))); 5503 DONE; 5504 } 5505}) 5506 5507(define_split 5508 [(parallel 5509 [(set (match_operand:SI 0 "register_operand" "") 5510 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))) 5511 (clobber (match_scratch:SI 2 ""))])] 5512 "!arm_arch6" 5513 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 5514 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))] 5515{ 5516 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 5517}) 5518 5519;; This pattern will only be used when ldsh is not available 5520(define_expand "extendhisi2_mem" 5521 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" ""))) 5522 (set (match_dup 3) 5523 (zero_extend:SI (match_dup 7))) 5524 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24))) 5525 (set (match_operand:SI 0 "" "") 5526 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))] 5527 "TARGET_ARM" 5528 " 5529 { 5530 rtx mem1, mem2; 5531 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 5532 5533 mem1 = change_address (operands[1], QImode, addr); 5534 mem2 = change_address (operands[1], QImode, 5535 plus_constant (Pmode, addr, 1)); 5536 operands[0] = gen_lowpart (SImode, operands[0]); 5537 operands[1] = mem1; 5538 operands[2] = gen_reg_rtx (SImode); 5539 operands[3] = gen_reg_rtx (SImode); 5540 operands[6] = gen_reg_rtx (SImode); 5541 operands[7] = mem2; 5542 5543 if (BYTES_BIG_ENDIAN) 5544 { 5545 operands[4] = operands[2]; 5546 operands[5] = operands[3]; 5547 } 5548 else 5549 { 5550 operands[4] = operands[3]; 5551 operands[5] = operands[2]; 5552 } 5553 }" 5554) 5555 5556(define_split 5557 [(set (match_operand:SI 0 "register_operand" "") 5558 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 5559 "!arm_arch6" 5560 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 5561 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))] 5562{ 5563 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 5564}) 5565 5566(define_insn "*arm_extendhisi2" 5567 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5568 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))] 5569 "TARGET_ARM && arm_arch4 && !arm_arch6" 5570 "@ 5571 # 5572 ldrsh%?\\t%0, %1" 5573 [(set_attr "length" "8,4") 5574 (set_attr "type" "alu_shift_reg,load_byte") 5575 (set_attr "predicable" "yes")] 5576) 5577 5578;; ??? Check Thumb-2 pool range 5579(define_insn "*arm_extendhisi2_v6" 5580 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5581 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))] 5582 "TARGET_32BIT && arm_arch6" 5583 "@ 5584 sxth%?\\t%0, %1 5585 ldrsh%?\\t%0, %1" 5586 [(set_attr "type" "extend,load_byte") 5587 (set_attr "predicable" "yes")] 5588) 5589 5590(define_insn "*arm_extendhisi2addsi" 5591 [(set (match_operand:SI 0 "s_register_operand" "=r") 5592 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r")) 5593 (match_operand:SI 2 "s_register_operand" "r")))] 5594 "TARGET_INT_SIMD" 5595 "sxtah%?\\t%0, %2, %1" 5596 [(set_attr "type" "alu_shift_reg")] 5597) 5598 5599(define_expand "extendqihi2" 5600 [(set (match_dup 2) 5601 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "") 5602 (const_int 24))) 5603 (set (match_operand:HI 0 "s_register_operand" "") 5604 (ashiftrt:SI (match_dup 2) 5605 (const_int 24)))] 5606 "TARGET_ARM" 5607 " 5608 { 5609 if (arm_arch4 && MEM_P (operands[1])) 5610 { 5611 emit_insn (gen_rtx_SET (operands[0], 5612 gen_rtx_SIGN_EXTEND (HImode, operands[1]))); 5613 DONE; 5614 } 5615 if (!s_register_operand (operands[1], QImode)) 5616 operands[1] = copy_to_mode_reg (QImode, operands[1]); 5617 operands[0] = gen_lowpart (SImode, operands[0]); 5618 operands[1] = gen_lowpart (SImode, operands[1]); 5619 operands[2] = gen_reg_rtx (SImode); 5620 }" 5621) 5622 5623(define_insn "*arm_extendqihi_insn" 5624 [(set (match_operand:HI 0 "s_register_operand" "=r") 5625 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))] 5626 "TARGET_ARM && arm_arch4" 5627 "ldrsb%?\\t%0, %1" 5628 [(set_attr "type" "load_byte") 5629 (set_attr "predicable" "yes")] 5630) 5631 5632(define_expand "extendqisi2" 5633 [(set (match_operand:SI 0 "s_register_operand" "") 5634 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))] 5635 "TARGET_EITHER" 5636{ 5637 if (!arm_arch4 && MEM_P (operands[1])) 5638 operands[1] = copy_to_mode_reg (QImode, operands[1]); 5639 5640 if (!arm_arch6 && !MEM_P (operands[1])) 5641 { 5642 rtx t = gen_lowpart (SImode, operands[1]); 5643 rtx tmp = gen_reg_rtx (SImode); 5644 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24))); 5645 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24))); 5646 DONE; 5647 } 5648}) 5649 5650(define_split 5651 [(set (match_operand:SI 0 "register_operand" "") 5652 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] 5653 "!arm_arch6" 5654 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24))) 5655 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))] 5656{ 5657 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0); 5658}) 5659 5660(define_insn "*arm_extendqisi" 5661 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5662 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))] 5663 "TARGET_ARM && arm_arch4 && !arm_arch6" 5664 "@ 5665 # 5666 ldrsb%?\\t%0, %1" 5667 [(set_attr "length" "8,4") 5668 (set_attr "type" "alu_shift_reg,load_byte") 5669 (set_attr "predicable" "yes")] 5670) 5671 5672(define_insn "*arm_extendqisi_v6" 5673 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5674 (sign_extend:SI 5675 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))] 5676 "TARGET_ARM && arm_arch6" 5677 "@ 5678 sxtb%?\\t%0, %1 5679 ldrsb%?\\t%0, %1" 5680 [(set_attr "type" "extend,load_byte") 5681 (set_attr "predicable" "yes")] 5682) 5683 5684(define_insn "*arm_extendqisi2addsi" 5685 [(set (match_operand:SI 0 "s_register_operand" "=r") 5686 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r")) 5687 (match_operand:SI 2 "s_register_operand" "r")))] 5688 "TARGET_INT_SIMD" 5689 "sxtab%?\\t%0, %2, %1" 5690 [(set_attr "type" "alu_shift_reg") 5691 (set_attr "predicable" "yes")] 5692) 5693 5694(define_expand "extendsfdf2" 5695 [(set (match_operand:DF 0 "s_register_operand" "") 5696 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))] 5697 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5698 "" 5699) 5700 5701;; HFmode -> DFmode conversions where we don't have an instruction for it 5702;; must go through SFmode. 5703;; 5704;; This is always safe for an extend. 5705 5706(define_expand "extendhfdf2" 5707 [(set (match_operand:DF 0 "s_register_operand" "") 5708 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))] 5709 "TARGET_EITHER" 5710{ 5711 /* We don't have a direct instruction for this, so go via SFmode. */ 5712 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE)) 5713 { 5714 rtx op1; 5715 op1 = convert_to_mode (SFmode, operands[1], 0); 5716 op1 = convert_to_mode (DFmode, op1, 0); 5717 emit_insn (gen_movdf (operands[0], op1)); 5718 DONE; 5719 } 5720 /* Otherwise, we're done producing RTL and will pick up the correct 5721 pattern to do this with one rounding-step in a single instruction. */ 5722} 5723) 5724 5725;; Move insns (including loads and stores) 5726 5727;; XXX Just some ideas about movti. 5728;; I don't think these are a good idea on the arm, there just aren't enough 5729;; registers 5730;;(define_expand "loadti" 5731;; [(set (match_operand:TI 0 "s_register_operand" "") 5732;; (mem:TI (match_operand:SI 1 "address_operand" "")))] 5733;; "" "") 5734 5735;;(define_expand "storeti" 5736;; [(set (mem:TI (match_operand:TI 0 "address_operand" "")) 5737;; (match_operand:TI 1 "s_register_operand" ""))] 5738;; "" "") 5739 5740;;(define_expand "movti" 5741;; [(set (match_operand:TI 0 "general_operand" "") 5742;; (match_operand:TI 1 "general_operand" ""))] 5743;; "" 5744;; " 5745;;{ 5746;; rtx insn; 5747;; 5748;; if (MEM_P (operands[0]) && MEM_P (operands[1])) 5749;; operands[1] = copy_to_reg (operands[1]); 5750;; if (MEM_P (operands[0])) 5751;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]); 5752;; else if (MEM_P (operands[1])) 5753;; insn = gen_loadti (operands[0], XEXP (operands[1], 0)); 5754;; else 5755;; FAIL; 5756;; 5757;; emit_insn (insn); 5758;; DONE; 5759;;}") 5760 5761;; Recognize garbage generated above. 5762 5763;;(define_insn "" 5764;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m") 5765;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))] 5766;; "" 5767;; "* 5768;; { 5769;; register mem = (which_alternative < 3); 5770;; register const char *template; 5771;; 5772;; operands[mem] = XEXP (operands[mem], 0); 5773;; switch (which_alternative) 5774;; { 5775;; case 0: template = \"ldmdb\\t%1!, %M0\"; break; 5776;; case 1: template = \"ldmia\\t%1!, %M0\"; break; 5777;; case 2: template = \"ldmia\\t%1, %M0\"; break; 5778;; case 3: template = \"stmdb\\t%0!, %M1\"; break; 5779;; case 4: template = \"stmia\\t%0!, %M1\"; break; 5780;; case 5: template = \"stmia\\t%0, %M1\"; break; 5781;; } 5782;; output_asm_insn (template, operands); 5783;; return \"\"; 5784;; }") 5785 5786(define_expand "movdi" 5787 [(set (match_operand:DI 0 "general_operand" "") 5788 (match_operand:DI 1 "general_operand" ""))] 5789 "TARGET_EITHER" 5790 " 5791 if (can_create_pseudo_p ()) 5792 { 5793 if (!REG_P (operands[0])) 5794 operands[1] = force_reg (DImode, operands[1]); 5795 } 5796 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM 5797 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode)) 5798 { 5799 /* Avoid LDRD's into an odd-numbered register pair in ARM state 5800 when expanding function calls. */ 5801 gcc_assert (can_create_pseudo_p ()); 5802 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1])) 5803 { 5804 /* Perform load into legal reg pair first, then move. */ 5805 rtx reg = gen_reg_rtx (DImode); 5806 emit_insn (gen_movdi (reg, operands[1])); 5807 operands[1] = reg; 5808 } 5809 emit_move_insn (gen_lowpart (SImode, operands[0]), 5810 gen_lowpart (SImode, operands[1])); 5811 emit_move_insn (gen_highpart (SImode, operands[0]), 5812 gen_highpart (SImode, operands[1])); 5813 DONE; 5814 } 5815 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM 5816 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode)) 5817 { 5818 /* Avoid STRD's from an odd-numbered register pair in ARM state 5819 when expanding function prologue. */ 5820 gcc_assert (can_create_pseudo_p ()); 5821 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) 5822 ? gen_reg_rtx (DImode) 5823 : operands[0]; 5824 emit_move_insn (gen_lowpart (SImode, split_dest), 5825 gen_lowpart (SImode, operands[1])); 5826 emit_move_insn (gen_highpart (SImode, split_dest), 5827 gen_highpart (SImode, operands[1])); 5828 if (split_dest != operands[0]) 5829 emit_insn (gen_movdi (operands[0], split_dest)); 5830 DONE; 5831 } 5832 " 5833) 5834 5835(define_insn "*arm_movdi" 5836 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m") 5837 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))] 5838 "TARGET_32BIT 5839 && !(TARGET_HARD_FLOAT) 5840 && !TARGET_IWMMXT 5841 && ( register_operand (operands[0], DImode) 5842 || register_operand (operands[1], DImode))" 5843 "* 5844 switch (which_alternative) 5845 { 5846 case 0: 5847 case 1: 5848 case 2: 5849 return \"#\"; 5850 default: 5851 return output_move_double (operands, true, NULL); 5852 } 5853 " 5854 [(set_attr "length" "8,12,16,8,8") 5855 (set_attr "type" "multiple,multiple,multiple,load_8,store_8") 5856 (set_attr "arm_pool_range" "*,*,*,1020,*") 5857 (set_attr "arm_neg_pool_range" "*,*,*,1004,*") 5858 (set_attr "thumb2_pool_range" "*,*,*,4094,*") 5859 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")] 5860) 5861 5862(define_split 5863 [(set (match_operand:ANY64 0 "arm_general_register_operand" "") 5864 (match_operand:ANY64 1 "immediate_operand" ""))] 5865 "TARGET_32BIT 5866 && reload_completed 5867 && (arm_disable_literal_pool 5868 || (arm_const_double_inline_cost (operands[1]) 5869 <= arm_max_const_double_inline_cost ()))" 5870 [(const_int 0)] 5871 " 5872 arm_split_constant (SET, SImode, curr_insn, 5873 INTVAL (gen_lowpart (SImode, operands[1])), 5874 gen_lowpart (SImode, operands[0]), NULL_RTX, 0); 5875 arm_split_constant (SET, SImode, curr_insn, 5876 INTVAL (gen_highpart_mode (SImode, 5877 GET_MODE (operands[0]), 5878 operands[1])), 5879 gen_highpart (SImode, operands[0]), NULL_RTX, 0); 5880 DONE; 5881 " 5882) 5883 5884; If optimizing for size, or if we have load delay slots, then 5885; we want to split the constant into two separate operations. 5886; In both cases this may split a trivial part into a single data op 5887; leaving a single complex constant to load. We can also get longer 5888; offsets in a LDR which means we get better chances of sharing the pool 5889; entries. Finally, we can normally do a better job of scheduling 5890; LDR instructions than we can with LDM. 5891; This pattern will only match if the one above did not. 5892(define_split 5893 [(set (match_operand:ANY64 0 "arm_general_register_operand" "") 5894 (match_operand:ANY64 1 "const_double_operand" ""))] 5895 "TARGET_ARM && reload_completed 5896 && arm_const_double_by_parts (operands[1])" 5897 [(set (match_dup 0) (match_dup 1)) 5898 (set (match_dup 2) (match_dup 3))] 5899 " 5900 operands[2] = gen_highpart (SImode, operands[0]); 5901 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]), 5902 operands[1]); 5903 operands[0] = gen_lowpart (SImode, operands[0]); 5904 operands[1] = gen_lowpart (SImode, operands[1]); 5905 " 5906) 5907 5908(define_split 5909 [(set (match_operand:ANY64 0 "arm_general_register_operand" "") 5910 (match_operand:ANY64 1 "arm_general_register_operand" ""))] 5911 "TARGET_EITHER && reload_completed" 5912 [(set (match_dup 0) (match_dup 1)) 5913 (set (match_dup 2) (match_dup 3))] 5914 " 5915 operands[2] = gen_highpart (SImode, operands[0]); 5916 operands[3] = gen_highpart (SImode, operands[1]); 5917 operands[0] = gen_lowpart (SImode, operands[0]); 5918 operands[1] = gen_lowpart (SImode, operands[1]); 5919 5920 /* Handle a partial overlap. */ 5921 if (rtx_equal_p (operands[0], operands[3])) 5922 { 5923 rtx tmp0 = operands[0]; 5924 rtx tmp1 = operands[1]; 5925 5926 operands[0] = operands[2]; 5927 operands[1] = operands[3]; 5928 operands[2] = tmp0; 5929 operands[3] = tmp1; 5930 } 5931 " 5932) 5933 5934;; We can't actually do base+index doubleword loads if the index and 5935;; destination overlap. Split here so that we at least have chance to 5936;; schedule. 5937(define_split 5938 [(set (match_operand:DI 0 "s_register_operand" "") 5939 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "") 5940 (match_operand:SI 2 "s_register_operand" ""))))] 5941 "TARGET_LDRD 5942 && reg_overlap_mentioned_p (operands[0], operands[1]) 5943 && reg_overlap_mentioned_p (operands[0], operands[2])" 5944 [(set (match_dup 4) 5945 (plus:SI (match_dup 1) 5946 (match_dup 2))) 5947 (set (match_dup 0) 5948 (mem:DI (match_dup 4)))] 5949 " 5950 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0])); 5951 " 5952) 5953 5954(define_expand "movsi" 5955 [(set (match_operand:SI 0 "general_operand" "") 5956 (match_operand:SI 1 "general_operand" ""))] 5957 "TARGET_EITHER" 5958 " 5959 { 5960 rtx base, offset, tmp; 5961 5962 if (TARGET_32BIT || TARGET_HAVE_MOVT) 5963 { 5964 /* Everything except mem = const or mem = mem can be done easily. */ 5965 if (MEM_P (operands[0])) 5966 operands[1] = force_reg (SImode, operands[1]); 5967 if (arm_general_register_operand (operands[0], SImode) 5968 && CONST_INT_P (operands[1]) 5969 && !(const_ok_for_arm (INTVAL (operands[1])) 5970 || const_ok_for_arm (~INTVAL (operands[1])))) 5971 { 5972 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET)) 5973 { 5974 emit_insn (gen_rtx_SET (operands[0], operands[1])); 5975 DONE; 5976 } 5977 else 5978 { 5979 arm_split_constant (SET, SImode, NULL_RTX, 5980 INTVAL (operands[1]), operands[0], NULL_RTX, 5981 optimize && can_create_pseudo_p ()); 5982 DONE; 5983 } 5984 } 5985 } 5986 else /* Target doesn't have MOVT... */ 5987 { 5988 if (can_create_pseudo_p ()) 5989 { 5990 if (!REG_P (operands[0])) 5991 operands[1] = force_reg (SImode, operands[1]); 5992 } 5993 } 5994 5995 split_const (operands[1], &base, &offset); 5996 if (INTVAL (offset) != 0 5997 && targetm.cannot_force_const_mem (SImode, operands[1])) 5998 { 5999 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; 6000 emit_move_insn (tmp, base); 6001 emit_insn (gen_addsi3 (operands[0], tmp, offset)); 6002 DONE; 6003 } 6004 6005 tmp = can_create_pseudo_p () ? NULL_RTX : operands[0]; 6006 6007 /* Recognize the case where operand[1] is a reference to thread-local 6008 data and load its address to a register. Offsets have been split off 6009 already. */ 6010 if (arm_tls_referenced_p (operands[1])) 6011 operands[1] = legitimize_tls_address (operands[1], tmp); 6012 else if (flag_pic 6013 && (CONSTANT_P (operands[1]) 6014 || symbol_mentioned_p (operands[1]) 6015 || label_mentioned_p (operands[1]))) 6016 operands[1] = 6017 legitimize_pic_address (operands[1], SImode, tmp); 6018 } 6019 " 6020) 6021 6022;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and 6023;; LO_SUM adds in the high bits. Fortunately these are opaque operations 6024;; so this does not matter. 6025(define_insn "*arm_movt" 6026 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r") 6027 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6028 (match_operand:SI 2 "general_operand" "i,i")))] 6029 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])" 6030 "@ 6031 movt%?\t%0, #:upper16:%c2 6032 movt\t%0, #:upper16:%c2" 6033 [(set_attr "arch" "32,v8mb") 6034 (set_attr "predicable" "yes") 6035 (set_attr "length" "4") 6036 (set_attr "type" "alu_sreg")] 6037) 6038 6039(define_insn "*arm_movsi_insn" 6040 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m") 6041 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))] 6042 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT 6043 && ( register_operand (operands[0], SImode) 6044 || register_operand (operands[1], SImode))" 6045 "@ 6046 mov%?\\t%0, %1 6047 mov%?\\t%0, %1 6048 mvn%?\\t%0, #%B1 6049 movw%?\\t%0, %1 6050 ldr%?\\t%0, %1 6051 str%?\\t%1, %0" 6052 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4") 6053 (set_attr "predicable" "yes") 6054 (set_attr "arch" "*,*,*,v6t2,*,*") 6055 (set_attr "pool_range" "*,*,*,*,4096,*") 6056 (set_attr "neg_pool_range" "*,*,*,*,4084,*")] 6057) 6058 6059(define_split 6060 [(set (match_operand:SI 0 "arm_general_register_operand" "") 6061 (match_operand:SI 1 "const_int_operand" ""))] 6062 "(TARGET_32BIT || TARGET_HAVE_MOVT) 6063 && (!(const_ok_for_arm (INTVAL (operands[1])) 6064 || const_ok_for_arm (~INTVAL (operands[1]))))" 6065 [(clobber (const_int 0))] 6066 " 6067 arm_split_constant (SET, SImode, NULL_RTX, 6068 INTVAL (operands[1]), operands[0], NULL_RTX, 0); 6069 DONE; 6070 " 6071) 6072 6073;; A normal way to do (symbol + offset) requires three instructions at least 6074;; (depends on how big the offset is) as below: 6075;; movw r0, #:lower16:g 6076;; movw r0, #:upper16:g 6077;; adds r0, #4 6078;; 6079;; A better way would be: 6080;; movw r0, #:lower16:g+4 6081;; movw r0, #:upper16:g+4 6082;; 6083;; The limitation of this way is that the length of offset should be a 16-bit 6084;; signed value, because current assembler only supports REL type relocation for 6085;; such case. If the more powerful RELA type is supported in future, we should 6086;; update this pattern to go with better way. 6087(define_split 6088 [(set (match_operand:SI 0 "arm_general_register_operand" "") 6089 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "") 6090 (match_operand:SI 2 "const_int_operand" ""))))] 6091 "TARGET_THUMB 6092 && TARGET_HAVE_MOVT 6093 && arm_disable_literal_pool 6094 && reload_completed 6095 && GET_CODE (operands[1]) == SYMBOL_REF" 6096 [(clobber (const_int 0))] 6097 " 6098 int offset = INTVAL (operands[2]); 6099 6100 if (offset < -0x8000 || offset > 0x7fff) 6101 { 6102 arm_emit_movpair (operands[0], operands[1]); 6103 emit_insn (gen_rtx_SET (operands[0], 6104 gen_rtx_PLUS (SImode, operands[0], operands[2]))); 6105 } 6106 else 6107 { 6108 rtx op = gen_rtx_CONST (SImode, 6109 gen_rtx_PLUS (SImode, operands[1], operands[2])); 6110 arm_emit_movpair (operands[0], op); 6111 } 6112 " 6113) 6114 6115;; Split symbol_refs at the later stage (after cprop), instead of generating 6116;; movt/movw pair directly at expand. Otherwise corresponding high_sum 6117;; and lo_sum would be merged back into memory load at cprop. However, 6118;; if the default is to prefer movt/movw rather than a load from the constant 6119;; pool, the performance is better. 6120(define_split 6121 [(set (match_operand:SI 0 "arm_general_register_operand" "") 6122 (match_operand:SI 1 "general_operand" ""))] 6123 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF 6124 && !flag_pic && !target_word_relocations 6125 && !arm_tls_referenced_p (operands[1])" 6126 [(clobber (const_int 0))] 6127{ 6128 arm_emit_movpair (operands[0], operands[1]); 6129 DONE; 6130}) 6131 6132;; When generating pic, we need to load the symbol offset into a register. 6133;; So that the optimizer does not confuse this with a normal symbol load 6134;; we use an unspec. The offset will be loaded from a constant pool entry, 6135;; since that is the only type of relocation we can use. 6136 6137;; Wrap calculation of the whole PIC address in a single pattern for the 6138;; benefit of optimizers, particularly, PRE and HOIST. Calculation of 6139;; a PIC address involves two loads from memory, so we want to CSE it 6140;; as often as possible. 6141;; This pattern will be split into one of the pic_load_addr_* patterns 6142;; and a move after GCSE optimizations. 6143;; 6144;; Note: Update arm.c: legitimize_pic_address() when changing this pattern. 6145(define_expand "calculate_pic_address" 6146 [(set (match_operand:SI 0 "register_operand" "") 6147 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "") 6148 (unspec:SI [(match_operand:SI 2 "" "")] 6149 UNSPEC_PIC_SYM))))] 6150 "flag_pic" 6151) 6152 6153;; Split calculate_pic_address into pic_load_addr_* and a move. 6154(define_split 6155 [(set (match_operand:SI 0 "register_operand" "") 6156 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "") 6157 (unspec:SI [(match_operand:SI 2 "" "")] 6158 UNSPEC_PIC_SYM))))] 6159 "flag_pic" 6160 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM)) 6161 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))] 6162 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];" 6163) 6164 6165;; operand1 is the memory address to go into 6166;; pic_load_addr_32bit. 6167;; operand2 is the PIC label to be emitted 6168;; from pic_add_dot_plus_eight. 6169;; We do this to allow hoisting of the entire insn. 6170(define_insn_and_split "pic_load_addr_unified" 6171 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l") 6172 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 6173 (match_operand:SI 2 "" "")] 6174 UNSPEC_PIC_UNIFIED))] 6175 "flag_pic" 6176 "#" 6177 "&& reload_completed" 6178 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM)) 6179 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3) 6180 (match_dup 2)] UNSPEC_PIC_BASE))] 6181 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);" 6182 [(set_attr "type" "load_4,load_4,load_4") 6183 (set_attr "pool_range" "4096,4094,1022") 6184 (set_attr "neg_pool_range" "4084,0,0") 6185 (set_attr "arch" "a,t2,t1") 6186 (set_attr "length" "8,6,4")] 6187) 6188 6189;; The rather odd constraints on the following are to force reload to leave 6190;; the insn alone, and to force the minipool generation pass to then move 6191;; the GOT symbol to memory. 6192 6193(define_insn "pic_load_addr_32bit" 6194 [(set (match_operand:SI 0 "s_register_operand" "=r") 6195 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))] 6196 "TARGET_32BIT && flag_pic" 6197 "ldr%?\\t%0, %1" 6198 [(set_attr "type" "load_4") 6199 (set (attr "pool_range") 6200 (if_then_else (eq_attr "is_thumb" "no") 6201 (const_int 4096) 6202 (const_int 4094))) 6203 (set (attr "neg_pool_range") 6204 (if_then_else (eq_attr "is_thumb" "no") 6205 (const_int 4084) 6206 (const_int 0)))] 6207) 6208 6209(define_insn "pic_load_addr_thumb1" 6210 [(set (match_operand:SI 0 "s_register_operand" "=l") 6211 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))] 6212 "TARGET_THUMB1 && flag_pic" 6213 "ldr\\t%0, %1" 6214 [(set_attr "type" "load_4") 6215 (set (attr "pool_range") (const_int 1018))] 6216) 6217 6218(define_insn "pic_add_dot_plus_four" 6219 [(set (match_operand:SI 0 "register_operand" "=r") 6220 (unspec:SI [(match_operand:SI 1 "register_operand" "0") 6221 (const_int 4) 6222 (match_operand 2 "" "")] 6223 UNSPEC_PIC_BASE))] 6224 "TARGET_THUMB" 6225 "* 6226 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\", 6227 INTVAL (operands[2])); 6228 return \"add\\t%0, %|pc\"; 6229 " 6230 [(set_attr "length" "2") 6231 (set_attr "type" "alu_sreg")] 6232) 6233 6234(define_insn "pic_add_dot_plus_eight" 6235 [(set (match_operand:SI 0 "register_operand" "=r") 6236 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 6237 (const_int 8) 6238 (match_operand 2 "" "")] 6239 UNSPEC_PIC_BASE))] 6240 "TARGET_ARM" 6241 "* 6242 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\", 6243 INTVAL (operands[2])); 6244 return \"add%?\\t%0, %|pc, %1\"; 6245 " 6246 [(set_attr "predicable" "yes") 6247 (set_attr "type" "alu_sreg")] 6248) 6249 6250(define_insn "tls_load_dot_plus_eight" 6251 [(set (match_operand:SI 0 "register_operand" "=r") 6252 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r") 6253 (const_int 8) 6254 (match_operand 2 "" "")] 6255 UNSPEC_PIC_BASE)))] 6256 "TARGET_ARM" 6257 "* 6258 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\", 6259 INTVAL (operands[2])); 6260 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\"; 6261 " 6262 [(set_attr "predicable" "yes") 6263 (set_attr "type" "load_4")] 6264) 6265 6266;; PIC references to local variables can generate pic_add_dot_plus_eight 6267;; followed by a load. These sequences can be crunched down to 6268;; tls_load_dot_plus_eight by a peephole. 6269 6270(define_peephole2 6271 [(set (match_operand:SI 0 "register_operand" "") 6272 (unspec:SI [(match_operand:SI 3 "register_operand" "") 6273 (const_int 8) 6274 (match_operand 1 "" "")] 6275 UNSPEC_PIC_BASE)) 6276 (set (match_operand:SI 2 "arm_general_register_operand" "") 6277 (mem:SI (match_dup 0)))] 6278 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])" 6279 [(set (match_dup 2) 6280 (mem:SI (unspec:SI [(match_dup 3) 6281 (const_int 8) 6282 (match_dup 1)] 6283 UNSPEC_PIC_BASE)))] 6284 "" 6285) 6286 6287(define_insn "pic_offset_arm" 6288 [(set (match_operand:SI 0 "register_operand" "=r") 6289 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 6290 (unspec:SI [(match_operand:SI 2 "" "X")] 6291 UNSPEC_PIC_OFFSET))))] 6292 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic" 6293 "ldr%?\\t%0, [%1,%2]" 6294 [(set_attr "type" "load_4")] 6295) 6296 6297(define_expand "builtin_setjmp_receiver" 6298 [(label_ref (match_operand 0 "" ""))] 6299 "flag_pic" 6300 " 6301{ 6302 /* r3 is clobbered by set/longjmp, so we can use it as a scratch 6303 register. */ 6304 if (arm_pic_register != INVALID_REGNUM) 6305 arm_load_pic_register (1UL << 3); 6306 DONE; 6307}") 6308 6309;; If copying one reg to another we can set the condition codes according to 6310;; its value. Such a move is common after a return from subroutine and the 6311;; result is being tested against zero. 6312 6313(define_insn "*movsi_compare0" 6314 [(set (reg:CC CC_REGNUM) 6315 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r") 6316 (const_int 0))) 6317 (set (match_operand:SI 0 "s_register_operand" "=r,r") 6318 (match_dup 1))] 6319 "TARGET_32BIT" 6320 "@ 6321 cmp%?\\t%0, #0 6322 subs%?\\t%0, %1, #0" 6323 [(set_attr "conds" "set") 6324 (set_attr "type" "alus_imm,alus_imm")] 6325) 6326 6327;; Subroutine to store a half word from a register into memory. 6328;; Operand 0 is the source register (HImode) 6329;; Operand 1 is the destination address in a register (SImode) 6330 6331;; In both this routine and the next, we must be careful not to spill 6332;; a memory address of reg+large_const into a separate PLUS insn, since this 6333;; can generate unrecognizable rtl. 6334 6335(define_expand "storehi" 6336 [;; store the low byte 6337 (set (match_operand 1 "" "") (match_dup 3)) 6338 ;; extract the high byte 6339 (set (match_dup 2) 6340 (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) 6341 ;; store the high byte 6342 (set (match_dup 4) (match_dup 5))] 6343 "TARGET_ARM" 6344 " 6345 { 6346 rtx op1 = operands[1]; 6347 rtx addr = XEXP (op1, 0); 6348 enum rtx_code code = GET_CODE (addr); 6349 6350 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1))) 6351 || code == MINUS) 6352 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr)); 6353 6354 operands[4] = adjust_address (op1, QImode, 1); 6355 operands[1] = adjust_address (operands[1], QImode, 0); 6356 operands[3] = gen_lowpart (QImode, operands[0]); 6357 operands[0] = gen_lowpart (SImode, operands[0]); 6358 operands[2] = gen_reg_rtx (SImode); 6359 operands[5] = gen_lowpart (QImode, operands[2]); 6360 }" 6361) 6362 6363(define_expand "storehi_bigend" 6364 [(set (match_dup 4) (match_dup 3)) 6365 (set (match_dup 2) 6366 (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) 6367 (set (match_operand 1 "" "") (match_dup 5))] 6368 "TARGET_ARM" 6369 " 6370 { 6371 rtx op1 = operands[1]; 6372 rtx addr = XEXP (op1, 0); 6373 enum rtx_code code = GET_CODE (addr); 6374 6375 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1))) 6376 || code == MINUS) 6377 op1 = replace_equiv_address (op1, force_reg (SImode, addr)); 6378 6379 operands[4] = adjust_address (op1, QImode, 1); 6380 operands[1] = adjust_address (operands[1], QImode, 0); 6381 operands[3] = gen_lowpart (QImode, operands[0]); 6382 operands[0] = gen_lowpart (SImode, operands[0]); 6383 operands[2] = gen_reg_rtx (SImode); 6384 operands[5] = gen_lowpart (QImode, operands[2]); 6385 }" 6386) 6387 6388;; Subroutine to store a half word integer constant into memory. 6389(define_expand "storeinthi" 6390 [(set (match_operand 0 "" "") 6391 (match_operand 1 "" "")) 6392 (set (match_dup 3) (match_dup 2))] 6393 "TARGET_ARM" 6394 " 6395 { 6396 HOST_WIDE_INT value = INTVAL (operands[1]); 6397 rtx addr = XEXP (operands[0], 0); 6398 rtx op0 = operands[0]; 6399 enum rtx_code code = GET_CODE (addr); 6400 6401 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1))) 6402 || code == MINUS) 6403 op0 = replace_equiv_address (op0, force_reg (SImode, addr)); 6404 6405 operands[1] = gen_reg_rtx (SImode); 6406 if (BYTES_BIG_ENDIAN) 6407 { 6408 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255))); 6409 if ((value & 255) == ((value >> 8) & 255)) 6410 operands[2] = operands[1]; 6411 else 6412 { 6413 operands[2] = gen_reg_rtx (SImode); 6414 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255))); 6415 } 6416 } 6417 else 6418 { 6419 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255))); 6420 if ((value & 255) == ((value >> 8) & 255)) 6421 operands[2] = operands[1]; 6422 else 6423 { 6424 operands[2] = gen_reg_rtx (SImode); 6425 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255))); 6426 } 6427 } 6428 6429 operands[3] = adjust_address (op0, QImode, 1); 6430 operands[0] = adjust_address (operands[0], QImode, 0); 6431 operands[2] = gen_lowpart (QImode, operands[2]); 6432 operands[1] = gen_lowpart (QImode, operands[1]); 6433 }" 6434) 6435 6436(define_expand "storehi_single_op" 6437 [(set (match_operand:HI 0 "memory_operand" "") 6438 (match_operand:HI 1 "general_operand" ""))] 6439 "TARGET_32BIT && arm_arch4" 6440 " 6441 if (!s_register_operand (operands[1], HImode)) 6442 operands[1] = copy_to_mode_reg (HImode, operands[1]); 6443 " 6444) 6445 6446(define_expand "movhi" 6447 [(set (match_operand:HI 0 "general_operand" "") 6448 (match_operand:HI 1 "general_operand" ""))] 6449 "TARGET_EITHER" 6450 " 6451 if (TARGET_ARM) 6452 { 6453 if (can_create_pseudo_p ()) 6454 { 6455 if (MEM_P (operands[0])) 6456 { 6457 if (arm_arch4) 6458 { 6459 emit_insn (gen_storehi_single_op (operands[0], operands[1])); 6460 DONE; 6461 } 6462 if (CONST_INT_P (operands[1])) 6463 emit_insn (gen_storeinthi (operands[0], operands[1])); 6464 else 6465 { 6466 if (MEM_P (operands[1])) 6467 operands[1] = force_reg (HImode, operands[1]); 6468 if (BYTES_BIG_ENDIAN) 6469 emit_insn (gen_storehi_bigend (operands[1], operands[0])); 6470 else 6471 emit_insn (gen_storehi (operands[1], operands[0])); 6472 } 6473 DONE; 6474 } 6475 /* Sign extend a constant, and keep it in an SImode reg. */ 6476 else if (CONST_INT_P (operands[1])) 6477 { 6478 rtx reg = gen_reg_rtx (SImode); 6479 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff; 6480 6481 /* If the constant is already valid, leave it alone. */ 6482 if (!const_ok_for_arm (val)) 6483 { 6484 /* If setting all the top bits will make the constant 6485 loadable in a single instruction, then set them. 6486 Otherwise, sign extend the number. */ 6487 6488 if (const_ok_for_arm (~(val | ~0xffff))) 6489 val |= ~0xffff; 6490 else if (val & 0x8000) 6491 val |= ~0xffff; 6492 } 6493 6494 emit_insn (gen_movsi (reg, GEN_INT (val))); 6495 operands[1] = gen_lowpart (HImode, reg); 6496 } 6497 else if (arm_arch4 && optimize && can_create_pseudo_p () 6498 && MEM_P (operands[1])) 6499 { 6500 rtx reg = gen_reg_rtx (SImode); 6501 6502 emit_insn (gen_zero_extendhisi2 (reg, operands[1])); 6503 operands[1] = gen_lowpart (HImode, reg); 6504 } 6505 else if (!arm_arch4) 6506 { 6507 if (MEM_P (operands[1])) 6508 { 6509 rtx base; 6510 rtx offset = const0_rtx; 6511 rtx reg = gen_reg_rtx (SImode); 6512 6513 if ((REG_P (base = XEXP (operands[1], 0)) 6514 || (GET_CODE (base) == PLUS 6515 && (CONST_INT_P (offset = XEXP (base, 1))) 6516 && ((INTVAL(offset) & 1) != 1) 6517 && REG_P (base = XEXP (base, 0)))) 6518 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32) 6519 { 6520 rtx new_rtx; 6521 6522 new_rtx = widen_memory_access (operands[1], SImode, 6523 ((INTVAL (offset) & ~3) 6524 - INTVAL (offset))); 6525 emit_insn (gen_movsi (reg, new_rtx)); 6526 if (((INTVAL (offset) & 2) != 0) 6527 ^ (BYTES_BIG_ENDIAN ? 1 : 0)) 6528 { 6529 rtx reg2 = gen_reg_rtx (SImode); 6530 6531 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16))); 6532 reg = reg2; 6533 } 6534 } 6535 else 6536 emit_insn (gen_movhi_bytes (reg, operands[1])); 6537 6538 operands[1] = gen_lowpart (HImode, reg); 6539 } 6540 } 6541 } 6542 /* Handle loading a large integer during reload. */ 6543 else if (CONST_INT_P (operands[1]) 6544 && !const_ok_for_arm (INTVAL (operands[1])) 6545 && !const_ok_for_arm (~INTVAL (operands[1]))) 6546 { 6547 /* Writing a constant to memory needs a scratch, which should 6548 be handled with SECONDARY_RELOADs. */ 6549 gcc_assert (REG_P (operands[0])); 6550 6551 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); 6552 emit_insn (gen_movsi (operands[0], operands[1])); 6553 DONE; 6554 } 6555 } 6556 else if (TARGET_THUMB2) 6557 { 6558 /* Thumb-2 can do everything except mem=mem and mem=const easily. */ 6559 if (can_create_pseudo_p ()) 6560 { 6561 if (!REG_P (operands[0])) 6562 operands[1] = force_reg (HImode, operands[1]); 6563 /* Zero extend a constant, and keep it in an SImode reg. */ 6564 else if (CONST_INT_P (operands[1])) 6565 { 6566 rtx reg = gen_reg_rtx (SImode); 6567 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff; 6568 6569 emit_insn (gen_movsi (reg, GEN_INT (val))); 6570 operands[1] = gen_lowpart (HImode, reg); 6571 } 6572 } 6573 } 6574 else /* TARGET_THUMB1 */ 6575 { 6576 if (can_create_pseudo_p ()) 6577 { 6578 if (CONST_INT_P (operands[1])) 6579 { 6580 rtx reg = gen_reg_rtx (SImode); 6581 6582 emit_insn (gen_movsi (reg, operands[1])); 6583 operands[1] = gen_lowpart (HImode, reg); 6584 } 6585 6586 /* ??? We shouldn't really get invalid addresses here, but this can 6587 happen if we are passed a SP (never OK for HImode/QImode) or 6588 virtual register (also rejected as illegitimate for HImode/QImode) 6589 relative address. */ 6590 /* ??? This should perhaps be fixed elsewhere, for instance, in 6591 fixup_stack_1, by checking for other kinds of invalid addresses, 6592 e.g. a bare reference to a virtual register. This may confuse the 6593 alpha though, which must handle this case differently. */ 6594 if (MEM_P (operands[0]) 6595 && !memory_address_p (GET_MODE (operands[0]), 6596 XEXP (operands[0], 0))) 6597 operands[0] 6598 = replace_equiv_address (operands[0], 6599 copy_to_reg (XEXP (operands[0], 0))); 6600 6601 if (MEM_P (operands[1]) 6602 && !memory_address_p (GET_MODE (operands[1]), 6603 XEXP (operands[1], 0))) 6604 operands[1] 6605 = replace_equiv_address (operands[1], 6606 copy_to_reg (XEXP (operands[1], 0))); 6607 6608 if (MEM_P (operands[1]) && optimize > 0) 6609 { 6610 rtx reg = gen_reg_rtx (SImode); 6611 6612 emit_insn (gen_zero_extendhisi2 (reg, operands[1])); 6613 operands[1] = gen_lowpart (HImode, reg); 6614 } 6615 6616 if (MEM_P (operands[0])) 6617 operands[1] = force_reg (HImode, operands[1]); 6618 } 6619 else if (CONST_INT_P (operands[1]) 6620 && !satisfies_constraint_I (operands[1])) 6621 { 6622 /* Handle loading a large integer during reload. */ 6623 6624 /* Writing a constant to memory needs a scratch, which should 6625 be handled with SECONDARY_RELOADs. */ 6626 gcc_assert (REG_P (operands[0])); 6627 6628 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); 6629 emit_insn (gen_movsi (operands[0], operands[1])); 6630 DONE; 6631 } 6632 } 6633 " 6634) 6635 6636(define_expand "movhi_bytes" 6637 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" ""))) 6638 (set (match_dup 3) 6639 (zero_extend:SI (match_dup 6))) 6640 (set (match_operand:SI 0 "" "") 6641 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))] 6642 "TARGET_ARM" 6643 " 6644 { 6645 rtx mem1, mem2; 6646 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 6647 6648 mem1 = change_address (operands[1], QImode, addr); 6649 mem2 = change_address (operands[1], QImode, 6650 plus_constant (Pmode, addr, 1)); 6651 operands[0] = gen_lowpart (SImode, operands[0]); 6652 operands[1] = mem1; 6653 operands[2] = gen_reg_rtx (SImode); 6654 operands[3] = gen_reg_rtx (SImode); 6655 operands[6] = mem2; 6656 6657 if (BYTES_BIG_ENDIAN) 6658 { 6659 operands[4] = operands[2]; 6660 operands[5] = operands[3]; 6661 } 6662 else 6663 { 6664 operands[4] = operands[3]; 6665 operands[5] = operands[2]; 6666 } 6667 }" 6668) 6669 6670(define_expand "movhi_bigend" 6671 [(set (match_dup 2) 6672 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0) 6673 (const_int 16))) 6674 (set (match_dup 3) 6675 (ashiftrt:SI (match_dup 2) (const_int 16))) 6676 (set (match_operand:HI 0 "s_register_operand" "") 6677 (match_dup 4))] 6678 "TARGET_ARM" 6679 " 6680 operands[2] = gen_reg_rtx (SImode); 6681 operands[3] = gen_reg_rtx (SImode); 6682 operands[4] = gen_lowpart (HImode, operands[3]); 6683 " 6684) 6685 6686;; Pattern to recognize insn generated default case above 6687(define_insn "*movhi_insn_arch4" 6688 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r") 6689 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))] 6690 "TARGET_ARM 6691 && arm_arch4 && !TARGET_HARD_FLOAT 6692 && (register_operand (operands[0], HImode) 6693 || register_operand (operands[1], HImode))" 6694 "@ 6695 mov%?\\t%0, %1\\t%@ movhi 6696 mvn%?\\t%0, #%B1\\t%@ movhi 6697 movw%?\\t%0, %L1\\t%@ movhi 6698 strh%?\\t%1, %0\\t%@ movhi 6699 ldrh%?\\t%0, %1\\t%@ movhi" 6700 [(set_attr "predicable" "yes") 6701 (set_attr "pool_range" "*,*,*,*,256") 6702 (set_attr "neg_pool_range" "*,*,*,*,244") 6703 (set_attr "arch" "*,*,v6t2,*,*") 6704 (set_attr_alternative "type" 6705 [(if_then_else (match_operand 1 "const_int_operand" "") 6706 (const_string "mov_imm" ) 6707 (const_string "mov_reg")) 6708 (const_string "mvn_imm") 6709 (const_string "mov_imm") 6710 (const_string "store_4") 6711 (const_string "load_4")])] 6712) 6713 6714(define_insn "*movhi_bytes" 6715 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r") 6716 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))] 6717 "TARGET_ARM && !TARGET_HARD_FLOAT" 6718 "@ 6719 mov%?\\t%0, %1\\t%@ movhi 6720 mov%?\\t%0, %1\\t%@ movhi 6721 mvn%?\\t%0, #%B1\\t%@ movhi" 6722 [(set_attr "predicable" "yes") 6723 (set_attr "type" "mov_imm,mov_reg,mvn_imm")] 6724) 6725 6726;; We use a DImode scratch because we may occasionally need an additional 6727;; temporary if the address isn't offsettable -- push_reload doesn't seem 6728;; to take any notice of the "o" constraints on reload_memory_operand operand. 6729(define_expand "reload_outhi" 6730 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o") 6731 (match_operand:HI 1 "s_register_operand" "r") 6732 (match_operand:DI 2 "s_register_operand" "=&l")])] 6733 "TARGET_EITHER" 6734 "if (TARGET_ARM) 6735 arm_reload_out_hi (operands); 6736 else 6737 thumb_reload_out_hi (operands); 6738 DONE; 6739 " 6740) 6741 6742(define_expand "reload_inhi" 6743 [(parallel [(match_operand:HI 0 "s_register_operand" "=r") 6744 (match_operand:HI 1 "arm_reload_memory_operand" "o") 6745 (match_operand:DI 2 "s_register_operand" "=&r")])] 6746 "TARGET_EITHER" 6747 " 6748 if (TARGET_ARM) 6749 arm_reload_in_hi (operands); 6750 else 6751 thumb_reload_out_hi (operands); 6752 DONE; 6753") 6754 6755(define_expand "movqi" 6756 [(set (match_operand:QI 0 "general_operand" "") 6757 (match_operand:QI 1 "general_operand" ""))] 6758 "TARGET_EITHER" 6759 " 6760 /* Everything except mem = const or mem = mem can be done easily */ 6761 6762 if (can_create_pseudo_p ()) 6763 { 6764 if (CONST_INT_P (operands[1])) 6765 { 6766 rtx reg = gen_reg_rtx (SImode); 6767 6768 /* For thumb we want an unsigned immediate, then we are more likely 6769 to be able to use a movs insn. */ 6770 if (TARGET_THUMB) 6771 operands[1] = GEN_INT (INTVAL (operands[1]) & 255); 6772 6773 emit_insn (gen_movsi (reg, operands[1])); 6774 operands[1] = gen_lowpart (QImode, reg); 6775 } 6776 6777 if (TARGET_THUMB) 6778 { 6779 /* ??? We shouldn't really get invalid addresses here, but this can 6780 happen if we are passed a SP (never OK for HImode/QImode) or 6781 virtual register (also rejected as illegitimate for HImode/QImode) 6782 relative address. */ 6783 /* ??? This should perhaps be fixed elsewhere, for instance, in 6784 fixup_stack_1, by checking for other kinds of invalid addresses, 6785 e.g. a bare reference to a virtual register. This may confuse the 6786 alpha though, which must handle this case differently. */ 6787 if (MEM_P (operands[0]) 6788 && !memory_address_p (GET_MODE (operands[0]), 6789 XEXP (operands[0], 0))) 6790 operands[0] 6791 = replace_equiv_address (operands[0], 6792 copy_to_reg (XEXP (operands[0], 0))); 6793 if (MEM_P (operands[1]) 6794 && !memory_address_p (GET_MODE (operands[1]), 6795 XEXP (operands[1], 0))) 6796 operands[1] 6797 = replace_equiv_address (operands[1], 6798 copy_to_reg (XEXP (operands[1], 0))); 6799 } 6800 6801 if (MEM_P (operands[1]) && optimize > 0) 6802 { 6803 rtx reg = gen_reg_rtx (SImode); 6804 6805 emit_insn (gen_zero_extendqisi2 (reg, operands[1])); 6806 operands[1] = gen_lowpart (QImode, reg); 6807 } 6808 6809 if (MEM_P (operands[0])) 6810 operands[1] = force_reg (QImode, operands[1]); 6811 } 6812 else if (TARGET_THUMB 6813 && CONST_INT_P (operands[1]) 6814 && !satisfies_constraint_I (operands[1])) 6815 { 6816 /* Handle loading a large integer during reload. */ 6817 6818 /* Writing a constant to memory needs a scratch, which should 6819 be handled with SECONDARY_RELOADs. */ 6820 gcc_assert (REG_P (operands[0])); 6821 6822 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); 6823 emit_insn (gen_movsi (operands[0], operands[1])); 6824 DONE; 6825 } 6826 " 6827) 6828 6829(define_insn "*arm_movqi_insn" 6830 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m") 6831 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))] 6832 "TARGET_32BIT 6833 && ( register_operand (operands[0], QImode) 6834 || register_operand (operands[1], QImode))" 6835 "@ 6836 mov%?\\t%0, %1 6837 mov%?\\t%0, %1 6838 mov%?\\t%0, %1 6839 mov%?\\t%0, %1 6840 mvn%?\\t%0, #%B1 6841 ldrb%?\\t%0, %1 6842 strb%?\\t%1, %0 6843 ldrb%?\\t%0, %1 6844 strb%?\\t%1, %0" 6845 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4") 6846 (set_attr "predicable" "yes") 6847 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no") 6848 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any") 6849 (set_attr "length" "2,4,4,2,4,2,2,4,4")] 6850) 6851 6852;; HFmode moves 6853(define_expand "movhf" 6854 [(set (match_operand:HF 0 "general_operand" "") 6855 (match_operand:HF 1 "general_operand" ""))] 6856 "TARGET_EITHER" 6857 " 6858 if (TARGET_32BIT) 6859 { 6860 if (MEM_P (operands[0])) 6861 operands[1] = force_reg (HFmode, operands[1]); 6862 } 6863 else /* TARGET_THUMB1 */ 6864 { 6865 if (can_create_pseudo_p ()) 6866 { 6867 if (!REG_P (operands[0])) 6868 operands[1] = force_reg (HFmode, operands[1]); 6869 } 6870 } 6871 " 6872) 6873 6874(define_insn "*arm32_movhf" 6875 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r") 6876 (match_operand:HF 1 "general_operand" " m,r,r,F"))] 6877 "TARGET_32BIT && !TARGET_HARD_FLOAT 6878 && ( s_register_operand (operands[0], HFmode) 6879 || s_register_operand (operands[1], HFmode))" 6880 "* 6881 switch (which_alternative) 6882 { 6883 case 0: /* ARM register from memory */ 6884 return \"ldrh%?\\t%0, %1\\t%@ __fp16\"; 6885 case 1: /* memory from ARM register */ 6886 return \"strh%?\\t%1, %0\\t%@ __fp16\"; 6887 case 2: /* ARM register from ARM register */ 6888 return \"mov%?\\t%0, %1\\t%@ __fp16\"; 6889 case 3: /* ARM register from constant */ 6890 { 6891 long bits; 6892 rtx ops[4]; 6893 6894 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), 6895 HFmode); 6896 ops[0] = operands[0]; 6897 ops[1] = GEN_INT (bits); 6898 ops[2] = GEN_INT (bits & 0xff00); 6899 ops[3] = GEN_INT (bits & 0x00ff); 6900 6901 if (arm_arch_thumb2) 6902 output_asm_insn (\"movw%?\\t%0, %1\", ops); 6903 else 6904 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops); 6905 return \"\"; 6906 } 6907 default: 6908 gcc_unreachable (); 6909 } 6910 " 6911 [(set_attr "conds" "unconditional") 6912 (set_attr "type" "load_4,store_4,mov_reg,multiple") 6913 (set_attr "length" "4,4,4,8") 6914 (set_attr "predicable" "yes")] 6915) 6916 6917(define_expand "movsf" 6918 [(set (match_operand:SF 0 "general_operand" "") 6919 (match_operand:SF 1 "general_operand" ""))] 6920 "TARGET_EITHER" 6921 " 6922 if (TARGET_32BIT) 6923 { 6924 if (MEM_P (operands[0])) 6925 operands[1] = force_reg (SFmode, operands[1]); 6926 } 6927 else /* TARGET_THUMB1 */ 6928 { 6929 if (can_create_pseudo_p ()) 6930 { 6931 if (!REG_P (operands[0])) 6932 operands[1] = force_reg (SFmode, operands[1]); 6933 } 6934 } 6935 " 6936) 6937 6938;; Transform a floating-point move of a constant into a core register into 6939;; an SImode operation. 6940(define_split 6941 [(set (match_operand:SF 0 "arm_general_register_operand" "") 6942 (match_operand:SF 1 "immediate_operand" ""))] 6943 "TARGET_EITHER 6944 && reload_completed 6945 && CONST_DOUBLE_P (operands[1])" 6946 [(set (match_dup 2) (match_dup 3))] 6947 " 6948 operands[2] = gen_lowpart (SImode, operands[0]); 6949 operands[3] = gen_lowpart (SImode, operands[1]); 6950 if (operands[2] == 0 || operands[3] == 0) 6951 FAIL; 6952 " 6953) 6954 6955(define_insn "*arm_movsf_soft_insn" 6956 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m") 6957 (match_operand:SF 1 "general_operand" "r,mE,r"))] 6958 "TARGET_32BIT 6959 && TARGET_SOFT_FLOAT 6960 && (!MEM_P (operands[0]) 6961 || register_operand (operands[1], SFmode))" 6962 "@ 6963 mov%?\\t%0, %1 6964 ldr%?\\t%0, %1\\t%@ float 6965 str%?\\t%1, %0\\t%@ float" 6966 [(set_attr "predicable" "yes") 6967 (set_attr "type" "mov_reg,load_4,store_4") 6968 (set_attr "arm_pool_range" "*,4096,*") 6969 (set_attr "thumb2_pool_range" "*,4094,*") 6970 (set_attr "arm_neg_pool_range" "*,4084,*") 6971 (set_attr "thumb2_neg_pool_range" "*,0,*")] 6972) 6973 6974(define_expand "movdf" 6975 [(set (match_operand:DF 0 "general_operand" "") 6976 (match_operand:DF 1 "general_operand" ""))] 6977 "TARGET_EITHER" 6978 " 6979 if (TARGET_32BIT) 6980 { 6981 if (MEM_P (operands[0])) 6982 operands[1] = force_reg (DFmode, operands[1]); 6983 } 6984 else /* TARGET_THUMB */ 6985 { 6986 if (can_create_pseudo_p ()) 6987 { 6988 if (!REG_P (operands[0])) 6989 operands[1] = force_reg (DFmode, operands[1]); 6990 } 6991 } 6992 " 6993) 6994 6995;; Reloading a df mode value stored in integer regs to memory can require a 6996;; scratch reg. 6997(define_expand "reload_outdf" 6998 [(match_operand:DF 0 "arm_reload_memory_operand" "=o") 6999 (match_operand:DF 1 "s_register_operand" "r") 7000 (match_operand:SI 2 "s_register_operand" "=&r")] 7001 "TARGET_THUMB2" 7002 " 7003 { 7004 enum rtx_code code = GET_CODE (XEXP (operands[0], 0)); 7005 7006 if (code == REG) 7007 operands[2] = XEXP (operands[0], 0); 7008 else if (code == POST_INC || code == PRE_DEC) 7009 { 7010 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0); 7011 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0); 7012 emit_insn (gen_movdi (operands[0], operands[1])); 7013 DONE; 7014 } 7015 else if (code == PRE_INC) 7016 { 7017 rtx reg = XEXP (XEXP (operands[0], 0), 0); 7018 7019 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8))); 7020 operands[2] = reg; 7021 } 7022 else if (code == POST_DEC) 7023 operands[2] = XEXP (XEXP (operands[0], 0), 0); 7024 else 7025 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0), 7026 XEXP (XEXP (operands[0], 0), 1))); 7027 7028 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]), 7029 operands[1])); 7030 7031 if (code == POST_DEC) 7032 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8))); 7033 7034 DONE; 7035 }" 7036) 7037 7038(define_insn "*movdf_soft_insn" 7039 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m") 7040 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))] 7041 "TARGET_32BIT && TARGET_SOFT_FLOAT 7042 && ( register_operand (operands[0], DFmode) 7043 || register_operand (operands[1], DFmode))" 7044 "* 7045 switch (which_alternative) 7046 { 7047 case 0: 7048 case 1: 7049 case 2: 7050 return \"#\"; 7051 default: 7052 return output_move_double (operands, true, NULL); 7053 } 7054 " 7055 [(set_attr "length" "8,12,16,8,8") 7056 (set_attr "type" "multiple,multiple,multiple,load_8,store_8") 7057 (set_attr "arm_pool_range" "*,*,*,1020,*") 7058 (set_attr "thumb2_pool_range" "*,*,*,1018,*") 7059 (set_attr "arm_neg_pool_range" "*,*,*,1004,*") 7060 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")] 7061) 7062 7063 7064;; load- and store-multiple insns 7065;; The arm can load/store any set of registers, provided that they are in 7066;; ascending order, but these expanders assume a contiguous set. 7067 7068(define_expand "load_multiple" 7069 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 7070 (match_operand:SI 1 "" "")) 7071 (use (match_operand:SI 2 "" ""))])] 7072 "TARGET_32BIT" 7073{ 7074 HOST_WIDE_INT offset = 0; 7075 7076 /* Support only fixed point registers. */ 7077 if (!CONST_INT_P (operands[2]) 7078 || INTVAL (operands[2]) > MAX_LDM_STM_OPS 7079 || INTVAL (operands[2]) < 2 7080 || !MEM_P (operands[1]) 7081 || !REG_P (operands[0]) 7082 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1) 7083 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM) 7084 FAIL; 7085 7086 operands[3] 7087 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]), 7088 INTVAL (operands[2]), 7089 force_reg (SImode, XEXP (operands[1], 0)), 7090 FALSE, operands[1], &offset); 7091}) 7092 7093(define_expand "store_multiple" 7094 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 7095 (match_operand:SI 1 "" "")) 7096 (use (match_operand:SI 2 "" ""))])] 7097 "TARGET_32BIT" 7098{ 7099 HOST_WIDE_INT offset = 0; 7100 7101 /* Support only fixed point registers. */ 7102 if (!CONST_INT_P (operands[2]) 7103 || INTVAL (operands[2]) > MAX_LDM_STM_OPS 7104 || INTVAL (operands[2]) < 2 7105 || !REG_P (operands[1]) 7106 || !MEM_P (operands[0]) 7107 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1) 7108 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM) 7109 FAIL; 7110 7111 operands[3] 7112 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]), 7113 INTVAL (operands[2]), 7114 force_reg (SImode, XEXP (operands[0], 0)), 7115 FALSE, operands[0], &offset); 7116}) 7117 7118 7119(define_expand "setmemsi" 7120 [(match_operand:BLK 0 "general_operand" "") 7121 (match_operand:SI 1 "const_int_operand" "") 7122 (match_operand:SI 2 "const_int_operand" "") 7123 (match_operand:SI 3 "const_int_operand" "")] 7124 "TARGET_32BIT" 7125{ 7126 if (arm_gen_setmem (operands)) 7127 DONE; 7128 7129 FAIL; 7130}) 7131 7132 7133;; Move a block of memory if it is word aligned and MORE than 2 words long. 7134;; We could let this apply for blocks of less than this, but it clobbers so 7135;; many registers that there is then probably a better way. 7136 7137(define_expand "movmemqi" 7138 [(match_operand:BLK 0 "general_operand" "") 7139 (match_operand:BLK 1 "general_operand" "") 7140 (match_operand:SI 2 "const_int_operand" "") 7141 (match_operand:SI 3 "const_int_operand" "")] 7142 "" 7143 " 7144 if (TARGET_32BIT) 7145 { 7146 if (TARGET_LDRD && current_tune->prefer_ldrd_strd 7147 && !optimize_function_for_size_p (cfun)) 7148 { 7149 if (gen_movmem_ldrd_strd (operands)) 7150 DONE; 7151 FAIL; 7152 } 7153 7154 if (arm_gen_movmemqi (operands)) 7155 DONE; 7156 FAIL; 7157 } 7158 else /* TARGET_THUMB1 */ 7159 { 7160 if ( INTVAL (operands[3]) != 4 7161 || INTVAL (operands[2]) > 48) 7162 FAIL; 7163 7164 thumb_expand_movmemqi (operands); 7165 DONE; 7166 } 7167 " 7168) 7169 7170 7171;; Compare & branch insns 7172;; The range calculations are based as follows: 7173;; For forward branches, the address calculation returns the address of 7174;; the next instruction. This is 2 beyond the branch instruction. 7175;; For backward branches, the address calculation returns the address of 7176;; the first instruction in this pattern (cmp). This is 2 before the branch 7177;; instruction for the shortest sequence, and 4 before the branch instruction 7178;; if we have to jump around an unconditional branch. 7179;; To the basic branch range the PC offset must be added (this is +4). 7180;; So for forward branches we have 7181;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4). 7182;; And for backward branches we have 7183;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4). 7184;; 7185;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048). 7186;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256). 7187 7188(define_expand "cbranchsi4" 7189 [(set (pc) (if_then_else 7190 (match_operator 0 "expandable_comparison_operator" 7191 [(match_operand:SI 1 "s_register_operand" "") 7192 (match_operand:SI 2 "nonmemory_operand" "")]) 7193 (label_ref (match_operand 3 "" "")) 7194 (pc)))] 7195 "TARGET_EITHER" 7196 " 7197 if (!TARGET_THUMB1) 7198 { 7199 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2])) 7200 FAIL; 7201 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7202 operands[3])); 7203 DONE; 7204 } 7205 if (thumb1_cmpneg_operand (operands[2], SImode)) 7206 { 7207 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2], 7208 operands[3], operands[0])); 7209 DONE; 7210 } 7211 if (!thumb1_cmp_operand (operands[2], SImode)) 7212 operands[2] = force_reg (SImode, operands[2]); 7213 ") 7214 7215(define_expand "cbranchsf4" 7216 [(set (pc) (if_then_else 7217 (match_operator 0 "expandable_comparison_operator" 7218 [(match_operand:SF 1 "s_register_operand" "") 7219 (match_operand:SF 2 "vfp_compare_operand" "")]) 7220 (label_ref (match_operand 3 "" "")) 7221 (pc)))] 7222 "TARGET_32BIT && TARGET_HARD_FLOAT" 7223 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7224 operands[3])); DONE;" 7225) 7226 7227(define_expand "cbranchdf4" 7228 [(set (pc) (if_then_else 7229 (match_operator 0 "expandable_comparison_operator" 7230 [(match_operand:DF 1 "s_register_operand" "") 7231 (match_operand:DF 2 "vfp_compare_operand" "")]) 7232 (label_ref (match_operand 3 "" "")) 7233 (pc)))] 7234 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 7235 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7236 operands[3])); DONE;" 7237) 7238 7239(define_expand "cbranchdi4" 7240 [(set (pc) (if_then_else 7241 (match_operator 0 "expandable_comparison_operator" 7242 [(match_operand:DI 1 "s_register_operand" "") 7243 (match_operand:DI 2 "cmpdi_operand" "")]) 7244 (label_ref (match_operand 3 "" "")) 7245 (pc)))] 7246 "TARGET_32BIT" 7247 "{ 7248 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2])) 7249 FAIL; 7250 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7251 operands[3])); 7252 DONE; 7253 }" 7254) 7255 7256;; Comparison and test insns 7257 7258(define_insn "*arm_cmpsi_insn" 7259 [(set (reg:CC CC_REGNUM) 7260 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r") 7261 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))] 7262 "TARGET_32BIT" 7263 "@ 7264 cmp%?\\t%0, %1 7265 cmp%?\\t%0, %1 7266 cmp%?\\t%0, %1 7267 cmp%?\\t%0, %1 7268 cmn%?\\t%0, #%n1" 7269 [(set_attr "conds" "set") 7270 (set_attr "arch" "t2,t2,any,any,any") 7271 (set_attr "length" "2,2,4,4,4") 7272 (set_attr "predicable" "yes") 7273 (set_attr "predicable_short_it" "yes,yes,yes,no,no") 7274 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")] 7275) 7276 7277(define_insn "*cmpsi_shiftsi" 7278 [(set (reg:CC CC_REGNUM) 7279 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r") 7280 (match_operator:SI 3 "shift_operator" 7281 [(match_operand:SI 1 "s_register_operand" "r,r,r") 7282 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))] 7283 "TARGET_32BIT" 7284 "cmp\\t%0, %1%S3" 7285 [(set_attr "conds" "set") 7286 (set_attr "shift" "1") 7287 (set_attr "arch" "32,a,a") 7288 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 7289 7290(define_insn "*cmpsi_shiftsi_swp" 7291 [(set (reg:CC_SWP CC_REGNUM) 7292 (compare:CC_SWP (match_operator:SI 3 "shift_operator" 7293 [(match_operand:SI 1 "s_register_operand" "r,r,r") 7294 (match_operand:SI 2 "shift_amount_operand" "M,r,M")]) 7295 (match_operand:SI 0 "s_register_operand" "r,r,r")))] 7296 "TARGET_32BIT" 7297 "cmp%?\\t%0, %1%S3" 7298 [(set_attr "conds" "set") 7299 (set_attr "shift" "1") 7300 (set_attr "arch" "32,a,a") 7301 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 7302 7303(define_insn "*arm_cmpsi_negshiftsi_si" 7304 [(set (reg:CC_Z CC_REGNUM) 7305 (compare:CC_Z 7306 (neg:SI (match_operator:SI 1 "shift_operator" 7307 [(match_operand:SI 2 "s_register_operand" "r") 7308 (match_operand:SI 3 "reg_or_int_operand" "rM")])) 7309 (match_operand:SI 0 "s_register_operand" "r")))] 7310 "TARGET_ARM" 7311 "cmn%?\\t%0, %2%S1" 7312 [(set_attr "conds" "set") 7313 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") 7314 (const_string "alus_shift_imm") 7315 (const_string "alus_shift_reg"))) 7316 (set_attr "predicable" "yes")] 7317) 7318 7319;; DImode comparisons. The generic code generates branches that 7320;; if-conversion can not reduce to a conditional compare, so we do 7321;; that directly. 7322 7323(define_insn_and_split "*arm_cmpdi_insn" 7324 [(set (reg:CC_NCV CC_REGNUM) 7325 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r") 7326 (match_operand:DI 1 "arm_di_operand" "rDi"))) 7327 (clobber (match_scratch:SI 2 "=r"))] 7328 "TARGET_32BIT" 7329 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1" 7330 "&& reload_completed" 7331 [(set (reg:CC CC_REGNUM) 7332 (compare:CC (match_dup 0) (match_dup 1))) 7333 (parallel [(set (reg:CC CC_REGNUM) 7334 (compare:CC (match_dup 3) (match_dup 4))) 7335 (set (match_dup 2) 7336 (minus:SI (match_dup 5) 7337 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])] 7338 { 7339 operands[3] = gen_highpart (SImode, operands[0]); 7340 operands[0] = gen_lowpart (SImode, operands[0]); 7341 if (CONST_INT_P (operands[1])) 7342 { 7343 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode, 7344 DImode, 7345 operands[1]))); 7346 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]); 7347 } 7348 else 7349 { 7350 operands[4] = gen_highpart (SImode, operands[1]); 7351 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]); 7352 } 7353 operands[1] = gen_lowpart (SImode, operands[1]); 7354 operands[2] = gen_lowpart (SImode, operands[2]); 7355 } 7356 [(set_attr "conds" "set") 7357 (set_attr "length" "8") 7358 (set_attr "type" "multiple")] 7359) 7360 7361(define_insn_and_split "*arm_cmpdi_unsigned" 7362 [(set (reg:CC_CZ CC_REGNUM) 7363 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r") 7364 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))] 7365 7366 "TARGET_32BIT" 7367 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1" 7368 "&& reload_completed" 7369 [(set (reg:CC CC_REGNUM) 7370 (compare:CC (match_dup 2) (match_dup 3))) 7371 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0)) 7372 (set (reg:CC CC_REGNUM) 7373 (compare:CC (match_dup 0) (match_dup 1))))] 7374 { 7375 operands[2] = gen_highpart (SImode, operands[0]); 7376 operands[0] = gen_lowpart (SImode, operands[0]); 7377 if (CONST_INT_P (operands[1])) 7378 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]); 7379 else 7380 operands[3] = gen_highpart (SImode, operands[1]); 7381 operands[1] = gen_lowpart (SImode, operands[1]); 7382 } 7383 [(set_attr "conds" "set") 7384 (set_attr "enabled_for_short_it" "yes,yes,no,*") 7385 (set_attr "arch" "t2,t2,t2,a") 7386 (set_attr "length" "6,6,10,8") 7387 (set_attr "type" "multiple")] 7388) 7389 7390(define_insn "*arm_cmpdi_zero" 7391 [(set (reg:CC_Z CC_REGNUM) 7392 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r") 7393 (const_int 0))) 7394 (clobber (match_scratch:SI 1 "=r"))] 7395 "TARGET_32BIT" 7396 "orrs%?\\t%1, %Q0, %R0" 7397 [(set_attr "conds" "set") 7398 (set_attr "type" "logics_reg")] 7399) 7400 7401; This insn allows redundant compares to be removed by cse, nothing should 7402; ever appear in the output file since (set (reg x) (reg x)) is a no-op that 7403; is deleted later on. The match_dup will match the mode here, so that 7404; mode changes of the condition codes aren't lost by this even though we don't 7405; specify what they are. 7406 7407(define_insn "*deleted_compare" 7408 [(set (match_operand 0 "cc_register" "") (match_dup 0))] 7409 "TARGET_32BIT" 7410 "\\t%@ deleted compare" 7411 [(set_attr "conds" "set") 7412 (set_attr "length" "0") 7413 (set_attr "type" "no_insn")] 7414) 7415 7416 7417;; Conditional branch insns 7418 7419(define_expand "cbranch_cc" 7420 [(set (pc) 7421 (if_then_else (match_operator 0 "" [(match_operand 1 "" "") 7422 (match_operand 2 "" "")]) 7423 (label_ref (match_operand 3 "" "")) 7424 (pc)))] 7425 "TARGET_32BIT" 7426 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]), 7427 operands[1], operands[2], NULL_RTX); 7428 operands[2] = const0_rtx;" 7429) 7430 7431;; 7432;; Patterns to match conditional branch insns. 7433;; 7434 7435(define_insn "arm_cond_branch" 7436 [(set (pc) 7437 (if_then_else (match_operator 1 "arm_comparison_operator" 7438 [(match_operand 2 "cc_register" "") (const_int 0)]) 7439 (label_ref (match_operand 0 "" "")) 7440 (pc)))] 7441 "TARGET_32BIT" 7442 "* 7443 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 7444 { 7445 arm_ccfsm_state += 2; 7446 return \"\"; 7447 } 7448 return \"b%d1\\t%l0\"; 7449 " 7450 [(set_attr "conds" "use") 7451 (set_attr "type" "branch") 7452 (set (attr "length") 7453 (if_then_else 7454 (and (match_test "TARGET_THUMB2") 7455 (and (ge (minus (match_dup 0) (pc)) (const_int -250)) 7456 (le (minus (match_dup 0) (pc)) (const_int 256)))) 7457 (const_int 2) 7458 (const_int 4)))] 7459) 7460 7461(define_insn "*arm_cond_branch_reversed" 7462 [(set (pc) 7463 (if_then_else (match_operator 1 "arm_comparison_operator" 7464 [(match_operand 2 "cc_register" "") (const_int 0)]) 7465 (pc) 7466 (label_ref (match_operand 0 "" ""))))] 7467 "TARGET_32BIT" 7468 "* 7469 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 7470 { 7471 arm_ccfsm_state += 2; 7472 return \"\"; 7473 } 7474 return \"b%D1\\t%l0\"; 7475 " 7476 [(set_attr "conds" "use") 7477 (set_attr "type" "branch") 7478 (set (attr "length") 7479 (if_then_else 7480 (and (match_test "TARGET_THUMB2") 7481 (and (ge (minus (match_dup 0) (pc)) (const_int -250)) 7482 (le (minus (match_dup 0) (pc)) (const_int 256)))) 7483 (const_int 2) 7484 (const_int 4)))] 7485) 7486 7487 7488 7489; scc insns 7490 7491(define_expand "cstore_cc" 7492 [(set (match_operand:SI 0 "s_register_operand" "") 7493 (match_operator:SI 1 "" [(match_operand 2 "" "") 7494 (match_operand 3 "" "")]))] 7495 "TARGET_32BIT" 7496 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]), 7497 operands[2], operands[3], NULL_RTX); 7498 operands[3] = const0_rtx;" 7499) 7500 7501(define_insn_and_split "*mov_scc" 7502 [(set (match_operand:SI 0 "s_register_operand" "=r") 7503 (match_operator:SI 1 "arm_comparison_operator_mode" 7504 [(match_operand 2 "cc_register" "") (const_int 0)]))] 7505 "TARGET_ARM" 7506 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1" 7507 "TARGET_ARM" 7508 [(set (match_dup 0) 7509 (if_then_else:SI (match_dup 1) 7510 (const_int 1) 7511 (const_int 0)))] 7512 "" 7513 [(set_attr "conds" "use") 7514 (set_attr "length" "8") 7515 (set_attr "type" "multiple")] 7516) 7517 7518(define_insn_and_split "*mov_negscc" 7519 [(set (match_operand:SI 0 "s_register_operand" "=r") 7520 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode" 7521 [(match_operand 2 "cc_register" "") (const_int 0)])))] 7522 "TARGET_ARM" 7523 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" 7524 "TARGET_ARM" 7525 [(set (match_dup 0) 7526 (if_then_else:SI (match_dup 1) 7527 (match_dup 3) 7528 (const_int 0)))] 7529 { 7530 operands[3] = GEN_INT (~0); 7531 } 7532 [(set_attr "conds" "use") 7533 (set_attr "length" "8") 7534 (set_attr "type" "multiple")] 7535) 7536 7537(define_insn_and_split "*mov_notscc" 7538 [(set (match_operand:SI 0 "s_register_operand" "=r") 7539 (not:SI (match_operator:SI 1 "arm_comparison_operator" 7540 [(match_operand 2 "cc_register" "") (const_int 0)])))] 7541 "TARGET_ARM" 7542 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1" 7543 "TARGET_ARM" 7544 [(set (match_dup 0) 7545 (if_then_else:SI (match_dup 1) 7546 (match_dup 3) 7547 (match_dup 4)))] 7548 { 7549 operands[3] = GEN_INT (~1); 7550 operands[4] = GEN_INT (~0); 7551 } 7552 [(set_attr "conds" "use") 7553 (set_attr "length" "8") 7554 (set_attr "type" "multiple")] 7555) 7556 7557(define_expand "cstoresi4" 7558 [(set (match_operand:SI 0 "s_register_operand" "") 7559 (match_operator:SI 1 "expandable_comparison_operator" 7560 [(match_operand:SI 2 "s_register_operand" "") 7561 (match_operand:SI 3 "reg_or_int_operand" "")]))] 7562 "TARGET_32BIT || TARGET_THUMB1" 7563 "{ 7564 rtx op3, scratch, scratch2; 7565 7566 if (!TARGET_THUMB1) 7567 { 7568 if (!arm_add_operand (operands[3], SImode)) 7569 operands[3] = force_reg (SImode, operands[3]); 7570 emit_insn (gen_cstore_cc (operands[0], operands[1], 7571 operands[2], operands[3])); 7572 DONE; 7573 } 7574 7575 if (operands[3] == const0_rtx) 7576 { 7577 switch (GET_CODE (operands[1])) 7578 { 7579 case EQ: 7580 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2])); 7581 break; 7582 7583 case NE: 7584 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2])); 7585 break; 7586 7587 case LE: 7588 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx, 7589 NULL_RTX, 0, OPTAB_WIDEN); 7590 scratch = expand_binop (SImode, ior_optab, operands[2], scratch, 7591 NULL_RTX, 0, OPTAB_WIDEN); 7592 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), 7593 operands[0], 1, OPTAB_WIDEN); 7594 break; 7595 7596 case GE: 7597 scratch = expand_unop (SImode, one_cmpl_optab, operands[2], 7598 NULL_RTX, 1); 7599 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), 7600 NULL_RTX, 1, OPTAB_WIDEN); 7601 break; 7602 7603 case GT: 7604 scratch = expand_binop (SImode, ashr_optab, operands[2], 7605 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN); 7606 scratch = expand_binop (SImode, sub_optab, scratch, operands[2], 7607 NULL_RTX, 0, OPTAB_WIDEN); 7608 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0], 7609 0, OPTAB_WIDEN); 7610 break; 7611 7612 /* LT is handled by generic code. No need for unsigned with 0. */ 7613 default: 7614 FAIL; 7615 } 7616 DONE; 7617 } 7618 7619 switch (GET_CODE (operands[1])) 7620 { 7621 case EQ: 7622 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3], 7623 NULL_RTX, 0, OPTAB_WIDEN); 7624 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch)); 7625 break; 7626 7627 case NE: 7628 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3], 7629 NULL_RTX, 0, OPTAB_WIDEN); 7630 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch)); 7631 break; 7632 7633 case LE: 7634 op3 = force_reg (SImode, operands[3]); 7635 7636 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31), 7637 NULL_RTX, 1, OPTAB_WIDEN); 7638 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31), 7639 NULL_RTX, 0, OPTAB_WIDEN); 7640 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2, 7641 op3, operands[2])); 7642 break; 7643 7644 case GE: 7645 op3 = operands[3]; 7646 if (!thumb1_cmp_operand (op3, SImode)) 7647 op3 = force_reg (SImode, op3); 7648 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31), 7649 NULL_RTX, 0, OPTAB_WIDEN); 7650 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31), 7651 NULL_RTX, 1, OPTAB_WIDEN); 7652 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2, 7653 operands[2], op3)); 7654 break; 7655 7656 case LEU: 7657 op3 = force_reg (SImode, operands[3]); 7658 scratch = force_reg (SImode, const0_rtx); 7659 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch, 7660 op3, operands[2])); 7661 break; 7662 7663 case GEU: 7664 op3 = operands[3]; 7665 if (!thumb1_cmp_operand (op3, SImode)) 7666 op3 = force_reg (SImode, op3); 7667 scratch = force_reg (SImode, const0_rtx); 7668 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch, 7669 operands[2], op3)); 7670 break; 7671 7672 case LTU: 7673 op3 = operands[3]; 7674 if (!thumb1_cmp_operand (op3, SImode)) 7675 op3 = force_reg (SImode, op3); 7676 scratch = gen_reg_rtx (SImode); 7677 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3)); 7678 break; 7679 7680 case GTU: 7681 op3 = force_reg (SImode, operands[3]); 7682 scratch = gen_reg_rtx (SImode); 7683 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2])); 7684 break; 7685 7686 /* No good sequences for GT, LT. */ 7687 default: 7688 FAIL; 7689 } 7690 DONE; 7691}") 7692 7693(define_expand "cstorehf4" 7694 [(set (match_operand:SI 0 "s_register_operand") 7695 (match_operator:SI 1 "expandable_comparison_operator" 7696 [(match_operand:HF 2 "s_register_operand") 7697 (match_operand:HF 3 "vfp_compare_operand")]))] 7698 "TARGET_VFP_FP16INST" 7699 { 7700 if (!arm_validize_comparison (&operands[1], 7701 &operands[2], 7702 &operands[3])) 7703 FAIL; 7704 7705 emit_insn (gen_cstore_cc (operands[0], operands[1], 7706 operands[2], operands[3])); 7707 DONE; 7708 } 7709) 7710 7711(define_expand "cstoresf4" 7712 [(set (match_operand:SI 0 "s_register_operand" "") 7713 (match_operator:SI 1 "expandable_comparison_operator" 7714 [(match_operand:SF 2 "s_register_operand" "") 7715 (match_operand:SF 3 "vfp_compare_operand" "")]))] 7716 "TARGET_32BIT && TARGET_HARD_FLOAT" 7717 "emit_insn (gen_cstore_cc (operands[0], operands[1], 7718 operands[2], operands[3])); DONE;" 7719) 7720 7721(define_expand "cstoredf4" 7722 [(set (match_operand:SI 0 "s_register_operand" "") 7723 (match_operator:SI 1 "expandable_comparison_operator" 7724 [(match_operand:DF 2 "s_register_operand" "") 7725 (match_operand:DF 3 "vfp_compare_operand" "")]))] 7726 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 7727 "emit_insn (gen_cstore_cc (operands[0], operands[1], 7728 operands[2], operands[3])); DONE;" 7729) 7730 7731(define_expand "cstoredi4" 7732 [(set (match_operand:SI 0 "s_register_operand" "") 7733 (match_operator:SI 1 "expandable_comparison_operator" 7734 [(match_operand:DI 2 "s_register_operand" "") 7735 (match_operand:DI 3 "cmpdi_operand" "")]))] 7736 "TARGET_32BIT" 7737 "{ 7738 if (!arm_validize_comparison (&operands[1], 7739 &operands[2], 7740 &operands[3])) 7741 FAIL; 7742 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2], 7743 operands[3])); 7744 DONE; 7745 }" 7746) 7747 7748 7749;; Conditional move insns 7750 7751(define_expand "movsicc" 7752 [(set (match_operand:SI 0 "s_register_operand" "") 7753 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "") 7754 (match_operand:SI 2 "arm_not_operand" "") 7755 (match_operand:SI 3 "arm_not_operand" "")))] 7756 "TARGET_32BIT" 7757 " 7758 { 7759 enum rtx_code code; 7760 rtx ccreg; 7761 7762 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7763 &XEXP (operands[1], 1))) 7764 FAIL; 7765 7766 code = GET_CODE (operands[1]); 7767 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7768 XEXP (operands[1], 1), NULL_RTX); 7769 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7770 }" 7771) 7772 7773(define_expand "movhfcc" 7774 [(set (match_operand:HF 0 "s_register_operand") 7775 (if_then_else:HF (match_operand 1 "arm_cond_move_operator") 7776 (match_operand:HF 2 "s_register_operand") 7777 (match_operand:HF 3 "s_register_operand")))] 7778 "TARGET_VFP_FP16INST" 7779 " 7780 { 7781 enum rtx_code code = GET_CODE (operands[1]); 7782 rtx ccreg; 7783 7784 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7785 &XEXP (operands[1], 1))) 7786 FAIL; 7787 7788 code = GET_CODE (operands[1]); 7789 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7790 XEXP (operands[1], 1), NULL_RTX); 7791 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7792 }" 7793) 7794 7795(define_expand "movsfcc" 7796 [(set (match_operand:SF 0 "s_register_operand" "") 7797 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "") 7798 (match_operand:SF 2 "s_register_operand" "") 7799 (match_operand:SF 3 "s_register_operand" "")))] 7800 "TARGET_32BIT && TARGET_HARD_FLOAT" 7801 " 7802 { 7803 enum rtx_code code = GET_CODE (operands[1]); 7804 rtx ccreg; 7805 7806 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7807 &XEXP (operands[1], 1))) 7808 FAIL; 7809 7810 code = GET_CODE (operands[1]); 7811 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7812 XEXP (operands[1], 1), NULL_RTX); 7813 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7814 }" 7815) 7816 7817(define_expand "movdfcc" 7818 [(set (match_operand:DF 0 "s_register_operand" "") 7819 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "") 7820 (match_operand:DF 2 "s_register_operand" "") 7821 (match_operand:DF 3 "s_register_operand" "")))] 7822 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 7823 " 7824 { 7825 enum rtx_code code = GET_CODE (operands[1]); 7826 rtx ccreg; 7827 7828 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7829 &XEXP (operands[1], 1))) 7830 FAIL; 7831 code = GET_CODE (operands[1]); 7832 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7833 XEXP (operands[1], 1), NULL_RTX); 7834 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7835 }" 7836) 7837 7838(define_insn "*cmov<mode>" 7839 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>") 7840 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator" 7841 [(match_operand 2 "cc_register" "") (const_int 0)]) 7842 (match_operand:SDF 3 "s_register_operand" 7843 "<F_constraint>") 7844 (match_operand:SDF 4 "s_register_operand" 7845 "<F_constraint>")))] 7846 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>" 7847 "* 7848 { 7849 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]); 7850 switch (code) 7851 { 7852 case ARM_GE: 7853 case ARM_GT: 7854 case ARM_EQ: 7855 case ARM_VS: 7856 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\"; 7857 case ARM_LT: 7858 case ARM_LE: 7859 case ARM_NE: 7860 case ARM_VC: 7861 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\"; 7862 default: 7863 gcc_unreachable (); 7864 } 7865 return \"\"; 7866 }" 7867 [(set_attr "conds" "use") 7868 (set_attr "type" "fcsel")] 7869) 7870 7871(define_insn "*cmovhf" 7872 [(set (match_operand:HF 0 "s_register_operand" "=t") 7873 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator" 7874 [(match_operand 2 "cc_register" "") (const_int 0)]) 7875 (match_operand:HF 3 "s_register_operand" "t") 7876 (match_operand:HF 4 "s_register_operand" "t")))] 7877 "TARGET_VFP_FP16INST" 7878 "* 7879 { 7880 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]); 7881 switch (code) 7882 { 7883 case ARM_GE: 7884 case ARM_GT: 7885 case ARM_EQ: 7886 case ARM_VS: 7887 return \"vsel%d1.f16\\t%0, %3, %4\"; 7888 case ARM_LT: 7889 case ARM_LE: 7890 case ARM_NE: 7891 case ARM_VC: 7892 return \"vsel%D1.f16\\t%0, %4, %3\"; 7893 default: 7894 gcc_unreachable (); 7895 } 7896 return \"\"; 7897 }" 7898 [(set_attr "conds" "use") 7899 (set_attr "type" "fcsel")] 7900) 7901 7902(define_insn_and_split "*movsicc_insn" 7903 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") 7904 (if_then_else:SI 7905 (match_operator 3 "arm_comparison_operator" 7906 [(match_operand 4 "cc_register" "") (const_int 0)]) 7907 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K") 7908 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))] 7909 "TARGET_ARM" 7910 "@ 7911 mov%D3\\t%0, %2 7912 mvn%D3\\t%0, #%B2 7913 mov%d3\\t%0, %1 7914 mvn%d3\\t%0, #%B1 7915 # 7916 # 7917 # 7918 #" 7919 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2 7920 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 7921 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 7922 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2" 7923 "&& reload_completed" 7924 [(const_int 0)] 7925 { 7926 enum rtx_code rev_code; 7927 machine_mode mode; 7928 rtx rev_cond; 7929 7930 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 7931 operands[3], 7932 gen_rtx_SET (operands[0], operands[1]))); 7933 7934 rev_code = GET_CODE (operands[3]); 7935 mode = GET_MODE (operands[4]); 7936 if (mode == CCFPmode || mode == CCFPEmode) 7937 rev_code = reverse_condition_maybe_unordered (rev_code); 7938 else 7939 rev_code = reverse_condition (rev_code); 7940 7941 rev_cond = gen_rtx_fmt_ee (rev_code, 7942 VOIDmode, 7943 operands[4], 7944 const0_rtx); 7945 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 7946 rev_cond, 7947 gen_rtx_SET (operands[0], operands[2]))); 7948 DONE; 7949 } 7950 [(set_attr "length" "4,4,4,4,8,8,8,8") 7951 (set_attr "conds" "use") 7952 (set_attr_alternative "type" 7953 [(if_then_else (match_operand 2 "const_int_operand" "") 7954 (const_string "mov_imm") 7955 (const_string "mov_reg")) 7956 (const_string "mvn_imm") 7957 (if_then_else (match_operand 1 "const_int_operand" "") 7958 (const_string "mov_imm") 7959 (const_string "mov_reg")) 7960 (const_string "mvn_imm") 7961 (const_string "multiple") 7962 (const_string "multiple") 7963 (const_string "multiple") 7964 (const_string "multiple")])] 7965) 7966 7967(define_insn "*movsfcc_soft_insn" 7968 [(set (match_operand:SF 0 "s_register_operand" "=r,r") 7969 (if_then_else:SF (match_operator 3 "arm_comparison_operator" 7970 [(match_operand 4 "cc_register" "") (const_int 0)]) 7971 (match_operand:SF 1 "s_register_operand" "0,r") 7972 (match_operand:SF 2 "s_register_operand" "r,0")))] 7973 "TARGET_ARM && TARGET_SOFT_FLOAT" 7974 "@ 7975 mov%D3\\t%0, %2 7976 mov%d3\\t%0, %1" 7977 [(set_attr "conds" "use") 7978 (set_attr "type" "mov_reg")] 7979) 7980 7981 7982;; Jump and linkage insns 7983 7984(define_expand "jump" 7985 [(set (pc) 7986 (label_ref (match_operand 0 "" "")))] 7987 "TARGET_EITHER" 7988 "" 7989) 7990 7991(define_insn "*arm_jump" 7992 [(set (pc) 7993 (label_ref (match_operand 0 "" "")))] 7994 "TARGET_32BIT" 7995 "* 7996 { 7997 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 7998 { 7999 arm_ccfsm_state += 2; 8000 return \"\"; 8001 } 8002 return \"b%?\\t%l0\"; 8003 } 8004 " 8005 [(set_attr "predicable" "yes") 8006 (set (attr "length") 8007 (if_then_else 8008 (and (match_test "TARGET_THUMB2") 8009 (and (ge (minus (match_dup 0) (pc)) (const_int -2044)) 8010 (le (minus (match_dup 0) (pc)) (const_int 2048)))) 8011 (const_int 2) 8012 (const_int 4))) 8013 (set_attr "type" "branch")] 8014) 8015 8016(define_expand "call" 8017 [(parallel [(call (match_operand 0 "memory_operand" "") 8018 (match_operand 1 "general_operand" "")) 8019 (use (match_operand 2 "" "")) 8020 (clobber (reg:SI LR_REGNUM))])] 8021 "TARGET_EITHER" 8022 " 8023 { 8024 rtx callee, pat; 8025 tree addr = MEM_EXPR (operands[0]); 8026 8027 /* In an untyped call, we can get NULL for operand 2. */ 8028 if (operands[2] == NULL_RTX) 8029 operands[2] = const0_rtx; 8030 8031 /* Decide if we should generate indirect calls by loading the 8032 32-bit address of the callee into a register before performing the 8033 branch and link. */ 8034 callee = XEXP (operands[0], 0); 8035 if (GET_CODE (callee) == SYMBOL_REF 8036 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee)) 8037 : !REG_P (callee)) 8038 XEXP (operands[0], 0) = force_reg (Pmode, callee); 8039 8040 if (detect_cmse_nonsecure_call (addr)) 8041 { 8042 pat = gen_nonsecure_call_internal (operands[0], operands[1], 8043 operands[2]); 8044 emit_call_insn (pat); 8045 } 8046 else 8047 { 8048 pat = gen_call_internal (operands[0], operands[1], operands[2]); 8049 arm_emit_call_insn (pat, XEXP (operands[0], 0), false); 8050 } 8051 DONE; 8052 }" 8053) 8054 8055(define_expand "call_internal" 8056 [(parallel [(call (match_operand 0 "memory_operand" "") 8057 (match_operand 1 "general_operand" "")) 8058 (use (match_operand 2 "" "")) 8059 (clobber (reg:SI LR_REGNUM))])]) 8060 8061(define_expand "nonsecure_call_internal" 8062 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")] 8063 UNSPEC_NONSECURE_MEM) 8064 (match_operand 1 "general_operand" "")) 8065 (use (match_operand 2 "" "")) 8066 (clobber (reg:SI LR_REGNUM))])] 8067 "use_cmse" 8068 " 8069 { 8070 rtx tmp; 8071 tmp = copy_to_suggested_reg (XEXP (operands[0], 0), 8072 gen_rtx_REG (SImode, R4_REGNUM), 8073 SImode); 8074 8075 operands[0] = replace_equiv_address (operands[0], tmp); 8076 }") 8077 8078(define_insn "*call_reg_armv5" 8079 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) 8080 (match_operand 1 "" "")) 8081 (use (match_operand 2 "" "")) 8082 (clobber (reg:SI LR_REGNUM))] 8083 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)" 8084 "blx%?\\t%0" 8085 [(set_attr "type" "call")] 8086) 8087 8088(define_insn "*call_reg_arm" 8089 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) 8090 (match_operand 1 "" "")) 8091 (use (match_operand 2 "" "")) 8092 (clobber (reg:SI LR_REGNUM))] 8093 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)" 8094 "* 8095 return output_call (operands); 8096 " 8097 ;; length is worst case, normally it is only two 8098 [(set_attr "length" "12") 8099 (set_attr "type" "call")] 8100) 8101 8102 8103(define_expand "call_value" 8104 [(parallel [(set (match_operand 0 "" "") 8105 (call (match_operand 1 "memory_operand" "") 8106 (match_operand 2 "general_operand" ""))) 8107 (use (match_operand 3 "" "")) 8108 (clobber (reg:SI LR_REGNUM))])] 8109 "TARGET_EITHER" 8110 " 8111 { 8112 rtx pat, callee; 8113 tree addr = MEM_EXPR (operands[1]); 8114 8115 /* In an untyped call, we can get NULL for operand 2. */ 8116 if (operands[3] == 0) 8117 operands[3] = const0_rtx; 8118 8119 /* Decide if we should generate indirect calls by loading the 8120 32-bit address of the callee into a register before performing the 8121 branch and link. */ 8122 callee = XEXP (operands[1], 0); 8123 if (GET_CODE (callee) == SYMBOL_REF 8124 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee)) 8125 : !REG_P (callee)) 8126 XEXP (operands[1], 0) = force_reg (Pmode, callee); 8127 8128 if (detect_cmse_nonsecure_call (addr)) 8129 { 8130 pat = gen_nonsecure_call_value_internal (operands[0], operands[1], 8131 operands[2], operands[3]); 8132 emit_call_insn (pat); 8133 } 8134 else 8135 { 8136 pat = gen_call_value_internal (operands[0], operands[1], 8137 operands[2], operands[3]); 8138 arm_emit_call_insn (pat, XEXP (operands[1], 0), false); 8139 } 8140 DONE; 8141 }" 8142) 8143 8144(define_expand "call_value_internal" 8145 [(parallel [(set (match_operand 0 "" "") 8146 (call (match_operand 1 "memory_operand" "") 8147 (match_operand 2 "general_operand" ""))) 8148 (use (match_operand 3 "" "")) 8149 (clobber (reg:SI LR_REGNUM))])]) 8150 8151(define_expand "nonsecure_call_value_internal" 8152 [(parallel [(set (match_operand 0 "" "") 8153 (call (unspec:SI [(match_operand 1 "memory_operand" "")] 8154 UNSPEC_NONSECURE_MEM) 8155 (match_operand 2 "general_operand" ""))) 8156 (use (match_operand 3 "" "")) 8157 (clobber (reg:SI LR_REGNUM))])] 8158 "use_cmse" 8159 " 8160 { 8161 rtx tmp; 8162 tmp = copy_to_suggested_reg (XEXP (operands[1], 0), 8163 gen_rtx_REG (SImode, R4_REGNUM), 8164 SImode); 8165 8166 operands[1] = replace_equiv_address (operands[1], tmp); 8167 }") 8168 8169(define_insn "*call_value_reg_armv5" 8170 [(set (match_operand 0 "" "") 8171 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r")) 8172 (match_operand 2 "" ""))) 8173 (use (match_operand 3 "" "")) 8174 (clobber (reg:SI LR_REGNUM))] 8175 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)" 8176 "blx%?\\t%1" 8177 [(set_attr "type" "call")] 8178) 8179 8180(define_insn "*call_value_reg_arm" 8181 [(set (match_operand 0 "" "") 8182 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r")) 8183 (match_operand 2 "" ""))) 8184 (use (match_operand 3 "" "")) 8185 (clobber (reg:SI LR_REGNUM))] 8186 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)" 8187 "* 8188 return output_call (&operands[1]); 8189 " 8190 [(set_attr "length" "12") 8191 (set_attr "type" "call")] 8192) 8193 8194;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses 8195;; The 'a' causes the operand to be treated as an address, i.e. no '#' output. 8196 8197(define_insn "*call_symbol" 8198 [(call (mem:SI (match_operand:SI 0 "" "")) 8199 (match_operand 1 "" "")) 8200 (use (match_operand 2 "" "")) 8201 (clobber (reg:SI LR_REGNUM))] 8202 "TARGET_32BIT 8203 && !SIBLING_CALL_P (insn) 8204 && (GET_CODE (operands[0]) == SYMBOL_REF) 8205 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))" 8206 "* 8207 { 8208 rtx op = operands[0]; 8209 8210 /* Switch mode now when possible. */ 8211 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op)) 8212 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op))) 8213 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\"; 8214 8215 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\"; 8216 }" 8217 [(set_attr "type" "call")] 8218) 8219 8220(define_insn "*call_value_symbol" 8221 [(set (match_operand 0 "" "") 8222 (call (mem:SI (match_operand:SI 1 "" "")) 8223 (match_operand:SI 2 "" ""))) 8224 (use (match_operand 3 "" "")) 8225 (clobber (reg:SI LR_REGNUM))] 8226 "TARGET_32BIT 8227 && !SIBLING_CALL_P (insn) 8228 && (GET_CODE (operands[1]) == SYMBOL_REF) 8229 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" 8230 "* 8231 { 8232 rtx op = operands[1]; 8233 8234 /* Switch mode now when possible. */ 8235 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op)) 8236 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op))) 8237 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\"; 8238 8239 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\"; 8240 }" 8241 [(set_attr "type" "call")] 8242) 8243 8244(define_expand "sibcall_internal" 8245 [(parallel [(call (match_operand 0 "memory_operand" "") 8246 (match_operand 1 "general_operand" "")) 8247 (return) 8248 (use (match_operand 2 "" ""))])]) 8249 8250;; We may also be able to do sibcalls for Thumb, but it's much harder... 8251(define_expand "sibcall" 8252 [(parallel [(call (match_operand 0 "memory_operand" "") 8253 (match_operand 1 "general_operand" "")) 8254 (return) 8255 (use (match_operand 2 "" ""))])] 8256 "TARGET_32BIT" 8257 " 8258 { 8259 rtx pat; 8260 8261 if ((!REG_P (XEXP (operands[0], 0)) 8262 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF) 8263 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF 8264 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0))))) 8265 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); 8266 8267 if (operands[2] == NULL_RTX) 8268 operands[2] = const0_rtx; 8269 8270 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]); 8271 arm_emit_call_insn (pat, operands[0], true); 8272 DONE; 8273 }" 8274) 8275 8276(define_expand "sibcall_value_internal" 8277 [(parallel [(set (match_operand 0 "" "") 8278 (call (match_operand 1 "memory_operand" "") 8279 (match_operand 2 "general_operand" ""))) 8280 (return) 8281 (use (match_operand 3 "" ""))])]) 8282 8283(define_expand "sibcall_value" 8284 [(parallel [(set (match_operand 0 "" "") 8285 (call (match_operand 1 "memory_operand" "") 8286 (match_operand 2 "general_operand" ""))) 8287 (return) 8288 (use (match_operand 3 "" ""))])] 8289 "TARGET_32BIT" 8290 " 8291 { 8292 rtx pat; 8293 8294 if ((!REG_P (XEXP (operands[1], 0)) 8295 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF) 8296 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF 8297 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0))))) 8298 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); 8299 8300 if (operands[3] == NULL_RTX) 8301 operands[3] = const0_rtx; 8302 8303 pat = gen_sibcall_value_internal (operands[0], operands[1], 8304 operands[2], operands[3]); 8305 arm_emit_call_insn (pat, operands[1], true); 8306 DONE; 8307 }" 8308) 8309 8310(define_insn "*sibcall_insn" 8311 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US")) 8312 (match_operand 1 "" "")) 8313 (return) 8314 (use (match_operand 2 "" ""))] 8315 "TARGET_32BIT && SIBLING_CALL_P (insn)" 8316 "* 8317 if (which_alternative == 1) 8318 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\"; 8319 else 8320 { 8321 if (arm_arch5 || arm_arch4t) 8322 return \"bx%?\\t%0\\t%@ indirect register sibling call\"; 8323 else 8324 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\"; 8325 } 8326 " 8327 [(set_attr "type" "call")] 8328) 8329 8330(define_insn "*sibcall_value_insn" 8331 [(set (match_operand 0 "" "") 8332 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US")) 8333 (match_operand 2 "" ""))) 8334 (return) 8335 (use (match_operand 3 "" ""))] 8336 "TARGET_32BIT && SIBLING_CALL_P (insn)" 8337 "* 8338 if (which_alternative == 1) 8339 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\"; 8340 else 8341 { 8342 if (arm_arch5 || arm_arch4t) 8343 return \"bx%?\\t%1\"; 8344 else 8345 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \"; 8346 } 8347 " 8348 [(set_attr "type" "call")] 8349) 8350 8351(define_expand "<return_str>return" 8352 [(RETURNS)] 8353 "(TARGET_ARM || (TARGET_THUMB2 8354 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL 8355 && !IS_STACKALIGN (arm_current_func_type ()))) 8356 <return_cond_false>" 8357 " 8358 { 8359 if (TARGET_THUMB2) 8360 { 8361 thumb2_expand_return (<return_simple_p>); 8362 DONE; 8363 } 8364 } 8365 " 8366) 8367 8368;; Often the return insn will be the same as loading from memory, so set attr 8369(define_insn "*arm_return" 8370 [(return)] 8371 "TARGET_ARM && USE_RETURN_INSN (FALSE)" 8372 "* 8373 { 8374 if (arm_ccfsm_state == 2) 8375 { 8376 arm_ccfsm_state += 2; 8377 return \"\"; 8378 } 8379 return output_return_instruction (const_true_rtx, true, false, false); 8380 }" 8381 [(set_attr "type" "load_4") 8382 (set_attr "length" "12") 8383 (set_attr "predicable" "yes")] 8384) 8385 8386(define_insn "*cond_<return_str>return" 8387 [(set (pc) 8388 (if_then_else (match_operator 0 "arm_comparison_operator" 8389 [(match_operand 1 "cc_register" "") (const_int 0)]) 8390 (RETURNS) 8391 (pc)))] 8392 "TARGET_ARM <return_cond_true>" 8393 "* 8394 { 8395 if (arm_ccfsm_state == 2) 8396 { 8397 arm_ccfsm_state += 2; 8398 return \"\"; 8399 } 8400 return output_return_instruction (operands[0], true, false, 8401 <return_simple_p>); 8402 }" 8403 [(set_attr "conds" "use") 8404 (set_attr "length" "12") 8405 (set_attr "type" "load_4")] 8406) 8407 8408(define_insn "*cond_<return_str>return_inverted" 8409 [(set (pc) 8410 (if_then_else (match_operator 0 "arm_comparison_operator" 8411 [(match_operand 1 "cc_register" "") (const_int 0)]) 8412 (pc) 8413 (RETURNS)))] 8414 "TARGET_ARM <return_cond_true>" 8415 "* 8416 { 8417 if (arm_ccfsm_state == 2) 8418 { 8419 arm_ccfsm_state += 2; 8420 return \"\"; 8421 } 8422 return output_return_instruction (operands[0], true, true, 8423 <return_simple_p>); 8424 }" 8425 [(set_attr "conds" "use") 8426 (set_attr "length" "12") 8427 (set_attr "type" "load_4")] 8428) 8429 8430(define_insn "*arm_simple_return" 8431 [(simple_return)] 8432 "TARGET_ARM" 8433 "* 8434 { 8435 if (arm_ccfsm_state == 2) 8436 { 8437 arm_ccfsm_state += 2; 8438 return \"\"; 8439 } 8440 return output_return_instruction (const_true_rtx, true, false, true); 8441 }" 8442 [(set_attr "type" "branch") 8443 (set_attr "length" "4") 8444 (set_attr "predicable" "yes")] 8445) 8446 8447;; Generate a sequence of instructions to determine if the processor is 8448;; in 26-bit or 32-bit mode, and return the appropriate return address 8449;; mask. 8450 8451(define_expand "return_addr_mask" 8452 [(set (match_dup 1) 8453 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH) 8454 (const_int 0))) 8455 (set (match_operand:SI 0 "s_register_operand" "") 8456 (if_then_else:SI (eq (match_dup 1) (const_int 0)) 8457 (const_int -1) 8458 (const_int 67108860)))] ; 0x03fffffc 8459 "TARGET_ARM" 8460 " 8461 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM); 8462 ") 8463 8464(define_insn "*check_arch2" 8465 [(set (match_operand:CC_NOOV 0 "cc_register" "") 8466 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH) 8467 (const_int 0)))] 8468 "TARGET_ARM" 8469 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc" 8470 [(set_attr "length" "8") 8471 (set_attr "conds" "set") 8472 (set_attr "type" "multiple")] 8473) 8474 8475;; Call subroutine returning any type. 8476 8477(define_expand "untyped_call" 8478 [(parallel [(call (match_operand 0 "" "") 8479 (const_int 0)) 8480 (match_operand 1 "" "") 8481 (match_operand 2 "" "")])] 8482 "TARGET_EITHER" 8483 " 8484 { 8485 int i; 8486 rtx par = gen_rtx_PARALLEL (VOIDmode, 8487 rtvec_alloc (XVECLEN (operands[2], 0))); 8488 rtx addr = gen_reg_rtx (Pmode); 8489 rtx mem; 8490 int size = 0; 8491 8492 emit_move_insn (addr, XEXP (operands[1], 0)); 8493 mem = change_address (operands[1], BLKmode, addr); 8494 8495 for (i = 0; i < XVECLEN (operands[2], 0); i++) 8496 { 8497 rtx src = SET_SRC (XVECEXP (operands[2], 0, i)); 8498 8499 /* Default code only uses r0 as a return value, but we could 8500 be using anything up to 4 registers. */ 8501 if (REGNO (src) == R0_REGNUM) 8502 src = gen_rtx_REG (TImode, R0_REGNUM); 8503 8504 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src, 8505 GEN_INT (size)); 8506 size += GET_MODE_SIZE (GET_MODE (src)); 8507 } 8508 8509 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL)); 8510 8511 size = 0; 8512 8513 for (i = 0; i < XVECLEN (par, 0); i++) 8514 { 8515 HOST_WIDE_INT offset = 0; 8516 rtx reg = XEXP (XVECEXP (par, 0, i), 0); 8517 8518 if (size != 0) 8519 emit_move_insn (addr, plus_constant (Pmode, addr, size)); 8520 8521 mem = change_address (mem, GET_MODE (reg), NULL); 8522 if (REGNO (reg) == R0_REGNUM) 8523 { 8524 /* On thumb we have to use a write-back instruction. */ 8525 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr, 8526 TARGET_THUMB ? TRUE : FALSE, mem, &offset)); 8527 size = TARGET_ARM ? 16 : 0; 8528 } 8529 else 8530 { 8531 emit_move_insn (mem, reg); 8532 size = GET_MODE_SIZE (GET_MODE (reg)); 8533 } 8534 } 8535 8536 /* The optimizer does not know that the call sets the function value 8537 registers we stored in the result block. We avoid problems by 8538 claiming that all hard registers are used and clobbered at this 8539 point. */ 8540 emit_insn (gen_blockage ()); 8541 8542 DONE; 8543 }" 8544) 8545 8546(define_expand "untyped_return" 8547 [(match_operand:BLK 0 "memory_operand" "") 8548 (match_operand 1 "" "")] 8549 "TARGET_EITHER" 8550 " 8551 { 8552 int i; 8553 rtx addr = gen_reg_rtx (Pmode); 8554 rtx mem; 8555 int size = 0; 8556 8557 emit_move_insn (addr, XEXP (operands[0], 0)); 8558 mem = change_address (operands[0], BLKmode, addr); 8559 8560 for (i = 0; i < XVECLEN (operands[1], 0); i++) 8561 { 8562 HOST_WIDE_INT offset = 0; 8563 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i)); 8564 8565 if (size != 0) 8566 emit_move_insn (addr, plus_constant (Pmode, addr, size)); 8567 8568 mem = change_address (mem, GET_MODE (reg), NULL); 8569 if (REGNO (reg) == R0_REGNUM) 8570 { 8571 /* On thumb we have to use a write-back instruction. */ 8572 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr, 8573 TARGET_THUMB ? TRUE : FALSE, mem, &offset)); 8574 size = TARGET_ARM ? 16 : 0; 8575 } 8576 else 8577 { 8578 emit_move_insn (reg, mem); 8579 size = GET_MODE_SIZE (GET_MODE (reg)); 8580 } 8581 } 8582 8583 /* Emit USE insns before the return. */ 8584 for (i = 0; i < XVECLEN (operands[1], 0); i++) 8585 emit_use (SET_DEST (XVECEXP (operands[1], 0, i))); 8586 8587 /* Construct the return. */ 8588 expand_naked_return (); 8589 8590 DONE; 8591 }" 8592) 8593 8594;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 8595;; all of memory. This blocks insns from being moved across this point. 8596 8597(define_insn "blockage" 8598 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)] 8599 "TARGET_EITHER" 8600 "" 8601 [(set_attr "length" "0") 8602 (set_attr "type" "block")] 8603) 8604 8605;; Since we hard code r0 here use the 'o' constraint to prevent 8606;; provoking undefined behaviour in the hardware with putting out 8607;; auto-increment operations with potentially r0 as the base register. 8608(define_insn "probe_stack" 8609 [(set (match_operand:SI 0 "memory_operand" "=o") 8610 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))] 8611 "TARGET_32BIT" 8612 "str%?\\tr0, %0" 8613 [(set_attr "type" "store_4") 8614 (set_attr "predicable" "yes")] 8615) 8616 8617(define_insn "probe_stack_range" 8618 [(set (match_operand:SI 0 "register_operand" "=r") 8619 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0") 8620 (match_operand:SI 2 "register_operand" "r")] 8621 VUNSPEC_PROBE_STACK_RANGE))] 8622 "TARGET_32BIT" 8623{ 8624 return output_probe_stack_range (operands[0], operands[2]); 8625} 8626 [(set_attr "type" "multiple") 8627 (set_attr "conds" "clob")] 8628) 8629 8630(define_expand "casesi" 8631 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on 8632 (match_operand:SI 1 "const_int_operand" "") ; lower bound 8633 (match_operand:SI 2 "const_int_operand" "") ; total range 8634 (match_operand:SI 3 "" "") ; table label 8635 (match_operand:SI 4 "" "")] ; Out of range label 8636 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code" 8637 " 8638 { 8639 enum insn_code code; 8640 if (operands[1] != const0_rtx) 8641 { 8642 rtx reg = gen_reg_rtx (SImode); 8643 8644 emit_insn (gen_addsi3 (reg, operands[0], 8645 gen_int_mode (-INTVAL (operands[1]), 8646 SImode))); 8647 operands[0] = reg; 8648 } 8649 8650 if (TARGET_ARM) 8651 code = CODE_FOR_arm_casesi_internal; 8652 else if (TARGET_THUMB1) 8653 code = CODE_FOR_thumb1_casesi_internal_pic; 8654 else if (flag_pic) 8655 code = CODE_FOR_thumb2_casesi_internal_pic; 8656 else 8657 code = CODE_FOR_thumb2_casesi_internal; 8658 8659 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode)) 8660 operands[2] = force_reg (SImode, operands[2]); 8661 8662 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2], 8663 operands[3], operands[4])); 8664 DONE; 8665 }" 8666) 8667 8668;; The USE in this pattern is needed to tell flow analysis that this is 8669;; a CASESI insn. It has no other purpose. 8670(define_insn "arm_casesi_internal" 8671 [(parallel [(set (pc) 8672 (if_then_else 8673 (leu (match_operand:SI 0 "s_register_operand" "r") 8674 (match_operand:SI 1 "arm_rhs_operand" "rI")) 8675 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) 8676 (label_ref (match_operand 2 "" "")))) 8677 (label_ref (match_operand 3 "" "")))) 8678 (clobber (reg:CC CC_REGNUM)) 8679 (use (label_ref (match_dup 2)))])] 8680 "TARGET_ARM" 8681 "* 8682 if (flag_pic) 8683 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\"; 8684 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\"; 8685 " 8686 [(set_attr "conds" "clob") 8687 (set_attr "length" "12") 8688 (set_attr "type" "multiple")] 8689) 8690 8691(define_expand "indirect_jump" 8692 [(set (pc) 8693 (match_operand:SI 0 "s_register_operand" ""))] 8694 "TARGET_EITHER" 8695 " 8696 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the 8697 address and use bx. */ 8698 if (TARGET_THUMB2) 8699 { 8700 rtx tmp; 8701 tmp = gen_reg_rtx (SImode); 8702 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1))); 8703 operands[0] = tmp; 8704 } 8705 " 8706) 8707 8708;; NB Never uses BX. 8709(define_insn "*arm_indirect_jump" 8710 [(set (pc) 8711 (match_operand:SI 0 "s_register_operand" "r"))] 8712 "TARGET_ARM" 8713 "mov%?\\t%|pc, %0\\t%@ indirect register jump" 8714 [(set_attr "predicable" "yes") 8715 (set_attr "type" "branch")] 8716) 8717 8718(define_insn "*load_indirect_jump" 8719 [(set (pc) 8720 (match_operand:SI 0 "memory_operand" "m"))] 8721 "TARGET_ARM" 8722 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump" 8723 [(set_attr "type" "load_4") 8724 (set_attr "pool_range" "4096") 8725 (set_attr "neg_pool_range" "4084") 8726 (set_attr "predicable" "yes")] 8727) 8728 8729 8730;; Misc insns 8731 8732(define_insn "nop" 8733 [(const_int 0)] 8734 "TARGET_EITHER" 8735 "nop" 8736 [(set (attr "length") 8737 (if_then_else (eq_attr "is_thumb" "yes") 8738 (const_int 2) 8739 (const_int 4))) 8740 (set_attr "type" "mov_reg")] 8741) 8742 8743(define_insn "trap" 8744 [(trap_if (const_int 1) (const_int 0))] 8745 "" 8746 "* 8747 if (TARGET_ARM) 8748 return \".inst\\t0xe7f000f0\"; 8749 else 8750 return \".inst\\t0xdeff\"; 8751 " 8752 [(set (attr "length") 8753 (if_then_else (eq_attr "is_thumb" "yes") 8754 (const_int 2) 8755 (const_int 4))) 8756 (set_attr "type" "trap") 8757 (set_attr "conds" "unconditional")] 8758) 8759 8760 8761;; Patterns to allow combination of arithmetic, cond code and shifts 8762 8763(define_insn "*<arith_shift_insn>_multsi" 8764 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 8765 (SHIFTABLE_OPS:SI 8766 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") 8767 (match_operand:SI 3 "power_of_two_operand" "")) 8768 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))] 8769 "TARGET_32BIT" 8770 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3" 8771 [(set_attr "predicable" "yes") 8772 (set_attr "shift" "2") 8773 (set_attr "arch" "a,t2") 8774 (set_attr "type" "alu_shift_imm")]) 8775 8776(define_insn "*<arith_shift_insn>_shiftsi" 8777 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 8778 (SHIFTABLE_OPS:SI 8779 (match_operator:SI 2 "shift_nomul_operator" 8780 [(match_operand:SI 3 "s_register_operand" "r,r,r") 8781 (match_operand:SI 4 "shift_amount_operand" "M,M,r")]) 8782 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))] 8783 "TARGET_32BIT && GET_CODE (operands[2]) != MULT" 8784 "<arith_shift_insn>%?\\t%0, %1, %3%S2" 8785 [(set_attr "predicable" "yes") 8786 (set_attr "shift" "3") 8787 (set_attr "arch" "a,t2,a") 8788 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")]) 8789 8790(define_split 8791 [(set (match_operand:SI 0 "s_register_operand" "") 8792 (match_operator:SI 1 "shiftable_operator" 8793 [(match_operator:SI 2 "shiftable_operator" 8794 [(match_operator:SI 3 "shift_operator" 8795 [(match_operand:SI 4 "s_register_operand" "") 8796 (match_operand:SI 5 "reg_or_int_operand" "")]) 8797 (match_operand:SI 6 "s_register_operand" "")]) 8798 (match_operand:SI 7 "arm_rhs_operand" "")])) 8799 (clobber (match_operand:SI 8 "s_register_operand" ""))] 8800 "TARGET_32BIT" 8801 [(set (match_dup 8) 8802 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)]) 8803 (match_dup 6)])) 8804 (set (match_dup 0) 8805 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))] 8806 "") 8807 8808(define_insn "*arith_shiftsi_compare0" 8809 [(set (reg:CC_NOOV CC_REGNUM) 8810 (compare:CC_NOOV 8811 (match_operator:SI 1 "shiftable_operator" 8812 [(match_operator:SI 3 "shift_operator" 8813 [(match_operand:SI 4 "s_register_operand" "r,r") 8814 (match_operand:SI 5 "shift_amount_operand" "M,r")]) 8815 (match_operand:SI 2 "s_register_operand" "r,r")]) 8816 (const_int 0))) 8817 (set (match_operand:SI 0 "s_register_operand" "=r,r") 8818 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)]) 8819 (match_dup 2)]))] 8820 "TARGET_32BIT" 8821 "%i1s%?\\t%0, %2, %4%S3" 8822 [(set_attr "conds" "set") 8823 (set_attr "shift" "4") 8824 (set_attr "arch" "32,a") 8825 (set_attr "type" "alus_shift_imm,alus_shift_reg")]) 8826 8827(define_insn "*arith_shiftsi_compare0_scratch" 8828 [(set (reg:CC_NOOV CC_REGNUM) 8829 (compare:CC_NOOV 8830 (match_operator:SI 1 "shiftable_operator" 8831 [(match_operator:SI 3 "shift_operator" 8832 [(match_operand:SI 4 "s_register_operand" "r,r") 8833 (match_operand:SI 5 "shift_amount_operand" "M,r")]) 8834 (match_operand:SI 2 "s_register_operand" "r,r")]) 8835 (const_int 0))) 8836 (clobber (match_scratch:SI 0 "=r,r"))] 8837 "TARGET_32BIT" 8838 "%i1s%?\\t%0, %2, %4%S3" 8839 [(set_attr "conds" "set") 8840 (set_attr "shift" "4") 8841 (set_attr "arch" "32,a") 8842 (set_attr "type" "alus_shift_imm,alus_shift_reg")]) 8843 8844(define_insn "*sub_shiftsi" 8845 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 8846 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r") 8847 (match_operator:SI 2 "shift_operator" 8848 [(match_operand:SI 3 "s_register_operand" "r,r") 8849 (match_operand:SI 4 "shift_amount_operand" "M,r")])))] 8850 "TARGET_32BIT" 8851 "sub%?\\t%0, %1, %3%S2" 8852 [(set_attr "predicable" "yes") 8853 (set_attr "predicable_short_it" "no") 8854 (set_attr "shift" "3") 8855 (set_attr "arch" "32,a") 8856 (set_attr "type" "alus_shift_imm,alus_shift_reg")]) 8857 8858(define_insn "*sub_shiftsi_compare0" 8859 [(set (reg:CC_NOOV CC_REGNUM) 8860 (compare:CC_NOOV 8861 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 8862 (match_operator:SI 2 "shift_operator" 8863 [(match_operand:SI 3 "s_register_operand" "r,r,r") 8864 (match_operand:SI 4 "shift_amount_operand" "M,r,M")])) 8865 (const_int 0))) 8866 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 8867 (minus:SI (match_dup 1) 8868 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))] 8869 "TARGET_32BIT" 8870 "subs%?\\t%0, %1, %3%S2" 8871 [(set_attr "conds" "set") 8872 (set_attr "shift" "3") 8873 (set_attr "arch" "32,a,a") 8874 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 8875 8876(define_insn "*sub_shiftsi_compare0_scratch" 8877 [(set (reg:CC_NOOV CC_REGNUM) 8878 (compare:CC_NOOV 8879 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 8880 (match_operator:SI 2 "shift_operator" 8881 [(match_operand:SI 3 "s_register_operand" "r,r,r") 8882 (match_operand:SI 4 "shift_amount_operand" "M,r,M")])) 8883 (const_int 0))) 8884 (clobber (match_scratch:SI 0 "=r,r,r"))] 8885 "TARGET_32BIT" 8886 "subs%?\\t%0, %1, %3%S2" 8887 [(set_attr "conds" "set") 8888 (set_attr "shift" "3") 8889 (set_attr "arch" "32,a,a") 8890 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 8891 8892 8893(define_insn_and_split "*and_scc" 8894 [(set (match_operand:SI 0 "s_register_operand" "=r") 8895 (and:SI (match_operator:SI 1 "arm_comparison_operator" 8896 [(match_operand 2 "cc_register" "") (const_int 0)]) 8897 (match_operand:SI 3 "s_register_operand" "r")))] 8898 "TARGET_ARM" 8899 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1" 8900 "&& reload_completed" 8901 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0))) 8902 (cond_exec (match_dup 4) (set (match_dup 0) 8903 (and:SI (match_dup 3) (const_int 1))))] 8904 { 8905 machine_mode mode = GET_MODE (operands[2]); 8906 enum rtx_code rc = GET_CODE (operands[1]); 8907 8908 /* Note that operands[4] is the same as operands[1], 8909 but with VOIDmode as the result. */ 8910 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 8911 if (mode == CCFPmode || mode == CCFPEmode) 8912 rc = reverse_condition_maybe_unordered (rc); 8913 else 8914 rc = reverse_condition (rc); 8915 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 8916 } 8917 [(set_attr "conds" "use") 8918 (set_attr "type" "multiple") 8919 (set_attr "length" "8")] 8920) 8921 8922(define_insn_and_split "*ior_scc" 8923 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 8924 (ior:SI (match_operator:SI 1 "arm_comparison_operator" 8925 [(match_operand 2 "cc_register" "") (const_int 0)]) 8926 (match_operand:SI 3 "s_register_operand" "0,?r")))] 8927 "TARGET_ARM" 8928 "@ 8929 orr%d1\\t%0, %3, #1 8930 #" 8931 "&& reload_completed 8932 && REGNO (operands [0]) != REGNO (operands[3])" 8933 ;; && which_alternative == 1 8934 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1 8935 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3))) 8936 (cond_exec (match_dup 4) (set (match_dup 0) 8937 (ior:SI (match_dup 3) (const_int 1))))] 8938 { 8939 machine_mode mode = GET_MODE (operands[2]); 8940 enum rtx_code rc = GET_CODE (operands[1]); 8941 8942 /* Note that operands[4] is the same as operands[1], 8943 but with VOIDmode as the result. */ 8944 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 8945 if (mode == CCFPmode || mode == CCFPEmode) 8946 rc = reverse_condition_maybe_unordered (rc); 8947 else 8948 rc = reverse_condition (rc); 8949 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 8950 } 8951 [(set_attr "conds" "use") 8952 (set_attr "length" "4,8") 8953 (set_attr "type" "logic_imm,multiple")] 8954) 8955 8956; A series of splitters for the compare_scc pattern below. Note that 8957; order is important. 8958(define_split 8959 [(set (match_operand:SI 0 "s_register_operand" "") 8960 (lt:SI (match_operand:SI 1 "s_register_operand" "") 8961 (const_int 0))) 8962 (clobber (reg:CC CC_REGNUM))] 8963 "TARGET_32BIT && reload_completed" 8964 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))]) 8965 8966(define_split 8967 [(set (match_operand:SI 0 "s_register_operand" "") 8968 (ge:SI (match_operand:SI 1 "s_register_operand" "") 8969 (const_int 0))) 8970 (clobber (reg:CC CC_REGNUM))] 8971 "TARGET_32BIT && reload_completed" 8972 [(set (match_dup 0) (not:SI (match_dup 1))) 8973 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))]) 8974 8975(define_split 8976 [(set (match_operand:SI 0 "s_register_operand" "") 8977 (eq:SI (match_operand:SI 1 "s_register_operand" "") 8978 (const_int 0))) 8979 (clobber (reg:CC CC_REGNUM))] 8980 "arm_arch5 && TARGET_32BIT" 8981 [(set (match_dup 0) (clz:SI (match_dup 1))) 8982 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))] 8983) 8984 8985(define_split 8986 [(set (match_operand:SI 0 "s_register_operand" "") 8987 (eq:SI (match_operand:SI 1 "s_register_operand" "") 8988 (const_int 0))) 8989 (clobber (reg:CC CC_REGNUM))] 8990 "TARGET_32BIT && reload_completed" 8991 [(parallel 8992 [(set (reg:CC CC_REGNUM) 8993 (compare:CC (const_int 1) (match_dup 1))) 8994 (set (match_dup 0) 8995 (minus:SI (const_int 1) (match_dup 1)))]) 8996 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0)) 8997 (set (match_dup 0) (const_int 0)))]) 8998 8999(define_split 9000 [(set (match_operand:SI 0 "s_register_operand" "") 9001 (ne:SI (match_operand:SI 1 "s_register_operand" "") 9002 (match_operand:SI 2 "const_int_operand" ""))) 9003 (clobber (reg:CC CC_REGNUM))] 9004 "TARGET_32BIT && reload_completed" 9005 [(parallel 9006 [(set (reg:CC CC_REGNUM) 9007 (compare:CC (match_dup 1) (match_dup 2))) 9008 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]) 9009 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0)) 9010 (set (match_dup 0) (const_int 1)))] 9011{ 9012 operands[3] = GEN_INT (-INTVAL (operands[2])); 9013}) 9014 9015(define_split 9016 [(set (match_operand:SI 0 "s_register_operand" "") 9017 (ne:SI (match_operand:SI 1 "s_register_operand" "") 9018 (match_operand:SI 2 "arm_add_operand" ""))) 9019 (clobber (reg:CC CC_REGNUM))] 9020 "TARGET_32BIT && reload_completed" 9021 [(parallel 9022 [(set (reg:CC_NOOV CC_REGNUM) 9023 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2)) 9024 (const_int 0))) 9025 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 9026 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0)) 9027 (set (match_dup 0) (const_int 1)))]) 9028 9029(define_insn_and_split "*compare_scc" 9030 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 9031 (match_operator:SI 1 "arm_comparison_operator" 9032 [(match_operand:SI 2 "s_register_operand" "r,r") 9033 (match_operand:SI 3 "arm_add_operand" "rI,L")])) 9034 (clobber (reg:CC CC_REGNUM))] 9035 "TARGET_32BIT" 9036 "#" 9037 "&& reload_completed" 9038 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3))) 9039 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0))) 9040 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))] 9041{ 9042 rtx tmp1; 9043 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 9044 operands[2], operands[3]); 9045 enum rtx_code rc = GET_CODE (operands[1]); 9046 9047 tmp1 = gen_rtx_REG (mode, CC_REGNUM); 9048 9049 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx); 9050 if (mode == CCFPmode || mode == CCFPEmode) 9051 rc = reverse_condition_maybe_unordered (rc); 9052 else 9053 rc = reverse_condition (rc); 9054 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx); 9055} 9056 [(set_attr "type" "multiple")] 9057) 9058 9059;; Attempt to improve the sequence generated by the compare_scc splitters 9060;; not to use conditional execution. 9061 9062;; Rd = (eq (reg1) (const_int0)) // ARMv5 9063;; clz Rd, reg1 9064;; lsr Rd, Rd, #5 9065(define_peephole2 9066 [(set (reg:CC CC_REGNUM) 9067 (compare:CC (match_operand:SI 1 "register_operand" "") 9068 (const_int 0))) 9069 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9070 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9071 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9072 (set (match_dup 0) (const_int 1)))] 9073 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)" 9074 [(set (match_dup 0) (clz:SI (match_dup 1))) 9075 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))] 9076) 9077 9078;; Rd = (eq (reg1) (const_int0)) // !ARMv5 9079;; negs Rd, reg1 9080;; adc Rd, Rd, reg1 9081(define_peephole2 9082 [(set (reg:CC CC_REGNUM) 9083 (compare:CC (match_operand:SI 1 "register_operand" "") 9084 (const_int 0))) 9085 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9086 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9087 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9088 (set (match_dup 0) (const_int 1))) 9089 (match_scratch:SI 2 "r")] 9090 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)" 9091 [(parallel 9092 [(set (reg:CC CC_REGNUM) 9093 (compare:CC (const_int 0) (match_dup 1))) 9094 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))]) 9095 (set (match_dup 0) 9096 (plus:SI (plus:SI (match_dup 1) (match_dup 2)) 9097 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))] 9098) 9099 9100;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed. 9101;; sub Rd, Reg1, reg2 9102;; clz Rd, Rd 9103;; lsr Rd, Rd, #5 9104(define_peephole2 9105 [(set (reg:CC CC_REGNUM) 9106 (compare:CC (match_operand:SI 1 "register_operand" "") 9107 (match_operand:SI 2 "arm_rhs_operand" ""))) 9108 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9109 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9110 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9111 (set (match_dup 0) (const_int 1)))] 9112 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM) 9113 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())" 9114 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2))) 9115 (set (match_dup 0) (clz:SI (match_dup 0))) 9116 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))] 9117) 9118 9119 9120;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size. 9121;; sub T1, Reg1, reg2 9122;; negs Rd, T1 9123;; adc Rd, Rd, T1 9124(define_peephole2 9125 [(set (reg:CC CC_REGNUM) 9126 (compare:CC (match_operand:SI 1 "register_operand" "") 9127 (match_operand:SI 2 "arm_rhs_operand" ""))) 9128 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9129 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9130 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9131 (set (match_dup 0) (const_int 1))) 9132 (match_scratch:SI 3 "r")] 9133 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)" 9134 [(set (match_dup 3) (match_dup 4)) 9135 (parallel 9136 [(set (reg:CC CC_REGNUM) 9137 (compare:CC (const_int 0) (match_dup 3))) 9138 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))]) 9139 (set (match_dup 0) 9140 (plus:SI (plus:SI (match_dup 0) (match_dup 3)) 9141 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))] 9142 " 9143 if (CONST_INT_P (operands[2])) 9144 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2])); 9145 else 9146 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]); 9147 ") 9148 9149(define_insn "*cond_move" 9150 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 9151 (if_then_else:SI (match_operator 3 "equality_operator" 9152 [(match_operator 4 "arm_comparison_operator" 9153 [(match_operand 5 "cc_register" "") (const_int 0)]) 9154 (const_int 0)]) 9155 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") 9156 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))] 9157 "TARGET_ARM" 9158 "* 9159 if (GET_CODE (operands[3]) == NE) 9160 { 9161 if (which_alternative != 1) 9162 output_asm_insn (\"mov%D4\\t%0, %2\", operands); 9163 if (which_alternative != 0) 9164 output_asm_insn (\"mov%d4\\t%0, %1\", operands); 9165 return \"\"; 9166 } 9167 if (which_alternative != 0) 9168 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 9169 if (which_alternative != 1) 9170 output_asm_insn (\"mov%d4\\t%0, %2\", operands); 9171 return \"\"; 9172 " 9173 [(set_attr "conds" "use") 9174 (set_attr_alternative "type" 9175 [(if_then_else (match_operand 2 "const_int_operand" "") 9176 (const_string "mov_imm") 9177 (const_string "mov_reg")) 9178 (if_then_else (match_operand 1 "const_int_operand" "") 9179 (const_string "mov_imm") 9180 (const_string "mov_reg")) 9181 (const_string "multiple")]) 9182 (set_attr "length" "4,4,8")] 9183) 9184 9185(define_insn "*cond_arith" 9186 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9187 (match_operator:SI 5 "shiftable_operator" 9188 [(match_operator:SI 4 "arm_comparison_operator" 9189 [(match_operand:SI 2 "s_register_operand" "r,r") 9190 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 9191 (match_operand:SI 1 "s_register_operand" "0,?r")])) 9192 (clobber (reg:CC CC_REGNUM))] 9193 "TARGET_ARM" 9194 "* 9195 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) 9196 return \"%i5\\t%0, %1, %2, lsr #31\"; 9197 9198 output_asm_insn (\"cmp\\t%2, %3\", operands); 9199 if (GET_CODE (operands[5]) == AND) 9200 output_asm_insn (\"mov%D4\\t%0, #0\", operands); 9201 else if (GET_CODE (operands[5]) == MINUS) 9202 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands); 9203 else if (which_alternative != 0) 9204 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 9205 return \"%i5%d4\\t%0, %1, #1\"; 9206 " 9207 [(set_attr "conds" "clob") 9208 (set_attr "length" "12") 9209 (set_attr "type" "multiple")] 9210) 9211 9212(define_insn "*cond_sub" 9213 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9214 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") 9215 (match_operator:SI 4 "arm_comparison_operator" 9216 [(match_operand:SI 2 "s_register_operand" "r,r") 9217 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) 9218 (clobber (reg:CC CC_REGNUM))] 9219 "TARGET_ARM" 9220 "* 9221 output_asm_insn (\"cmp\\t%2, %3\", operands); 9222 if (which_alternative != 0) 9223 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 9224 return \"sub%d4\\t%0, %1, #1\"; 9225 " 9226 [(set_attr "conds" "clob") 9227 (set_attr "length" "8,12") 9228 (set_attr "type" "multiple")] 9229) 9230 9231(define_insn "*cmp_ite0" 9232 [(set (match_operand 6 "dominant_cc_register" "") 9233 (compare 9234 (if_then_else:SI 9235 (match_operator 4 "arm_comparison_operator" 9236 [(match_operand:SI 0 "s_register_operand" 9237 "l,l,l,r,r,r,r,r,r") 9238 (match_operand:SI 1 "arm_add_operand" 9239 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9240 (match_operator:SI 5 "arm_comparison_operator" 9241 [(match_operand:SI 2 "s_register_operand" 9242 "l,r,r,l,l,r,r,r,r") 9243 (match_operand:SI 3 "arm_add_operand" 9244 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]) 9245 (const_int 0)) 9246 (const_int 0)))] 9247 "TARGET_32BIT" 9248 "* 9249 { 9250 static const char * const cmp1[NUM_OF_COND_CMP][2] = 9251 { 9252 {\"cmp%d5\\t%0, %1\", 9253 \"cmp%d4\\t%2, %3\"}, 9254 {\"cmn%d5\\t%0, #%n1\", 9255 \"cmp%d4\\t%2, %3\"}, 9256 {\"cmp%d5\\t%0, %1\", 9257 \"cmn%d4\\t%2, #%n3\"}, 9258 {\"cmn%d5\\t%0, #%n1\", 9259 \"cmn%d4\\t%2, #%n3\"} 9260 }; 9261 static const char * const cmp2[NUM_OF_COND_CMP][2] = 9262 { 9263 {\"cmp\\t%2, %3\", 9264 \"cmp\\t%0, %1\"}, 9265 {\"cmp\\t%2, %3\", 9266 \"cmn\\t%0, #%n1\"}, 9267 {\"cmn\\t%2, #%n3\", 9268 \"cmp\\t%0, %1\"}, 9269 {\"cmn\\t%2, #%n3\", 9270 \"cmn\\t%0, #%n1\"} 9271 }; 9272 static const char * const ite[2] = 9273 { 9274 \"it\\t%d5\", 9275 \"it\\t%d4\" 9276 }; 9277 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9278 CMP_CMP, CMN_CMP, CMP_CMP, 9279 CMN_CMP, CMP_CMN, CMN_CMN}; 9280 int swap = 9281 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 9282 9283 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9284 if (TARGET_THUMB2) { 9285 output_asm_insn (ite[swap], operands); 9286 } 9287 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9288 return \"\"; 9289 }" 9290 [(set_attr "conds" "set") 9291 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9292 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9293 (set_attr "type" "multiple") 9294 (set_attr_alternative "length" 9295 [(const_int 6) 9296 (const_int 8) 9297 (const_int 8) 9298 (const_int 8) 9299 (const_int 8) 9300 (if_then_else (eq_attr "is_thumb" "no") 9301 (const_int 8) 9302 (const_int 10)) 9303 (if_then_else (eq_attr "is_thumb" "no") 9304 (const_int 8) 9305 (const_int 10)) 9306 (if_then_else (eq_attr "is_thumb" "no") 9307 (const_int 8) 9308 (const_int 10)) 9309 (if_then_else (eq_attr "is_thumb" "no") 9310 (const_int 8) 9311 (const_int 10))])] 9312) 9313 9314(define_insn "*cmp_ite1" 9315 [(set (match_operand 6 "dominant_cc_register" "") 9316 (compare 9317 (if_then_else:SI 9318 (match_operator 4 "arm_comparison_operator" 9319 [(match_operand:SI 0 "s_register_operand" 9320 "l,l,l,r,r,r,r,r,r") 9321 (match_operand:SI 1 "arm_add_operand" 9322 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9323 (match_operator:SI 5 "arm_comparison_operator" 9324 [(match_operand:SI 2 "s_register_operand" 9325 "l,r,r,l,l,r,r,r,r") 9326 (match_operand:SI 3 "arm_add_operand" 9327 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]) 9328 (const_int 1)) 9329 (const_int 0)))] 9330 "TARGET_32BIT" 9331 "* 9332 { 9333 static const char * const cmp1[NUM_OF_COND_CMP][2] = 9334 { 9335 {\"cmp\\t%0, %1\", 9336 \"cmp\\t%2, %3\"}, 9337 {\"cmn\\t%0, #%n1\", 9338 \"cmp\\t%2, %3\"}, 9339 {\"cmp\\t%0, %1\", 9340 \"cmn\\t%2, #%n3\"}, 9341 {\"cmn\\t%0, #%n1\", 9342 \"cmn\\t%2, #%n3\"} 9343 }; 9344 static const char * const cmp2[NUM_OF_COND_CMP][2] = 9345 { 9346 {\"cmp%d4\\t%2, %3\", 9347 \"cmp%D5\\t%0, %1\"}, 9348 {\"cmp%d4\\t%2, %3\", 9349 \"cmn%D5\\t%0, #%n1\"}, 9350 {\"cmn%d4\\t%2, #%n3\", 9351 \"cmp%D5\\t%0, %1\"}, 9352 {\"cmn%d4\\t%2, #%n3\", 9353 \"cmn%D5\\t%0, #%n1\"} 9354 }; 9355 static const char * const ite[2] = 9356 { 9357 \"it\\t%d4\", 9358 \"it\\t%D5\" 9359 }; 9360 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9361 CMP_CMP, CMN_CMP, CMP_CMP, 9362 CMN_CMP, CMP_CMN, CMN_CMN}; 9363 int swap = 9364 comparison_dominates_p (GET_CODE (operands[5]), 9365 reverse_condition (GET_CODE (operands[4]))); 9366 9367 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9368 if (TARGET_THUMB2) { 9369 output_asm_insn (ite[swap], operands); 9370 } 9371 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9372 return \"\"; 9373 }" 9374 [(set_attr "conds" "set") 9375 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9376 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9377 (set_attr_alternative "length" 9378 [(const_int 6) 9379 (const_int 8) 9380 (const_int 8) 9381 (const_int 8) 9382 (const_int 8) 9383 (if_then_else (eq_attr "is_thumb" "no") 9384 (const_int 8) 9385 (const_int 10)) 9386 (if_then_else (eq_attr "is_thumb" "no") 9387 (const_int 8) 9388 (const_int 10)) 9389 (if_then_else (eq_attr "is_thumb" "no") 9390 (const_int 8) 9391 (const_int 10)) 9392 (if_then_else (eq_attr "is_thumb" "no") 9393 (const_int 8) 9394 (const_int 10))]) 9395 (set_attr "type" "multiple")] 9396) 9397 9398(define_insn "*cmp_and" 9399 [(set (match_operand 6 "dominant_cc_register" "") 9400 (compare 9401 (and:SI 9402 (match_operator 4 "arm_comparison_operator" 9403 [(match_operand:SI 0 "s_register_operand" 9404 "l,l,l,r,r,r,r,r,r") 9405 (match_operand:SI 1 "arm_add_operand" 9406 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9407 (match_operator:SI 5 "arm_comparison_operator" 9408 [(match_operand:SI 2 "s_register_operand" 9409 "l,r,r,l,l,r,r,r,r") 9410 (match_operand:SI 3 "arm_add_operand" 9411 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])) 9412 (const_int 0)))] 9413 "TARGET_32BIT" 9414 "* 9415 { 9416 static const char *const cmp1[NUM_OF_COND_CMP][2] = 9417 { 9418 {\"cmp%d5\\t%0, %1\", 9419 \"cmp%d4\\t%2, %3\"}, 9420 {\"cmn%d5\\t%0, #%n1\", 9421 \"cmp%d4\\t%2, %3\"}, 9422 {\"cmp%d5\\t%0, %1\", 9423 \"cmn%d4\\t%2, #%n3\"}, 9424 {\"cmn%d5\\t%0, #%n1\", 9425 \"cmn%d4\\t%2, #%n3\"} 9426 }; 9427 static const char *const cmp2[NUM_OF_COND_CMP][2] = 9428 { 9429 {\"cmp\\t%2, %3\", 9430 \"cmp\\t%0, %1\"}, 9431 {\"cmp\\t%2, %3\", 9432 \"cmn\\t%0, #%n1\"}, 9433 {\"cmn\\t%2, #%n3\", 9434 \"cmp\\t%0, %1\"}, 9435 {\"cmn\\t%2, #%n3\", 9436 \"cmn\\t%0, #%n1\"} 9437 }; 9438 static const char *const ite[2] = 9439 { 9440 \"it\\t%d5\", 9441 \"it\\t%d4\" 9442 }; 9443 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9444 CMP_CMP, CMN_CMP, CMP_CMP, 9445 CMN_CMP, CMP_CMN, CMN_CMN}; 9446 int swap = 9447 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 9448 9449 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9450 if (TARGET_THUMB2) { 9451 output_asm_insn (ite[swap], operands); 9452 } 9453 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9454 return \"\"; 9455 }" 9456 [(set_attr "conds" "set") 9457 (set_attr "predicable" "no") 9458 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9459 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9460 (set_attr_alternative "length" 9461 [(const_int 6) 9462 (const_int 8) 9463 (const_int 8) 9464 (const_int 8) 9465 (const_int 8) 9466 (if_then_else (eq_attr "is_thumb" "no") 9467 (const_int 8) 9468 (const_int 10)) 9469 (if_then_else (eq_attr "is_thumb" "no") 9470 (const_int 8) 9471 (const_int 10)) 9472 (if_then_else (eq_attr "is_thumb" "no") 9473 (const_int 8) 9474 (const_int 10)) 9475 (if_then_else (eq_attr "is_thumb" "no") 9476 (const_int 8) 9477 (const_int 10))]) 9478 (set_attr "type" "multiple")] 9479) 9480 9481(define_insn "*cmp_ior" 9482 [(set (match_operand 6 "dominant_cc_register" "") 9483 (compare 9484 (ior:SI 9485 (match_operator 4 "arm_comparison_operator" 9486 [(match_operand:SI 0 "s_register_operand" 9487 "l,l,l,r,r,r,r,r,r") 9488 (match_operand:SI 1 "arm_add_operand" 9489 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9490 (match_operator:SI 5 "arm_comparison_operator" 9491 [(match_operand:SI 2 "s_register_operand" 9492 "l,r,r,l,l,r,r,r,r") 9493 (match_operand:SI 3 "arm_add_operand" 9494 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])) 9495 (const_int 0)))] 9496 "TARGET_32BIT" 9497 "* 9498 { 9499 static const char *const cmp1[NUM_OF_COND_CMP][2] = 9500 { 9501 {\"cmp\\t%0, %1\", 9502 \"cmp\\t%2, %3\"}, 9503 {\"cmn\\t%0, #%n1\", 9504 \"cmp\\t%2, %3\"}, 9505 {\"cmp\\t%0, %1\", 9506 \"cmn\\t%2, #%n3\"}, 9507 {\"cmn\\t%0, #%n1\", 9508 \"cmn\\t%2, #%n3\"} 9509 }; 9510 static const char *const cmp2[NUM_OF_COND_CMP][2] = 9511 { 9512 {\"cmp%D4\\t%2, %3\", 9513 \"cmp%D5\\t%0, %1\"}, 9514 {\"cmp%D4\\t%2, %3\", 9515 \"cmn%D5\\t%0, #%n1\"}, 9516 {\"cmn%D4\\t%2, #%n3\", 9517 \"cmp%D5\\t%0, %1\"}, 9518 {\"cmn%D4\\t%2, #%n3\", 9519 \"cmn%D5\\t%0, #%n1\"} 9520 }; 9521 static const char *const ite[2] = 9522 { 9523 \"it\\t%D4\", 9524 \"it\\t%D5\" 9525 }; 9526 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9527 CMP_CMP, CMN_CMP, CMP_CMP, 9528 CMN_CMP, CMP_CMN, CMN_CMN}; 9529 int swap = 9530 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 9531 9532 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9533 if (TARGET_THUMB2) { 9534 output_asm_insn (ite[swap], operands); 9535 } 9536 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9537 return \"\"; 9538 } 9539 " 9540 [(set_attr "conds" "set") 9541 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9542 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9543 (set_attr_alternative "length" 9544 [(const_int 6) 9545 (const_int 8) 9546 (const_int 8) 9547 (const_int 8) 9548 (const_int 8) 9549 (if_then_else (eq_attr "is_thumb" "no") 9550 (const_int 8) 9551 (const_int 10)) 9552 (if_then_else (eq_attr "is_thumb" "no") 9553 (const_int 8) 9554 (const_int 10)) 9555 (if_then_else (eq_attr "is_thumb" "no") 9556 (const_int 8) 9557 (const_int 10)) 9558 (if_then_else (eq_attr "is_thumb" "no") 9559 (const_int 8) 9560 (const_int 10))]) 9561 (set_attr "type" "multiple")] 9562) 9563 9564(define_insn_and_split "*ior_scc_scc" 9565 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 9566 (ior:SI (match_operator:SI 3 "arm_comparison_operator" 9567 [(match_operand:SI 1 "s_register_operand" "l,r") 9568 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9569 (match_operator:SI 6 "arm_comparison_operator" 9570 [(match_operand:SI 4 "s_register_operand" "l,r") 9571 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))) 9572 (clobber (reg:CC CC_REGNUM))] 9573 "TARGET_32BIT 9574 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y) 9575 != CCmode)" 9576 "#" 9577 "TARGET_32BIT && reload_completed" 9578 [(set (match_dup 7) 9579 (compare 9580 (ior:SI 9581 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9582 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9583 (const_int 0))) 9584 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] 9585 "operands[7] 9586 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], 9587 DOM_CC_X_OR_Y), 9588 CC_REGNUM);" 9589 [(set_attr "conds" "clob") 9590 (set_attr "enabled_for_short_it" "yes,no") 9591 (set_attr "length" "16") 9592 (set_attr "type" "multiple")] 9593) 9594 9595; If the above pattern is followed by a CMP insn, then the compare is 9596; redundant, since we can rework the conditional instruction that follows. 9597(define_insn_and_split "*ior_scc_scc_cmp" 9598 [(set (match_operand 0 "dominant_cc_register" "") 9599 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator" 9600 [(match_operand:SI 1 "s_register_operand" "l,r") 9601 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9602 (match_operator:SI 6 "arm_comparison_operator" 9603 [(match_operand:SI 4 "s_register_operand" "l,r") 9604 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])) 9605 (const_int 0))) 9606 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts") 9607 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9608 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] 9609 "TARGET_32BIT" 9610 "#" 9611 "TARGET_32BIT && reload_completed" 9612 [(set (match_dup 0) 9613 (compare 9614 (ior:SI 9615 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9616 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9617 (const_int 0))) 9618 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] 9619 "" 9620 [(set_attr "conds" "set") 9621 (set_attr "enabled_for_short_it" "yes,no") 9622 (set_attr "length" "16") 9623 (set_attr "type" "multiple")] 9624) 9625 9626(define_insn_and_split "*and_scc_scc" 9627 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 9628 (and:SI (match_operator:SI 3 "arm_comparison_operator" 9629 [(match_operand:SI 1 "s_register_operand" "l,r") 9630 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9631 (match_operator:SI 6 "arm_comparison_operator" 9632 [(match_operand:SI 4 "s_register_operand" "l,r") 9633 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))) 9634 (clobber (reg:CC CC_REGNUM))] 9635 "TARGET_32BIT 9636 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) 9637 != CCmode)" 9638 "#" 9639 "TARGET_32BIT && reload_completed 9640 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) 9641 != CCmode)" 9642 [(set (match_dup 7) 9643 (compare 9644 (and:SI 9645 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9646 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9647 (const_int 0))) 9648 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] 9649 "operands[7] 9650 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], 9651 DOM_CC_X_AND_Y), 9652 CC_REGNUM);" 9653 [(set_attr "conds" "clob") 9654 (set_attr "enabled_for_short_it" "yes,no") 9655 (set_attr "length" "16") 9656 (set_attr "type" "multiple")] 9657) 9658 9659; If the above pattern is followed by a CMP insn, then the compare is 9660; redundant, since we can rework the conditional instruction that follows. 9661(define_insn_and_split "*and_scc_scc_cmp" 9662 [(set (match_operand 0 "dominant_cc_register" "") 9663 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator" 9664 [(match_operand:SI 1 "s_register_operand" "l,r") 9665 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9666 (match_operator:SI 6 "arm_comparison_operator" 9667 [(match_operand:SI 4 "s_register_operand" "l,r") 9668 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])) 9669 (const_int 0))) 9670 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts") 9671 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9672 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] 9673 "TARGET_32BIT" 9674 "#" 9675 "TARGET_32BIT && reload_completed" 9676 [(set (match_dup 0) 9677 (compare 9678 (and:SI 9679 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9680 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9681 (const_int 0))) 9682 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] 9683 "" 9684 [(set_attr "conds" "set") 9685 (set_attr "enabled_for_short_it" "yes,no") 9686 (set_attr "length" "16") 9687 (set_attr "type" "multiple")] 9688) 9689 9690;; If there is no dominance in the comparison, then we can still save an 9691;; instruction in the AND case, since we can know that the second compare 9692;; need only zero the value if false (if true, then the value is already 9693;; correct). 9694(define_insn_and_split "*and_scc_scc_nodom" 9695 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts") 9696 (and:SI (match_operator:SI 3 "arm_comparison_operator" 9697 [(match_operand:SI 1 "s_register_operand" "r,r,0") 9698 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")]) 9699 (match_operator:SI 6 "arm_comparison_operator" 9700 [(match_operand:SI 4 "s_register_operand" "r,r,r") 9701 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")]))) 9702 (clobber (reg:CC CC_REGNUM))] 9703 "TARGET_32BIT 9704 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) 9705 == CCmode)" 9706 "#" 9707 "TARGET_32BIT && reload_completed" 9708 [(parallel [(set (match_dup 0) 9709 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 9710 (clobber (reg:CC CC_REGNUM))]) 9711 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)])) 9712 (set (match_dup 0) 9713 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)]) 9714 (match_dup 0) 9715 (const_int 0)))] 9716 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]), 9717 operands[4], operands[5]), 9718 CC_REGNUM); 9719 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4], 9720 operands[5]);" 9721 [(set_attr "conds" "clob") 9722 (set_attr "length" "20") 9723 (set_attr "type" "multiple")] 9724) 9725 9726(define_split 9727 [(set (reg:CC_NOOV CC_REGNUM) 9728 (compare:CC_NOOV (ior:SI 9729 (and:SI (match_operand:SI 0 "s_register_operand" "") 9730 (const_int 1)) 9731 (match_operator:SI 1 "arm_comparison_operator" 9732 [(match_operand:SI 2 "s_register_operand" "") 9733 (match_operand:SI 3 "arm_add_operand" "")])) 9734 (const_int 0))) 9735 (clobber (match_operand:SI 4 "s_register_operand" ""))] 9736 "TARGET_ARM" 9737 [(set (match_dup 4) 9738 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) 9739 (match_dup 0))) 9740 (set (reg:CC_NOOV CC_REGNUM) 9741 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1)) 9742 (const_int 0)))] 9743 "") 9744 9745(define_split 9746 [(set (reg:CC_NOOV CC_REGNUM) 9747 (compare:CC_NOOV (ior:SI 9748 (match_operator:SI 1 "arm_comparison_operator" 9749 [(match_operand:SI 2 "s_register_operand" "") 9750 (match_operand:SI 3 "arm_add_operand" "")]) 9751 (and:SI (match_operand:SI 0 "s_register_operand" "") 9752 (const_int 1))) 9753 (const_int 0))) 9754 (clobber (match_operand:SI 4 "s_register_operand" ""))] 9755 "TARGET_ARM" 9756 [(set (match_dup 4) 9757 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) 9758 (match_dup 0))) 9759 (set (reg:CC_NOOV CC_REGNUM) 9760 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1)) 9761 (const_int 0)))] 9762 "") 9763;; ??? The conditional patterns above need checking for Thumb-2 usefulness 9764 9765(define_insn_and_split "*negscc" 9766 [(set (match_operand:SI 0 "s_register_operand" "=r") 9767 (neg:SI (match_operator 3 "arm_comparison_operator" 9768 [(match_operand:SI 1 "s_register_operand" "r") 9769 (match_operand:SI 2 "arm_rhs_operand" "rI")]))) 9770 (clobber (reg:CC CC_REGNUM))] 9771 "TARGET_ARM" 9772 "#" 9773 "&& reload_completed" 9774 [(const_int 0)] 9775 { 9776 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); 9777 9778 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx) 9779 { 9780 /* Emit mov\\t%0, %1, asr #31 */ 9781 emit_insn (gen_rtx_SET (operands[0], 9782 gen_rtx_ASHIFTRT (SImode, 9783 operands[1], 9784 GEN_INT (31)))); 9785 DONE; 9786 } 9787 else if (GET_CODE (operands[3]) == NE) 9788 { 9789 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */ 9790 if (CONST_INT_P (operands[2])) 9791 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2], 9792 GEN_INT (- INTVAL (operands[2])))); 9793 else 9794 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2])); 9795 9796 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 9797 gen_rtx_NE (SImode, 9798 cc_reg, 9799 const0_rtx), 9800 gen_rtx_SET (operands[0], 9801 GEN_INT (~0)))); 9802 DONE; 9803 } 9804 else 9805 { 9806 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */ 9807 emit_insn (gen_rtx_SET (cc_reg, 9808 gen_rtx_COMPARE (CCmode, operands[1], operands[2]))); 9809 enum rtx_code rc = GET_CODE (operands[3]); 9810 9811 rc = reverse_condition (rc); 9812 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 9813 gen_rtx_fmt_ee (rc, 9814 VOIDmode, 9815 cc_reg, 9816 const0_rtx), 9817 gen_rtx_SET (operands[0], const0_rtx))); 9818 rc = GET_CODE (operands[3]); 9819 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 9820 gen_rtx_fmt_ee (rc, 9821 VOIDmode, 9822 cc_reg, 9823 const0_rtx), 9824 gen_rtx_SET (operands[0], 9825 GEN_INT (~0)))); 9826 DONE; 9827 } 9828 FAIL; 9829 } 9830 [(set_attr "conds" "clob") 9831 (set_attr "length" "12") 9832 (set_attr "type" "multiple")] 9833) 9834 9835(define_insn_and_split "movcond_addsi" 9836 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") 9837 (if_then_else:SI 9838 (match_operator 5 "comparison_operator" 9839 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r") 9840 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")) 9841 (const_int 0)]) 9842 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r") 9843 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r"))) 9844 (clobber (reg:CC CC_REGNUM))] 9845 "TARGET_32BIT" 9846 "#" 9847 "&& reload_completed" 9848 [(set (reg:CC_NOOV CC_REGNUM) 9849 (compare:CC_NOOV 9850 (plus:SI (match_dup 3) 9851 (match_dup 4)) 9852 (const_int 0))) 9853 (set (match_dup 0) (match_dup 1)) 9854 (cond_exec (match_dup 6) 9855 (set (match_dup 0) (match_dup 2)))] 9856 " 9857 { 9858 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]), 9859 operands[3], operands[4]); 9860 enum rtx_code rc = GET_CODE (operands[5]); 9861 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 9862 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode)); 9863 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0])) 9864 rc = reverse_condition (rc); 9865 else 9866 std::swap (operands[1], operands[2]); 9867 9868 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 9869 } 9870 " 9871 [(set_attr "conds" "clob") 9872 (set_attr "enabled_for_short_it" "no,yes,yes") 9873 (set_attr "type" "multiple")] 9874) 9875 9876(define_insn "movcond" 9877 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 9878 (if_then_else:SI 9879 (match_operator 5 "arm_comparison_operator" 9880 [(match_operand:SI 3 "s_register_operand" "r,r,r") 9881 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")]) 9882 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") 9883 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 9884 (clobber (reg:CC CC_REGNUM))] 9885 "TARGET_ARM" 9886 "* 9887 if (GET_CODE (operands[5]) == LT 9888 && (operands[4] == const0_rtx)) 9889 { 9890 if (which_alternative != 1 && REG_P (operands[1])) 9891 { 9892 if (operands[2] == const0_rtx) 9893 return \"and\\t%0, %1, %3, asr #31\"; 9894 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\"; 9895 } 9896 else if (which_alternative != 0 && REG_P (operands[2])) 9897 { 9898 if (operands[1] == const0_rtx) 9899 return \"bic\\t%0, %2, %3, asr #31\"; 9900 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\"; 9901 } 9902 /* The only case that falls through to here is when both ops 1 & 2 9903 are constants. */ 9904 } 9905 9906 if (GET_CODE (operands[5]) == GE 9907 && (operands[4] == const0_rtx)) 9908 { 9909 if (which_alternative != 1 && REG_P (operands[1])) 9910 { 9911 if (operands[2] == const0_rtx) 9912 return \"bic\\t%0, %1, %3, asr #31\"; 9913 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\"; 9914 } 9915 else if (which_alternative != 0 && REG_P (operands[2])) 9916 { 9917 if (operands[1] == const0_rtx) 9918 return \"and\\t%0, %2, %3, asr #31\"; 9919 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\"; 9920 } 9921 /* The only case that falls through to here is when both ops 1 & 2 9922 are constants. */ 9923 } 9924 if (CONST_INT_P (operands[4]) 9925 && !const_ok_for_arm (INTVAL (operands[4]))) 9926 output_asm_insn (\"cmn\\t%3, #%n4\", operands); 9927 else 9928 output_asm_insn (\"cmp\\t%3, %4\", operands); 9929 if (which_alternative != 0) 9930 output_asm_insn (\"mov%d5\\t%0, %1\", operands); 9931 if (which_alternative != 1) 9932 output_asm_insn (\"mov%D5\\t%0, %2\", operands); 9933 return \"\"; 9934 " 9935 [(set_attr "conds" "clob") 9936 (set_attr "length" "8,8,12") 9937 (set_attr "type" "multiple")] 9938) 9939 9940;; ??? The patterns below need checking for Thumb-2 usefulness. 9941 9942(define_insn "*ifcompare_plus_move" 9943 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9944 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 9945 [(match_operand:SI 4 "s_register_operand" "r,r") 9946 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 9947 (plus:SI 9948 (match_operand:SI 2 "s_register_operand" "r,r") 9949 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")) 9950 (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) 9951 (clobber (reg:CC CC_REGNUM))] 9952 "TARGET_ARM" 9953 "#" 9954 [(set_attr "conds" "clob") 9955 (set_attr "length" "8,12") 9956 (set_attr "type" "multiple")] 9957) 9958 9959(define_insn "*if_plus_move" 9960 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") 9961 (if_then_else:SI 9962 (match_operator 4 "arm_comparison_operator" 9963 [(match_operand 5 "cc_register" "") (const_int 0)]) 9964 (plus:SI 9965 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 9966 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")) 9967 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))] 9968 "TARGET_ARM" 9969 "@ 9970 add%d4\\t%0, %2, %3 9971 sub%d4\\t%0, %2, #%n3 9972 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1 9973 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1" 9974 [(set_attr "conds" "use") 9975 (set_attr "length" "4,4,8,8") 9976 (set_attr_alternative "type" 9977 [(if_then_else (match_operand 3 "const_int_operand" "") 9978 (const_string "alu_imm" ) 9979 (const_string "alu_sreg")) 9980 (const_string "alu_imm") 9981 (const_string "multiple") 9982 (const_string "multiple")])] 9983) 9984 9985(define_insn "*ifcompare_move_plus" 9986 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9987 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 9988 [(match_operand:SI 4 "s_register_operand" "r,r") 9989 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 9990 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 9991 (plus:SI 9992 (match_operand:SI 2 "s_register_operand" "r,r") 9993 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")))) 9994 (clobber (reg:CC CC_REGNUM))] 9995 "TARGET_ARM" 9996 "#" 9997 [(set_attr "conds" "clob") 9998 (set_attr "length" "8,12") 9999 (set_attr "type" "multiple")] 10000) 10001 10002(define_insn "*if_move_plus" 10003 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") 10004 (if_then_else:SI 10005 (match_operator 4 "arm_comparison_operator" 10006 [(match_operand 5 "cc_register" "") (const_int 0)]) 10007 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI") 10008 (plus:SI 10009 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 10010 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))] 10011 "TARGET_ARM" 10012 "@ 10013 add%D4\\t%0, %2, %3 10014 sub%D4\\t%0, %2, #%n3 10015 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1 10016 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1" 10017 [(set_attr "conds" "use") 10018 (set_attr "length" "4,4,8,8") 10019 (set_attr_alternative "type" 10020 [(if_then_else (match_operand 3 "const_int_operand" "") 10021 (const_string "alu_imm" ) 10022 (const_string "alu_sreg")) 10023 (const_string "alu_imm") 10024 (const_string "multiple") 10025 (const_string "multiple")])] 10026) 10027 10028(define_insn "*ifcompare_arith_arith" 10029 [(set (match_operand:SI 0 "s_register_operand" "=r") 10030 (if_then_else:SI (match_operator 9 "arm_comparison_operator" 10031 [(match_operand:SI 5 "s_register_operand" "r") 10032 (match_operand:SI 6 "arm_add_operand" "rIL")]) 10033 (match_operator:SI 8 "shiftable_operator" 10034 [(match_operand:SI 1 "s_register_operand" "r") 10035 (match_operand:SI 2 "arm_rhs_operand" "rI")]) 10036 (match_operator:SI 7 "shiftable_operator" 10037 [(match_operand:SI 3 "s_register_operand" "r") 10038 (match_operand:SI 4 "arm_rhs_operand" "rI")]))) 10039 (clobber (reg:CC CC_REGNUM))] 10040 "TARGET_ARM" 10041 "#" 10042 [(set_attr "conds" "clob") 10043 (set_attr "length" "12") 10044 (set_attr "type" "multiple")] 10045) 10046 10047(define_insn "*if_arith_arith" 10048 [(set (match_operand:SI 0 "s_register_operand" "=r") 10049 (if_then_else:SI (match_operator 5 "arm_comparison_operator" 10050 [(match_operand 8 "cc_register" "") (const_int 0)]) 10051 (match_operator:SI 6 "shiftable_operator" 10052 [(match_operand:SI 1 "s_register_operand" "r") 10053 (match_operand:SI 2 "arm_rhs_operand" "rI")]) 10054 (match_operator:SI 7 "shiftable_operator" 10055 [(match_operand:SI 3 "s_register_operand" "r") 10056 (match_operand:SI 4 "arm_rhs_operand" "rI")])))] 10057 "TARGET_ARM" 10058 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4" 10059 [(set_attr "conds" "use") 10060 (set_attr "length" "8") 10061 (set_attr "type" "multiple")] 10062) 10063 10064(define_insn "*ifcompare_arith_move" 10065 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10066 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 10067 [(match_operand:SI 2 "s_register_operand" "r,r") 10068 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")]) 10069 (match_operator:SI 7 "shiftable_operator" 10070 [(match_operand:SI 4 "s_register_operand" "r,r") 10071 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")]) 10072 (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) 10073 (clobber (reg:CC CC_REGNUM))] 10074 "TARGET_ARM" 10075 "* 10076 /* If we have an operation where (op x 0) is the identity operation and 10077 the conditional operator is LT or GE and we are comparing against zero and 10078 everything is in registers then we can do this in two instructions. */ 10079 if (operands[3] == const0_rtx 10080 && GET_CODE (operands[7]) != AND 10081 && REG_P (operands[5]) 10082 && REG_P (operands[1]) 10083 && REGNO (operands[1]) == REGNO (operands[4]) 10084 && REGNO (operands[4]) != REGNO (operands[0])) 10085 { 10086 if (GET_CODE (operands[6]) == LT) 10087 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; 10088 else if (GET_CODE (operands[6]) == GE) 10089 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; 10090 } 10091 if (CONST_INT_P (operands[3]) 10092 && !const_ok_for_arm (INTVAL (operands[3]))) 10093 output_asm_insn (\"cmn\\t%2, #%n3\", operands); 10094 else 10095 output_asm_insn (\"cmp\\t%2, %3\", operands); 10096 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands); 10097 if (which_alternative != 0) 10098 return \"mov%D6\\t%0, %1\"; 10099 return \"\"; 10100 " 10101 [(set_attr "conds" "clob") 10102 (set_attr "length" "8,12") 10103 (set_attr "type" "multiple")] 10104) 10105 10106(define_insn "*if_arith_move" 10107 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10108 (if_then_else:SI (match_operator 4 "arm_comparison_operator" 10109 [(match_operand 6 "cc_register" "") (const_int 0)]) 10110 (match_operator:SI 5 "shiftable_operator" 10111 [(match_operand:SI 2 "s_register_operand" "r,r") 10112 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 10113 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))] 10114 "TARGET_ARM" 10115 "@ 10116 %I5%d4\\t%0, %2, %3 10117 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1" 10118 [(set_attr "conds" "use") 10119 (set_attr "length" "4,8") 10120 (set_attr_alternative "type" 10121 [(if_then_else (match_operand 3 "const_int_operand" "") 10122 (const_string "alu_shift_imm" ) 10123 (const_string "alu_shift_reg")) 10124 (const_string "multiple")])] 10125) 10126 10127(define_insn "*ifcompare_move_arith" 10128 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10129 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 10130 [(match_operand:SI 4 "s_register_operand" "r,r") 10131 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10132 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 10133 (match_operator:SI 7 "shiftable_operator" 10134 [(match_operand:SI 2 "s_register_operand" "r,r") 10135 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) 10136 (clobber (reg:CC CC_REGNUM))] 10137 "TARGET_ARM" 10138 "* 10139 /* If we have an operation where (op x 0) is the identity operation and 10140 the conditional operator is LT or GE and we are comparing against zero and 10141 everything is in registers then we can do this in two instructions */ 10142 if (operands[5] == const0_rtx 10143 && GET_CODE (operands[7]) != AND 10144 && REG_P (operands[3]) 10145 && REG_P (operands[1]) 10146 && REGNO (operands[1]) == REGNO (operands[2]) 10147 && REGNO (operands[2]) != REGNO (operands[0])) 10148 { 10149 if (GET_CODE (operands[6]) == GE) 10150 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; 10151 else if (GET_CODE (operands[6]) == LT) 10152 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; 10153 } 10154 10155 if (CONST_INT_P (operands[5]) 10156 && !const_ok_for_arm (INTVAL (operands[5]))) 10157 output_asm_insn (\"cmn\\t%4, #%n5\", operands); 10158 else 10159 output_asm_insn (\"cmp\\t%4, %5\", operands); 10160 10161 if (which_alternative != 0) 10162 output_asm_insn (\"mov%d6\\t%0, %1\", operands); 10163 return \"%I7%D6\\t%0, %2, %3\"; 10164 " 10165 [(set_attr "conds" "clob") 10166 (set_attr "length" "8,12") 10167 (set_attr "type" "multiple")] 10168) 10169 10170(define_insn "*if_move_arith" 10171 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10172 (if_then_else:SI 10173 (match_operator 4 "arm_comparison_operator" 10174 [(match_operand 6 "cc_register" "") (const_int 0)]) 10175 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 10176 (match_operator:SI 5 "shiftable_operator" 10177 [(match_operand:SI 2 "s_register_operand" "r,r") 10178 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))] 10179 "TARGET_ARM" 10180 "@ 10181 %I5%D4\\t%0, %2, %3 10182 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1" 10183 [(set_attr "conds" "use") 10184 (set_attr "length" "4,8") 10185 (set_attr_alternative "type" 10186 [(if_then_else (match_operand 3 "const_int_operand" "") 10187 (const_string "alu_shift_imm" ) 10188 (const_string "alu_shift_reg")) 10189 (const_string "multiple")])] 10190) 10191 10192(define_insn "*ifcompare_move_not" 10193 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10194 (if_then_else:SI 10195 (match_operator 5 "arm_comparison_operator" 10196 [(match_operand:SI 3 "s_register_operand" "r,r") 10197 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10198 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 10199 (not:SI 10200 (match_operand:SI 2 "s_register_operand" "r,r")))) 10201 (clobber (reg:CC CC_REGNUM))] 10202 "TARGET_ARM" 10203 "#" 10204 [(set_attr "conds" "clob") 10205 (set_attr "length" "8,12") 10206 (set_attr "type" "multiple")] 10207) 10208 10209(define_insn "*if_move_not" 10210 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10211 (if_then_else:SI 10212 (match_operator 4 "arm_comparison_operator" 10213 [(match_operand 3 "cc_register" "") (const_int 0)]) 10214 (match_operand:SI 1 "arm_not_operand" "0,?rI,K") 10215 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))] 10216 "TARGET_ARM" 10217 "@ 10218 mvn%D4\\t%0, %2 10219 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2 10220 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2" 10221 [(set_attr "conds" "use") 10222 (set_attr "type" "mvn_reg") 10223 (set_attr "length" "4,8,8") 10224 (set_attr "type" "mvn_reg,multiple,multiple")] 10225) 10226 10227(define_insn "*ifcompare_not_move" 10228 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10229 (if_then_else:SI 10230 (match_operator 5 "arm_comparison_operator" 10231 [(match_operand:SI 3 "s_register_operand" "r,r") 10232 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10233 (not:SI 10234 (match_operand:SI 2 "s_register_operand" "r,r")) 10235 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 10236 (clobber (reg:CC CC_REGNUM))] 10237 "TARGET_ARM" 10238 "#" 10239 [(set_attr "conds" "clob") 10240 (set_attr "length" "8,12") 10241 (set_attr "type" "multiple")] 10242) 10243 10244(define_insn "*if_not_move" 10245 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10246 (if_then_else:SI 10247 (match_operator 4 "arm_comparison_operator" 10248 [(match_operand 3 "cc_register" "") (const_int 0)]) 10249 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r")) 10250 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] 10251 "TARGET_ARM" 10252 "@ 10253 mvn%d4\\t%0, %2 10254 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2 10255 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2" 10256 [(set_attr "conds" "use") 10257 (set_attr "type" "mvn_reg,multiple,multiple") 10258 (set_attr "length" "4,8,8")] 10259) 10260 10261(define_insn "*ifcompare_shift_move" 10262 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10263 (if_then_else:SI 10264 (match_operator 6 "arm_comparison_operator" 10265 [(match_operand:SI 4 "s_register_operand" "r,r") 10266 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10267 (match_operator:SI 7 "shift_operator" 10268 [(match_operand:SI 2 "s_register_operand" "r,r") 10269 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]) 10270 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 10271 (clobber (reg:CC CC_REGNUM))] 10272 "TARGET_ARM" 10273 "#" 10274 [(set_attr "conds" "clob") 10275 (set_attr "length" "8,12") 10276 (set_attr "type" "multiple")] 10277) 10278 10279(define_insn "*if_shift_move" 10280 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10281 (if_then_else:SI 10282 (match_operator 5 "arm_comparison_operator" 10283 [(match_operand 6 "cc_register" "") (const_int 0)]) 10284 (match_operator:SI 4 "shift_operator" 10285 [(match_operand:SI 2 "s_register_operand" "r,r,r") 10286 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")]) 10287 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] 10288 "TARGET_ARM" 10289 "@ 10290 mov%d5\\t%0, %2%S4 10291 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4 10292 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4" 10293 [(set_attr "conds" "use") 10294 (set_attr "shift" "2") 10295 (set_attr "length" "4,8,8") 10296 (set_attr_alternative "type" 10297 [(if_then_else (match_operand 3 "const_int_operand" "") 10298 (const_string "mov_shift" ) 10299 (const_string "mov_shift_reg")) 10300 (const_string "multiple") 10301 (const_string "multiple")])] 10302) 10303 10304(define_insn "*ifcompare_move_shift" 10305 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10306 (if_then_else:SI 10307 (match_operator 6 "arm_comparison_operator" 10308 [(match_operand:SI 4 "s_register_operand" "r,r") 10309 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10310 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 10311 (match_operator:SI 7 "shift_operator" 10312 [(match_operand:SI 2 "s_register_operand" "r,r") 10313 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]))) 10314 (clobber (reg:CC CC_REGNUM))] 10315 "TARGET_ARM" 10316 "#" 10317 [(set_attr "conds" "clob") 10318 (set_attr "length" "8,12") 10319 (set_attr "type" "multiple")] 10320) 10321 10322(define_insn "*if_move_shift" 10323 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10324 (if_then_else:SI 10325 (match_operator 5 "arm_comparison_operator" 10326 [(match_operand 6 "cc_register" "") (const_int 0)]) 10327 (match_operand:SI 1 "arm_not_operand" "0,?rI,K") 10328 (match_operator:SI 4 "shift_operator" 10329 [(match_operand:SI 2 "s_register_operand" "r,r,r") 10330 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))] 10331 "TARGET_ARM" 10332 "@ 10333 mov%D5\\t%0, %2%S4 10334 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4 10335 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4" 10336 [(set_attr "conds" "use") 10337 (set_attr "shift" "2") 10338 (set_attr "length" "4,8,8") 10339 (set_attr_alternative "type" 10340 [(if_then_else (match_operand 3 "const_int_operand" "") 10341 (const_string "mov_shift" ) 10342 (const_string "mov_shift_reg")) 10343 (const_string "multiple") 10344 (const_string "multiple")])] 10345) 10346 10347(define_insn "*ifcompare_shift_shift" 10348 [(set (match_operand:SI 0 "s_register_operand" "=r") 10349 (if_then_else:SI 10350 (match_operator 7 "arm_comparison_operator" 10351 [(match_operand:SI 5 "s_register_operand" "r") 10352 (match_operand:SI 6 "arm_add_operand" "rIL")]) 10353 (match_operator:SI 8 "shift_operator" 10354 [(match_operand:SI 1 "s_register_operand" "r") 10355 (match_operand:SI 2 "arm_rhs_operand" "rM")]) 10356 (match_operator:SI 9 "shift_operator" 10357 [(match_operand:SI 3 "s_register_operand" "r") 10358 (match_operand:SI 4 "arm_rhs_operand" "rM")]))) 10359 (clobber (reg:CC CC_REGNUM))] 10360 "TARGET_ARM" 10361 "#" 10362 [(set_attr "conds" "clob") 10363 (set_attr "length" "12") 10364 (set_attr "type" "multiple")] 10365) 10366 10367(define_insn "*if_shift_shift" 10368 [(set (match_operand:SI 0 "s_register_operand" "=r") 10369 (if_then_else:SI 10370 (match_operator 5 "arm_comparison_operator" 10371 [(match_operand 8 "cc_register" "") (const_int 0)]) 10372 (match_operator:SI 6 "shift_operator" 10373 [(match_operand:SI 1 "s_register_operand" "r") 10374 (match_operand:SI 2 "arm_rhs_operand" "rM")]) 10375 (match_operator:SI 7 "shift_operator" 10376 [(match_operand:SI 3 "s_register_operand" "r") 10377 (match_operand:SI 4 "arm_rhs_operand" "rM")])))] 10378 "TARGET_ARM" 10379 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7" 10380 [(set_attr "conds" "use") 10381 (set_attr "shift" "1") 10382 (set_attr "length" "8") 10383 (set (attr "type") (if_then_else 10384 (and (match_operand 2 "const_int_operand" "") 10385 (match_operand 4 "const_int_operand" "")) 10386 (const_string "mov_shift") 10387 (const_string "mov_shift_reg")))] 10388) 10389 10390(define_insn "*ifcompare_not_arith" 10391 [(set (match_operand:SI 0 "s_register_operand" "=r") 10392 (if_then_else:SI 10393 (match_operator 6 "arm_comparison_operator" 10394 [(match_operand:SI 4 "s_register_operand" "r") 10395 (match_operand:SI 5 "arm_add_operand" "rIL")]) 10396 (not:SI (match_operand:SI 1 "s_register_operand" "r")) 10397 (match_operator:SI 7 "shiftable_operator" 10398 [(match_operand:SI 2 "s_register_operand" "r") 10399 (match_operand:SI 3 "arm_rhs_operand" "rI")]))) 10400 (clobber (reg:CC CC_REGNUM))] 10401 "TARGET_ARM" 10402 "#" 10403 [(set_attr "conds" "clob") 10404 (set_attr "length" "12") 10405 (set_attr "type" "multiple")] 10406) 10407 10408(define_insn "*if_not_arith" 10409 [(set (match_operand:SI 0 "s_register_operand" "=r") 10410 (if_then_else:SI 10411 (match_operator 5 "arm_comparison_operator" 10412 [(match_operand 4 "cc_register" "") (const_int 0)]) 10413 (not:SI (match_operand:SI 1 "s_register_operand" "r")) 10414 (match_operator:SI 6 "shiftable_operator" 10415 [(match_operand:SI 2 "s_register_operand" "r") 10416 (match_operand:SI 3 "arm_rhs_operand" "rI")])))] 10417 "TARGET_ARM" 10418 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3" 10419 [(set_attr "conds" "use") 10420 (set_attr "type" "mvn_reg") 10421 (set_attr "length" "8")] 10422) 10423 10424(define_insn "*ifcompare_arith_not" 10425 [(set (match_operand:SI 0 "s_register_operand" "=r") 10426 (if_then_else:SI 10427 (match_operator 6 "arm_comparison_operator" 10428 [(match_operand:SI 4 "s_register_operand" "r") 10429 (match_operand:SI 5 "arm_add_operand" "rIL")]) 10430 (match_operator:SI 7 "shiftable_operator" 10431 [(match_operand:SI 2 "s_register_operand" "r") 10432 (match_operand:SI 3 "arm_rhs_operand" "rI")]) 10433 (not:SI (match_operand:SI 1 "s_register_operand" "r")))) 10434 (clobber (reg:CC CC_REGNUM))] 10435 "TARGET_ARM" 10436 "#" 10437 [(set_attr "conds" "clob") 10438 (set_attr "length" "12") 10439 (set_attr "type" "multiple")] 10440) 10441 10442(define_insn "*if_arith_not" 10443 [(set (match_operand:SI 0 "s_register_operand" "=r") 10444 (if_then_else:SI 10445 (match_operator 5 "arm_comparison_operator" 10446 [(match_operand 4 "cc_register" "") (const_int 0)]) 10447 (match_operator:SI 6 "shiftable_operator" 10448 [(match_operand:SI 2 "s_register_operand" "r") 10449 (match_operand:SI 3 "arm_rhs_operand" "rI")]) 10450 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))] 10451 "TARGET_ARM" 10452 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3" 10453 [(set_attr "conds" "use") 10454 (set_attr "type" "multiple") 10455 (set_attr "length" "8")] 10456) 10457 10458(define_insn "*ifcompare_neg_move" 10459 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10460 (if_then_else:SI 10461 (match_operator 5 "arm_comparison_operator" 10462 [(match_operand:SI 3 "s_register_operand" "r,r") 10463 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10464 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")) 10465 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 10466 (clobber (reg:CC CC_REGNUM))] 10467 "TARGET_ARM" 10468 "#" 10469 [(set_attr "conds" "clob") 10470 (set_attr "length" "8,12") 10471 (set_attr "type" "multiple")] 10472) 10473 10474(define_insn_and_split "*if_neg_move" 10475 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 10476 (if_then_else:SI 10477 (match_operator 4 "arm_comparison_operator" 10478 [(match_operand 3 "cc_register" "") (const_int 0)]) 10479 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r")) 10480 (match_operand:SI 1 "s_register_operand" "0,0")))] 10481 "TARGET_32BIT" 10482 "#" 10483 "&& reload_completed" 10484 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)]) 10485 (set (match_dup 0) (neg:SI (match_dup 2))))] 10486 "" 10487 [(set_attr "conds" "use") 10488 (set_attr "length" "4") 10489 (set_attr "arch" "t2,32") 10490 (set_attr "enabled_for_short_it" "yes,no") 10491 (set_attr "type" "logic_shift_imm")] 10492) 10493 10494(define_insn "*ifcompare_move_neg" 10495 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10496 (if_then_else:SI 10497 (match_operator 5 "arm_comparison_operator" 10498 [(match_operand:SI 3 "s_register_operand" "r,r") 10499 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10500 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 10501 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")))) 10502 (clobber (reg:CC CC_REGNUM))] 10503 "TARGET_ARM" 10504 "#" 10505 [(set_attr "conds" "clob") 10506 (set_attr "length" "8,12") 10507 (set_attr "type" "multiple")] 10508) 10509 10510(define_insn_and_split "*if_move_neg" 10511 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 10512 (if_then_else:SI 10513 (match_operator 4 "arm_comparison_operator" 10514 [(match_operand 3 "cc_register" "") (const_int 0)]) 10515 (match_operand:SI 1 "s_register_operand" "0,0") 10516 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))] 10517 "TARGET_32BIT" 10518 "#" 10519 "&& reload_completed" 10520 [(cond_exec (match_dup 5) 10521 (set (match_dup 0) (neg:SI (match_dup 2))))] 10522 { 10523 machine_mode mode = GET_MODE (operands[3]); 10524 rtx_code rc = GET_CODE (operands[4]); 10525 10526 if (mode == CCFPmode || mode == CCFPEmode) 10527 rc = reverse_condition_maybe_unordered (rc); 10528 else 10529 rc = reverse_condition (rc); 10530 10531 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx); 10532 } 10533 [(set_attr "conds" "use") 10534 (set_attr "length" "4") 10535 (set_attr "arch" "t2,32") 10536 (set_attr "enabled_for_short_it" "yes,no") 10537 (set_attr "type" "logic_shift_imm")] 10538) 10539 10540(define_insn "*arith_adjacentmem" 10541 [(set (match_operand:SI 0 "s_register_operand" "=r") 10542 (match_operator:SI 1 "shiftable_operator" 10543 [(match_operand:SI 2 "memory_operand" "m") 10544 (match_operand:SI 3 "memory_operand" "m")])) 10545 (clobber (match_scratch:SI 4 "=r"))] 10546 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])" 10547 "* 10548 { 10549 rtx ldm[3]; 10550 rtx arith[4]; 10551 rtx base_reg; 10552 HOST_WIDE_INT val1 = 0, val2 = 0; 10553 10554 if (REGNO (operands[0]) > REGNO (operands[4])) 10555 { 10556 ldm[1] = operands[4]; 10557 ldm[2] = operands[0]; 10558 } 10559 else 10560 { 10561 ldm[1] = operands[0]; 10562 ldm[2] = operands[4]; 10563 } 10564 10565 base_reg = XEXP (operands[2], 0); 10566 10567 if (!REG_P (base_reg)) 10568 { 10569 val1 = INTVAL (XEXP (base_reg, 1)); 10570 base_reg = XEXP (base_reg, 0); 10571 } 10572 10573 if (!REG_P (XEXP (operands[3], 0))) 10574 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1)); 10575 10576 arith[0] = operands[0]; 10577 arith[3] = operands[1]; 10578 10579 if (val1 < val2) 10580 { 10581 arith[1] = ldm[1]; 10582 arith[2] = ldm[2]; 10583 } 10584 else 10585 { 10586 arith[1] = ldm[2]; 10587 arith[2] = ldm[1]; 10588 } 10589 10590 ldm[0] = base_reg; 10591 if (val1 !=0 && val2 != 0) 10592 { 10593 rtx ops[3]; 10594 10595 if (val1 == 4 || val2 == 4) 10596 /* Other val must be 8, since we know they are adjacent and neither 10597 is zero. */ 10598 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm); 10599 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1)) 10600 { 10601 ldm[0] = ops[0] = operands[4]; 10602 ops[1] = base_reg; 10603 ops[2] = GEN_INT (val1); 10604 output_add_immediate (ops); 10605 if (val1 < val2) 10606 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm); 10607 else 10608 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm); 10609 } 10610 else 10611 { 10612 /* Offset is out of range for a single add, so use two ldr. */ 10613 ops[0] = ldm[1]; 10614 ops[1] = base_reg; 10615 ops[2] = GEN_INT (val1); 10616 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops); 10617 ops[0] = ldm[2]; 10618 ops[2] = GEN_INT (val2); 10619 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops); 10620 } 10621 } 10622 else if (val1 != 0) 10623 { 10624 if (val1 < val2) 10625 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm); 10626 else 10627 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm); 10628 } 10629 else 10630 { 10631 if (val1 < val2) 10632 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm); 10633 else 10634 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm); 10635 } 10636 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith); 10637 return \"\"; 10638 }" 10639 [(set_attr "length" "12") 10640 (set_attr "predicable" "yes") 10641 (set_attr "type" "load_4")] 10642) 10643 10644; This pattern is never tried by combine, so do it as a peephole 10645 10646(define_peephole2 10647 [(set (match_operand:SI 0 "arm_general_register_operand" "") 10648 (match_operand:SI 1 "arm_general_register_operand" "")) 10649 (set (reg:CC CC_REGNUM) 10650 (compare:CC (match_dup 1) (const_int 0)))] 10651 "TARGET_ARM" 10652 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0))) 10653 (set (match_dup 0) (match_dup 1))])] 10654 "" 10655) 10656 10657(define_split 10658 [(set (match_operand:SI 0 "s_register_operand" "") 10659 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "") 10660 (const_int 0)) 10661 (neg:SI (match_operator:SI 2 "arm_comparison_operator" 10662 [(match_operand:SI 3 "s_register_operand" "") 10663 (match_operand:SI 4 "arm_rhs_operand" "")])))) 10664 (clobber (match_operand:SI 5 "s_register_operand" ""))] 10665 "TARGET_ARM" 10666 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31)))) 10667 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) 10668 (match_dup 5)))] 10669 "" 10670) 10671 10672;; This split can be used because CC_Z mode implies that the following 10673;; branch will be an equality, or an unsigned inequality, so the sign 10674;; extension is not needed. 10675 10676(define_split 10677 [(set (reg:CC_Z CC_REGNUM) 10678 (compare:CC_Z 10679 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0) 10680 (const_int 24)) 10681 (match_operand 1 "const_int_operand" ""))) 10682 (clobber (match_scratch:SI 2 ""))] 10683 "TARGET_ARM 10684 && ((UINTVAL (operands[1])) 10685 == ((UINTVAL (operands[1])) >> 24) << 24)" 10686 [(set (match_dup 2) (zero_extend:SI (match_dup 0))) 10687 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))] 10688 " 10689 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24); 10690 " 10691) 10692;; ??? Check the patterns above for Thumb-2 usefulness 10693 10694(define_expand "prologue" 10695 [(clobber (const_int 0))] 10696 "TARGET_EITHER" 10697 "if (TARGET_32BIT) 10698 arm_expand_prologue (); 10699 else 10700 thumb1_expand_prologue (); 10701 DONE; 10702 " 10703) 10704 10705(define_expand "epilogue" 10706 [(clobber (const_int 0))] 10707 "TARGET_EITHER" 10708 " 10709 if (crtl->calls_eh_return) 10710 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2))); 10711 if (TARGET_THUMB1) 10712 { 10713 thumb1_expand_epilogue (); 10714 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, 10715 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE)); 10716 } 10717 else if (HAVE_return) 10718 { 10719 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence, 10720 no need for explicit testing again. */ 10721 emit_jump_insn (gen_return ()); 10722 } 10723 else if (TARGET_32BIT) 10724 { 10725 arm_expand_epilogue (true); 10726 } 10727 DONE; 10728 " 10729) 10730 10731;; Note - although unspec_volatile's USE all hard registers, 10732;; USEs are ignored after relaod has completed. Thus we need 10733;; to add an unspec of the link register to ensure that flow 10734;; does not think that it is unused by the sibcall branch that 10735;; will replace the standard function epilogue. 10736(define_expand "sibcall_epilogue" 10737 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE) 10738 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])] 10739 "TARGET_32BIT" 10740 " 10741 arm_expand_epilogue (false); 10742 DONE; 10743 " 10744) 10745 10746(define_expand "eh_epilogue" 10747 [(use (match_operand:SI 0 "register_operand" "")) 10748 (use (match_operand:SI 1 "register_operand" "")) 10749 (use (match_operand:SI 2 "register_operand" ""))] 10750 "TARGET_EITHER" 10751 " 10752 { 10753 cfun->machine->eh_epilogue_sp_ofs = operands[1]; 10754 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2) 10755 { 10756 rtx ra = gen_rtx_REG (Pmode, 2); 10757 10758 emit_move_insn (ra, operands[2]); 10759 operands[2] = ra; 10760 } 10761 /* This is a hack -- we may have crystalized the function type too 10762 early. */ 10763 cfun->machine->func_type = 0; 10764 }" 10765) 10766 10767;; This split is only used during output to reduce the number of patterns 10768;; that need assembler instructions adding to them. We allowed the setting 10769;; of the conditions to be implicit during rtl generation so that 10770;; the conditional compare patterns would work. However this conflicts to 10771;; some extent with the conditional data operations, so we have to split them 10772;; up again here. 10773 10774;; ??? Need to audit these splitters for Thumb-2. Why isn't normal 10775;; conditional execution sufficient? 10776 10777(define_split 10778 [(set (match_operand:SI 0 "s_register_operand" "") 10779 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 10780 [(match_operand 2 "" "") (match_operand 3 "" "")]) 10781 (match_dup 0) 10782 (match_operand 4 "" ""))) 10783 (clobber (reg:CC CC_REGNUM))] 10784 "TARGET_ARM && reload_completed" 10785 [(set (match_dup 5) (match_dup 6)) 10786 (cond_exec (match_dup 7) 10787 (set (match_dup 0) (match_dup 4)))] 10788 " 10789 { 10790 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 10791 operands[2], operands[3]); 10792 enum rtx_code rc = GET_CODE (operands[1]); 10793 10794 operands[5] = gen_rtx_REG (mode, CC_REGNUM); 10795 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 10796 if (mode == CCFPmode || mode == CCFPEmode) 10797 rc = reverse_condition_maybe_unordered (rc); 10798 else 10799 rc = reverse_condition (rc); 10800 10801 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx); 10802 }" 10803) 10804 10805(define_split 10806 [(set (match_operand:SI 0 "s_register_operand" "") 10807 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 10808 [(match_operand 2 "" "") (match_operand 3 "" "")]) 10809 (match_operand 4 "" "") 10810 (match_dup 0))) 10811 (clobber (reg:CC CC_REGNUM))] 10812 "TARGET_ARM && reload_completed" 10813 [(set (match_dup 5) (match_dup 6)) 10814 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)]) 10815 (set (match_dup 0) (match_dup 4)))] 10816 " 10817 { 10818 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 10819 operands[2], operands[3]); 10820 10821 operands[5] = gen_rtx_REG (mode, CC_REGNUM); 10822 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 10823 }" 10824) 10825 10826(define_split 10827 [(set (match_operand:SI 0 "s_register_operand" "") 10828 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 10829 [(match_operand 2 "" "") (match_operand 3 "" "")]) 10830 (match_operand 4 "" "") 10831 (match_operand 5 "" ""))) 10832 (clobber (reg:CC CC_REGNUM))] 10833 "TARGET_ARM && reload_completed" 10834 [(set (match_dup 6) (match_dup 7)) 10835 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) 10836 (set (match_dup 0) (match_dup 4))) 10837 (cond_exec (match_dup 8) 10838 (set (match_dup 0) (match_dup 5)))] 10839 " 10840 { 10841 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 10842 operands[2], operands[3]); 10843 enum rtx_code rc = GET_CODE (operands[1]); 10844 10845 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 10846 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 10847 if (mode == CCFPmode || mode == CCFPEmode) 10848 rc = reverse_condition_maybe_unordered (rc); 10849 else 10850 rc = reverse_condition (rc); 10851 10852 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 10853 }" 10854) 10855 10856(define_split 10857 [(set (match_operand:SI 0 "s_register_operand" "") 10858 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 10859 [(match_operand:SI 2 "s_register_operand" "") 10860 (match_operand:SI 3 "arm_add_operand" "")]) 10861 (match_operand:SI 4 "arm_rhs_operand" "") 10862 (not:SI 10863 (match_operand:SI 5 "s_register_operand" "")))) 10864 (clobber (reg:CC CC_REGNUM))] 10865 "TARGET_ARM && reload_completed" 10866 [(set (match_dup 6) (match_dup 7)) 10867 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) 10868 (set (match_dup 0) (match_dup 4))) 10869 (cond_exec (match_dup 8) 10870 (set (match_dup 0) (not:SI (match_dup 5))))] 10871 " 10872 { 10873 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 10874 operands[2], operands[3]); 10875 enum rtx_code rc = GET_CODE (operands[1]); 10876 10877 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 10878 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 10879 if (mode == CCFPmode || mode == CCFPEmode) 10880 rc = reverse_condition_maybe_unordered (rc); 10881 else 10882 rc = reverse_condition (rc); 10883 10884 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 10885 }" 10886) 10887 10888(define_insn "*cond_move_not" 10889 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10890 (if_then_else:SI (match_operator 4 "arm_comparison_operator" 10891 [(match_operand 3 "cc_register" "") (const_int 0)]) 10892 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 10893 (not:SI 10894 (match_operand:SI 2 "s_register_operand" "r,r"))))] 10895 "TARGET_ARM" 10896 "@ 10897 mvn%D4\\t%0, %2 10898 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2" 10899 [(set_attr "conds" "use") 10900 (set_attr "type" "mvn_reg,multiple") 10901 (set_attr "length" "4,8")] 10902) 10903 10904;; The next two patterns occur when an AND operation is followed by a 10905;; scc insn sequence 10906 10907(define_insn "*sign_extract_onebit" 10908 [(set (match_operand:SI 0 "s_register_operand" "=r") 10909 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 10910 (const_int 1) 10911 (match_operand:SI 2 "const_int_operand" "n"))) 10912 (clobber (reg:CC CC_REGNUM))] 10913 "TARGET_ARM" 10914 "* 10915 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10916 output_asm_insn (\"ands\\t%0, %1, %2\", operands); 10917 return \"mvnne\\t%0, #0\"; 10918 " 10919 [(set_attr "conds" "clob") 10920 (set_attr "length" "8") 10921 (set_attr "type" "multiple")] 10922) 10923 10924(define_insn "*not_signextract_onebit" 10925 [(set (match_operand:SI 0 "s_register_operand" "=r") 10926 (not:SI 10927 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 10928 (const_int 1) 10929 (match_operand:SI 2 "const_int_operand" "n")))) 10930 (clobber (reg:CC CC_REGNUM))] 10931 "TARGET_ARM" 10932 "* 10933 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10934 output_asm_insn (\"tst\\t%1, %2\", operands); 10935 output_asm_insn (\"mvneq\\t%0, #0\", operands); 10936 return \"movne\\t%0, #0\"; 10937 " 10938 [(set_attr "conds" "clob") 10939 (set_attr "length" "12") 10940 (set_attr "type" "multiple")] 10941) 10942;; ??? The above patterns need auditing for Thumb-2 10943 10944;; Push multiple registers to the stack. Registers are in parallel (use ...) 10945;; expressions. For simplicity, the first register is also in the unspec 10946;; part. 10947;; To avoid the usage of GNU extension, the length attribute is computed 10948;; in a C function arm_attr_length_push_multi. 10949(define_insn "*push_multi" 10950 [(match_parallel 2 "multi_register_push" 10951 [(set (match_operand:BLK 0 "push_mult_memory_operand" "") 10952 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")] 10953 UNSPEC_PUSH_MULT))])] 10954 "" 10955 "* 10956 { 10957 int num_saves = XVECLEN (operands[2], 0); 10958 10959 /* For the StrongARM at least it is faster to 10960 use STR to store only a single register. 10961 In Thumb mode always use push, and the assembler will pick 10962 something appropriate. */ 10963 if (num_saves == 1 && TARGET_ARM) 10964 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands); 10965 else 10966 { 10967 int i; 10968 char pattern[100]; 10969 10970 if (TARGET_32BIT) 10971 strcpy (pattern, \"push%?\\t{%1\"); 10972 else 10973 strcpy (pattern, \"push\\t{%1\"); 10974 10975 for (i = 1; i < num_saves; i++) 10976 { 10977 strcat (pattern, \", %|\"); 10978 strcat (pattern, 10979 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]); 10980 } 10981 10982 strcat (pattern, \"}\"); 10983 output_asm_insn (pattern, operands); 10984 } 10985 10986 return \"\"; 10987 }" 10988 [(set_attr "type" "store_16") 10989 (set (attr "length") 10990 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))] 10991) 10992 10993(define_insn "stack_tie" 10994 [(set (mem:BLK (scratch)) 10995 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk") 10996 (match_operand:SI 1 "s_register_operand" "rk")] 10997 UNSPEC_PRLG_STK))] 10998 "" 10999 "" 11000 [(set_attr "length" "0") 11001 (set_attr "type" "block")] 11002) 11003 11004;; Pop (as used in epilogue RTL) 11005;; 11006(define_insn "*load_multiple_with_writeback" 11007 [(match_parallel 0 "load_multiple_operation" 11008 [(set (match_operand:SI 1 "s_register_operand" "+rk") 11009 (plus:SI (match_dup 1) 11010 (match_operand:SI 2 "const_int_I_operand" "I"))) 11011 (set (match_operand:SI 3 "s_register_operand" "=rk") 11012 (mem:SI (match_dup 1))) 11013 ])] 11014 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11015 "* 11016 { 11017 arm_output_multireg_pop (operands, /*return_pc=*/false, 11018 /*cond=*/const_true_rtx, 11019 /*reverse=*/false, 11020 /*update=*/true); 11021 return \"\"; 11022 } 11023 " 11024 [(set_attr "type" "load_16") 11025 (set_attr "predicable" "yes") 11026 (set (attr "length") 11027 (symbol_ref "arm_attr_length_pop_multi (operands, 11028 /*return_pc=*/false, 11029 /*write_back_p=*/true)"))] 11030) 11031 11032;; Pop with return (as used in epilogue RTL) 11033;; 11034;; This instruction is generated when the registers are popped at the end of 11035;; epilogue. Here, instead of popping the value into LR and then generating 11036;; jump to LR, value is popped into PC directly. Hence, the pattern is combined 11037;; with (return). 11038(define_insn "*pop_multiple_with_writeback_and_return" 11039 [(match_parallel 0 "pop_multiple_return" 11040 [(return) 11041 (set (match_operand:SI 1 "s_register_operand" "+rk") 11042 (plus:SI (match_dup 1) 11043 (match_operand:SI 2 "const_int_I_operand" "I"))) 11044 (set (match_operand:SI 3 "s_register_operand" "=rk") 11045 (mem:SI (match_dup 1))) 11046 ])] 11047 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11048 "* 11049 { 11050 arm_output_multireg_pop (operands, /*return_pc=*/true, 11051 /*cond=*/const_true_rtx, 11052 /*reverse=*/false, 11053 /*update=*/true); 11054 return \"\"; 11055 } 11056 " 11057 [(set_attr "type" "load_16") 11058 (set_attr "predicable" "yes") 11059 (set (attr "length") 11060 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true, 11061 /*write_back_p=*/true)"))] 11062) 11063 11064(define_insn "*pop_multiple_with_return" 11065 [(match_parallel 0 "pop_multiple_return" 11066 [(return) 11067 (set (match_operand:SI 2 "s_register_operand" "=rk") 11068 (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) 11069 ])] 11070 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11071 "* 11072 { 11073 arm_output_multireg_pop (operands, /*return_pc=*/true, 11074 /*cond=*/const_true_rtx, 11075 /*reverse=*/false, 11076 /*update=*/false); 11077 return \"\"; 11078 } 11079 " 11080 [(set_attr "type" "load_16") 11081 (set_attr "predicable" "yes") 11082 (set (attr "length") 11083 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true, 11084 /*write_back_p=*/false)"))] 11085) 11086 11087;; Load into PC and return 11088(define_insn "*ldr_with_return" 11089 [(return) 11090 (set (reg:SI PC_REGNUM) 11091 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))] 11092 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11093 "ldr%?\t%|pc, [%0], #4" 11094 [(set_attr "type" "load_4") 11095 (set_attr "predicable" "yes")] 11096) 11097;; Pop for floating point registers (as used in epilogue RTL) 11098(define_insn "*vfp_pop_multiple_with_writeback" 11099 [(match_parallel 0 "pop_multiple_fp" 11100 [(set (match_operand:SI 1 "s_register_operand" "+rk") 11101 (plus:SI (match_dup 1) 11102 (match_operand:SI 2 "const_int_I_operand" "I"))) 11103 (set (match_operand:DF 3 "vfp_hard_register_operand" "") 11104 (mem:DF (match_dup 1)))])] 11105 "TARGET_32BIT && TARGET_HARD_FLOAT" 11106 "* 11107 { 11108 int num_regs = XVECLEN (operands[0], 0); 11109 char pattern[100]; 11110 rtx op_list[2]; 11111 strcpy (pattern, \"vldm\\t\"); 11112 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]); 11113 strcat (pattern, \"!, {\"); 11114 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0); 11115 strcat (pattern, \"%P0\"); 11116 if ((num_regs - 1) > 1) 11117 { 11118 strcat (pattern, \"-%P1\"); 11119 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0); 11120 } 11121 11122 strcat (pattern, \"}\"); 11123 output_asm_insn (pattern, op_list); 11124 return \"\"; 11125 } 11126 " 11127 [(set_attr "type" "load_16") 11128 (set_attr "conds" "unconditional") 11129 (set_attr "predicable" "no")] 11130) 11131 11132;; Special patterns for dealing with the constant pool 11133 11134(define_insn "align_4" 11135 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)] 11136 "TARGET_EITHER" 11137 "* 11138 assemble_align (32); 11139 return \"\"; 11140 " 11141 [(set_attr "type" "no_insn")] 11142) 11143 11144(define_insn "align_8" 11145 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)] 11146 "TARGET_EITHER" 11147 "* 11148 assemble_align (64); 11149 return \"\"; 11150 " 11151 [(set_attr "type" "no_insn")] 11152) 11153 11154(define_insn "consttable_end" 11155 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)] 11156 "TARGET_EITHER" 11157 "* 11158 making_const_table = FALSE; 11159 return \"\"; 11160 " 11161 [(set_attr "type" "no_insn")] 11162) 11163 11164(define_insn "consttable_1" 11165 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)] 11166 "TARGET_EITHER" 11167 "* 11168 making_const_table = TRUE; 11169 assemble_integer (operands[0], 1, BITS_PER_WORD, 1); 11170 assemble_zeros (3); 11171 return \"\"; 11172 " 11173 [(set_attr "length" "4") 11174 (set_attr "type" "no_insn")] 11175) 11176 11177(define_insn "consttable_2" 11178 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)] 11179 "TARGET_EITHER" 11180 "* 11181 { 11182 rtx x = operands[0]; 11183 making_const_table = TRUE; 11184 switch (GET_MODE_CLASS (GET_MODE (x))) 11185 { 11186 case MODE_FLOAT: 11187 arm_emit_fp16_const (x); 11188 break; 11189 default: 11190 assemble_integer (operands[0], 2, BITS_PER_WORD, 1); 11191 assemble_zeros (2); 11192 break; 11193 } 11194 return \"\"; 11195 }" 11196 [(set_attr "length" "4") 11197 (set_attr "type" "no_insn")] 11198) 11199 11200(define_insn "consttable_4" 11201 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)] 11202 "TARGET_EITHER" 11203 "* 11204 { 11205 rtx x = operands[0]; 11206 making_const_table = TRUE; 11207 scalar_float_mode float_mode; 11208 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode)) 11209 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD); 11210 else 11211 { 11212 /* XXX: Sometimes gcc does something really dumb and ends up with 11213 a HIGH in a constant pool entry, usually because it's trying to 11214 load into a VFP register. We know this will always be used in 11215 combination with a LO_SUM which ignores the high bits, so just 11216 strip off the HIGH. */ 11217 if (GET_CODE (x) == HIGH) 11218 x = XEXP (x, 0); 11219 assemble_integer (x, 4, BITS_PER_WORD, 1); 11220 mark_symbol_refs_as_used (x); 11221 } 11222 return \"\"; 11223 }" 11224 [(set_attr "length" "4") 11225 (set_attr "type" "no_insn")] 11226) 11227 11228(define_insn "consttable_8" 11229 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)] 11230 "TARGET_EITHER" 11231 "* 11232 { 11233 making_const_table = TRUE; 11234 scalar_float_mode float_mode; 11235 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode)) 11236 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]), 11237 float_mode, BITS_PER_WORD); 11238 else 11239 assemble_integer (operands[0], 8, BITS_PER_WORD, 1); 11240 return \"\"; 11241 }" 11242 [(set_attr "length" "8") 11243 (set_attr "type" "no_insn")] 11244) 11245 11246(define_insn "consttable_16" 11247 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)] 11248 "TARGET_EITHER" 11249 "* 11250 { 11251 making_const_table = TRUE; 11252 scalar_float_mode float_mode; 11253 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode)) 11254 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]), 11255 float_mode, BITS_PER_WORD); 11256 else 11257 assemble_integer (operands[0], 16, BITS_PER_WORD, 1); 11258 return \"\"; 11259 }" 11260 [(set_attr "length" "16") 11261 (set_attr "type" "no_insn")] 11262) 11263 11264;; V5 Instructions, 11265 11266(define_insn "clzsi2" 11267 [(set (match_operand:SI 0 "s_register_operand" "=r") 11268 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))] 11269 "TARGET_32BIT && arm_arch5" 11270 "clz%?\\t%0, %1" 11271 [(set_attr "predicable" "yes") 11272 (set_attr "type" "clz")]) 11273 11274(define_insn "rbitsi2" 11275 [(set (match_operand:SI 0 "s_register_operand" "=r") 11276 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))] 11277 "TARGET_32BIT && arm_arch_thumb2" 11278 "rbit%?\\t%0, %1" 11279 [(set_attr "predicable" "yes") 11280 (set_attr "type" "clz")]) 11281 11282;; Keep this as a CTZ expression until after reload and then split 11283;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely 11284;; to fold with any other expression. 11285 11286(define_insn_and_split "ctzsi2" 11287 [(set (match_operand:SI 0 "s_register_operand" "=r") 11288 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))] 11289 "TARGET_32BIT && arm_arch_thumb2" 11290 "#" 11291 "&& reload_completed" 11292 [(const_int 0)] 11293 " 11294 emit_insn (gen_rbitsi2 (operands[0], operands[1])); 11295 emit_insn (gen_clzsi2 (operands[0], operands[0])); 11296 DONE; 11297") 11298 11299;; V5E instructions. 11300 11301(define_insn "prefetch" 11302 [(prefetch (match_operand:SI 0 "address_operand" "p") 11303 (match_operand:SI 1 "" "") 11304 (match_operand:SI 2 "" ""))] 11305 "TARGET_32BIT && arm_arch5e" 11306 "pld\\t%a0" 11307 [(set_attr "type" "load_4")] 11308) 11309 11310;; General predication pattern 11311 11312(define_cond_exec 11313 [(match_operator 0 "arm_comparison_operator" 11314 [(match_operand 1 "cc_register" "") 11315 (const_int 0)])] 11316 "TARGET_32BIT 11317 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))" 11318 "" 11319[(set_attr "predicated" "yes")] 11320) 11321 11322(define_insn "force_register_use" 11323 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)] 11324 "" 11325 "%@ %0 needed" 11326 [(set_attr "length" "0") 11327 (set_attr "type" "no_insn")] 11328) 11329 11330 11331;; Patterns for exception handling 11332 11333(define_expand "eh_return" 11334 [(use (match_operand 0 "general_operand" ""))] 11335 "TARGET_EITHER" 11336 " 11337 { 11338 if (TARGET_32BIT) 11339 emit_insn (gen_arm_eh_return (operands[0])); 11340 else 11341 emit_insn (gen_thumb_eh_return (operands[0])); 11342 DONE; 11343 }" 11344) 11345 11346;; We can't expand this before we know where the link register is stored. 11347(define_insn_and_split "arm_eh_return" 11348 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")] 11349 VUNSPEC_EH_RETURN) 11350 (clobber (match_scratch:SI 1 "=&r"))] 11351 "TARGET_ARM" 11352 "#" 11353 "&& reload_completed" 11354 [(const_int 0)] 11355 " 11356 { 11357 arm_set_return_address (operands[0], operands[1]); 11358 DONE; 11359 }" 11360) 11361 11362 11363;; TLS support 11364 11365(define_insn "load_tp_hard" 11366 [(set (match_operand:SI 0 "register_operand" "=r") 11367 (unspec:SI [(const_int 0)] UNSPEC_TLS))] 11368 "TARGET_HARD_TP" 11369 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard" 11370 [(set_attr "predicable" "yes") 11371 (set_attr "type" "mrs")] 11372) 11373 11374;; Doesn't clobber R1-R3. Must use r0 for the first operand. 11375(define_insn "load_tp_soft" 11376 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS)) 11377 (clobber (reg:SI LR_REGNUM)) 11378 (clobber (reg:SI IP_REGNUM)) 11379 (clobber (reg:CC CC_REGNUM))] 11380 "TARGET_SOFT_TP" 11381 "bl\\t__aeabi_read_tp\\t@ load_tp_soft" 11382 [(set_attr "conds" "clob") 11383 (set_attr "type" "branch")] 11384) 11385 11386;; tls descriptor call 11387(define_insn "tlscall" 11388 [(set (reg:SI R0_REGNUM) 11389 (unspec:SI [(reg:SI R0_REGNUM) 11390 (match_operand:SI 0 "" "X") 11391 (match_operand 1 "" "")] UNSPEC_TLS)) 11392 (clobber (reg:SI R1_REGNUM)) 11393 (clobber (reg:SI LR_REGNUM)) 11394 (clobber (reg:SI CC_REGNUM))] 11395 "TARGET_GNU2_TLS" 11396 { 11397 targetm.asm_out.internal_label (asm_out_file, "LPIC", 11398 INTVAL (operands[1])); 11399 return "bl\\t%c0(tlscall)"; 11400 } 11401 [(set_attr "conds" "clob") 11402 (set_attr "length" "4") 11403 (set_attr "type" "branch")] 11404) 11405 11406;; For thread pointer builtin 11407(define_expand "get_thread_pointersi" 11408 [(match_operand:SI 0 "s_register_operand" "=r")] 11409 "" 11410 " 11411 { 11412 arm_load_tp (operands[0]); 11413 DONE; 11414 }") 11415 11416;; 11417 11418;; We only care about the lower 16 bits of the constant 11419;; being inserted into the upper 16 bits of the register. 11420(define_insn "*arm_movtas_ze" 11421 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r") 11422 (const_int 16) 11423 (const_int 16)) 11424 (match_operand:SI 1 "const_int_operand" ""))] 11425 "TARGET_HAVE_MOVT" 11426 "@ 11427 movt%?\t%0, %L1 11428 movt\t%0, %L1" 11429 [(set_attr "arch" "32,v8mb") 11430 (set_attr "predicable" "yes") 11431 (set_attr "length" "4") 11432 (set_attr "type" "alu_sreg")] 11433) 11434 11435(define_insn "*arm_rev" 11436 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") 11437 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))] 11438 "arm_arch6" 11439 "@ 11440 rev\t%0, %1 11441 rev%?\t%0, %1 11442 rev%?\t%0, %1" 11443 [(set_attr "arch" "t1,t2,32") 11444 (set_attr "length" "2,2,4") 11445 (set_attr "predicable" "no,yes,yes") 11446 (set_attr "type" "rev")] 11447) 11448 11449(define_expand "arm_legacy_rev" 11450 [(set (match_operand:SI 2 "s_register_operand" "") 11451 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "") 11452 (const_int 16)) 11453 (match_dup 1))) 11454 (set (match_dup 2) 11455 (lshiftrt:SI (match_dup 2) 11456 (const_int 8))) 11457 (set (match_operand:SI 3 "s_register_operand" "") 11458 (rotatert:SI (match_dup 1) 11459 (const_int 8))) 11460 (set (match_dup 2) 11461 (and:SI (match_dup 2) 11462 (const_int -65281))) 11463 (set (match_operand:SI 0 "s_register_operand" "") 11464 (xor:SI (match_dup 3) 11465 (match_dup 2)))] 11466 "TARGET_32BIT" 11467 "" 11468) 11469 11470;; Reuse temporaries to keep register pressure down. 11471(define_expand "thumb_legacy_rev" 11472 [(set (match_operand:SI 2 "s_register_operand" "") 11473 (ashift:SI (match_operand:SI 1 "s_register_operand" "") 11474 (const_int 24))) 11475 (set (match_operand:SI 3 "s_register_operand" "") 11476 (lshiftrt:SI (match_dup 1) 11477 (const_int 24))) 11478 (set (match_dup 3) 11479 (ior:SI (match_dup 3) 11480 (match_dup 2))) 11481 (set (match_operand:SI 4 "s_register_operand" "") 11482 (const_int 16)) 11483 (set (match_operand:SI 5 "s_register_operand" "") 11484 (rotatert:SI (match_dup 1) 11485 (match_dup 4))) 11486 (set (match_dup 2) 11487 (ashift:SI (match_dup 5) 11488 (const_int 24))) 11489 (set (match_dup 5) 11490 (lshiftrt:SI (match_dup 5) 11491 (const_int 24))) 11492 (set (match_dup 5) 11493 (ior:SI (match_dup 5) 11494 (match_dup 2))) 11495 (set (match_dup 5) 11496 (rotatert:SI (match_dup 5) 11497 (match_dup 4))) 11498 (set (match_operand:SI 0 "s_register_operand" "") 11499 (ior:SI (match_dup 5) 11500 (match_dup 3)))] 11501 "TARGET_THUMB" 11502 "" 11503) 11504 11505;; ARM-specific expansion of signed mod by power of 2 11506;; using conditional negate. 11507;; For r0 % n where n is a power of 2 produce: 11508;; rsbs r1, r0, #0 11509;; and r0, r0, #(n - 1) 11510;; and r1, r1, #(n - 1) 11511;; rsbpl r0, r1, #0 11512 11513(define_expand "modsi3" 11514 [(match_operand:SI 0 "register_operand" "") 11515 (match_operand:SI 1 "register_operand" "") 11516 (match_operand:SI 2 "const_int_operand" "")] 11517 "TARGET_32BIT" 11518 { 11519 HOST_WIDE_INT val = INTVAL (operands[2]); 11520 11521 if (val <= 0 11522 || exact_log2 (val) <= 0) 11523 FAIL; 11524 11525 rtx mask = GEN_INT (val - 1); 11526 11527 /* In the special case of x0 % 2 we can do the even shorter: 11528 cmp r0, #0 11529 and r0, r0, #1 11530 rsblt r0, r0, #0. */ 11531 11532 if (val == 2) 11533 { 11534 rtx cc_reg = arm_gen_compare_reg (LT, 11535 operands[1], const0_rtx, NULL_RTX); 11536 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx); 11537 rtx masked = gen_reg_rtx (SImode); 11538 11539 emit_insn (gen_andsi3 (masked, operands[1], mask)); 11540 emit_move_insn (operands[0], 11541 gen_rtx_IF_THEN_ELSE (SImode, cond, 11542 gen_rtx_NEG (SImode, 11543 masked), 11544 masked)); 11545 DONE; 11546 } 11547 11548 rtx neg_op = gen_reg_rtx (SImode); 11549 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx, 11550 operands[1])); 11551 11552 /* Extract the condition register and mode. */ 11553 rtx cmp = XVECEXP (PATTERN (insn), 0, 0); 11554 rtx cc_reg = SET_DEST (cmp); 11555 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx); 11556 11557 emit_insn (gen_andsi3 (operands[0], operands[1], mask)); 11558 11559 rtx masked_neg = gen_reg_rtx (SImode); 11560 emit_insn (gen_andsi3 (masked_neg, neg_op, mask)); 11561 11562 /* We want a conditional negate here, but emitting COND_EXEC rtxes 11563 during expand does not always work. Do an IF_THEN_ELSE instead. */ 11564 emit_move_insn (operands[0], 11565 gen_rtx_IF_THEN_ELSE (SImode, cond, 11566 gen_rtx_NEG (SImode, masked_neg), 11567 operands[0])); 11568 11569 11570 DONE; 11571 } 11572) 11573 11574(define_expand "bswapsi2" 11575 [(set (match_operand:SI 0 "s_register_operand" "=r") 11576 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))] 11577"TARGET_EITHER && (arm_arch6 || !optimize_size)" 11578" 11579 if (!arm_arch6) 11580 { 11581 rtx op2 = gen_reg_rtx (SImode); 11582 rtx op3 = gen_reg_rtx (SImode); 11583 11584 if (TARGET_THUMB) 11585 { 11586 rtx op4 = gen_reg_rtx (SImode); 11587 rtx op5 = gen_reg_rtx (SImode); 11588 11589 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1], 11590 op2, op3, op4, op5)); 11591 } 11592 else 11593 { 11594 emit_insn (gen_arm_legacy_rev (operands[0], operands[1], 11595 op2, op3)); 11596 } 11597 11598 DONE; 11599 } 11600 " 11601) 11602 11603;; bswap16 patterns: use revsh and rev16 instructions for the signed 11604;; and unsigned variants, respectively. For rev16, expose 11605;; byte-swapping in the lower 16 bits only. 11606(define_insn "*arm_revsh" 11607 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") 11608 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))] 11609 "arm_arch6" 11610 "@ 11611 revsh\t%0, %1 11612 revsh%?\t%0, %1 11613 revsh%?\t%0, %1" 11614 [(set_attr "arch" "t1,t2,32") 11615 (set_attr "length" "2,2,4") 11616 (set_attr "type" "rev")] 11617) 11618 11619(define_insn "*arm_rev16" 11620 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r") 11621 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))] 11622 "arm_arch6" 11623 "@ 11624 rev16\t%0, %1 11625 rev16%?\t%0, %1 11626 rev16%?\t%0, %1" 11627 [(set_attr "arch" "t1,t2,32") 11628 (set_attr "length" "2,2,4") 11629 (set_attr "type" "rev")] 11630) 11631 11632;; There are no canonicalisation rules for the position of the lshiftrt, ashift 11633;; operations within an IOR/AND RTX, therefore we have two patterns matching 11634;; each valid permutation. 11635 11636(define_insn "arm_rev16si2" 11637 [(set (match_operand:SI 0 "register_operand" "=l,l,r") 11638 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r") 11639 (const_int 8)) 11640 (match_operand:SI 3 "const_int_operand" "n,n,n")) 11641 (and:SI (lshiftrt:SI (match_dup 1) 11642 (const_int 8)) 11643 (match_operand:SI 2 "const_int_operand" "n,n,n"))))] 11644 "arm_arch6 11645 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode) 11646 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)" 11647 "rev16\\t%0, %1" 11648 [(set_attr "arch" "t1,t2,32") 11649 (set_attr "length" "2,2,4") 11650 (set_attr "type" "rev")] 11651) 11652 11653(define_insn "arm_rev16si2_alt" 11654 [(set (match_operand:SI 0 "register_operand" "=l,l,r") 11655 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r") 11656 (const_int 8)) 11657 (match_operand:SI 2 "const_int_operand" "n,n,n")) 11658 (and:SI (ashift:SI (match_dup 1) 11659 (const_int 8)) 11660 (match_operand:SI 3 "const_int_operand" "n,n,n"))))] 11661 "arm_arch6 11662 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode) 11663 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)" 11664 "rev16\\t%0, %1" 11665 [(set_attr "arch" "t1,t2,32") 11666 (set_attr "length" "2,2,4") 11667 (set_attr "type" "rev")] 11668) 11669 11670(define_expand "bswaphi2" 11671 [(set (match_operand:HI 0 "s_register_operand" "=r") 11672 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))] 11673"arm_arch6" 11674"" 11675) 11676 11677;; Patterns for LDRD/STRD in Thumb2 mode 11678 11679(define_insn "*thumb2_ldrd" 11680 [(set (match_operand:SI 0 "s_register_operand" "=r") 11681 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk") 11682 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do")))) 11683 (set (match_operand:SI 3 "s_register_operand" "=r") 11684 (mem:SI (plus:SI (match_dup 1) 11685 (match_operand:SI 4 "const_int_operand" ""))))] 11686 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11687 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4])) 11688 && (operands_ok_ldrd_strd (operands[0], operands[3], 11689 operands[1], INTVAL (operands[2]), 11690 false, true))" 11691 "ldrd%?\t%0, %3, [%1, %2]" 11692 [(set_attr "type" "load_8") 11693 (set_attr "predicable" "yes")]) 11694 11695(define_insn "*thumb2_ldrd_base" 11696 [(set (match_operand:SI 0 "s_register_operand" "=r") 11697 (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) 11698 (set (match_operand:SI 2 "s_register_operand" "=r") 11699 (mem:SI (plus:SI (match_dup 1) 11700 (const_int 4))))] 11701 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11702 && (operands_ok_ldrd_strd (operands[0], operands[2], 11703 operands[1], 0, false, true))" 11704 "ldrd%?\t%0, %2, [%1]" 11705 [(set_attr "type" "load_8") 11706 (set_attr "predicable" "yes")]) 11707 11708(define_insn "*thumb2_ldrd_base_neg" 11709 [(set (match_operand:SI 0 "s_register_operand" "=r") 11710 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk") 11711 (const_int -4)))) 11712 (set (match_operand:SI 2 "s_register_operand" "=r") 11713 (mem:SI (match_dup 1)))] 11714 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11715 && (operands_ok_ldrd_strd (operands[0], operands[2], 11716 operands[1], -4, false, true))" 11717 "ldrd%?\t%0, %2, [%1, #-4]" 11718 [(set_attr "type" "load_8") 11719 (set_attr "predicable" "yes")]) 11720 11721(define_insn "*thumb2_strd" 11722 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk") 11723 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do"))) 11724 (match_operand:SI 2 "s_register_operand" "r")) 11725 (set (mem:SI (plus:SI (match_dup 0) 11726 (match_operand:SI 3 "const_int_operand" ""))) 11727 (match_operand:SI 4 "s_register_operand" "r"))] 11728 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11729 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3])) 11730 && (operands_ok_ldrd_strd (operands[2], operands[4], 11731 operands[0], INTVAL (operands[1]), 11732 false, false))" 11733 "strd%?\t%2, %4, [%0, %1]" 11734 [(set_attr "type" "store_8") 11735 (set_attr "predicable" "yes")]) 11736 11737(define_insn "*thumb2_strd_base" 11738 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk")) 11739 (match_operand:SI 1 "s_register_operand" "r")) 11740 (set (mem:SI (plus:SI (match_dup 0) 11741 (const_int 4))) 11742 (match_operand:SI 2 "s_register_operand" "r"))] 11743 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11744 && (operands_ok_ldrd_strd (operands[1], operands[2], 11745 operands[0], 0, false, false))" 11746 "strd%?\t%1, %2, [%0]" 11747 [(set_attr "type" "store_8") 11748 (set_attr "predicable" "yes")]) 11749 11750(define_insn "*thumb2_strd_base_neg" 11751 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk") 11752 (const_int -4))) 11753 (match_operand:SI 1 "s_register_operand" "r")) 11754 (set (mem:SI (match_dup 0)) 11755 (match_operand:SI 2 "s_register_operand" "r"))] 11756 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11757 && (operands_ok_ldrd_strd (operands[1], operands[2], 11758 operands[0], -4, false, false))" 11759 "strd%?\t%1, %2, [%0, #-4]" 11760 [(set_attr "type" "store_8") 11761 (set_attr "predicable" "yes")]) 11762 11763;; ARMv8 CRC32 instructions. 11764(define_insn "<crc_variant>" 11765 [(set (match_operand:SI 0 "s_register_operand" "=r") 11766 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r") 11767 (match_operand:<crc_mode> 2 "s_register_operand" "r")] 11768 CRC))] 11769 "TARGET_CRC32" 11770 "<crc_variant>\\t%0, %1, %2" 11771 [(set_attr "type" "crc") 11772 (set_attr "conds" "unconditional")] 11773) 11774 11775;; Load the load/store double peephole optimizations. 11776(include "ldrdstrd.md") 11777 11778;; Load the load/store multiple patterns 11779(include "ldmstm.md") 11780 11781;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers 11782;; large lists without explicit writeback generated for APCS_FRAME epilogue. 11783;; The operands are validated through the load_multiple_operation 11784;; match_parallel predicate rather than through constraints so enable it only 11785;; after reload. 11786(define_insn "*load_multiple" 11787 [(match_parallel 0 "load_multiple_operation" 11788 [(set (match_operand:SI 2 "s_register_operand" "=rk") 11789 (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) 11790 ])] 11791 "TARGET_32BIT && reload_completed" 11792 "* 11793 { 11794 arm_output_multireg_pop (operands, /*return_pc=*/false, 11795 /*cond=*/const_true_rtx, 11796 /*reverse=*/false, 11797 /*update=*/false); 11798 return \"\"; 11799 } 11800 " 11801 [(set_attr "predicable" "yes")] 11802) 11803 11804(define_expand "copysignsf3" 11805 [(match_operand:SF 0 "register_operand") 11806 (match_operand:SF 1 "register_operand") 11807 (match_operand:SF 2 "register_operand")] 11808 "TARGET_SOFT_FLOAT && arm_arch_thumb2" 11809 "{ 11810 emit_move_insn (operands[0], operands[2]); 11811 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0), 11812 GEN_INT (31), GEN_INT (0), 11813 simplify_gen_subreg (SImode, operands[1], SFmode, 0))); 11814 DONE; 11815 }" 11816) 11817 11818(define_expand "copysigndf3" 11819 [(match_operand:DF 0 "register_operand") 11820 (match_operand:DF 1 "register_operand") 11821 (match_operand:DF 2 "register_operand")] 11822 "TARGET_SOFT_FLOAT && arm_arch_thumb2" 11823 "{ 11824 rtx op0_low = gen_lowpart (SImode, operands[0]); 11825 rtx op0_high = gen_highpart (SImode, operands[0]); 11826 rtx op1_low = gen_lowpart (SImode, operands[1]); 11827 rtx op1_high = gen_highpart (SImode, operands[1]); 11828 rtx op2_high = gen_highpart (SImode, operands[2]); 11829 11830 rtx scratch1 = gen_reg_rtx (SImode); 11831 rtx scratch2 = gen_reg_rtx (SImode); 11832 emit_move_insn (scratch1, op2_high); 11833 emit_move_insn (scratch2, op1_high); 11834 11835 emit_insn(gen_rtx_SET(scratch1, 11836 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31)))); 11837 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1)); 11838 emit_move_insn (op0_low, op1_low); 11839 emit_move_insn (op0_high, scratch2); 11840 11841 DONE; 11842 }" 11843) 11844 11845;; movmisalign patterns for HImode and SImode. 11846(define_expand "movmisalign<mode>" 11847 [(match_operand:HSI 0 "general_operand") 11848 (match_operand:HSI 1 "general_operand")] 11849 "unaligned_access" 11850{ 11851 /* This pattern is not permitted to fail during expansion: if both arguments 11852 are non-registers (e.g. memory := constant), force operand 1 into a 11853 register. */ 11854 rtx (* gen_unaligned_load)(rtx, rtx); 11855 rtx tmp_dest = operands[0]; 11856 if (!s_register_operand (operands[0], <MODE>mode) 11857 && !s_register_operand (operands[1], <MODE>mode)) 11858 operands[1] = force_reg (<MODE>mode, operands[1]); 11859 11860 if (<MODE>mode == HImode) 11861 { 11862 gen_unaligned_load = gen_unaligned_loadhiu; 11863 tmp_dest = gen_reg_rtx (SImode); 11864 } 11865 else 11866 gen_unaligned_load = gen_unaligned_loadsi; 11867 11868 if (MEM_P (operands[1])) 11869 { 11870 emit_insn (gen_unaligned_load (tmp_dest, operands[1])); 11871 if (<MODE>mode == HImode) 11872 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest)); 11873 } 11874 else 11875 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1])); 11876 11877 DONE; 11878}) 11879 11880(define_insn "<cdp>" 11881 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 11882 (match_operand:SI 1 "immediate_operand" "n") 11883 (match_operand:SI 2 "immediate_operand" "n") 11884 (match_operand:SI 3 "immediate_operand" "n") 11885 (match_operand:SI 4 "immediate_operand" "n") 11886 (match_operand:SI 5 "immediate_operand" "n")] CDPI)] 11887 "arm_coproc_builtin_available (VUNSPEC_<CDP>)" 11888{ 11889 arm_const_bounds (operands[0], 0, 16); 11890 arm_const_bounds (operands[1], 0, 16); 11891 arm_const_bounds (operands[2], 0, (1 << 5)); 11892 arm_const_bounds (operands[3], 0, (1 << 5)); 11893 arm_const_bounds (operands[4], 0, (1 << 5)); 11894 arm_const_bounds (operands[5], 0, 8); 11895 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5"; 11896} 11897 [(set_attr "length" "4") 11898 (set_attr "type" "coproc")]) 11899 11900(define_insn "*ldc" 11901 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 11902 (match_operand:SI 1 "immediate_operand" "n") 11903 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)] 11904 "arm_coproc_builtin_available (VUNSPEC_<LDC>)" 11905{ 11906 arm_const_bounds (operands[0], 0, 16); 11907 arm_const_bounds (operands[1], 0, (1 << 5)); 11908 return "<ldc>\\tp%c0, CR%c1, %2"; 11909} 11910 [(set_attr "length" "4") 11911 (set_attr "type" "coproc")]) 11912 11913(define_insn "*stc" 11914 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 11915 (match_operand:SI 1 "immediate_operand" "n") 11916 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)] 11917 "arm_coproc_builtin_available (VUNSPEC_<STC>)" 11918{ 11919 arm_const_bounds (operands[0], 0, 16); 11920 arm_const_bounds (operands[1], 0, (1 << 5)); 11921 return "<stc>\\tp%c0, CR%c1, %2"; 11922} 11923 [(set_attr "length" "4") 11924 (set_attr "type" "coproc")]) 11925 11926(define_expand "<ldc>" 11927 [(unspec_volatile [(match_operand:SI 0 "immediate_operand") 11928 (match_operand:SI 1 "immediate_operand") 11929 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)] 11930 "arm_coproc_builtin_available (VUNSPEC_<LDC>)") 11931 11932(define_expand "<stc>" 11933 [(unspec_volatile [(match_operand:SI 0 "immediate_operand") 11934 (match_operand:SI 1 "immediate_operand") 11935 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)] 11936 "arm_coproc_builtin_available (VUNSPEC_<STC>)") 11937 11938(define_insn "<mcr>" 11939 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 11940 (match_operand:SI 1 "immediate_operand" "n") 11941 (match_operand:SI 2 "s_register_operand" "r") 11942 (match_operand:SI 3 "immediate_operand" "n") 11943 (match_operand:SI 4 "immediate_operand" "n") 11944 (match_operand:SI 5 "immediate_operand" "n")] MCRI) 11945 (use (match_dup 2))] 11946 "arm_coproc_builtin_available (VUNSPEC_<MCR>)" 11947{ 11948 arm_const_bounds (operands[0], 0, 16); 11949 arm_const_bounds (operands[1], 0, 8); 11950 arm_const_bounds (operands[3], 0, (1 << 5)); 11951 arm_const_bounds (operands[4], 0, (1 << 5)); 11952 arm_const_bounds (operands[5], 0, 8); 11953 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5"; 11954} 11955 [(set_attr "length" "4") 11956 (set_attr "type" "coproc")]) 11957 11958(define_insn "<mrc>" 11959 [(set (match_operand:SI 0 "s_register_operand" "=r") 11960 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n") 11961 (match_operand:SI 2 "immediate_operand" "n") 11962 (match_operand:SI 3 "immediate_operand" "n") 11963 (match_operand:SI 4 "immediate_operand" "n") 11964 (match_operand:SI 5 "immediate_operand" "n")] MRCI))] 11965 "arm_coproc_builtin_available (VUNSPEC_<MRC>)" 11966{ 11967 arm_const_bounds (operands[1], 0, 16); 11968 arm_const_bounds (operands[2], 0, 8); 11969 arm_const_bounds (operands[3], 0, (1 << 5)); 11970 arm_const_bounds (operands[4], 0, (1 << 5)); 11971 arm_const_bounds (operands[5], 0, 8); 11972 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5"; 11973} 11974 [(set_attr "length" "4") 11975 (set_attr "type" "coproc")]) 11976 11977(define_insn "<mcrr>" 11978 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 11979 (match_operand:SI 1 "immediate_operand" "n") 11980 (match_operand:DI 2 "s_register_operand" "r") 11981 (match_operand:SI 3 "immediate_operand" "n")] MCRRI) 11982 (use (match_dup 2))] 11983 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)" 11984{ 11985 arm_const_bounds (operands[0], 0, 16); 11986 arm_const_bounds (operands[1], 0, 8); 11987 arm_const_bounds (operands[3], 0, (1 << 5)); 11988 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3"; 11989} 11990 [(set_attr "length" "4") 11991 (set_attr "type" "coproc")]) 11992 11993(define_insn "<mrrc>" 11994 [(set (match_operand:DI 0 "s_register_operand" "=r") 11995 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n") 11996 (match_operand:SI 2 "immediate_operand" "n") 11997 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))] 11998 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)" 11999{ 12000 arm_const_bounds (operands[1], 0, 16); 12001 arm_const_bounds (operands[2], 0, 8); 12002 arm_const_bounds (operands[3], 0, (1 << 5)); 12003 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3"; 12004} 12005 [(set_attr "length" "4") 12006 (set_attr "type" "coproc")]) 12007 12008;; Vector bits common to IWMMXT and Neon 12009(include "vec-common.md") 12010;; Load the Intel Wireless Multimedia Extension patterns 12011(include "iwmmxt.md") 12012;; Load the VFP co-processor patterns 12013(include "vfp.md") 12014;; Thumb-1 patterns 12015(include "thumb1.md") 12016;; Thumb-2 patterns 12017(include "thumb2.md") 12018;; Neon patterns 12019(include "neon.md") 12020;; Crypto patterns 12021(include "crypto.md") 12022;; Synchronization Primitives 12023(include "sync.md") 12024;; Fixed-point patterns 12025(include "arm-fixed.md") 12026