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,r") 4452 (unspec:SI [(match_operand:SI 1 "memory_operand" "Uw,m")] 4453 UNSPEC_UNALIGNED_LOAD))] 4454 "unaligned_access" 4455 "ldr%?\t%0, %1\t@ unaligned" 4456 [(set_attr "arch" "t2,any") 4457 (set_attr "length" "2,4") 4458 (set_attr "predicable" "yes") 4459 (set_attr "predicable_short_it" "yes,no") 4460 (set_attr "type" "load_4")]) 4461 4462(define_insn "unaligned_loadhis" 4463 [(set (match_operand:SI 0 "s_register_operand" "=r") 4464 (sign_extend:SI 4465 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uh")] 4466 UNSPEC_UNALIGNED_LOAD)))] 4467 "unaligned_access" 4468 "ldrsh%?\t%0, %1\t@ unaligned" 4469 [(set_attr "predicable" "yes") 4470 (set_attr "type" "load_byte")]) 4471 4472(define_insn "unaligned_loadhiu" 4473 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 4474 (zero_extend:SI 4475 (unspec:HI [(match_operand:HI 1 "memory_operand" "Uw,m")] 4476 UNSPEC_UNALIGNED_LOAD)))] 4477 "unaligned_access" 4478 "ldrh%?\t%0, %1\t@ unaligned" 4479 [(set_attr "arch" "t2,any") 4480 (set_attr "length" "2,4") 4481 (set_attr "predicable" "yes") 4482 (set_attr "predicable_short_it" "yes,no") 4483 (set_attr "type" "load_byte")]) 4484 4485(define_insn "unaligned_storesi" 4486 [(set (match_operand:SI 0 "memory_operand" "=Uw,m") 4487 (unspec:SI [(match_operand:SI 1 "s_register_operand" "l,r")] 4488 UNSPEC_UNALIGNED_STORE))] 4489 "unaligned_access" 4490 "str%?\t%1, %0\t@ unaligned" 4491 [(set_attr "arch" "t2,any") 4492 (set_attr "length" "2,4") 4493 (set_attr "predicable" "yes") 4494 (set_attr "predicable_short_it" "yes,no") 4495 (set_attr "type" "store_4")]) 4496 4497(define_insn "unaligned_storehi" 4498 [(set (match_operand:HI 0 "memory_operand" "=Uw,m") 4499 (unspec:HI [(match_operand:HI 1 "s_register_operand" "l,r")] 4500 UNSPEC_UNALIGNED_STORE))] 4501 "unaligned_access" 4502 "strh%?\t%1, %0\t@ unaligned" 4503 [(set_attr "arch" "t2,any") 4504 (set_attr "length" "2,4") 4505 (set_attr "predicable" "yes") 4506 (set_attr "predicable_short_it" "yes,no") 4507 (set_attr "type" "store_4")]) 4508 4509 4510(define_insn "*extv_reg" 4511 [(set (match_operand:SI 0 "s_register_operand" "=r") 4512 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 4513 (match_operand:SI 2 "const_int_operand" "n") 4514 (match_operand:SI 3 "const_int_operand" "n")))] 4515 "arm_arch_thumb2 4516 && IN_RANGE (INTVAL (operands[3]), 0, 31) 4517 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))" 4518 "sbfx%?\t%0, %1, %3, %2" 4519 [(set_attr "length" "4") 4520 (set_attr "predicable" "yes") 4521 (set_attr "type" "bfm")] 4522) 4523 4524(define_insn "extzv_t2" 4525 [(set (match_operand:SI 0 "s_register_operand" "=r") 4526 (zero_extract:SI (match_operand:SI 1 "s_register_operand" "r") 4527 (match_operand:SI 2 "const_int_operand" "n") 4528 (match_operand:SI 3 "const_int_operand" "n")))] 4529 "arm_arch_thumb2 4530 && IN_RANGE (INTVAL (operands[3]), 0, 31) 4531 && IN_RANGE (INTVAL (operands[2]), 1, 32 - INTVAL (operands[3]))" 4532 "ubfx%?\t%0, %1, %3, %2" 4533 [(set_attr "length" "4") 4534 (set_attr "predicable" "yes") 4535 (set_attr "type" "bfm")] 4536) 4537 4538 4539;; Division instructions 4540(define_insn "divsi3" 4541 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 4542 (div:SI (match_operand:SI 1 "s_register_operand" "r,r") 4543 (match_operand:SI 2 "s_register_operand" "r,r")))] 4544 "TARGET_IDIV" 4545 "@ 4546 sdiv%?\t%0, %1, %2 4547 sdiv\t%0, %1, %2" 4548 [(set_attr "arch" "32,v8mb") 4549 (set_attr "predicable" "yes") 4550 (set_attr "type" "sdiv")] 4551) 4552 4553(define_insn "udivsi3" 4554 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 4555 (udiv:SI (match_operand:SI 1 "s_register_operand" "r,r") 4556 (match_operand:SI 2 "s_register_operand" "r,r")))] 4557 "TARGET_IDIV" 4558 "@ 4559 udiv%?\t%0, %1, %2 4560 udiv\t%0, %1, %2" 4561 [(set_attr "arch" "32,v8mb") 4562 (set_attr "predicable" "yes") 4563 (set_attr "type" "udiv")] 4564) 4565 4566 4567;; Unary arithmetic insns 4568 4569(define_expand "negvsi3" 4570 [(match_operand:SI 0 "register_operand") 4571 (match_operand:SI 1 "register_operand") 4572 (match_operand 2 "")] 4573 "TARGET_32BIT" 4574{ 4575 emit_insn (gen_subsi3_compare (operands[0], const0_rtx, operands[1])); 4576 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); 4577 4578 DONE; 4579}) 4580 4581(define_expand "negvdi3" 4582 [(match_operand:DI 0 "register_operand") 4583 (match_operand:DI 1 "register_operand") 4584 (match_operand 2 "")] 4585 "TARGET_ARM" 4586{ 4587 emit_insn (gen_negdi2_compare (operands[0], operands[1])); 4588 arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[2]); 4589 4590 DONE; 4591}) 4592 4593 4594(define_insn_and_split "negdi2_compare" 4595 [(set (reg:CC CC_REGNUM) 4596 (compare:CC 4597 (const_int 0) 4598 (match_operand:DI 1 "register_operand" "0,r"))) 4599 (set (match_operand:DI 0 "register_operand" "=r,&r") 4600 (minus:DI (const_int 0) (match_dup 1)))] 4601 "TARGET_ARM" 4602 "#" 4603 "&& reload_completed" 4604 [(parallel [(set (reg:CC CC_REGNUM) 4605 (compare:CC (const_int 0) (match_dup 1))) 4606 (set (match_dup 0) (minus:SI (const_int 0) 4607 (match_dup 1)))]) 4608 (parallel [(set (reg:CC CC_REGNUM) 4609 (compare:CC (const_int 0) (match_dup 3))) 4610 (set (match_dup 2) 4611 (minus:SI 4612 (minus:SI (const_int 0) (match_dup 3)) 4613 (ltu:SI (reg:CC_C CC_REGNUM) 4614 (const_int 0))))])] 4615 { 4616 operands[2] = gen_highpart (SImode, operands[0]); 4617 operands[0] = gen_lowpart (SImode, operands[0]); 4618 operands[3] = gen_highpart (SImode, operands[1]); 4619 operands[1] = gen_lowpart (SImode, operands[1]); 4620 } 4621 [(set_attr "conds" "set") 4622 (set_attr "length" "8") 4623 (set_attr "type" "multiple")] 4624) 4625 4626(define_expand "negdi2" 4627 [(parallel 4628 [(set (match_operand:DI 0 "s_register_operand" "") 4629 (neg:DI (match_operand:DI 1 "s_register_operand" ""))) 4630 (clobber (reg:CC CC_REGNUM))])] 4631 "TARGET_EITHER" 4632 { 4633 if (TARGET_NEON) 4634 { 4635 emit_insn (gen_negdi2_neon (operands[0], operands[1])); 4636 DONE; 4637 } 4638 } 4639) 4640 4641;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). 4642;; The first alternative allows the common case of a *full* overlap. 4643(define_insn_and_split "*negdi2_insn" 4644 [(set (match_operand:DI 0 "s_register_operand" "=r,&r") 4645 (neg:DI (match_operand:DI 1 "s_register_operand" "0,r"))) 4646 (clobber (reg:CC CC_REGNUM))] 4647 "TARGET_32BIT" 4648 "#" ; rsbs %Q0, %Q1, #0; rsc %R0, %R1, #0 (ARM) 4649 ; negs %Q0, %Q1 ; sbc %R0, %R1, %R1, lsl #1 (Thumb-2) 4650 "&& reload_completed" 4651 [(parallel [(set (reg:CC CC_REGNUM) 4652 (compare:CC (const_int 0) (match_dup 1))) 4653 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) 4654 (set (match_dup 2) (minus:SI (minus:SI (const_int 0) (match_dup 3)) 4655 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 4656 { 4657 operands[2] = gen_highpart (SImode, operands[0]); 4658 operands[0] = gen_lowpart (SImode, operands[0]); 4659 operands[3] = gen_highpart (SImode, operands[1]); 4660 operands[1] = gen_lowpart (SImode, operands[1]); 4661 } 4662 [(set_attr "conds" "clob") 4663 (set_attr "length" "8") 4664 (set_attr "type" "multiple")] 4665) 4666 4667(define_insn "*negsi2_carryin_compare" 4668 [(set (reg:CC CC_REGNUM) 4669 (compare:CC (const_int 0) 4670 (match_operand:SI 1 "s_register_operand" "r"))) 4671 (set (match_operand:SI 0 "s_register_operand" "=r") 4672 (minus:SI (minus:SI (const_int 0) 4673 (match_dup 1)) 4674 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 4675 "TARGET_ARM" 4676 "rscs\\t%0, %1, #0" 4677 [(set_attr "conds" "set") 4678 (set_attr "type" "alus_imm")] 4679) 4680 4681(define_expand "negsi2" 4682 [(set (match_operand:SI 0 "s_register_operand" "") 4683 (neg:SI (match_operand:SI 1 "s_register_operand" "")))] 4684 "TARGET_EITHER" 4685 "" 4686) 4687 4688(define_insn "*arm_negsi2" 4689 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 4690 (neg:SI (match_operand:SI 1 "s_register_operand" "l,r")))] 4691 "TARGET_32BIT" 4692 "rsb%?\\t%0, %1, #0" 4693 [(set_attr "predicable" "yes") 4694 (set_attr "predicable_short_it" "yes,no") 4695 (set_attr "arch" "t2,*") 4696 (set_attr "length" "4") 4697 (set_attr "type" "alu_sreg")] 4698) 4699 4700(define_expand "negsf2" 4701 [(set (match_operand:SF 0 "s_register_operand" "") 4702 (neg:SF (match_operand:SF 1 "s_register_operand" "")))] 4703 "TARGET_32BIT && TARGET_HARD_FLOAT" 4704 "" 4705) 4706 4707(define_expand "negdf2" 4708 [(set (match_operand:DF 0 "s_register_operand" "") 4709 (neg:DF (match_operand:DF 1 "s_register_operand" "")))] 4710 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 4711 "") 4712 4713(define_insn_and_split "*zextendsidi_negsi" 4714 [(set (match_operand:DI 0 "s_register_operand" "=r") 4715 (zero_extend:DI (neg:SI (match_operand:SI 1 "s_register_operand" "r"))))] 4716 "TARGET_32BIT" 4717 "#" 4718 "" 4719 [(set (match_dup 2) 4720 (neg:SI (match_dup 1))) 4721 (set (match_dup 3) 4722 (const_int 0))] 4723 { 4724 operands[2] = gen_lowpart (SImode, operands[0]); 4725 operands[3] = gen_highpart (SImode, operands[0]); 4726 } 4727 [(set_attr "length" "8") 4728 (set_attr "type" "multiple")] 4729) 4730 4731;; Negate an extended 32-bit value. 4732(define_insn_and_split "*negdi_extendsidi" 4733 [(set (match_operand:DI 0 "s_register_operand" "=l,r") 4734 (neg:DI (sign_extend:DI 4735 (match_operand:SI 1 "s_register_operand" "l,r")))) 4736 (clobber (reg:CC CC_REGNUM))] 4737 "TARGET_32BIT" 4738 "#" 4739 "&& reload_completed" 4740 [(const_int 0)] 4741 { 4742 rtx low = gen_lowpart (SImode, operands[0]); 4743 rtx high = gen_highpart (SImode, operands[0]); 4744 4745 if (reg_overlap_mentioned_p (low, operands[1])) 4746 { 4747 /* Input overlaps the low word of the output. Use: 4748 asr Rhi, Rin, #31 4749 rsbs Rlo, Rin, #0 4750 rsc Rhi, Rhi, #0 (thumb2: sbc Rhi, Rhi, Rhi, lsl #1). */ 4751 rtx cc_reg = gen_rtx_REG (CC_Cmode, CC_REGNUM); 4752 4753 emit_insn (gen_rtx_SET (high, 4754 gen_rtx_ASHIFTRT (SImode, operands[1], 4755 GEN_INT (31)))); 4756 4757 emit_insn (gen_subsi3_compare (low, const0_rtx, operands[1])); 4758 if (TARGET_ARM) 4759 emit_insn (gen_rtx_SET (high, 4760 gen_rtx_MINUS (SImode, 4761 gen_rtx_MINUS (SImode, 4762 const0_rtx, 4763 high), 4764 gen_rtx_LTU (SImode, 4765 cc_reg, 4766 const0_rtx)))); 4767 else 4768 { 4769 rtx two_x = gen_rtx_ASHIFT (SImode, high, GEN_INT (1)); 4770 emit_insn (gen_rtx_SET (high, 4771 gen_rtx_MINUS (SImode, 4772 gen_rtx_MINUS (SImode, 4773 high, 4774 two_x), 4775 gen_rtx_LTU (SImode, 4776 cc_reg, 4777 const0_rtx)))); 4778 } 4779 } 4780 else 4781 { 4782 /* No overlap, or overlap on high word. Use: 4783 rsb Rlo, Rin, #0 4784 bic Rhi, Rlo, Rin 4785 asr Rhi, Rhi, #31 4786 Flags not needed for this sequence. */ 4787 emit_insn (gen_rtx_SET (low, gen_rtx_NEG (SImode, operands[1]))); 4788 emit_insn (gen_rtx_SET (high, 4789 gen_rtx_AND (SImode, 4790 gen_rtx_NOT (SImode, operands[1]), 4791 low))); 4792 emit_insn (gen_rtx_SET (high, 4793 gen_rtx_ASHIFTRT (SImode, high, 4794 GEN_INT (31)))); 4795 } 4796 DONE; 4797 } 4798 [(set_attr "length" "12") 4799 (set_attr "arch" "t2,*") 4800 (set_attr "type" "multiple")] 4801) 4802 4803(define_insn_and_split "*negdi_zero_extendsidi" 4804 [(set (match_operand:DI 0 "s_register_operand" "=r,&r") 4805 (neg:DI (zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r")))) 4806 (clobber (reg:CC CC_REGNUM))] 4807 "TARGET_32BIT" 4808 "#" ; "rsbs\\t%Q0, %1, #0\;sbc\\t%R0,%R0,%R0" 4809 ;; Don't care what register is input to sbc, 4810 ;; since we just need to propagate the carry. 4811 "&& reload_completed" 4812 [(parallel [(set (reg:CC CC_REGNUM) 4813 (compare:CC (const_int 0) (match_dup 1))) 4814 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1)))]) 4815 (set (match_dup 2) (minus:SI (minus:SI (match_dup 2) (match_dup 2)) 4816 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 4817 { 4818 operands[2] = gen_highpart (SImode, operands[0]); 4819 operands[0] = gen_lowpart (SImode, operands[0]); 4820 } 4821 [(set_attr "conds" "clob") 4822 (set_attr "length" "8") 4823 (set_attr "type" "multiple")] ;; length in thumb is 4 4824) 4825 4826;; abssi2 doesn't really clobber the condition codes if a different register 4827;; is being set. To keep things simple, assume during rtl manipulations that 4828;; it does, but tell the final scan operator the truth. Similarly for 4829;; (neg (abs...)) 4830 4831(define_expand "abssi2" 4832 [(parallel 4833 [(set (match_operand:SI 0 "s_register_operand" "") 4834 (abs:SI (match_operand:SI 1 "s_register_operand" ""))) 4835 (clobber (match_dup 2))])] 4836 "TARGET_EITHER" 4837 " 4838 if (TARGET_THUMB1) 4839 operands[2] = gen_rtx_SCRATCH (SImode); 4840 else 4841 operands[2] = gen_rtx_REG (CCmode, CC_REGNUM); 4842") 4843 4844(define_insn_and_split "*arm_abssi2" 4845 [(set (match_operand:SI 0 "s_register_operand" "=r,&r") 4846 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))) 4847 (clobber (reg:CC CC_REGNUM))] 4848 "TARGET_ARM" 4849 "#" 4850 "&& reload_completed" 4851 [(const_int 0)] 4852 { 4853 /* if (which_alternative == 0) */ 4854 if (REGNO(operands[0]) == REGNO(operands[1])) 4855 { 4856 /* Emit the pattern: 4857 cmp\\t%0, #0\;rsblt\\t%0, %0, #0 4858 [(set (reg:CC CC_REGNUM) 4859 (compare:CC (match_dup 0) (const_int 0))) 4860 (cond_exec (lt:CC (reg:CC CC_REGNUM) (const_int 0)) 4861 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 1))))] 4862 */ 4863 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM), 4864 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); 4865 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 4866 (gen_rtx_LT (SImode, 4867 gen_rtx_REG (CCmode, CC_REGNUM), 4868 const0_rtx)), 4869 (gen_rtx_SET (operands[0], 4870 (gen_rtx_MINUS (SImode, 4871 const0_rtx, 4872 operands[1])))))); 4873 DONE; 4874 } 4875 else 4876 { 4877 /* Emit the pattern: 4878 alt1: eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31 4879 [(set (match_dup 0) 4880 (xor:SI (match_dup 1) 4881 (ashiftrt:SI (match_dup 1) (const_int 31)))) 4882 (set (match_dup 0) 4883 (minus:SI (match_dup 0) 4884 (ashiftrt:SI (match_dup 1) (const_int 31))))] 4885 */ 4886 emit_insn (gen_rtx_SET (operands[0], 4887 gen_rtx_XOR (SImode, 4888 gen_rtx_ASHIFTRT (SImode, 4889 operands[1], 4890 GEN_INT (31)), 4891 operands[1]))); 4892 emit_insn (gen_rtx_SET (operands[0], 4893 gen_rtx_MINUS (SImode, 4894 operands[0], 4895 gen_rtx_ASHIFTRT (SImode, 4896 operands[1], 4897 GEN_INT (31))))); 4898 DONE; 4899 } 4900 } 4901 [(set_attr "conds" "clob,*") 4902 (set_attr "shift" "1") 4903 (set_attr "predicable" "no, yes") 4904 (set_attr "length" "8") 4905 (set_attr "type" "multiple")] 4906) 4907 4908(define_insn_and_split "*arm_neg_abssi2" 4909 [(set (match_operand:SI 0 "s_register_operand" "=r,&r") 4910 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))) 4911 (clobber (reg:CC CC_REGNUM))] 4912 "TARGET_ARM" 4913 "#" 4914 "&& reload_completed" 4915 [(const_int 0)] 4916 { 4917 /* if (which_alternative == 0) */ 4918 if (REGNO (operands[0]) == REGNO (operands[1])) 4919 { 4920 /* Emit the pattern: 4921 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0 4922 */ 4923 emit_insn (gen_rtx_SET (gen_rtx_REG (CCmode, CC_REGNUM), 4924 gen_rtx_COMPARE (CCmode, operands[0], const0_rtx))); 4925 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 4926 gen_rtx_GT (SImode, 4927 gen_rtx_REG (CCmode, CC_REGNUM), 4928 const0_rtx), 4929 gen_rtx_SET (operands[0], 4930 (gen_rtx_MINUS (SImode, 4931 const0_rtx, 4932 operands[1]))))); 4933 } 4934 else 4935 { 4936 /* Emit the pattern: 4937 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31 4938 */ 4939 emit_insn (gen_rtx_SET (operands[0], 4940 gen_rtx_XOR (SImode, 4941 gen_rtx_ASHIFTRT (SImode, 4942 operands[1], 4943 GEN_INT (31)), 4944 operands[1]))); 4945 emit_insn (gen_rtx_SET (operands[0], 4946 gen_rtx_MINUS (SImode, 4947 gen_rtx_ASHIFTRT (SImode, 4948 operands[1], 4949 GEN_INT (31)), 4950 operands[0]))); 4951 } 4952 DONE; 4953 } 4954 [(set_attr "conds" "clob,*") 4955 (set_attr "shift" "1") 4956 (set_attr "predicable" "no, yes") 4957 (set_attr "length" "8") 4958 (set_attr "type" "multiple")] 4959) 4960 4961(define_expand "abssf2" 4962 [(set (match_operand:SF 0 "s_register_operand" "") 4963 (abs:SF (match_operand:SF 1 "s_register_operand" "")))] 4964 "TARGET_32BIT && TARGET_HARD_FLOAT" 4965 "") 4966 4967(define_expand "absdf2" 4968 [(set (match_operand:DF 0 "s_register_operand" "") 4969 (abs:DF (match_operand:DF 1 "s_register_operand" "")))] 4970 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 4971 "") 4972 4973(define_expand "sqrtsf2" 4974 [(set (match_operand:SF 0 "s_register_operand" "") 4975 (sqrt:SF (match_operand:SF 1 "s_register_operand" "")))] 4976 "TARGET_32BIT && TARGET_HARD_FLOAT" 4977 "") 4978 4979(define_expand "sqrtdf2" 4980 [(set (match_operand:DF 0 "s_register_operand" "") 4981 (sqrt:DF (match_operand:DF 1 "s_register_operand" "")))] 4982 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 4983 "") 4984 4985(define_expand "one_cmpldi2" 4986 [(set (match_operand:DI 0 "s_register_operand" "") 4987 (not:DI (match_operand:DI 1 "s_register_operand" "")))] 4988 "TARGET_32BIT" 4989 " 4990 if (!TARGET_NEON && !TARGET_IWMMXT) 4991 { 4992 rtx low = simplify_gen_unary (NOT, SImode, 4993 gen_lowpart (SImode, operands[1]), 4994 SImode); 4995 rtx high = simplify_gen_unary (NOT, SImode, 4996 gen_highpart_mode (SImode, DImode, 4997 operands[1]), 4998 SImode); 4999 5000 emit_insn (gen_rtx_SET (gen_lowpart (SImode, operands[0]), low)); 5001 emit_insn (gen_rtx_SET (gen_highpart (SImode, operands[0]), high)); 5002 5003 DONE; 5004 } 5005 /* Otherwise expand pattern as above. */ 5006 " 5007) 5008 5009(define_insn_and_split "*one_cmpldi2_insn" 5010 [(set (match_operand:DI 0 "s_register_operand" "=w,&r,&r,?w") 5011 (not:DI (match_operand:DI 1 "s_register_operand" " w, 0, r, w")))] 5012 "TARGET_32BIT" 5013 "@ 5014 vmvn\t%P0, %P1 5015 # 5016 # 5017 vmvn\t%P0, %P1" 5018 "TARGET_32BIT && reload_completed 5019 && arm_general_register_operand (operands[0], DImode)" 5020 [(set (match_dup 0) (not:SI (match_dup 1))) 5021 (set (match_dup 2) (not:SI (match_dup 3)))] 5022 " 5023 { 5024 operands[2] = gen_highpart (SImode, operands[0]); 5025 operands[0] = gen_lowpart (SImode, operands[0]); 5026 operands[3] = gen_highpart (SImode, operands[1]); 5027 operands[1] = gen_lowpart (SImode, operands[1]); 5028 }" 5029 [(set_attr "length" "*,8,8,*") 5030 (set_attr "predicable" "no,yes,yes,no") 5031 (set_attr "type" "neon_move,multiple,multiple,neon_move") 5032 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits")] 5033) 5034 5035(define_expand "one_cmplsi2" 5036 [(set (match_operand:SI 0 "s_register_operand" "") 5037 (not:SI (match_operand:SI 1 "s_register_operand" "")))] 5038 "TARGET_EITHER" 5039 "" 5040) 5041 5042(define_insn "*arm_one_cmplsi2" 5043 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 5044 (not:SI (match_operand:SI 1 "s_register_operand" "l,r")))] 5045 "TARGET_32BIT" 5046 "mvn%?\\t%0, %1" 5047 [(set_attr "predicable" "yes") 5048 (set_attr "predicable_short_it" "yes,no") 5049 (set_attr "arch" "t2,*") 5050 (set_attr "length" "4") 5051 (set_attr "type" "mvn_reg")] 5052) 5053 5054(define_insn "*notsi_compare0" 5055 [(set (reg:CC_NOOV CC_REGNUM) 5056 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) 5057 (const_int 0))) 5058 (set (match_operand:SI 0 "s_register_operand" "=r") 5059 (not:SI (match_dup 1)))] 5060 "TARGET_32BIT" 5061 "mvns%?\\t%0, %1" 5062 [(set_attr "conds" "set") 5063 (set_attr "type" "mvn_reg")] 5064) 5065 5066(define_insn "*notsi_compare0_scratch" 5067 [(set (reg:CC_NOOV CC_REGNUM) 5068 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) 5069 (const_int 0))) 5070 (clobber (match_scratch:SI 0 "=r"))] 5071 "TARGET_32BIT" 5072 "mvns%?\\t%0, %1" 5073 [(set_attr "conds" "set") 5074 (set_attr "type" "mvn_reg")] 5075) 5076 5077;; Fixed <--> Floating conversion insns 5078 5079(define_expand "floatsihf2" 5080 [(set (match_operand:HF 0 "general_operand" "") 5081 (float:HF (match_operand:SI 1 "general_operand" "")))] 5082 "TARGET_EITHER" 5083 " 5084 { 5085 rtx op1 = gen_reg_rtx (SFmode); 5086 expand_float (op1, operands[1], 0); 5087 op1 = convert_to_mode (HFmode, op1, 0); 5088 emit_move_insn (operands[0], op1); 5089 DONE; 5090 }" 5091) 5092 5093(define_expand "floatdihf2" 5094 [(set (match_operand:HF 0 "general_operand" "") 5095 (float:HF (match_operand:DI 1 "general_operand" "")))] 5096 "TARGET_EITHER" 5097 " 5098 { 5099 rtx op1 = gen_reg_rtx (SFmode); 5100 expand_float (op1, operands[1], 0); 5101 op1 = convert_to_mode (HFmode, op1, 0); 5102 emit_move_insn (operands[0], op1); 5103 DONE; 5104 }" 5105) 5106 5107(define_expand "floatsisf2" 5108 [(set (match_operand:SF 0 "s_register_operand" "") 5109 (float:SF (match_operand:SI 1 "s_register_operand" "")))] 5110 "TARGET_32BIT && TARGET_HARD_FLOAT" 5111 " 5112") 5113 5114(define_expand "floatsidf2" 5115 [(set (match_operand:DF 0 "s_register_operand" "") 5116 (float:DF (match_operand:SI 1 "s_register_operand" "")))] 5117 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5118 " 5119") 5120 5121(define_expand "fix_trunchfsi2" 5122 [(set (match_operand:SI 0 "general_operand" "") 5123 (fix:SI (fix:HF (match_operand:HF 1 "general_operand" ""))))] 5124 "TARGET_EITHER" 5125 " 5126 { 5127 rtx op1 = convert_to_mode (SFmode, operands[1], 0); 5128 expand_fix (operands[0], op1, 0); 5129 DONE; 5130 }" 5131) 5132 5133(define_expand "fix_trunchfdi2" 5134 [(set (match_operand:DI 0 "general_operand" "") 5135 (fix:DI (fix:HF (match_operand:HF 1 "general_operand" ""))))] 5136 "TARGET_EITHER" 5137 " 5138 { 5139 rtx op1 = convert_to_mode (SFmode, operands[1], 0); 5140 expand_fix (operands[0], op1, 0); 5141 DONE; 5142 }" 5143) 5144 5145(define_expand "fix_truncsfsi2" 5146 [(set (match_operand:SI 0 "s_register_operand" "") 5147 (fix:SI (fix:SF (match_operand:SF 1 "s_register_operand" ""))))] 5148 "TARGET_32BIT && TARGET_HARD_FLOAT" 5149 " 5150") 5151 5152(define_expand "fix_truncdfsi2" 5153 [(set (match_operand:SI 0 "s_register_operand" "") 5154 (fix:SI (fix:DF (match_operand:DF 1 "s_register_operand" ""))))] 5155 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5156 " 5157") 5158 5159;; Truncation insns 5160 5161(define_expand "truncdfsf2" 5162 [(set (match_operand:SF 0 "s_register_operand" "") 5163 (float_truncate:SF 5164 (match_operand:DF 1 "s_register_operand" "")))] 5165 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5166 "" 5167) 5168 5169;; DFmode to HFmode conversions on targets without a single-step hardware 5170;; instruction for it would have to go through SFmode. This is dangerous 5171;; as it introduces double rounding. 5172;; 5173;; Disable this pattern unless we are in an unsafe math mode, or we have 5174;; a single-step instruction. 5175 5176(define_expand "truncdfhf2" 5177 [(set (match_operand:HF 0 "s_register_operand" "") 5178 (float_truncate:HF 5179 (match_operand:DF 1 "s_register_operand" "")))] 5180 "(TARGET_EITHER && flag_unsafe_math_optimizations) 5181 || (TARGET_32BIT && TARGET_FP16_TO_DOUBLE)" 5182{ 5183 /* We don't have a direct instruction for this, so we must be in 5184 an unsafe math mode, and going via SFmode. */ 5185 5186 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE)) 5187 { 5188 rtx op1; 5189 op1 = convert_to_mode (SFmode, operands[1], 0); 5190 op1 = convert_to_mode (HFmode, op1, 0); 5191 emit_move_insn (operands[0], op1); 5192 DONE; 5193 } 5194 /* Otherwise, we will pick this up as a single instruction with 5195 no intermediary rounding. */ 5196} 5197) 5198 5199;; Zero and sign extension instructions. 5200 5201(define_insn "zero_extend<mode>di2" 5202 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,w") 5203 (zero_extend:DI (match_operand:QHSI 1 "<qhs_zextenddi_op>" 5204 "<qhs_zextenddi_cstr>")))] 5205 "TARGET_32BIT <qhs_zextenddi_cond>" 5206 "#" 5207 [(set_attr "length" "8,4,8,8") 5208 (set_attr "arch" "neon_for_64bits,*,*,avoid_neon_for_64bits") 5209 (set_attr "ce_count" "2") 5210 (set_attr "predicable" "yes") 5211 (set_attr "type" "multiple,mov_reg,multiple,multiple")] 5212) 5213 5214(define_insn "extend<mode>di2" 5215 [(set (match_operand:DI 0 "s_register_operand" "=w,r,?r,?r,w") 5216 (sign_extend:DI (match_operand:QHSI 1 "<qhs_extenddi_op>" 5217 "<qhs_extenddi_cstr>")))] 5218 "TARGET_32BIT <qhs_sextenddi_cond>" 5219 "#" 5220 [(set_attr "length" "8,4,8,8,8") 5221 (set_attr "ce_count" "2") 5222 (set_attr "shift" "1") 5223 (set_attr "predicable" "yes") 5224 (set_attr "arch" "neon_for_64bits,*,a,t,avoid_neon_for_64bits") 5225 (set_attr "type" "multiple,mov_reg,multiple,multiple,multiple")] 5226) 5227 5228;; Splits for all extensions to DImode 5229(define_split 5230 [(set (match_operand:DI 0 "s_register_operand" "") 5231 (zero_extend:DI (match_operand 1 "nonimmediate_operand" "")))] 5232 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))" 5233 [(set (match_dup 0) (match_dup 1))] 5234{ 5235 rtx lo_part = gen_lowpart (SImode, operands[0]); 5236 machine_mode src_mode = GET_MODE (operands[1]); 5237 5238 if (REG_P (operands[0]) 5239 && !reg_overlap_mentioned_p (operands[0], operands[1])) 5240 emit_clobber (operands[0]); 5241 if (!REG_P (lo_part) || src_mode != SImode 5242 || !rtx_equal_p (lo_part, operands[1])) 5243 { 5244 if (src_mode == SImode) 5245 emit_move_insn (lo_part, operands[1]); 5246 else 5247 emit_insn (gen_rtx_SET (lo_part, 5248 gen_rtx_ZERO_EXTEND (SImode, operands[1]))); 5249 operands[1] = lo_part; 5250 } 5251 operands[0] = gen_highpart (SImode, operands[0]); 5252 operands[1] = const0_rtx; 5253}) 5254 5255(define_split 5256 [(set (match_operand:DI 0 "s_register_operand" "") 5257 (sign_extend:DI (match_operand 1 "nonimmediate_operand" "")))] 5258 "TARGET_32BIT && reload_completed && !IS_VFP_REGNUM (REGNO (operands[0]))" 5259 [(set (match_dup 0) (ashiftrt:SI (match_dup 1) (const_int 31)))] 5260{ 5261 rtx lo_part = gen_lowpart (SImode, operands[0]); 5262 machine_mode src_mode = GET_MODE (operands[1]); 5263 5264 if (REG_P (operands[0]) 5265 && !reg_overlap_mentioned_p (operands[0], operands[1])) 5266 emit_clobber (operands[0]); 5267 5268 if (!REG_P (lo_part) || src_mode != SImode 5269 || !rtx_equal_p (lo_part, operands[1])) 5270 { 5271 if (src_mode == SImode) 5272 emit_move_insn (lo_part, operands[1]); 5273 else 5274 emit_insn (gen_rtx_SET (lo_part, 5275 gen_rtx_SIGN_EXTEND (SImode, operands[1]))); 5276 operands[1] = lo_part; 5277 } 5278 operands[0] = gen_highpart (SImode, operands[0]); 5279}) 5280 5281(define_expand "zero_extendhisi2" 5282 [(set (match_operand:SI 0 "s_register_operand" "") 5283 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 5284 "TARGET_EITHER" 5285{ 5286 if (TARGET_ARM && !arm_arch4 && MEM_P (operands[1])) 5287 { 5288 emit_insn (gen_movhi_bytes (operands[0], operands[1])); 5289 DONE; 5290 } 5291 if (!arm_arch6 && !MEM_P (operands[1])) 5292 { 5293 rtx t = gen_lowpart (SImode, operands[1]); 5294 rtx tmp = gen_reg_rtx (SImode); 5295 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16))); 5296 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (16))); 5297 DONE; 5298 } 5299}) 5300 5301(define_split 5302 [(set (match_operand:SI 0 "s_register_operand" "") 5303 (zero_extend:SI (match_operand:HI 1 "s_register_operand" "")))] 5304 "!TARGET_THUMB2 && !arm_arch6" 5305 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 5306 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 16)))] 5307{ 5308 operands[2] = gen_lowpart (SImode, operands[1]); 5309}) 5310 5311(define_insn "*arm_zero_extendhisi2" 5312 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5313 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,m")))] 5314 "TARGET_ARM && arm_arch4 && !arm_arch6" 5315 "@ 5316 # 5317 ldrh%?\\t%0, %1" 5318 [(set_attr "type" "alu_shift_reg,load_byte") 5319 (set_attr "predicable" "yes")] 5320) 5321 5322(define_insn "*arm_zero_extendhisi2_v6" 5323 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5324 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))] 5325 "TARGET_ARM && arm_arch6" 5326 "@ 5327 uxth%?\\t%0, %1 5328 ldrh%?\\t%0, %1" 5329 [(set_attr "predicable" "yes") 5330 (set_attr "type" "extend,load_byte")] 5331) 5332 5333(define_insn "*arm_zero_extendhisi2addsi" 5334 [(set (match_operand:SI 0 "s_register_operand" "=r") 5335 (plus:SI (zero_extend:SI (match_operand:HI 1 "s_register_operand" "r")) 5336 (match_operand:SI 2 "s_register_operand" "r")))] 5337 "TARGET_INT_SIMD" 5338 "uxtah%?\\t%0, %2, %1" 5339 [(set_attr "type" "alu_shift_reg") 5340 (set_attr "predicable" "yes")] 5341) 5342 5343(define_expand "zero_extendqisi2" 5344 [(set (match_operand:SI 0 "s_register_operand" "") 5345 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 5346 "TARGET_EITHER" 5347{ 5348 if (TARGET_ARM && !arm_arch6 && !MEM_P (operands[1])) 5349 { 5350 emit_insn (gen_andsi3 (operands[0], 5351 gen_lowpart (SImode, operands[1]), 5352 GEN_INT (255))); 5353 DONE; 5354 } 5355 if (!arm_arch6 && !MEM_P (operands[1])) 5356 { 5357 rtx t = gen_lowpart (SImode, operands[1]); 5358 rtx tmp = gen_reg_rtx (SImode); 5359 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24))); 5360 emit_insn (gen_lshrsi3 (operands[0], tmp, GEN_INT (24))); 5361 DONE; 5362 } 5363}) 5364 5365(define_split 5366 [(set (match_operand:SI 0 "s_register_operand" "") 5367 (zero_extend:SI (match_operand:QI 1 "s_register_operand" "")))] 5368 "!arm_arch6" 5369 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24))) 5370 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 24)))] 5371{ 5372 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0); 5373 if (TARGET_ARM) 5374 { 5375 emit_insn (gen_andsi3 (operands[0], operands[2], GEN_INT (255))); 5376 DONE; 5377 } 5378}) 5379 5380(define_insn "*arm_zero_extendqisi2" 5381 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5382 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 5383 "TARGET_ARM && !arm_arch6" 5384 "@ 5385 # 5386 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2" 5387 [(set_attr "length" "8,4") 5388 (set_attr "type" "alu_shift_reg,load_byte") 5389 (set_attr "predicable" "yes")] 5390) 5391 5392(define_insn "*arm_zero_extendqisi2_v6" 5393 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5394 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "r,Uh")))] 5395 "TARGET_ARM && arm_arch6" 5396 "@ 5397 uxtb%?\\t%0, %1 5398 ldrb%?\\t%0, %1\\t%@ zero_extendqisi2" 5399 [(set_attr "type" "extend,load_byte") 5400 (set_attr "predicable" "yes")] 5401) 5402 5403(define_insn "*arm_zero_extendqisi2addsi" 5404 [(set (match_operand:SI 0 "s_register_operand" "=r") 5405 (plus:SI (zero_extend:SI (match_operand:QI 1 "s_register_operand" "r")) 5406 (match_operand:SI 2 "s_register_operand" "r")))] 5407 "TARGET_INT_SIMD" 5408 "uxtab%?\\t%0, %2, %1" 5409 [(set_attr "predicable" "yes") 5410 (set_attr "type" "alu_shift_reg")] 5411) 5412 5413(define_split 5414 [(set (match_operand:SI 0 "s_register_operand" "") 5415 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0))) 5416 (clobber (match_operand:SI 2 "s_register_operand" ""))] 5417 "TARGET_32BIT && (!MEM_P (operands[1])) && ! BYTES_BIG_ENDIAN" 5418 [(set (match_dup 2) (match_dup 1)) 5419 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))] 5420 "" 5421) 5422 5423(define_split 5424 [(set (match_operand:SI 0 "s_register_operand" "") 5425 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 3))) 5426 (clobber (match_operand:SI 2 "s_register_operand" ""))] 5427 "TARGET_32BIT && (!MEM_P (operands[1])) && BYTES_BIG_ENDIAN" 5428 [(set (match_dup 2) (match_dup 1)) 5429 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))] 5430 "" 5431) 5432 5433 5434(define_split 5435 [(set (match_operand:SI 0 "s_register_operand" "") 5436 (IOR_XOR:SI (and:SI (ashift:SI 5437 (match_operand:SI 1 "s_register_operand" "") 5438 (match_operand:SI 2 "const_int_operand" "")) 5439 (match_operand:SI 3 "const_int_operand" "")) 5440 (zero_extend:SI 5441 (match_operator 5 "subreg_lowpart_operator" 5442 [(match_operand:SI 4 "s_register_operand" "")]))))] 5443 "TARGET_32BIT 5444 && (UINTVAL (operands[3]) 5445 == (GET_MODE_MASK (GET_MODE (operands[5])) 5446 & (GET_MODE_MASK (GET_MODE (operands[5])) 5447 << (INTVAL (operands[2])))))" 5448 [(set (match_dup 0) (IOR_XOR:SI (ashift:SI (match_dup 1) (match_dup 2)) 5449 (match_dup 4))) 5450 (set (match_dup 0) (zero_extend:SI (match_dup 5)))] 5451 "operands[5] = gen_lowpart (GET_MODE (operands[5]), operands[0]);" 5452) 5453 5454(define_insn "*compareqi_eq0" 5455 [(set (reg:CC_Z CC_REGNUM) 5456 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r") 5457 (const_int 0)))] 5458 "TARGET_32BIT" 5459 "tst%?\\t%0, #255" 5460 [(set_attr "conds" "set") 5461 (set_attr "predicable" "yes") 5462 (set_attr "type" "logic_imm")] 5463) 5464 5465(define_expand "extendhisi2" 5466 [(set (match_operand:SI 0 "s_register_operand" "") 5467 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))] 5468 "TARGET_EITHER" 5469{ 5470 if (TARGET_THUMB1) 5471 { 5472 emit_insn (gen_thumb1_extendhisi2 (operands[0], operands[1])); 5473 DONE; 5474 } 5475 if (MEM_P (operands[1]) && TARGET_ARM && !arm_arch4) 5476 { 5477 emit_insn (gen_extendhisi2_mem (operands[0], operands[1])); 5478 DONE; 5479 } 5480 5481 if (!arm_arch6 && !MEM_P (operands[1])) 5482 { 5483 rtx t = gen_lowpart (SImode, operands[1]); 5484 rtx tmp = gen_reg_rtx (SImode); 5485 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (16))); 5486 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (16))); 5487 DONE; 5488 } 5489}) 5490 5491(define_split 5492 [(parallel 5493 [(set (match_operand:SI 0 "register_operand" "") 5494 (sign_extend:SI (match_operand:HI 1 "register_operand" ""))) 5495 (clobber (match_scratch:SI 2 ""))])] 5496 "!arm_arch6" 5497 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 5498 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))] 5499{ 5500 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 5501}) 5502 5503;; This pattern will only be used when ldsh is not available 5504(define_expand "extendhisi2_mem" 5505 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" ""))) 5506 (set (match_dup 3) 5507 (zero_extend:SI (match_dup 7))) 5508 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24))) 5509 (set (match_operand:SI 0 "" "") 5510 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))] 5511 "TARGET_ARM" 5512 " 5513 { 5514 rtx mem1, mem2; 5515 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 5516 5517 mem1 = change_address (operands[1], QImode, addr); 5518 mem2 = change_address (operands[1], QImode, 5519 plus_constant (Pmode, addr, 1)); 5520 operands[0] = gen_lowpart (SImode, operands[0]); 5521 operands[1] = mem1; 5522 operands[2] = gen_reg_rtx (SImode); 5523 operands[3] = gen_reg_rtx (SImode); 5524 operands[6] = gen_reg_rtx (SImode); 5525 operands[7] = mem2; 5526 5527 if (BYTES_BIG_ENDIAN) 5528 { 5529 operands[4] = operands[2]; 5530 operands[5] = operands[3]; 5531 } 5532 else 5533 { 5534 operands[4] = operands[3]; 5535 operands[5] = operands[2]; 5536 } 5537 }" 5538) 5539 5540(define_split 5541 [(set (match_operand:SI 0 "register_operand" "") 5542 (sign_extend:SI (match_operand:HI 1 "register_operand" "")))] 5543 "!arm_arch6" 5544 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 16))) 5545 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 16)))] 5546{ 5547 operands[2] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 5548}) 5549 5550(define_insn "*arm_extendhisi2" 5551 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5552 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))] 5553 "TARGET_ARM && arm_arch4 && !arm_arch6" 5554 "@ 5555 # 5556 ldrsh%?\\t%0, %1" 5557 [(set_attr "length" "8,4") 5558 (set_attr "type" "alu_shift_reg,load_byte") 5559 (set_attr "predicable" "yes")] 5560) 5561 5562;; ??? Check Thumb-2 pool range 5563(define_insn "*arm_extendhisi2_v6" 5564 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5565 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "r,Uh")))] 5566 "TARGET_32BIT && arm_arch6" 5567 "@ 5568 sxth%?\\t%0, %1 5569 ldrsh%?\\t%0, %1" 5570 [(set_attr "type" "extend,load_byte") 5571 (set_attr "predicable" "yes")] 5572) 5573 5574(define_insn "*arm_extendhisi2addsi" 5575 [(set (match_operand:SI 0 "s_register_operand" "=r") 5576 (plus:SI (sign_extend:SI (match_operand:HI 1 "s_register_operand" "r")) 5577 (match_operand:SI 2 "s_register_operand" "r")))] 5578 "TARGET_INT_SIMD" 5579 "sxtah%?\\t%0, %2, %1" 5580 [(set_attr "type" "alu_shift_reg")] 5581) 5582 5583(define_expand "extendqihi2" 5584 [(set (match_dup 2) 5585 (ashift:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "") 5586 (const_int 24))) 5587 (set (match_operand:HI 0 "s_register_operand" "") 5588 (ashiftrt:SI (match_dup 2) 5589 (const_int 24)))] 5590 "TARGET_ARM" 5591 " 5592 { 5593 if (arm_arch4 && MEM_P (operands[1])) 5594 { 5595 emit_insn (gen_rtx_SET (operands[0], 5596 gen_rtx_SIGN_EXTEND (HImode, operands[1]))); 5597 DONE; 5598 } 5599 if (!s_register_operand (operands[1], QImode)) 5600 operands[1] = copy_to_mode_reg (QImode, operands[1]); 5601 operands[0] = gen_lowpart (SImode, operands[0]); 5602 operands[1] = gen_lowpart (SImode, operands[1]); 5603 operands[2] = gen_reg_rtx (SImode); 5604 }" 5605) 5606 5607(define_insn "*arm_extendqihi_insn" 5608 [(set (match_operand:HI 0 "s_register_operand" "=r") 5609 (sign_extend:HI (match_operand:QI 1 "arm_extendqisi_mem_op" "Uq")))] 5610 "TARGET_ARM && arm_arch4" 5611 "ldrsb%?\\t%0, %1" 5612 [(set_attr "type" "load_byte") 5613 (set_attr "predicable" "yes")] 5614) 5615 5616(define_expand "extendqisi2" 5617 [(set (match_operand:SI 0 "s_register_operand" "") 5618 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "")))] 5619 "TARGET_EITHER" 5620{ 5621 if (!arm_arch4 && MEM_P (operands[1])) 5622 operands[1] = copy_to_mode_reg (QImode, operands[1]); 5623 5624 if (!arm_arch6 && !MEM_P (operands[1])) 5625 { 5626 rtx t = gen_lowpart (SImode, operands[1]); 5627 rtx tmp = gen_reg_rtx (SImode); 5628 emit_insn (gen_ashlsi3 (tmp, t, GEN_INT (24))); 5629 emit_insn (gen_ashrsi3 (operands[0], tmp, GEN_INT (24))); 5630 DONE; 5631 } 5632}) 5633 5634(define_split 5635 [(set (match_operand:SI 0 "register_operand" "") 5636 (sign_extend:SI (match_operand:QI 1 "register_operand" "")))] 5637 "!arm_arch6" 5638 [(set (match_dup 0) (ashift:SI (match_dup 2) (const_int 24))) 5639 (set (match_dup 0) (ashiftrt:SI (match_dup 0) (const_int 24)))] 5640{ 5641 operands[2] = simplify_gen_subreg (SImode, operands[1], QImode, 0); 5642}) 5643 5644(define_insn "*arm_extendqisi" 5645 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5646 (sign_extend:SI (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))] 5647 "TARGET_ARM && arm_arch4 && !arm_arch6" 5648 "@ 5649 # 5650 ldrsb%?\\t%0, %1" 5651 [(set_attr "length" "8,4") 5652 (set_attr "type" "alu_shift_reg,load_byte") 5653 (set_attr "predicable" "yes")] 5654) 5655 5656(define_insn "*arm_extendqisi_v6" 5657 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 5658 (sign_extend:SI 5659 (match_operand:QI 1 "arm_reg_or_extendqisi_mem_op" "r,Uq")))] 5660 "TARGET_ARM && arm_arch6" 5661 "@ 5662 sxtb%?\\t%0, %1 5663 ldrsb%?\\t%0, %1" 5664 [(set_attr "type" "extend,load_byte") 5665 (set_attr "predicable" "yes")] 5666) 5667 5668(define_insn "*arm_extendqisi2addsi" 5669 [(set (match_operand:SI 0 "s_register_operand" "=r") 5670 (plus:SI (sign_extend:SI (match_operand:QI 1 "s_register_operand" "r")) 5671 (match_operand:SI 2 "s_register_operand" "r")))] 5672 "TARGET_INT_SIMD" 5673 "sxtab%?\\t%0, %2, %1" 5674 [(set_attr "type" "alu_shift_reg") 5675 (set_attr "predicable" "yes")] 5676) 5677 5678(define_expand "extendsfdf2" 5679 [(set (match_operand:DF 0 "s_register_operand" "") 5680 (float_extend:DF (match_operand:SF 1 "s_register_operand" "")))] 5681 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 5682 "" 5683) 5684 5685;; HFmode -> DFmode conversions where we don't have an instruction for it 5686;; must go through SFmode. 5687;; 5688;; This is always safe for an extend. 5689 5690(define_expand "extendhfdf2" 5691 [(set (match_operand:DF 0 "s_register_operand" "") 5692 (float_extend:DF (match_operand:HF 1 "s_register_operand" "")))] 5693 "TARGET_EITHER" 5694{ 5695 /* We don't have a direct instruction for this, so go via SFmode. */ 5696 if (!(TARGET_32BIT && TARGET_FP16_TO_DOUBLE)) 5697 { 5698 rtx op1; 5699 op1 = convert_to_mode (SFmode, operands[1], 0); 5700 op1 = convert_to_mode (DFmode, op1, 0); 5701 emit_insn (gen_movdf (operands[0], op1)); 5702 DONE; 5703 } 5704 /* Otherwise, we're done producing RTL and will pick up the correct 5705 pattern to do this with one rounding-step in a single instruction. */ 5706} 5707) 5708 5709;; Move insns (including loads and stores) 5710 5711;; XXX Just some ideas about movti. 5712;; I don't think these are a good idea on the arm, there just aren't enough 5713;; registers 5714;;(define_expand "loadti" 5715;; [(set (match_operand:TI 0 "s_register_operand" "") 5716;; (mem:TI (match_operand:SI 1 "address_operand" "")))] 5717;; "" "") 5718 5719;;(define_expand "storeti" 5720;; [(set (mem:TI (match_operand:TI 0 "address_operand" "")) 5721;; (match_operand:TI 1 "s_register_operand" ""))] 5722;; "" "") 5723 5724;;(define_expand "movti" 5725;; [(set (match_operand:TI 0 "general_operand" "") 5726;; (match_operand:TI 1 "general_operand" ""))] 5727;; "" 5728;; " 5729;;{ 5730;; rtx insn; 5731;; 5732;; if (MEM_P (operands[0]) && MEM_P (operands[1])) 5733;; operands[1] = copy_to_reg (operands[1]); 5734;; if (MEM_P (operands[0])) 5735;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]); 5736;; else if (MEM_P (operands[1])) 5737;; insn = gen_loadti (operands[0], XEXP (operands[1], 0)); 5738;; else 5739;; FAIL; 5740;; 5741;; emit_insn (insn); 5742;; DONE; 5743;;}") 5744 5745;; Recognize garbage generated above. 5746 5747;;(define_insn "" 5748;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m") 5749;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))] 5750;; "" 5751;; "* 5752;; { 5753;; register mem = (which_alternative < 3); 5754;; register const char *template; 5755;; 5756;; operands[mem] = XEXP (operands[mem], 0); 5757;; switch (which_alternative) 5758;; { 5759;; case 0: template = \"ldmdb\\t%1!, %M0\"; break; 5760;; case 1: template = \"ldmia\\t%1!, %M0\"; break; 5761;; case 2: template = \"ldmia\\t%1, %M0\"; break; 5762;; case 3: template = \"stmdb\\t%0!, %M1\"; break; 5763;; case 4: template = \"stmia\\t%0!, %M1\"; break; 5764;; case 5: template = \"stmia\\t%0, %M1\"; break; 5765;; } 5766;; output_asm_insn (template, operands); 5767;; return \"\"; 5768;; }") 5769 5770(define_expand "movdi" 5771 [(set (match_operand:DI 0 "general_operand" "") 5772 (match_operand:DI 1 "general_operand" ""))] 5773 "TARGET_EITHER" 5774 " 5775 if (can_create_pseudo_p ()) 5776 { 5777 if (!REG_P (operands[0])) 5778 operands[1] = force_reg (DImode, operands[1]); 5779 } 5780 if (REG_P (operands[0]) && REGNO (operands[0]) <= LAST_ARM_REGNUM 5781 && !targetm.hard_regno_mode_ok (REGNO (operands[0]), DImode)) 5782 { 5783 /* Avoid LDRD's into an odd-numbered register pair in ARM state 5784 when expanding function calls. */ 5785 gcc_assert (can_create_pseudo_p ()); 5786 if (MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1])) 5787 { 5788 /* Perform load into legal reg pair first, then move. */ 5789 rtx reg = gen_reg_rtx (DImode); 5790 emit_insn (gen_movdi (reg, operands[1])); 5791 operands[1] = reg; 5792 } 5793 emit_move_insn (gen_lowpart (SImode, operands[0]), 5794 gen_lowpart (SImode, operands[1])); 5795 emit_move_insn (gen_highpart (SImode, operands[0]), 5796 gen_highpart (SImode, operands[1])); 5797 DONE; 5798 } 5799 else if (REG_P (operands[1]) && REGNO (operands[1]) <= LAST_ARM_REGNUM 5800 && !targetm.hard_regno_mode_ok (REGNO (operands[1]), DImode)) 5801 { 5802 /* Avoid STRD's from an odd-numbered register pair in ARM state 5803 when expanding function prologue. */ 5804 gcc_assert (can_create_pseudo_p ()); 5805 rtx split_dest = (MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) 5806 ? gen_reg_rtx (DImode) 5807 : operands[0]; 5808 emit_move_insn (gen_lowpart (SImode, split_dest), 5809 gen_lowpart (SImode, operands[1])); 5810 emit_move_insn (gen_highpart (SImode, split_dest), 5811 gen_highpart (SImode, operands[1])); 5812 if (split_dest != operands[0]) 5813 emit_insn (gen_movdi (operands[0], split_dest)); 5814 DONE; 5815 } 5816 " 5817) 5818 5819(define_insn "*arm_movdi" 5820 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, r, q, m") 5821 (match_operand:DI 1 "di_operand" "rDa,Db,Dc,mi,q"))] 5822 "TARGET_32BIT 5823 && !(TARGET_HARD_FLOAT) 5824 && !TARGET_IWMMXT 5825 && ( register_operand (operands[0], DImode) 5826 || register_operand (operands[1], DImode))" 5827 "* 5828 switch (which_alternative) 5829 { 5830 case 0: 5831 case 1: 5832 case 2: 5833 return \"#\"; 5834 default: 5835 return output_move_double (operands, true, NULL); 5836 } 5837 " 5838 [(set_attr "length" "8,12,16,8,8") 5839 (set_attr "type" "multiple,multiple,multiple,load_8,store_8") 5840 (set_attr "arm_pool_range" "*,*,*,1020,*") 5841 (set_attr "arm_neg_pool_range" "*,*,*,1004,*") 5842 (set_attr "thumb2_pool_range" "*,*,*,4094,*") 5843 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")] 5844) 5845 5846(define_split 5847 [(set (match_operand:ANY64 0 "arm_general_register_operand" "") 5848 (match_operand:ANY64 1 "immediate_operand" ""))] 5849 "TARGET_32BIT 5850 && reload_completed 5851 && (arm_disable_literal_pool 5852 || (arm_const_double_inline_cost (operands[1]) 5853 <= arm_max_const_double_inline_cost ()))" 5854 [(const_int 0)] 5855 " 5856 arm_split_constant (SET, SImode, curr_insn, 5857 INTVAL (gen_lowpart (SImode, operands[1])), 5858 gen_lowpart (SImode, operands[0]), NULL_RTX, 0); 5859 arm_split_constant (SET, SImode, curr_insn, 5860 INTVAL (gen_highpart_mode (SImode, 5861 GET_MODE (operands[0]), 5862 operands[1])), 5863 gen_highpart (SImode, operands[0]), NULL_RTX, 0); 5864 DONE; 5865 " 5866) 5867 5868; If optimizing for size, or if we have load delay slots, then 5869; we want to split the constant into two separate operations. 5870; In both cases this may split a trivial part into a single data op 5871; leaving a single complex constant to load. We can also get longer 5872; offsets in a LDR which means we get better chances of sharing the pool 5873; entries. Finally, we can normally do a better job of scheduling 5874; LDR instructions than we can with LDM. 5875; This pattern will only match if the one above did not. 5876(define_split 5877 [(set (match_operand:ANY64 0 "arm_general_register_operand" "") 5878 (match_operand:ANY64 1 "const_double_operand" ""))] 5879 "TARGET_ARM && reload_completed 5880 && arm_const_double_by_parts (operands[1])" 5881 [(set (match_dup 0) (match_dup 1)) 5882 (set (match_dup 2) (match_dup 3))] 5883 " 5884 operands[2] = gen_highpart (SImode, operands[0]); 5885 operands[3] = gen_highpart_mode (SImode, GET_MODE (operands[0]), 5886 operands[1]); 5887 operands[0] = gen_lowpart (SImode, operands[0]); 5888 operands[1] = gen_lowpart (SImode, operands[1]); 5889 " 5890) 5891 5892(define_split 5893 [(set (match_operand:ANY64 0 "arm_general_register_operand" "") 5894 (match_operand:ANY64 1 "arm_general_register_operand" ""))] 5895 "TARGET_EITHER && reload_completed" 5896 [(set (match_dup 0) (match_dup 1)) 5897 (set (match_dup 2) (match_dup 3))] 5898 " 5899 operands[2] = gen_highpart (SImode, operands[0]); 5900 operands[3] = gen_highpart (SImode, operands[1]); 5901 operands[0] = gen_lowpart (SImode, operands[0]); 5902 operands[1] = gen_lowpart (SImode, operands[1]); 5903 5904 /* Handle a partial overlap. */ 5905 if (rtx_equal_p (operands[0], operands[3])) 5906 { 5907 rtx tmp0 = operands[0]; 5908 rtx tmp1 = operands[1]; 5909 5910 operands[0] = operands[2]; 5911 operands[1] = operands[3]; 5912 operands[2] = tmp0; 5913 operands[3] = tmp1; 5914 } 5915 " 5916) 5917 5918;; We can't actually do base+index doubleword loads if the index and 5919;; destination overlap. Split here so that we at least have chance to 5920;; schedule. 5921(define_split 5922 [(set (match_operand:DI 0 "s_register_operand" "") 5923 (mem:DI (plus:SI (match_operand:SI 1 "s_register_operand" "") 5924 (match_operand:SI 2 "s_register_operand" ""))))] 5925 "TARGET_LDRD 5926 && reg_overlap_mentioned_p (operands[0], operands[1]) 5927 && reg_overlap_mentioned_p (operands[0], operands[2])" 5928 [(set (match_dup 4) 5929 (plus:SI (match_dup 1) 5930 (match_dup 2))) 5931 (set (match_dup 0) 5932 (mem:DI (match_dup 4)))] 5933 " 5934 operands[4] = gen_rtx_REG (SImode, REGNO(operands[0])); 5935 " 5936) 5937 5938(define_expand "movsi" 5939 [(set (match_operand:SI 0 "general_operand" "") 5940 (match_operand:SI 1 "general_operand" ""))] 5941 "TARGET_EITHER" 5942 " 5943 { 5944 rtx base, offset, tmp; 5945 5946 if (TARGET_32BIT || TARGET_HAVE_MOVT) 5947 { 5948 /* Everything except mem = const or mem = mem can be done easily. */ 5949 if (MEM_P (operands[0])) 5950 operands[1] = force_reg (SImode, operands[1]); 5951 if (arm_general_register_operand (operands[0], SImode) 5952 && CONST_INT_P (operands[1]) 5953 && !(const_ok_for_arm (INTVAL (operands[1])) 5954 || const_ok_for_arm (~INTVAL (operands[1])))) 5955 { 5956 if (DONT_EARLY_SPLIT_CONSTANT (INTVAL (operands[1]), SET)) 5957 { 5958 emit_insn (gen_rtx_SET (operands[0], operands[1])); 5959 DONE; 5960 } 5961 else 5962 { 5963 arm_split_constant (SET, SImode, NULL_RTX, 5964 INTVAL (operands[1]), operands[0], NULL_RTX, 5965 optimize && can_create_pseudo_p ()); 5966 DONE; 5967 } 5968 } 5969 } 5970 else /* Target doesn't have MOVT... */ 5971 { 5972 if (can_create_pseudo_p ()) 5973 { 5974 if (!REG_P (operands[0])) 5975 operands[1] = force_reg (SImode, operands[1]); 5976 } 5977 } 5978 5979 if (ARM_OFFSETS_MUST_BE_WITHIN_SECTIONS_P) 5980 { 5981 split_const (operands[1], &base, &offset); 5982 if (GET_CODE (base) == SYMBOL_REF 5983 && !offset_within_block_p (base, INTVAL (offset))) 5984 { 5985 tmp = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0]; 5986 emit_move_insn (tmp, base); 5987 emit_insn (gen_addsi3 (operands[0], tmp, offset)); 5988 DONE; 5989 } 5990 } 5991 5992 /* Recognize the case where operand[1] is a reference to thread-local 5993 data and load its address to a register. */ 5994 if (arm_tls_referenced_p (operands[1])) 5995 { 5996 rtx tmp = operands[1]; 5997 rtx addend = NULL; 5998 5999 if (GET_CODE (tmp) == CONST && GET_CODE (XEXP (tmp, 0)) == PLUS) 6000 { 6001 addend = XEXP (XEXP (tmp, 0), 1); 6002 tmp = XEXP (XEXP (tmp, 0), 0); 6003 } 6004 6005 gcc_assert (GET_CODE (tmp) == SYMBOL_REF); 6006 gcc_assert (SYMBOL_REF_TLS_MODEL (tmp) != 0); 6007 6008 tmp = legitimize_tls_address (tmp, 6009 !can_create_pseudo_p () ? operands[0] : 0); 6010 if (addend) 6011 { 6012 tmp = gen_rtx_PLUS (SImode, tmp, addend); 6013 tmp = force_operand (tmp, operands[0]); 6014 } 6015 operands[1] = tmp; 6016 } 6017 else if (flag_pic 6018 && (CONSTANT_P (operands[1]) 6019 || symbol_mentioned_p (operands[1]) 6020 || label_mentioned_p (operands[1]))) 6021 operands[1] = legitimize_pic_address (operands[1], SImode, 6022 (!can_create_pseudo_p () 6023 ? operands[0] 6024 : 0)); 6025 } 6026 " 6027) 6028 6029;; The ARM LO_SUM and HIGH are backwards - HIGH sets the low bits, and 6030;; LO_SUM adds in the high bits. Fortunately these are opaque operations 6031;; so this does not matter. 6032(define_insn "*arm_movt" 6033 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r") 6034 (lo_sum:SI (match_operand:SI 1 "nonimmediate_operand" "0,0") 6035 (match_operand:SI 2 "general_operand" "i,i")))] 6036 "TARGET_HAVE_MOVT && arm_valid_symbolic_address_p (operands[2])" 6037 "@ 6038 movt%?\t%0, #:upper16:%c2 6039 movt\t%0, #:upper16:%c2" 6040 [(set_attr "arch" "32,v8mb") 6041 (set_attr "predicable" "yes") 6042 (set_attr "length" "4") 6043 (set_attr "type" "alu_sreg")] 6044) 6045 6046(define_insn "*arm_movsi_insn" 6047 [(set (match_operand:SI 0 "nonimmediate_operand" "=rk,r,r,r,rk,m") 6048 (match_operand:SI 1 "general_operand" "rk, I,K,j,mi,rk"))] 6049 "TARGET_ARM && !TARGET_IWMMXT && !TARGET_HARD_FLOAT 6050 && ( register_operand (operands[0], SImode) 6051 || register_operand (operands[1], SImode))" 6052 "@ 6053 mov%?\\t%0, %1 6054 mov%?\\t%0, %1 6055 mvn%?\\t%0, #%B1 6056 movw%?\\t%0, %1 6057 ldr%?\\t%0, %1 6058 str%?\\t%1, %0" 6059 [(set_attr "type" "mov_reg,mov_imm,mvn_imm,mov_imm,load_4,store_4") 6060 (set_attr "predicable" "yes") 6061 (set_attr "arch" "*,*,*,v6t2,*,*") 6062 (set_attr "pool_range" "*,*,*,*,4096,*") 6063 (set_attr "neg_pool_range" "*,*,*,*,4084,*")] 6064) 6065 6066(define_split 6067 [(set (match_operand:SI 0 "arm_general_register_operand" "") 6068 (match_operand:SI 1 "const_int_operand" ""))] 6069 "(TARGET_32BIT || TARGET_HAVE_MOVT) 6070 && (!(const_ok_for_arm (INTVAL (operands[1])) 6071 || const_ok_for_arm (~INTVAL (operands[1]))))" 6072 [(clobber (const_int 0))] 6073 " 6074 arm_split_constant (SET, SImode, NULL_RTX, 6075 INTVAL (operands[1]), operands[0], NULL_RTX, 0); 6076 DONE; 6077 " 6078) 6079 6080;; A normal way to do (symbol + offset) requires three instructions at least 6081;; (depends on how big the offset is) as below: 6082;; movw r0, #:lower16:g 6083;; movw r0, #:upper16:g 6084;; adds r0, #4 6085;; 6086;; A better way would be: 6087;; movw r0, #:lower16:g+4 6088;; movw r0, #:upper16:g+4 6089;; 6090;; The limitation of this way is that the length of offset should be a 16-bit 6091;; signed value, because current assembler only supports REL type relocation for 6092;; such case. If the more powerful RELA type is supported in future, we should 6093;; update this pattern to go with better way. 6094(define_split 6095 [(set (match_operand:SI 0 "arm_general_register_operand" "") 6096 (const:SI (plus:SI (match_operand:SI 1 "general_operand" "") 6097 (match_operand:SI 2 "const_int_operand" ""))))] 6098 "TARGET_THUMB 6099 && TARGET_HAVE_MOVT 6100 && arm_disable_literal_pool 6101 && reload_completed 6102 && GET_CODE (operands[1]) == SYMBOL_REF" 6103 [(clobber (const_int 0))] 6104 " 6105 int offset = INTVAL (operands[2]); 6106 6107 if (offset < -0x8000 || offset > 0x7fff) 6108 { 6109 arm_emit_movpair (operands[0], operands[1]); 6110 emit_insn (gen_rtx_SET (operands[0], 6111 gen_rtx_PLUS (SImode, operands[0], operands[2]))); 6112 } 6113 else 6114 { 6115 rtx op = gen_rtx_CONST (SImode, 6116 gen_rtx_PLUS (SImode, operands[1], operands[2])); 6117 arm_emit_movpair (operands[0], op); 6118 } 6119 " 6120) 6121 6122;; Split symbol_refs at the later stage (after cprop), instead of generating 6123;; movt/movw pair directly at expand. Otherwise corresponding high_sum 6124;; and lo_sum would be merged back into memory load at cprop. However, 6125;; if the default is to prefer movt/movw rather than a load from the constant 6126;; pool, the performance is better. 6127(define_split 6128 [(set (match_operand:SI 0 "arm_general_register_operand" "") 6129 (match_operand:SI 1 "general_operand" ""))] 6130 "TARGET_USE_MOVT && GET_CODE (operands[1]) == SYMBOL_REF 6131 && !flag_pic && !target_word_relocations 6132 && !arm_tls_referenced_p (operands[1])" 6133 [(clobber (const_int 0))] 6134{ 6135 arm_emit_movpair (operands[0], operands[1]); 6136 DONE; 6137}) 6138 6139;; When generating pic, we need to load the symbol offset into a register. 6140;; So that the optimizer does not confuse this with a normal symbol load 6141;; we use an unspec. The offset will be loaded from a constant pool entry, 6142;; since that is the only type of relocation we can use. 6143 6144;; Wrap calculation of the whole PIC address in a single pattern for the 6145;; benefit of optimizers, particularly, PRE and HOIST. Calculation of 6146;; a PIC address involves two loads from memory, so we want to CSE it 6147;; as often as possible. 6148;; This pattern will be split into one of the pic_load_addr_* patterns 6149;; and a move after GCSE optimizations. 6150;; 6151;; Note: Update arm.c: legitimize_pic_address() when changing this pattern. 6152(define_expand "calculate_pic_address" 6153 [(set (match_operand:SI 0 "register_operand" "") 6154 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "") 6155 (unspec:SI [(match_operand:SI 2 "" "")] 6156 UNSPEC_PIC_SYM))))] 6157 "flag_pic" 6158) 6159 6160;; Split calculate_pic_address into pic_load_addr_* and a move. 6161(define_split 6162 [(set (match_operand:SI 0 "register_operand" "") 6163 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "") 6164 (unspec:SI [(match_operand:SI 2 "" "")] 6165 UNSPEC_PIC_SYM))))] 6166 "flag_pic" 6167 [(set (match_dup 3) (unspec:SI [(match_dup 2)] UNSPEC_PIC_SYM)) 6168 (set (match_dup 0) (mem:SI (plus:SI (match_dup 1) (match_dup 3))))] 6169 "operands[3] = can_create_pseudo_p () ? gen_reg_rtx (SImode) : operands[0];" 6170) 6171 6172;; operand1 is the memory address to go into 6173;; pic_load_addr_32bit. 6174;; operand2 is the PIC label to be emitted 6175;; from pic_add_dot_plus_eight. 6176;; We do this to allow hoisting of the entire insn. 6177(define_insn_and_split "pic_load_addr_unified" 6178 [(set (match_operand:SI 0 "s_register_operand" "=r,r,l") 6179 (unspec:SI [(match_operand:SI 1 "" "mX,mX,mX") 6180 (match_operand:SI 2 "" "")] 6181 UNSPEC_PIC_UNIFIED))] 6182 "flag_pic" 6183 "#" 6184 "&& reload_completed" 6185 [(set (match_dup 0) (unspec:SI [(match_dup 1)] UNSPEC_PIC_SYM)) 6186 (set (match_dup 0) (unspec:SI [(match_dup 0) (match_dup 3) 6187 (match_dup 2)] UNSPEC_PIC_BASE))] 6188 "operands[3] = TARGET_THUMB ? GEN_INT (4) : GEN_INT (8);" 6189 [(set_attr "type" "load_4,load_4,load_4") 6190 (set_attr "pool_range" "4096,4094,1022") 6191 (set_attr "neg_pool_range" "4084,0,0") 6192 (set_attr "arch" "a,t2,t1") 6193 (set_attr "length" "8,6,4")] 6194) 6195 6196;; The rather odd constraints on the following are to force reload to leave 6197;; the insn alone, and to force the minipool generation pass to then move 6198;; the GOT symbol to memory. 6199 6200(define_insn "pic_load_addr_32bit" 6201 [(set (match_operand:SI 0 "s_register_operand" "=r") 6202 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))] 6203 "TARGET_32BIT && flag_pic" 6204 "ldr%?\\t%0, %1" 6205 [(set_attr "type" "load_4") 6206 (set (attr "pool_range") 6207 (if_then_else (eq_attr "is_thumb" "no") 6208 (const_int 4096) 6209 (const_int 4094))) 6210 (set (attr "neg_pool_range") 6211 (if_then_else (eq_attr "is_thumb" "no") 6212 (const_int 4084) 6213 (const_int 0)))] 6214) 6215 6216(define_insn "pic_load_addr_thumb1" 6217 [(set (match_operand:SI 0 "s_register_operand" "=l") 6218 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))] 6219 "TARGET_THUMB1 && flag_pic" 6220 "ldr\\t%0, %1" 6221 [(set_attr "type" "load_4") 6222 (set (attr "pool_range") (const_int 1018))] 6223) 6224 6225(define_insn "pic_add_dot_plus_four" 6226 [(set (match_operand:SI 0 "register_operand" "=r") 6227 (unspec:SI [(match_operand:SI 1 "register_operand" "0") 6228 (const_int 4) 6229 (match_operand 2 "" "")] 6230 UNSPEC_PIC_BASE))] 6231 "TARGET_THUMB" 6232 "* 6233 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\", 6234 INTVAL (operands[2])); 6235 return \"add\\t%0, %|pc\"; 6236 " 6237 [(set_attr "length" "2") 6238 (set_attr "type" "alu_sreg")] 6239) 6240 6241(define_insn "pic_add_dot_plus_eight" 6242 [(set (match_operand:SI 0 "register_operand" "=r") 6243 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 6244 (const_int 8) 6245 (match_operand 2 "" "")] 6246 UNSPEC_PIC_BASE))] 6247 "TARGET_ARM" 6248 "* 6249 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\", 6250 INTVAL (operands[2])); 6251 return \"add%?\\t%0, %|pc, %1\"; 6252 " 6253 [(set_attr "predicable" "yes") 6254 (set_attr "type" "alu_sreg")] 6255) 6256 6257(define_insn "tls_load_dot_plus_eight" 6258 [(set (match_operand:SI 0 "register_operand" "=r") 6259 (mem:SI (unspec:SI [(match_operand:SI 1 "register_operand" "r") 6260 (const_int 8) 6261 (match_operand 2 "" "")] 6262 UNSPEC_PIC_BASE)))] 6263 "TARGET_ARM" 6264 "* 6265 (*targetm.asm_out.internal_label) (asm_out_file, \"LPIC\", 6266 INTVAL (operands[2])); 6267 return \"ldr%?\\t%0, [%|pc, %1]\t\t@ tls_load_dot_plus_eight\"; 6268 " 6269 [(set_attr "predicable" "yes") 6270 (set_attr "type" "load_4")] 6271) 6272 6273;; PIC references to local variables can generate pic_add_dot_plus_eight 6274;; followed by a load. These sequences can be crunched down to 6275;; tls_load_dot_plus_eight by a peephole. 6276 6277(define_peephole2 6278 [(set (match_operand:SI 0 "register_operand" "") 6279 (unspec:SI [(match_operand:SI 3 "register_operand" "") 6280 (const_int 8) 6281 (match_operand 1 "" "")] 6282 UNSPEC_PIC_BASE)) 6283 (set (match_operand:SI 2 "arm_general_register_operand" "") 6284 (mem:SI (match_dup 0)))] 6285 "TARGET_ARM && peep2_reg_dead_p (2, operands[0])" 6286 [(set (match_dup 2) 6287 (mem:SI (unspec:SI [(match_dup 3) 6288 (const_int 8) 6289 (match_dup 1)] 6290 UNSPEC_PIC_BASE)))] 6291 "" 6292) 6293 6294(define_insn "pic_offset_arm" 6295 [(set (match_operand:SI 0 "register_operand" "=r") 6296 (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r") 6297 (unspec:SI [(match_operand:SI 2 "" "X")] 6298 UNSPEC_PIC_OFFSET))))] 6299 "TARGET_VXWORKS_RTP && TARGET_ARM && flag_pic" 6300 "ldr%?\\t%0, [%1,%2]" 6301 [(set_attr "type" "load_4")] 6302) 6303 6304(define_expand "builtin_setjmp_receiver" 6305 [(label_ref (match_operand 0 "" ""))] 6306 "flag_pic" 6307 " 6308{ 6309 /* r3 is clobbered by set/longjmp, so we can use it as a scratch 6310 register. */ 6311 if (arm_pic_register != INVALID_REGNUM) 6312 arm_load_pic_register (1UL << 3); 6313 DONE; 6314}") 6315 6316;; If copying one reg to another we can set the condition codes according to 6317;; its value. Such a move is common after a return from subroutine and the 6318;; result is being tested against zero. 6319 6320(define_insn "*movsi_compare0" 6321 [(set (reg:CC CC_REGNUM) 6322 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r") 6323 (const_int 0))) 6324 (set (match_operand:SI 0 "s_register_operand" "=r,r") 6325 (match_dup 1))] 6326 "TARGET_32BIT" 6327 "@ 6328 cmp%?\\t%0, #0 6329 subs%?\\t%0, %1, #0" 6330 [(set_attr "conds" "set") 6331 (set_attr "type" "alus_imm,alus_imm")] 6332) 6333 6334;; Subroutine to store a half word from a register into memory. 6335;; Operand 0 is the source register (HImode) 6336;; Operand 1 is the destination address in a register (SImode) 6337 6338;; In both this routine and the next, we must be careful not to spill 6339;; a memory address of reg+large_const into a separate PLUS insn, since this 6340;; can generate unrecognizable rtl. 6341 6342(define_expand "storehi" 6343 [;; store the low byte 6344 (set (match_operand 1 "" "") (match_dup 3)) 6345 ;; extract the high byte 6346 (set (match_dup 2) 6347 (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) 6348 ;; store the high byte 6349 (set (match_dup 4) (match_dup 5))] 6350 "TARGET_ARM" 6351 " 6352 { 6353 rtx op1 = operands[1]; 6354 rtx addr = XEXP (op1, 0); 6355 enum rtx_code code = GET_CODE (addr); 6356 6357 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1))) 6358 || code == MINUS) 6359 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr)); 6360 6361 operands[4] = adjust_address (op1, QImode, 1); 6362 operands[1] = adjust_address (operands[1], QImode, 0); 6363 operands[3] = gen_lowpart (QImode, operands[0]); 6364 operands[0] = gen_lowpart (SImode, operands[0]); 6365 operands[2] = gen_reg_rtx (SImode); 6366 operands[5] = gen_lowpart (QImode, operands[2]); 6367 }" 6368) 6369 6370(define_expand "storehi_bigend" 6371 [(set (match_dup 4) (match_dup 3)) 6372 (set (match_dup 2) 6373 (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) 6374 (set (match_operand 1 "" "") (match_dup 5))] 6375 "TARGET_ARM" 6376 " 6377 { 6378 rtx op1 = operands[1]; 6379 rtx addr = XEXP (op1, 0); 6380 enum rtx_code code = GET_CODE (addr); 6381 6382 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1))) 6383 || code == MINUS) 6384 op1 = replace_equiv_address (op1, force_reg (SImode, addr)); 6385 6386 operands[4] = adjust_address (op1, QImode, 1); 6387 operands[1] = adjust_address (operands[1], QImode, 0); 6388 operands[3] = gen_lowpart (QImode, operands[0]); 6389 operands[0] = gen_lowpart (SImode, operands[0]); 6390 operands[2] = gen_reg_rtx (SImode); 6391 operands[5] = gen_lowpart (QImode, operands[2]); 6392 }" 6393) 6394 6395;; Subroutine to store a half word integer constant into memory. 6396(define_expand "storeinthi" 6397 [(set (match_operand 0 "" "") 6398 (match_operand 1 "" "")) 6399 (set (match_dup 3) (match_dup 2))] 6400 "TARGET_ARM" 6401 " 6402 { 6403 HOST_WIDE_INT value = INTVAL (operands[1]); 6404 rtx addr = XEXP (operands[0], 0); 6405 rtx op0 = operands[0]; 6406 enum rtx_code code = GET_CODE (addr); 6407 6408 if ((code == PLUS && !CONST_INT_P (XEXP (addr, 1))) 6409 || code == MINUS) 6410 op0 = replace_equiv_address (op0, force_reg (SImode, addr)); 6411 6412 operands[1] = gen_reg_rtx (SImode); 6413 if (BYTES_BIG_ENDIAN) 6414 { 6415 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255))); 6416 if ((value & 255) == ((value >> 8) & 255)) 6417 operands[2] = operands[1]; 6418 else 6419 { 6420 operands[2] = gen_reg_rtx (SImode); 6421 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255))); 6422 } 6423 } 6424 else 6425 { 6426 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255))); 6427 if ((value & 255) == ((value >> 8) & 255)) 6428 operands[2] = operands[1]; 6429 else 6430 { 6431 operands[2] = gen_reg_rtx (SImode); 6432 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255))); 6433 } 6434 } 6435 6436 operands[3] = adjust_address (op0, QImode, 1); 6437 operands[0] = adjust_address (operands[0], QImode, 0); 6438 operands[2] = gen_lowpart (QImode, operands[2]); 6439 operands[1] = gen_lowpart (QImode, operands[1]); 6440 }" 6441) 6442 6443(define_expand "storehi_single_op" 6444 [(set (match_operand:HI 0 "memory_operand" "") 6445 (match_operand:HI 1 "general_operand" ""))] 6446 "TARGET_32BIT && arm_arch4" 6447 " 6448 if (!s_register_operand (operands[1], HImode)) 6449 operands[1] = copy_to_mode_reg (HImode, operands[1]); 6450 " 6451) 6452 6453(define_expand "movhi" 6454 [(set (match_operand:HI 0 "general_operand" "") 6455 (match_operand:HI 1 "general_operand" ""))] 6456 "TARGET_EITHER" 6457 " 6458 if (TARGET_ARM) 6459 { 6460 if (can_create_pseudo_p ()) 6461 { 6462 if (MEM_P (operands[0])) 6463 { 6464 if (arm_arch4) 6465 { 6466 emit_insn (gen_storehi_single_op (operands[0], operands[1])); 6467 DONE; 6468 } 6469 if (CONST_INT_P (operands[1])) 6470 emit_insn (gen_storeinthi (operands[0], operands[1])); 6471 else 6472 { 6473 if (MEM_P (operands[1])) 6474 operands[1] = force_reg (HImode, operands[1]); 6475 if (BYTES_BIG_ENDIAN) 6476 emit_insn (gen_storehi_bigend (operands[1], operands[0])); 6477 else 6478 emit_insn (gen_storehi (operands[1], operands[0])); 6479 } 6480 DONE; 6481 } 6482 /* Sign extend a constant, and keep it in an SImode reg. */ 6483 else if (CONST_INT_P (operands[1])) 6484 { 6485 rtx reg = gen_reg_rtx (SImode); 6486 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff; 6487 6488 /* If the constant is already valid, leave it alone. */ 6489 if (!const_ok_for_arm (val)) 6490 { 6491 /* If setting all the top bits will make the constant 6492 loadable in a single instruction, then set them. 6493 Otherwise, sign extend the number. */ 6494 6495 if (const_ok_for_arm (~(val | ~0xffff))) 6496 val |= ~0xffff; 6497 else if (val & 0x8000) 6498 val |= ~0xffff; 6499 } 6500 6501 emit_insn (gen_movsi (reg, GEN_INT (val))); 6502 operands[1] = gen_lowpart (HImode, reg); 6503 } 6504 else if (arm_arch4 && optimize && can_create_pseudo_p () 6505 && MEM_P (operands[1])) 6506 { 6507 rtx reg = gen_reg_rtx (SImode); 6508 6509 emit_insn (gen_zero_extendhisi2 (reg, operands[1])); 6510 operands[1] = gen_lowpart (HImode, reg); 6511 } 6512 else if (!arm_arch4) 6513 { 6514 if (MEM_P (operands[1])) 6515 { 6516 rtx base; 6517 rtx offset = const0_rtx; 6518 rtx reg = gen_reg_rtx (SImode); 6519 6520 if ((REG_P (base = XEXP (operands[1], 0)) 6521 || (GET_CODE (base) == PLUS 6522 && (CONST_INT_P (offset = XEXP (base, 1))) 6523 && ((INTVAL(offset) & 1) != 1) 6524 && REG_P (base = XEXP (base, 0)))) 6525 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32) 6526 { 6527 rtx new_rtx; 6528 6529 new_rtx = widen_memory_access (operands[1], SImode, 6530 ((INTVAL (offset) & ~3) 6531 - INTVAL (offset))); 6532 emit_insn (gen_movsi (reg, new_rtx)); 6533 if (((INTVAL (offset) & 2) != 0) 6534 ^ (BYTES_BIG_ENDIAN ? 1 : 0)) 6535 { 6536 rtx reg2 = gen_reg_rtx (SImode); 6537 6538 emit_insn (gen_lshrsi3 (reg2, reg, GEN_INT (16))); 6539 reg = reg2; 6540 } 6541 } 6542 else 6543 emit_insn (gen_movhi_bytes (reg, operands[1])); 6544 6545 operands[1] = gen_lowpart (HImode, reg); 6546 } 6547 } 6548 } 6549 /* Handle loading a large integer during reload. */ 6550 else if (CONST_INT_P (operands[1]) 6551 && !const_ok_for_arm (INTVAL (operands[1])) 6552 && !const_ok_for_arm (~INTVAL (operands[1]))) 6553 { 6554 /* Writing a constant to memory needs a scratch, which should 6555 be handled with SECONDARY_RELOADs. */ 6556 gcc_assert (REG_P (operands[0])); 6557 6558 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); 6559 emit_insn (gen_movsi (operands[0], operands[1])); 6560 DONE; 6561 } 6562 } 6563 else if (TARGET_THUMB2) 6564 { 6565 /* Thumb-2 can do everything except mem=mem and mem=const easily. */ 6566 if (can_create_pseudo_p ()) 6567 { 6568 if (!REG_P (operands[0])) 6569 operands[1] = force_reg (HImode, operands[1]); 6570 /* Zero extend a constant, and keep it in an SImode reg. */ 6571 else if (CONST_INT_P (operands[1])) 6572 { 6573 rtx reg = gen_reg_rtx (SImode); 6574 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff; 6575 6576 emit_insn (gen_movsi (reg, GEN_INT (val))); 6577 operands[1] = gen_lowpart (HImode, reg); 6578 } 6579 } 6580 } 6581 else /* TARGET_THUMB1 */ 6582 { 6583 if (can_create_pseudo_p ()) 6584 { 6585 if (CONST_INT_P (operands[1])) 6586 { 6587 rtx reg = gen_reg_rtx (SImode); 6588 6589 emit_insn (gen_movsi (reg, operands[1])); 6590 operands[1] = gen_lowpart (HImode, reg); 6591 } 6592 6593 /* ??? We shouldn't really get invalid addresses here, but this can 6594 happen if we are passed a SP (never OK for HImode/QImode) or 6595 virtual register (also rejected as illegitimate for HImode/QImode) 6596 relative address. */ 6597 /* ??? This should perhaps be fixed elsewhere, for instance, in 6598 fixup_stack_1, by checking for other kinds of invalid addresses, 6599 e.g. a bare reference to a virtual register. This may confuse the 6600 alpha though, which must handle this case differently. */ 6601 if (MEM_P (operands[0]) 6602 && !memory_address_p (GET_MODE (operands[0]), 6603 XEXP (operands[0], 0))) 6604 operands[0] 6605 = replace_equiv_address (operands[0], 6606 copy_to_reg (XEXP (operands[0], 0))); 6607 6608 if (MEM_P (operands[1]) 6609 && !memory_address_p (GET_MODE (operands[1]), 6610 XEXP (operands[1], 0))) 6611 operands[1] 6612 = replace_equiv_address (operands[1], 6613 copy_to_reg (XEXP (operands[1], 0))); 6614 6615 if (MEM_P (operands[1]) && optimize > 0) 6616 { 6617 rtx reg = gen_reg_rtx (SImode); 6618 6619 emit_insn (gen_zero_extendhisi2 (reg, operands[1])); 6620 operands[1] = gen_lowpart (HImode, reg); 6621 } 6622 6623 if (MEM_P (operands[0])) 6624 operands[1] = force_reg (HImode, operands[1]); 6625 } 6626 else if (CONST_INT_P (operands[1]) 6627 && !satisfies_constraint_I (operands[1])) 6628 { 6629 /* Handle loading a large integer during reload. */ 6630 6631 /* Writing a constant to memory needs a scratch, which should 6632 be handled with SECONDARY_RELOADs. */ 6633 gcc_assert (REG_P (operands[0])); 6634 6635 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); 6636 emit_insn (gen_movsi (operands[0], operands[1])); 6637 DONE; 6638 } 6639 } 6640 " 6641) 6642 6643(define_expand "movhi_bytes" 6644 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" ""))) 6645 (set (match_dup 3) 6646 (zero_extend:SI (match_dup 6))) 6647 (set (match_operand:SI 0 "" "") 6648 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))] 6649 "TARGET_ARM" 6650 " 6651 { 6652 rtx mem1, mem2; 6653 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 6654 6655 mem1 = change_address (operands[1], QImode, addr); 6656 mem2 = change_address (operands[1], QImode, 6657 plus_constant (Pmode, addr, 1)); 6658 operands[0] = gen_lowpart (SImode, operands[0]); 6659 operands[1] = mem1; 6660 operands[2] = gen_reg_rtx (SImode); 6661 operands[3] = gen_reg_rtx (SImode); 6662 operands[6] = mem2; 6663 6664 if (BYTES_BIG_ENDIAN) 6665 { 6666 operands[4] = operands[2]; 6667 operands[5] = operands[3]; 6668 } 6669 else 6670 { 6671 operands[4] = operands[3]; 6672 operands[5] = operands[2]; 6673 } 6674 }" 6675) 6676 6677(define_expand "movhi_bigend" 6678 [(set (match_dup 2) 6679 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0) 6680 (const_int 16))) 6681 (set (match_dup 3) 6682 (ashiftrt:SI (match_dup 2) (const_int 16))) 6683 (set (match_operand:HI 0 "s_register_operand" "") 6684 (match_dup 4))] 6685 "TARGET_ARM" 6686 " 6687 operands[2] = gen_reg_rtx (SImode); 6688 operands[3] = gen_reg_rtx (SImode); 6689 operands[4] = gen_lowpart (HImode, operands[3]); 6690 " 6691) 6692 6693;; Pattern to recognize insn generated default case above 6694(define_insn "*movhi_insn_arch4" 6695 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m,r") 6696 (match_operand:HI 1 "general_operand" "rIk,K,n,r,mi"))] 6697 "TARGET_ARM 6698 && arm_arch4 && !TARGET_HARD_FLOAT 6699 && (register_operand (operands[0], HImode) 6700 || register_operand (operands[1], HImode))" 6701 "@ 6702 mov%?\\t%0, %1\\t%@ movhi 6703 mvn%?\\t%0, #%B1\\t%@ movhi 6704 movw%?\\t%0, %L1\\t%@ movhi 6705 strh%?\\t%1, %0\\t%@ movhi 6706 ldrh%?\\t%0, %1\\t%@ movhi" 6707 [(set_attr "predicable" "yes") 6708 (set_attr "pool_range" "*,*,*,*,256") 6709 (set_attr "neg_pool_range" "*,*,*,*,244") 6710 (set_attr "arch" "*,*,v6t2,*,*") 6711 (set_attr_alternative "type" 6712 [(if_then_else (match_operand 1 "const_int_operand" "") 6713 (const_string "mov_imm" ) 6714 (const_string "mov_reg")) 6715 (const_string "mvn_imm") 6716 (const_string "mov_imm") 6717 (const_string "store_4") 6718 (const_string "load_4")])] 6719) 6720 6721(define_insn "*movhi_bytes" 6722 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r") 6723 (match_operand:HI 1 "arm_rhs_operand" "I,rk,K"))] 6724 "TARGET_ARM && !TARGET_HARD_FLOAT" 6725 "@ 6726 mov%?\\t%0, %1\\t%@ movhi 6727 mov%?\\t%0, %1\\t%@ movhi 6728 mvn%?\\t%0, #%B1\\t%@ movhi" 6729 [(set_attr "predicable" "yes") 6730 (set_attr "type" "mov_imm,mov_reg,mvn_imm")] 6731) 6732 6733;; We use a DImode scratch because we may occasionally need an additional 6734;; temporary if the address isn't offsettable -- push_reload doesn't seem 6735;; to take any notice of the "o" constraints on reload_memory_operand operand. 6736(define_expand "reload_outhi" 6737 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o") 6738 (match_operand:HI 1 "s_register_operand" "r") 6739 (match_operand:DI 2 "s_register_operand" "=&l")])] 6740 "TARGET_EITHER" 6741 "if (TARGET_ARM) 6742 arm_reload_out_hi (operands); 6743 else 6744 thumb_reload_out_hi (operands); 6745 DONE; 6746 " 6747) 6748 6749(define_expand "reload_inhi" 6750 [(parallel [(match_operand:HI 0 "s_register_operand" "=r") 6751 (match_operand:HI 1 "arm_reload_memory_operand" "o") 6752 (match_operand:DI 2 "s_register_operand" "=&r")])] 6753 "TARGET_EITHER" 6754 " 6755 if (TARGET_ARM) 6756 arm_reload_in_hi (operands); 6757 else 6758 thumb_reload_out_hi (operands); 6759 DONE; 6760") 6761 6762(define_expand "movqi" 6763 [(set (match_operand:QI 0 "general_operand" "") 6764 (match_operand:QI 1 "general_operand" ""))] 6765 "TARGET_EITHER" 6766 " 6767 /* Everything except mem = const or mem = mem can be done easily */ 6768 6769 if (can_create_pseudo_p ()) 6770 { 6771 if (CONST_INT_P (operands[1])) 6772 { 6773 rtx reg = gen_reg_rtx (SImode); 6774 6775 /* For thumb we want an unsigned immediate, then we are more likely 6776 to be able to use a movs insn. */ 6777 if (TARGET_THUMB) 6778 operands[1] = GEN_INT (INTVAL (operands[1]) & 255); 6779 6780 emit_insn (gen_movsi (reg, operands[1])); 6781 operands[1] = gen_lowpart (QImode, reg); 6782 } 6783 6784 if (TARGET_THUMB) 6785 { 6786 /* ??? We shouldn't really get invalid addresses here, but this can 6787 happen if we are passed a SP (never OK for HImode/QImode) or 6788 virtual register (also rejected as illegitimate for HImode/QImode) 6789 relative address. */ 6790 /* ??? This should perhaps be fixed elsewhere, for instance, in 6791 fixup_stack_1, by checking for other kinds of invalid addresses, 6792 e.g. a bare reference to a virtual register. This may confuse the 6793 alpha though, which must handle this case differently. */ 6794 if (MEM_P (operands[0]) 6795 && !memory_address_p (GET_MODE (operands[0]), 6796 XEXP (operands[0], 0))) 6797 operands[0] 6798 = replace_equiv_address (operands[0], 6799 copy_to_reg (XEXP (operands[0], 0))); 6800 if (MEM_P (operands[1]) 6801 && !memory_address_p (GET_MODE (operands[1]), 6802 XEXP (operands[1], 0))) 6803 operands[1] 6804 = replace_equiv_address (operands[1], 6805 copy_to_reg (XEXP (operands[1], 0))); 6806 } 6807 6808 if (MEM_P (operands[1]) && optimize > 0) 6809 { 6810 rtx reg = gen_reg_rtx (SImode); 6811 6812 emit_insn (gen_zero_extendqisi2 (reg, operands[1])); 6813 operands[1] = gen_lowpart (QImode, reg); 6814 } 6815 6816 if (MEM_P (operands[0])) 6817 operands[1] = force_reg (QImode, operands[1]); 6818 } 6819 else if (TARGET_THUMB 6820 && CONST_INT_P (operands[1]) 6821 && !satisfies_constraint_I (operands[1])) 6822 { 6823 /* Handle loading a large integer during reload. */ 6824 6825 /* Writing a constant to memory needs a scratch, which should 6826 be handled with SECONDARY_RELOADs. */ 6827 gcc_assert (REG_P (operands[0])); 6828 6829 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); 6830 emit_insn (gen_movsi (operands[0], operands[1])); 6831 DONE; 6832 } 6833 " 6834) 6835 6836(define_insn "*arm_movqi_insn" 6837 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,l,r,l,Uu,r,m") 6838 (match_operand:QI 1 "general_operand" "rk,rk,I,Py,K,Uu,l,Uh,r"))] 6839 "TARGET_32BIT 6840 && ( register_operand (operands[0], QImode) 6841 || register_operand (operands[1], QImode))" 6842 "@ 6843 mov%?\\t%0, %1 6844 mov%?\\t%0, %1 6845 mov%?\\t%0, %1 6846 mov%?\\t%0, %1 6847 mvn%?\\t%0, #%B1 6848 ldrb%?\\t%0, %1 6849 strb%?\\t%1, %0 6850 ldrb%?\\t%0, %1 6851 strb%?\\t%1, %0" 6852 [(set_attr "type" "mov_reg,mov_reg,mov_imm,mov_imm,mvn_imm,load_4,store_4,load_4,store_4") 6853 (set_attr "predicable" "yes") 6854 (set_attr "predicable_short_it" "yes,yes,no,yes,no,no,no,no,no") 6855 (set_attr "arch" "t2,any,any,t2,any,t2,t2,any,any") 6856 (set_attr "length" "2,4,4,2,4,2,2,4,4")] 6857) 6858 6859;; HFmode moves 6860(define_expand "movhf" 6861 [(set (match_operand:HF 0 "general_operand" "") 6862 (match_operand:HF 1 "general_operand" ""))] 6863 "TARGET_EITHER" 6864 " 6865 if (TARGET_32BIT) 6866 { 6867 if (MEM_P (operands[0])) 6868 operands[1] = force_reg (HFmode, operands[1]); 6869 } 6870 else /* TARGET_THUMB1 */ 6871 { 6872 if (can_create_pseudo_p ()) 6873 { 6874 if (!REG_P (operands[0])) 6875 operands[1] = force_reg (HFmode, operands[1]); 6876 } 6877 } 6878 " 6879) 6880 6881(define_insn "*arm32_movhf" 6882 [(set (match_operand:HF 0 "nonimmediate_operand" "=r,m,r,r") 6883 (match_operand:HF 1 "general_operand" " m,r,r,F"))] 6884 "TARGET_32BIT && !TARGET_HARD_FLOAT 6885 && ( s_register_operand (operands[0], HFmode) 6886 || s_register_operand (operands[1], HFmode))" 6887 "* 6888 switch (which_alternative) 6889 { 6890 case 0: /* ARM register from memory */ 6891 return \"ldrh%?\\t%0, %1\\t%@ __fp16\"; 6892 case 1: /* memory from ARM register */ 6893 return \"strh%?\\t%1, %0\\t%@ __fp16\"; 6894 case 2: /* ARM register from ARM register */ 6895 return \"mov%?\\t%0, %1\\t%@ __fp16\"; 6896 case 3: /* ARM register from constant */ 6897 { 6898 long bits; 6899 rtx ops[4]; 6900 6901 bits = real_to_target (NULL, CONST_DOUBLE_REAL_VALUE (operands[1]), 6902 HFmode); 6903 ops[0] = operands[0]; 6904 ops[1] = GEN_INT (bits); 6905 ops[2] = GEN_INT (bits & 0xff00); 6906 ops[3] = GEN_INT (bits & 0x00ff); 6907 6908 if (arm_arch_thumb2) 6909 output_asm_insn (\"movw%?\\t%0, %1\", ops); 6910 else 6911 output_asm_insn (\"mov%?\\t%0, %2\;orr%?\\t%0, %0, %3\", ops); 6912 return \"\"; 6913 } 6914 default: 6915 gcc_unreachable (); 6916 } 6917 " 6918 [(set_attr "conds" "unconditional") 6919 (set_attr "type" "load_4,store_4,mov_reg,multiple") 6920 (set_attr "length" "4,4,4,8") 6921 (set_attr "predicable" "yes")] 6922) 6923 6924(define_expand "movsf" 6925 [(set (match_operand:SF 0 "general_operand" "") 6926 (match_operand:SF 1 "general_operand" ""))] 6927 "TARGET_EITHER" 6928 " 6929 if (TARGET_32BIT) 6930 { 6931 if (MEM_P (operands[0])) 6932 operands[1] = force_reg (SFmode, operands[1]); 6933 } 6934 else /* TARGET_THUMB1 */ 6935 { 6936 if (can_create_pseudo_p ()) 6937 { 6938 if (!REG_P (operands[0])) 6939 operands[1] = force_reg (SFmode, operands[1]); 6940 } 6941 } 6942 " 6943) 6944 6945;; Transform a floating-point move of a constant into a core register into 6946;; an SImode operation. 6947(define_split 6948 [(set (match_operand:SF 0 "arm_general_register_operand" "") 6949 (match_operand:SF 1 "immediate_operand" ""))] 6950 "TARGET_EITHER 6951 && reload_completed 6952 && CONST_DOUBLE_P (operands[1])" 6953 [(set (match_dup 2) (match_dup 3))] 6954 " 6955 operands[2] = gen_lowpart (SImode, operands[0]); 6956 operands[3] = gen_lowpart (SImode, operands[1]); 6957 if (operands[2] == 0 || operands[3] == 0) 6958 FAIL; 6959 " 6960) 6961 6962(define_insn "*arm_movsf_soft_insn" 6963 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m") 6964 (match_operand:SF 1 "general_operand" "r,mE,r"))] 6965 "TARGET_32BIT 6966 && TARGET_SOFT_FLOAT 6967 && (!MEM_P (operands[0]) 6968 || register_operand (operands[1], SFmode))" 6969 "@ 6970 mov%?\\t%0, %1 6971 ldr%?\\t%0, %1\\t%@ float 6972 str%?\\t%1, %0\\t%@ float" 6973 [(set_attr "predicable" "yes") 6974 (set_attr "type" "mov_reg,load_4,store_4") 6975 (set_attr "arm_pool_range" "*,4096,*") 6976 (set_attr "thumb2_pool_range" "*,4094,*") 6977 (set_attr "arm_neg_pool_range" "*,4084,*") 6978 (set_attr "thumb2_neg_pool_range" "*,0,*")] 6979) 6980 6981(define_expand "movdf" 6982 [(set (match_operand:DF 0 "general_operand" "") 6983 (match_operand:DF 1 "general_operand" ""))] 6984 "TARGET_EITHER" 6985 " 6986 if (TARGET_32BIT) 6987 { 6988 if (MEM_P (operands[0])) 6989 operands[1] = force_reg (DFmode, operands[1]); 6990 } 6991 else /* TARGET_THUMB */ 6992 { 6993 if (can_create_pseudo_p ()) 6994 { 6995 if (!REG_P (operands[0])) 6996 operands[1] = force_reg (DFmode, operands[1]); 6997 } 6998 } 6999 " 7000) 7001 7002;; Reloading a df mode value stored in integer regs to memory can require a 7003;; scratch reg. 7004(define_expand "reload_outdf" 7005 [(match_operand:DF 0 "arm_reload_memory_operand" "=o") 7006 (match_operand:DF 1 "s_register_operand" "r") 7007 (match_operand:SI 2 "s_register_operand" "=&r")] 7008 "TARGET_THUMB2" 7009 " 7010 { 7011 enum rtx_code code = GET_CODE (XEXP (operands[0], 0)); 7012 7013 if (code == REG) 7014 operands[2] = XEXP (operands[0], 0); 7015 else if (code == POST_INC || code == PRE_DEC) 7016 { 7017 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0); 7018 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0); 7019 emit_insn (gen_movdi (operands[0], operands[1])); 7020 DONE; 7021 } 7022 else if (code == PRE_INC) 7023 { 7024 rtx reg = XEXP (XEXP (operands[0], 0), 0); 7025 7026 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8))); 7027 operands[2] = reg; 7028 } 7029 else if (code == POST_DEC) 7030 operands[2] = XEXP (XEXP (operands[0], 0), 0); 7031 else 7032 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0), 7033 XEXP (XEXP (operands[0], 0), 1))); 7034 7035 emit_insn (gen_rtx_SET (replace_equiv_address (operands[0], operands[2]), 7036 operands[1])); 7037 7038 if (code == POST_DEC) 7039 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8))); 7040 7041 DONE; 7042 }" 7043) 7044 7045(define_insn "*movdf_soft_insn" 7046 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,r,q,m") 7047 (match_operand:DF 1 "soft_df_operand" "rDa,Db,Dc,mF,q"))] 7048 "TARGET_32BIT && TARGET_SOFT_FLOAT 7049 && ( register_operand (operands[0], DFmode) 7050 || register_operand (operands[1], DFmode))" 7051 "* 7052 switch (which_alternative) 7053 { 7054 case 0: 7055 case 1: 7056 case 2: 7057 return \"#\"; 7058 default: 7059 return output_move_double (operands, true, NULL); 7060 } 7061 " 7062 [(set_attr "length" "8,12,16,8,8") 7063 (set_attr "type" "multiple,multiple,multiple,load_8,store_8") 7064 (set_attr "arm_pool_range" "*,*,*,1020,*") 7065 (set_attr "thumb2_pool_range" "*,*,*,1018,*") 7066 (set_attr "arm_neg_pool_range" "*,*,*,1004,*") 7067 (set_attr "thumb2_neg_pool_range" "*,*,*,0,*")] 7068) 7069 7070 7071;; load- and store-multiple insns 7072;; The arm can load/store any set of registers, provided that they are in 7073;; ascending order, but these expanders assume a contiguous set. 7074 7075(define_expand "load_multiple" 7076 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 7077 (match_operand:SI 1 "" "")) 7078 (use (match_operand:SI 2 "" ""))])] 7079 "TARGET_32BIT" 7080{ 7081 HOST_WIDE_INT offset = 0; 7082 7083 /* Support only fixed point registers. */ 7084 if (!CONST_INT_P (operands[2]) 7085 || INTVAL (operands[2]) > MAX_LDM_STM_OPS 7086 || INTVAL (operands[2]) < 2 7087 || !MEM_P (operands[1]) 7088 || !REG_P (operands[0]) 7089 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1) 7090 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM) 7091 FAIL; 7092 7093 operands[3] 7094 = arm_gen_load_multiple (arm_regs_in_sequence + REGNO (operands[0]), 7095 INTVAL (operands[2]), 7096 force_reg (SImode, XEXP (operands[1], 0)), 7097 FALSE, operands[1], &offset); 7098}) 7099 7100(define_expand "store_multiple" 7101 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 7102 (match_operand:SI 1 "" "")) 7103 (use (match_operand:SI 2 "" ""))])] 7104 "TARGET_32BIT" 7105{ 7106 HOST_WIDE_INT offset = 0; 7107 7108 /* Support only fixed point registers. */ 7109 if (!CONST_INT_P (operands[2]) 7110 || INTVAL (operands[2]) > MAX_LDM_STM_OPS 7111 || INTVAL (operands[2]) < 2 7112 || !REG_P (operands[1]) 7113 || !MEM_P (operands[0]) 7114 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1) 7115 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM) 7116 FAIL; 7117 7118 operands[3] 7119 = arm_gen_store_multiple (arm_regs_in_sequence + REGNO (operands[1]), 7120 INTVAL (operands[2]), 7121 force_reg (SImode, XEXP (operands[0], 0)), 7122 FALSE, operands[0], &offset); 7123}) 7124 7125 7126(define_expand "setmemsi" 7127 [(match_operand:BLK 0 "general_operand" "") 7128 (match_operand:SI 1 "const_int_operand" "") 7129 (match_operand:SI 2 "const_int_operand" "") 7130 (match_operand:SI 3 "const_int_operand" "")] 7131 "TARGET_32BIT" 7132{ 7133 if (arm_gen_setmem (operands)) 7134 DONE; 7135 7136 FAIL; 7137}) 7138 7139 7140;; Move a block of memory if it is word aligned and MORE than 2 words long. 7141;; We could let this apply for blocks of less than this, but it clobbers so 7142;; many registers that there is then probably a better way. 7143 7144(define_expand "movmemqi" 7145 [(match_operand:BLK 0 "general_operand" "") 7146 (match_operand:BLK 1 "general_operand" "") 7147 (match_operand:SI 2 "const_int_operand" "") 7148 (match_operand:SI 3 "const_int_operand" "")] 7149 "" 7150 " 7151 if (TARGET_32BIT) 7152 { 7153 if (TARGET_LDRD && current_tune->prefer_ldrd_strd 7154 && !optimize_function_for_size_p (cfun)) 7155 { 7156 if (gen_movmem_ldrd_strd (operands)) 7157 DONE; 7158 FAIL; 7159 } 7160 7161 if (arm_gen_movmemqi (operands)) 7162 DONE; 7163 FAIL; 7164 } 7165 else /* TARGET_THUMB1 */ 7166 { 7167 if ( INTVAL (operands[3]) != 4 7168 || INTVAL (operands[2]) > 48) 7169 FAIL; 7170 7171 thumb_expand_movmemqi (operands); 7172 DONE; 7173 } 7174 " 7175) 7176 7177 7178;; Compare & branch insns 7179;; The range calculations are based as follows: 7180;; For forward branches, the address calculation returns the address of 7181;; the next instruction. This is 2 beyond the branch instruction. 7182;; For backward branches, the address calculation returns the address of 7183;; the first instruction in this pattern (cmp). This is 2 before the branch 7184;; instruction for the shortest sequence, and 4 before the branch instruction 7185;; if we have to jump around an unconditional branch. 7186;; To the basic branch range the PC offset must be added (this is +4). 7187;; So for forward branches we have 7188;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4). 7189;; And for backward branches we have 7190;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4). 7191;; 7192;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048). 7193;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256). 7194 7195(define_expand "cbranchsi4" 7196 [(set (pc) (if_then_else 7197 (match_operator 0 "expandable_comparison_operator" 7198 [(match_operand:SI 1 "s_register_operand" "") 7199 (match_operand:SI 2 "nonmemory_operand" "")]) 7200 (label_ref (match_operand 3 "" "")) 7201 (pc)))] 7202 "TARGET_EITHER" 7203 " 7204 if (!TARGET_THUMB1) 7205 { 7206 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2])) 7207 FAIL; 7208 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7209 operands[3])); 7210 DONE; 7211 } 7212 if (thumb1_cmpneg_operand (operands[2], SImode)) 7213 { 7214 emit_jump_insn (gen_cbranchsi4_scratch (NULL, operands[1], operands[2], 7215 operands[3], operands[0])); 7216 DONE; 7217 } 7218 if (!thumb1_cmp_operand (operands[2], SImode)) 7219 operands[2] = force_reg (SImode, operands[2]); 7220 ") 7221 7222(define_expand "cbranchsf4" 7223 [(set (pc) (if_then_else 7224 (match_operator 0 "expandable_comparison_operator" 7225 [(match_operand:SF 1 "s_register_operand" "") 7226 (match_operand:SF 2 "vfp_compare_operand" "")]) 7227 (label_ref (match_operand 3 "" "")) 7228 (pc)))] 7229 "TARGET_32BIT && TARGET_HARD_FLOAT" 7230 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7231 operands[3])); DONE;" 7232) 7233 7234(define_expand "cbranchdf4" 7235 [(set (pc) (if_then_else 7236 (match_operator 0 "expandable_comparison_operator" 7237 [(match_operand:DF 1 "s_register_operand" "") 7238 (match_operand:DF 2 "vfp_compare_operand" "")]) 7239 (label_ref (match_operand 3 "" "")) 7240 (pc)))] 7241 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 7242 "emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7243 operands[3])); DONE;" 7244) 7245 7246(define_expand "cbranchdi4" 7247 [(set (pc) (if_then_else 7248 (match_operator 0 "expandable_comparison_operator" 7249 [(match_operand:DI 1 "s_register_operand" "") 7250 (match_operand:DI 2 "cmpdi_operand" "")]) 7251 (label_ref (match_operand 3 "" "")) 7252 (pc)))] 7253 "TARGET_32BIT" 7254 "{ 7255 if (!arm_validize_comparison (&operands[0], &operands[1], &operands[2])) 7256 FAIL; 7257 emit_jump_insn (gen_cbranch_cc (operands[0], operands[1], operands[2], 7258 operands[3])); 7259 DONE; 7260 }" 7261) 7262 7263;; Comparison and test insns 7264 7265(define_insn "*arm_cmpsi_insn" 7266 [(set (reg:CC CC_REGNUM) 7267 (compare:CC (match_operand:SI 0 "s_register_operand" "l,r,r,r,r") 7268 (match_operand:SI 1 "arm_add_operand" "Py,r,r,I,L")))] 7269 "TARGET_32BIT" 7270 "@ 7271 cmp%?\\t%0, %1 7272 cmp%?\\t%0, %1 7273 cmp%?\\t%0, %1 7274 cmp%?\\t%0, %1 7275 cmn%?\\t%0, #%n1" 7276 [(set_attr "conds" "set") 7277 (set_attr "arch" "t2,t2,any,any,any") 7278 (set_attr "length" "2,2,4,4,4") 7279 (set_attr "predicable" "yes") 7280 (set_attr "predicable_short_it" "yes,yes,yes,no,no") 7281 (set_attr "type" "alus_imm,alus_sreg,alus_sreg,alus_imm,alus_imm")] 7282) 7283 7284(define_insn "*cmpsi_shiftsi" 7285 [(set (reg:CC CC_REGNUM) 7286 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r,r") 7287 (match_operator:SI 3 "shift_operator" 7288 [(match_operand:SI 1 "s_register_operand" "r,r,r") 7289 (match_operand:SI 2 "shift_amount_operand" "M,r,M")])))] 7290 "TARGET_32BIT" 7291 "cmp\\t%0, %1%S3" 7292 [(set_attr "conds" "set") 7293 (set_attr "shift" "1") 7294 (set_attr "arch" "32,a,a") 7295 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 7296 7297(define_insn "*cmpsi_shiftsi_swp" 7298 [(set (reg:CC_SWP CC_REGNUM) 7299 (compare:CC_SWP (match_operator:SI 3 "shift_operator" 7300 [(match_operand:SI 1 "s_register_operand" "r,r,r") 7301 (match_operand:SI 2 "shift_amount_operand" "M,r,M")]) 7302 (match_operand:SI 0 "s_register_operand" "r,r,r")))] 7303 "TARGET_32BIT" 7304 "cmp%?\\t%0, %1%S3" 7305 [(set_attr "conds" "set") 7306 (set_attr "shift" "1") 7307 (set_attr "arch" "32,a,a") 7308 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 7309 7310(define_insn "*arm_cmpsi_negshiftsi_si" 7311 [(set (reg:CC_Z CC_REGNUM) 7312 (compare:CC_Z 7313 (neg:SI (match_operator:SI 1 "shift_operator" 7314 [(match_operand:SI 2 "s_register_operand" "r") 7315 (match_operand:SI 3 "reg_or_int_operand" "rM")])) 7316 (match_operand:SI 0 "s_register_operand" "r")))] 7317 "TARGET_ARM" 7318 "cmn%?\\t%0, %2%S1" 7319 [(set_attr "conds" "set") 7320 (set (attr "type") (if_then_else (match_operand 3 "const_int_operand" "") 7321 (const_string "alus_shift_imm") 7322 (const_string "alus_shift_reg"))) 7323 (set_attr "predicable" "yes")] 7324) 7325 7326;; DImode comparisons. The generic code generates branches that 7327;; if-conversion can not reduce to a conditional compare, so we do 7328;; that directly. 7329 7330(define_insn_and_split "*arm_cmpdi_insn" 7331 [(set (reg:CC_NCV CC_REGNUM) 7332 (compare:CC_NCV (match_operand:DI 0 "s_register_operand" "r") 7333 (match_operand:DI 1 "arm_di_operand" "rDi"))) 7334 (clobber (match_scratch:SI 2 "=r"))] 7335 "TARGET_32BIT" 7336 "#" ; "cmp\\t%Q0, %Q1\;sbcs\\t%2, %R0, %R1" 7337 "&& reload_completed" 7338 [(set (reg:CC CC_REGNUM) 7339 (compare:CC (match_dup 0) (match_dup 1))) 7340 (parallel [(set (reg:CC CC_REGNUM) 7341 (compare:CC (match_dup 3) (match_dup 4))) 7342 (set (match_dup 2) 7343 (minus:SI (match_dup 5) 7344 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))])] 7345 { 7346 operands[3] = gen_highpart (SImode, operands[0]); 7347 operands[0] = gen_lowpart (SImode, operands[0]); 7348 if (CONST_INT_P (operands[1])) 7349 { 7350 operands[4] = GEN_INT (~INTVAL (gen_highpart_mode (SImode, 7351 DImode, 7352 operands[1]))); 7353 operands[5] = gen_rtx_PLUS (SImode, operands[3], operands[4]); 7354 } 7355 else 7356 { 7357 operands[4] = gen_highpart (SImode, operands[1]); 7358 operands[5] = gen_rtx_MINUS (SImode, operands[3], operands[4]); 7359 } 7360 operands[1] = gen_lowpart (SImode, operands[1]); 7361 operands[2] = gen_lowpart (SImode, operands[2]); 7362 } 7363 [(set_attr "conds" "set") 7364 (set_attr "length" "8") 7365 (set_attr "type" "multiple")] 7366) 7367 7368(define_insn_and_split "*arm_cmpdi_unsigned" 7369 [(set (reg:CC_CZ CC_REGNUM) 7370 (compare:CC_CZ (match_operand:DI 0 "s_register_operand" "l,r,r,r") 7371 (match_operand:DI 1 "arm_di_operand" "Py,r,Di,rDi")))] 7372 7373 "TARGET_32BIT" 7374 "#" ; "cmp\\t%R0, %R1\;it eq\;cmpeq\\t%Q0, %Q1" 7375 "&& reload_completed" 7376 [(set (reg:CC CC_REGNUM) 7377 (compare:CC (match_dup 2) (match_dup 3))) 7378 (cond_exec (eq:SI (reg:CC CC_REGNUM) (const_int 0)) 7379 (set (reg:CC CC_REGNUM) 7380 (compare:CC (match_dup 0) (match_dup 1))))] 7381 { 7382 operands[2] = gen_highpart (SImode, operands[0]); 7383 operands[0] = gen_lowpart (SImode, operands[0]); 7384 if (CONST_INT_P (operands[1])) 7385 operands[3] = gen_highpart_mode (SImode, DImode, operands[1]); 7386 else 7387 operands[3] = gen_highpart (SImode, operands[1]); 7388 operands[1] = gen_lowpart (SImode, operands[1]); 7389 } 7390 [(set_attr "conds" "set") 7391 (set_attr "enabled_for_short_it" "yes,yes,no,*") 7392 (set_attr "arch" "t2,t2,t2,a") 7393 (set_attr "length" "6,6,10,8") 7394 (set_attr "type" "multiple")] 7395) 7396 7397(define_insn "*arm_cmpdi_zero" 7398 [(set (reg:CC_Z CC_REGNUM) 7399 (compare:CC_Z (match_operand:DI 0 "s_register_operand" "r") 7400 (const_int 0))) 7401 (clobber (match_scratch:SI 1 "=r"))] 7402 "TARGET_32BIT" 7403 "orrs%?\\t%1, %Q0, %R0" 7404 [(set_attr "conds" "set") 7405 (set_attr "type" "logics_reg")] 7406) 7407 7408; This insn allows redundant compares to be removed by cse, nothing should 7409; ever appear in the output file since (set (reg x) (reg x)) is a no-op that 7410; is deleted later on. The match_dup will match the mode here, so that 7411; mode changes of the condition codes aren't lost by this even though we don't 7412; specify what they are. 7413 7414(define_insn "*deleted_compare" 7415 [(set (match_operand 0 "cc_register" "") (match_dup 0))] 7416 "TARGET_32BIT" 7417 "\\t%@ deleted compare" 7418 [(set_attr "conds" "set") 7419 (set_attr "length" "0") 7420 (set_attr "type" "no_insn")] 7421) 7422 7423 7424;; Conditional branch insns 7425 7426(define_expand "cbranch_cc" 7427 [(set (pc) 7428 (if_then_else (match_operator 0 "" [(match_operand 1 "" "") 7429 (match_operand 2 "" "")]) 7430 (label_ref (match_operand 3 "" "")) 7431 (pc)))] 7432 "TARGET_32BIT" 7433 "operands[1] = arm_gen_compare_reg (GET_CODE (operands[0]), 7434 operands[1], operands[2], NULL_RTX); 7435 operands[2] = const0_rtx;" 7436) 7437 7438;; 7439;; Patterns to match conditional branch insns. 7440;; 7441 7442(define_insn "arm_cond_branch" 7443 [(set (pc) 7444 (if_then_else (match_operator 1 "arm_comparison_operator" 7445 [(match_operand 2 "cc_register" "") (const_int 0)]) 7446 (label_ref (match_operand 0 "" "")) 7447 (pc)))] 7448 "TARGET_32BIT" 7449 "* 7450 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 7451 { 7452 arm_ccfsm_state += 2; 7453 return \"\"; 7454 } 7455 return \"b%d1\\t%l0\"; 7456 " 7457 [(set_attr "conds" "use") 7458 (set_attr "type" "branch") 7459 (set (attr "length") 7460 (if_then_else 7461 (and (match_test "TARGET_THUMB2") 7462 (and (ge (minus (match_dup 0) (pc)) (const_int -250)) 7463 (le (minus (match_dup 0) (pc)) (const_int 256)))) 7464 (const_int 2) 7465 (const_int 4)))] 7466) 7467 7468(define_insn "*arm_cond_branch_reversed" 7469 [(set (pc) 7470 (if_then_else (match_operator 1 "arm_comparison_operator" 7471 [(match_operand 2 "cc_register" "") (const_int 0)]) 7472 (pc) 7473 (label_ref (match_operand 0 "" ""))))] 7474 "TARGET_32BIT" 7475 "* 7476 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 7477 { 7478 arm_ccfsm_state += 2; 7479 return \"\"; 7480 } 7481 return \"b%D1\\t%l0\"; 7482 " 7483 [(set_attr "conds" "use") 7484 (set_attr "type" "branch") 7485 (set (attr "length") 7486 (if_then_else 7487 (and (match_test "TARGET_THUMB2") 7488 (and (ge (minus (match_dup 0) (pc)) (const_int -250)) 7489 (le (minus (match_dup 0) (pc)) (const_int 256)))) 7490 (const_int 2) 7491 (const_int 4)))] 7492) 7493 7494 7495 7496; scc insns 7497 7498(define_expand "cstore_cc" 7499 [(set (match_operand:SI 0 "s_register_operand" "") 7500 (match_operator:SI 1 "" [(match_operand 2 "" "") 7501 (match_operand 3 "" "")]))] 7502 "TARGET_32BIT" 7503 "operands[2] = arm_gen_compare_reg (GET_CODE (operands[1]), 7504 operands[2], operands[3], NULL_RTX); 7505 operands[3] = const0_rtx;" 7506) 7507 7508(define_insn_and_split "*mov_scc" 7509 [(set (match_operand:SI 0 "s_register_operand" "=r") 7510 (match_operator:SI 1 "arm_comparison_operator_mode" 7511 [(match_operand 2 "cc_register" "") (const_int 0)]))] 7512 "TARGET_ARM" 7513 "#" ; "mov%D1\\t%0, #0\;mov%d1\\t%0, #1" 7514 "TARGET_ARM" 7515 [(set (match_dup 0) 7516 (if_then_else:SI (match_dup 1) 7517 (const_int 1) 7518 (const_int 0)))] 7519 "" 7520 [(set_attr "conds" "use") 7521 (set_attr "length" "8") 7522 (set_attr "type" "multiple")] 7523) 7524 7525(define_insn_and_split "*mov_negscc" 7526 [(set (match_operand:SI 0 "s_register_operand" "=r") 7527 (neg:SI (match_operator:SI 1 "arm_comparison_operator_mode" 7528 [(match_operand 2 "cc_register" "") (const_int 0)])))] 7529 "TARGET_ARM" 7530 "#" ; "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" 7531 "TARGET_ARM" 7532 [(set (match_dup 0) 7533 (if_then_else:SI (match_dup 1) 7534 (match_dup 3) 7535 (const_int 0)))] 7536 { 7537 operands[3] = GEN_INT (~0); 7538 } 7539 [(set_attr "conds" "use") 7540 (set_attr "length" "8") 7541 (set_attr "type" "multiple")] 7542) 7543 7544(define_insn_and_split "*mov_notscc" 7545 [(set (match_operand:SI 0 "s_register_operand" "=r") 7546 (not:SI (match_operator:SI 1 "arm_comparison_operator" 7547 [(match_operand 2 "cc_register" "") (const_int 0)])))] 7548 "TARGET_ARM" 7549 "#" ; "mvn%D1\\t%0, #0\;mvn%d1\\t%0, #1" 7550 "TARGET_ARM" 7551 [(set (match_dup 0) 7552 (if_then_else:SI (match_dup 1) 7553 (match_dup 3) 7554 (match_dup 4)))] 7555 { 7556 operands[3] = GEN_INT (~1); 7557 operands[4] = GEN_INT (~0); 7558 } 7559 [(set_attr "conds" "use") 7560 (set_attr "length" "8") 7561 (set_attr "type" "multiple")] 7562) 7563 7564(define_expand "cstoresi4" 7565 [(set (match_operand:SI 0 "s_register_operand" "") 7566 (match_operator:SI 1 "expandable_comparison_operator" 7567 [(match_operand:SI 2 "s_register_operand" "") 7568 (match_operand:SI 3 "reg_or_int_operand" "")]))] 7569 "TARGET_32BIT || TARGET_THUMB1" 7570 "{ 7571 rtx op3, scratch, scratch2; 7572 7573 if (!TARGET_THUMB1) 7574 { 7575 if (!arm_add_operand (operands[3], SImode)) 7576 operands[3] = force_reg (SImode, operands[3]); 7577 emit_insn (gen_cstore_cc (operands[0], operands[1], 7578 operands[2], operands[3])); 7579 DONE; 7580 } 7581 7582 if (operands[3] == const0_rtx) 7583 { 7584 switch (GET_CODE (operands[1])) 7585 { 7586 case EQ: 7587 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], operands[2])); 7588 break; 7589 7590 case NE: 7591 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], operands[2])); 7592 break; 7593 7594 case LE: 7595 scratch = expand_binop (SImode, add_optab, operands[2], constm1_rtx, 7596 NULL_RTX, 0, OPTAB_WIDEN); 7597 scratch = expand_binop (SImode, ior_optab, operands[2], scratch, 7598 NULL_RTX, 0, OPTAB_WIDEN); 7599 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), 7600 operands[0], 1, OPTAB_WIDEN); 7601 break; 7602 7603 case GE: 7604 scratch = expand_unop (SImode, one_cmpl_optab, operands[2], 7605 NULL_RTX, 1); 7606 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), 7607 NULL_RTX, 1, OPTAB_WIDEN); 7608 break; 7609 7610 case GT: 7611 scratch = expand_binop (SImode, ashr_optab, operands[2], 7612 GEN_INT (31), NULL_RTX, 0, OPTAB_WIDEN); 7613 scratch = expand_binop (SImode, sub_optab, scratch, operands[2], 7614 NULL_RTX, 0, OPTAB_WIDEN); 7615 expand_binop (SImode, lshr_optab, scratch, GEN_INT (31), operands[0], 7616 0, OPTAB_WIDEN); 7617 break; 7618 7619 /* LT is handled by generic code. No need for unsigned with 0. */ 7620 default: 7621 FAIL; 7622 } 7623 DONE; 7624 } 7625 7626 switch (GET_CODE (operands[1])) 7627 { 7628 case EQ: 7629 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3], 7630 NULL_RTX, 0, OPTAB_WIDEN); 7631 emit_insn (gen_cstoresi_eq0_thumb1 (operands[0], scratch)); 7632 break; 7633 7634 case NE: 7635 scratch = expand_binop (SImode, sub_optab, operands[2], operands[3], 7636 NULL_RTX, 0, OPTAB_WIDEN); 7637 emit_insn (gen_cstoresi_ne0_thumb1 (operands[0], scratch)); 7638 break; 7639 7640 case LE: 7641 op3 = force_reg (SImode, operands[3]); 7642 7643 scratch = expand_binop (SImode, lshr_optab, operands[2], GEN_INT (31), 7644 NULL_RTX, 1, OPTAB_WIDEN); 7645 scratch2 = expand_binop (SImode, ashr_optab, op3, GEN_INT (31), 7646 NULL_RTX, 0, OPTAB_WIDEN); 7647 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2, 7648 op3, operands[2])); 7649 break; 7650 7651 case GE: 7652 op3 = operands[3]; 7653 if (!thumb1_cmp_operand (op3, SImode)) 7654 op3 = force_reg (SImode, op3); 7655 scratch = expand_binop (SImode, ashr_optab, operands[2], GEN_INT (31), 7656 NULL_RTX, 0, OPTAB_WIDEN); 7657 scratch2 = expand_binop (SImode, lshr_optab, op3, GEN_INT (31), 7658 NULL_RTX, 1, OPTAB_WIDEN); 7659 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch2, 7660 operands[2], op3)); 7661 break; 7662 7663 case LEU: 7664 op3 = force_reg (SImode, operands[3]); 7665 scratch = force_reg (SImode, const0_rtx); 7666 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch, 7667 op3, operands[2])); 7668 break; 7669 7670 case GEU: 7671 op3 = operands[3]; 7672 if (!thumb1_cmp_operand (op3, SImode)) 7673 op3 = force_reg (SImode, op3); 7674 scratch = force_reg (SImode, const0_rtx); 7675 emit_insn (gen_thumb1_addsi3_addgeu (operands[0], scratch, scratch, 7676 operands[2], op3)); 7677 break; 7678 7679 case LTU: 7680 op3 = operands[3]; 7681 if (!thumb1_cmp_operand (op3, SImode)) 7682 op3 = force_reg (SImode, op3); 7683 scratch = gen_reg_rtx (SImode); 7684 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], operands[2], op3)); 7685 break; 7686 7687 case GTU: 7688 op3 = force_reg (SImode, operands[3]); 7689 scratch = gen_reg_rtx (SImode); 7690 emit_insn (gen_cstoresi_ltu_thumb1 (operands[0], op3, operands[2])); 7691 break; 7692 7693 /* No good sequences for GT, LT. */ 7694 default: 7695 FAIL; 7696 } 7697 DONE; 7698}") 7699 7700(define_expand "cstorehf4" 7701 [(set (match_operand:SI 0 "s_register_operand") 7702 (match_operator:SI 1 "expandable_comparison_operator" 7703 [(match_operand:HF 2 "s_register_operand") 7704 (match_operand:HF 3 "vfp_compare_operand")]))] 7705 "TARGET_VFP_FP16INST" 7706 { 7707 if (!arm_validize_comparison (&operands[1], 7708 &operands[2], 7709 &operands[3])) 7710 FAIL; 7711 7712 emit_insn (gen_cstore_cc (operands[0], operands[1], 7713 operands[2], operands[3])); 7714 DONE; 7715 } 7716) 7717 7718(define_expand "cstoresf4" 7719 [(set (match_operand:SI 0 "s_register_operand" "") 7720 (match_operator:SI 1 "expandable_comparison_operator" 7721 [(match_operand:SF 2 "s_register_operand" "") 7722 (match_operand:SF 3 "vfp_compare_operand" "")]))] 7723 "TARGET_32BIT && TARGET_HARD_FLOAT" 7724 "emit_insn (gen_cstore_cc (operands[0], operands[1], 7725 operands[2], operands[3])); DONE;" 7726) 7727 7728(define_expand "cstoredf4" 7729 [(set (match_operand:SI 0 "s_register_operand" "") 7730 (match_operator:SI 1 "expandable_comparison_operator" 7731 [(match_operand:DF 2 "s_register_operand" "") 7732 (match_operand:DF 3 "vfp_compare_operand" "")]))] 7733 "TARGET_32BIT && TARGET_HARD_FLOAT && !TARGET_VFP_SINGLE" 7734 "emit_insn (gen_cstore_cc (operands[0], operands[1], 7735 operands[2], operands[3])); DONE;" 7736) 7737 7738(define_expand "cstoredi4" 7739 [(set (match_operand:SI 0 "s_register_operand" "") 7740 (match_operator:SI 1 "expandable_comparison_operator" 7741 [(match_operand:DI 2 "s_register_operand" "") 7742 (match_operand:DI 3 "cmpdi_operand" "")]))] 7743 "TARGET_32BIT" 7744 "{ 7745 if (!arm_validize_comparison (&operands[1], 7746 &operands[2], 7747 &operands[3])) 7748 FAIL; 7749 emit_insn (gen_cstore_cc (operands[0], operands[1], operands[2], 7750 operands[3])); 7751 DONE; 7752 }" 7753) 7754 7755 7756;; Conditional move insns 7757 7758(define_expand "movsicc" 7759 [(set (match_operand:SI 0 "s_register_operand" "") 7760 (if_then_else:SI (match_operand 1 "expandable_comparison_operator" "") 7761 (match_operand:SI 2 "arm_not_operand" "") 7762 (match_operand:SI 3 "arm_not_operand" "")))] 7763 "TARGET_32BIT" 7764 " 7765 { 7766 enum rtx_code code; 7767 rtx ccreg; 7768 7769 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7770 &XEXP (operands[1], 1))) 7771 FAIL; 7772 7773 code = GET_CODE (operands[1]); 7774 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7775 XEXP (operands[1], 1), NULL_RTX); 7776 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7777 }" 7778) 7779 7780(define_expand "movhfcc" 7781 [(set (match_operand:HF 0 "s_register_operand") 7782 (if_then_else:HF (match_operand 1 "arm_cond_move_operator") 7783 (match_operand:HF 2 "s_register_operand") 7784 (match_operand:HF 3 "s_register_operand")))] 7785 "TARGET_VFP_FP16INST" 7786 " 7787 { 7788 enum rtx_code code = GET_CODE (operands[1]); 7789 rtx ccreg; 7790 7791 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7792 &XEXP (operands[1], 1))) 7793 FAIL; 7794 7795 code = GET_CODE (operands[1]); 7796 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7797 XEXP (operands[1], 1), NULL_RTX); 7798 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7799 }" 7800) 7801 7802(define_expand "movsfcc" 7803 [(set (match_operand:SF 0 "s_register_operand" "") 7804 (if_then_else:SF (match_operand 1 "arm_cond_move_operator" "") 7805 (match_operand:SF 2 "s_register_operand" "") 7806 (match_operand:SF 3 "s_register_operand" "")))] 7807 "TARGET_32BIT && TARGET_HARD_FLOAT" 7808 " 7809 { 7810 enum rtx_code code = GET_CODE (operands[1]); 7811 rtx ccreg; 7812 7813 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7814 &XEXP (operands[1], 1))) 7815 FAIL; 7816 7817 code = GET_CODE (operands[1]); 7818 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7819 XEXP (operands[1], 1), NULL_RTX); 7820 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7821 }" 7822) 7823 7824(define_expand "movdfcc" 7825 [(set (match_operand:DF 0 "s_register_operand" "") 7826 (if_then_else:DF (match_operand 1 "arm_cond_move_operator" "") 7827 (match_operand:DF 2 "s_register_operand" "") 7828 (match_operand:DF 3 "s_register_operand" "")))] 7829 "TARGET_32BIT && TARGET_HARD_FLOAT && TARGET_VFP_DOUBLE" 7830 " 7831 { 7832 enum rtx_code code = GET_CODE (operands[1]); 7833 rtx ccreg; 7834 7835 if (!arm_validize_comparison (&operands[1], &XEXP (operands[1], 0), 7836 &XEXP (operands[1], 1))) 7837 FAIL; 7838 code = GET_CODE (operands[1]); 7839 ccreg = arm_gen_compare_reg (code, XEXP (operands[1], 0), 7840 XEXP (operands[1], 1), NULL_RTX); 7841 operands[1] = gen_rtx_fmt_ee (code, VOIDmode, ccreg, const0_rtx); 7842 }" 7843) 7844 7845(define_insn "*cmov<mode>" 7846 [(set (match_operand:SDF 0 "s_register_operand" "=<F_constraint>") 7847 (if_then_else:SDF (match_operator 1 "arm_vsel_comparison_operator" 7848 [(match_operand 2 "cc_register" "") (const_int 0)]) 7849 (match_operand:SDF 3 "s_register_operand" 7850 "<F_constraint>") 7851 (match_operand:SDF 4 "s_register_operand" 7852 "<F_constraint>")))] 7853 "TARGET_HARD_FLOAT && TARGET_VFP5 <vfp_double_cond>" 7854 "* 7855 { 7856 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]); 7857 switch (code) 7858 { 7859 case ARM_GE: 7860 case ARM_GT: 7861 case ARM_EQ: 7862 case ARM_VS: 7863 return \"vsel%d1.<V_if_elem>\\t%<V_reg>0, %<V_reg>3, %<V_reg>4\"; 7864 case ARM_LT: 7865 case ARM_LE: 7866 case ARM_NE: 7867 case ARM_VC: 7868 return \"vsel%D1.<V_if_elem>\\t%<V_reg>0, %<V_reg>4, %<V_reg>3\"; 7869 default: 7870 gcc_unreachable (); 7871 } 7872 return \"\"; 7873 }" 7874 [(set_attr "conds" "use") 7875 (set_attr "type" "fcsel")] 7876) 7877 7878(define_insn "*cmovhf" 7879 [(set (match_operand:HF 0 "s_register_operand" "=t") 7880 (if_then_else:HF (match_operator 1 "arm_vsel_comparison_operator" 7881 [(match_operand 2 "cc_register" "") (const_int 0)]) 7882 (match_operand:HF 3 "s_register_operand" "t") 7883 (match_operand:HF 4 "s_register_operand" "t")))] 7884 "TARGET_VFP_FP16INST" 7885 "* 7886 { 7887 enum arm_cond_code code = maybe_get_arm_condition_code (operands[1]); 7888 switch (code) 7889 { 7890 case ARM_GE: 7891 case ARM_GT: 7892 case ARM_EQ: 7893 case ARM_VS: 7894 return \"vsel%d1.f16\\t%0, %3, %4\"; 7895 case ARM_LT: 7896 case ARM_LE: 7897 case ARM_NE: 7898 case ARM_VC: 7899 return \"vsel%D1.f16\\t%0, %4, %3\"; 7900 default: 7901 gcc_unreachable (); 7902 } 7903 return \"\"; 7904 }" 7905 [(set_attr "conds" "use") 7906 (set_attr "type" "fcsel")] 7907) 7908 7909(define_insn_and_split "*movsicc_insn" 7910 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") 7911 (if_then_else:SI 7912 (match_operator 3 "arm_comparison_operator" 7913 [(match_operand 4 "cc_register" "") (const_int 0)]) 7914 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K") 7915 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))] 7916 "TARGET_ARM" 7917 "@ 7918 mov%D3\\t%0, %2 7919 mvn%D3\\t%0, #%B2 7920 mov%d3\\t%0, %1 7921 mvn%d3\\t%0, #%B1 7922 # 7923 # 7924 # 7925 #" 7926 ; alt4: mov%d3\\t%0, %1\;mov%D3\\t%0, %2 7927 ; alt5: mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 7928 ; alt6: mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 7929 ; alt7: mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2" 7930 "&& reload_completed" 7931 [(const_int 0)] 7932 { 7933 enum rtx_code rev_code; 7934 machine_mode mode; 7935 rtx rev_cond; 7936 7937 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 7938 operands[3], 7939 gen_rtx_SET (operands[0], operands[1]))); 7940 7941 rev_code = GET_CODE (operands[3]); 7942 mode = GET_MODE (operands[4]); 7943 if (mode == CCFPmode || mode == CCFPEmode) 7944 rev_code = reverse_condition_maybe_unordered (rev_code); 7945 else 7946 rev_code = reverse_condition (rev_code); 7947 7948 rev_cond = gen_rtx_fmt_ee (rev_code, 7949 VOIDmode, 7950 operands[4], 7951 const0_rtx); 7952 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 7953 rev_cond, 7954 gen_rtx_SET (operands[0], operands[2]))); 7955 DONE; 7956 } 7957 [(set_attr "length" "4,4,4,4,8,8,8,8") 7958 (set_attr "conds" "use") 7959 (set_attr_alternative "type" 7960 [(if_then_else (match_operand 2 "const_int_operand" "") 7961 (const_string "mov_imm") 7962 (const_string "mov_reg")) 7963 (const_string "mvn_imm") 7964 (if_then_else (match_operand 1 "const_int_operand" "") 7965 (const_string "mov_imm") 7966 (const_string "mov_reg")) 7967 (const_string "mvn_imm") 7968 (const_string "multiple") 7969 (const_string "multiple") 7970 (const_string "multiple") 7971 (const_string "multiple")])] 7972) 7973 7974(define_insn "*movsfcc_soft_insn" 7975 [(set (match_operand:SF 0 "s_register_operand" "=r,r") 7976 (if_then_else:SF (match_operator 3 "arm_comparison_operator" 7977 [(match_operand 4 "cc_register" "") (const_int 0)]) 7978 (match_operand:SF 1 "s_register_operand" "0,r") 7979 (match_operand:SF 2 "s_register_operand" "r,0")))] 7980 "TARGET_ARM && TARGET_SOFT_FLOAT" 7981 "@ 7982 mov%D3\\t%0, %2 7983 mov%d3\\t%0, %1" 7984 [(set_attr "conds" "use") 7985 (set_attr "type" "mov_reg")] 7986) 7987 7988 7989;; Jump and linkage insns 7990 7991(define_expand "jump" 7992 [(set (pc) 7993 (label_ref (match_operand 0 "" "")))] 7994 "TARGET_EITHER" 7995 "" 7996) 7997 7998(define_insn "*arm_jump" 7999 [(set (pc) 8000 (label_ref (match_operand 0 "" "")))] 8001 "TARGET_32BIT" 8002 "* 8003 { 8004 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 8005 { 8006 arm_ccfsm_state += 2; 8007 return \"\"; 8008 } 8009 return \"b%?\\t%l0\"; 8010 } 8011 " 8012 [(set_attr "predicable" "yes") 8013 (set (attr "length") 8014 (if_then_else 8015 (and (match_test "TARGET_THUMB2") 8016 (and (ge (minus (match_dup 0) (pc)) (const_int -2044)) 8017 (le (minus (match_dup 0) (pc)) (const_int 2048)))) 8018 (const_int 2) 8019 (const_int 4))) 8020 (set_attr "type" "branch")] 8021) 8022 8023(define_expand "call" 8024 [(parallel [(call (match_operand 0 "memory_operand" "") 8025 (match_operand 1 "general_operand" "")) 8026 (use (match_operand 2 "" "")) 8027 (clobber (reg:SI LR_REGNUM))])] 8028 "TARGET_EITHER" 8029 " 8030 { 8031 rtx callee, pat; 8032 tree addr = MEM_EXPR (operands[0]); 8033 8034 /* In an untyped call, we can get NULL for operand 2. */ 8035 if (operands[2] == NULL_RTX) 8036 operands[2] = const0_rtx; 8037 8038 /* Decide if we should generate indirect calls by loading the 8039 32-bit address of the callee into a register before performing the 8040 branch and link. */ 8041 callee = XEXP (operands[0], 0); 8042 if (GET_CODE (callee) == SYMBOL_REF 8043 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee)) 8044 : !REG_P (callee)) 8045 XEXP (operands[0], 0) = force_reg (Pmode, callee); 8046 8047 if (detect_cmse_nonsecure_call (addr)) 8048 { 8049 pat = gen_nonsecure_call_internal (operands[0], operands[1], 8050 operands[2]); 8051 emit_call_insn (pat); 8052 } 8053 else 8054 { 8055 pat = gen_call_internal (operands[0], operands[1], operands[2]); 8056 arm_emit_call_insn (pat, XEXP (operands[0], 0), false); 8057 } 8058 DONE; 8059 }" 8060) 8061 8062(define_expand "call_internal" 8063 [(parallel [(call (match_operand 0 "memory_operand" "") 8064 (match_operand 1 "general_operand" "")) 8065 (use (match_operand 2 "" "")) 8066 (clobber (reg:SI LR_REGNUM))])]) 8067 8068(define_expand "nonsecure_call_internal" 8069 [(parallel [(call (unspec:SI [(match_operand 0 "memory_operand" "")] 8070 UNSPEC_NONSECURE_MEM) 8071 (match_operand 1 "general_operand" "")) 8072 (use (match_operand 2 "" "")) 8073 (clobber (reg:SI LR_REGNUM))])] 8074 "use_cmse" 8075 " 8076 { 8077 rtx tmp; 8078 tmp = copy_to_suggested_reg (XEXP (operands[0], 0), 8079 gen_rtx_REG (SImode, R4_REGNUM), 8080 SImode); 8081 8082 operands[0] = replace_equiv_address (operands[0], tmp); 8083 }") 8084 8085(define_insn "*call_reg_armv5" 8086 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) 8087 (match_operand 1 "" "")) 8088 (use (match_operand 2 "" "")) 8089 (clobber (reg:SI LR_REGNUM))] 8090 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)" 8091 "blx%?\\t%0" 8092 [(set_attr "type" "call")] 8093) 8094 8095(define_insn "*call_reg_arm" 8096 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) 8097 (match_operand 1 "" "")) 8098 (use (match_operand 2 "" "")) 8099 (clobber (reg:SI LR_REGNUM))] 8100 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)" 8101 "* 8102 return output_call (operands); 8103 " 8104 ;; length is worst case, normally it is only two 8105 [(set_attr "length" "12") 8106 (set_attr "type" "call")] 8107) 8108 8109 8110(define_expand "call_value" 8111 [(parallel [(set (match_operand 0 "" "") 8112 (call (match_operand 1 "memory_operand" "") 8113 (match_operand 2 "general_operand" ""))) 8114 (use (match_operand 3 "" "")) 8115 (clobber (reg:SI LR_REGNUM))])] 8116 "TARGET_EITHER" 8117 " 8118 { 8119 rtx pat, callee; 8120 tree addr = MEM_EXPR (operands[1]); 8121 8122 /* In an untyped call, we can get NULL for operand 2. */ 8123 if (operands[3] == 0) 8124 operands[3] = const0_rtx; 8125 8126 /* Decide if we should generate indirect calls by loading the 8127 32-bit address of the callee into a register before performing the 8128 branch and link. */ 8129 callee = XEXP (operands[1], 0); 8130 if (GET_CODE (callee) == SYMBOL_REF 8131 ? arm_is_long_call_p (SYMBOL_REF_DECL (callee)) 8132 : !REG_P (callee)) 8133 XEXP (operands[1], 0) = force_reg (Pmode, callee); 8134 8135 if (detect_cmse_nonsecure_call (addr)) 8136 { 8137 pat = gen_nonsecure_call_value_internal (operands[0], operands[1], 8138 operands[2], operands[3]); 8139 emit_call_insn (pat); 8140 } 8141 else 8142 { 8143 pat = gen_call_value_internal (operands[0], operands[1], 8144 operands[2], operands[3]); 8145 arm_emit_call_insn (pat, XEXP (operands[1], 0), false); 8146 } 8147 DONE; 8148 }" 8149) 8150 8151(define_expand "call_value_internal" 8152 [(parallel [(set (match_operand 0 "" "") 8153 (call (match_operand 1 "memory_operand" "") 8154 (match_operand 2 "general_operand" ""))) 8155 (use (match_operand 3 "" "")) 8156 (clobber (reg:SI LR_REGNUM))])]) 8157 8158(define_expand "nonsecure_call_value_internal" 8159 [(parallel [(set (match_operand 0 "" "") 8160 (call (unspec:SI [(match_operand 1 "memory_operand" "")] 8161 UNSPEC_NONSECURE_MEM) 8162 (match_operand 2 "general_operand" ""))) 8163 (use (match_operand 3 "" "")) 8164 (clobber (reg:SI LR_REGNUM))])] 8165 "use_cmse" 8166 " 8167 { 8168 rtx tmp; 8169 tmp = copy_to_suggested_reg (XEXP (operands[1], 0), 8170 gen_rtx_REG (SImode, R4_REGNUM), 8171 SImode); 8172 8173 operands[1] = replace_equiv_address (operands[1], tmp); 8174 }") 8175 8176(define_insn "*call_value_reg_armv5" 8177 [(set (match_operand 0 "" "") 8178 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r")) 8179 (match_operand 2 "" ""))) 8180 (use (match_operand 3 "" "")) 8181 (clobber (reg:SI LR_REGNUM))] 8182 "TARGET_ARM && arm_arch5 && !SIBLING_CALL_P (insn)" 8183 "blx%?\\t%1" 8184 [(set_attr "type" "call")] 8185) 8186 8187(define_insn "*call_value_reg_arm" 8188 [(set (match_operand 0 "" "") 8189 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r")) 8190 (match_operand 2 "" ""))) 8191 (use (match_operand 3 "" "")) 8192 (clobber (reg:SI LR_REGNUM))] 8193 "TARGET_ARM && !arm_arch5 && !SIBLING_CALL_P (insn)" 8194 "* 8195 return output_call (&operands[1]); 8196 " 8197 [(set_attr "length" "12") 8198 (set_attr "type" "call")] 8199) 8200 8201;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses 8202;; The 'a' causes the operand to be treated as an address, i.e. no '#' output. 8203 8204(define_insn "*call_symbol" 8205 [(call (mem:SI (match_operand:SI 0 "" "")) 8206 (match_operand 1 "" "")) 8207 (use (match_operand 2 "" "")) 8208 (clobber (reg:SI LR_REGNUM))] 8209 "TARGET_32BIT 8210 && !SIBLING_CALL_P (insn) 8211 && (GET_CODE (operands[0]) == SYMBOL_REF) 8212 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[0]))" 8213 "* 8214 { 8215 rtx op = operands[0]; 8216 8217 /* Switch mode now when possible. */ 8218 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op)) 8219 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op))) 8220 return NEED_PLT_RELOC ? \"blx%?\\t%a0(PLT)\" : \"blx%?\\t(%a0)\"; 8221 8222 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\"; 8223 }" 8224 [(set_attr "type" "call")] 8225) 8226 8227(define_insn "*call_value_symbol" 8228 [(set (match_operand 0 "" "") 8229 (call (mem:SI (match_operand:SI 1 "" "")) 8230 (match_operand:SI 2 "" ""))) 8231 (use (match_operand 3 "" "")) 8232 (clobber (reg:SI LR_REGNUM))] 8233 "TARGET_32BIT 8234 && !SIBLING_CALL_P (insn) 8235 && (GET_CODE (operands[1]) == SYMBOL_REF) 8236 && !arm_is_long_call_p (SYMBOL_REF_DECL (operands[1]))" 8237 "* 8238 { 8239 rtx op = operands[1]; 8240 8241 /* Switch mode now when possible. */ 8242 if (SYMBOL_REF_DECL (op) && !TREE_PUBLIC (SYMBOL_REF_DECL (op)) 8243 && arm_arch5 && arm_change_mode_p (SYMBOL_REF_DECL (op))) 8244 return NEED_PLT_RELOC ? \"blx%?\\t%a1(PLT)\" : \"blx%?\\t(%a1)\"; 8245 8246 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\"; 8247 }" 8248 [(set_attr "type" "call")] 8249) 8250 8251(define_expand "sibcall_internal" 8252 [(parallel [(call (match_operand 0 "memory_operand" "") 8253 (match_operand 1 "general_operand" "")) 8254 (return) 8255 (use (match_operand 2 "" ""))])]) 8256 8257;; We may also be able to do sibcalls for Thumb, but it's much harder... 8258(define_expand "sibcall" 8259 [(parallel [(call (match_operand 0 "memory_operand" "") 8260 (match_operand 1 "general_operand" "")) 8261 (return) 8262 (use (match_operand 2 "" ""))])] 8263 "TARGET_32BIT" 8264 " 8265 { 8266 rtx pat; 8267 8268 if ((!REG_P (XEXP (operands[0], 0)) 8269 && GET_CODE (XEXP (operands[0], 0)) != SYMBOL_REF) 8270 || (GET_CODE (XEXP (operands[0], 0)) == SYMBOL_REF 8271 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[0], 0))))) 8272 XEXP (operands[0], 0) = force_reg (SImode, XEXP (operands[0], 0)); 8273 8274 if (operands[2] == NULL_RTX) 8275 operands[2] = const0_rtx; 8276 8277 pat = gen_sibcall_internal (operands[0], operands[1], operands[2]); 8278 arm_emit_call_insn (pat, operands[0], true); 8279 DONE; 8280 }" 8281) 8282 8283(define_expand "sibcall_value_internal" 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 8290(define_expand "sibcall_value" 8291 [(parallel [(set (match_operand 0 "" "") 8292 (call (match_operand 1 "memory_operand" "") 8293 (match_operand 2 "general_operand" ""))) 8294 (return) 8295 (use (match_operand 3 "" ""))])] 8296 "TARGET_32BIT" 8297 " 8298 { 8299 rtx pat; 8300 8301 if ((!REG_P (XEXP (operands[1], 0)) 8302 && GET_CODE (XEXP (operands[1], 0)) != SYMBOL_REF) 8303 || (GET_CODE (XEXP (operands[1], 0)) == SYMBOL_REF 8304 && arm_is_long_call_p (SYMBOL_REF_DECL (XEXP (operands[1], 0))))) 8305 XEXP (operands[1], 0) = force_reg (SImode, XEXP (operands[1], 0)); 8306 8307 if (operands[3] == NULL_RTX) 8308 operands[3] = const0_rtx; 8309 8310 pat = gen_sibcall_value_internal (operands[0], operands[1], 8311 operands[2], operands[3]); 8312 arm_emit_call_insn (pat, operands[1], true); 8313 DONE; 8314 }" 8315) 8316 8317(define_insn "*sibcall_insn" 8318 [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs, US")) 8319 (match_operand 1 "" "")) 8320 (return) 8321 (use (match_operand 2 "" ""))] 8322 "TARGET_32BIT && SIBLING_CALL_P (insn)" 8323 "* 8324 if (which_alternative == 1) 8325 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\"; 8326 else 8327 { 8328 if (arm_arch5 || arm_arch4t) 8329 return \"bx%?\\t%0\\t%@ indirect register sibling call\"; 8330 else 8331 return \"mov%?\\t%|pc, %0\\t%@ indirect register sibling call\"; 8332 } 8333 " 8334 [(set_attr "type" "call")] 8335) 8336 8337(define_insn "*sibcall_value_insn" 8338 [(set (match_operand 0 "" "") 8339 (call (mem:SI (match_operand:SI 1 "call_insn_operand" "Cs,US")) 8340 (match_operand 2 "" ""))) 8341 (return) 8342 (use (match_operand 3 "" ""))] 8343 "TARGET_32BIT && SIBLING_CALL_P (insn)" 8344 "* 8345 if (which_alternative == 1) 8346 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\"; 8347 else 8348 { 8349 if (arm_arch5 || arm_arch4t) 8350 return \"bx%?\\t%1\"; 8351 else 8352 return \"mov%?\\t%|pc, %1\\t@ indirect sibling call \"; 8353 } 8354 " 8355 [(set_attr "type" "call")] 8356) 8357 8358(define_expand "<return_str>return" 8359 [(RETURNS)] 8360 "(TARGET_ARM || (TARGET_THUMB2 8361 && ARM_FUNC_TYPE (arm_current_func_type ()) == ARM_FT_NORMAL 8362 && !IS_STACKALIGN (arm_current_func_type ()))) 8363 <return_cond_false>" 8364 " 8365 { 8366 if (TARGET_THUMB2) 8367 { 8368 thumb2_expand_return (<return_simple_p>); 8369 DONE; 8370 } 8371 } 8372 " 8373) 8374 8375;; Often the return insn will be the same as loading from memory, so set attr 8376(define_insn "*arm_return" 8377 [(return)] 8378 "TARGET_ARM && USE_RETURN_INSN (FALSE)" 8379 "* 8380 { 8381 if (arm_ccfsm_state == 2) 8382 { 8383 arm_ccfsm_state += 2; 8384 return \"\"; 8385 } 8386 return output_return_instruction (const_true_rtx, true, false, false); 8387 }" 8388 [(set_attr "type" "load_4") 8389 (set_attr "length" "12") 8390 (set_attr "predicable" "yes")] 8391) 8392 8393(define_insn "*cond_<return_str>return" 8394 [(set (pc) 8395 (if_then_else (match_operator 0 "arm_comparison_operator" 8396 [(match_operand 1 "cc_register" "") (const_int 0)]) 8397 (RETURNS) 8398 (pc)))] 8399 "TARGET_ARM <return_cond_true>" 8400 "* 8401 { 8402 if (arm_ccfsm_state == 2) 8403 { 8404 arm_ccfsm_state += 2; 8405 return \"\"; 8406 } 8407 return output_return_instruction (operands[0], true, false, 8408 <return_simple_p>); 8409 }" 8410 [(set_attr "conds" "use") 8411 (set_attr "length" "12") 8412 (set_attr "type" "load_4")] 8413) 8414 8415(define_insn "*cond_<return_str>return_inverted" 8416 [(set (pc) 8417 (if_then_else (match_operator 0 "arm_comparison_operator" 8418 [(match_operand 1 "cc_register" "") (const_int 0)]) 8419 (pc) 8420 (RETURNS)))] 8421 "TARGET_ARM <return_cond_true>" 8422 "* 8423 { 8424 if (arm_ccfsm_state == 2) 8425 { 8426 arm_ccfsm_state += 2; 8427 return \"\"; 8428 } 8429 return output_return_instruction (operands[0], true, true, 8430 <return_simple_p>); 8431 }" 8432 [(set_attr "conds" "use") 8433 (set_attr "length" "12") 8434 (set_attr "type" "load_4")] 8435) 8436 8437(define_insn "*arm_simple_return" 8438 [(simple_return)] 8439 "TARGET_ARM" 8440 "* 8441 { 8442 if (arm_ccfsm_state == 2) 8443 { 8444 arm_ccfsm_state += 2; 8445 return \"\"; 8446 } 8447 return output_return_instruction (const_true_rtx, true, false, true); 8448 }" 8449 [(set_attr "type" "branch") 8450 (set_attr "length" "4") 8451 (set_attr "predicable" "yes")] 8452) 8453 8454;; Generate a sequence of instructions to determine if the processor is 8455;; in 26-bit or 32-bit mode, and return the appropriate return address 8456;; mask. 8457 8458(define_expand "return_addr_mask" 8459 [(set (match_dup 1) 8460 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH) 8461 (const_int 0))) 8462 (set (match_operand:SI 0 "s_register_operand" "") 8463 (if_then_else:SI (eq (match_dup 1) (const_int 0)) 8464 (const_int -1) 8465 (const_int 67108860)))] ; 0x03fffffc 8466 "TARGET_ARM" 8467 " 8468 operands[1] = gen_rtx_REG (CC_NOOVmode, CC_REGNUM); 8469 ") 8470 8471(define_insn "*check_arch2" 8472 [(set (match_operand:CC_NOOV 0 "cc_register" "") 8473 (compare:CC_NOOV (unspec [(const_int 0)] UNSPEC_CHECK_ARCH) 8474 (const_int 0)))] 8475 "TARGET_ARM" 8476 "teq\\t%|r0, %|r0\;teq\\t%|pc, %|pc" 8477 [(set_attr "length" "8") 8478 (set_attr "conds" "set") 8479 (set_attr "type" "multiple")] 8480) 8481 8482;; Call subroutine returning any type. 8483 8484(define_expand "untyped_call" 8485 [(parallel [(call (match_operand 0 "" "") 8486 (const_int 0)) 8487 (match_operand 1 "" "") 8488 (match_operand 2 "" "")])] 8489 "TARGET_EITHER" 8490 " 8491 { 8492 int i; 8493 rtx par = gen_rtx_PARALLEL (VOIDmode, 8494 rtvec_alloc (XVECLEN (operands[2], 0))); 8495 rtx addr = gen_reg_rtx (Pmode); 8496 rtx mem; 8497 int size = 0; 8498 8499 emit_move_insn (addr, XEXP (operands[1], 0)); 8500 mem = change_address (operands[1], BLKmode, addr); 8501 8502 for (i = 0; i < XVECLEN (operands[2], 0); i++) 8503 { 8504 rtx src = SET_SRC (XVECEXP (operands[2], 0, i)); 8505 8506 /* Default code only uses r0 as a return value, but we could 8507 be using anything up to 4 registers. */ 8508 if (REGNO (src) == R0_REGNUM) 8509 src = gen_rtx_REG (TImode, R0_REGNUM); 8510 8511 XVECEXP (par, 0, i) = gen_rtx_EXPR_LIST (VOIDmode, src, 8512 GEN_INT (size)); 8513 size += GET_MODE_SIZE (GET_MODE (src)); 8514 } 8515 8516 emit_call_insn (gen_call_value (par, operands[0], const0_rtx, NULL)); 8517 8518 size = 0; 8519 8520 for (i = 0; i < XVECLEN (par, 0); i++) 8521 { 8522 HOST_WIDE_INT offset = 0; 8523 rtx reg = XEXP (XVECEXP (par, 0, i), 0); 8524 8525 if (size != 0) 8526 emit_move_insn (addr, plus_constant (Pmode, addr, size)); 8527 8528 mem = change_address (mem, GET_MODE (reg), NULL); 8529 if (REGNO (reg) == R0_REGNUM) 8530 { 8531 /* On thumb we have to use a write-back instruction. */ 8532 emit_insn (arm_gen_store_multiple (arm_regs_in_sequence, 4, addr, 8533 TARGET_THUMB ? TRUE : FALSE, mem, &offset)); 8534 size = TARGET_ARM ? 16 : 0; 8535 } 8536 else 8537 { 8538 emit_move_insn (mem, reg); 8539 size = GET_MODE_SIZE (GET_MODE (reg)); 8540 } 8541 } 8542 8543 /* The optimizer does not know that the call sets the function value 8544 registers we stored in the result block. We avoid problems by 8545 claiming that all hard registers are used and clobbered at this 8546 point. */ 8547 emit_insn (gen_blockage ()); 8548 8549 DONE; 8550 }" 8551) 8552 8553(define_expand "untyped_return" 8554 [(match_operand:BLK 0 "memory_operand" "") 8555 (match_operand 1 "" "")] 8556 "TARGET_EITHER" 8557 " 8558 { 8559 int i; 8560 rtx addr = gen_reg_rtx (Pmode); 8561 rtx mem; 8562 int size = 0; 8563 8564 emit_move_insn (addr, XEXP (operands[0], 0)); 8565 mem = change_address (operands[0], BLKmode, addr); 8566 8567 for (i = 0; i < XVECLEN (operands[1], 0); i++) 8568 { 8569 HOST_WIDE_INT offset = 0; 8570 rtx reg = SET_DEST (XVECEXP (operands[1], 0, i)); 8571 8572 if (size != 0) 8573 emit_move_insn (addr, plus_constant (Pmode, addr, size)); 8574 8575 mem = change_address (mem, GET_MODE (reg), NULL); 8576 if (REGNO (reg) == R0_REGNUM) 8577 { 8578 /* On thumb we have to use a write-back instruction. */ 8579 emit_insn (arm_gen_load_multiple (arm_regs_in_sequence, 4, addr, 8580 TARGET_THUMB ? TRUE : FALSE, mem, &offset)); 8581 size = TARGET_ARM ? 16 : 0; 8582 } 8583 else 8584 { 8585 emit_move_insn (reg, mem); 8586 size = GET_MODE_SIZE (GET_MODE (reg)); 8587 } 8588 } 8589 8590 /* Emit USE insns before the return. */ 8591 for (i = 0; i < XVECLEN (operands[1], 0); i++) 8592 emit_use (SET_DEST (XVECEXP (operands[1], 0, i))); 8593 8594 /* Construct the return. */ 8595 expand_naked_return (); 8596 8597 DONE; 8598 }" 8599) 8600 8601;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 8602;; all of memory. This blocks insns from being moved across this point. 8603 8604(define_insn "blockage" 8605 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)] 8606 "TARGET_EITHER" 8607 "" 8608 [(set_attr "length" "0") 8609 (set_attr "type" "block")] 8610) 8611 8612;; Since we hard code r0 here use the 'o' constraint to prevent 8613;; provoking undefined behaviour in the hardware with putting out 8614;; auto-increment operations with potentially r0 as the base register. 8615(define_insn "probe_stack" 8616 [(set (match_operand:SI 0 "memory_operand" "=o") 8617 (unspec:SI [(const_int 0)] UNSPEC_PROBE_STACK))] 8618 "TARGET_32BIT" 8619 "str%?\\tr0, %0" 8620 [(set_attr "type" "store_4") 8621 (set_attr "predicable" "yes")] 8622) 8623 8624(define_insn "probe_stack_range" 8625 [(set (match_operand:SI 0 "register_operand" "=r") 8626 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0") 8627 (match_operand:SI 2 "register_operand" "r")] 8628 VUNSPEC_PROBE_STACK_RANGE))] 8629 "TARGET_32BIT" 8630{ 8631 return output_probe_stack_range (operands[0], operands[2]); 8632} 8633 [(set_attr "type" "multiple") 8634 (set_attr "conds" "clob")] 8635) 8636 8637(define_expand "casesi" 8638 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on 8639 (match_operand:SI 1 "const_int_operand" "") ; lower bound 8640 (match_operand:SI 2 "const_int_operand" "") ; total range 8641 (match_operand:SI 3 "" "") ; table label 8642 (match_operand:SI 4 "" "")] ; Out of range label 8643 "(TARGET_32BIT || optimize_size || flag_pic) && !target_pure_code" 8644 " 8645 { 8646 enum insn_code code; 8647 if (operands[1] != const0_rtx) 8648 { 8649 rtx reg = gen_reg_rtx (SImode); 8650 8651 emit_insn (gen_addsi3 (reg, operands[0], 8652 gen_int_mode (-INTVAL (operands[1]), 8653 SImode))); 8654 operands[0] = reg; 8655 } 8656 8657 if (TARGET_ARM) 8658 code = CODE_FOR_arm_casesi_internal; 8659 else if (TARGET_THUMB1) 8660 code = CODE_FOR_thumb1_casesi_internal_pic; 8661 else if (flag_pic) 8662 code = CODE_FOR_thumb2_casesi_internal_pic; 8663 else 8664 code = CODE_FOR_thumb2_casesi_internal; 8665 8666 if (!insn_data[(int) code].operand[1].predicate(operands[2], SImode)) 8667 operands[2] = force_reg (SImode, operands[2]); 8668 8669 emit_jump_insn (GEN_FCN ((int) code) (operands[0], operands[2], 8670 operands[3], operands[4])); 8671 DONE; 8672 }" 8673) 8674 8675;; The USE in this pattern is needed to tell flow analysis that this is 8676;; a CASESI insn. It has no other purpose. 8677(define_insn "arm_casesi_internal" 8678 [(parallel [(set (pc) 8679 (if_then_else 8680 (leu (match_operand:SI 0 "s_register_operand" "r") 8681 (match_operand:SI 1 "arm_rhs_operand" "rI")) 8682 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) 8683 (label_ref (match_operand 2 "" "")))) 8684 (label_ref (match_operand 3 "" "")))) 8685 (clobber (reg:CC CC_REGNUM)) 8686 (use (label_ref (match_dup 2)))])] 8687 "TARGET_ARM" 8688 "* 8689 if (flag_pic) 8690 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\"; 8691 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\"; 8692 " 8693 [(set_attr "conds" "clob") 8694 (set_attr "length" "12") 8695 (set_attr "type" "multiple")] 8696) 8697 8698(define_expand "indirect_jump" 8699 [(set (pc) 8700 (match_operand:SI 0 "s_register_operand" ""))] 8701 "TARGET_EITHER" 8702 " 8703 /* Thumb-2 doesn't have mov pc, reg. Explicitly set the low bit of the 8704 address and use bx. */ 8705 if (TARGET_THUMB2) 8706 { 8707 rtx tmp; 8708 tmp = gen_reg_rtx (SImode); 8709 emit_insn (gen_iorsi3 (tmp, operands[0], GEN_INT(1))); 8710 operands[0] = tmp; 8711 } 8712 " 8713) 8714 8715;; NB Never uses BX. 8716(define_insn "*arm_indirect_jump" 8717 [(set (pc) 8718 (match_operand:SI 0 "s_register_operand" "r"))] 8719 "TARGET_ARM" 8720 "mov%?\\t%|pc, %0\\t%@ indirect register jump" 8721 [(set_attr "predicable" "yes") 8722 (set_attr "type" "branch")] 8723) 8724 8725(define_insn "*load_indirect_jump" 8726 [(set (pc) 8727 (match_operand:SI 0 "memory_operand" "m"))] 8728 "TARGET_ARM" 8729 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump" 8730 [(set_attr "type" "load_4") 8731 (set_attr "pool_range" "4096") 8732 (set_attr "neg_pool_range" "4084") 8733 (set_attr "predicable" "yes")] 8734) 8735 8736 8737;; Misc insns 8738 8739(define_insn "nop" 8740 [(const_int 0)] 8741 "TARGET_EITHER" 8742 "nop" 8743 [(set (attr "length") 8744 (if_then_else (eq_attr "is_thumb" "yes") 8745 (const_int 2) 8746 (const_int 4))) 8747 (set_attr "type" "mov_reg")] 8748) 8749 8750(define_insn "trap" 8751 [(trap_if (const_int 1) (const_int 0))] 8752 "" 8753 "* 8754 if (TARGET_ARM) 8755 return \".inst\\t0xe7f000f0\"; 8756 else 8757 return \".inst\\t0xdeff\"; 8758 " 8759 [(set (attr "length") 8760 (if_then_else (eq_attr "is_thumb" "yes") 8761 (const_int 2) 8762 (const_int 4))) 8763 (set_attr "type" "trap") 8764 (set_attr "conds" "unconditional")] 8765) 8766 8767 8768;; Patterns to allow combination of arithmetic, cond code and shifts 8769 8770(define_insn "*<arith_shift_insn>_multsi" 8771 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 8772 (SHIFTABLE_OPS:SI 8773 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") 8774 (match_operand:SI 3 "power_of_two_operand" "")) 8775 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>")))] 8776 "TARGET_32BIT" 8777 "<arith_shift_insn>%?\\t%0, %1, %2, lsl %b3" 8778 [(set_attr "predicable" "yes") 8779 (set_attr "shift" "2") 8780 (set_attr "arch" "a,t2") 8781 (set_attr "type" "alu_shift_imm")]) 8782 8783(define_insn "*<arith_shift_insn>_shiftsi" 8784 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 8785 (SHIFTABLE_OPS:SI 8786 (match_operator:SI 2 "shift_nomul_operator" 8787 [(match_operand:SI 3 "s_register_operand" "r,r,r") 8788 (match_operand:SI 4 "shift_amount_operand" "M,M,r")]) 8789 (match_operand:SI 1 "s_register_operand" "rk,<t2_binop0>,rk")))] 8790 "TARGET_32BIT && GET_CODE (operands[2]) != MULT" 8791 "<arith_shift_insn>%?\\t%0, %1, %3%S2" 8792 [(set_attr "predicable" "yes") 8793 (set_attr "shift" "3") 8794 (set_attr "arch" "a,t2,a") 8795 (set_attr "type" "alu_shift_imm,alu_shift_imm,alu_shift_reg")]) 8796 8797(define_split 8798 [(set (match_operand:SI 0 "s_register_operand" "") 8799 (match_operator:SI 1 "shiftable_operator" 8800 [(match_operator:SI 2 "shiftable_operator" 8801 [(match_operator:SI 3 "shift_operator" 8802 [(match_operand:SI 4 "s_register_operand" "") 8803 (match_operand:SI 5 "reg_or_int_operand" "")]) 8804 (match_operand:SI 6 "s_register_operand" "")]) 8805 (match_operand:SI 7 "arm_rhs_operand" "")])) 8806 (clobber (match_operand:SI 8 "s_register_operand" ""))] 8807 "TARGET_32BIT" 8808 [(set (match_dup 8) 8809 (match_op_dup 2 [(match_op_dup 3 [(match_dup 4) (match_dup 5)]) 8810 (match_dup 6)])) 8811 (set (match_dup 0) 8812 (match_op_dup 1 [(match_dup 8) (match_dup 7)]))] 8813 "") 8814 8815(define_insn "*arith_shiftsi_compare0" 8816 [(set (reg:CC_NOOV CC_REGNUM) 8817 (compare:CC_NOOV 8818 (match_operator:SI 1 "shiftable_operator" 8819 [(match_operator:SI 3 "shift_operator" 8820 [(match_operand:SI 4 "s_register_operand" "r,r") 8821 (match_operand:SI 5 "shift_amount_operand" "M,r")]) 8822 (match_operand:SI 2 "s_register_operand" "r,r")]) 8823 (const_int 0))) 8824 (set (match_operand:SI 0 "s_register_operand" "=r,r") 8825 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)]) 8826 (match_dup 2)]))] 8827 "TARGET_32BIT" 8828 "%i1s%?\\t%0, %2, %4%S3" 8829 [(set_attr "conds" "set") 8830 (set_attr "shift" "4") 8831 (set_attr "arch" "32,a") 8832 (set_attr "type" "alus_shift_imm,alus_shift_reg")]) 8833 8834(define_insn "*arith_shiftsi_compare0_scratch" 8835 [(set (reg:CC_NOOV CC_REGNUM) 8836 (compare:CC_NOOV 8837 (match_operator:SI 1 "shiftable_operator" 8838 [(match_operator:SI 3 "shift_operator" 8839 [(match_operand:SI 4 "s_register_operand" "r,r") 8840 (match_operand:SI 5 "shift_amount_operand" "M,r")]) 8841 (match_operand:SI 2 "s_register_operand" "r,r")]) 8842 (const_int 0))) 8843 (clobber (match_scratch:SI 0 "=r,r"))] 8844 "TARGET_32BIT" 8845 "%i1s%?\\t%0, %2, %4%S3" 8846 [(set_attr "conds" "set") 8847 (set_attr "shift" "4") 8848 (set_attr "arch" "32,a") 8849 (set_attr "type" "alus_shift_imm,alus_shift_reg")]) 8850 8851(define_insn "*sub_shiftsi" 8852 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 8853 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r") 8854 (match_operator:SI 2 "shift_operator" 8855 [(match_operand:SI 3 "s_register_operand" "r,r") 8856 (match_operand:SI 4 "shift_amount_operand" "M,r")])))] 8857 "TARGET_32BIT" 8858 "sub%?\\t%0, %1, %3%S2" 8859 [(set_attr "predicable" "yes") 8860 (set_attr "predicable_short_it" "no") 8861 (set_attr "shift" "3") 8862 (set_attr "arch" "32,a") 8863 (set_attr "type" "alus_shift_imm,alus_shift_reg")]) 8864 8865(define_insn "*sub_shiftsi_compare0" 8866 [(set (reg:CC_NOOV CC_REGNUM) 8867 (compare:CC_NOOV 8868 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 8869 (match_operator:SI 2 "shift_operator" 8870 [(match_operand:SI 3 "s_register_operand" "r,r,r") 8871 (match_operand:SI 4 "shift_amount_operand" "M,r,M")])) 8872 (const_int 0))) 8873 (set (match_operand:SI 0 "s_register_operand" "=r,r,r") 8874 (minus:SI (match_dup 1) 8875 (match_op_dup 2 [(match_dup 3) (match_dup 4)])))] 8876 "TARGET_32BIT" 8877 "subs%?\\t%0, %1, %3%S2" 8878 [(set_attr "conds" "set") 8879 (set_attr "shift" "3") 8880 (set_attr "arch" "32,a,a") 8881 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 8882 8883(define_insn "*sub_shiftsi_compare0_scratch" 8884 [(set (reg:CC_NOOV CC_REGNUM) 8885 (compare:CC_NOOV 8886 (minus:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 8887 (match_operator:SI 2 "shift_operator" 8888 [(match_operand:SI 3 "s_register_operand" "r,r,r") 8889 (match_operand:SI 4 "shift_amount_operand" "M,r,M")])) 8890 (const_int 0))) 8891 (clobber (match_scratch:SI 0 "=r,r,r"))] 8892 "TARGET_32BIT" 8893 "subs%?\\t%0, %1, %3%S2" 8894 [(set_attr "conds" "set") 8895 (set_attr "shift" "3") 8896 (set_attr "arch" "32,a,a") 8897 (set_attr "type" "alus_shift_imm,alus_shift_reg,alus_shift_imm")]) 8898 8899 8900(define_insn_and_split "*and_scc" 8901 [(set (match_operand:SI 0 "s_register_operand" "=r") 8902 (and:SI (match_operator:SI 1 "arm_comparison_operator" 8903 [(match_operand 2 "cc_register" "") (const_int 0)]) 8904 (match_operand:SI 3 "s_register_operand" "r")))] 8905 "TARGET_ARM" 8906 "#" ; "mov%D1\\t%0, #0\;and%d1\\t%0, %3, #1" 8907 "&& reload_completed" 8908 [(cond_exec (match_dup 5) (set (match_dup 0) (const_int 0))) 8909 (cond_exec (match_dup 4) (set (match_dup 0) 8910 (and:SI (match_dup 3) (const_int 1))))] 8911 { 8912 machine_mode mode = GET_MODE (operands[2]); 8913 enum rtx_code rc = GET_CODE (operands[1]); 8914 8915 /* Note that operands[4] is the same as operands[1], 8916 but with VOIDmode as the result. */ 8917 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 8918 if (mode == CCFPmode || mode == CCFPEmode) 8919 rc = reverse_condition_maybe_unordered (rc); 8920 else 8921 rc = reverse_condition (rc); 8922 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 8923 } 8924 [(set_attr "conds" "use") 8925 (set_attr "type" "multiple") 8926 (set_attr "length" "8")] 8927) 8928 8929(define_insn_and_split "*ior_scc" 8930 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 8931 (ior:SI (match_operator:SI 1 "arm_comparison_operator" 8932 [(match_operand 2 "cc_register" "") (const_int 0)]) 8933 (match_operand:SI 3 "s_register_operand" "0,?r")))] 8934 "TARGET_ARM" 8935 "@ 8936 orr%d1\\t%0, %3, #1 8937 #" 8938 "&& reload_completed 8939 && REGNO (operands [0]) != REGNO (operands[3])" 8940 ;; && which_alternative == 1 8941 ; mov%D1\\t%0, %3\;orr%d1\\t%0, %3, #1 8942 [(cond_exec (match_dup 5) (set (match_dup 0) (match_dup 3))) 8943 (cond_exec (match_dup 4) (set (match_dup 0) 8944 (ior:SI (match_dup 3) (const_int 1))))] 8945 { 8946 machine_mode mode = GET_MODE (operands[2]); 8947 enum rtx_code rc = GET_CODE (operands[1]); 8948 8949 /* Note that operands[4] is the same as operands[1], 8950 but with VOIDmode as the result. */ 8951 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 8952 if (mode == CCFPmode || mode == CCFPEmode) 8953 rc = reverse_condition_maybe_unordered (rc); 8954 else 8955 rc = reverse_condition (rc); 8956 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[2], const0_rtx); 8957 } 8958 [(set_attr "conds" "use") 8959 (set_attr "length" "4,8") 8960 (set_attr "type" "logic_imm,multiple")] 8961) 8962 8963; A series of splitters for the compare_scc pattern below. Note that 8964; order is important. 8965(define_split 8966 [(set (match_operand:SI 0 "s_register_operand" "") 8967 (lt:SI (match_operand:SI 1 "s_register_operand" "") 8968 (const_int 0))) 8969 (clobber (reg:CC CC_REGNUM))] 8970 "TARGET_32BIT && reload_completed" 8971 [(set (match_dup 0) (lshiftrt:SI (match_dup 1) (const_int 31)))]) 8972 8973(define_split 8974 [(set (match_operand:SI 0 "s_register_operand" "") 8975 (ge:SI (match_operand:SI 1 "s_register_operand" "") 8976 (const_int 0))) 8977 (clobber (reg:CC CC_REGNUM))] 8978 "TARGET_32BIT && reload_completed" 8979 [(set (match_dup 0) (not:SI (match_dup 1))) 8980 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 31)))]) 8981 8982(define_split 8983 [(set (match_operand:SI 0 "s_register_operand" "") 8984 (eq:SI (match_operand:SI 1 "s_register_operand" "") 8985 (const_int 0))) 8986 (clobber (reg:CC CC_REGNUM))] 8987 "arm_arch5 && TARGET_32BIT" 8988 [(set (match_dup 0) (clz:SI (match_dup 1))) 8989 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))] 8990) 8991 8992(define_split 8993 [(set (match_operand:SI 0 "s_register_operand" "") 8994 (eq:SI (match_operand:SI 1 "s_register_operand" "") 8995 (const_int 0))) 8996 (clobber (reg:CC CC_REGNUM))] 8997 "TARGET_32BIT && reload_completed" 8998 [(parallel 8999 [(set (reg:CC CC_REGNUM) 9000 (compare:CC (const_int 1) (match_dup 1))) 9001 (set (match_dup 0) 9002 (minus:SI (const_int 1) (match_dup 1)))]) 9003 (cond_exec (ltu:CC (reg:CC CC_REGNUM) (const_int 0)) 9004 (set (match_dup 0) (const_int 0)))]) 9005 9006(define_split 9007 [(set (match_operand:SI 0 "s_register_operand" "") 9008 (ne:SI (match_operand:SI 1 "s_register_operand" "") 9009 (match_operand:SI 2 "const_int_operand" ""))) 9010 (clobber (reg:CC CC_REGNUM))] 9011 "TARGET_32BIT && reload_completed" 9012 [(parallel 9013 [(set (reg:CC CC_REGNUM) 9014 (compare:CC (match_dup 1) (match_dup 2))) 9015 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))]) 9016 (cond_exec (ne:CC (reg:CC CC_REGNUM) (const_int 0)) 9017 (set (match_dup 0) (const_int 1)))] 9018{ 9019 operands[3] = GEN_INT (-INTVAL (operands[2])); 9020}) 9021 9022(define_split 9023 [(set (match_operand:SI 0 "s_register_operand" "") 9024 (ne:SI (match_operand:SI 1 "s_register_operand" "") 9025 (match_operand:SI 2 "arm_add_operand" ""))) 9026 (clobber (reg:CC CC_REGNUM))] 9027 "TARGET_32BIT && reload_completed" 9028 [(parallel 9029 [(set (reg:CC_NOOV CC_REGNUM) 9030 (compare:CC_NOOV (minus:SI (match_dup 1) (match_dup 2)) 9031 (const_int 0))) 9032 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))]) 9033 (cond_exec (ne:CC_NOOV (reg:CC_NOOV CC_REGNUM) (const_int 0)) 9034 (set (match_dup 0) (const_int 1)))]) 9035 9036(define_insn_and_split "*compare_scc" 9037 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 9038 (match_operator:SI 1 "arm_comparison_operator" 9039 [(match_operand:SI 2 "s_register_operand" "r,r") 9040 (match_operand:SI 3 "arm_add_operand" "rI,L")])) 9041 (clobber (reg:CC CC_REGNUM))] 9042 "TARGET_32BIT" 9043 "#" 9044 "&& reload_completed" 9045 [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 3))) 9046 (cond_exec (match_dup 4) (set (match_dup 0) (const_int 0))) 9047 (cond_exec (match_dup 5) (set (match_dup 0) (const_int 1)))] 9048{ 9049 rtx tmp1; 9050 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 9051 operands[2], operands[3]); 9052 enum rtx_code rc = GET_CODE (operands[1]); 9053 9054 tmp1 = gen_rtx_REG (mode, CC_REGNUM); 9055 9056 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx); 9057 if (mode == CCFPmode || mode == CCFPEmode) 9058 rc = reverse_condition_maybe_unordered (rc); 9059 else 9060 rc = reverse_condition (rc); 9061 operands[4] = gen_rtx_fmt_ee (rc, VOIDmode, tmp1, const0_rtx); 9062} 9063 [(set_attr "type" "multiple")] 9064) 9065 9066;; Attempt to improve the sequence generated by the compare_scc splitters 9067;; not to use conditional execution. 9068 9069;; Rd = (eq (reg1) (const_int0)) // ARMv5 9070;; clz Rd, reg1 9071;; lsr Rd, Rd, #5 9072(define_peephole2 9073 [(set (reg:CC CC_REGNUM) 9074 (compare:CC (match_operand:SI 1 "register_operand" "") 9075 (const_int 0))) 9076 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9077 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9078 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9079 (set (match_dup 0) (const_int 1)))] 9080 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)" 9081 [(set (match_dup 0) (clz:SI (match_dup 1))) 9082 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))] 9083) 9084 9085;; Rd = (eq (reg1) (const_int0)) // !ARMv5 9086;; negs Rd, reg1 9087;; adc Rd, Rd, reg1 9088(define_peephole2 9089 [(set (reg:CC CC_REGNUM) 9090 (compare:CC (match_operand:SI 1 "register_operand" "") 9091 (const_int 0))) 9092 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9093 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9094 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9095 (set (match_dup 0) (const_int 1))) 9096 (match_scratch:SI 2 "r")] 9097 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)" 9098 [(parallel 9099 [(set (reg:CC CC_REGNUM) 9100 (compare:CC (const_int 0) (match_dup 1))) 9101 (set (match_dup 2) (minus:SI (const_int 0) (match_dup 1)))]) 9102 (set (match_dup 0) 9103 (plus:SI (plus:SI (match_dup 1) (match_dup 2)) 9104 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))] 9105) 9106 9107;; Rd = (eq (reg1) (reg2/imm)) // ARMv5 and optimising for speed. 9108;; sub Rd, Reg1, reg2 9109;; clz Rd, Rd 9110;; lsr Rd, Rd, #5 9111(define_peephole2 9112 [(set (reg:CC CC_REGNUM) 9113 (compare:CC (match_operand:SI 1 "register_operand" "") 9114 (match_operand:SI 2 "arm_rhs_operand" ""))) 9115 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9116 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9117 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9118 (set (match_dup 0) (const_int 1)))] 9119 "arm_arch5 && TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM) 9120 && !(TARGET_THUMB2 && optimize_insn_for_size_p ())" 9121 [(set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2))) 9122 (set (match_dup 0) (clz:SI (match_dup 0))) 9123 (set (match_dup 0) (lshiftrt:SI (match_dup 0) (const_int 5)))] 9124) 9125 9126 9127;; Rd = (eq (reg1) (reg2)) // ! ARMv5 or optimising for size. 9128;; sub T1, Reg1, reg2 9129;; negs Rd, T1 9130;; adc Rd, Rd, T1 9131(define_peephole2 9132 [(set (reg:CC CC_REGNUM) 9133 (compare:CC (match_operand:SI 1 "register_operand" "") 9134 (match_operand:SI 2 "arm_rhs_operand" ""))) 9135 (cond_exec (ne (reg:CC CC_REGNUM) (const_int 0)) 9136 (set (match_operand:SI 0 "register_operand" "") (const_int 0))) 9137 (cond_exec (eq (reg:CC CC_REGNUM) (const_int 0)) 9138 (set (match_dup 0) (const_int 1))) 9139 (match_scratch:SI 3 "r")] 9140 "TARGET_32BIT && peep2_regno_dead_p (3, CC_REGNUM)" 9141 [(set (match_dup 3) (match_dup 4)) 9142 (parallel 9143 [(set (reg:CC CC_REGNUM) 9144 (compare:CC (const_int 0) (match_dup 3))) 9145 (set (match_dup 0) (minus:SI (const_int 0) (match_dup 3)))]) 9146 (set (match_dup 0) 9147 (plus:SI (plus:SI (match_dup 0) (match_dup 3)) 9148 (geu:SI (reg:CC CC_REGNUM) (const_int 0))))] 9149 " 9150 if (CONST_INT_P (operands[2])) 9151 operands[4] = plus_constant (SImode, operands[1], -INTVAL (operands[2])); 9152 else 9153 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[2]); 9154 ") 9155 9156(define_insn "*cond_move" 9157 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 9158 (if_then_else:SI (match_operator 3 "equality_operator" 9159 [(match_operator 4 "arm_comparison_operator" 9160 [(match_operand 5 "cc_register" "") (const_int 0)]) 9161 (const_int 0)]) 9162 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") 9163 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))] 9164 "TARGET_ARM" 9165 "* 9166 if (GET_CODE (operands[3]) == NE) 9167 { 9168 if (which_alternative != 1) 9169 output_asm_insn (\"mov%D4\\t%0, %2\", operands); 9170 if (which_alternative != 0) 9171 output_asm_insn (\"mov%d4\\t%0, %1\", operands); 9172 return \"\"; 9173 } 9174 if (which_alternative != 0) 9175 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 9176 if (which_alternative != 1) 9177 output_asm_insn (\"mov%d4\\t%0, %2\", operands); 9178 return \"\"; 9179 " 9180 [(set_attr "conds" "use") 9181 (set_attr_alternative "type" 9182 [(if_then_else (match_operand 2 "const_int_operand" "") 9183 (const_string "mov_imm") 9184 (const_string "mov_reg")) 9185 (if_then_else (match_operand 1 "const_int_operand" "") 9186 (const_string "mov_imm") 9187 (const_string "mov_reg")) 9188 (const_string "multiple")]) 9189 (set_attr "length" "4,4,8")] 9190) 9191 9192(define_insn "*cond_arith" 9193 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9194 (match_operator:SI 5 "shiftable_operator" 9195 [(match_operator:SI 4 "arm_comparison_operator" 9196 [(match_operand:SI 2 "s_register_operand" "r,r") 9197 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 9198 (match_operand:SI 1 "s_register_operand" "0,?r")])) 9199 (clobber (reg:CC CC_REGNUM))] 9200 "TARGET_ARM" 9201 "* 9202 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) 9203 return \"%i5\\t%0, %1, %2, lsr #31\"; 9204 9205 output_asm_insn (\"cmp\\t%2, %3\", operands); 9206 if (GET_CODE (operands[5]) == AND) 9207 output_asm_insn (\"mov%D4\\t%0, #0\", operands); 9208 else if (GET_CODE (operands[5]) == MINUS) 9209 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands); 9210 else if (which_alternative != 0) 9211 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 9212 return \"%i5%d4\\t%0, %1, #1\"; 9213 " 9214 [(set_attr "conds" "clob") 9215 (set_attr "length" "12") 9216 (set_attr "type" "multiple")] 9217) 9218 9219(define_insn "*cond_sub" 9220 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9221 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") 9222 (match_operator:SI 4 "arm_comparison_operator" 9223 [(match_operand:SI 2 "s_register_operand" "r,r") 9224 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) 9225 (clobber (reg:CC CC_REGNUM))] 9226 "TARGET_ARM" 9227 "* 9228 output_asm_insn (\"cmp\\t%2, %3\", operands); 9229 if (which_alternative != 0) 9230 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 9231 return \"sub%d4\\t%0, %1, #1\"; 9232 " 9233 [(set_attr "conds" "clob") 9234 (set_attr "length" "8,12") 9235 (set_attr "type" "multiple")] 9236) 9237 9238(define_insn "*cmp_ite0" 9239 [(set (match_operand 6 "dominant_cc_register" "") 9240 (compare 9241 (if_then_else:SI 9242 (match_operator 4 "arm_comparison_operator" 9243 [(match_operand:SI 0 "s_register_operand" 9244 "l,l,l,r,r,r,r,r,r") 9245 (match_operand:SI 1 "arm_add_operand" 9246 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9247 (match_operator:SI 5 "arm_comparison_operator" 9248 [(match_operand:SI 2 "s_register_operand" 9249 "l,r,r,l,l,r,r,r,r") 9250 (match_operand:SI 3 "arm_add_operand" 9251 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]) 9252 (const_int 0)) 9253 (const_int 0)))] 9254 "TARGET_32BIT" 9255 "* 9256 { 9257 static const char * const cmp1[NUM_OF_COND_CMP][2] = 9258 { 9259 {\"cmp%d5\\t%0, %1\", 9260 \"cmp%d4\\t%2, %3\"}, 9261 {\"cmn%d5\\t%0, #%n1\", 9262 \"cmp%d4\\t%2, %3\"}, 9263 {\"cmp%d5\\t%0, %1\", 9264 \"cmn%d4\\t%2, #%n3\"}, 9265 {\"cmn%d5\\t%0, #%n1\", 9266 \"cmn%d4\\t%2, #%n3\"} 9267 }; 9268 static const char * const cmp2[NUM_OF_COND_CMP][2] = 9269 { 9270 {\"cmp\\t%2, %3\", 9271 \"cmp\\t%0, %1\"}, 9272 {\"cmp\\t%2, %3\", 9273 \"cmn\\t%0, #%n1\"}, 9274 {\"cmn\\t%2, #%n3\", 9275 \"cmp\\t%0, %1\"}, 9276 {\"cmn\\t%2, #%n3\", 9277 \"cmn\\t%0, #%n1\"} 9278 }; 9279 static const char * const ite[2] = 9280 { 9281 \"it\\t%d5\", 9282 \"it\\t%d4\" 9283 }; 9284 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9285 CMP_CMP, CMN_CMP, CMP_CMP, 9286 CMN_CMP, CMP_CMN, CMN_CMN}; 9287 int swap = 9288 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 9289 9290 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9291 if (TARGET_THUMB2) { 9292 output_asm_insn (ite[swap], operands); 9293 } 9294 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9295 return \"\"; 9296 }" 9297 [(set_attr "conds" "set") 9298 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9299 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9300 (set_attr "type" "multiple") 9301 (set_attr_alternative "length" 9302 [(const_int 6) 9303 (const_int 8) 9304 (const_int 8) 9305 (const_int 8) 9306 (const_int 8) 9307 (if_then_else (eq_attr "is_thumb" "no") 9308 (const_int 8) 9309 (const_int 10)) 9310 (if_then_else (eq_attr "is_thumb" "no") 9311 (const_int 8) 9312 (const_int 10)) 9313 (if_then_else (eq_attr "is_thumb" "no") 9314 (const_int 8) 9315 (const_int 10)) 9316 (if_then_else (eq_attr "is_thumb" "no") 9317 (const_int 8) 9318 (const_int 10))])] 9319) 9320 9321(define_insn "*cmp_ite1" 9322 [(set (match_operand 6 "dominant_cc_register" "") 9323 (compare 9324 (if_then_else:SI 9325 (match_operator 4 "arm_comparison_operator" 9326 [(match_operand:SI 0 "s_register_operand" 9327 "l,l,l,r,r,r,r,r,r") 9328 (match_operand:SI 1 "arm_add_operand" 9329 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9330 (match_operator:SI 5 "arm_comparison_operator" 9331 [(match_operand:SI 2 "s_register_operand" 9332 "l,r,r,l,l,r,r,r,r") 9333 (match_operand:SI 3 "arm_add_operand" 9334 "lPy,rI,L,lPy,lPy,rI,rI,L,L")]) 9335 (const_int 1)) 9336 (const_int 0)))] 9337 "TARGET_32BIT" 9338 "* 9339 { 9340 static const char * const cmp1[NUM_OF_COND_CMP][2] = 9341 { 9342 {\"cmp\\t%0, %1\", 9343 \"cmp\\t%2, %3\"}, 9344 {\"cmn\\t%0, #%n1\", 9345 \"cmp\\t%2, %3\"}, 9346 {\"cmp\\t%0, %1\", 9347 \"cmn\\t%2, #%n3\"}, 9348 {\"cmn\\t%0, #%n1\", 9349 \"cmn\\t%2, #%n3\"} 9350 }; 9351 static const char * const cmp2[NUM_OF_COND_CMP][2] = 9352 { 9353 {\"cmp%d4\\t%2, %3\", 9354 \"cmp%D5\\t%0, %1\"}, 9355 {\"cmp%d4\\t%2, %3\", 9356 \"cmn%D5\\t%0, #%n1\"}, 9357 {\"cmn%d4\\t%2, #%n3\", 9358 \"cmp%D5\\t%0, %1\"}, 9359 {\"cmn%d4\\t%2, #%n3\", 9360 \"cmn%D5\\t%0, #%n1\"} 9361 }; 9362 static const char * const ite[2] = 9363 { 9364 \"it\\t%d4\", 9365 \"it\\t%D5\" 9366 }; 9367 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9368 CMP_CMP, CMN_CMP, CMP_CMP, 9369 CMN_CMP, CMP_CMN, CMN_CMN}; 9370 int swap = 9371 comparison_dominates_p (GET_CODE (operands[5]), 9372 reverse_condition (GET_CODE (operands[4]))); 9373 9374 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9375 if (TARGET_THUMB2) { 9376 output_asm_insn (ite[swap], operands); 9377 } 9378 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9379 return \"\"; 9380 }" 9381 [(set_attr "conds" "set") 9382 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9383 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9384 (set_attr_alternative "length" 9385 [(const_int 6) 9386 (const_int 8) 9387 (const_int 8) 9388 (const_int 8) 9389 (const_int 8) 9390 (if_then_else (eq_attr "is_thumb" "no") 9391 (const_int 8) 9392 (const_int 10)) 9393 (if_then_else (eq_attr "is_thumb" "no") 9394 (const_int 8) 9395 (const_int 10)) 9396 (if_then_else (eq_attr "is_thumb" "no") 9397 (const_int 8) 9398 (const_int 10)) 9399 (if_then_else (eq_attr "is_thumb" "no") 9400 (const_int 8) 9401 (const_int 10))]) 9402 (set_attr "type" "multiple")] 9403) 9404 9405(define_insn "*cmp_and" 9406 [(set (match_operand 6 "dominant_cc_register" "") 9407 (compare 9408 (and:SI 9409 (match_operator 4 "arm_comparison_operator" 9410 [(match_operand:SI 0 "s_register_operand" 9411 "l,l,l,r,r,r,r,r,r") 9412 (match_operand:SI 1 "arm_add_operand" 9413 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9414 (match_operator:SI 5 "arm_comparison_operator" 9415 [(match_operand:SI 2 "s_register_operand" 9416 "l,r,r,l,l,r,r,r,r") 9417 (match_operand:SI 3 "arm_add_operand" 9418 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])) 9419 (const_int 0)))] 9420 "TARGET_32BIT" 9421 "* 9422 { 9423 static const char *const cmp1[NUM_OF_COND_CMP][2] = 9424 { 9425 {\"cmp%d5\\t%0, %1\", 9426 \"cmp%d4\\t%2, %3\"}, 9427 {\"cmn%d5\\t%0, #%n1\", 9428 \"cmp%d4\\t%2, %3\"}, 9429 {\"cmp%d5\\t%0, %1\", 9430 \"cmn%d4\\t%2, #%n3\"}, 9431 {\"cmn%d5\\t%0, #%n1\", 9432 \"cmn%d4\\t%2, #%n3\"} 9433 }; 9434 static const char *const cmp2[NUM_OF_COND_CMP][2] = 9435 { 9436 {\"cmp\\t%2, %3\", 9437 \"cmp\\t%0, %1\"}, 9438 {\"cmp\\t%2, %3\", 9439 \"cmn\\t%0, #%n1\"}, 9440 {\"cmn\\t%2, #%n3\", 9441 \"cmp\\t%0, %1\"}, 9442 {\"cmn\\t%2, #%n3\", 9443 \"cmn\\t%0, #%n1\"} 9444 }; 9445 static const char *const ite[2] = 9446 { 9447 \"it\\t%d5\", 9448 \"it\\t%d4\" 9449 }; 9450 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9451 CMP_CMP, CMN_CMP, CMP_CMP, 9452 CMN_CMP, CMP_CMN, CMN_CMN}; 9453 int swap = 9454 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 9455 9456 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9457 if (TARGET_THUMB2) { 9458 output_asm_insn (ite[swap], operands); 9459 } 9460 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9461 return \"\"; 9462 }" 9463 [(set_attr "conds" "set") 9464 (set_attr "predicable" "no") 9465 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9466 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9467 (set_attr_alternative "length" 9468 [(const_int 6) 9469 (const_int 8) 9470 (const_int 8) 9471 (const_int 8) 9472 (const_int 8) 9473 (if_then_else (eq_attr "is_thumb" "no") 9474 (const_int 8) 9475 (const_int 10)) 9476 (if_then_else (eq_attr "is_thumb" "no") 9477 (const_int 8) 9478 (const_int 10)) 9479 (if_then_else (eq_attr "is_thumb" "no") 9480 (const_int 8) 9481 (const_int 10)) 9482 (if_then_else (eq_attr "is_thumb" "no") 9483 (const_int 8) 9484 (const_int 10))]) 9485 (set_attr "type" "multiple")] 9486) 9487 9488(define_insn "*cmp_ior" 9489 [(set (match_operand 6 "dominant_cc_register" "") 9490 (compare 9491 (ior:SI 9492 (match_operator 4 "arm_comparison_operator" 9493 [(match_operand:SI 0 "s_register_operand" 9494 "l,l,l,r,r,r,r,r,r") 9495 (match_operand:SI 1 "arm_add_operand" 9496 "lPy,lPy,lPy,rI,L,rI,L,rI,L")]) 9497 (match_operator:SI 5 "arm_comparison_operator" 9498 [(match_operand:SI 2 "s_register_operand" 9499 "l,r,r,l,l,r,r,r,r") 9500 (match_operand:SI 3 "arm_add_operand" 9501 "lPy,rI,L,lPy,lPy,rI,rI,L,L")])) 9502 (const_int 0)))] 9503 "TARGET_32BIT" 9504 "* 9505 { 9506 static const char *const cmp1[NUM_OF_COND_CMP][2] = 9507 { 9508 {\"cmp\\t%0, %1\", 9509 \"cmp\\t%2, %3\"}, 9510 {\"cmn\\t%0, #%n1\", 9511 \"cmp\\t%2, %3\"}, 9512 {\"cmp\\t%0, %1\", 9513 \"cmn\\t%2, #%n3\"}, 9514 {\"cmn\\t%0, #%n1\", 9515 \"cmn\\t%2, #%n3\"} 9516 }; 9517 static const char *const cmp2[NUM_OF_COND_CMP][2] = 9518 { 9519 {\"cmp%D4\\t%2, %3\", 9520 \"cmp%D5\\t%0, %1\"}, 9521 {\"cmp%D4\\t%2, %3\", 9522 \"cmn%D5\\t%0, #%n1\"}, 9523 {\"cmn%D4\\t%2, #%n3\", 9524 \"cmp%D5\\t%0, %1\"}, 9525 {\"cmn%D4\\t%2, #%n3\", 9526 \"cmn%D5\\t%0, #%n1\"} 9527 }; 9528 static const char *const ite[2] = 9529 { 9530 \"it\\t%D4\", 9531 \"it\\t%D5\" 9532 }; 9533 static const int cmp_idx[9] = {CMP_CMP, CMP_CMP, CMP_CMN, 9534 CMP_CMP, CMN_CMP, CMP_CMP, 9535 CMN_CMP, CMP_CMN, CMN_CMN}; 9536 int swap = 9537 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 9538 9539 output_asm_insn (cmp1[cmp_idx[which_alternative]][swap], operands); 9540 if (TARGET_THUMB2) { 9541 output_asm_insn (ite[swap], operands); 9542 } 9543 output_asm_insn (cmp2[cmp_idx[which_alternative]][swap], operands); 9544 return \"\"; 9545 } 9546 " 9547 [(set_attr "conds" "set") 9548 (set_attr "arch" "t2,t2,t2,t2,t2,any,any,any,any") 9549 (set_attr "enabled_for_short_it" "yes,no,no,no,no,no,no,no,no") 9550 (set_attr_alternative "length" 9551 [(const_int 6) 9552 (const_int 8) 9553 (const_int 8) 9554 (const_int 8) 9555 (const_int 8) 9556 (if_then_else (eq_attr "is_thumb" "no") 9557 (const_int 8) 9558 (const_int 10)) 9559 (if_then_else (eq_attr "is_thumb" "no") 9560 (const_int 8) 9561 (const_int 10)) 9562 (if_then_else (eq_attr "is_thumb" "no") 9563 (const_int 8) 9564 (const_int 10)) 9565 (if_then_else (eq_attr "is_thumb" "no") 9566 (const_int 8) 9567 (const_int 10))]) 9568 (set_attr "type" "multiple")] 9569) 9570 9571(define_insn_and_split "*ior_scc_scc" 9572 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 9573 (ior:SI (match_operator:SI 3 "arm_comparison_operator" 9574 [(match_operand:SI 1 "s_register_operand" "l,r") 9575 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9576 (match_operator:SI 6 "arm_comparison_operator" 9577 [(match_operand:SI 4 "s_register_operand" "l,r") 9578 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))) 9579 (clobber (reg:CC CC_REGNUM))] 9580 "TARGET_32BIT 9581 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_OR_Y) 9582 != CCmode)" 9583 "#" 9584 "TARGET_32BIT && reload_completed" 9585 [(set (match_dup 7) 9586 (compare 9587 (ior:SI 9588 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9589 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9590 (const_int 0))) 9591 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] 9592 "operands[7] 9593 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], 9594 DOM_CC_X_OR_Y), 9595 CC_REGNUM);" 9596 [(set_attr "conds" "clob") 9597 (set_attr "enabled_for_short_it" "yes,no") 9598 (set_attr "length" "16") 9599 (set_attr "type" "multiple")] 9600) 9601 9602; If the above pattern is followed by a CMP insn, then the compare is 9603; redundant, since we can rework the conditional instruction that follows. 9604(define_insn_and_split "*ior_scc_scc_cmp" 9605 [(set (match_operand 0 "dominant_cc_register" "") 9606 (compare (ior:SI (match_operator:SI 3 "arm_comparison_operator" 9607 [(match_operand:SI 1 "s_register_operand" "l,r") 9608 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9609 (match_operator:SI 6 "arm_comparison_operator" 9610 [(match_operand:SI 4 "s_register_operand" "l,r") 9611 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])) 9612 (const_int 0))) 9613 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts") 9614 (ior:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9615 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] 9616 "TARGET_32BIT" 9617 "#" 9618 "TARGET_32BIT && reload_completed" 9619 [(set (match_dup 0) 9620 (compare 9621 (ior:SI 9622 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9623 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9624 (const_int 0))) 9625 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] 9626 "" 9627 [(set_attr "conds" "set") 9628 (set_attr "enabled_for_short_it" "yes,no") 9629 (set_attr "length" "16") 9630 (set_attr "type" "multiple")] 9631) 9632 9633(define_insn_and_split "*and_scc_scc" 9634 [(set (match_operand:SI 0 "s_register_operand" "=Ts,Ts") 9635 (and:SI (match_operator:SI 3 "arm_comparison_operator" 9636 [(match_operand:SI 1 "s_register_operand" "l,r") 9637 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9638 (match_operator:SI 6 "arm_comparison_operator" 9639 [(match_operand:SI 4 "s_register_operand" "l,r") 9640 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")]))) 9641 (clobber (reg:CC CC_REGNUM))] 9642 "TARGET_32BIT 9643 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) 9644 != CCmode)" 9645 "#" 9646 "TARGET_32BIT && reload_completed 9647 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) 9648 != CCmode)" 9649 [(set (match_dup 7) 9650 (compare 9651 (and:SI 9652 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9653 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9654 (const_int 0))) 9655 (set (match_dup 0) (ne:SI (match_dup 7) (const_int 0)))] 9656 "operands[7] 9657 = gen_rtx_REG (arm_select_dominance_cc_mode (operands[3], operands[6], 9658 DOM_CC_X_AND_Y), 9659 CC_REGNUM);" 9660 [(set_attr "conds" "clob") 9661 (set_attr "enabled_for_short_it" "yes,no") 9662 (set_attr "length" "16") 9663 (set_attr "type" "multiple")] 9664) 9665 9666; If the above pattern is followed by a CMP insn, then the compare is 9667; redundant, since we can rework the conditional instruction that follows. 9668(define_insn_and_split "*and_scc_scc_cmp" 9669 [(set (match_operand 0 "dominant_cc_register" "") 9670 (compare (and:SI (match_operator:SI 3 "arm_comparison_operator" 9671 [(match_operand:SI 1 "s_register_operand" "l,r") 9672 (match_operand:SI 2 "arm_add_operand" "lPy,rIL")]) 9673 (match_operator:SI 6 "arm_comparison_operator" 9674 [(match_operand:SI 4 "s_register_operand" "l,r") 9675 (match_operand:SI 5 "arm_add_operand" "lPy,rIL")])) 9676 (const_int 0))) 9677 (set (match_operand:SI 7 "s_register_operand" "=Ts,Ts") 9678 (and:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9679 (match_op_dup 6 [(match_dup 4) (match_dup 5)])))] 9680 "TARGET_32BIT" 9681 "#" 9682 "TARGET_32BIT && reload_completed" 9683 [(set (match_dup 0) 9684 (compare 9685 (and:SI 9686 (match_op_dup 3 [(match_dup 1) (match_dup 2)]) 9687 (match_op_dup 6 [(match_dup 4) (match_dup 5)])) 9688 (const_int 0))) 9689 (set (match_dup 7) (ne:SI (match_dup 0) (const_int 0)))] 9690 "" 9691 [(set_attr "conds" "set") 9692 (set_attr "enabled_for_short_it" "yes,no") 9693 (set_attr "length" "16") 9694 (set_attr "type" "multiple")] 9695) 9696 9697;; If there is no dominance in the comparison, then we can still save an 9698;; instruction in the AND case, since we can know that the second compare 9699;; need only zero the value if false (if true, then the value is already 9700;; correct). 9701(define_insn_and_split "*and_scc_scc_nodom" 9702 [(set (match_operand:SI 0 "s_register_operand" "=&Ts,&Ts,&Ts") 9703 (and:SI (match_operator:SI 3 "arm_comparison_operator" 9704 [(match_operand:SI 1 "s_register_operand" "r,r,0") 9705 (match_operand:SI 2 "arm_add_operand" "rIL,0,rIL")]) 9706 (match_operator:SI 6 "arm_comparison_operator" 9707 [(match_operand:SI 4 "s_register_operand" "r,r,r") 9708 (match_operand:SI 5 "arm_add_operand" "rIL,rIL,rIL")]))) 9709 (clobber (reg:CC CC_REGNUM))] 9710 "TARGET_32BIT 9711 && (arm_select_dominance_cc_mode (operands[3], operands[6], DOM_CC_X_AND_Y) 9712 == CCmode)" 9713 "#" 9714 "TARGET_32BIT && reload_completed" 9715 [(parallel [(set (match_dup 0) 9716 (match_op_dup 3 [(match_dup 1) (match_dup 2)])) 9717 (clobber (reg:CC CC_REGNUM))]) 9718 (set (match_dup 7) (match_op_dup 8 [(match_dup 4) (match_dup 5)])) 9719 (set (match_dup 0) 9720 (if_then_else:SI (match_op_dup 6 [(match_dup 7) (const_int 0)]) 9721 (match_dup 0) 9722 (const_int 0)))] 9723 "operands[7] = gen_rtx_REG (SELECT_CC_MODE (GET_CODE (operands[6]), 9724 operands[4], operands[5]), 9725 CC_REGNUM); 9726 operands[8] = gen_rtx_COMPARE (GET_MODE (operands[7]), operands[4], 9727 operands[5]);" 9728 [(set_attr "conds" "clob") 9729 (set_attr "length" "20") 9730 (set_attr "type" "multiple")] 9731) 9732 9733(define_split 9734 [(set (reg:CC_NOOV CC_REGNUM) 9735 (compare:CC_NOOV (ior:SI 9736 (and:SI (match_operand:SI 0 "s_register_operand" "") 9737 (const_int 1)) 9738 (match_operator:SI 1 "arm_comparison_operator" 9739 [(match_operand:SI 2 "s_register_operand" "") 9740 (match_operand:SI 3 "arm_add_operand" "")])) 9741 (const_int 0))) 9742 (clobber (match_operand:SI 4 "s_register_operand" ""))] 9743 "TARGET_ARM" 9744 [(set (match_dup 4) 9745 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) 9746 (match_dup 0))) 9747 (set (reg:CC_NOOV CC_REGNUM) 9748 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1)) 9749 (const_int 0)))] 9750 "") 9751 9752(define_split 9753 [(set (reg:CC_NOOV CC_REGNUM) 9754 (compare:CC_NOOV (ior:SI 9755 (match_operator:SI 1 "arm_comparison_operator" 9756 [(match_operand:SI 2 "s_register_operand" "") 9757 (match_operand:SI 3 "arm_add_operand" "")]) 9758 (and:SI (match_operand:SI 0 "s_register_operand" "") 9759 (const_int 1))) 9760 (const_int 0))) 9761 (clobber (match_operand:SI 4 "s_register_operand" ""))] 9762 "TARGET_ARM" 9763 [(set (match_dup 4) 9764 (ior:SI (match_op_dup 1 [(match_dup 2) (match_dup 3)]) 9765 (match_dup 0))) 9766 (set (reg:CC_NOOV CC_REGNUM) 9767 (compare:CC_NOOV (and:SI (match_dup 4) (const_int 1)) 9768 (const_int 0)))] 9769 "") 9770;; ??? The conditional patterns above need checking for Thumb-2 usefulness 9771 9772(define_insn_and_split "*negscc" 9773 [(set (match_operand:SI 0 "s_register_operand" "=r") 9774 (neg:SI (match_operator 3 "arm_comparison_operator" 9775 [(match_operand:SI 1 "s_register_operand" "r") 9776 (match_operand:SI 2 "arm_rhs_operand" "rI")]))) 9777 (clobber (reg:CC CC_REGNUM))] 9778 "TARGET_ARM" 9779 "#" 9780 "&& reload_completed" 9781 [(const_int 0)] 9782 { 9783 rtx cc_reg = gen_rtx_REG (CCmode, CC_REGNUM); 9784 9785 if (GET_CODE (operands[3]) == LT && operands[2] == const0_rtx) 9786 { 9787 /* Emit mov\\t%0, %1, asr #31 */ 9788 emit_insn (gen_rtx_SET (operands[0], 9789 gen_rtx_ASHIFTRT (SImode, 9790 operands[1], 9791 GEN_INT (31)))); 9792 DONE; 9793 } 9794 else if (GET_CODE (operands[3]) == NE) 9795 { 9796 /* Emit subs\\t%0, %1, %2\;mvnne\\t%0, #0 */ 9797 if (CONST_INT_P (operands[2])) 9798 emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2], 9799 GEN_INT (- INTVAL (operands[2])))); 9800 else 9801 emit_insn (gen_subsi3_compare (operands[0], operands[1], operands[2])); 9802 9803 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 9804 gen_rtx_NE (SImode, 9805 cc_reg, 9806 const0_rtx), 9807 gen_rtx_SET (operands[0], 9808 GEN_INT (~0)))); 9809 DONE; 9810 } 9811 else 9812 { 9813 /* Emit: cmp\\t%1, %2\;mov%D3\\t%0, #0\;mvn%d3\\t%0, #0 */ 9814 emit_insn (gen_rtx_SET (cc_reg, 9815 gen_rtx_COMPARE (CCmode, operands[1], operands[2]))); 9816 enum rtx_code rc = GET_CODE (operands[3]); 9817 9818 rc = reverse_condition (rc); 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], const0_rtx))); 9825 rc = GET_CODE (operands[3]); 9826 emit_insn (gen_rtx_COND_EXEC (VOIDmode, 9827 gen_rtx_fmt_ee (rc, 9828 VOIDmode, 9829 cc_reg, 9830 const0_rtx), 9831 gen_rtx_SET (operands[0], 9832 GEN_INT (~0)))); 9833 DONE; 9834 } 9835 FAIL; 9836 } 9837 [(set_attr "conds" "clob") 9838 (set_attr "length" "12") 9839 (set_attr "type" "multiple")] 9840) 9841 9842(define_insn_and_split "movcond_addsi" 9843 [(set (match_operand:SI 0 "s_register_operand" "=r,l,r") 9844 (if_then_else:SI 9845 (match_operator 5 "comparison_operator" 9846 [(plus:SI (match_operand:SI 3 "s_register_operand" "r,r,r") 9847 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")) 9848 (const_int 0)]) 9849 (match_operand:SI 1 "arm_rhs_operand" "rI,rPy,r") 9850 (match_operand:SI 2 "arm_rhs_operand" "rI,rPy,r"))) 9851 (clobber (reg:CC CC_REGNUM))] 9852 "TARGET_32BIT" 9853 "#" 9854 "&& reload_completed" 9855 [(set (reg:CC_NOOV CC_REGNUM) 9856 (compare:CC_NOOV 9857 (plus:SI (match_dup 3) 9858 (match_dup 4)) 9859 (const_int 0))) 9860 (set (match_dup 0) (match_dup 1)) 9861 (cond_exec (match_dup 6) 9862 (set (match_dup 0) (match_dup 2)))] 9863 " 9864 { 9865 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[5]), 9866 operands[3], operands[4]); 9867 enum rtx_code rc = GET_CODE (operands[5]); 9868 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 9869 gcc_assert (!(mode == CCFPmode || mode == CCFPEmode)); 9870 if (!REG_P (operands[2]) || REGNO (operands[2]) != REGNO (operands[0])) 9871 rc = reverse_condition (rc); 9872 else 9873 std::swap (operands[1], operands[2]); 9874 9875 operands[6] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 9876 } 9877 " 9878 [(set_attr "conds" "clob") 9879 (set_attr "enabled_for_short_it" "no,yes,yes") 9880 (set_attr "type" "multiple")] 9881) 9882 9883(define_insn "movcond" 9884 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 9885 (if_then_else:SI 9886 (match_operator 5 "arm_comparison_operator" 9887 [(match_operand:SI 3 "s_register_operand" "r,r,r") 9888 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")]) 9889 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") 9890 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 9891 (clobber (reg:CC CC_REGNUM))] 9892 "TARGET_ARM" 9893 "* 9894 if (GET_CODE (operands[5]) == LT 9895 && (operands[4] == const0_rtx)) 9896 { 9897 if (which_alternative != 1 && REG_P (operands[1])) 9898 { 9899 if (operands[2] == const0_rtx) 9900 return \"and\\t%0, %1, %3, asr #31\"; 9901 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\"; 9902 } 9903 else if (which_alternative != 0 && REG_P (operands[2])) 9904 { 9905 if (operands[1] == const0_rtx) 9906 return \"bic\\t%0, %2, %3, asr #31\"; 9907 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\"; 9908 } 9909 /* The only case that falls through to here is when both ops 1 & 2 9910 are constants. */ 9911 } 9912 9913 if (GET_CODE (operands[5]) == GE 9914 && (operands[4] == const0_rtx)) 9915 { 9916 if (which_alternative != 1 && REG_P (operands[1])) 9917 { 9918 if (operands[2] == const0_rtx) 9919 return \"bic\\t%0, %1, %3, asr #31\"; 9920 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\"; 9921 } 9922 else if (which_alternative != 0 && REG_P (operands[2])) 9923 { 9924 if (operands[1] == const0_rtx) 9925 return \"and\\t%0, %2, %3, asr #31\"; 9926 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\"; 9927 } 9928 /* The only case that falls through to here is when both ops 1 & 2 9929 are constants. */ 9930 } 9931 if (CONST_INT_P (operands[4]) 9932 && !const_ok_for_arm (INTVAL (operands[4]))) 9933 output_asm_insn (\"cmn\\t%3, #%n4\", operands); 9934 else 9935 output_asm_insn (\"cmp\\t%3, %4\", operands); 9936 if (which_alternative != 0) 9937 output_asm_insn (\"mov%d5\\t%0, %1\", operands); 9938 if (which_alternative != 1) 9939 output_asm_insn (\"mov%D5\\t%0, %2\", operands); 9940 return \"\"; 9941 " 9942 [(set_attr "conds" "clob") 9943 (set_attr "length" "8,8,12") 9944 (set_attr "type" "multiple")] 9945) 9946 9947;; ??? The patterns below need checking for Thumb-2 usefulness. 9948 9949(define_insn "*ifcompare_plus_move" 9950 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9951 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 9952 [(match_operand:SI 4 "s_register_operand" "r,r") 9953 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 9954 (plus:SI 9955 (match_operand:SI 2 "s_register_operand" "r,r") 9956 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")) 9957 (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) 9958 (clobber (reg:CC CC_REGNUM))] 9959 "TARGET_ARM" 9960 "#" 9961 [(set_attr "conds" "clob") 9962 (set_attr "length" "8,12") 9963 (set_attr "type" "multiple")] 9964) 9965 9966(define_insn "*if_plus_move" 9967 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") 9968 (if_then_else:SI 9969 (match_operator 4 "arm_comparison_operator" 9970 [(match_operand 5 "cc_register" "") (const_int 0)]) 9971 (plus:SI 9972 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 9973 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")) 9974 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))] 9975 "TARGET_ARM" 9976 "@ 9977 add%d4\\t%0, %2, %3 9978 sub%d4\\t%0, %2, #%n3 9979 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1 9980 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1" 9981 [(set_attr "conds" "use") 9982 (set_attr "length" "4,4,8,8") 9983 (set_attr_alternative "type" 9984 [(if_then_else (match_operand 3 "const_int_operand" "") 9985 (const_string "alu_imm" ) 9986 (const_string "alu_sreg")) 9987 (const_string "alu_imm") 9988 (const_string "multiple") 9989 (const_string "multiple")])] 9990) 9991 9992(define_insn "*ifcompare_move_plus" 9993 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 9994 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 9995 [(match_operand:SI 4 "s_register_operand" "r,r") 9996 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 9997 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 9998 (plus:SI 9999 (match_operand:SI 2 "s_register_operand" "r,r") 10000 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")))) 10001 (clobber (reg:CC CC_REGNUM))] 10002 "TARGET_ARM" 10003 "#" 10004 [(set_attr "conds" "clob") 10005 (set_attr "length" "8,12") 10006 (set_attr "type" "multiple")] 10007) 10008 10009(define_insn "*if_move_plus" 10010 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") 10011 (if_then_else:SI 10012 (match_operator 4 "arm_comparison_operator" 10013 [(match_operand 5 "cc_register" "") (const_int 0)]) 10014 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI") 10015 (plus:SI 10016 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 10017 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))] 10018 "TARGET_ARM" 10019 "@ 10020 add%D4\\t%0, %2, %3 10021 sub%D4\\t%0, %2, #%n3 10022 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1 10023 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1" 10024 [(set_attr "conds" "use") 10025 (set_attr "length" "4,4,8,8") 10026 (set_attr_alternative "type" 10027 [(if_then_else (match_operand 3 "const_int_operand" "") 10028 (const_string "alu_imm" ) 10029 (const_string "alu_sreg")) 10030 (const_string "alu_imm") 10031 (const_string "multiple") 10032 (const_string "multiple")])] 10033) 10034 10035(define_insn "*ifcompare_arith_arith" 10036 [(set (match_operand:SI 0 "s_register_operand" "=r") 10037 (if_then_else:SI (match_operator 9 "arm_comparison_operator" 10038 [(match_operand:SI 5 "s_register_operand" "r") 10039 (match_operand:SI 6 "arm_add_operand" "rIL")]) 10040 (match_operator:SI 8 "shiftable_operator" 10041 [(match_operand:SI 1 "s_register_operand" "r") 10042 (match_operand:SI 2 "arm_rhs_operand" "rI")]) 10043 (match_operator:SI 7 "shiftable_operator" 10044 [(match_operand:SI 3 "s_register_operand" "r") 10045 (match_operand:SI 4 "arm_rhs_operand" "rI")]))) 10046 (clobber (reg:CC CC_REGNUM))] 10047 "TARGET_ARM" 10048 "#" 10049 [(set_attr "conds" "clob") 10050 (set_attr "length" "12") 10051 (set_attr "type" "multiple")] 10052) 10053 10054(define_insn "*if_arith_arith" 10055 [(set (match_operand:SI 0 "s_register_operand" "=r") 10056 (if_then_else:SI (match_operator 5 "arm_comparison_operator" 10057 [(match_operand 8 "cc_register" "") (const_int 0)]) 10058 (match_operator:SI 6 "shiftable_operator" 10059 [(match_operand:SI 1 "s_register_operand" "r") 10060 (match_operand:SI 2 "arm_rhs_operand" "rI")]) 10061 (match_operator:SI 7 "shiftable_operator" 10062 [(match_operand:SI 3 "s_register_operand" "r") 10063 (match_operand:SI 4 "arm_rhs_operand" "rI")])))] 10064 "TARGET_ARM" 10065 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4" 10066 [(set_attr "conds" "use") 10067 (set_attr "length" "8") 10068 (set_attr "type" "multiple")] 10069) 10070 10071(define_insn "*ifcompare_arith_move" 10072 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10073 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 10074 [(match_operand:SI 2 "s_register_operand" "r,r") 10075 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")]) 10076 (match_operator:SI 7 "shiftable_operator" 10077 [(match_operand:SI 4 "s_register_operand" "r,r") 10078 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")]) 10079 (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) 10080 (clobber (reg:CC CC_REGNUM))] 10081 "TARGET_ARM" 10082 "* 10083 /* If we have an operation where (op x 0) is the identity operation and 10084 the conditional operator is LT or GE and we are comparing against zero and 10085 everything is in registers then we can do this in two instructions. */ 10086 if (operands[3] == const0_rtx 10087 && GET_CODE (operands[7]) != AND 10088 && REG_P (operands[5]) 10089 && REG_P (operands[1]) 10090 && REGNO (operands[1]) == REGNO (operands[4]) 10091 && REGNO (operands[4]) != REGNO (operands[0])) 10092 { 10093 if (GET_CODE (operands[6]) == LT) 10094 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; 10095 else if (GET_CODE (operands[6]) == GE) 10096 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; 10097 } 10098 if (CONST_INT_P (operands[3]) 10099 && !const_ok_for_arm (INTVAL (operands[3]))) 10100 output_asm_insn (\"cmn\\t%2, #%n3\", operands); 10101 else 10102 output_asm_insn (\"cmp\\t%2, %3\", operands); 10103 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands); 10104 if (which_alternative != 0) 10105 return \"mov%D6\\t%0, %1\"; 10106 return \"\"; 10107 " 10108 [(set_attr "conds" "clob") 10109 (set_attr "length" "8,12") 10110 (set_attr "type" "multiple")] 10111) 10112 10113(define_insn "*if_arith_move" 10114 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10115 (if_then_else:SI (match_operator 4 "arm_comparison_operator" 10116 [(match_operand 6 "cc_register" "") (const_int 0)]) 10117 (match_operator:SI 5 "shiftable_operator" 10118 [(match_operand:SI 2 "s_register_operand" "r,r") 10119 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 10120 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))] 10121 "TARGET_ARM" 10122 "@ 10123 %I5%d4\\t%0, %2, %3 10124 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1" 10125 [(set_attr "conds" "use") 10126 (set_attr "length" "4,8") 10127 (set_attr_alternative "type" 10128 [(if_then_else (match_operand 3 "const_int_operand" "") 10129 (const_string "alu_shift_imm" ) 10130 (const_string "alu_shift_reg")) 10131 (const_string "multiple")])] 10132) 10133 10134(define_insn "*ifcompare_move_arith" 10135 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10136 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 10137 [(match_operand:SI 4 "s_register_operand" "r,r") 10138 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10139 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 10140 (match_operator:SI 7 "shiftable_operator" 10141 [(match_operand:SI 2 "s_register_operand" "r,r") 10142 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) 10143 (clobber (reg:CC CC_REGNUM))] 10144 "TARGET_ARM" 10145 "* 10146 /* If we have an operation where (op x 0) is the identity operation and 10147 the conditional operator is LT or GE and we are comparing against zero and 10148 everything is in registers then we can do this in two instructions */ 10149 if (operands[5] == const0_rtx 10150 && GET_CODE (operands[7]) != AND 10151 && REG_P (operands[3]) 10152 && REG_P (operands[1]) 10153 && REGNO (operands[1]) == REGNO (operands[2]) 10154 && REGNO (operands[2]) != REGNO (operands[0])) 10155 { 10156 if (GET_CODE (operands[6]) == GE) 10157 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; 10158 else if (GET_CODE (operands[6]) == LT) 10159 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; 10160 } 10161 10162 if (CONST_INT_P (operands[5]) 10163 && !const_ok_for_arm (INTVAL (operands[5]))) 10164 output_asm_insn (\"cmn\\t%4, #%n5\", operands); 10165 else 10166 output_asm_insn (\"cmp\\t%4, %5\", operands); 10167 10168 if (which_alternative != 0) 10169 output_asm_insn (\"mov%d6\\t%0, %1\", operands); 10170 return \"%I7%D6\\t%0, %2, %3\"; 10171 " 10172 [(set_attr "conds" "clob") 10173 (set_attr "length" "8,12") 10174 (set_attr "type" "multiple")] 10175) 10176 10177(define_insn "*if_move_arith" 10178 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10179 (if_then_else:SI 10180 (match_operator 4 "arm_comparison_operator" 10181 [(match_operand 6 "cc_register" "") (const_int 0)]) 10182 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 10183 (match_operator:SI 5 "shiftable_operator" 10184 [(match_operand:SI 2 "s_register_operand" "r,r") 10185 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))] 10186 "TARGET_ARM" 10187 "@ 10188 %I5%D4\\t%0, %2, %3 10189 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1" 10190 [(set_attr "conds" "use") 10191 (set_attr "length" "4,8") 10192 (set_attr_alternative "type" 10193 [(if_then_else (match_operand 3 "const_int_operand" "") 10194 (const_string "alu_shift_imm" ) 10195 (const_string "alu_shift_reg")) 10196 (const_string "multiple")])] 10197) 10198 10199(define_insn "*ifcompare_move_not" 10200 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10201 (if_then_else:SI 10202 (match_operator 5 "arm_comparison_operator" 10203 [(match_operand:SI 3 "s_register_operand" "r,r") 10204 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10205 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 10206 (not:SI 10207 (match_operand:SI 2 "s_register_operand" "r,r")))) 10208 (clobber (reg:CC CC_REGNUM))] 10209 "TARGET_ARM" 10210 "#" 10211 [(set_attr "conds" "clob") 10212 (set_attr "length" "8,12") 10213 (set_attr "type" "multiple")] 10214) 10215 10216(define_insn "*if_move_not" 10217 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10218 (if_then_else:SI 10219 (match_operator 4 "arm_comparison_operator" 10220 [(match_operand 3 "cc_register" "") (const_int 0)]) 10221 (match_operand:SI 1 "arm_not_operand" "0,?rI,K") 10222 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))] 10223 "TARGET_ARM" 10224 "@ 10225 mvn%D4\\t%0, %2 10226 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2 10227 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2" 10228 [(set_attr "conds" "use") 10229 (set_attr "type" "mvn_reg") 10230 (set_attr "length" "4,8,8") 10231 (set_attr "type" "mvn_reg,multiple,multiple")] 10232) 10233 10234(define_insn "*ifcompare_not_move" 10235 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10236 (if_then_else:SI 10237 (match_operator 5 "arm_comparison_operator" 10238 [(match_operand:SI 3 "s_register_operand" "r,r") 10239 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10240 (not:SI 10241 (match_operand:SI 2 "s_register_operand" "r,r")) 10242 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 10243 (clobber (reg:CC CC_REGNUM))] 10244 "TARGET_ARM" 10245 "#" 10246 [(set_attr "conds" "clob") 10247 (set_attr "length" "8,12") 10248 (set_attr "type" "multiple")] 10249) 10250 10251(define_insn "*if_not_move" 10252 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10253 (if_then_else:SI 10254 (match_operator 4 "arm_comparison_operator" 10255 [(match_operand 3 "cc_register" "") (const_int 0)]) 10256 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r")) 10257 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] 10258 "TARGET_ARM" 10259 "@ 10260 mvn%d4\\t%0, %2 10261 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2 10262 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2" 10263 [(set_attr "conds" "use") 10264 (set_attr "type" "mvn_reg,multiple,multiple") 10265 (set_attr "length" "4,8,8")] 10266) 10267 10268(define_insn "*ifcompare_shift_move" 10269 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10270 (if_then_else:SI 10271 (match_operator 6 "arm_comparison_operator" 10272 [(match_operand:SI 4 "s_register_operand" "r,r") 10273 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10274 (match_operator:SI 7 "shift_operator" 10275 [(match_operand:SI 2 "s_register_operand" "r,r") 10276 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]) 10277 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 10278 (clobber (reg:CC CC_REGNUM))] 10279 "TARGET_ARM" 10280 "#" 10281 [(set_attr "conds" "clob") 10282 (set_attr "length" "8,12") 10283 (set_attr "type" "multiple")] 10284) 10285 10286(define_insn "*if_shift_move" 10287 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10288 (if_then_else:SI 10289 (match_operator 5 "arm_comparison_operator" 10290 [(match_operand 6 "cc_register" "") (const_int 0)]) 10291 (match_operator:SI 4 "shift_operator" 10292 [(match_operand:SI 2 "s_register_operand" "r,r,r") 10293 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")]) 10294 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] 10295 "TARGET_ARM" 10296 "@ 10297 mov%d5\\t%0, %2%S4 10298 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4 10299 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4" 10300 [(set_attr "conds" "use") 10301 (set_attr "shift" "2") 10302 (set_attr "length" "4,8,8") 10303 (set_attr_alternative "type" 10304 [(if_then_else (match_operand 3 "const_int_operand" "") 10305 (const_string "mov_shift" ) 10306 (const_string "mov_shift_reg")) 10307 (const_string "multiple") 10308 (const_string "multiple")])] 10309) 10310 10311(define_insn "*ifcompare_move_shift" 10312 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10313 (if_then_else:SI 10314 (match_operator 6 "arm_comparison_operator" 10315 [(match_operand:SI 4 "s_register_operand" "r,r") 10316 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 10317 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 10318 (match_operator:SI 7 "shift_operator" 10319 [(match_operand:SI 2 "s_register_operand" "r,r") 10320 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]))) 10321 (clobber (reg:CC CC_REGNUM))] 10322 "TARGET_ARM" 10323 "#" 10324 [(set_attr "conds" "clob") 10325 (set_attr "length" "8,12") 10326 (set_attr "type" "multiple")] 10327) 10328 10329(define_insn "*if_move_shift" 10330 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 10331 (if_then_else:SI 10332 (match_operator 5 "arm_comparison_operator" 10333 [(match_operand 6 "cc_register" "") (const_int 0)]) 10334 (match_operand:SI 1 "arm_not_operand" "0,?rI,K") 10335 (match_operator:SI 4 "shift_operator" 10336 [(match_operand:SI 2 "s_register_operand" "r,r,r") 10337 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))] 10338 "TARGET_ARM" 10339 "@ 10340 mov%D5\\t%0, %2%S4 10341 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4 10342 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4" 10343 [(set_attr "conds" "use") 10344 (set_attr "shift" "2") 10345 (set_attr "length" "4,8,8") 10346 (set_attr_alternative "type" 10347 [(if_then_else (match_operand 3 "const_int_operand" "") 10348 (const_string "mov_shift" ) 10349 (const_string "mov_shift_reg")) 10350 (const_string "multiple") 10351 (const_string "multiple")])] 10352) 10353 10354(define_insn "*ifcompare_shift_shift" 10355 [(set (match_operand:SI 0 "s_register_operand" "=r") 10356 (if_then_else:SI 10357 (match_operator 7 "arm_comparison_operator" 10358 [(match_operand:SI 5 "s_register_operand" "r") 10359 (match_operand:SI 6 "arm_add_operand" "rIL")]) 10360 (match_operator:SI 8 "shift_operator" 10361 [(match_operand:SI 1 "s_register_operand" "r") 10362 (match_operand:SI 2 "arm_rhs_operand" "rM")]) 10363 (match_operator:SI 9 "shift_operator" 10364 [(match_operand:SI 3 "s_register_operand" "r") 10365 (match_operand:SI 4 "arm_rhs_operand" "rM")]))) 10366 (clobber (reg:CC CC_REGNUM))] 10367 "TARGET_ARM" 10368 "#" 10369 [(set_attr "conds" "clob") 10370 (set_attr "length" "12") 10371 (set_attr "type" "multiple")] 10372) 10373 10374(define_insn "*if_shift_shift" 10375 [(set (match_operand:SI 0 "s_register_operand" "=r") 10376 (if_then_else:SI 10377 (match_operator 5 "arm_comparison_operator" 10378 [(match_operand 8 "cc_register" "") (const_int 0)]) 10379 (match_operator:SI 6 "shift_operator" 10380 [(match_operand:SI 1 "s_register_operand" "r") 10381 (match_operand:SI 2 "arm_rhs_operand" "rM")]) 10382 (match_operator:SI 7 "shift_operator" 10383 [(match_operand:SI 3 "s_register_operand" "r") 10384 (match_operand:SI 4 "arm_rhs_operand" "rM")])))] 10385 "TARGET_ARM" 10386 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7" 10387 [(set_attr "conds" "use") 10388 (set_attr "shift" "1") 10389 (set_attr "length" "8") 10390 (set (attr "type") (if_then_else 10391 (and (match_operand 2 "const_int_operand" "") 10392 (match_operand 4 "const_int_operand" "")) 10393 (const_string "mov_shift") 10394 (const_string "mov_shift_reg")))] 10395) 10396 10397(define_insn "*ifcompare_not_arith" 10398 [(set (match_operand:SI 0 "s_register_operand" "=r") 10399 (if_then_else:SI 10400 (match_operator 6 "arm_comparison_operator" 10401 [(match_operand:SI 4 "s_register_operand" "r") 10402 (match_operand:SI 5 "arm_add_operand" "rIL")]) 10403 (not:SI (match_operand:SI 1 "s_register_operand" "r")) 10404 (match_operator:SI 7 "shiftable_operator" 10405 [(match_operand:SI 2 "s_register_operand" "r") 10406 (match_operand:SI 3 "arm_rhs_operand" "rI")]))) 10407 (clobber (reg:CC CC_REGNUM))] 10408 "TARGET_ARM" 10409 "#" 10410 [(set_attr "conds" "clob") 10411 (set_attr "length" "12") 10412 (set_attr "type" "multiple")] 10413) 10414 10415(define_insn "*if_not_arith" 10416 [(set (match_operand:SI 0 "s_register_operand" "=r") 10417 (if_then_else:SI 10418 (match_operator 5 "arm_comparison_operator" 10419 [(match_operand 4 "cc_register" "") (const_int 0)]) 10420 (not:SI (match_operand:SI 1 "s_register_operand" "r")) 10421 (match_operator:SI 6 "shiftable_operator" 10422 [(match_operand:SI 2 "s_register_operand" "r") 10423 (match_operand:SI 3 "arm_rhs_operand" "rI")])))] 10424 "TARGET_ARM" 10425 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3" 10426 [(set_attr "conds" "use") 10427 (set_attr "type" "mvn_reg") 10428 (set_attr "length" "8")] 10429) 10430 10431(define_insn "*ifcompare_arith_not" 10432 [(set (match_operand:SI 0 "s_register_operand" "=r") 10433 (if_then_else:SI 10434 (match_operator 6 "arm_comparison_operator" 10435 [(match_operand:SI 4 "s_register_operand" "r") 10436 (match_operand:SI 5 "arm_add_operand" "rIL")]) 10437 (match_operator:SI 7 "shiftable_operator" 10438 [(match_operand:SI 2 "s_register_operand" "r") 10439 (match_operand:SI 3 "arm_rhs_operand" "rI")]) 10440 (not:SI (match_operand:SI 1 "s_register_operand" "r")))) 10441 (clobber (reg:CC CC_REGNUM))] 10442 "TARGET_ARM" 10443 "#" 10444 [(set_attr "conds" "clob") 10445 (set_attr "length" "12") 10446 (set_attr "type" "multiple")] 10447) 10448 10449(define_insn "*if_arith_not" 10450 [(set (match_operand:SI 0 "s_register_operand" "=r") 10451 (if_then_else:SI 10452 (match_operator 5 "arm_comparison_operator" 10453 [(match_operand 4 "cc_register" "") (const_int 0)]) 10454 (match_operator:SI 6 "shiftable_operator" 10455 [(match_operand:SI 2 "s_register_operand" "r") 10456 (match_operand:SI 3 "arm_rhs_operand" "rI")]) 10457 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))] 10458 "TARGET_ARM" 10459 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3" 10460 [(set_attr "conds" "use") 10461 (set_attr "type" "multiple") 10462 (set_attr "length" "8")] 10463) 10464 10465(define_insn "*ifcompare_neg_move" 10466 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10467 (if_then_else:SI 10468 (match_operator 5 "arm_comparison_operator" 10469 [(match_operand:SI 3 "s_register_operand" "r,r") 10470 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10471 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")) 10472 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 10473 (clobber (reg:CC CC_REGNUM))] 10474 "TARGET_ARM" 10475 "#" 10476 [(set_attr "conds" "clob") 10477 (set_attr "length" "8,12") 10478 (set_attr "type" "multiple")] 10479) 10480 10481(define_insn_and_split "*if_neg_move" 10482 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 10483 (if_then_else:SI 10484 (match_operator 4 "arm_comparison_operator" 10485 [(match_operand 3 "cc_register" "") (const_int 0)]) 10486 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r")) 10487 (match_operand:SI 1 "s_register_operand" "0,0")))] 10488 "TARGET_32BIT" 10489 "#" 10490 "&& reload_completed" 10491 [(cond_exec (match_op_dup 4 [(match_dup 3) (const_int 0)]) 10492 (set (match_dup 0) (neg:SI (match_dup 2))))] 10493 "" 10494 [(set_attr "conds" "use") 10495 (set_attr "length" "4") 10496 (set_attr "arch" "t2,32") 10497 (set_attr "enabled_for_short_it" "yes,no") 10498 (set_attr "type" "logic_shift_imm")] 10499) 10500 10501(define_insn "*ifcompare_move_neg" 10502 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10503 (if_then_else:SI 10504 (match_operator 5 "arm_comparison_operator" 10505 [(match_operand:SI 3 "s_register_operand" "r,r") 10506 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 10507 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 10508 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")))) 10509 (clobber (reg:CC CC_REGNUM))] 10510 "TARGET_ARM" 10511 "#" 10512 [(set_attr "conds" "clob") 10513 (set_attr "length" "8,12") 10514 (set_attr "type" "multiple")] 10515) 10516 10517(define_insn_and_split "*if_move_neg" 10518 [(set (match_operand:SI 0 "s_register_operand" "=l,r") 10519 (if_then_else:SI 10520 (match_operator 4 "arm_comparison_operator" 10521 [(match_operand 3 "cc_register" "") (const_int 0)]) 10522 (match_operand:SI 1 "s_register_operand" "0,0") 10523 (neg:SI (match_operand:SI 2 "s_register_operand" "l,r"))))] 10524 "TARGET_32BIT" 10525 "#" 10526 "&& reload_completed" 10527 [(cond_exec (match_dup 5) 10528 (set (match_dup 0) (neg:SI (match_dup 2))))] 10529 { 10530 machine_mode mode = GET_MODE (operands[3]); 10531 rtx_code rc = GET_CODE (operands[4]); 10532 10533 if (mode == CCFPmode || mode == CCFPEmode) 10534 rc = reverse_condition_maybe_unordered (rc); 10535 else 10536 rc = reverse_condition (rc); 10537 10538 operands[5] = gen_rtx_fmt_ee (rc, VOIDmode, operands[3], const0_rtx); 10539 } 10540 [(set_attr "conds" "use") 10541 (set_attr "length" "4") 10542 (set_attr "arch" "t2,32") 10543 (set_attr "enabled_for_short_it" "yes,no") 10544 (set_attr "type" "logic_shift_imm")] 10545) 10546 10547(define_insn "*arith_adjacentmem" 10548 [(set (match_operand:SI 0 "s_register_operand" "=r") 10549 (match_operator:SI 1 "shiftable_operator" 10550 [(match_operand:SI 2 "memory_operand" "m") 10551 (match_operand:SI 3 "memory_operand" "m")])) 10552 (clobber (match_scratch:SI 4 "=r"))] 10553 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])" 10554 "* 10555 { 10556 rtx ldm[3]; 10557 rtx arith[4]; 10558 rtx base_reg; 10559 HOST_WIDE_INT val1 = 0, val2 = 0; 10560 10561 if (REGNO (operands[0]) > REGNO (operands[4])) 10562 { 10563 ldm[1] = operands[4]; 10564 ldm[2] = operands[0]; 10565 } 10566 else 10567 { 10568 ldm[1] = operands[0]; 10569 ldm[2] = operands[4]; 10570 } 10571 10572 base_reg = XEXP (operands[2], 0); 10573 10574 if (!REG_P (base_reg)) 10575 { 10576 val1 = INTVAL (XEXP (base_reg, 1)); 10577 base_reg = XEXP (base_reg, 0); 10578 } 10579 10580 if (!REG_P (XEXP (operands[3], 0))) 10581 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1)); 10582 10583 arith[0] = operands[0]; 10584 arith[3] = operands[1]; 10585 10586 if (val1 < val2) 10587 { 10588 arith[1] = ldm[1]; 10589 arith[2] = ldm[2]; 10590 } 10591 else 10592 { 10593 arith[1] = ldm[2]; 10594 arith[2] = ldm[1]; 10595 } 10596 10597 ldm[0] = base_reg; 10598 if (val1 !=0 && val2 != 0) 10599 { 10600 rtx ops[3]; 10601 10602 if (val1 == 4 || val2 == 4) 10603 /* Other val must be 8, since we know they are adjacent and neither 10604 is zero. */ 10605 output_asm_insn (\"ldmib%?\\t%0, {%1, %2}\", ldm); 10606 else if (const_ok_for_arm (val1) || const_ok_for_arm (-val1)) 10607 { 10608 ldm[0] = ops[0] = operands[4]; 10609 ops[1] = base_reg; 10610 ops[2] = GEN_INT (val1); 10611 output_add_immediate (ops); 10612 if (val1 < val2) 10613 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm); 10614 else 10615 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm); 10616 } 10617 else 10618 { 10619 /* Offset is out of range for a single add, so use two ldr. */ 10620 ops[0] = ldm[1]; 10621 ops[1] = base_reg; 10622 ops[2] = GEN_INT (val1); 10623 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops); 10624 ops[0] = ldm[2]; 10625 ops[2] = GEN_INT (val2); 10626 output_asm_insn (\"ldr%?\\t%0, [%1, %2]\", ops); 10627 } 10628 } 10629 else if (val1 != 0) 10630 { 10631 if (val1 < val2) 10632 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm); 10633 else 10634 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm); 10635 } 10636 else 10637 { 10638 if (val1 < val2) 10639 output_asm_insn (\"ldmia%?\\t%0, {%1, %2}\", ldm); 10640 else 10641 output_asm_insn (\"ldmda%?\\t%0, {%1, %2}\", ldm); 10642 } 10643 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith); 10644 return \"\"; 10645 }" 10646 [(set_attr "length" "12") 10647 (set_attr "predicable" "yes") 10648 (set_attr "type" "load_4")] 10649) 10650 10651; This pattern is never tried by combine, so do it as a peephole 10652 10653(define_peephole2 10654 [(set (match_operand:SI 0 "arm_general_register_operand" "") 10655 (match_operand:SI 1 "arm_general_register_operand" "")) 10656 (set (reg:CC CC_REGNUM) 10657 (compare:CC (match_dup 1) (const_int 0)))] 10658 "TARGET_ARM" 10659 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0))) 10660 (set (match_dup 0) (match_dup 1))])] 10661 "" 10662) 10663 10664(define_split 10665 [(set (match_operand:SI 0 "s_register_operand" "") 10666 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "") 10667 (const_int 0)) 10668 (neg:SI (match_operator:SI 2 "arm_comparison_operator" 10669 [(match_operand:SI 3 "s_register_operand" "") 10670 (match_operand:SI 4 "arm_rhs_operand" "")])))) 10671 (clobber (match_operand:SI 5 "s_register_operand" ""))] 10672 "TARGET_ARM" 10673 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31)))) 10674 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) 10675 (match_dup 5)))] 10676 "" 10677) 10678 10679;; This split can be used because CC_Z mode implies that the following 10680;; branch will be an equality, or an unsigned inequality, so the sign 10681;; extension is not needed. 10682 10683(define_split 10684 [(set (reg:CC_Z CC_REGNUM) 10685 (compare:CC_Z 10686 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0) 10687 (const_int 24)) 10688 (match_operand 1 "const_int_operand" ""))) 10689 (clobber (match_scratch:SI 2 ""))] 10690 "TARGET_ARM 10691 && ((UINTVAL (operands[1])) 10692 == ((UINTVAL (operands[1])) >> 24) << 24)" 10693 [(set (match_dup 2) (zero_extend:SI (match_dup 0))) 10694 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))] 10695 " 10696 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24); 10697 " 10698) 10699;; ??? Check the patterns above for Thumb-2 usefulness 10700 10701(define_expand "prologue" 10702 [(clobber (const_int 0))] 10703 "TARGET_EITHER" 10704 "if (TARGET_32BIT) 10705 arm_expand_prologue (); 10706 else 10707 thumb1_expand_prologue (); 10708 DONE; 10709 " 10710) 10711 10712(define_expand "epilogue" 10713 [(clobber (const_int 0))] 10714 "TARGET_EITHER" 10715 " 10716 if (crtl->calls_eh_return) 10717 emit_insn (gen_force_register_use (gen_rtx_REG (Pmode, 2))); 10718 if (TARGET_THUMB1) 10719 { 10720 thumb1_expand_epilogue (); 10721 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, 10722 gen_rtvec (1, ret_rtx), VUNSPEC_EPILOGUE)); 10723 } 10724 else if (HAVE_return) 10725 { 10726 /* HAVE_return is testing for USE_RETURN_INSN (FALSE). Hence, 10727 no need for explicit testing again. */ 10728 emit_jump_insn (gen_return ()); 10729 } 10730 else if (TARGET_32BIT) 10731 { 10732 arm_expand_epilogue (true); 10733 } 10734 DONE; 10735 " 10736) 10737 10738;; Note - although unspec_volatile's USE all hard registers, 10739;; USEs are ignored after relaod has completed. Thus we need 10740;; to add an unspec of the link register to ensure that flow 10741;; does not think that it is unused by the sibcall branch that 10742;; will replace the standard function epilogue. 10743(define_expand "sibcall_epilogue" 10744 [(parallel [(unspec:SI [(reg:SI LR_REGNUM)] UNSPEC_REGISTER_USE) 10745 (unspec_volatile [(return)] VUNSPEC_EPILOGUE)])] 10746 "TARGET_32BIT" 10747 " 10748 arm_expand_epilogue (false); 10749 DONE; 10750 " 10751) 10752 10753(define_expand "eh_epilogue" 10754 [(use (match_operand:SI 0 "register_operand" "")) 10755 (use (match_operand:SI 1 "register_operand" "")) 10756 (use (match_operand:SI 2 "register_operand" ""))] 10757 "TARGET_EITHER" 10758 " 10759 { 10760 cfun->machine->eh_epilogue_sp_ofs = operands[1]; 10761 if (!REG_P (operands[2]) || REGNO (operands[2]) != 2) 10762 { 10763 rtx ra = gen_rtx_REG (Pmode, 2); 10764 10765 emit_move_insn (ra, operands[2]); 10766 operands[2] = ra; 10767 } 10768 /* This is a hack -- we may have crystalized the function type too 10769 early. */ 10770 cfun->machine->func_type = 0; 10771 }" 10772) 10773 10774;; This split is only used during output to reduce the number of patterns 10775;; that need assembler instructions adding to them. We allowed the setting 10776;; of the conditions to be implicit during rtl generation so that 10777;; the conditional compare patterns would work. However this conflicts to 10778;; some extent with the conditional data operations, so we have to split them 10779;; up again here. 10780 10781;; ??? Need to audit these splitters for Thumb-2. Why isn't normal 10782;; conditional execution sufficient? 10783 10784(define_split 10785 [(set (match_operand:SI 0 "s_register_operand" "") 10786 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 10787 [(match_operand 2 "" "") (match_operand 3 "" "")]) 10788 (match_dup 0) 10789 (match_operand 4 "" ""))) 10790 (clobber (reg:CC CC_REGNUM))] 10791 "TARGET_ARM && reload_completed" 10792 [(set (match_dup 5) (match_dup 6)) 10793 (cond_exec (match_dup 7) 10794 (set (match_dup 0) (match_dup 4)))] 10795 " 10796 { 10797 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 10798 operands[2], operands[3]); 10799 enum rtx_code rc = GET_CODE (operands[1]); 10800 10801 operands[5] = gen_rtx_REG (mode, CC_REGNUM); 10802 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 10803 if (mode == CCFPmode || mode == CCFPEmode) 10804 rc = reverse_condition_maybe_unordered (rc); 10805 else 10806 rc = reverse_condition (rc); 10807 10808 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx); 10809 }" 10810) 10811 10812(define_split 10813 [(set (match_operand:SI 0 "s_register_operand" "") 10814 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 10815 [(match_operand 2 "" "") (match_operand 3 "" "")]) 10816 (match_operand 4 "" "") 10817 (match_dup 0))) 10818 (clobber (reg:CC CC_REGNUM))] 10819 "TARGET_ARM && reload_completed" 10820 [(set (match_dup 5) (match_dup 6)) 10821 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)]) 10822 (set (match_dup 0) (match_dup 4)))] 10823 " 10824 { 10825 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 10826 operands[2], operands[3]); 10827 10828 operands[5] = gen_rtx_REG (mode, CC_REGNUM); 10829 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 10830 }" 10831) 10832 10833(define_split 10834 [(set (match_operand:SI 0 "s_register_operand" "") 10835 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 10836 [(match_operand 2 "" "") (match_operand 3 "" "")]) 10837 (match_operand 4 "" "") 10838 (match_operand 5 "" ""))) 10839 (clobber (reg:CC CC_REGNUM))] 10840 "TARGET_ARM && reload_completed" 10841 [(set (match_dup 6) (match_dup 7)) 10842 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) 10843 (set (match_dup 0) (match_dup 4))) 10844 (cond_exec (match_dup 8) 10845 (set (match_dup 0) (match_dup 5)))] 10846 " 10847 { 10848 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 10849 operands[2], operands[3]); 10850 enum rtx_code rc = GET_CODE (operands[1]); 10851 10852 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 10853 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 10854 if (mode == CCFPmode || mode == CCFPEmode) 10855 rc = reverse_condition_maybe_unordered (rc); 10856 else 10857 rc = reverse_condition (rc); 10858 10859 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 10860 }" 10861) 10862 10863(define_split 10864 [(set (match_operand:SI 0 "s_register_operand" "") 10865 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 10866 [(match_operand:SI 2 "s_register_operand" "") 10867 (match_operand:SI 3 "arm_add_operand" "")]) 10868 (match_operand:SI 4 "arm_rhs_operand" "") 10869 (not:SI 10870 (match_operand:SI 5 "s_register_operand" "")))) 10871 (clobber (reg:CC CC_REGNUM))] 10872 "TARGET_ARM && reload_completed" 10873 [(set (match_dup 6) (match_dup 7)) 10874 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) 10875 (set (match_dup 0) (match_dup 4))) 10876 (cond_exec (match_dup 8) 10877 (set (match_dup 0) (not:SI (match_dup 5))))] 10878 " 10879 { 10880 machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 10881 operands[2], operands[3]); 10882 enum rtx_code rc = GET_CODE (operands[1]); 10883 10884 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 10885 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 10886 if (mode == CCFPmode || mode == CCFPEmode) 10887 rc = reverse_condition_maybe_unordered (rc); 10888 else 10889 rc = reverse_condition (rc); 10890 10891 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 10892 }" 10893) 10894 10895(define_insn "*cond_move_not" 10896 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 10897 (if_then_else:SI (match_operator 4 "arm_comparison_operator" 10898 [(match_operand 3 "cc_register" "") (const_int 0)]) 10899 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 10900 (not:SI 10901 (match_operand:SI 2 "s_register_operand" "r,r"))))] 10902 "TARGET_ARM" 10903 "@ 10904 mvn%D4\\t%0, %2 10905 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2" 10906 [(set_attr "conds" "use") 10907 (set_attr "type" "mvn_reg,multiple") 10908 (set_attr "length" "4,8")] 10909) 10910 10911;; The next two patterns occur when an AND operation is followed by a 10912;; scc insn sequence 10913 10914(define_insn "*sign_extract_onebit" 10915 [(set (match_operand:SI 0 "s_register_operand" "=r") 10916 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 10917 (const_int 1) 10918 (match_operand:SI 2 "const_int_operand" "n"))) 10919 (clobber (reg:CC CC_REGNUM))] 10920 "TARGET_ARM" 10921 "* 10922 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10923 output_asm_insn (\"ands\\t%0, %1, %2\", operands); 10924 return \"mvnne\\t%0, #0\"; 10925 " 10926 [(set_attr "conds" "clob") 10927 (set_attr "length" "8") 10928 (set_attr "type" "multiple")] 10929) 10930 10931(define_insn "*not_signextract_onebit" 10932 [(set (match_operand:SI 0 "s_register_operand" "=r") 10933 (not:SI 10934 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 10935 (const_int 1) 10936 (match_operand:SI 2 "const_int_operand" "n")))) 10937 (clobber (reg:CC CC_REGNUM))] 10938 "TARGET_ARM" 10939 "* 10940 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 10941 output_asm_insn (\"tst\\t%1, %2\", operands); 10942 output_asm_insn (\"mvneq\\t%0, #0\", operands); 10943 return \"movne\\t%0, #0\"; 10944 " 10945 [(set_attr "conds" "clob") 10946 (set_attr "length" "12") 10947 (set_attr "type" "multiple")] 10948) 10949;; ??? The above patterns need auditing for Thumb-2 10950 10951;; Push multiple registers to the stack. Registers are in parallel (use ...) 10952;; expressions. For simplicity, the first register is also in the unspec 10953;; part. 10954;; To avoid the usage of GNU extension, the length attribute is computed 10955;; in a C function arm_attr_length_push_multi. 10956(define_insn "*push_multi" 10957 [(match_parallel 2 "multi_register_push" 10958 [(set (match_operand:BLK 0 "push_mult_memory_operand" "") 10959 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "")] 10960 UNSPEC_PUSH_MULT))])] 10961 "" 10962 "* 10963 { 10964 int num_saves = XVECLEN (operands[2], 0); 10965 10966 /* For the StrongARM at least it is faster to 10967 use STR to store only a single register. 10968 In Thumb mode always use push, and the assembler will pick 10969 something appropriate. */ 10970 if (num_saves == 1 && TARGET_ARM) 10971 output_asm_insn (\"str%?\\t%1, [%m0, #-4]!\", operands); 10972 else 10973 { 10974 int i; 10975 char pattern[100]; 10976 10977 if (TARGET_32BIT) 10978 strcpy (pattern, \"push%?\\t{%1\"); 10979 else 10980 strcpy (pattern, \"push\\t{%1\"); 10981 10982 for (i = 1; i < num_saves; i++) 10983 { 10984 strcat (pattern, \", %|\"); 10985 strcat (pattern, 10986 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]); 10987 } 10988 10989 strcat (pattern, \"}\"); 10990 output_asm_insn (pattern, operands); 10991 } 10992 10993 return \"\"; 10994 }" 10995 [(set_attr "type" "store_16") 10996 (set (attr "length") 10997 (symbol_ref "arm_attr_length_push_multi (operands[2], operands[1])"))] 10998) 10999 11000(define_insn "stack_tie" 11001 [(set (mem:BLK (scratch)) 11002 (unspec:BLK [(match_operand:SI 0 "s_register_operand" "rk") 11003 (match_operand:SI 1 "s_register_operand" "rk")] 11004 UNSPEC_PRLG_STK))] 11005 "" 11006 "" 11007 [(set_attr "length" "0") 11008 (set_attr "type" "block")] 11009) 11010 11011;; Pop (as used in epilogue RTL) 11012;; 11013(define_insn "*load_multiple_with_writeback" 11014 [(match_parallel 0 "load_multiple_operation" 11015 [(set (match_operand:SI 1 "s_register_operand" "+rk") 11016 (plus:SI (match_dup 1) 11017 (match_operand:SI 2 "const_int_I_operand" "I"))) 11018 (set (match_operand:SI 3 "s_register_operand" "=rk") 11019 (mem:SI (match_dup 1))) 11020 ])] 11021 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11022 "* 11023 { 11024 arm_output_multireg_pop (operands, /*return_pc=*/false, 11025 /*cond=*/const_true_rtx, 11026 /*reverse=*/false, 11027 /*update=*/true); 11028 return \"\"; 11029 } 11030 " 11031 [(set_attr "type" "load_16") 11032 (set_attr "predicable" "yes") 11033 (set (attr "length") 11034 (symbol_ref "arm_attr_length_pop_multi (operands, 11035 /*return_pc=*/false, 11036 /*write_back_p=*/true)"))] 11037) 11038 11039;; Pop with return (as used in epilogue RTL) 11040;; 11041;; This instruction is generated when the registers are popped at the end of 11042;; epilogue. Here, instead of popping the value into LR and then generating 11043;; jump to LR, value is popped into PC directly. Hence, the pattern is combined 11044;; with (return). 11045(define_insn "*pop_multiple_with_writeback_and_return" 11046 [(match_parallel 0 "pop_multiple_return" 11047 [(return) 11048 (set (match_operand:SI 1 "s_register_operand" "+rk") 11049 (plus:SI (match_dup 1) 11050 (match_operand:SI 2 "const_int_I_operand" "I"))) 11051 (set (match_operand:SI 3 "s_register_operand" "=rk") 11052 (mem:SI (match_dup 1))) 11053 ])] 11054 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11055 "* 11056 { 11057 arm_output_multireg_pop (operands, /*return_pc=*/true, 11058 /*cond=*/const_true_rtx, 11059 /*reverse=*/false, 11060 /*update=*/true); 11061 return \"\"; 11062 } 11063 " 11064 [(set_attr "type" "load_16") 11065 (set_attr "predicable" "yes") 11066 (set (attr "length") 11067 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true, 11068 /*write_back_p=*/true)"))] 11069) 11070 11071(define_insn "*pop_multiple_with_return" 11072 [(match_parallel 0 "pop_multiple_return" 11073 [(return) 11074 (set (match_operand:SI 2 "s_register_operand" "=rk") 11075 (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) 11076 ])] 11077 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11078 "* 11079 { 11080 arm_output_multireg_pop (operands, /*return_pc=*/true, 11081 /*cond=*/const_true_rtx, 11082 /*reverse=*/false, 11083 /*update=*/false); 11084 return \"\"; 11085 } 11086 " 11087 [(set_attr "type" "load_16") 11088 (set_attr "predicable" "yes") 11089 (set (attr "length") 11090 (symbol_ref "arm_attr_length_pop_multi (operands, /*return_pc=*/true, 11091 /*write_back_p=*/false)"))] 11092) 11093 11094;; Load into PC and return 11095(define_insn "*ldr_with_return" 11096 [(return) 11097 (set (reg:SI PC_REGNUM) 11098 (mem:SI (post_inc:SI (match_operand:SI 0 "s_register_operand" "+rk"))))] 11099 "TARGET_32BIT && (reload_in_progress || reload_completed)" 11100 "ldr%?\t%|pc, [%0], #4" 11101 [(set_attr "type" "load_4") 11102 (set_attr "predicable" "yes")] 11103) 11104;; Pop for floating point registers (as used in epilogue RTL) 11105(define_insn "*vfp_pop_multiple_with_writeback" 11106 [(match_parallel 0 "pop_multiple_fp" 11107 [(set (match_operand:SI 1 "s_register_operand" "+rk") 11108 (plus:SI (match_dup 1) 11109 (match_operand:SI 2 "const_int_I_operand" "I"))) 11110 (set (match_operand:DF 3 "vfp_hard_register_operand" "") 11111 (mem:DF (match_dup 1)))])] 11112 "TARGET_32BIT && TARGET_HARD_FLOAT" 11113 "* 11114 { 11115 int num_regs = XVECLEN (operands[0], 0); 11116 char pattern[100]; 11117 rtx op_list[2]; 11118 strcpy (pattern, \"vldm\\t\"); 11119 strcat (pattern, reg_names[REGNO (SET_DEST (XVECEXP (operands[0], 0, 0)))]); 11120 strcat (pattern, \"!, {\"); 11121 op_list[0] = XEXP (XVECEXP (operands[0], 0, 1), 0); 11122 strcat (pattern, \"%P0\"); 11123 if ((num_regs - 1) > 1) 11124 { 11125 strcat (pattern, \"-%P1\"); 11126 op_list [1] = XEXP (XVECEXP (operands[0], 0, num_regs - 1), 0); 11127 } 11128 11129 strcat (pattern, \"}\"); 11130 output_asm_insn (pattern, op_list); 11131 return \"\"; 11132 } 11133 " 11134 [(set_attr "type" "load_16") 11135 (set_attr "conds" "unconditional") 11136 (set_attr "predicable" "no")] 11137) 11138 11139;; Special patterns for dealing with the constant pool 11140 11141(define_insn "align_4" 11142 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)] 11143 "TARGET_EITHER" 11144 "* 11145 assemble_align (32); 11146 return \"\"; 11147 " 11148 [(set_attr "type" "no_insn")] 11149) 11150 11151(define_insn "align_8" 11152 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN8)] 11153 "TARGET_EITHER" 11154 "* 11155 assemble_align (64); 11156 return \"\"; 11157 " 11158 [(set_attr "type" "no_insn")] 11159) 11160 11161(define_insn "consttable_end" 11162 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)] 11163 "TARGET_EITHER" 11164 "* 11165 making_const_table = FALSE; 11166 return \"\"; 11167 " 11168 [(set_attr "type" "no_insn")] 11169) 11170 11171(define_insn "consttable_1" 11172 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)] 11173 "TARGET_EITHER" 11174 "* 11175 making_const_table = TRUE; 11176 assemble_integer (operands[0], 1, BITS_PER_WORD, 1); 11177 assemble_zeros (3); 11178 return \"\"; 11179 " 11180 [(set_attr "length" "4") 11181 (set_attr "type" "no_insn")] 11182) 11183 11184(define_insn "consttable_2" 11185 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)] 11186 "TARGET_EITHER" 11187 "* 11188 { 11189 rtx x = operands[0]; 11190 making_const_table = TRUE; 11191 switch (GET_MODE_CLASS (GET_MODE (x))) 11192 { 11193 case MODE_FLOAT: 11194 arm_emit_fp16_const (x); 11195 break; 11196 default: 11197 assemble_integer (operands[0], 2, BITS_PER_WORD, 1); 11198 assemble_zeros (2); 11199 break; 11200 } 11201 return \"\"; 11202 }" 11203 [(set_attr "length" "4") 11204 (set_attr "type" "no_insn")] 11205) 11206 11207(define_insn "consttable_4" 11208 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)] 11209 "TARGET_EITHER" 11210 "* 11211 { 11212 rtx x = operands[0]; 11213 making_const_table = TRUE; 11214 scalar_float_mode float_mode; 11215 if (is_a <scalar_float_mode> (GET_MODE (x), &float_mode)) 11216 assemble_real (*CONST_DOUBLE_REAL_VALUE (x), float_mode, BITS_PER_WORD); 11217 else 11218 { 11219 /* XXX: Sometimes gcc does something really dumb and ends up with 11220 a HIGH in a constant pool entry, usually because it's trying to 11221 load into a VFP register. We know this will always be used in 11222 combination with a LO_SUM which ignores the high bits, so just 11223 strip off the HIGH. */ 11224 if (GET_CODE (x) == HIGH) 11225 x = XEXP (x, 0); 11226 assemble_integer (x, 4, BITS_PER_WORD, 1); 11227 mark_symbol_refs_as_used (x); 11228 } 11229 return \"\"; 11230 }" 11231 [(set_attr "length" "4") 11232 (set_attr "type" "no_insn")] 11233) 11234 11235(define_insn "consttable_8" 11236 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)] 11237 "TARGET_EITHER" 11238 "* 11239 { 11240 making_const_table = TRUE; 11241 scalar_float_mode float_mode; 11242 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode)) 11243 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]), 11244 float_mode, BITS_PER_WORD); 11245 else 11246 assemble_integer (operands[0], 8, BITS_PER_WORD, 1); 11247 return \"\"; 11248 }" 11249 [(set_attr "length" "8") 11250 (set_attr "type" "no_insn")] 11251) 11252 11253(define_insn "consttable_16" 11254 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_16)] 11255 "TARGET_EITHER" 11256 "* 11257 { 11258 making_const_table = TRUE; 11259 scalar_float_mode float_mode; 11260 if (is_a <scalar_float_mode> (GET_MODE (operands[0]), &float_mode)) 11261 assemble_real (*CONST_DOUBLE_REAL_VALUE (operands[0]), 11262 float_mode, BITS_PER_WORD); 11263 else 11264 assemble_integer (operands[0], 16, BITS_PER_WORD, 1); 11265 return \"\"; 11266 }" 11267 [(set_attr "length" "16") 11268 (set_attr "type" "no_insn")] 11269) 11270 11271;; V5 Instructions, 11272 11273(define_insn "clzsi2" 11274 [(set (match_operand:SI 0 "s_register_operand" "=r") 11275 (clz:SI (match_operand:SI 1 "s_register_operand" "r")))] 11276 "TARGET_32BIT && arm_arch5" 11277 "clz%?\\t%0, %1" 11278 [(set_attr "predicable" "yes") 11279 (set_attr "type" "clz")]) 11280 11281(define_insn "rbitsi2" 11282 [(set (match_operand:SI 0 "s_register_operand" "=r") 11283 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] UNSPEC_RBIT))] 11284 "TARGET_32BIT && arm_arch_thumb2" 11285 "rbit%?\\t%0, %1" 11286 [(set_attr "predicable" "yes") 11287 (set_attr "type" "clz")]) 11288 11289;; Keep this as a CTZ expression until after reload and then split 11290;; into RBIT + CLZ. Since RBIT is represented as an UNSPEC it is unlikely 11291;; to fold with any other expression. 11292 11293(define_insn_and_split "ctzsi2" 11294 [(set (match_operand:SI 0 "s_register_operand" "=r") 11295 (ctz:SI (match_operand:SI 1 "s_register_operand" "r")))] 11296 "TARGET_32BIT && arm_arch_thumb2" 11297 "#" 11298 "&& reload_completed" 11299 [(const_int 0)] 11300 " 11301 emit_insn (gen_rbitsi2 (operands[0], operands[1])); 11302 emit_insn (gen_clzsi2 (operands[0], operands[0])); 11303 DONE; 11304") 11305 11306;; V5E instructions. 11307 11308(define_insn "prefetch" 11309 [(prefetch (match_operand:SI 0 "address_operand" "p") 11310 (match_operand:SI 1 "" "") 11311 (match_operand:SI 2 "" ""))] 11312 "TARGET_32BIT && arm_arch5e" 11313 "pld\\t%a0" 11314 [(set_attr "type" "load_4")] 11315) 11316 11317;; General predication pattern 11318 11319(define_cond_exec 11320 [(match_operator 0 "arm_comparison_operator" 11321 [(match_operand 1 "cc_register" "") 11322 (const_int 0)])] 11323 "TARGET_32BIT 11324 && (!TARGET_NO_VOLATILE_CE || !volatile_refs_p (PATTERN (insn)))" 11325 "" 11326[(set_attr "predicated" "yes")] 11327) 11328 11329(define_insn "force_register_use" 11330 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_REGISTER_USE)] 11331 "" 11332 "%@ %0 needed" 11333 [(set_attr "length" "0") 11334 (set_attr "type" "no_insn")] 11335) 11336 11337 11338;; Patterns for exception handling 11339 11340(define_expand "eh_return" 11341 [(use (match_operand 0 "general_operand" ""))] 11342 "TARGET_EITHER" 11343 " 11344 { 11345 if (TARGET_32BIT) 11346 emit_insn (gen_arm_eh_return (operands[0])); 11347 else 11348 emit_insn (gen_thumb_eh_return (operands[0])); 11349 DONE; 11350 }" 11351) 11352 11353;; We can't expand this before we know where the link register is stored. 11354(define_insn_and_split "arm_eh_return" 11355 [(unspec_volatile [(match_operand:SI 0 "s_register_operand" "r")] 11356 VUNSPEC_EH_RETURN) 11357 (clobber (match_scratch:SI 1 "=&r"))] 11358 "TARGET_ARM" 11359 "#" 11360 "&& reload_completed" 11361 [(const_int 0)] 11362 " 11363 { 11364 arm_set_return_address (operands[0], operands[1]); 11365 DONE; 11366 }" 11367) 11368 11369 11370;; TLS support 11371 11372(define_insn "load_tp_hard" 11373 [(set (match_operand:SI 0 "register_operand" "=r") 11374 (unspec:SI [(const_int 0)] UNSPEC_TLS))] 11375 "TARGET_HARD_TP" 11376 "mrc%?\\tp15, 0, %0, c13, c0, 3\\t@ load_tp_hard" 11377 [(set_attr "predicable" "yes") 11378 (set_attr "type" "mrs")] 11379) 11380 11381;; Doesn't clobber R1-R3. Must use r0 for the first operand. 11382(define_insn "load_tp_soft" 11383 [(set (reg:SI 0) (unspec:SI [(const_int 0)] UNSPEC_TLS)) 11384 (clobber (reg:SI LR_REGNUM)) 11385 (clobber (reg:SI IP_REGNUM)) 11386 (clobber (reg:CC CC_REGNUM))] 11387 "TARGET_SOFT_TP" 11388 "bl\\t__aeabi_read_tp\\t@ load_tp_soft" 11389 [(set_attr "conds" "clob") 11390 (set_attr "type" "branch")] 11391) 11392 11393;; tls descriptor call 11394(define_insn "tlscall" 11395 [(set (reg:SI R0_REGNUM) 11396 (unspec:SI [(reg:SI R0_REGNUM) 11397 (match_operand:SI 0 "" "X") 11398 (match_operand 1 "" "")] UNSPEC_TLS)) 11399 (clobber (reg:SI R1_REGNUM)) 11400 (clobber (reg:SI LR_REGNUM)) 11401 (clobber (reg:SI CC_REGNUM))] 11402 "TARGET_GNU2_TLS" 11403 { 11404 targetm.asm_out.internal_label (asm_out_file, "LPIC", 11405 INTVAL (operands[1])); 11406 return "bl\\t%c0(tlscall)"; 11407 } 11408 [(set_attr "conds" "clob") 11409 (set_attr "length" "4") 11410 (set_attr "type" "branch")] 11411) 11412 11413;; For thread pointer builtin 11414(define_expand "get_thread_pointersi" 11415 [(match_operand:SI 0 "s_register_operand" "=r")] 11416 "" 11417 " 11418 { 11419 arm_load_tp (operands[0]); 11420 DONE; 11421 }") 11422 11423;; 11424 11425;; We only care about the lower 16 bits of the constant 11426;; being inserted into the upper 16 bits of the register. 11427(define_insn "*arm_movtas_ze" 11428 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "+r,r") 11429 (const_int 16) 11430 (const_int 16)) 11431 (match_operand:SI 1 "const_int_operand" ""))] 11432 "TARGET_HAVE_MOVT" 11433 "@ 11434 movt%?\t%0, %L1 11435 movt\t%0, %L1" 11436 [(set_attr "arch" "32,v8mb") 11437 (set_attr "predicable" "yes") 11438 (set_attr "length" "4") 11439 (set_attr "type" "alu_sreg")] 11440) 11441 11442(define_insn "*arm_rev" 11443 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") 11444 (bswap:SI (match_operand:SI 1 "s_register_operand" "l,l,r")))] 11445 "arm_arch6" 11446 "@ 11447 rev\t%0, %1 11448 rev%?\t%0, %1 11449 rev%?\t%0, %1" 11450 [(set_attr "arch" "t1,t2,32") 11451 (set_attr "length" "2,2,4") 11452 (set_attr "predicable" "no,yes,yes") 11453 (set_attr "type" "rev")] 11454) 11455 11456(define_expand "arm_legacy_rev" 11457 [(set (match_operand:SI 2 "s_register_operand" "") 11458 (xor:SI (rotatert:SI (match_operand:SI 1 "s_register_operand" "") 11459 (const_int 16)) 11460 (match_dup 1))) 11461 (set (match_dup 2) 11462 (lshiftrt:SI (match_dup 2) 11463 (const_int 8))) 11464 (set (match_operand:SI 3 "s_register_operand" "") 11465 (rotatert:SI (match_dup 1) 11466 (const_int 8))) 11467 (set (match_dup 2) 11468 (and:SI (match_dup 2) 11469 (const_int -65281))) 11470 (set (match_operand:SI 0 "s_register_operand" "") 11471 (xor:SI (match_dup 3) 11472 (match_dup 2)))] 11473 "TARGET_32BIT" 11474 "" 11475) 11476 11477;; Reuse temporaries to keep register pressure down. 11478(define_expand "thumb_legacy_rev" 11479 [(set (match_operand:SI 2 "s_register_operand" "") 11480 (ashift:SI (match_operand:SI 1 "s_register_operand" "") 11481 (const_int 24))) 11482 (set (match_operand:SI 3 "s_register_operand" "") 11483 (lshiftrt:SI (match_dup 1) 11484 (const_int 24))) 11485 (set (match_dup 3) 11486 (ior:SI (match_dup 3) 11487 (match_dup 2))) 11488 (set (match_operand:SI 4 "s_register_operand" "") 11489 (const_int 16)) 11490 (set (match_operand:SI 5 "s_register_operand" "") 11491 (rotatert:SI (match_dup 1) 11492 (match_dup 4))) 11493 (set (match_dup 2) 11494 (ashift:SI (match_dup 5) 11495 (const_int 24))) 11496 (set (match_dup 5) 11497 (lshiftrt:SI (match_dup 5) 11498 (const_int 24))) 11499 (set (match_dup 5) 11500 (ior:SI (match_dup 5) 11501 (match_dup 2))) 11502 (set (match_dup 5) 11503 (rotatert:SI (match_dup 5) 11504 (match_dup 4))) 11505 (set (match_operand:SI 0 "s_register_operand" "") 11506 (ior:SI (match_dup 5) 11507 (match_dup 3)))] 11508 "TARGET_THUMB" 11509 "" 11510) 11511 11512;; ARM-specific expansion of signed mod by power of 2 11513;; using conditional negate. 11514;; For r0 % n where n is a power of 2 produce: 11515;; rsbs r1, r0, #0 11516;; and r0, r0, #(n - 1) 11517;; and r1, r1, #(n - 1) 11518;; rsbpl r0, r1, #0 11519 11520(define_expand "modsi3" 11521 [(match_operand:SI 0 "register_operand" "") 11522 (match_operand:SI 1 "register_operand" "") 11523 (match_operand:SI 2 "const_int_operand" "")] 11524 "TARGET_32BIT" 11525 { 11526 HOST_WIDE_INT val = INTVAL (operands[2]); 11527 11528 if (val <= 0 11529 || exact_log2 (val) <= 0) 11530 FAIL; 11531 11532 rtx mask = GEN_INT (val - 1); 11533 11534 /* In the special case of x0 % 2 we can do the even shorter: 11535 cmp r0, #0 11536 and r0, r0, #1 11537 rsblt r0, r0, #0. */ 11538 11539 if (val == 2) 11540 { 11541 rtx cc_reg = arm_gen_compare_reg (LT, 11542 operands[1], const0_rtx, NULL_RTX); 11543 rtx cond = gen_rtx_LT (SImode, cc_reg, const0_rtx); 11544 rtx masked = gen_reg_rtx (SImode); 11545 11546 emit_insn (gen_andsi3 (masked, operands[1], mask)); 11547 emit_move_insn (operands[0], 11548 gen_rtx_IF_THEN_ELSE (SImode, cond, 11549 gen_rtx_NEG (SImode, 11550 masked), 11551 masked)); 11552 DONE; 11553 } 11554 11555 rtx neg_op = gen_reg_rtx (SImode); 11556 rtx_insn *insn = emit_insn (gen_subsi3_compare0 (neg_op, const0_rtx, 11557 operands[1])); 11558 11559 /* Extract the condition register and mode. */ 11560 rtx cmp = XVECEXP (PATTERN (insn), 0, 0); 11561 rtx cc_reg = SET_DEST (cmp); 11562 rtx cond = gen_rtx_GE (SImode, cc_reg, const0_rtx); 11563 11564 emit_insn (gen_andsi3 (operands[0], operands[1], mask)); 11565 11566 rtx masked_neg = gen_reg_rtx (SImode); 11567 emit_insn (gen_andsi3 (masked_neg, neg_op, mask)); 11568 11569 /* We want a conditional negate here, but emitting COND_EXEC rtxes 11570 during expand does not always work. Do an IF_THEN_ELSE instead. */ 11571 emit_move_insn (operands[0], 11572 gen_rtx_IF_THEN_ELSE (SImode, cond, 11573 gen_rtx_NEG (SImode, masked_neg), 11574 operands[0])); 11575 11576 11577 DONE; 11578 } 11579) 11580 11581(define_expand "bswapsi2" 11582 [(set (match_operand:SI 0 "s_register_operand" "=r") 11583 (bswap:SI (match_operand:SI 1 "s_register_operand" "r")))] 11584"TARGET_EITHER && (arm_arch6 || !optimize_size)" 11585" 11586 if (!arm_arch6) 11587 { 11588 rtx op2 = gen_reg_rtx (SImode); 11589 rtx op3 = gen_reg_rtx (SImode); 11590 11591 if (TARGET_THUMB) 11592 { 11593 rtx op4 = gen_reg_rtx (SImode); 11594 rtx op5 = gen_reg_rtx (SImode); 11595 11596 emit_insn (gen_thumb_legacy_rev (operands[0], operands[1], 11597 op2, op3, op4, op5)); 11598 } 11599 else 11600 { 11601 emit_insn (gen_arm_legacy_rev (operands[0], operands[1], 11602 op2, op3)); 11603 } 11604 11605 DONE; 11606 } 11607 " 11608) 11609 11610;; bswap16 patterns: use revsh and rev16 instructions for the signed 11611;; and unsigned variants, respectively. For rev16, expose 11612;; byte-swapping in the lower 16 bits only. 11613(define_insn "*arm_revsh" 11614 [(set (match_operand:SI 0 "s_register_operand" "=l,l,r") 11615 (sign_extend:SI (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r"))))] 11616 "arm_arch6" 11617 "@ 11618 revsh\t%0, %1 11619 revsh%?\t%0, %1 11620 revsh%?\t%0, %1" 11621 [(set_attr "arch" "t1,t2,32") 11622 (set_attr "length" "2,2,4") 11623 (set_attr "type" "rev")] 11624) 11625 11626(define_insn "*arm_rev16" 11627 [(set (match_operand:HI 0 "s_register_operand" "=l,l,r") 11628 (bswap:HI (match_operand:HI 1 "s_register_operand" "l,l,r")))] 11629 "arm_arch6" 11630 "@ 11631 rev16\t%0, %1 11632 rev16%?\t%0, %1 11633 rev16%?\t%0, %1" 11634 [(set_attr "arch" "t1,t2,32") 11635 (set_attr "length" "2,2,4") 11636 (set_attr "type" "rev")] 11637) 11638 11639;; There are no canonicalisation rules for the position of the lshiftrt, ashift 11640;; operations within an IOR/AND RTX, therefore we have two patterns matching 11641;; each valid permutation. 11642 11643(define_insn "arm_rev16si2" 11644 [(set (match_operand:SI 0 "register_operand" "=l,l,r") 11645 (ior:SI (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "l,l,r") 11646 (const_int 8)) 11647 (match_operand:SI 3 "const_int_operand" "n,n,n")) 11648 (and:SI (lshiftrt:SI (match_dup 1) 11649 (const_int 8)) 11650 (match_operand:SI 2 "const_int_operand" "n,n,n"))))] 11651 "arm_arch6 11652 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode) 11653 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)" 11654 "rev16\\t%0, %1" 11655 [(set_attr "arch" "t1,t2,32") 11656 (set_attr "length" "2,2,4") 11657 (set_attr "type" "rev")] 11658) 11659 11660(define_insn "arm_rev16si2_alt" 11661 [(set (match_operand:SI 0 "register_operand" "=l,l,r") 11662 (ior:SI (and:SI (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,l,r") 11663 (const_int 8)) 11664 (match_operand:SI 2 "const_int_operand" "n,n,n")) 11665 (and:SI (ashift:SI (match_dup 1) 11666 (const_int 8)) 11667 (match_operand:SI 3 "const_int_operand" "n,n,n"))))] 11668 "arm_arch6 11669 && aarch_rev16_shleft_mask_imm_p (operands[3], SImode) 11670 && aarch_rev16_shright_mask_imm_p (operands[2], SImode)" 11671 "rev16\\t%0, %1" 11672 [(set_attr "arch" "t1,t2,32") 11673 (set_attr "length" "2,2,4") 11674 (set_attr "type" "rev")] 11675) 11676 11677(define_expand "bswaphi2" 11678 [(set (match_operand:HI 0 "s_register_operand" "=r") 11679 (bswap:HI (match_operand:HI 1 "s_register_operand" "r")))] 11680"arm_arch6" 11681"" 11682) 11683 11684;; Patterns for LDRD/STRD in Thumb2 mode 11685 11686(define_insn "*thumb2_ldrd" 11687 [(set (match_operand:SI 0 "s_register_operand" "=r") 11688 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk") 11689 (match_operand:SI 2 "ldrd_strd_offset_operand" "Do")))) 11690 (set (match_operand:SI 3 "s_register_operand" "=r") 11691 (mem:SI (plus:SI (match_dup 1) 11692 (match_operand:SI 4 "const_int_operand" ""))))] 11693 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11694 && ((INTVAL (operands[2]) + 4) == INTVAL (operands[4])) 11695 && (operands_ok_ldrd_strd (operands[0], operands[3], 11696 operands[1], INTVAL (operands[2]), 11697 false, true))" 11698 "ldrd%?\t%0, %3, [%1, %2]" 11699 [(set_attr "type" "load_8") 11700 (set_attr "predicable" "yes")]) 11701 11702(define_insn "*thumb2_ldrd_base" 11703 [(set (match_operand:SI 0 "s_register_operand" "=r") 11704 (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) 11705 (set (match_operand:SI 2 "s_register_operand" "=r") 11706 (mem:SI (plus:SI (match_dup 1) 11707 (const_int 4))))] 11708 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11709 && (operands_ok_ldrd_strd (operands[0], operands[2], 11710 operands[1], 0, false, true))" 11711 "ldrd%?\t%0, %2, [%1]" 11712 [(set_attr "type" "load_8") 11713 (set_attr "predicable" "yes")]) 11714 11715(define_insn "*thumb2_ldrd_base_neg" 11716 [(set (match_operand:SI 0 "s_register_operand" "=r") 11717 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "rk") 11718 (const_int -4)))) 11719 (set (match_operand:SI 2 "s_register_operand" "=r") 11720 (mem:SI (match_dup 1)))] 11721 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11722 && (operands_ok_ldrd_strd (operands[0], operands[2], 11723 operands[1], -4, false, true))" 11724 "ldrd%?\t%0, %2, [%1, #-4]" 11725 [(set_attr "type" "load_8") 11726 (set_attr "predicable" "yes")]) 11727 11728(define_insn "*thumb2_strd" 11729 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk") 11730 (match_operand:SI 1 "ldrd_strd_offset_operand" "Do"))) 11731 (match_operand:SI 2 "s_register_operand" "r")) 11732 (set (mem:SI (plus:SI (match_dup 0) 11733 (match_operand:SI 3 "const_int_operand" ""))) 11734 (match_operand:SI 4 "s_register_operand" "r"))] 11735 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11736 && ((INTVAL (operands[1]) + 4) == INTVAL (operands[3])) 11737 && (operands_ok_ldrd_strd (operands[2], operands[4], 11738 operands[0], INTVAL (operands[1]), 11739 false, false))" 11740 "strd%?\t%2, %4, [%0, %1]" 11741 [(set_attr "type" "store_8") 11742 (set_attr "predicable" "yes")]) 11743 11744(define_insn "*thumb2_strd_base" 11745 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "rk")) 11746 (match_operand:SI 1 "s_register_operand" "r")) 11747 (set (mem:SI (plus:SI (match_dup 0) 11748 (const_int 4))) 11749 (match_operand:SI 2 "s_register_operand" "r"))] 11750 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11751 && (operands_ok_ldrd_strd (operands[1], operands[2], 11752 operands[0], 0, false, false))" 11753 "strd%?\t%1, %2, [%0]" 11754 [(set_attr "type" "store_8") 11755 (set_attr "predicable" "yes")]) 11756 11757(define_insn "*thumb2_strd_base_neg" 11758 [(set (mem:SI (plus:SI (match_operand:SI 0 "s_register_operand" "rk") 11759 (const_int -4))) 11760 (match_operand:SI 1 "s_register_operand" "r")) 11761 (set (mem:SI (match_dup 0)) 11762 (match_operand:SI 2 "s_register_operand" "r"))] 11763 "TARGET_LDRD && TARGET_THUMB2 && reload_completed 11764 && (operands_ok_ldrd_strd (operands[1], operands[2], 11765 operands[0], -4, false, false))" 11766 "strd%?\t%1, %2, [%0, #-4]" 11767 [(set_attr "type" "store_8") 11768 (set_attr "predicable" "yes")]) 11769 11770;; ARMv8 CRC32 instructions. 11771(define_insn "<crc_variant>" 11772 [(set (match_operand:SI 0 "s_register_operand" "=r") 11773 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r") 11774 (match_operand:<crc_mode> 2 "s_register_operand" "r")] 11775 CRC))] 11776 "TARGET_CRC32" 11777 "<crc_variant>\\t%0, %1, %2" 11778 [(set_attr "type" "crc") 11779 (set_attr "conds" "unconditional")] 11780) 11781 11782;; Load the load/store double peephole optimizations. 11783(include "ldrdstrd.md") 11784 11785;; Load the load/store multiple patterns 11786(include "ldmstm.md") 11787 11788;; Patterns in ldmstm.md don't cover more than 4 registers. This pattern covers 11789;; large lists without explicit writeback generated for APCS_FRAME epilogue. 11790;; The operands are validated through the load_multiple_operation 11791;; match_parallel predicate rather than through constraints so enable it only 11792;; after reload. 11793(define_insn "*load_multiple" 11794 [(match_parallel 0 "load_multiple_operation" 11795 [(set (match_operand:SI 2 "s_register_operand" "=rk") 11796 (mem:SI (match_operand:SI 1 "s_register_operand" "rk"))) 11797 ])] 11798 "TARGET_32BIT && reload_completed" 11799 "* 11800 { 11801 arm_output_multireg_pop (operands, /*return_pc=*/false, 11802 /*cond=*/const_true_rtx, 11803 /*reverse=*/false, 11804 /*update=*/false); 11805 return \"\"; 11806 } 11807 " 11808 [(set_attr "predicable" "yes")] 11809) 11810 11811(define_expand "copysignsf3" 11812 [(match_operand:SF 0 "register_operand") 11813 (match_operand:SF 1 "register_operand") 11814 (match_operand:SF 2 "register_operand")] 11815 "TARGET_SOFT_FLOAT && arm_arch_thumb2" 11816 "{ 11817 emit_move_insn (operands[0], operands[2]); 11818 emit_insn (gen_insv_t2 (simplify_gen_subreg (SImode, operands[0], SFmode, 0), 11819 GEN_INT (31), GEN_INT (0), 11820 simplify_gen_subreg (SImode, operands[1], SFmode, 0))); 11821 DONE; 11822 }" 11823) 11824 11825(define_expand "copysigndf3" 11826 [(match_operand:DF 0 "register_operand") 11827 (match_operand:DF 1 "register_operand") 11828 (match_operand:DF 2 "register_operand")] 11829 "TARGET_SOFT_FLOAT && arm_arch_thumb2" 11830 "{ 11831 rtx op0_low = gen_lowpart (SImode, operands[0]); 11832 rtx op0_high = gen_highpart (SImode, operands[0]); 11833 rtx op1_low = gen_lowpart (SImode, operands[1]); 11834 rtx op1_high = gen_highpart (SImode, operands[1]); 11835 rtx op2_high = gen_highpart (SImode, operands[2]); 11836 11837 rtx scratch1 = gen_reg_rtx (SImode); 11838 rtx scratch2 = gen_reg_rtx (SImode); 11839 emit_move_insn (scratch1, op2_high); 11840 emit_move_insn (scratch2, op1_high); 11841 11842 emit_insn(gen_rtx_SET(scratch1, 11843 gen_rtx_LSHIFTRT (SImode, op2_high, GEN_INT(31)))); 11844 emit_insn(gen_insv_t2(scratch2, GEN_INT(1), GEN_INT(31), scratch1)); 11845 emit_move_insn (op0_low, op1_low); 11846 emit_move_insn (op0_high, scratch2); 11847 11848 DONE; 11849 }" 11850) 11851 11852;; movmisalign patterns for HImode and SImode. 11853(define_expand "movmisalign<mode>" 11854 [(match_operand:HSI 0 "general_operand") 11855 (match_operand:HSI 1 "general_operand")] 11856 "unaligned_access" 11857{ 11858 /* This pattern is not permitted to fail during expansion: if both arguments 11859 are non-registers (e.g. memory := constant), force operand 1 into a 11860 register. */ 11861 rtx (* gen_unaligned_load)(rtx, rtx); 11862 rtx tmp_dest = operands[0]; 11863 if (!s_register_operand (operands[0], <MODE>mode) 11864 && !s_register_operand (operands[1], <MODE>mode)) 11865 operands[1] = force_reg (<MODE>mode, operands[1]); 11866 11867 if (<MODE>mode == HImode) 11868 { 11869 gen_unaligned_load = gen_unaligned_loadhiu; 11870 tmp_dest = gen_reg_rtx (SImode); 11871 } 11872 else 11873 gen_unaligned_load = gen_unaligned_loadsi; 11874 11875 if (MEM_P (operands[1])) 11876 { 11877 emit_insn (gen_unaligned_load (tmp_dest, operands[1])); 11878 if (<MODE>mode == HImode) 11879 emit_move_insn (operands[0], gen_lowpart (HImode, tmp_dest)); 11880 } 11881 else 11882 emit_insn (gen_unaligned_store<mode> (operands[0], operands[1])); 11883 11884 DONE; 11885}) 11886 11887(define_insn "<cdp>" 11888 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 11889 (match_operand:SI 1 "immediate_operand" "n") 11890 (match_operand:SI 2 "immediate_operand" "n") 11891 (match_operand:SI 3 "immediate_operand" "n") 11892 (match_operand:SI 4 "immediate_operand" "n") 11893 (match_operand:SI 5 "immediate_operand" "n")] CDPI)] 11894 "arm_coproc_builtin_available (VUNSPEC_<CDP>)" 11895{ 11896 arm_const_bounds (operands[0], 0, 16); 11897 arm_const_bounds (operands[1], 0, 16); 11898 arm_const_bounds (operands[2], 0, (1 << 5)); 11899 arm_const_bounds (operands[3], 0, (1 << 5)); 11900 arm_const_bounds (operands[4], 0, (1 << 5)); 11901 arm_const_bounds (operands[5], 0, 8); 11902 return "<cdp>\\tp%c0, %1, CR%c2, CR%c3, CR%c4, %5"; 11903} 11904 [(set_attr "length" "4") 11905 (set_attr "type" "coproc")]) 11906 11907(define_insn "*ldc" 11908 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 11909 (match_operand:SI 1 "immediate_operand" "n") 11910 (match_operand:SI 2 "memory_operand" "Uz")] LDCI)] 11911 "arm_coproc_builtin_available (VUNSPEC_<LDC>)" 11912{ 11913 arm_const_bounds (operands[0], 0, 16); 11914 arm_const_bounds (operands[1], 0, (1 << 5)); 11915 return "<ldc>\\tp%c0, CR%c1, %2"; 11916} 11917 [(set_attr "length" "4") 11918 (set_attr "type" "coproc")]) 11919 11920(define_insn "*stc" 11921 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 11922 (match_operand:SI 1 "immediate_operand" "n") 11923 (match_operand:SI 2 "memory_operand" "=Uz")] STCI)] 11924 "arm_coproc_builtin_available (VUNSPEC_<STC>)" 11925{ 11926 arm_const_bounds (operands[0], 0, 16); 11927 arm_const_bounds (operands[1], 0, (1 << 5)); 11928 return "<stc>\\tp%c0, CR%c1, %2"; 11929} 11930 [(set_attr "length" "4") 11931 (set_attr "type" "coproc")]) 11932 11933(define_expand "<ldc>" 11934 [(unspec_volatile [(match_operand:SI 0 "immediate_operand") 11935 (match_operand:SI 1 "immediate_operand") 11936 (mem:SI (match_operand:SI 2 "s_register_operand"))] LDCI)] 11937 "arm_coproc_builtin_available (VUNSPEC_<LDC>)") 11938 11939(define_expand "<stc>" 11940 [(unspec_volatile [(match_operand:SI 0 "immediate_operand") 11941 (match_operand:SI 1 "immediate_operand") 11942 (mem:SI (match_operand:SI 2 "s_register_operand"))] STCI)] 11943 "arm_coproc_builtin_available (VUNSPEC_<STC>)") 11944 11945(define_insn "<mcr>" 11946 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 11947 (match_operand:SI 1 "immediate_operand" "n") 11948 (match_operand:SI 2 "s_register_operand" "r") 11949 (match_operand:SI 3 "immediate_operand" "n") 11950 (match_operand:SI 4 "immediate_operand" "n") 11951 (match_operand:SI 5 "immediate_operand" "n")] MCRI) 11952 (use (match_dup 2))] 11953 "arm_coproc_builtin_available (VUNSPEC_<MCR>)" 11954{ 11955 arm_const_bounds (operands[0], 0, 16); 11956 arm_const_bounds (operands[1], 0, 8); 11957 arm_const_bounds (operands[3], 0, (1 << 5)); 11958 arm_const_bounds (operands[4], 0, (1 << 5)); 11959 arm_const_bounds (operands[5], 0, 8); 11960 return "<mcr>\\tp%c0, %1, %2, CR%c3, CR%c4, %5"; 11961} 11962 [(set_attr "length" "4") 11963 (set_attr "type" "coproc")]) 11964 11965(define_insn "<mrc>" 11966 [(set (match_operand:SI 0 "s_register_operand" "=r") 11967 (unspec_volatile:SI [(match_operand:SI 1 "immediate_operand" "n") 11968 (match_operand:SI 2 "immediate_operand" "n") 11969 (match_operand:SI 3 "immediate_operand" "n") 11970 (match_operand:SI 4 "immediate_operand" "n") 11971 (match_operand:SI 5 "immediate_operand" "n")] MRCI))] 11972 "arm_coproc_builtin_available (VUNSPEC_<MRC>)" 11973{ 11974 arm_const_bounds (operands[1], 0, 16); 11975 arm_const_bounds (operands[2], 0, 8); 11976 arm_const_bounds (operands[3], 0, (1 << 5)); 11977 arm_const_bounds (operands[4], 0, (1 << 5)); 11978 arm_const_bounds (operands[5], 0, 8); 11979 return "<mrc>\\tp%c1, %2, %0, CR%c3, CR%c4, %5"; 11980} 11981 [(set_attr "length" "4") 11982 (set_attr "type" "coproc")]) 11983 11984(define_insn "<mcrr>" 11985 [(unspec_volatile [(match_operand:SI 0 "immediate_operand" "n") 11986 (match_operand:SI 1 "immediate_operand" "n") 11987 (match_operand:DI 2 "s_register_operand" "r") 11988 (match_operand:SI 3 "immediate_operand" "n")] MCRRI) 11989 (use (match_dup 2))] 11990 "arm_coproc_builtin_available (VUNSPEC_<MCRR>)" 11991{ 11992 arm_const_bounds (operands[0], 0, 16); 11993 arm_const_bounds (operands[1], 0, 8); 11994 arm_const_bounds (operands[3], 0, (1 << 5)); 11995 return "<mcrr>\\tp%c0, %1, %Q2, %R2, CR%c3"; 11996} 11997 [(set_attr "length" "4") 11998 (set_attr "type" "coproc")]) 11999 12000(define_insn "<mrrc>" 12001 [(set (match_operand:DI 0 "s_register_operand" "=r") 12002 (unspec_volatile:DI [(match_operand:SI 1 "immediate_operand" "n") 12003 (match_operand:SI 2 "immediate_operand" "n") 12004 (match_operand:SI 3 "immediate_operand" "n")] MRRCI))] 12005 "arm_coproc_builtin_available (VUNSPEC_<MRRC>)" 12006{ 12007 arm_const_bounds (operands[1], 0, 16); 12008 arm_const_bounds (operands[2], 0, 8); 12009 arm_const_bounds (operands[3], 0, (1 << 5)); 12010 return "<mrrc>\\tp%c1, %2, %Q0, %R0, CR%c3"; 12011} 12012 [(set_attr "length" "4") 12013 (set_attr "type" "coproc")]) 12014 12015;; Vector bits common to IWMMXT and Neon 12016(include "vec-common.md") 12017;; Load the Intel Wireless Multimedia Extension patterns 12018(include "iwmmxt.md") 12019;; Load the VFP co-processor patterns 12020(include "vfp.md") 12021;; Thumb-1 patterns 12022(include "thumb1.md") 12023;; Thumb-2 patterns 12024(include "thumb2.md") 12025;; Neon patterns 12026(include "neon.md") 12027;; Crypto patterns 12028(include "crypto.md") 12029;; Synchronization Primitives 12030(include "sync.md") 12031;; Fixed-point patterns 12032(include "arm-fixed.md") 12033