arm.md revision 90075
1;;- Machine description for ARM for GNU compiler 2;; Copyright 1991, 1993, 1994, 1995, 1996, 1996, 1997, 1998, 1999, 2000, 3;; 2001, 2002 Free Software Foundation, Inc. 4;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl) 5;; and Martin Simmons (@harleqn.co.uk). 6;; More major hacks by Richard Earnshaw (rearnsha@arm.com). 7 8;; This file is part of GNU CC. 9 10;; GNU CC is free software; you can redistribute it and/or modify 11;; it under the terms of the GNU General Public License as published by 12;; the Free Software Foundation; either version 2, or (at your option) 13;; any later version. 14 15;; GNU CC is distributed in the hope that it will be useful, 16;; but WITHOUT ANY WARRANTY; without even the implied warranty of 17;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18;; GNU General Public License for more details. 19 20;; You should have received a copy of the GNU General Public License 21;; along with GNU CC; see the file COPYING. If not, write to 22;; the Free Software Foundation, 59 Temple Place - Suite 330, 23;; Boston, MA 02111-1307, USA. 24 25;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 26 27;; There are patterns in this file to support XFmode arithmetic. 28;; Unfortunately RISC iX doesn't work well with these so they are disabled. 29;; (See arm.h) 30 31;;--------------------------------------------------------------------------- 32;; Constants 33 34;; Register numbers 35(define_constants 36 [(IP_REGNUM 12) ; Scratch register 37 (SP_REGNUM 13) ; Stack pointer 38 (LR_REGNUM 14) ; Return address register 39 (PC_REGNUM 15) ; Program counter 40 (CC_REGNUM 24) ; Condition code pseudo register 41 (LAST_ARM_REGNUM 15) 42 ] 43) 44 45;; UNSPEC Usage: 46;; Note: sin and cos are no-longer used. 47 48(define_constants 49 [(UNSPEC_SIN 0) ; `sin' operation (MODE_FLOAT): 50 ; operand 0 is the result, 51 ; operand 1 the parameter. 52 (UNPSEC_COS 1) ; `cos' operation (MODE_FLOAT): 53 ; operand 0 is the result, 54 ; operand 1 the parameter. 55 (UNSPEC_PUSH_MULT 2) ; `push multiple' operation: 56 ; operand 0 is the first register, 57 ; subsequent registers are in parallel (use ...) 58 ; expressions. 59 (UNSPEC_PIC_SYM 3) ; A symbol that has been treated properly for pic 60 ; usage, that is, we will add the pic_register 61 ; value to it before trying to dereference it. 62 (UNSPEC_PRLG_STK 4) ; A special barrier that prevents frame accesses 63 ; being scheduled before the stack adjustment insn. 64 (UNSPEC_CLZ 5) ; `clz' instruction, count leading zeros (SImode): 65 ; operand 0 is the result, 66 ; operand 1 is the parameter. 67 (UNSPEC_PROLOGUE_USE 6) ; As USE insns are not meaningful after reload, 68 ; this unspec is used to prevent the deletion of 69 ; instructions setting registers for EH handling 70 ; and stack frame generation. Operand 0 is the 71 ; register to "use". 72 ] 73) 74 75;; UNSPEC_VOLATILE Usage: 76 77(define_constants 78 [(VUNSPEC_BLOCKAGE 0) ; `blockage' insn to prevent scheduling across an 79 ; insn in the code. 80 (VUNSPEC_EPILOGUE 1) ; `epilogue' insn, used to represent any part of the 81 ; instruction epilogue sequence that isn't expanded 82 ; into normal RTL. Used for both normal and sibcall 83 ; epilogues. 84 (VUNSPEC_ALIGN 2) ; `align' insn. Used at the head of a minipool table 85 ; for inlined constants. 86 (VUNSPEC_POOL_END 3) ; `end-of-table'. Used to mark the end of a minipool 87 ; table. 88 (VUNSPEC_POOL_1 4) ; `pool-entry(1)'. An entry in the constant pool for 89 ; an 8-bit object. 90 (VUNSPEC_POOL_2 5) ; `pool-entry(2)'. An entry in the constant pool for 91 ; a 16-bit object. 92 (VUNSPEC_POOL_4 6) ; `pool-entry(4)'. An entry in the constant pool for 93 ; a 32-bit object. 94 (VUNSPEC_POOL_8 7) ; `pool-entry(8)'. An entry in the constant pool for 95 ; a 64-bit object. 96 ] 97) 98 99;;--------------------------------------------------------------------------- 100;; Attributes 101 102; IS_THUMB is set to 'yes' when we are generating Thumb code, and 'no' when 103; generating ARM code. This is used to control the length of some insn 104; patterns that share the same RTL in both ARM and Thumb code. 105(define_attr "is_thumb" "no,yes" (const (symbol_ref "thumb_code"))) 106 107; PROG_MODE attribute is used to determine whether condition codes are 108; clobbered by a call insn: they are if in prog32 mode. This is controlled 109; by the -mapcs-{32,26} flag, and possibly the -mcpu=... option. 110(define_attr "prog_mode" "prog26,prog32" (const (symbol_ref "arm_prog_mode"))) 111 112; IS_STRONGARM is set to 'yes' when compiling for StrongARM, it affects 113; scheduling decisions for the load unit and the multiplier. 114(define_attr "is_strongarm" "no,yes" (const (symbol_ref "arm_is_strong"))) 115 116;; Operand number of an input operand that is shifted. Zero if the 117;; given instruction does not shift one of its input operands. 118(define_attr "is_xscale" "no,yes" (const (symbol_ref "arm_is_xscale"))) 119(define_attr "shift" "" (const_int 0)) 120 121; Floating Point Unit. If we only have floating point emulation, then there 122; is no point in scheduling the floating point insns. (Well, for best 123; performance we should try and group them together). 124(define_attr "fpu" "fpa,fpe2,fpe3" (const (symbol_ref "arm_fpu_attr"))) 125 126; LENGTH of an instruction (in bytes) 127(define_attr "length" "" (const_int 4)) 128 129; POOL_RANGE is how far away from a constant pool entry that this insn 130; can be placed. If the distance is zero, then this insn will never 131; reference the pool. 132; NEG_POOL_RANGE is nonzero for insns that can reference a constant pool entry 133; before its address. 134(define_attr "pool_range" "" (const_int 0)) 135(define_attr "neg_pool_range" "" (const_int 0)) 136 137; An assembler sequence may clobber the condition codes without us knowing. 138(define_asm_attributes 139 [(set_attr "conds" "clob")]) 140 141; TYPE attribute is used to detect floating point instructions which, if 142; running on a co-processor can run in parallel with other, basic instructions 143; If write-buffer scheduling is enabled then it can also be used in the 144; scheduling of writes. 145 146; Classification of each insn 147; normal any data instruction that doesn't hit memory or fp regs 148; mult a multiply instruction 149; block blockage insn, this blocks all functional units 150; float a floating point arithmetic operation (subject to expansion) 151; fdivx XFmode floating point division 152; fdivd DFmode floating point division 153; fdivs SFmode floating point division 154; fmul Floating point multiply 155; ffmul Fast floating point multiply 156; farith Floating point arithmetic (4 cycle) 157; ffarith Fast floating point arithmetic (2 cycle) 158; float_em a floating point arithmetic operation that is normally emulated 159; even on a machine with an fpa. 160; f_load a floating point load from memory 161; f_store a floating point store to memory 162; f_mem_r a transfer of a floating point register to a real reg via mem 163; r_mem_f the reverse of f_mem_r 164; f_2_r fast transfer float to arm (no memory needed) 165; r_2_f fast transfer arm to float 166; call a subroutine call 167; load any load from memory 168; store1 store 1 word to memory from arm registers 169; store2 store 2 words 170; store3 store 3 words 171; store4 store 4 words 172; 173(define_attr "type" 174 "normal,mult,block,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith,float_em,f_load,f_store,f_mem_r,r_mem_f,f_2_r,r_2_f,call,load,store1,store2,store3,store4" 175 (const_string "normal")) 176 177; Load scheduling, set from the arm_ld_sched variable 178; initialised by arm_override_options() 179(define_attr "ldsched" "no,yes" (const (symbol_ref "arm_ld_sched"))) 180 181; condition codes: this one is used by final_prescan_insn to speed up 182; conditionalizing instructions. It saves having to scan the rtl to see if 183; it uses or alters the condition codes. 184; 185; USE means that the condition codes are used by the insn in the process of 186; outputting code, this means (at present) that we can't use the insn in 187; inlined branches 188; 189; SET means that the purpose of the insn is to set the condition codes in a 190; well defined manner. 191; 192; CLOB means that the condition codes are altered in an undefined manner, if 193; they are altered at all 194; 195; JUMP_CLOB is used when the condition cannot be represented by a single 196; instruction (UNEQ and LTGT). These cannot be predicated. 197; 198; NOCOND means that the condition codes are neither altered nor affect the 199; output of this insn 200 201(define_attr "conds" "use,set,clob,jump_clob,nocond" 202 (if_then_else (eq_attr "type" "call") 203 (if_then_else (eq_attr "prog_mode" "prog32") 204 (const_string "clob") (const_string "nocond")) 205 (const_string "nocond"))) 206 207; Predicable means that the insn can be conditionally executed based on 208; an automatically added predicate (additional patterns are generated by 209; gen...). We default to 'no' because no Thumb patterns match this rule 210; and not all ARM patterns do. 211(define_attr "predicable" "no,yes" (const_string "no")) 212 213; Only model the write buffer for ARM6 and ARM7. Earlier processors don't 214; have one. Later ones, such as StrongARM, have write-back caches, so don't 215; suffer blockages enough to warrent modelling this (and it can adversely 216; affect the schedule). 217(define_attr "model_wbuf" "no,yes" (const (symbol_ref "arm_is_6_or_7"))) 218 219; WRITE_CONFLICT implies that a read following an unrelated write is likely 220; to stall the processor. Used with model_wbuf above. 221(define_attr "write_conflict" "no,yes" 222 (if_then_else (eq_attr "type" 223 "block,float_em,f_load,f_store,f_mem_r,r_mem_f,call,load") 224 (const_string "yes") 225 (const_string "no"))) 226 227; Classify the insns into those that take one cycle and those that take more 228; than one on the main cpu execution unit. 229(define_attr "core_cycles" "single,multi" 230 (if_then_else (eq_attr "type" 231 "normal,float,fdivx,fdivd,fdivs,fmul,ffmul,farith,ffarith") 232 (const_string "single") 233 (const_string "multi"))) 234 235;; FAR_JUMP is "yes" if a BL instruction is used to generate a branch to a 236;; distant label. Only applicable to Thumb code. 237(define_attr "far_jump" "yes,no" (const_string "no")) 238 239;; (define_function_unit {name} {num-units} {n-users} {test} 240;; {ready-delay} {issue-delay} [{conflict-list}]) 241 242;;-------------------------------------------------------------------- 243;; Floating point unit (FPA) 244;;-------------------------------------------------------------------- 245(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa") 246 (eq_attr "type" "fdivx")) 71 69) 247 248(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa") 249 (eq_attr "type" "fdivd")) 59 57) 250 251(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa") 252 (eq_attr "type" "fdivs")) 31 29) 253 254(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa") 255 (eq_attr "type" "fmul")) 9 7) 256 257(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa") 258 (eq_attr "type" "ffmul")) 6 4) 259 260(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa") 261 (eq_attr "type" "farith")) 4 2) 262 263(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa") 264 (eq_attr "type" "ffarith")) 2 2) 265 266(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa") 267 (eq_attr "type" "r_2_f")) 5 3) 268 269(define_function_unit "fpa" 1 0 (and (eq_attr "fpu" "fpa") 270 (eq_attr "type" "f_2_r")) 1 2) 271 272; The fpa10 doesn't really have a memory read unit, but it can start to 273; speculatively execute the instruction in the pipeline, provided the data 274; is already loaded, so pretend reads have a delay of 2 (and that the 275; pipeline is infinite). 276 277(define_function_unit "fpa_mem" 1 0 (and (eq_attr "fpu" "fpa") 278 (eq_attr "type" "f_load")) 3 1) 279 280;;-------------------------------------------------------------------- 281;; Write buffer 282;;-------------------------------------------------------------------- 283; Strictly, we should model a 4-deep write buffer for ARM7xx based chips 284; 285; The write buffer on some of the arm6 processors is hard to model exactly. 286; There is room in the buffer for up to two addresses and up to eight words 287; of memory, but the two needn't be split evenly. When writing the two 288; addresses are fully pipelined. However, a read from memory that is not 289; currently in the cache will block until the writes have completed. 290; It is normally the case that FCLK and MCLK will be in the ratio 2:1, so 291; writes will take 2 FCLK cycles per word, if FCLK and MCLK are asynchronous 292; (they aren't allowed to be at present) then there is a startup cost of 1MCLK 293; cycle to add as well. 294 295(define_function_unit "write_buf" 1 2 296 (and (eq_attr "model_wbuf" "yes") 297 (eq_attr "type" "store1,r_mem_f")) 5 3) 298(define_function_unit "write_buf" 1 2 299 (and (eq_attr "model_wbuf" "yes") 300 (eq_attr "type" "store2")) 7 4) 301(define_function_unit "write_buf" 1 2 302 (and (eq_attr "model_wbuf" "yes") 303 (eq_attr "type" "store3")) 9 5) 304(define_function_unit "write_buf" 1 2 305 (and (eq_attr "model_wbuf" "yes") 306 (eq_attr "type" "store4")) 11 6) 307 308;;-------------------------------------------------------------------- 309;; Write blockage unit 310;;-------------------------------------------------------------------- 311; The write_blockage unit models (partially), the fact that reads will stall 312; until the write buffer empties. 313; The f_mem_r and r_mem_f could also block, but they are to the stack, 314; so we don't model them here 315(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes") 316 (eq_attr "type" "store1")) 5 5 317 [(eq_attr "write_conflict" "yes")]) 318(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes") 319 (eq_attr "type" "store2")) 7 7 320 [(eq_attr "write_conflict" "yes")]) 321(define_function_unit "write_blockage" 1 0 (and (eq_attr "model_wbuf" "yes") 322 (eq_attr "type" "store3")) 9 9 323 [(eq_attr "write_conflict" "yes")]) 324(define_function_unit "write_blockage" 1 0 325 (and (eq_attr "model_wbuf" "yes") (eq_attr "type" "store4")) 11 11 326 [(eq_attr "write_conflict" "yes")]) 327(define_function_unit "write_blockage" 1 0 328 (and (eq_attr "model_wbuf" "yes") 329 (eq_attr "write_conflict" "yes")) 1 1) 330 331;;-------------------------------------------------------------------- 332;; Core unit 333;;-------------------------------------------------------------------- 334; Everything must spend at least one cycle in the core unit 335(define_function_unit "core" 1 0 (eq_attr "core_cycles" "single") 1 1) 336 337(define_function_unit "core" 1 0 338 (and (eq_attr "ldsched" "yes") (eq_attr "type" "store1")) 1 1) 339 340(define_function_unit "core" 1 0 341 (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 2 1) 342 343;; We do not need to conditionalize the define_function_unit immediately 344;; above. This one will be ignored for anything other than xscale 345;; compiles and for xscale compiles it provides a larger delay 346;; and the scheduler will DTRT. 347;; FIXME: this test needs to be revamped to not depend on this feature 348;; of the scheduler. 349 350(define_function_unit "core" 1 0 351 (and (and (eq_attr "ldsched" "yes") (eq_attr "type" "load")) 352 (eq_attr "is_xscale" "yes")) 353 3 1) 354 355(define_function_unit "core" 1 0 356 (and (eq_attr "ldsched" "!yes") (eq_attr "type" "load,store1")) 2 2) 357 358(define_function_unit "core" 1 0 359 (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_load")) 3 3) 360 361(define_function_unit "core" 1 0 362 (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_store")) 4 4) 363 364(define_function_unit "core" 1 0 365 (and (eq_attr "fpu" "fpa") (eq_attr "type" "r_mem_f")) 6 6) 366 367(define_function_unit "core" 1 0 368 (and (eq_attr "fpu" "fpa") (eq_attr "type" "f_mem_r")) 7 7) 369 370(define_function_unit "core" 1 0 371 (and (eq_attr "ldsched" "no") (eq_attr "type" "mult")) 16 16) 372 373(define_function_unit "core" 1 0 374 (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "no")) 375 (eq_attr "type" "mult")) 4 4) 376 377(define_function_unit "core" 1 0 378 (and (and (eq_attr "ldsched" "yes") (eq_attr "is_strongarm" "yes")) 379 (eq_attr "type" "mult")) 3 2) 380 381(define_function_unit "core" 1 0 (eq_attr "type" "store2") 3 3) 382 383(define_function_unit "core" 1 0 (eq_attr "type" "store3") 4 4) 384 385(define_function_unit "core" 1 0 (eq_attr "type" "store4") 5 5) 386 387(define_function_unit "core" 1 0 388 (and (eq_attr "core_cycles" "multi") 389 (eq_attr "type" "!mult,load,store1,store2,store3,store4")) 32 32) 390 391;;--------------------------------------------------------------------------- 392;; Insn patterns 393;; 394;; Addition insns. 395 396;; Note: For DImode insns, there is normally no reason why operands should 397;; not be in the same register, what we don't want is for something being 398;; written to partially overlap something that is an input. 399 400(define_expand "adddi3" 401 [(parallel 402 [(set (match_operand:DI 0 "s_register_operand" "") 403 (plus:DI (match_operand:DI 1 "s_register_operand" "") 404 (match_operand:DI 2 "s_register_operand" ""))) 405 (clobber (reg:CC CC_REGNUM))])] 406 "TARGET_EITHER" 407 " 408 if (TARGET_THUMB) 409 { 410 if (GET_CODE (operands[1]) != REG) 411 operands[1] = force_reg (SImode, operands[1]); 412 if (GET_CODE (operands[2]) != REG) 413 operands[2] = force_reg (SImode, operands[2]); 414 } 415 " 416) 417 418(define_insn "*thumb_adddi3" 419 [(set (match_operand:DI 0 "register_operand" "=l") 420 (plus:DI (match_operand:DI 1 "register_operand" "%0") 421 (match_operand:DI 2 "register_operand" "l"))) 422 (clobber (reg:CC CC_REGNUM)) 423 ] 424 "TARGET_THUMB" 425 "add\\t%Q0, %Q0, %Q2\;adc\\t%R0, %R0, %R2" 426 [(set_attr "length" "4")] 427) 428 429(define_insn_and_split "*arm_adddi3" 430 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 431 (plus:DI (match_operand:DI 1 "s_register_operand" "%0, 0") 432 (match_operand:DI 2 "s_register_operand" "r, 0"))) 433 (clobber (reg:CC CC_REGNUM))] 434 "TARGET_ARM" 435 "#" 436 "TARGET_ARM && reload_completed" 437 [(parallel [(set (reg:CC_C CC_REGNUM) 438 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) 439 (match_dup 1))) 440 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 441 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0)) 442 (plus:SI (match_dup 4) (match_dup 5))))] 443 " 444 { 445 operands[3] = gen_highpart (SImode, operands[0]); 446 operands[0] = gen_lowpart (SImode, operands[0]); 447 operands[4] = gen_highpart (SImode, operands[1]); 448 operands[1] = gen_lowpart (SImode, operands[1]); 449 operands[5] = gen_highpart (SImode, operands[2]); 450 operands[2] = gen_lowpart (SImode, operands[2]); 451 }" 452 [(set_attr "conds" "clob") 453 (set_attr "length" "8")] 454) 455 456(define_insn_and_split "*adddi_sesidi_di" 457 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 458 (plus:DI (sign_extend:DI 459 (match_operand:SI 2 "s_register_operand" "r,r")) 460 (match_operand:DI 1 "s_register_operand" "r,0"))) 461 (clobber (reg:CC CC_REGNUM))] 462 "TARGET_ARM" 463 "#" 464 "TARGET_ARM && reload_completed" 465 [(parallel [(set (reg:CC_C CC_REGNUM) 466 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) 467 (match_dup 1))) 468 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 469 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0)) 470 (plus:SI (ashiftrt:SI (match_dup 2) 471 (const_int 31)) 472 (match_dup 4))))] 473 " 474 { 475 operands[3] = gen_highpart (SImode, operands[0]); 476 operands[0] = gen_lowpart (SImode, operands[0]); 477 operands[4] = gen_highpart (SImode, operands[1]); 478 operands[1] = gen_lowpart (SImode, operands[1]); 479 operands[2] = gen_lowpart (SImode, operands[2]); 480 }" 481 [(set_attr "conds" "clob") 482 (set_attr "length" "8")] 483) 484 485(define_insn_and_split "*adddi_zesidi_di" 486 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 487 (plus:DI (zero_extend:DI 488 (match_operand:SI 2 "s_register_operand" "r,r")) 489 (match_operand:DI 1 "s_register_operand" "r,0"))) 490 (clobber (reg:CC CC_REGNUM))] 491 "TARGET_ARM" 492 "#" 493 "TARGET_ARM && reload_completed" 494 [(parallel [(set (reg:CC_C CC_REGNUM) 495 (compare:CC_C (plus:SI (match_dup 1) (match_dup 2)) 496 (match_dup 1))) 497 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))]) 498 (set (match_dup 3) (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0)) 499 (plus:SI (match_dup 4) (const_int 0))))] 500 " 501 { 502 operands[3] = gen_highpart (SImode, operands[0]); 503 operands[0] = gen_lowpart (SImode, operands[0]); 504 operands[4] = gen_highpart (SImode, operands[1]); 505 operands[1] = gen_lowpart (SImode, operands[1]); 506 operands[2] = gen_lowpart (SImode, operands[2]); 507 }" 508 [(set_attr "conds" "clob") 509 (set_attr "length" "8")] 510) 511 512(define_expand "addsi3" 513 [(set (match_operand:SI 0 "s_register_operand" "") 514 (plus:SI (match_operand:SI 1 "s_register_operand" "") 515 (match_operand:SI 2 "reg_or_int_operand" "")))] 516 "TARGET_EITHER" 517 " 518 if (TARGET_ARM && GET_CODE (operands[2]) == CONST_INT) 519 { 520 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0], 521 operands[1], 522 (no_new_pseudos ? 0 : preserve_subexpressions_p ())); 523 DONE; 524 } 525 " 526) 527 528; If there is a scratch available, this will be faster than synthesising the 529; addition. 530(define_peephole2 531 [(match_scratch:SI 3 "r") 532 (set (match_operand:SI 0 "s_register_operand" "") 533 (plus:SI (match_operand:SI 1 "s_register_operand" "") 534 (match_operand:SI 2 "const_int_operand" "")))] 535 "TARGET_ARM && 536 !(const_ok_for_arm (INTVAL (operands[2])) 537 || const_ok_for_arm (-INTVAL (operands[2]))) 538 && const_ok_for_arm (~INTVAL (operands[2]))" 539 [(set (match_dup 3) (match_dup 2)) 540 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 3)))] 541 "" 542) 543 544(define_insn_and_split "*arm_addsi3" 545 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 546 (plus:SI (match_operand:SI 1 "s_register_operand" "%r,r,r") 547 (match_operand:SI 2 "reg_or_int_operand" "rI,L,?n")))] 548 "TARGET_ARM" 549 "@ 550 add%?\\t%0, %1, %2 551 sub%?\\t%0, %1, #%n2 552 #" 553 "TARGET_ARM && 554 GET_CODE (operands[2]) == CONST_INT 555 && !(const_ok_for_arm (INTVAL (operands[2])) 556 || const_ok_for_arm (-INTVAL (operands[2])))" 557 [(clobber (const_int 0))] 558 " 559 arm_split_constant (PLUS, SImode, INTVAL (operands[2]), operands[0], 560 operands[1], 0); 561 DONE; 562 " 563 [(set_attr "length" "4,4,16") 564 (set_attr "predicable" "yes")] 565) 566 567;; Register group 'k' is a single register group containing only the stack 568;; register. Trying to reload it will always fail catastrophically, 569;; so never allow those alternatives to match if reloading is needed. 570 571(define_insn "*thumb_addsi3" 572 [(set (match_operand:SI 0 "register_operand" "=l,l,l,*r,*h,l,!k") 573 (plus:SI (match_operand:SI 1 "register_operand" "%0,0,l,*0,*0,!k,!k") 574 (match_operand:SI 2 "nonmemory_operand" "I,J,lL,*h,*r,!M,!O")))] 575 "TARGET_THUMB" 576 "* 577 static const char * const asms[] = 578 { 579 \"add\\t%0, %0, %2\", 580 \"sub\\t%0, %0, #%n2\", 581 \"add\\t%0, %1, %2\", 582 \"add\\t%0, %0, %2\", 583 \"add\\t%0, %0, %2\", 584 \"add\\t%0, %1, %2\", 585 \"add\\t%0, %1, %2\" 586 }; 587 if ((which_alternative == 2 || which_alternative == 6) 588 && GET_CODE (operands[2]) == CONST_INT 589 && INTVAL (operands[2]) < 0) 590 return \"sub\\t%0, %1, #%n2\"; 591 return asms[which_alternative]; 592 " 593 [(set_attr "length" "2")] 594) 595 596;; Reloading and elimination of the frame pointer can 597;; sometimes cause this optimization to be missed. 598(define_peephole2 599 [(set (match_operand:SI 0 "register_operand" "=l") 600 (match_operand:SI 1 "const_int_operand" "M")) 601 (set (match_dup 0) 602 (plus:SI (match_dup 0) (match_operand:SI 2 "register_operand" "k")))] 603 "TARGET_THUMB 604 && REGNO (operands[2]) == STACK_POINTER_REGNUM 605 && (unsigned HOST_WIDE_INT) (INTVAL (operands[1])) < 1024 606 && (INTVAL (operands[1]) & 3) == 0" 607 [(set (match_dup 0) (plus:SI (match_dup 2) (match_dup 1)))] 608 "" 609) 610 611(define_insn "*addsi3_compare0" 612 [(set (reg:CC_NOOV CC_REGNUM) 613 (compare:CC_NOOV 614 (plus:SI (match_operand:SI 1 "s_register_operand" "r, r") 615 (match_operand:SI 2 "arm_add_operand" "rI,L")) 616 (const_int 0))) 617 (set (match_operand:SI 0 "s_register_operand" "=r,r") 618 (plus:SI (match_dup 1) (match_dup 2)))] 619 "TARGET_ARM" 620 "@ 621 add%?s\\t%0, %1, %2 622 sub%?s\\t%0, %1, #%n2" 623 [(set_attr "conds" "set")] 624) 625 626(define_insn "*addsi3_compare0_scratch" 627 [(set (reg:CC_NOOV CC_REGNUM) 628 (compare:CC_NOOV 629 (plus:SI (match_operand:SI 0 "s_register_operand" "r, r") 630 (match_operand:SI 1 "arm_add_operand" "rI,L")) 631 (const_int 0)))] 632 "TARGET_ARM" 633 "@ 634 cmn%?\\t%0, %1 635 cmp%?\\t%0, #%n1" 636 [(set_attr "conds" "set")] 637) 638 639;; These patterns are the same ones as the two regular addsi3_compare0 640;; patterns, except we write them slightly different - the combiner 641;; tends to generate them this way. 642(define_insn "*addsi3_compare0_for_combiner" 643 [(set (reg:CC CC_REGNUM) 644 (compare:CC 645 (match_operand:SI 1 "s_register_operand" "r,r") 646 (neg:SI (match_operand:SI 2 "arm_add_operand" "rI,L")))) 647 (set (match_operand:SI 0 "s_register_operand" "=r,r") 648 (plus:SI (match_dup 1) (match_dup 2)))] 649 "TARGET_ARM" 650 "@ 651 add%?s\\t%0, %1, %2 652 sub%?s\\t%0, %1, #%n2" 653 [(set_attr "conds" "set")] 654) 655 656(define_insn "*addsi3_compare0_scratch_for_combiner" 657 [(set (reg:CC CC_REGNUM) 658 (compare:CC 659 (match_operand:SI 0 "s_register_operand" "r,r") 660 (neg:SI (match_operand:SI 1 "arm_add_operand" "rI,L"))))] 661 "TARGET_ARM" 662 "@ 663 cmn%?\\t%0, %1 664 cmp%?\\t%0, #%n1" 665 [(set_attr "conds" "set")] 666) 667 668;; The next four insns work because they compare the result with one of 669;; the operands, and we know that the use of the condition code is 670;; either GEU or LTU, so we can use the carry flag from the addition 671;; instead of doing the compare a second time. 672(define_insn "*addsi3_compare_op1" 673 [(set (reg:CC_C CC_REGNUM) 674 (compare:CC_C 675 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r") 676 (match_operand:SI 2 "arm_add_operand" "rI,L")) 677 (match_dup 1))) 678 (set (match_operand:SI 0 "s_register_operand" "=r,r") 679 (plus:SI (match_dup 1) (match_dup 2)))] 680 "TARGET_ARM" 681 "@ 682 add%?s\\t%0, %1, %2 683 sub%?s\\t%0, %1, #%n2" 684 [(set_attr "conds" "set")] 685) 686 687(define_insn "*addsi3_compare_op2" 688 [(set (reg:CC_C CC_REGNUM) 689 (compare:CC_C 690 (plus:SI (match_operand:SI 1 "s_register_operand" "r,r") 691 (match_operand:SI 2 "arm_add_operand" "rI,L")) 692 (match_dup 2))) 693 (set (match_operand:SI 0 "s_register_operand" "=r,r") 694 (plus:SI (match_dup 1) (match_dup 2)))] 695 "TARGET_ARM" 696 "@ 697 add%?s\\t%0, %1, %2 698 sub%?s\\t%0, %1, #%n2" 699 [(set_attr "conds" "set")] 700) 701 702(define_insn "*compare_addsi2_op0" 703 [(set (reg:CC_C CC_REGNUM) 704 (compare:CC_C 705 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r") 706 (match_operand:SI 1 "arm_add_operand" "rI,L")) 707 (match_dup 0)))] 708 "TARGET_ARM" 709 "@ 710 cmn%?\\t%0, %1 711 cmp%?\\t%0, #%n1" 712 [(set_attr "conds" "set")] 713) 714 715(define_insn "*compare_addsi2_op1" 716 [(set (reg:CC_C CC_REGNUM) 717 (compare:CC_C 718 (plus:SI (match_operand:SI 0 "s_register_operand" "r,r") 719 (match_operand:SI 1 "arm_add_operand" "rI,L")) 720 (match_dup 1)))] 721 "TARGET_ARM" 722 "@ 723 cmn%?\\t%0, %1 724 cmp%?\\t%0, #%n1" 725 [(set_attr "conds" "set")] 726) 727 728(define_insn "*addsi3_carryin" 729 [(set (match_operand:SI 0 "s_register_operand" "=r") 730 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0)) 731 (plus:SI (match_operand:SI 1 "s_register_operand" "r") 732 (match_operand:SI 2 "arm_rhs_operand" "rI"))))] 733 "TARGET_ARM" 734 "adc%?\\t%0, %1, %2" 735 [(set_attr "conds" "use")] 736) 737 738(define_insn "*addsi3_carryin_shift" 739 [(set (match_operand:SI 0 "s_register_operand" "") 740 (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0)) 741 (plus:SI 742 (match_operator:SI 2 "shift_operator" 743 [(match_operand:SI 3 "s_register_operand" "") 744 (match_operand:SI 4 "reg_or_int_operand" "")]) 745 (match_operand:SI 1 "s_register_operand" ""))))] 746 "TARGET_ARM" 747 "adc%?\\t%0, %1, %3%S2" 748 [(set_attr "conds" "use")] 749) 750 751(define_insn "*addsi3_carryin_alt1" 752 [(set (match_operand:SI 0 "s_register_operand" "=r") 753 (plus:SI (plus:SI (match_operand:SI 1 "s_register_operand" "r") 754 (match_operand:SI 2 "arm_rhs_operand" "rI")) 755 (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0))))] 756 "TARGET_ARM" 757 "adc%?\\t%0, %1, %2" 758 [(set_attr "conds" "use")] 759) 760 761(define_insn "*addsi3_carryin_alt2" 762 [(set (match_operand:SI 0 "s_register_operand" "=r") 763 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0)) 764 (match_operand:SI 1 "s_register_operand" "r")) 765 (match_operand:SI 2 "arm_rhs_operand" "rI")))] 766 "TARGET_ARM" 767 "adc%?\\t%0, %1, %2" 768 [(set_attr "conds" "use")] 769) 770 771(define_insn "*addsi3_carryin_alt3" 772 [(set (match_operand:SI 0 "s_register_operand" "=r") 773 (plus:SI (plus:SI (ltu:SI (reg:CC_C CC_REGNUM) (const_int 0)) 774 (match_operand:SI 2 "arm_rhs_operand" "rI")) 775 (match_operand:SI 1 "s_register_operand" "r")))] 776 "TARGET_ARM" 777 "adc%?\\t%0, %1, %2" 778 [(set_attr "conds" "use")] 779) 780 781(define_insn "incscc" 782 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 783 (plus:SI (match_operator:SI 2 "arm_comparison_operator" 784 [(match_operand:CC 3 "cc_register" "") (const_int 0)]) 785 (match_operand:SI 1 "s_register_operand" "0,?r")))] 786 "TARGET_ARM" 787 "@ 788 add%d2\\t%0, %1, #1 789 mov%D2\\t%0, %1\;add%d2\\t%0, %1, #1" 790 [(set_attr "conds" "use") 791 (set_attr "length" "4,8")] 792) 793 794(define_insn "addsf3" 795 [(set (match_operand:SF 0 "s_register_operand" "=f,f") 796 (plus:SF (match_operand:SF 1 "s_register_operand" "%f,f") 797 (match_operand:SF 2 "fpu_add_operand" "fG,H")))] 798 "TARGET_ARM && TARGET_HARD_FLOAT" 799 "@ 800 adf%?s\\t%0, %1, %2 801 suf%?s\\t%0, %1, #%N2" 802 [(set_attr "type" "farith") 803 (set_attr "predicable" "yes")] 804) 805 806(define_insn "adddf3" 807 [(set (match_operand:DF 0 "s_register_operand" "=f,f") 808 (plus:DF (match_operand:DF 1 "s_register_operand" "%f,f") 809 (match_operand:DF 2 "fpu_add_operand" "fG,H")))] 810 "TARGET_ARM && TARGET_HARD_FLOAT" 811 "@ 812 adf%?d\\t%0, %1, %2 813 suf%?d\\t%0, %1, #%N2" 814 [(set_attr "type" "farith") 815 (set_attr "predicable" "yes")] 816) 817 818(define_insn "*adddf_esfdf_df" 819 [(set (match_operand:DF 0 "s_register_operand" "=f,f") 820 (plus:DF (float_extend:DF 821 (match_operand:SF 1 "s_register_operand" "f,f")) 822 (match_operand:DF 2 "fpu_add_operand" "fG,H")))] 823 "TARGET_ARM && TARGET_HARD_FLOAT" 824 "@ 825 adf%?d\\t%0, %1, %2 826 suf%?d\\t%0, %1, #%N2" 827 [(set_attr "type" "farith") 828 (set_attr "predicable" "yes")] 829) 830 831(define_insn "*adddf_df_esfdf" 832 [(set (match_operand:DF 0 "s_register_operand" "=f") 833 (plus:DF (match_operand:DF 1 "s_register_operand" "f") 834 (float_extend:DF 835 (match_operand:SF 2 "s_register_operand" "f"))))] 836 "TARGET_ARM && TARGET_HARD_FLOAT" 837 "adf%?d\\t%0, %1, %2" 838 [(set_attr "type" "farith") 839 (set_attr "predicable" "yes")] 840) 841 842(define_insn "*adddf_esfdf_esfdf" 843 [(set (match_operand:DF 0 "s_register_operand" "=f") 844 (plus:DF (float_extend:DF 845 (match_operand:SF 1 "s_register_operand" "f")) 846 (float_extend:DF 847 (match_operand:SF 2 "s_register_operand" "f"))))] 848 "TARGET_ARM && TARGET_HARD_FLOAT" 849 "adf%?d\\t%0, %1, %2" 850 [(set_attr "type" "farith") 851 (set_attr "predicable" "yes")] 852) 853 854(define_insn "addxf3" 855 [(set (match_operand:XF 0 "s_register_operand" "=f,f") 856 (plus:XF (match_operand:XF 1 "s_register_operand" "f,f") 857 (match_operand:XF 2 "fpu_add_operand" "fG,H")))] 858 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 859 "@ 860 adf%?e\\t%0, %1, %2 861 suf%?e\\t%0, %1, #%N2" 862 [(set_attr "type" "farith") 863 (set_attr "predicable" "yes")] 864) 865 866(define_expand "subdi3" 867 [(parallel 868 [(set (match_operand:DI 0 "s_register_operand" "") 869 (minus:DI (match_operand:DI 1 "s_register_operand" "") 870 (match_operand:DI 2 "s_register_operand" ""))) 871 (clobber (reg:CC CC_REGNUM))])] 872 "TARGET_EITHER" 873 " 874 if (TARGET_THUMB) 875 { 876 if (GET_CODE (operands[1]) != REG) 877 operands[1] = force_reg (SImode, operands[1]); 878 if (GET_CODE (operands[2]) != REG) 879 operands[2] = force_reg (SImode, operands[2]); 880 } 881 " 882) 883 884(define_insn "*arm_subdi3" 885 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r,&r") 886 (minus:DI (match_operand:DI 1 "s_register_operand" "0,r,0") 887 (match_operand:DI 2 "s_register_operand" "r,0,0"))) 888 (clobber (reg:CC CC_REGNUM))] 889 "TARGET_ARM" 890 "subs\\t%Q0, %Q1, %Q2\;sbc\\t%R0, %R1, %R2" 891 [(set_attr "conds" "clob") 892 (set_attr "length" "8")] 893) 894 895(define_insn "*thumb_subdi3" 896 [(set (match_operand:DI 0 "register_operand" "=l") 897 (minus:DI (match_operand:DI 1 "register_operand" "0") 898 (match_operand:DI 2 "register_operand" "l"))) 899 (clobber (reg:CC CC_REGNUM))] 900 "TARGET_THUMB" 901 "sub\\t%Q0, %Q0, %Q2\;sbc\\t%R0, %R0, %R2" 902 [(set_attr "length" "4")] 903) 904 905(define_insn "*subdi_di_zesidi" 906 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 907 (minus:DI (match_operand:DI 1 "s_register_operand" "?r,0") 908 (zero_extend:DI 909 (match_operand:SI 2 "s_register_operand" "r,r")))) 910 (clobber (reg:CC CC_REGNUM))] 911 "TARGET_ARM" 912 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, #0" 913 [(set_attr "conds" "clob") 914 (set_attr "length" "8")] 915) 916 917(define_insn "*subdi_di_sesidi" 918 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 919 (minus:DI (match_operand:DI 1 "s_register_operand" "r,0") 920 (sign_extend:DI 921 (match_operand:SI 2 "s_register_operand" "r,r")))) 922 (clobber (reg:CC CC_REGNUM))] 923 "TARGET_ARM" 924 "subs\\t%Q0, %Q1, %2\;sbc\\t%R0, %R1, %2, asr #31" 925 [(set_attr "conds" "clob") 926 (set_attr "length" "8")] 927) 928 929(define_insn "*subdi_zesidi_di" 930 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 931 (minus:DI (zero_extend:DI 932 (match_operand:SI 2 "s_register_operand" "r,r")) 933 (match_operand:DI 1 "s_register_operand" "?r,0"))) 934 (clobber (reg:CC CC_REGNUM))] 935 "TARGET_ARM" 936 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, #0" 937 [(set_attr "conds" "clob") 938 (set_attr "length" "8")] 939) 940 941(define_insn "*subdi_sesidi_di" 942 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 943 (minus:DI (sign_extend:DI 944 (match_operand:SI 2 "s_register_operand" "r,r")) 945 (match_operand:DI 1 "s_register_operand" "?r,0"))) 946 (clobber (reg:CC CC_REGNUM))] 947 "TARGET_ARM" 948 "rsbs\\t%Q0, %Q1, %2\;rsc\\t%R0, %R1, %2, asr #31" 949 [(set_attr "conds" "clob") 950 (set_attr "length" "8")] 951) 952 953(define_insn "*subdi_zesidi_zesidi" 954 [(set (match_operand:DI 0 "s_register_operand" "=r") 955 (minus:DI (zero_extend:DI 956 (match_operand:SI 1 "s_register_operand" "r")) 957 (zero_extend:DI 958 (match_operand:SI 2 "s_register_operand" "r")))) 959 (clobber (reg:CC CC_REGNUM))] 960 "TARGET_ARM" 961 "subs\\t%Q0, %1, %2\;rsc\\t%R0, %1, %1" 962 [(set_attr "conds" "clob") 963 (set_attr "length" "8")] 964) 965 966(define_expand "subsi3" 967 [(set (match_operand:SI 0 "s_register_operand" "") 968 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "") 969 (match_operand:SI 2 "s_register_operand" "")))] 970 "TARGET_EITHER" 971 " 972 if (GET_CODE (operands[1]) == CONST_INT) 973 { 974 if (TARGET_ARM) 975 { 976 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0], 977 operands[2], 978 (no_new_pseudos ? 0 979 : preserve_subexpressions_p ())); 980 DONE; 981 } 982 else /* TARGET_THUMB */ 983 operands[1] = force_reg (SImode, operands[1]); 984 } 985 " 986) 987 988(define_insn "*thumb_subsi3_insn" 989 [(set (match_operand:SI 0 "register_operand" "=l") 990 (minus:SI (match_operand:SI 1 "register_operand" "l") 991 (match_operand:SI 2 "register_operand" "l")))] 992 "TARGET_THUMB" 993 "sub\\t%0, %1, %2" 994 [(set_attr "length" "2")] 995) 996 997(define_insn_and_split "*arm_subsi3_insn" 998 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 999 (minus:SI (match_operand:SI 1 "reg_or_int_operand" "rI,?n") 1000 (match_operand:SI 2 "s_register_operand" "r,r")))] 1001 "TARGET_ARM" 1002 "@ 1003 rsb%?\\t%0, %2, %1 1004 #" 1005 "TARGET_ARM 1006 && GET_CODE (operands[1]) == CONST_INT 1007 && !const_ok_for_arm (INTVAL (operands[1]))" 1008 [(clobber (const_int 0))] 1009 " 1010 arm_split_constant (MINUS, SImode, INTVAL (operands[1]), operands[0], 1011 operands[2], 0); 1012 DONE; 1013 " 1014 [(set_attr "length" "4,16") 1015 (set_attr "predicable" "yes")] 1016) 1017 1018(define_peephole2 1019 [(match_scratch:SI 3 "r") 1020 (set (match_operand:SI 0 "s_register_operand" "") 1021 (minus:SI (match_operand:SI 1 "const_int_operand" "") 1022 (match_operand:SI 2 "s_register_operand" "")))] 1023 "TARGET_ARM 1024 && !const_ok_for_arm (INTVAL (operands[1])) 1025 && const_ok_for_arm (~INTVAL (operands[1]))" 1026 [(set (match_dup 3) (match_dup 1)) 1027 (set (match_dup 0) (minus:SI (match_dup 3) (match_dup 2)))] 1028 "" 1029) 1030 1031(define_insn "*subsi3_compare0" 1032 [(set (reg:CC_NOOV CC_REGNUM) 1033 (compare:CC_NOOV 1034 (minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,I") 1035 (match_operand:SI 2 "arm_rhs_operand" "rI,r")) 1036 (const_int 0))) 1037 (set (match_operand:SI 0 "s_register_operand" "=r,r") 1038 (minus:SI (match_dup 1) (match_dup 2)))] 1039 "TARGET_ARM" 1040 "@ 1041 sub%?s\\t%0, %1, %2 1042 rsb%?s\\t%0, %2, %1" 1043 [(set_attr "conds" "set")] 1044) 1045 1046(define_insn "decscc" 1047 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 1048 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") 1049 (match_operator:SI 2 "arm_comparison_operator" 1050 [(match_operand 3 "cc_register" "") (const_int 0)])))] 1051 "TARGET_ARM" 1052 "@ 1053 sub%d2\\t%0, %1, #1 1054 mov%D2\\t%0, %1\;sub%d2\\t%0, %1, #1" 1055 [(set_attr "conds" "use") 1056 (set_attr "length" "*,8")] 1057) 1058 1059(define_insn "subsf3" 1060 [(set (match_operand:SF 0 "s_register_operand" "=f,f") 1061 (minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G") 1062 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))] 1063 "TARGET_ARM && TARGET_HARD_FLOAT" 1064 "@ 1065 suf%?s\\t%0, %1, %2 1066 rsf%?s\\t%0, %2, %1" 1067 [(set_attr "type" "farith")] 1068) 1069 1070(define_insn "subdf3" 1071 [(set (match_operand:DF 0 "s_register_operand" "=f,f") 1072 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") 1073 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))] 1074 "TARGET_ARM && TARGET_HARD_FLOAT" 1075 "@ 1076 suf%?d\\t%0, %1, %2 1077 rsf%?d\\t%0, %2, %1" 1078 [(set_attr "type" "farith") 1079 (set_attr "predicable" "yes")] 1080) 1081 1082(define_insn "*subdf_esfdf_df" 1083 [(set (match_operand:DF 0 "s_register_operand" "=f") 1084 (minus:DF (float_extend:DF 1085 (match_operand:SF 1 "s_register_operand" "f")) 1086 (match_operand:DF 2 "fpu_rhs_operand" "fG")))] 1087 "TARGET_ARM && TARGET_HARD_FLOAT" 1088 "suf%?d\\t%0, %1, %2" 1089 [(set_attr "type" "farith") 1090 (set_attr "predicable" "yes")] 1091) 1092 1093(define_insn "*subdf_df_esfdf" 1094 [(set (match_operand:DF 0 "s_register_operand" "=f,f") 1095 (minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") 1096 (float_extend:DF 1097 (match_operand:SF 2 "s_register_operand" "f,f"))))] 1098 "TARGET_ARM && TARGET_HARD_FLOAT" 1099 "@ 1100 suf%?d\\t%0, %1, %2 1101 rsf%?d\\t%0, %2, %1" 1102 [(set_attr "type" "farith") 1103 (set_attr "predicable" "yes")] 1104) 1105 1106(define_insn "*subdf_esfdf_esfdf" 1107 [(set (match_operand:DF 0 "s_register_operand" "=f") 1108 (minus:DF (float_extend:DF 1109 (match_operand:SF 1 "s_register_operand" "f")) 1110 (float_extend:DF 1111 (match_operand:SF 2 "s_register_operand" "f"))))] 1112 "TARGET_ARM && TARGET_HARD_FLOAT" 1113 "suf%?d\\t%0, %1, %2" 1114 [(set_attr "type" "farith") 1115 (set_attr "predicable" "yes")] 1116) 1117 1118(define_insn "subxf3" 1119 [(set (match_operand:XF 0 "s_register_operand" "=f,f") 1120 (minus:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G") 1121 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))] 1122 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 1123 "@ 1124 suf%?e\\t%0, %1, %2 1125 rsf%?e\\t%0, %2, %1" 1126 [(set_attr "type" "farith") 1127 (set_attr "predicable" "yes")] 1128) 1129 1130;; Multiplication insns 1131 1132(define_expand "mulsi3" 1133 [(set (match_operand:SI 0 "s_register_operand" "") 1134 (mult:SI (match_operand:SI 2 "s_register_operand" "") 1135 (match_operand:SI 1 "s_register_operand" "")))] 1136 "TARGET_EITHER" 1137 "" 1138) 1139 1140;; Use `&' and then `0' to prevent the operands 0 and 1 being the same 1141(define_insn "*arm_mulsi3" 1142 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1143 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r") 1144 (match_operand:SI 1 "s_register_operand" "%?r,0")))] 1145 "TARGET_ARM" 1146 "mul%?\\t%0, %2, %1" 1147 [(set_attr "type" "mult") 1148 (set_attr "predicable" "yes")] 1149) 1150 1151; Unfortunately with the Thumb the '&'/'0' trick can fails when operands 1152; 1 and 2; are the same, because reload will make operand 0 match 1153; operand 1 without realizing that this conflicts with operand 2. We fix 1154; this by adding another alternative to match this case, and then `reload' 1155; it ourselves. This alternative must come first. 1156(define_insn "*thumb_mulsi3" 1157 [(set (match_operand:SI 0 "register_operand" "=&l,&l,&l") 1158 (mult:SI (match_operand:SI 1 "register_operand" "%l,*h,0") 1159 (match_operand:SI 2 "register_operand" "l,l,l")))] 1160 "TARGET_THUMB" 1161 "* 1162 if (which_alternative < 2) 1163 return \"mov\\t%0, %1\;mul\\t%0, %0, %2\"; 1164 else 1165 return \"mul\\t%0, %0, %2\"; 1166 " 1167 [(set_attr "length" "4,4,2") 1168 (set_attr "type" "mult")] 1169) 1170 1171(define_insn "*mulsi3_compare0" 1172 [(set (reg:CC_NOOV CC_REGNUM) 1173 (compare:CC_NOOV (mult:SI 1174 (match_operand:SI 2 "s_register_operand" "r,r") 1175 (match_operand:SI 1 "s_register_operand" "%?r,0")) 1176 (const_int 0))) 1177 (set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1178 (mult:SI (match_dup 2) (match_dup 1)))] 1179 "TARGET_ARM && !arm_is_xscale" 1180 "mul%?s\\t%0, %2, %1" 1181 [(set_attr "conds" "set") 1182 (set_attr "type" "mult")] 1183) 1184 1185(define_insn "*mulsi_compare0_scratch" 1186 [(set (reg:CC_NOOV CC_REGNUM) 1187 (compare:CC_NOOV (mult:SI 1188 (match_operand:SI 2 "s_register_operand" "r,r") 1189 (match_operand:SI 1 "s_register_operand" "%?r,0")) 1190 (const_int 0))) 1191 (clobber (match_scratch:SI 0 "=&r,&r"))] 1192 "TARGET_ARM && !arm_is_xscale" 1193 "mul%?s\\t%0, %2, %1" 1194 [(set_attr "conds" "set") 1195 (set_attr "type" "mult")] 1196) 1197 1198;; Unnamed templates to match MLA instruction. 1199 1200(define_insn "*mulsi3addsi" 1201 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") 1202 (plus:SI 1203 (mult:SI (match_operand:SI 2 "s_register_operand" "r,r,r,r") 1204 (match_operand:SI 1 "s_register_operand" "%r,0,r,0")) 1205 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")))] 1206 "TARGET_ARM" 1207 "mla%?\\t%0, %2, %1, %3" 1208 [(set_attr "type" "mult") 1209 (set_attr "predicable" "yes")] 1210) 1211 1212(define_insn "*mulsi3addsi_compare0" 1213 [(set (reg:CC_NOOV CC_REGNUM) 1214 (compare:CC_NOOV 1215 (plus:SI (mult:SI 1216 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 1217 (match_operand:SI 1 "s_register_operand" "%r,0,r,0")) 1218 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")) 1219 (const_int 0))) 1220 (set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r,&r") 1221 (plus:SI (mult:SI (match_dup 2) (match_dup 1)) 1222 (match_dup 3)))] 1223 "TARGET_ARM && !arm_is_xscale" 1224 "mla%?s\\t%0, %2, %1, %3" 1225 [(set_attr "conds" "set") 1226 (set_attr "type" "mult")] 1227) 1228 1229(define_insn "*mulsi3addsi_compare0_scratch" 1230 [(set (reg:CC_NOOV CC_REGNUM) 1231 (compare:CC_NOOV 1232 (plus:SI (mult:SI 1233 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 1234 (match_operand:SI 1 "s_register_operand" "%r,0,r,0")) 1235 (match_operand:SI 3 "s_register_operand" "?r,r,0,0")) 1236 (const_int 0))) 1237 (clobber (match_scratch:SI 0 "=&r,&r,&r,&r"))] 1238 "TARGET_ARM && !arm_is_xscale" 1239 "mla%?s\\t%0, %2, %1, %3" 1240 [(set_attr "conds" "set") 1241 (set_attr "type" "mult")] 1242) 1243 1244;; Unnamed template to match long long multiply-accumlate (smlal) 1245 1246(define_insn "*mulsidi3adddi" 1247 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1248 (plus:DI 1249 (mult:DI 1250 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "%r")) 1251 (sign_extend:DI (match_operand:SI 3 "s_register_operand" "r"))) 1252 (match_operand:DI 1 "s_register_operand" "0")))] 1253 "TARGET_ARM && arm_fast_multiply" 1254 "smlal%?\\t%Q0, %R0, %3, %2" 1255 [(set_attr "type" "mult") 1256 (set_attr "predicable" "yes")] 1257) 1258 1259(define_insn "mulsidi3" 1260 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1261 (mult:DI 1262 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r")) 1263 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] 1264 "TARGET_ARM && arm_fast_multiply" 1265 "smull%?\\t%Q0, %R0, %1, %2" 1266 [(set_attr "type" "mult") 1267 (set_attr "predicable" "yes")] 1268) 1269 1270(define_insn "umulsidi3" 1271 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1272 (mult:DI 1273 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r")) 1274 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r"))))] 1275 "TARGET_ARM && arm_fast_multiply" 1276 "umull%?\\t%Q0, %R0, %1, %2" 1277 [(set_attr "type" "mult") 1278 (set_attr "predicable" "yes")] 1279) 1280 1281;; Unnamed template to match long long unsigned multiply-accumlate (umlal) 1282 1283(define_insn "*umulsidi3adddi" 1284 [(set (match_operand:DI 0 "s_register_operand" "=&r") 1285 (plus:DI 1286 (mult:DI 1287 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "%r")) 1288 (zero_extend:DI (match_operand:SI 3 "s_register_operand" "r"))) 1289 (match_operand:DI 1 "s_register_operand" "0")))] 1290 "TARGET_ARM && arm_fast_multiply" 1291 "umlal%?\\t%Q0, %R0, %3, %2" 1292 [(set_attr "type" "mult") 1293 (set_attr "predicable" "yes")] 1294) 1295 1296(define_insn "smulsi3_highpart" 1297 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1298 (truncate:SI 1299 (lshiftrt:DI 1300 (mult:DI 1301 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0")) 1302 (sign_extend:DI (match_operand:SI 2 "s_register_operand" "r,r"))) 1303 (const_int 32)))) 1304 (clobber (match_scratch:SI 3 "=&r,&r"))] 1305 "TARGET_ARM && arm_fast_multiply" 1306 "smull%?\\t%3, %0, %2, %1" 1307 [(set_attr "type" "mult") 1308 (set_attr "predicable" "yes")] 1309) 1310 1311(define_insn "umulsi3_highpart" 1312 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r") 1313 (truncate:SI 1314 (lshiftrt:DI 1315 (mult:DI 1316 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "%r,0")) 1317 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "r,r"))) 1318 (const_int 32)))) 1319 (clobber (match_scratch:SI 3 "=&r,&r"))] 1320 "TARGET_ARM && arm_fast_multiply" 1321 "umull%?\\t%3, %0, %2, %1" 1322 [(set_attr "type" "mult") 1323 (set_attr "predicable" "yes")] 1324) 1325 1326(define_insn "mulhisi3" 1327 [(set (match_operand:SI 0 "s_register_operand" "=r") 1328 (mult:SI (sign_extend:SI 1329 (match_operand:HI 1 "s_register_operand" "%r")) 1330 (sign_extend:SI 1331 (match_operand:HI 2 "s_register_operand" "r"))))] 1332 "TARGET_ARM && arm_is_xscale" 1333 "smulbb%?\\t%0, %1, %2" 1334 [(set_attr "type" "mult")] 1335) 1336 1337(define_insn "*mulhisi3addsi" 1338 [(set (match_operand:SI 0 "s_register_operand" "=r") 1339 (plus:SI (match_operand:SI 1 "s_register_operand" "r") 1340 (mult:SI (sign_extend:SI 1341 (match_operand:HI 2 "s_register_operand" "%r")) 1342 (sign_extend:SI 1343 (match_operand:HI 3 "s_register_operand" "r")))))] 1344 "TARGET_ARM && arm_is_xscale" 1345 "smlabb%?\\t%0, %2, %3, %1" 1346 [(set_attr "type" "mult")] 1347) 1348 1349(define_insn "*mulhidi3adddi" 1350 [(set (match_operand:DI 0 "s_register_operand" "=r") 1351 (plus:DI 1352 (match_operand:DI 1 "s_register_operand" "0") 1353 (mult:DI (sign_extend:DI 1354 (match_operand:HI 2 "s_register_operand" "%r")) 1355 (sign_extend:DI 1356 (match_operand:HI 3 "s_register_operand" "r")))))] 1357 "TARGET_ARM && arm_is_xscale" 1358 "smlalbb%?\\t%Q0, %R0, %2, %3" 1359[(set_attr "type" "mult")]) 1360 1361(define_insn "mulsf3" 1362 [(set (match_operand:SF 0 "s_register_operand" "=f") 1363 (mult:SF (match_operand:SF 1 "s_register_operand" "f") 1364 (match_operand:SF 2 "fpu_rhs_operand" "fG")))] 1365 "TARGET_ARM && TARGET_HARD_FLOAT" 1366 "fml%?s\\t%0, %1, %2" 1367 [(set_attr "type" "ffmul") 1368 (set_attr "predicable" "yes")] 1369) 1370 1371(define_insn "muldf3" 1372 [(set (match_operand:DF 0 "s_register_operand" "=f") 1373 (mult:DF (match_operand:DF 1 "s_register_operand" "f") 1374 (match_operand:DF 2 "fpu_rhs_operand" "fG")))] 1375 "TARGET_ARM && TARGET_HARD_FLOAT" 1376 "muf%?d\\t%0, %1, %2" 1377 [(set_attr "type" "fmul") 1378 (set_attr "predicable" "yes")] 1379) 1380 1381(define_insn "*muldf_esfdf_df" 1382 [(set (match_operand:DF 0 "s_register_operand" "=f") 1383 (mult:DF (float_extend:DF 1384 (match_operand:SF 1 "s_register_operand" "f")) 1385 (match_operand:DF 2 "fpu_rhs_operand" "fG")))] 1386 "TARGET_ARM && TARGET_HARD_FLOAT" 1387 "muf%?d\\t%0, %1, %2" 1388 [(set_attr "type" "fmul") 1389 (set_attr "predicable" "yes")] 1390) 1391 1392(define_insn "*muldf_df_esfdf" 1393 [(set (match_operand:DF 0 "s_register_operand" "=f") 1394 (mult:DF (match_operand:DF 1 "s_register_operand" "f") 1395 (float_extend:DF 1396 (match_operand:SF 2 "s_register_operand" "f"))))] 1397 "TARGET_ARM && TARGET_HARD_FLOAT" 1398 "muf%?d\\t%0, %1, %2" 1399 [(set_attr "type" "fmul") 1400 (set_attr "predicable" "yes")] 1401) 1402 1403(define_insn "*muldf_esfdf_esfdf" 1404 [(set (match_operand:DF 0 "s_register_operand" "=f") 1405 (mult:DF 1406 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")) 1407 (float_extend:DF (match_operand:SF 2 "s_register_operand" "f"))))] 1408 "TARGET_ARM && TARGET_HARD_FLOAT" 1409 "muf%?d\\t%0, %1, %2" 1410 [(set_attr "type" "fmul") 1411 (set_attr "predicable" "yes")] 1412) 1413 1414(define_insn "mulxf3" 1415 [(set (match_operand:XF 0 "s_register_operand" "=f") 1416 (mult:XF (match_operand:XF 1 "s_register_operand" "f") 1417 (match_operand:XF 2 "fpu_rhs_operand" "fG")))] 1418 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 1419 "muf%?e\\t%0, %1, %2" 1420 [(set_attr "type" "fmul") 1421 (set_attr "predicable" "yes")] 1422) 1423 1424;; Division insns 1425 1426(define_insn "divsf3" 1427 [(set (match_operand:SF 0 "s_register_operand" "=f,f") 1428 (div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G") 1429 (match_operand:SF 2 "fpu_rhs_operand" "fG,f")))] 1430 "TARGET_ARM && TARGET_HARD_FLOAT" 1431 "@ 1432 fdv%?s\\t%0, %1, %2 1433 frd%?s\\t%0, %2, %1" 1434 [(set_attr "type" "fdivs") 1435 (set_attr "predicable" "yes")] 1436) 1437 1438(define_insn "divdf3" 1439 [(set (match_operand:DF 0 "s_register_operand" "=f,f") 1440 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G") 1441 (match_operand:DF 2 "fpu_rhs_operand" "fG,f")))] 1442 "TARGET_ARM && TARGET_HARD_FLOAT" 1443 "@ 1444 dvf%?d\\t%0, %1, %2 1445 rdf%?d\\t%0, %2, %1" 1446 [(set_attr "type" "fdivd") 1447 (set_attr "predicable" "yes")] 1448) 1449 1450(define_insn "*divdf_esfdf_df" 1451 [(set (match_operand:DF 0 "s_register_operand" "=f") 1452 (div:DF (float_extend:DF 1453 (match_operand:SF 1 "s_register_operand" "f")) 1454 (match_operand:DF 2 "fpu_rhs_operand" "fG")))] 1455 "TARGET_ARM && TARGET_HARD_FLOAT" 1456 "dvf%?d\\t%0, %1, %2" 1457 [(set_attr "type" "fdivd") 1458 (set_attr "predicable" "yes")] 1459) 1460 1461(define_insn "*divdf_df_esfdf" 1462 [(set (match_operand:DF 0 "s_register_operand" "=f") 1463 (div:DF (match_operand:DF 1 "fpu_rhs_operand" "fG") 1464 (float_extend:DF 1465 (match_operand:SF 2 "s_register_operand" "f"))))] 1466 "TARGET_ARM && TARGET_HARD_FLOAT" 1467 "rdf%?d\\t%0, %2, %1" 1468 [(set_attr "type" "fdivd") 1469 (set_attr "predicable" "yes")] 1470) 1471 1472(define_insn "*divdf_esfdf_esfdf" 1473 [(set (match_operand:DF 0 "s_register_operand" "=f") 1474 (div:DF (float_extend:DF 1475 (match_operand:SF 1 "s_register_operand" "f")) 1476 (float_extend:DF 1477 (match_operand:SF 2 "s_register_operand" "f"))))] 1478 "TARGET_ARM && TARGET_HARD_FLOAT" 1479 "dvf%?d\\t%0, %1, %2" 1480 [(set_attr "type" "fdivd") 1481 (set_attr "predicable" "yes")] 1482) 1483 1484(define_insn "divxf3" 1485 [(set (match_operand:XF 0 "s_register_operand" "=f,f") 1486 (div:XF (match_operand:XF 1 "fpu_rhs_operand" "f,G") 1487 (match_operand:XF 2 "fpu_rhs_operand" "fG,f")))] 1488 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 1489 "@ 1490 dvf%?e\\t%0, %1, %2 1491 rdf%?e\\t%0, %2, %1" 1492 [(set_attr "type" "fdivx") 1493 (set_attr "predicable" "yes")] 1494) 1495 1496;; Modulo insns 1497 1498(define_insn "modsf3" 1499 [(set (match_operand:SF 0 "s_register_operand" "=f") 1500 (mod:SF (match_operand:SF 1 "s_register_operand" "f") 1501 (match_operand:SF 2 "fpu_rhs_operand" "fG")))] 1502 "TARGET_ARM && TARGET_HARD_FLOAT" 1503 "rmf%?s\\t%0, %1, %2" 1504 [(set_attr "type" "fdivs") 1505 (set_attr "predicable" "yes")] 1506) 1507 1508(define_insn "moddf3" 1509 [(set (match_operand:DF 0 "s_register_operand" "=f") 1510 (mod:DF (match_operand:DF 1 "s_register_operand" "f") 1511 (match_operand:DF 2 "fpu_rhs_operand" "fG")))] 1512 "TARGET_ARM && TARGET_HARD_FLOAT" 1513 "rmf%?d\\t%0, %1, %2" 1514 [(set_attr "type" "fdivd") 1515 (set_attr "predicable" "yes")] 1516) 1517 1518(define_insn "*moddf_esfdf_df" 1519 [(set (match_operand:DF 0 "s_register_operand" "=f") 1520 (mod:DF (float_extend:DF 1521 (match_operand:SF 1 "s_register_operand" "f")) 1522 (match_operand:DF 2 "fpu_rhs_operand" "fG")))] 1523 "TARGET_ARM && TARGET_HARD_FLOAT" 1524 "rmf%?d\\t%0, %1, %2" 1525 [(set_attr "type" "fdivd") 1526 (set_attr "predicable" "yes")] 1527) 1528 1529(define_insn "*moddf_df_esfdf" 1530 [(set (match_operand:DF 0 "s_register_operand" "=f") 1531 (mod:DF (match_operand:DF 1 "s_register_operand" "f") 1532 (float_extend:DF 1533 (match_operand:SF 2 "s_register_operand" "f"))))] 1534 "TARGET_ARM && TARGET_HARD_FLOAT" 1535 "rmf%?d\\t%0, %1, %2" 1536 [(set_attr "type" "fdivd") 1537 (set_attr "predicable" "yes")] 1538) 1539 1540(define_insn "*moddf_esfdf_esfdf" 1541 [(set (match_operand:DF 0 "s_register_operand" "=f") 1542 (mod:DF (float_extend:DF 1543 (match_operand:SF 1 "s_register_operand" "f")) 1544 (float_extend:DF 1545 (match_operand:SF 2 "s_register_operand" "f"))))] 1546 "TARGET_ARM && TARGET_HARD_FLOAT" 1547 "rmf%?d\\t%0, %1, %2" 1548 [(set_attr "type" "fdivd") 1549 (set_attr "predicable" "yes")] 1550) 1551 1552(define_insn "modxf3" 1553 [(set (match_operand:XF 0 "s_register_operand" "=f") 1554 (mod:XF (match_operand:XF 1 "s_register_operand" "f") 1555 (match_operand:XF 2 "fpu_rhs_operand" "fG")))] 1556 "ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 1557 "rmf%?e\\t%0, %1, %2" 1558 [(set_attr "type" "fdivx") 1559 (set_attr "predicable" "yes")] 1560) 1561 1562;; Boolean and,ior,xor insns 1563 1564;; Split up double word logical operations 1565 1566;; Split up simple DImode logical operations. Simply perform the logical 1567;; operation on the upper and lower halves of the registers. 1568(define_split 1569 [(set (match_operand:DI 0 "s_register_operand" "") 1570 (match_operator:DI 6 "logical_binary_operator" 1571 [(match_operand:DI 1 "s_register_operand" "") 1572 (match_operand:DI 2 "s_register_operand" "")]))] 1573 "TARGET_ARM && reload_completed" 1574 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) 1575 (set (match_dup 3) (match_op_dup:SI 6 [(match_dup 4) (match_dup 5)]))] 1576 " 1577 { 1578 operands[3] = gen_highpart (SImode, operands[0]); 1579 operands[0] = gen_lowpart (SImode, operands[0]); 1580 operands[4] = gen_highpart (SImode, operands[1]); 1581 operands[1] = gen_lowpart (SImode, operands[1]); 1582 operands[5] = gen_highpart (SImode, operands[2]); 1583 operands[2] = gen_lowpart (SImode, operands[2]); 1584 }" 1585) 1586 1587(define_split 1588 [(set (match_operand:DI 0 "s_register_operand" "") 1589 (match_operator:DI 6 "logical_binary_operator" 1590 [(sign_extend:DI (match_operand:SI 2 "s_register_operand" "")) 1591 (match_operand:DI 1 "s_register_operand" "")]))] 1592 "TARGET_ARM && reload_completed" 1593 [(set (match_dup 0) (match_op_dup:SI 6 [(match_dup 1) (match_dup 2)])) 1594 (set (match_dup 3) (match_op_dup:SI 6 1595 [(ashiftrt:SI (match_dup 2) (const_int 31)) 1596 (match_dup 4)]))] 1597 " 1598 { 1599 operands[3] = gen_highpart (SImode, operands[0]); 1600 operands[0] = gen_lowpart (SImode, operands[0]); 1601 operands[4] = gen_highpart (SImode, operands[1]); 1602 operands[1] = gen_lowpart (SImode, operands[1]); 1603 operands[5] = gen_highpart (SImode, operands[2]); 1604 operands[2] = gen_lowpart (SImode, operands[2]); 1605 }" 1606) 1607 1608;; The zero extend of operand 2 means we can just copy the high part of 1609;; operand1 into operand0. 1610(define_split 1611 [(set (match_operand:DI 0 "s_register_operand" "") 1612 (ior:DI 1613 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")) 1614 (match_operand:DI 1 "s_register_operand" "")))] 1615 "TARGET_ARM && operands[0] != operands[1] && reload_completed" 1616 [(set (match_dup 0) (ior:SI (match_dup 1) (match_dup 2))) 1617 (set (match_dup 3) (match_dup 4))] 1618 " 1619 { 1620 operands[4] = gen_highpart (SImode, operands[1]); 1621 operands[3] = gen_highpart (SImode, operands[0]); 1622 operands[0] = gen_lowpart (SImode, operands[0]); 1623 operands[1] = gen_lowpart (SImode, operands[1]); 1624 }" 1625) 1626 1627;; The zero extend of operand 2 means we can just copy the high part of 1628;; operand1 into operand0. 1629(define_split 1630 [(set (match_operand:DI 0 "s_register_operand" "") 1631 (xor:DI 1632 (zero_extend:DI (match_operand:SI 2 "s_register_operand" "")) 1633 (match_operand:DI 1 "s_register_operand" "")))] 1634 "TARGET_ARM && operands[0] != operands[1] && reload_completed" 1635 [(set (match_dup 0) (xor:SI (match_dup 1) (match_dup 2))) 1636 (set (match_dup 3) (match_dup 4))] 1637 " 1638 { 1639 operands[4] = gen_highpart (SImode, operands[1]); 1640 operands[3] = gen_highpart (SImode, operands[0]); 1641 operands[0] = gen_lowpart (SImode, operands[0]); 1642 operands[1] = gen_lowpart (SImode, operands[1]); 1643 }" 1644) 1645 1646(define_insn "anddi3" 1647 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1648 (and:DI (match_operand:DI 1 "s_register_operand" "%0,r") 1649 (match_operand:DI 2 "s_register_operand" "r,r")))] 1650 "TARGET_ARM" 1651 "#" 1652 [(set_attr "length" "8")] 1653) 1654 1655(define_insn_and_split "*anddi_zesidi_di" 1656 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1657 (and:DI (zero_extend:DI 1658 (match_operand:SI 2 "s_register_operand" "r,r")) 1659 (match_operand:DI 1 "s_register_operand" "?r,0")))] 1660 "TARGET_ARM" 1661 "#" 1662 "TARGET_ARM && reload_completed" 1663 ; The zero extend of operand 2 clears the high word of the output 1664 ; operand. 1665 [(set (match_dup 0) (and:SI (match_dup 1) (match_dup 2))) 1666 (set (match_dup 3) (const_int 0))] 1667 " 1668 { 1669 operands[3] = gen_highpart (SImode, operands[0]); 1670 operands[0] = gen_lowpart (SImode, operands[0]); 1671 operands[1] = gen_lowpart (SImode, operands[1]); 1672 }" 1673 [(set_attr "length" "8")] 1674) 1675 1676(define_insn "*anddi_sesdi_di" 1677 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1678 (and:DI (sign_extend:DI 1679 (match_operand:SI 2 "s_register_operand" "r,r")) 1680 (match_operand:DI 1 "s_register_operand" "?r,0")))] 1681 "TARGET_ARM" 1682 "#" 1683 [(set_attr "length" "8")] 1684) 1685 1686(define_expand "andsi3" 1687 [(set (match_operand:SI 0 "s_register_operand" "") 1688 (and:SI (match_operand:SI 1 "s_register_operand" "") 1689 (match_operand:SI 2 "reg_or_int_operand" "")))] 1690 "TARGET_EITHER" 1691 " 1692 if (TARGET_ARM) 1693 { 1694 if (GET_CODE (operands[2]) == CONST_INT) 1695 { 1696 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0], 1697 operands[1], 1698 (no_new_pseudos 1699 ? 0 : preserve_subexpressions_p ())); 1700 DONE; 1701 } 1702 } 1703 else /* TARGET_THUMB */ 1704 { 1705 if (GET_CODE (operands[2]) != CONST_INT) 1706 operands[2] = force_reg (SImode, operands[2]); 1707 else 1708 { 1709 int i; 1710 1711 if (((unsigned HOST_WIDE_INT) ~INTVAL (operands[2])) < 256) 1712 { 1713 operands[2] = force_reg (SImode, 1714 GEN_INT (~INTVAL (operands[2]))); 1715 1716 emit_insn (gen_bicsi3 (operands[0], operands[2], operands[1])); 1717 1718 DONE; 1719 } 1720 1721 for (i = 9; i <= 31; i++) 1722 { 1723 if ((((HOST_WIDE_INT) 1) << i) - 1 == INTVAL (operands[2])) 1724 { 1725 emit_insn (gen_extzv (operands[0], operands[1], GEN_INT (i), 1726 const0_rtx)); 1727 DONE; 1728 } 1729 else if ((((HOST_WIDE_INT) 1) << i) - 1 1730 == ~INTVAL (operands[2])) 1731 { 1732 rtx shift = GEN_INT (i); 1733 rtx reg = gen_reg_rtx (SImode); 1734 1735 emit_insn (gen_lshrsi3 (reg, operands[1], shift)); 1736 emit_insn (gen_ashlsi3 (operands[0], reg, shift)); 1737 1738 DONE; 1739 } 1740 } 1741 1742 operands[2] = force_reg (SImode, operands[2]); 1743 } 1744 } 1745 " 1746) 1747 1748(define_insn_and_split "*arm_andsi3_insn" 1749 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 1750 (and:SI (match_operand:SI 1 "s_register_operand" "r,r,r") 1751 (match_operand:SI 2 "reg_or_int_operand" "rI,K,?n")))] 1752 "TARGET_ARM" 1753 "@ 1754 and%?\\t%0, %1, %2 1755 bic%?\\t%0, %1, #%B2 1756 #" 1757 "TARGET_ARM 1758 && GET_CODE (operands[2]) == CONST_INT 1759 && !(const_ok_for_arm (INTVAL (operands[2])) 1760 || const_ok_for_arm (~INTVAL (operands[2])))" 1761 [(clobber (const_int 0))] 1762 " 1763 arm_split_constant (AND, SImode, INTVAL (operands[2]), operands[0], 1764 operands[1], 0); 1765 DONE; 1766 " 1767 [(set_attr "length" "4,4,16") 1768 (set_attr "predicable" "yes")] 1769) 1770 1771(define_insn "*thumb_andsi3_insn" 1772 [(set (match_operand:SI 0 "register_operand" "=l") 1773 (and:SI (match_operand:SI 1 "register_operand" "%0") 1774 (match_operand:SI 2 "register_operand" "l")))] 1775 "TARGET_THUMB" 1776 "and\\t%0, %0, %2" 1777 [(set_attr "length" "2")] 1778) 1779 1780(define_insn "*andsi3_compare0" 1781 [(set (reg:CC_NOOV CC_REGNUM) 1782 (compare:CC_NOOV 1783 (and:SI (match_operand:SI 1 "s_register_operand" "r,r") 1784 (match_operand:SI 2 "arm_not_operand" "rI,K")) 1785 (const_int 0))) 1786 (set (match_operand:SI 0 "s_register_operand" "=r,r") 1787 (and:SI (match_dup 1) (match_dup 2)))] 1788 "TARGET_ARM" 1789 "@ 1790 and%?s\\t%0, %1, %2 1791 bic%?s\\t%0, %1, #%B2" 1792 [(set_attr "conds" "set")] 1793) 1794 1795(define_insn "*andsi3_compare0_scratch" 1796 [(set (reg:CC_NOOV CC_REGNUM) 1797 (compare:CC_NOOV 1798 (and:SI (match_operand:SI 0 "s_register_operand" "r,r") 1799 (match_operand:SI 1 "arm_not_operand" "rI,K")) 1800 (const_int 0))) 1801 (clobber (match_scratch:SI 2 "=X,r"))] 1802 "TARGET_ARM" 1803 "@ 1804 tst%?\\t%0, %1 1805 bic%?s\\t%2, %0, #%B1" 1806 [(set_attr "conds" "set")] 1807) 1808 1809(define_insn "*zeroextractsi_compare0_scratch" 1810 [(set (reg:CC_NOOV CC_REGNUM) 1811 (compare:CC_NOOV (zero_extract:SI 1812 (match_operand:SI 0 "s_register_operand" "r") 1813 (match_operand 1 "const_int_operand" "n") 1814 (match_operand 2 "const_int_operand" "n")) 1815 (const_int 0)))] 1816 "TARGET_ARM 1817 && (INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) < 32 1818 && INTVAL (operands[1]) > 0 1819 && INTVAL (operands[1]) + (INTVAL (operands[2]) & 1) <= 8 1820 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)" 1821 "* 1822 operands[1] = GEN_INT (((1 << INTVAL (operands[1])) - 1) 1823 << INTVAL (operands[2])); 1824 output_asm_insn (\"tst%?\\t%0, %1\", operands); 1825 return \"\"; 1826 " 1827 [(set_attr "conds" "set")] 1828) 1829 1830(define_insn "*ne_zeroextractsi" 1831 [(set (match_operand:SI 0 "s_register_operand" "=r") 1832 (ne:SI (zero_extract:SI 1833 (match_operand:SI 1 "s_register_operand" "r") 1834 (match_operand:SI 2 "const_int_operand" "n") 1835 (match_operand:SI 3 "const_int_operand" "n")) 1836 (const_int 0)))] 1837 "TARGET_ARM 1838 && (INTVAL (operands[3]) >= 0 && INTVAL (operands[3]) < 32 1839 && INTVAL (operands[2]) > 0 1840 && INTVAL (operands[2]) + (INTVAL (operands[3]) & 1) <= 8 1841 && INTVAL (operands[2]) + INTVAL (operands[3]) <= 32)" 1842 "* 1843 operands[2] = GEN_INT (((1 << INTVAL (operands[2])) - 1) 1844 << INTVAL (operands[3])); 1845 output_asm_insn (\"ands\\t%0, %1, %2\", operands); 1846 return \"movne\\t%0, #1\"; 1847 " 1848 [(set_attr "conds" "clob") 1849 (set_attr "length" "8")] 1850) 1851 1852;;; ??? This pattern is bogus. If operand3 has bits outside the range 1853;;; represented by the bitfield, then this will produce incorrect results. 1854;;; Somewhere, the value needs to be truncated. On targets like the m68k, 1855;;; which have a real bitfield insert instruction, the truncation happens 1856;;; in the bitfield insert instruction itself. Since arm does not have a 1857;;; bitfield insert instruction, we would have to emit code here to truncate 1858;;; the value before we insert. This loses some of the advantage of having 1859;;; this insv pattern, so this pattern needs to be reevalutated. 1860 1861(define_expand "insv" 1862 [(set (zero_extract:SI (match_operand:SI 0 "s_register_operand" "") 1863 (match_operand:SI 1 "general_operand" "") 1864 (match_operand:SI 2 "general_operand" "")) 1865 (match_operand:SI 3 "nonmemory_operand" ""))] 1866 "TARGET_ARM" 1867 " 1868 { 1869 int start_bit = INTVAL (operands[2]); 1870 int width = INTVAL (operands[1]); 1871 HOST_WIDE_INT mask = (((HOST_WIDE_INT)1) << width) - 1; 1872 rtx target, subtarget; 1873 1874 target = operands[0]; 1875 /* Avoid using a subreg as a subtarget, and avoid writing a paradoxical 1876 subreg as the final target. */ 1877 if (GET_CODE (target) == SUBREG) 1878 { 1879 subtarget = gen_reg_rtx (SImode); 1880 if (GET_MODE_SIZE (GET_MODE (SUBREG_REG (target))) 1881 < GET_MODE_SIZE (SImode)) 1882 target = SUBREG_REG (target); 1883 } 1884 else 1885 subtarget = target; 1886 1887 if (GET_CODE (operands[3]) == CONST_INT) 1888 { 1889 /* Since we are inserting a known constant, we may be able to 1890 reduce the number of bits that we have to clear so that 1891 the mask becomes simple. */ 1892 /* ??? This code does not check to see if the new mask is actually 1893 simpler. It may not be. */ 1894 rtx op1 = gen_reg_rtx (SImode); 1895 /* ??? Truncate operand3 to fit in the bitfield. See comment before 1896 start of this pattern. */ 1897 HOST_WIDE_INT op3_value = mask & INTVAL (operands[3]); 1898 HOST_WIDE_INT mask2 = ((mask & ~op3_value) << start_bit); 1899 1900 emit_insn (gen_andsi3 (op1, operands[0], GEN_INT (~mask2))); 1901 emit_insn (gen_iorsi3 (subtarget, op1, 1902 GEN_INT (op3_value << start_bit))); 1903 } 1904 else if (start_bit == 0 1905 && !(const_ok_for_arm (mask) 1906 || const_ok_for_arm (~mask))) 1907 { 1908 /* A Trick, since we are setting the bottom bits in the word, 1909 we can shift operand[3] up, operand[0] down, OR them together 1910 and rotate the result back again. This takes 3 insns, and 1911 the third might be mergable into another op. */ 1912 /* The shift up copes with the possibility that operand[3] is 1913 wider than the bitfield. */ 1914 rtx op0 = gen_reg_rtx (SImode); 1915 rtx op1 = gen_reg_rtx (SImode); 1916 1917 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width))); 1918 emit_insn (gen_lshrsi3 (op1, operands[0], operands[1])); 1919 emit_insn (gen_iorsi3 (op1, op1, op0)); 1920 emit_insn (gen_rotlsi3 (subtarget, op1, operands[1])); 1921 } 1922 else if ((width + start_bit == 32) 1923 && !(const_ok_for_arm (mask) 1924 || const_ok_for_arm (~mask))) 1925 { 1926 /* Similar trick, but slightly less efficient. */ 1927 1928 rtx op0 = gen_reg_rtx (SImode); 1929 rtx op1 = gen_reg_rtx (SImode); 1930 1931 emit_insn (gen_ashlsi3 (op0, operands[3], GEN_INT (32 - width))); 1932 emit_insn (gen_ashlsi3 (op1, operands[0], operands[1])); 1933 emit_insn (gen_lshrsi3 (op1, op1, operands[1])); 1934 emit_insn (gen_iorsi3 (subtarget, op1, op0)); 1935 } 1936 else 1937 { 1938 rtx op0 = GEN_INT (mask); 1939 rtx op1 = gen_reg_rtx (SImode); 1940 rtx op2 = gen_reg_rtx (SImode); 1941 1942 if (!(const_ok_for_arm (mask) || const_ok_for_arm (~mask))) 1943 { 1944 rtx tmp = gen_reg_rtx (SImode); 1945 1946 emit_insn (gen_movsi (tmp, op0)); 1947 op0 = tmp; 1948 } 1949 1950 /* Mask out any bits in operand[3] that are not needed. */ 1951 emit_insn (gen_andsi3 (op1, operands[3], op0)); 1952 1953 if (GET_CODE (op0) == CONST_INT 1954 && (const_ok_for_arm (mask << start_bit) 1955 || const_ok_for_arm (~(mask << start_bit)))) 1956 { 1957 op0 = GEN_INT (~(mask << start_bit)); 1958 emit_insn (gen_andsi3 (op2, operands[0], op0)); 1959 } 1960 else 1961 { 1962 if (GET_CODE (op0) == CONST_INT) 1963 { 1964 rtx tmp = gen_reg_rtx (SImode); 1965 1966 emit_insn (gen_movsi (tmp, op0)); 1967 op0 = tmp; 1968 } 1969 1970 if (start_bit != 0) 1971 emit_insn (gen_ashlsi3 (op0, op0, operands[2])); 1972 1973 emit_insn (gen_andsi_notsi_si (op2, operands[0], op0)); 1974 } 1975 1976 if (start_bit != 0) 1977 emit_insn (gen_ashlsi3 (op1, op1, operands[2])); 1978 1979 emit_insn (gen_iorsi3 (subtarget, op1, op2)); 1980 } 1981 1982 if (subtarget != target) 1983 { 1984 /* If TARGET is still a SUBREG, then it must be wider than a word, 1985 so we must be careful only to set the subword we were asked to. */ 1986 if (GET_CODE (target) == SUBREG) 1987 emit_move_insn (target, subtarget); 1988 else 1989 emit_move_insn (target, gen_lowpart (GET_MODE (target), subtarget)); 1990 } 1991 1992 DONE; 1993 }" 1994) 1995 1996; constants for op 2 will never be given to these patterns. 1997(define_insn_and_split "*anddi_notdi_di" 1998 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 1999 (and:DI (not:DI (match_operand:DI 1 "s_register_operand" "r,0")) 2000 (match_operand:DI 2 "s_register_operand" "0,r")))] 2001 "TARGET_ARM" 2002 "#" 2003 "TARGET_ARM && reload_completed" 2004 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2))) 2005 (set (match_dup 3) (and:SI (not:SI (match_dup 4)) (match_dup 5)))] 2006 " 2007 { 2008 operands[3] = gen_highpart (SImode, operands[0]); 2009 operands[0] = gen_lowpart (SImode, operands[0]); 2010 operands[4] = gen_highpart (SImode, operands[1]); 2011 operands[1] = gen_lowpart (SImode, operands[1]); 2012 operands[5] = gen_highpart (SImode, operands[2]); 2013 operands[2] = gen_lowpart (SImode, operands[2]); 2014 }" 2015 [(set_attr "length" "8") 2016 (set_attr "predicable" "yes")] 2017) 2018 2019(define_insn_and_split "*anddi_notzesidi_di" 2020 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2021 (and:DI (not:DI (zero_extend:DI 2022 (match_operand:SI 2 "s_register_operand" "r,r"))) 2023 (match_operand:DI 1 "s_register_operand" "0,?r")))] 2024 "TARGET_ARM" 2025 "@ 2026 bic%?\\t%Q0, %Q1, %2 2027 #" 2028 ; (not (zero_extend ...)) allows us to just copy the high word from 2029 ; operand1 to operand0. 2030 "TARGET_ARM 2031 && reload_completed 2032 && operands[0] != operands[1]" 2033 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2))) 2034 (set (match_dup 3) (match_dup 4))] 2035 " 2036 { 2037 operands[3] = gen_highpart (SImode, operands[0]); 2038 operands[0] = gen_lowpart (SImode, operands[0]); 2039 operands[4] = gen_highpart (SImode, operands[1]); 2040 operands[1] = gen_lowpart (SImode, operands[1]); 2041 }" 2042 [(set_attr "length" "4,8") 2043 (set_attr "predicable" "yes")] 2044) 2045 2046(define_insn_and_split "*anddi_notsesidi_di" 2047 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2048 (and:DI (not:DI (sign_extend:DI 2049 (match_operand:SI 2 "s_register_operand" "r,r"))) 2050 (match_operand:DI 1 "s_register_operand" "?r,0")))] 2051 "TARGET_ARM" 2052 "#" 2053 "TARGET_ARM && reload_completed" 2054 [(set (match_dup 0) (and:SI (not:SI (match_dup 1)) (match_dup 2))) 2055 (set (match_dup 3) (and:SI (not:SI 2056 (ashiftrt:SI (match_dup 2) (const_int 31))) 2057 (match_dup 4)))] 2058 " 2059 { 2060 operands[3] = gen_highpart (SImode, operands[0]); 2061 operands[0] = gen_lowpart (SImode, operands[0]); 2062 operands[4] = gen_highpart (SImode, operands[1]); 2063 operands[1] = gen_lowpart (SImode, operands[1]); 2064 }" 2065 [(set_attr "length" "8") 2066 (set_attr "predicable" "yes")] 2067) 2068 2069(define_insn "andsi_notsi_si" 2070 [(set (match_operand:SI 0 "s_register_operand" "=r") 2071 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) 2072 (match_operand:SI 1 "s_register_operand" "r")))] 2073 "TARGET_ARM" 2074 "bic%?\\t%0, %1, %2" 2075 [(set_attr "predicable" "yes")] 2076) 2077 2078(define_insn "bicsi3" 2079 [(set (match_operand:SI 0 "register_operand" "=l") 2080 (and:SI (not:SI (match_operand:SI 1 "register_operand" "l")) 2081 (match_operand:SI 2 "register_operand" "0")))] 2082 "TARGET_THUMB" 2083 "bic\\t%0, %0, %1" 2084 [(set_attr "length" "2")] 2085) 2086 2087(define_insn "andsi_not_shiftsi_si" 2088 [(set (match_operand:SI 0 "s_register_operand" "=r") 2089 (and:SI (not:SI (match_operator:SI 4 "shift_operator" 2090 [(match_operand:SI 2 "s_register_operand" "r") 2091 (match_operand:SI 3 "arm_rhs_operand" "rM")])) 2092 (match_operand:SI 1 "s_register_operand" "r")))] 2093 "TARGET_ARM" 2094 "bic%?\\t%0, %1, %2%S4" 2095 [(set_attr "predicable" "yes") 2096 (set_attr "shift" "2") 2097 ] 2098) 2099 2100(define_insn "*andsi_notsi_si_compare0" 2101 [(set (reg:CC_NOOV CC_REGNUM) 2102 (compare:CC_NOOV 2103 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) 2104 (match_operand:SI 1 "s_register_operand" "r")) 2105 (const_int 0))) 2106 (set (match_operand:SI 0 "s_register_operand" "=r") 2107 (and:SI (not:SI (match_dup 2)) (match_dup 1)))] 2108 "TARGET_ARM" 2109 "bic%?s\\t%0, %1, %2" 2110 [(set_attr "conds" "set")] 2111) 2112 2113(define_insn "*andsi_notsi_si_compare0_scratch" 2114 [(set (reg:CC_NOOV CC_REGNUM) 2115 (compare:CC_NOOV 2116 (and:SI (not:SI (match_operand:SI 2 "s_register_operand" "r")) 2117 (match_operand:SI 1 "s_register_operand" "r")) 2118 (const_int 0))) 2119 (clobber (match_scratch:SI 0 "=r"))] 2120 "TARGET_ARM" 2121 "bic%?s\\t%0, %1, %2" 2122 [(set_attr "conds" "set")] 2123) 2124 2125(define_insn "iordi3" 2126 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2127 (ior:DI (match_operand:DI 1 "s_register_operand" "%0,r") 2128 (match_operand:DI 2 "s_register_operand" "r,r")))] 2129 "TARGET_ARM" 2130 "#" 2131 [(set_attr "length" "8") 2132 (set_attr "predicable" "yes")] 2133) 2134 2135(define_insn "*iordi_zesidi_di" 2136 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2137 (ior:DI (zero_extend:DI 2138 (match_operand:SI 2 "s_register_operand" "r,r")) 2139 (match_operand:DI 1 "s_register_operand" "0,?r")))] 2140 "TARGET_ARM" 2141 "@ 2142 orr%?\\t%Q0, %Q1, %2 2143 #" 2144 [(set_attr "length" "4,8") 2145 (set_attr "predicable" "yes")] 2146) 2147 2148(define_insn "*iordi_sesidi_di" 2149 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2150 (ior:DI (sign_extend:DI 2151 (match_operand:SI 2 "s_register_operand" "r,r")) 2152 (match_operand:DI 1 "s_register_operand" "?r,0")))] 2153 "TARGET_ARM" 2154 "#" 2155 [(set_attr "length" "8") 2156 (set_attr "predicable" "yes")] 2157) 2158 2159(define_expand "iorsi3" 2160 [(set (match_operand:SI 0 "s_register_operand" "") 2161 (ior:SI (match_operand:SI 1 "s_register_operand" "") 2162 (match_operand:SI 2 "reg_or_int_operand" "")))] 2163 "TARGET_EITHER" 2164 " 2165 if (GET_CODE (operands[2]) == CONST_INT) 2166 { 2167 if (TARGET_ARM) 2168 { 2169 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0], 2170 operands[1], 2171 (no_new_pseudos 2172 ? 0 : preserve_subexpressions_p ())); 2173 DONE; 2174 } 2175 else /* TARGET_THUMB */ 2176 operands [2] = force_reg (SImode, operands [2]); 2177 } 2178 " 2179) 2180 2181(define_insn_and_split "*arm_iorsi3" 2182 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 2183 (ior:SI (match_operand:SI 1 "s_register_operand" "r,r") 2184 (match_operand:SI 2 "reg_or_int_operand" "rI,?n")))] 2185 "TARGET_ARM" 2186 "@ 2187 orr%?\\t%0, %1, %2 2188 #" 2189 "TARGET_ARM 2190 && GET_CODE (operands[2]) == CONST_INT 2191 && !const_ok_for_arm (INTVAL (operands[2]))" 2192 [(clobber (const_int 0))] 2193 " 2194 arm_split_constant (IOR, SImode, INTVAL (operands[2]), operands[0], 2195 operands[1], 0); 2196 DONE; 2197 " 2198 [(set_attr "length" "4,16") 2199 (set_attr "predicable" "yes")] 2200) 2201 2202(define_insn "*thumb_iorsi3" 2203 [(set (match_operand:SI 0 "register_operand" "=l") 2204 (ior:SI (match_operand:SI 1 "register_operand" "%0") 2205 (match_operand:SI 2 "register_operand" "l")))] 2206 "TARGET_THUMB" 2207 "orr\\t%0, %0, %2" 2208 [(set_attr "length" "2")] 2209) 2210 2211(define_peephole2 2212 [(match_scratch:SI 3 "r") 2213 (set (match_operand:SI 0 "s_register_operand" "") 2214 (ior:SI (match_operand:SI 1 "s_register_operand" "") 2215 (match_operand:SI 2 "const_int_operand" "")))] 2216 "TARGET_ARM 2217 && !const_ok_for_arm (INTVAL (operands[2])) 2218 && const_ok_for_arm (~INTVAL (operands[2]))" 2219 [(set (match_dup 3) (match_dup 2)) 2220 (set (match_dup 0) (ior:SI (match_dup 1) (match_dup 3)))] 2221 "" 2222) 2223 2224(define_insn "*iorsi3_compare0" 2225 [(set (reg:CC_NOOV CC_REGNUM) 2226 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r") 2227 (match_operand:SI 2 "arm_rhs_operand" "rI")) 2228 (const_int 0))) 2229 (set (match_operand:SI 0 "s_register_operand" "=r") 2230 (ior:SI (match_dup 1) (match_dup 2)))] 2231 "TARGET_ARM" 2232 "orr%?s\\t%0, %1, %2" 2233 [(set_attr "conds" "set")] 2234) 2235 2236(define_insn "*iorsi3_compare0_scratch" 2237 [(set (reg:CC_NOOV CC_REGNUM) 2238 (compare:CC_NOOV (ior:SI (match_operand:SI 1 "s_register_operand" "%r") 2239 (match_operand:SI 2 "arm_rhs_operand" "rI")) 2240 (const_int 0))) 2241 (clobber (match_scratch:SI 0 "=r"))] 2242 "TARGET_ARM" 2243 "orr%?s\\t%0, %1, %2" 2244 [(set_attr "conds" "set")] 2245) 2246 2247(define_insn "xordi3" 2248 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2249 (xor:DI (match_operand:DI 1 "s_register_operand" "%0,r") 2250 (match_operand:DI 2 "s_register_operand" "r,r")))] 2251 "TARGET_ARM" 2252 "#" 2253 [(set_attr "length" "8") 2254 (set_attr "predicable" "yes")] 2255) 2256 2257(define_insn "*xordi_zesidi_di" 2258 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2259 (xor:DI (zero_extend:DI 2260 (match_operand:SI 2 "s_register_operand" "r,r")) 2261 (match_operand:DI 1 "s_register_operand" "0,?r")))] 2262 "TARGET_ARM" 2263 "@ 2264 eor%?\\t%Q0, %Q1, %2 2265 #" 2266 [(set_attr "length" "4,8") 2267 (set_attr "predicable" "yes")] 2268) 2269 2270(define_insn "*xordi_sesidi_di" 2271 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2272 (xor:DI (sign_extend:DI 2273 (match_operand:SI 2 "s_register_operand" "r,r")) 2274 (match_operand:DI 1 "s_register_operand" "?r,0")))] 2275 "TARGET_ARM" 2276 "#" 2277 [(set_attr "length" "8") 2278 (set_attr "predicable" "yes")] 2279) 2280 2281(define_expand "xorsi3" 2282 [(set (match_operand:SI 0 "s_register_operand" "") 2283 (xor:SI (match_operand:SI 1 "s_register_operand" "") 2284 (match_operand:SI 2 "arm_rhs_operand" "")))] 2285 "TARGET_EITHER" 2286 "if (TARGET_THUMB) 2287 if (GET_CODE (operands[2]) == CONST_INT) 2288 operands[2] = force_reg (SImode, operands[2]); 2289 " 2290) 2291 2292(define_insn "*arm_xorsi3" 2293 [(set (match_operand:SI 0 "s_register_operand" "=r") 2294 (xor:SI (match_operand:SI 1 "s_register_operand" "r") 2295 (match_operand:SI 2 "arm_rhs_operand" "rI")))] 2296 "TARGET_ARM" 2297 "eor%?\\t%0, %1, %2" 2298 [(set_attr "predicable" "yes")] 2299) 2300 2301(define_insn "*thumb_xorsi3" 2302 [(set (match_operand:SI 0 "register_operand" "=l") 2303 (xor:SI (match_operand:SI 1 "register_operand" "%0") 2304 (match_operand:SI 2 "register_operand" "l")))] 2305 "TARGET_THUMB" 2306 "eor\\t%0, %0, %2" 2307 [(set_attr "length" "2")] 2308) 2309 2310(define_insn "*xorsi3_compare0" 2311 [(set (reg:CC_NOOV CC_REGNUM) 2312 (compare:CC_NOOV (xor:SI (match_operand:SI 1 "s_register_operand" "r") 2313 (match_operand:SI 2 "arm_rhs_operand" "rI")) 2314 (const_int 0))) 2315 (set (match_operand:SI 0 "s_register_operand" "=r") 2316 (xor:SI (match_dup 1) (match_dup 2)))] 2317 "TARGET_ARM" 2318 "eor%?s\\t%0, %1, %2" 2319 [(set_attr "conds" "set")] 2320) 2321 2322(define_insn "*xorsi3_compare0_scratch" 2323 [(set (reg:CC_NOOV CC_REGNUM) 2324 (compare:CC_NOOV (xor:SI (match_operand:SI 0 "s_register_operand" "r") 2325 (match_operand:SI 1 "arm_rhs_operand" "rI")) 2326 (const_int 0)))] 2327 "TARGET_ARM" 2328 "teq%?\\t%0, %1" 2329 [(set_attr "conds" "set")] 2330) 2331 2332; By splitting (IOR (AND (NOT A) (NOT B)) C) as D = AND (IOR A B) (NOT C), 2333; (NOT D) we can sometimes merge the final NOT into one of the following 2334; insns. 2335 2336(define_split 2337 [(set (match_operand:SI 0 "s_register_operand" "=r") 2338 (ior:SI (and:SI (not:SI (match_operand:SI 1 "s_register_operand" "r")) 2339 (not:SI (match_operand:SI 2 "arm_rhs_operand" "rI"))) 2340 (match_operand:SI 3 "arm_rhs_operand" "rI"))) 2341 (clobber (match_operand:SI 4 "s_register_operand" "=r"))] 2342 "TARGET_ARM" 2343 [(set (match_dup 4) (and:SI (ior:SI (match_dup 1) (match_dup 2)) 2344 (not:SI (match_dup 3)))) 2345 (set (match_dup 0) (not:SI (match_dup 4)))] 2346 "" 2347) 2348 2349(define_insn "*andsi_iorsi3_notsi" 2350 [(set (match_operand:SI 0 "s_register_operand" "=&r,&r,&r") 2351 (and:SI (ior:SI (match_operand:SI 1 "s_register_operand" "r,r,0") 2352 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")) 2353 (not:SI (match_operand:SI 3 "arm_rhs_operand" "rI,rI,rI"))))] 2354 "TARGET_ARM" 2355 "orr%?\\t%0, %1, %2\;bic%?\\t%0, %0, %3" 2356 [(set_attr "length" "8") 2357 (set_attr "predicable" "yes")] 2358) 2359 2360 2361 2362;; Minimum and maximum insns 2363 2364(define_insn "smaxsi3" 2365 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 2366 (smax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") 2367 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 2368 (clobber (reg:CC CC_REGNUM))] 2369 "TARGET_ARM" 2370 "@ 2371 cmp\\t%1, %2\;movlt\\t%0, %2 2372 cmp\\t%1, %2\;movge\\t%0, %1 2373 cmp\\t%1, %2\;movge\\t%0, %1\;movlt\\t%0, %2" 2374 [(set_attr "conds" "clob") 2375 (set_attr "length" "8,8,12")] 2376) 2377 2378(define_insn "sminsi3" 2379 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 2380 (smin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") 2381 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 2382 (clobber (reg:CC CC_REGNUM))] 2383 "TARGET_ARM" 2384 "@ 2385 cmp\\t%1, %2\;movge\\t%0, %2 2386 cmp\\t%1, %2\;movlt\\t%0, %1 2387 cmp\\t%1, %2\;movlt\\t%0, %1\;movge\\t%0, %2" 2388 [(set_attr "conds" "clob") 2389 (set_attr "length" "8,8,12")] 2390) 2391 2392(define_insn "umaxsi3" 2393 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 2394 (umax:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") 2395 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 2396 (clobber (reg:CC CC_REGNUM))] 2397 "TARGET_ARM" 2398 "@ 2399 cmp\\t%1, %2\;movcc\\t%0, %2 2400 cmp\\t%1, %2\;movcs\\t%0, %1 2401 cmp\\t%1, %2\;movcs\\t%0, %1\;movcc\\t%0, %2" 2402 [(set_attr "conds" "clob") 2403 (set_attr "length" "8,8,12")] 2404) 2405 2406(define_insn "uminsi3" 2407 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 2408 (umin:SI (match_operand:SI 1 "s_register_operand" "0,r,?r") 2409 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 2410 (clobber (reg:CC CC_REGNUM))] 2411 "TARGET_ARM" 2412 "@ 2413 cmp\\t%1, %2\;movcs\\t%0, %2 2414 cmp\\t%1, %2\;movcc\\t%0, %1 2415 cmp\\t%1, %2\;movcc\\t%0, %1\;movcs\\t%0, %2" 2416 [(set_attr "conds" "clob") 2417 (set_attr "length" "8,8,12")] 2418) 2419 2420(define_insn "*store_minmaxsi" 2421 [(set (match_operand:SI 0 "memory_operand" "=m") 2422 (match_operator:SI 3 "minmax_operator" 2423 [(match_operand:SI 1 "s_register_operand" "r") 2424 (match_operand:SI 2 "s_register_operand" "r")])) 2425 (clobber (reg:CC CC_REGNUM))] 2426 "TARGET_ARM" 2427 "* 2428 operands[3] = gen_rtx (minmax_code (operands[3]), SImode, operands[1], 2429 operands[2]); 2430 output_asm_insn (\"cmp\\t%1, %2\", operands); 2431 output_asm_insn (\"str%d3\\t%1, %0\", operands); 2432 output_asm_insn (\"str%D3\\t%2, %0\", operands); 2433 return \"\"; 2434 " 2435 [(set_attr "conds" "clob") 2436 (set_attr "length" "12") 2437 (set_attr "type" "store1")] 2438) 2439 2440; Reject the frame pointer in operand[1], since reloading this after 2441; it has been eliminated can cause carnage. 2442(define_insn "*minmax_arithsi" 2443 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 2444 (match_operator:SI 4 "shiftable_operator" 2445 [(match_operator:SI 5 "minmax_operator" 2446 [(match_operand:SI 2 "s_register_operand" "r,r") 2447 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 2448 (match_operand:SI 1 "s_register_operand" "0,?r")])) 2449 (clobber (reg:CC CC_REGNUM))] 2450 "TARGET_ARM 2451 && (GET_CODE (operands[1]) != REG 2452 || (REGNO(operands[1]) != FRAME_POINTER_REGNUM 2453 && REGNO(operands[1]) != ARG_POINTER_REGNUM))" 2454 "* 2455 { 2456 enum rtx_code code = GET_CODE (operands[4]); 2457 2458 operands[5] = gen_rtx (minmax_code (operands[5]), SImode, operands[2], 2459 operands[3]); 2460 output_asm_insn (\"cmp\\t%2, %3\", operands); 2461 output_asm_insn (\"%i4%d5\\t%0, %1, %2\", operands); 2462 if (which_alternative != 0 || operands[3] != const0_rtx 2463 || (code != PLUS && code != MINUS && code != IOR && code != XOR)) 2464 output_asm_insn (\"%i4%D5\\t%0, %1, %3\", operands); 2465 return \"\"; 2466 }" 2467 [(set_attr "conds" "clob") 2468 (set_attr "length" "12")] 2469) 2470 2471 2472;; Shift and rotation insns 2473 2474(define_expand "ashlsi3" 2475 [(set (match_operand:SI 0 "s_register_operand" "") 2476 (ashift:SI (match_operand:SI 1 "s_register_operand" "") 2477 (match_operand:SI 2 "arm_rhs_operand" "")))] 2478 "TARGET_EITHER" 2479 " 2480 if (GET_CODE (operands[2]) == CONST_INT 2481 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31) 2482 { 2483 emit_insn (gen_movsi (operands[0], const0_rtx)); 2484 DONE; 2485 } 2486 " 2487) 2488 2489(define_insn "*thumb_ashlsi3" 2490 [(set (match_operand:SI 0 "register_operand" "=l,l") 2491 (ashift:SI (match_operand:SI 1 "register_operand" "l,0") 2492 (match_operand:SI 2 "nonmemory_operand" "N,l")))] 2493 "TARGET_THUMB" 2494 "lsl\\t%0, %1, %2" 2495 [(set_attr "length" "2")] 2496) 2497 2498(define_expand "ashrsi3" 2499 [(set (match_operand:SI 0 "s_register_operand" "") 2500 (ashiftrt:SI (match_operand:SI 1 "s_register_operand" "") 2501 (match_operand:SI 2 "arm_rhs_operand" "")))] 2502 "TARGET_EITHER" 2503 " 2504 if (GET_CODE (operands[2]) == CONST_INT 2505 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31) 2506 operands[2] = GEN_INT (31); 2507 " 2508) 2509 2510(define_insn "*thumb_ashrsi3" 2511 [(set (match_operand:SI 0 "register_operand" "=l,l") 2512 (ashiftrt:SI (match_operand:SI 1 "register_operand" "l,0") 2513 (match_operand:SI 2 "nonmemory_operand" "N,l")))] 2514 "TARGET_THUMB" 2515 "asr\\t%0, %1, %2" 2516 [(set_attr "length" "2")] 2517) 2518 2519(define_expand "lshrsi3" 2520 [(set (match_operand:SI 0 "s_register_operand" "") 2521 (lshiftrt:SI (match_operand:SI 1 "s_register_operand" "") 2522 (match_operand:SI 2 "arm_rhs_operand" "")))] 2523 "TARGET_EITHER" 2524 " 2525 if (GET_CODE (operands[2]) == CONST_INT 2526 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31) 2527 { 2528 emit_insn (gen_movsi (operands[0], const0_rtx)); 2529 DONE; 2530 } 2531 " 2532) 2533 2534(define_insn "*thumb_lshrsi3" 2535 [(set (match_operand:SI 0 "register_operand" "=l,l") 2536 (lshiftrt:SI (match_operand:SI 1 "register_operand" "l,0") 2537 (match_operand:SI 2 "nonmemory_operand" "N,l")))] 2538 "TARGET_THUMB" 2539 "lsr\\t%0, %1, %2" 2540 [(set_attr "length" "2")] 2541) 2542 2543(define_expand "rotlsi3" 2544 [(set (match_operand:SI 0 "s_register_operand" "") 2545 (rotatert:SI (match_operand:SI 1 "s_register_operand" "") 2546 (match_operand:SI 2 "reg_or_int_operand" "")))] 2547 "TARGET_ARM" 2548 " 2549 if (GET_CODE (operands[2]) == CONST_INT) 2550 operands[2] = GEN_INT ((32 - INTVAL (operands[2])) % 32); 2551 else 2552 { 2553 rtx reg = gen_reg_rtx (SImode); 2554 emit_insn (gen_subsi3 (reg, GEN_INT (32), operands[2])); 2555 operands[2] = reg; 2556 } 2557 " 2558) 2559 2560(define_expand "rotrsi3" 2561 [(set (match_operand:SI 0 "s_register_operand" "") 2562 (rotatert:SI (match_operand:SI 1 "s_register_operand" "") 2563 (match_operand:SI 2 "arm_rhs_operand" "")))] 2564 "TARGET_EITHER" 2565 " 2566 if (TARGET_ARM) 2567 { 2568 if (GET_CODE (operands[2]) == CONST_INT 2569 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) > 31) 2570 operands[2] = GEN_INT (INTVAL (operands[2]) % 32); 2571 } 2572 else /* TARGET_THUMB */ 2573 { 2574 if (GET_CODE (operands [2]) == CONST_INT) 2575 operands [2] = force_reg (SImode, operands[2]); 2576 } 2577 " 2578) 2579 2580(define_insn "*thumb_rotrsi3" 2581 [(set (match_operand:SI 0 "register_operand" "=l") 2582 (rotatert:SI (match_operand:SI 1 "register_operand" "0") 2583 (match_operand:SI 2 "register_operand" "l")))] 2584 "TARGET_THUMB" 2585 "ror\\t%0, %0, %2" 2586 [(set_attr "length" "2")] 2587) 2588 2589(define_insn "*arm_shiftsi3" 2590 [(set (match_operand:SI 0 "s_register_operand" "=r") 2591 (match_operator:SI 3 "shift_operator" 2592 [(match_operand:SI 1 "s_register_operand" "r") 2593 (match_operand:SI 2 "reg_or_int_operand" "rM")]))] 2594 "TARGET_ARM" 2595 "mov%?\\t%0, %1%S3" 2596 [(set_attr "predicable" "yes") 2597 (set_attr "shift" "1") 2598 ] 2599) 2600 2601(define_insn "*shiftsi3_compare0" 2602 [(set (reg:CC_NOOV CC_REGNUM) 2603 (compare:CC_NOOV (match_operator:SI 3 "shift_operator" 2604 [(match_operand:SI 1 "s_register_operand" "r") 2605 (match_operand:SI 2 "arm_rhs_operand" "rM")]) 2606 (const_int 0))) 2607 (set (match_operand:SI 0 "s_register_operand" "=r") 2608 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))] 2609 "TARGET_ARM" 2610 "mov%?s\\t%0, %1%S3" 2611 [(set_attr "conds" "set") 2612 (set_attr "shift" "1") 2613 ] 2614) 2615 2616(define_insn "*shiftsi3_compare0_scratch" 2617 [(set (reg:CC_NOOV CC_REGNUM) 2618 (compare:CC_NOOV (match_operator:SI 3 "shift_operator" 2619 [(match_operand:SI 1 "s_register_operand" "r") 2620 (match_operand:SI 2 "arm_rhs_operand" "rM")]) 2621 (const_int 0))) 2622 (clobber (match_scratch:SI 0 "=r"))] 2623 "TARGET_ARM" 2624 "mov%?s\\t%0, %1%S3" 2625 [(set_attr "conds" "set") 2626 (set_attr "shift" "1") 2627 ] 2628) 2629 2630(define_insn "*notsi_shiftsi" 2631 [(set (match_operand:SI 0 "s_register_operand" "=r") 2632 (not:SI (match_operator:SI 3 "shift_operator" 2633 [(match_operand:SI 1 "s_register_operand" "r") 2634 (match_operand:SI 2 "arm_rhs_operand" "rM")])))] 2635 "TARGET_ARM" 2636 "mvn%?\\t%0, %1%S3" 2637 [(set_attr "predicable" "yes") 2638 (set_attr "shift" "1") 2639 ] 2640) 2641 2642(define_insn "*notsi_shiftsi_compare0" 2643 [(set (reg:CC_NOOV CC_REGNUM) 2644 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator" 2645 [(match_operand:SI 1 "s_register_operand" "r") 2646 (match_operand:SI 2 "arm_rhs_operand" "rM")])) 2647 (const_int 0))) 2648 (set (match_operand:SI 0 "s_register_operand" "=r") 2649 (not:SI (match_op_dup 3 [(match_dup 1) (match_dup 2)])))] 2650 "TARGET_ARM" 2651 "mvn%?s\\t%0, %1%S3" 2652 [(set_attr "conds" "set") 2653 (set_attr "shift" "1") 2654 ] 2655) 2656 2657(define_insn "*not_shiftsi_compare0_scratch" 2658 [(set (reg:CC_NOOV CC_REGNUM) 2659 (compare:CC_NOOV (not:SI (match_operator:SI 3 "shift_operator" 2660 [(match_operand:SI 1 "s_register_operand" "r") 2661 (match_operand:SI 2 "arm_rhs_operand" "rM")])) 2662 (const_int 0))) 2663 (clobber (match_scratch:SI 0 "=r"))] 2664 "TARGET_ARM" 2665 "mvn%?s\\t%0, %1%S3" 2666 [(set_attr "conds" "set") 2667 (set_attr "shift" "1") 2668 ] 2669) 2670 2671;; We don't really have extzv, but defining this using shifts helps 2672;; to reduce register pressure later on. 2673 2674(define_expand "extzv" 2675 [(set (match_dup 4) 2676 (ashift:SI (match_operand:SI 1 "register_operand" "") 2677 (match_operand:SI 2 "const_int_operand" ""))) 2678 (set (match_operand:SI 0 "register_operand" "") 2679 (lshiftrt:SI (match_dup 4) 2680 (match_operand:SI 3 "const_int_operand" "")))] 2681 "TARGET_THUMB" 2682 " 2683 { 2684 HOST_WIDE_INT lshift = 32 - INTVAL (operands[2]) - INTVAL (operands[3]); 2685 HOST_WIDE_INT rshift = 32 - INTVAL (operands[2]); 2686 2687 operands[3] = GEN_INT (rshift); 2688 2689 if (lshift == 0) 2690 { 2691 emit_insn (gen_lshrsi3 (operands[0], operands[1], operands[3])); 2692 DONE; 2693 } 2694 2695 operands[2] = GEN_INT (lshift); 2696 operands[4] = gen_reg_rtx (SImode); 2697 }" 2698) 2699 2700 2701;; Unary arithmetic insns 2702 2703(define_expand "negdi2" 2704 [(parallel 2705 [(set (match_operand:DI 0 "s_register_operand" "") 2706 (neg:DI (match_operand:DI 1 "s_register_operand" ""))) 2707 (clobber (reg:CC CC_REGNUM))])] 2708 "TARGET_EITHER" 2709 " 2710 if (TARGET_THUMB) 2711 { 2712 if (GET_CODE (operands[1]) != REG) 2713 operands[1] = force_reg (SImode, operands[1]); 2714 } 2715 " 2716) 2717 2718;; The constraints here are to prevent a *partial* overlap (where %Q0 == %R1). 2719;; The second alternative is to allow the common case of a *full* overlap. 2720(define_insn "*arm_negdi2" 2721 [(set (match_operand:DI 0 "s_register_operand" "=&r,r") 2722 (neg:DI (match_operand:DI 1 "s_register_operand" "?r,0"))) 2723 (clobber (reg:CC CC_REGNUM))] 2724 "TARGET_ARM" 2725 "rsbs\\t%Q0, %Q1, #0\;rsc\\t%R0, %R1, #0" 2726 [(set_attr "conds" "clob") 2727 (set_attr "length" "8")] 2728) 2729 2730(define_insn "*thumb_negdi2" 2731 [(set (match_operand:DI 0 "register_operand" "=&l") 2732 (neg:DI (match_operand:DI 1 "register_operand" "l"))) 2733 (clobber (reg:CC CC_REGNUM))] 2734 "TARGET_THUMB" 2735 "mov\\t%R0, #0\;neg\\t%Q0, %Q1\;sbc\\t%R0, %R1" 2736 [(set_attr "length" "6")] 2737) 2738 2739(define_expand "negsi2" 2740 [(set (match_operand:SI 0 "s_register_operand" "") 2741 (neg:SI (match_operand:SI 1 "s_register_operand" "")))] 2742 "TARGET_EITHER" 2743 "" 2744) 2745 2746(define_insn "*arm_negsi2" 2747 [(set (match_operand:SI 0 "s_register_operand" "=r") 2748 (neg:SI (match_operand:SI 1 "s_register_operand" "r")))] 2749 "TARGET_ARM" 2750 "rsb%?\\t%0, %1, #0" 2751 [(set_attr "predicable" "yes")] 2752) 2753 2754(define_insn "*thumb_negsi2" 2755 [(set (match_operand:SI 0 "register_operand" "=l") 2756 (neg:SI (match_operand:SI 1 "register_operand" "l")))] 2757 "TARGET_THUMB" 2758 "neg\\t%0, %1" 2759 [(set_attr "length" "2")] 2760) 2761 2762(define_insn "negsf2" 2763 [(set (match_operand:SF 0 "s_register_operand" "=f") 2764 (neg:SF (match_operand:SF 1 "s_register_operand" "f")))] 2765 "TARGET_ARM && TARGET_HARD_FLOAT" 2766 "mnf%?s\\t%0, %1" 2767 [(set_attr "type" "ffarith") 2768 (set_attr "predicable" "yes")] 2769) 2770 2771(define_insn "negdf2" 2772 [(set (match_operand:DF 0 "s_register_operand" "=f") 2773 (neg:DF (match_operand:DF 1 "s_register_operand" "f")))] 2774 "TARGET_ARM && TARGET_HARD_FLOAT" 2775 "mnf%?d\\t%0, %1" 2776 [(set_attr "type" "ffarith") 2777 (set_attr "predicable" "yes")] 2778) 2779 2780(define_insn "*negdf_esfdf" 2781 [(set (match_operand:DF 0 "s_register_operand" "=f") 2782 (neg:DF (float_extend:DF 2783 (match_operand:SF 1 "s_register_operand" "f"))))] 2784 "TARGET_ARM && TARGET_HARD_FLOAT" 2785 "mnf%?d\\t%0, %1" 2786 [(set_attr "type" "ffarith") 2787 (set_attr "predicable" "yes")] 2788) 2789 2790(define_insn "negxf2" 2791 [(set (match_operand:XF 0 "s_register_operand" "=f") 2792 (neg:XF (match_operand:XF 1 "s_register_operand" "f")))] 2793 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 2794 "mnf%?e\\t%0, %1" 2795 [(set_attr "type" "ffarith") 2796 (set_attr "predicable" "yes")] 2797) 2798 2799;; abssi2 doesn't really clobber the condition codes if a different register 2800;; is being set. To keep things simple, assume during rtl manipulations that 2801;; it does, but tell the final scan operator the truth. Similarly for 2802;; (neg (abs...)) 2803 2804(define_insn "abssi2" 2805 [(set (match_operand:SI 0 "s_register_operand" "=r,&r") 2806 (abs:SI (match_operand:SI 1 "s_register_operand" "0,r"))) 2807 (clobber (reg:CC CC_REGNUM))] 2808 "TARGET_ARM" 2809 "@ 2810 cmp\\t%0, #0\;rsblt\\t%0, %0, #0 2811 eor%?\\t%0, %1, %1, asr #31\;sub%?\\t%0, %0, %1, asr #31" 2812 [(set_attr "conds" "clob,*") 2813 (set_attr "shift" "1") 2814 ;; predicable can't be set based on the variant, so left as no 2815 (set_attr "length" "8")] 2816) 2817 2818(define_insn "*neg_abssi2" 2819 [(set (match_operand:SI 0 "s_register_operand" "=r,&r") 2820 (neg:SI (abs:SI (match_operand:SI 1 "s_register_operand" "0,r")))) 2821 (clobber (reg:CC CC_REGNUM))] 2822 "TARGET_ARM" 2823 "@ 2824 cmp\\t%0, #0\;rsbgt\\t%0, %0, #0 2825 eor%?\\t%0, %1, %1, asr #31\;rsb%?\\t%0, %0, %1, asr #31" 2826 [(set_attr "conds" "clob,*") 2827 (set_attr "shift" "1") 2828 ;; predicable can't be set based on the variant, so left as no 2829 (set_attr "length" "8")] 2830) 2831 2832(define_insn "abssf2" 2833 [(set (match_operand:SF 0 "s_register_operand" "=f") 2834 (abs:SF (match_operand:SF 1 "s_register_operand" "f")))] 2835 "TARGET_ARM && TARGET_HARD_FLOAT" 2836 "abs%?s\\t%0, %1" 2837 [(set_attr "type" "ffarith") 2838 (set_attr "predicable" "yes")] 2839) 2840 2841(define_insn "absdf2" 2842 [(set (match_operand:DF 0 "s_register_operand" "=f") 2843 (abs:DF (match_operand:DF 1 "s_register_operand" "f")))] 2844 "TARGET_ARM && TARGET_HARD_FLOAT" 2845 "abs%?d\\t%0, %1" 2846 [(set_attr "type" "ffarith") 2847 (set_attr "predicable" "yes")] 2848) 2849 2850(define_insn "*absdf_esfdf" 2851 [(set (match_operand:DF 0 "s_register_operand" "=f") 2852 (abs:DF (float_extend:DF 2853 (match_operand:SF 1 "s_register_operand" "f"))))] 2854 "TARGET_ARM && TARGET_HARD_FLOAT" 2855 "abs%?d\\t%0, %1" 2856 [(set_attr "type" "ffarith") 2857 (set_attr "predicable" "yes")] 2858) 2859 2860(define_insn "absxf2" 2861 [(set (match_operand:XF 0 "s_register_operand" "=f") 2862 (abs:XF (match_operand:XF 1 "s_register_operand" "f")))] 2863 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 2864 "abs%?e\\t%0, %1" 2865 [(set_attr "type" "ffarith") 2866 (set_attr "predicable" "yes")] 2867) 2868 2869(define_insn "sqrtsf2" 2870 [(set (match_operand:SF 0 "s_register_operand" "=f") 2871 (sqrt:SF (match_operand:SF 1 "s_register_operand" "f")))] 2872 "TARGET_ARM && TARGET_HARD_FLOAT" 2873 "sqt%?s\\t%0, %1" 2874 [(set_attr "type" "float_em") 2875 (set_attr "predicable" "yes")] 2876) 2877 2878(define_insn "sqrtdf2" 2879 [(set (match_operand:DF 0 "s_register_operand" "=f") 2880 (sqrt:DF (match_operand:DF 1 "s_register_operand" "f")))] 2881 "TARGET_ARM && TARGET_HARD_FLOAT" 2882 "sqt%?d\\t%0, %1" 2883 [(set_attr "type" "float_em") 2884 (set_attr "predicable" "yes")] 2885) 2886 2887(define_insn "*sqrtdf_esfdf" 2888 [(set (match_operand:DF 0 "s_register_operand" "=f") 2889 (sqrt:DF (float_extend:DF 2890 (match_operand:SF 1 "s_register_operand" "f"))))] 2891 "TARGET_ARM && TARGET_HARD_FLOAT" 2892 "sqt%?d\\t%0, %1" 2893 [(set_attr "type" "float_em") 2894 (set_attr "predicable" "yes")] 2895) 2896 2897(define_insn "sqrtxf2" 2898 [(set (match_operand:XF 0 "s_register_operand" "=f") 2899 (sqrt:XF (match_operand:XF 1 "s_register_operand" "f")))] 2900 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 2901 "sqt%?e\\t%0, %1" 2902 [(set_attr "type" "float_em") 2903 (set_attr "predicable" "yes")] 2904) 2905 2906;; SIN COS TAN and family are always emulated, so it's probably better 2907;; to always call a library function. 2908;(define_insn "sinsf2" 2909; [(set (match_operand:SF 0 "s_register_operand" "=f") 2910; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 2911; UNSPEC_SIN))] 2912; "TARGET_ARM && TARGET_HARD_FLOAT" 2913; "sin%?s\\t%0, %1" 2914;[(set_attr "type" "float_em")]) 2915; 2916;(define_insn "sindf2" 2917; [(set (match_operand:DF 0 "s_register_operand" "=f") 2918; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 2919; UNSPEC_SIN))] 2920; "TARGET_ARM && TARGET_HARD_FLOAT" 2921; "sin%?d\\t%0, %1" 2922;[(set_attr "type" "float_em")]) 2923; 2924;(define_insn "*sindf_esfdf" 2925; [(set (match_operand:DF 0 "s_register_operand" "=f") 2926; (unspec:DF [(float_extend:DF 2927; (match_operand:SF 1 "s_register_operand" "f"))] 2928; UNSPEC_SIN))] 2929; "TARGET_ARM && TARGET_HARD_FLOAT" 2930; "sin%?d\\t%0, %1" 2931;[(set_attr "type" "float_em")]) 2932; 2933;(define_insn "sinxf2" 2934; [(set (match_operand:XF 0 "s_register_operand" "=f") 2935; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 2936; UNSPEC_SIN))] 2937; "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 2938; "sin%?e\\t%0, %1" 2939;[(set_attr "type" "float_em")]) 2940; 2941;(define_insn "cossf2" 2942; [(set (match_operand:SF 0 "s_register_operand" "=f") 2943; (unspec:SF [(match_operand:SF 1 "s_register_operand" "f")] 2944; UNSPEC_COS))] 2945; "TARGET_ARM && TARGET_HARD_FLOAT" 2946; "cos%?s\\t%0, %1" 2947;[(set_attr "type" "float_em")]) 2948; 2949;(define_insn "cosdf2" 2950; [(set (match_operand:DF 0 "s_register_operand" "=f") 2951; (unspec:DF [(match_operand:DF 1 "s_register_operand" "f")] 2952; UNSPEC_COS))] 2953; "TARGET_ARM && TARGET_HARD_FLOAT" 2954; "cos%?d\\t%0, %1" 2955;[(set_attr "type" "float_em")]) 2956; 2957;(define_insn "*cosdf_esfdf" 2958; [(set (match_operand:DF 0 "s_register_operand" "=f") 2959; (unspec:DF [(float_extend:DF 2960; (match_operand:SF 1 "s_register_operand" "f"))] 2961; UNSPEC_COS))] 2962; "TARGET_ARM && TARGET_HARD_FLOAT" 2963; "cos%?d\\t%0, %1" 2964;[(set_attr "type" "float_em")]) 2965; 2966;(define_insn "cosxf2" 2967; [(set (match_operand:XF 0 "s_register_operand" "=f") 2968; (unspec:XF [(match_operand:XF 1 "s_register_operand" "f")] 2969; UNSEPC_COS))] 2970; "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 2971; "cos%?e\\t%0, %1" 2972;[(set_attr "type" "float_em")]) 2973 2974(define_insn_and_split "one_cmpldi2" 2975 [(set (match_operand:DI 0 "s_register_operand" "=&r,&r") 2976 (not:DI (match_operand:DI 1 "s_register_operand" "?r,0")))] 2977 "TARGET_ARM" 2978 "#" 2979 "TARGET_ARM && reload_completed" 2980 [(set (match_dup 0) (not:SI (match_dup 1))) 2981 (set (match_dup 2) (not:SI (match_dup 3)))] 2982 " 2983 { 2984 operands[2] = gen_highpart (SImode, operands[0]); 2985 operands[0] = gen_lowpart (SImode, operands[0]); 2986 operands[3] = gen_highpart (SImode, operands[1]); 2987 operands[1] = gen_lowpart (SImode, operands[1]); 2988 }" 2989 [(set_attr "length" "8") 2990 (set_attr "predicable" "yes")] 2991) 2992 2993(define_expand "one_cmplsi2" 2994 [(set (match_operand:SI 0 "s_register_operand" "") 2995 (not:SI (match_operand:SI 1 "s_register_operand" "")))] 2996 "TARGET_EITHER" 2997 "" 2998) 2999 3000(define_insn "*arm_one_cmplsi2" 3001 [(set (match_operand:SI 0 "s_register_operand" "=r") 3002 (not:SI (match_operand:SI 1 "s_register_operand" "r")))] 3003 "TARGET_ARM" 3004 "mvn%?\\t%0, %1" 3005 [(set_attr "predicable" "yes")] 3006) 3007 3008(define_insn "*thumb_one_cmplsi2" 3009 [(set (match_operand:SI 0 "register_operand" "=l") 3010 (not:SI (match_operand:SI 1 "register_operand" "l")))] 3011 "TARGET_THUMB" 3012 "mvn\\t%0, %1" 3013 [(set_attr "length" "2")] 3014) 3015 3016(define_insn "*notsi_compare0" 3017 [(set (reg:CC_NOOV CC_REGNUM) 3018 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) 3019 (const_int 0))) 3020 (set (match_operand:SI 0 "s_register_operand" "=r") 3021 (not:SI (match_dup 1)))] 3022 "TARGET_ARM" 3023 "mvn%?s\\t%0, %1" 3024 [(set_attr "conds" "set")] 3025) 3026 3027(define_insn "*notsi_compare0_scratch" 3028 [(set (reg:CC_NOOV CC_REGNUM) 3029 (compare:CC_NOOV (not:SI (match_operand:SI 1 "s_register_operand" "r")) 3030 (const_int 0))) 3031 (clobber (match_scratch:SI 0 "=r"))] 3032 "TARGET_ARM" 3033 "mvn%?s\\t%0, %1" 3034 [(set_attr "conds" "set")] 3035) 3036 3037;; Fixed <--> Floating conversion insns 3038 3039(define_insn "floatsisf2" 3040 [(set (match_operand:SF 0 "s_register_operand" "=f") 3041 (float:SF (match_operand:SI 1 "s_register_operand" "r")))] 3042 "TARGET_ARM && TARGET_HARD_FLOAT" 3043 "flt%?s\\t%0, %1" 3044 [(set_attr "type" "r_2_f") 3045 (set_attr "predicable" "yes")] 3046) 3047 3048(define_insn "floatsidf2" 3049 [(set (match_operand:DF 0 "s_register_operand" "=f") 3050 (float:DF (match_operand:SI 1 "s_register_operand" "r")))] 3051 "TARGET_ARM && TARGET_HARD_FLOAT" 3052 "flt%?d\\t%0, %1" 3053 [(set_attr "type" "r_2_f") 3054 (set_attr "predicable" "yes")] 3055) 3056 3057(define_insn "floatsixf2" 3058 [(set (match_operand:XF 0 "s_register_operand" "=f") 3059 (float:XF (match_operand:SI 1 "s_register_operand" "r")))] 3060 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 3061 "flt%?e\\t%0, %1" 3062 [(set_attr "type" "r_2_f") 3063 (set_attr "predicable" "yes")] 3064) 3065 3066(define_insn "fix_truncsfsi2" 3067 [(set (match_operand:SI 0 "s_register_operand" "=r") 3068 (fix:SI (match_operand:SF 1 "s_register_operand" "f")))] 3069 "TARGET_ARM && TARGET_HARD_FLOAT" 3070 "fix%?z\\t%0, %1" 3071 [(set_attr "type" "f_2_r") 3072 (set_attr "predicable" "yes")] 3073) 3074 3075(define_insn "fix_truncdfsi2" 3076 [(set (match_operand:SI 0 "s_register_operand" "=r") 3077 (fix:SI (match_operand:DF 1 "s_register_operand" "f")))] 3078 "TARGET_ARM && TARGET_HARD_FLOAT" 3079 "fix%?z\\t%0, %1" 3080 [(set_attr "type" "f_2_r") 3081 (set_attr "predicable" "yes")] 3082) 3083 3084(define_insn "fix_truncxfsi2" 3085 [(set (match_operand:SI 0 "s_register_operand" "=r") 3086 (fix:SI (match_operand:XF 1 "s_register_operand" "f")))] 3087 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 3088 "fix%?z\\t%0, %1" 3089 [(set_attr "type" "f_2_r") 3090 (set_attr "predicable" "yes")] 3091) 3092 3093;; Truncation insns 3094 3095(define_insn "truncdfsf2" 3096 [(set (match_operand:SF 0 "s_register_operand" "=f") 3097 (float_truncate:SF 3098 (match_operand:DF 1 "s_register_operand" "f")))] 3099 "TARGET_ARM && TARGET_HARD_FLOAT" 3100 "mvf%?s\\t%0, %1" 3101 [(set_attr "type" "ffarith") 3102 (set_attr "predicable" "yes")] 3103) 3104 3105(define_insn "truncxfsf2" 3106 [(set (match_operand:SF 0 "s_register_operand" "=f") 3107 (float_truncate:SF 3108 (match_operand:XF 1 "s_register_operand" "f")))] 3109 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 3110 "mvf%?s\\t%0, %1" 3111 [(set_attr "type" "ffarith") 3112 (set_attr "predicable" "yes")] 3113) 3114 3115(define_insn "truncxfdf2" 3116 [(set (match_operand:DF 0 "s_register_operand" "=f") 3117 (float_truncate:DF 3118 (match_operand:XF 1 "s_register_operand" "f")))] 3119 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 3120 "mvf%?d\\t%0, %1" 3121 [(set_attr "type" "ffarith") 3122 (set_attr "predicable" "yes")] 3123) 3124 3125;; Zero and sign extension instructions. 3126 3127(define_insn "zero_extendsidi2" 3128 [(set (match_operand:DI 0 "s_register_operand" "=r") 3129 (zero_extend:DI (match_operand:SI 1 "s_register_operand" "r")))] 3130 "TARGET_ARM" 3131 "* 3132 if (REGNO (operands[1]) 3133 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0)) 3134 output_asm_insn (\"mov%?\\t%Q0, %1\", operands); 3135 return \"mov%?\\t%R0, #0\"; 3136 " 3137 [(set_attr "length" "8") 3138 (set_attr "predicable" "yes")] 3139) 3140 3141(define_insn "zero_extendqidi2" 3142 [(set (match_operand:DI 0 "s_register_operand" "=r,r") 3143 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "r,m")))] 3144 "TARGET_ARM" 3145 "@ 3146 and%?\\t%Q0, %1, #255\;mov%?\\t%R0, #0 3147 ldr%?b\\t%Q0, %1\;mov%?\\t%R0, #0" 3148 [(set_attr "length" "8") 3149 (set_attr "predicable" "yes") 3150 (set_attr "type" "*,load") 3151 (set_attr "pool_range" "*,4092") 3152 (set_attr "neg_pool_range" "*,4084")] 3153) 3154 3155(define_insn "extendsidi2" 3156 [(set (match_operand:DI 0 "s_register_operand" "=r") 3157 (sign_extend:DI (match_operand:SI 1 "s_register_operand" "r")))] 3158 "TARGET_ARM" 3159 "* 3160 if (REGNO (operands[1]) 3161 != REGNO (operands[0]) + (WORDS_BIG_ENDIAN ? 1 : 0)) 3162 output_asm_insn (\"mov%?\\t%Q0, %1\", operands); 3163 return \"mov%?\\t%R0, %Q0, asr #31\"; 3164 " 3165 [(set_attr "length" "8") 3166 (set_attr "shift" "1") 3167 (set_attr "predicable" "yes")] 3168) 3169 3170(define_expand "zero_extendhisi2" 3171 [(set (match_dup 2) 3172 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "") 3173 (const_int 16))) 3174 (set (match_operand:SI 0 "s_register_operand" "") 3175 (lshiftrt:SI (match_dup 2) (const_int 16)))] 3176 "TARGET_EITHER" 3177 " 3178 { 3179 if (TARGET_ARM) 3180 { 3181 if (arm_arch4 && GET_CODE (operands[1]) == MEM) 3182 { 3183 /* Note: We do not have to worry about TARGET_MMU_TRAPS 3184 here because the insn below will generate an LDRH instruction 3185 rather than an LDR instruction, so we cannot get an unaligned 3186 word access. */ 3187 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 3188 gen_rtx_ZERO_EXTEND (SImode, 3189 operands[1]))); 3190 DONE; 3191 } 3192 if (TARGET_MMU_TRAPS && GET_CODE (operands[1]) == MEM) 3193 { 3194 emit_insn (gen_movhi_bytes (operands[0], operands[1])); 3195 DONE; 3196 } 3197 if (!s_register_operand (operands[1], HImode)) 3198 operands[1] = copy_to_mode_reg (HImode, operands[1]); 3199 operands[1] = gen_lowpart (SImode, operands[1]); 3200 operands[2] = gen_reg_rtx (SImode); 3201 } 3202 else /* TARGET_THUMB */ 3203 { 3204 if (GET_CODE (operands[1]) == MEM) 3205 { 3206 rtx tmp; 3207 3208 tmp = gen_rtx_ZERO_EXTEND (SImode, operands[1]); 3209 tmp = gen_rtx_SET (VOIDmode, operands[0], tmp); 3210 emit_insn (tmp); 3211 } 3212 else 3213 { 3214 rtx ops[3]; 3215 3216 if (!s_register_operand (operands[1], HImode)) 3217 operands[1] = copy_to_mode_reg (HImode, operands[1]); 3218 operands[1] = gen_lowpart (SImode, operands[1]); 3219 operands[2] = gen_reg_rtx (SImode); 3220 3221 ops[0] = operands[2]; 3222 ops[1] = operands[1]; 3223 ops[2] = GEN_INT (16); 3224 3225 emit_insn (gen_rtx_SET (VOIDmode, ops[0], 3226 gen_rtx_ASHIFT (SImode, ops[1], ops[2]))); 3227 3228 ops[0] = operands[0]; 3229 ops[1] = operands[2]; 3230 ops[2] = GEN_INT (16); 3231 3232 emit_insn (gen_rtx_SET (VOIDmode, ops[0], 3233 gen_rtx_LSHIFTRT (SImode, ops[1], 3234 ops[2]))); 3235 } 3236 DONE; 3237 } 3238 }" 3239) 3240 3241(define_insn "*thumb_zero_extendhisi2" 3242 [(set (match_operand:SI 0 "register_operand" "=l") 3243 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] 3244 "TARGET_THUMB" 3245 "* 3246 rtx mem = XEXP (operands[1], 0); 3247 3248 if (GET_CODE (mem) == CONST) 3249 mem = XEXP (mem, 0); 3250 3251 if (GET_CODE (mem) == LABEL_REF) 3252 return \"ldr\\t%0, %1\"; 3253 3254 if (GET_CODE (mem) == PLUS) 3255 { 3256 rtx a = XEXP (mem, 0); 3257 rtx b = XEXP (mem, 1); 3258 3259 /* This can happen due to bugs in reload. */ 3260 if (GET_CODE (a) == REG && REGNO (a) == SP_REGNUM) 3261 { 3262 rtx ops[2]; 3263 ops[0] = operands[0]; 3264 ops[1] = a; 3265 3266 output_asm_insn (\"mov %0, %1\", ops); 3267 3268 XEXP (mem, 0) = operands[0]; 3269 } 3270 3271 else if ( GET_CODE (a) == LABEL_REF 3272 && GET_CODE (b) == CONST_INT) 3273 return \"ldr\\t%0, %1\"; 3274 } 3275 3276 return \"ldrh\\t%0, %1\"; 3277 " 3278 [(set_attr "length" "4") 3279 (set_attr "type" "load") 3280 (set_attr "pool_range" "60")] 3281) 3282 3283(define_insn "*arm_zero_extendhisi2" 3284 [(set (match_operand:SI 0 "s_register_operand" "=r") 3285 (zero_extend:SI (match_operand:HI 1 "memory_operand" "m")))] 3286 "TARGET_ARM && arm_arch4" 3287 "ldr%?h\\t%0, %1" 3288 [(set_attr "type" "load") 3289 (set_attr "predicable" "yes") 3290 (set_attr "pool_range" "256") 3291 (set_attr "neg_pool_range" "244")] 3292) 3293 3294(define_split 3295 [(set (match_operand:SI 0 "s_register_operand" "") 3296 (zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))) 3297 (clobber (match_operand:SI 2 "s_register_operand" ""))] 3298 "TARGET_ARM && (!arm_arch4)" 3299 [(set (match_dup 2) (match_dup 1)) 3300 (set (match_dup 0) (lshiftrt:SI (match_dup 2) (const_int 16)))] 3301 " 3302 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL) 3303 FAIL; 3304 " 3305) 3306 3307(define_split 3308 [(set (match_operand:SI 0 "s_register_operand" "") 3309 (match_operator:SI 3 "shiftable_operator" 3310 [(zero_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")) 3311 (match_operand:SI 4 "s_register_operand" "")])) 3312 (clobber (match_operand:SI 2 "s_register_operand" ""))] 3313 "TARGET_ARM && (!arm_arch4)" 3314 [(set (match_dup 2) (match_dup 1)) 3315 (set (match_dup 0) 3316 (match_op_dup 3 3317 [(lshiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))] 3318 " 3319 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL) 3320 FAIL; 3321 " 3322) 3323 3324(define_expand "zero_extendqisi2" 3325 [(set (match_operand:SI 0 "s_register_operand" "") 3326 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))] 3327 "TARGET_EITHER" 3328 " 3329 if (GET_CODE (operands[1]) != MEM) 3330 { 3331 if (TARGET_ARM) 3332 { 3333 emit_insn (gen_andsi3 (operands[0], 3334 gen_lowpart (SImode, operands[1]), 3335 GEN_INT (255))); 3336 } 3337 else /* TARGET_THUMB */ 3338 { 3339 rtx temp = gen_reg_rtx (SImode); 3340 rtx ops[3]; 3341 3342 operands[1] = copy_to_mode_reg (QImode, operands[1]); 3343 operands[1] = gen_lowpart (SImode, operands[1]); 3344 3345 ops[0] = temp; 3346 ops[1] = operands[1]; 3347 ops[2] = GEN_INT (24); 3348 3349 emit_insn (gen_rtx_SET (VOIDmode, ops[0], 3350 gen_rtx_ASHIFT (SImode, ops[1], ops[2]))); 3351 3352 ops[0] = operands[0]; 3353 ops[1] = temp; 3354 ops[2] = GEN_INT (24); 3355 3356 emit_insn (gen_rtx_SET (VOIDmode, ops[0], 3357 gen_rtx_LSHIFTRT (SImode, ops[1], ops[2]))); 3358 } 3359 DONE; 3360 } 3361 " 3362) 3363 3364(define_insn "*thumb_zero_extendqisi2" 3365 [(set (match_operand:SI 0 "register_operand" "=l") 3366 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] 3367 "TARGET_THUMB" 3368 "ldrb\\t%0, %1" 3369 [(set_attr "length" "2") 3370 (set_attr "type" "load") 3371 (set_attr "pool_range" "32")] 3372) 3373 3374(define_insn "*arm_zero_extendqisi2" 3375 [(set (match_operand:SI 0 "s_register_operand" "=r") 3376 (zero_extend:SI (match_operand:QI 1 "memory_operand" "m")))] 3377 "TARGET_ARM" 3378 "ldr%?b\\t%0, %1\\t%@ zero_extendqisi2" 3379 [(set_attr "type" "load") 3380 (set_attr "predicable" "yes") 3381 (set_attr "pool_range" "4096") 3382 (set_attr "neg_pool_range" "4084")] 3383) 3384 3385(define_split 3386 [(set (match_operand:SI 0 "s_register_operand" "") 3387 (zero_extend:SI (subreg:QI (match_operand:SI 1 "" "") 0))) 3388 (clobber (match_operand:SI 2 "s_register_operand" ""))] 3389 "TARGET_ARM && (GET_CODE (operands[1]) != MEM)" 3390 [(set (match_dup 2) (match_dup 1)) 3391 (set (match_dup 0) (and:SI (match_dup 2) (const_int 255)))] 3392 "" 3393) 3394 3395(define_insn "*compareqi_eq0" 3396 [(set (reg:CC_Z CC_REGNUM) 3397 (compare:CC_Z (match_operand:QI 0 "s_register_operand" "r") 3398 (const_int 0)))] 3399 "TARGET_ARM" 3400 "tst\\t%0, #255" 3401 [(set_attr "conds" "set")] 3402) 3403 3404(define_expand "extendhisi2" 3405 [(set (match_dup 2) 3406 (ashift:SI (match_operand:HI 1 "nonimmediate_operand" "") 3407 (const_int 16))) 3408 (set (match_operand:SI 0 "s_register_operand" "") 3409 (ashiftrt:SI (match_dup 2) 3410 (const_int 16)))] 3411 "TARGET_EITHER" 3412 " 3413 { 3414 if (TARGET_ARM && arm_arch4 && GET_CODE (operands[1]) == MEM) 3415 { 3416 /* Note: We do not have to worry about TARGET_MMU_TRAPS 3417 here because the insn below will generate an LDRH instruction 3418 rather than an LDR instruction, so we cannot get an unaligned 3419 word access. */ 3420 emit_insn (gen_rtx_SET (VOIDmode, operands[0], 3421 gen_rtx_SIGN_EXTEND (SImode, operands[1]))); 3422 DONE; 3423 } 3424 3425 if (TARGET_ARM && TARGET_MMU_TRAPS && GET_CODE (operands[1]) == MEM) 3426 { 3427 emit_insn (gen_extendhisi2_mem (operands[0], operands[1])); 3428 DONE; 3429 } 3430 if (!s_register_operand (operands[1], HImode)) 3431 operands[1] = copy_to_mode_reg (HImode, operands[1]); 3432 operands[1] = gen_lowpart (SImode, operands[1]); 3433 operands[2] = gen_reg_rtx (SImode); 3434 3435 if (TARGET_THUMB) 3436 { 3437 rtx ops[3]; 3438 3439 ops[0] = operands[2]; 3440 ops[1] = operands[1]; 3441 ops[2] = GEN_INT (16); 3442 3443 emit_insn (gen_rtx_SET (VOIDmode, ops[0], 3444 gen_rtx_ASHIFT (SImode, ops[1], ops[2]))); 3445 3446 ops[0] = operands[0]; 3447 ops[1] = operands[2]; 3448 ops[2] = GEN_INT (16); 3449 3450 emit_insn (gen_rtx_SET (VOIDmode, ops[0], 3451 gen_rtx_ASHIFTRT (SImode, ops[1], ops[2]))); 3452 3453 DONE; 3454 } 3455 }" 3456) 3457 3458(define_insn "*thumb_extendhisi2_insn" 3459 [(set (match_operand:SI 0 "register_operand" "=l") 3460 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))) 3461 (clobber (match_scratch:SI 2 "=&l"))] 3462 "TARGET_THUMB" 3463 "* 3464 { 3465 rtx ops[4]; 3466 rtx mem = XEXP (operands[1], 0); 3467 3468 /* This code used to try to use 'V', and fix the address only if it was 3469 offsettable, but this fails for e.g. REG+48 because 48 is outside the 3470 range of QImode offsets, and offsettable_address_p does a QImode 3471 address check. */ 3472 3473 if (GET_CODE (mem) == CONST) 3474 mem = XEXP (mem, 0); 3475 3476 if (GET_CODE (mem) == LABEL_REF) 3477 return \"ldr\\t%0, %1\"; 3478 3479 if (GET_CODE (mem) == PLUS) 3480 { 3481 rtx a = XEXP (mem, 0); 3482 rtx b = XEXP (mem, 1); 3483 3484 if (GET_CODE (a) == LABEL_REF 3485 && GET_CODE (b) == CONST_INT) 3486 return \"ldr\\t%0, %1\"; 3487 3488 if (GET_CODE (b) == REG) 3489 return \"ldrsh\\t%0, %1\"; 3490 3491 ops[1] = a; 3492 ops[2] = b; 3493 } 3494 else 3495 { 3496 ops[1] = mem; 3497 ops[2] = const0_rtx; 3498 } 3499 3500 if (GET_CODE (ops[1]) != REG) 3501 { 3502 debug_rtx (ops[1]); 3503 abort (); 3504 } 3505 3506 ops[0] = operands[0]; 3507 ops[3] = operands[2]; 3508 output_asm_insn (\"mov\\t%3, %2\;ldrsh\\t%0, [%1, %3]\", ops); 3509 return \"\"; 3510 }" 3511 [(set_attr "length" "4") 3512 (set_attr "type" "load") 3513 (set_attr "pool_range" "1020")] 3514) 3515 3516(define_expand "extendhisi2_mem" 3517 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" ""))) 3518 (set (match_dup 3) 3519 (zero_extend:SI (match_dup 7))) 3520 (set (match_dup 6) (ashift:SI (match_dup 4) (const_int 24))) 3521 (set (match_operand:SI 0 "" "") 3522 (ior:SI (ashiftrt:SI (match_dup 6) (const_int 16)) (match_dup 5)))] 3523 "TARGET_ARM" 3524 " 3525 { 3526 rtx mem1, mem2; 3527 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 3528 3529 mem1 = gen_rtx_MEM (QImode, addr); 3530 MEM_COPY_ATTRIBUTES (mem1, operands[1]); 3531 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1)); 3532 MEM_COPY_ATTRIBUTES (mem2, operands[1]); 3533 operands[0] = gen_lowpart (SImode, operands[0]); 3534 operands[1] = mem1; 3535 operands[2] = gen_reg_rtx (SImode); 3536 operands[3] = gen_reg_rtx (SImode); 3537 operands[6] = gen_reg_rtx (SImode); 3538 operands[7] = mem2; 3539 3540 if (BYTES_BIG_ENDIAN) 3541 { 3542 operands[4] = operands[2]; 3543 operands[5] = operands[3]; 3544 } 3545 else 3546 { 3547 operands[4] = operands[3]; 3548 operands[5] = operands[2]; 3549 } 3550 }" 3551) 3552 3553(define_insn "*arm_extendhisi_insn" 3554 [(set (match_operand:SI 0 "s_register_operand" "=r") 3555 (sign_extend:SI (match_operand:HI 1 "memory_operand" "m")))] 3556 "TARGET_ARM && arm_arch4" 3557 "ldr%?sh\\t%0, %1" 3558 [(set_attr "type" "load") 3559 (set_attr "predicable" "yes") 3560 (set_attr "pool_range" "256") 3561 (set_attr "neg_pool_range" "244")] 3562) 3563 3564(define_split 3565 [(set (match_operand:SI 0 "s_register_operand" "") 3566 (sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" ""))) 3567 (clobber (match_operand:SI 2 "s_register_operand" ""))] 3568 "TARGET_ARM && (!arm_arch4)" 3569 [(set (match_dup 2) (match_dup 1)) 3570 (set (match_dup 0) (ashiftrt:SI (match_dup 2) (const_int 16)))] 3571 " 3572 if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL) 3573 FAIL; 3574 " 3575) 3576 3577(define_split 3578 [(set (match_operand:SI 0 "s_register_operand" "") 3579 (match_operator:SI 3 "shiftable_operator" 3580 [(sign_extend:SI (match_operand:HI 1 "alignable_memory_operand" "")) 3581 (match_operand:SI 4 "s_register_operand" "")])) 3582 (clobber (match_operand:SI 2 "s_register_operand" ""))] 3583 "TARGET_ARM && (!arm_arch4)" 3584 [(set (match_dup 2) (match_dup 1)) 3585 (set (match_dup 0) 3586 (match_op_dup 3 3587 [(ashiftrt:SI (match_dup 2) (const_int 16)) (match_dup 4)]))] 3588 "if ((operands[1] = arm_gen_rotated_half_load (operands[1])) == NULL) 3589 FAIL; 3590 " 3591) 3592 3593(define_expand "extendqihi2" 3594 [(set (match_dup 2) 3595 (ashift:SI (match_operand:QI 1 "general_operand" "") 3596 (const_int 24))) 3597 (set (match_operand:HI 0 "s_register_operand" "") 3598 (ashiftrt:SI (match_dup 2) 3599 (const_int 24)))] 3600 "TARGET_ARM" 3601 " 3602 { 3603 if (arm_arch4 && GET_CODE (operands[1]) == MEM) 3604 { 3605 emit_insn (gen_rtx_SET (VOIDmode, 3606 operands[0], 3607 gen_rtx_SIGN_EXTEND (HImode, operands[1]))); 3608 DONE; 3609 } 3610 if (!s_register_operand (operands[1], QImode)) 3611 operands[1] = copy_to_mode_reg (QImode, operands[1]); 3612 operands[0] = gen_lowpart (SImode, operands[0]); 3613 operands[1] = gen_lowpart (SImode, operands[1]); 3614 operands[2] = gen_reg_rtx (SImode); 3615 }" 3616) 3617 3618; Rather than restricting all byte accesses to memory addresses that ldrsb 3619; can handle, we fix up the ones that ldrsb can't grok with a split. 3620(define_insn "*extendqihi_insn" 3621 [(set (match_operand:HI 0 "s_register_operand" "=r") 3622 (sign_extend:HI (match_operand:QI 1 "memory_operand" "m")))] 3623 "TARGET_ARM && arm_arch4" 3624 "* 3625 /* If the address is invalid, this will split the instruction into two. */ 3626 if (bad_signed_byte_operand (operands[1], VOIDmode)) 3627 return \"#\"; 3628 return \"ldr%?sb\\t%0, %1\"; 3629 " 3630 [(set_attr "type" "load") 3631 (set_attr "predicable" "yes") 3632 (set_attr "length" "8") 3633 (set_attr "pool_range" "256") 3634 (set_attr "neg_pool_range" "244")] 3635) 3636 3637(define_split 3638 [(set (match_operand:HI 0 "s_register_operand" "") 3639 (sign_extend:HI (match_operand:QI 1 "bad_signed_byte_operand" "")))] 3640 "TARGET_ARM && arm_arch4 && reload_completed" 3641 [(set (match_dup 3) (match_dup 1)) 3642 (set (match_dup 0) (sign_extend:HI (match_dup 2)))] 3643 " 3644 { 3645 HOST_WIDE_INT offset; 3646 3647 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0])); 3648 operands[2] = gen_rtx_MEM (QImode, operands[3]); 3649 MEM_COPY_ATTRIBUTES (operands[2], operands[1]); 3650 operands[1] = XEXP (operands[1], 0); 3651 if (GET_CODE (operands[1]) == PLUS 3652 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT 3653 && !(const_ok_for_arm (offset = INTVAL (XEXP (operands[1], 1))) 3654 || const_ok_for_arm (-offset))) 3655 { 3656 HOST_WIDE_INT low = (offset > 0 3657 ? (offset & 0xff) : -((-offset) & 0xff)); 3658 XEXP (operands[2], 0) = plus_constant (operands[3], low); 3659 operands[1] = plus_constant (XEXP (operands[1], 0), offset - low); 3660 } 3661 /* Ensure the sum is in correct canonical form */ 3662 else if (GET_CODE (operands[1]) == PLUS 3663 && GET_CODE (XEXP (operands[1], 1)) != CONST_INT 3664 && !s_register_operand (XEXP (operands[1], 1), VOIDmode)) 3665 operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), 3666 XEXP (operands[1], 1), 3667 XEXP (operands[1], 0)); 3668 }" 3669) 3670 3671(define_expand "extendqisi2" 3672 [(set (match_dup 2) 3673 (ashift:SI (match_operand:QI 1 "general_operand" "") 3674 (const_int 24))) 3675 (set (match_operand:SI 0 "s_register_operand" "") 3676 (ashiftrt:SI (match_dup 2) 3677 (const_int 24)))] 3678 "TARGET_EITHER" 3679 " 3680 { 3681 if (TARGET_ARM && arm_arch4 && GET_CODE (operands[1]) == MEM) 3682 { 3683 emit_insn (gen_rtx_SET (VOIDmode, 3684 operands[0], 3685 gen_rtx_SIGN_EXTEND (SImode, operands[1]))); 3686 DONE; 3687 } 3688 if (!s_register_operand (operands[1], QImode)) 3689 operands[1] = copy_to_mode_reg (QImode, operands[1]); 3690 operands[1] = gen_lowpart (SImode, operands[1]); 3691 operands[2] = gen_reg_rtx (SImode); 3692 3693 if (TARGET_THUMB) 3694 { 3695 rtx ops[3]; 3696 3697 ops[0] = operands[2]; 3698 ops[1] = operands[1]; 3699 ops[2] = GEN_INT (24); 3700 3701 emit_insn (gen_rtx_SET (VOIDmode, ops[0], 3702 gen_rtx_ASHIFT (SImode, ops[1], ops[2]))); 3703 3704 ops[0] = operands[0]; 3705 ops[1] = operands[2]; 3706 ops[2] = GEN_INT (24); 3707 3708 emit_insn (gen_rtx_SET (VOIDmode, ops[0], 3709 gen_rtx_ASHIFTRT (SImode, ops[1], ops[2]))); 3710 3711 DONE; 3712 } 3713 }" 3714) 3715 3716; Rather than restricting all byte accesses to memory addresses that ldrsb 3717; can handle, we fix up the ones that ldrsb can't grok with a split. 3718(define_insn "*arm_extendqisi_insn" 3719 [(set (match_operand:SI 0 "s_register_operand" "=r") 3720 (sign_extend:SI (match_operand:QI 1 "memory_operand" "m")))] 3721 "TARGET_ARM && arm_arch4" 3722 "* 3723 /* If the address is invalid, this will split the instruction into two. */ 3724 if (bad_signed_byte_operand (operands[1], VOIDmode)) 3725 return \"#\"; 3726 return \"ldr%?sb\\t%0, %1\"; 3727 " 3728 [(set_attr "type" "load") 3729 (set_attr "predicable" "yes") 3730 (set_attr "length" "8") 3731 (set_attr "pool_range" "256") 3732 (set_attr "neg_pool_range" "244")] 3733) 3734 3735(define_split 3736 [(set (match_operand:SI 0 "s_register_operand" "") 3737 (sign_extend:SI (match_operand:QI 1 "bad_signed_byte_operand" "")))] 3738 "TARGET_ARM && arm_arch4 && reload_completed" 3739 [(set (match_dup 0) (match_dup 1)) 3740 (set (match_dup 0) (sign_extend:SI (match_dup 2)))] 3741 " 3742 { 3743 HOST_WIDE_INT offset; 3744 3745 operands[2] = gen_rtx_MEM (QImode, operands[0]); 3746 MEM_COPY_ATTRIBUTES (operands[2], operands[1]); 3747 operands[1] = XEXP (operands[1], 0); 3748 if (GET_CODE (operands[1]) == PLUS 3749 && GET_CODE (XEXP (operands[1], 1)) == CONST_INT 3750 && !(const_ok_for_arm (offset = INTVAL (XEXP (operands[1], 1))) 3751 || const_ok_for_arm (-offset))) 3752 { 3753 HOST_WIDE_INT low = (offset > 0 3754 ? (offset & 0xff) : -((-offset) & 0xff)); 3755 XEXP (operands[2], 0) = plus_constant (operands[0], low); 3756 operands[1] = plus_constant (XEXP (operands[1], 0), offset - low); 3757 } 3758 /* Ensure the sum is in correct canonical form */ 3759 else if (GET_CODE (operands[1]) == PLUS 3760 && GET_CODE (XEXP (operands[1], 1)) != CONST_INT 3761 && !s_register_operand (XEXP (operands[1], 1), VOIDmode)) 3762 operands[1] = gen_rtx_PLUS (GET_MODE (operands[1]), 3763 XEXP (operands[1], 1), 3764 XEXP (operands[1], 0)); 3765 }" 3766) 3767 3768(define_insn "*thumb_extendqisi2_insn" 3769 [(set (match_operand:SI 0 "register_operand" "=l,l") 3770 (sign_extend:SI (match_operand:QI 1 "memory_operand" "V,m")))] 3771 "TARGET_THUMB" 3772 "* 3773 { 3774 rtx ops[3]; 3775 rtx mem = XEXP (operands[1], 0); 3776 3777 if (GET_CODE (mem) == CONST) 3778 mem = XEXP (mem, 0); 3779 3780 if (GET_CODE (mem) == LABEL_REF) 3781 return \"ldr\\t%0, %1\"; 3782 3783 if (GET_CODE (mem) == PLUS 3784 && GET_CODE (XEXP (mem, 0)) == LABEL_REF) 3785 return \"ldr\\t%0, %1\"; 3786 3787 if (which_alternative == 0) 3788 return \"ldrsb\\t%0, %1\"; 3789 3790 ops[0] = operands[0]; 3791 3792 if (GET_CODE (mem) == PLUS) 3793 { 3794 rtx a = XEXP (mem, 0); 3795 rtx b = XEXP (mem, 1); 3796 3797 ops[1] = a; 3798 ops[2] = b; 3799 3800 if (GET_CODE (a) == REG) 3801 { 3802 if (GET_CODE (b) == REG) 3803 output_asm_insn (\"ldrsb\\t%0, [%1, %2]\", ops); 3804 else if (REGNO (a) == REGNO (ops[0])) 3805 { 3806 output_asm_insn (\"ldrb\\t%0, [%1, %2]\", ops); 3807 output_asm_insn (\"lsl\\t%0, %0, #24\", ops); 3808 output_asm_insn (\"asr\\t%0, %0, #24\", ops); 3809 } 3810 else 3811 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops); 3812 } 3813 else if (GET_CODE (b) != REG) 3814 abort (); 3815 else 3816 { 3817 if (REGNO (b) == REGNO (ops[0])) 3818 { 3819 output_asm_insn (\"ldrb\\t%0, [%2, %1]\", ops); 3820 output_asm_insn (\"lsl\\t%0, %0, #24\", ops); 3821 output_asm_insn (\"asr\\t%0, %0, #24\", ops); 3822 } 3823 else 3824 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops); 3825 } 3826 } 3827 else if (GET_CODE (mem) == REG && REGNO (ops[0]) == REGNO (mem)) 3828 { 3829 output_asm_insn (\"ldrb\\t%0, [%0, #0]\", ops); 3830 output_asm_insn (\"lsl\\t%0, %0, #24\", ops); 3831 output_asm_insn (\"asr\\t%0, %0, #24\", ops); 3832 } 3833 else 3834 { 3835 ops[1] = mem; 3836 ops[2] = const0_rtx; 3837 3838 output_asm_insn (\"mov\\t%0, %2\;ldrsb\\t%0, [%1, %0]\", ops); 3839 } 3840 return \"\"; 3841 }" 3842 [(set_attr "length" "2,6") 3843 (set_attr "type" "load,load") 3844 (set_attr "pool_range" "32,32")] 3845) 3846 3847(define_insn "extendsfdf2" 3848 [(set (match_operand:DF 0 "s_register_operand" "=f") 3849 (float_extend:DF (match_operand:SF 1 "s_register_operand" "f")))] 3850 "TARGET_ARM && TARGET_HARD_FLOAT" 3851 "mvf%?d\\t%0, %1" 3852 [(set_attr "type" "ffarith") 3853 (set_attr "predicable" "yes")] 3854) 3855 3856(define_insn "extendsfxf2" 3857 [(set (match_operand:XF 0 "s_register_operand" "=f") 3858 (float_extend:XF (match_operand:SF 1 "s_register_operand" "f")))] 3859 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 3860 "mvf%?e\\t%0, %1" 3861 [(set_attr "type" "ffarith") 3862 (set_attr "predicable" "yes")] 3863) 3864 3865(define_insn "extenddfxf2" 3866 [(set (match_operand:XF 0 "s_register_operand" "=f") 3867 (float_extend:XF (match_operand:DF 1 "s_register_operand" "f")))] 3868 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 3869 "mvf%?e\\t%0, %1" 3870 [(set_attr "type" "ffarith") 3871 (set_attr "predicable" "yes")] 3872) 3873 3874 3875;; Move insns (including loads and stores) 3876 3877;; XXX Just some ideas about movti. 3878;; I don't think these are a good idea on the arm, there just aren't enough 3879;; registers 3880;;(define_expand "loadti" 3881;; [(set (match_operand:TI 0 "s_register_operand" "") 3882;; (mem:TI (match_operand:SI 1 "address_operand" "")))] 3883;; "" "") 3884 3885;;(define_expand "storeti" 3886;; [(set (mem:TI (match_operand:TI 0 "address_operand" "")) 3887;; (match_operand:TI 1 "s_register_operand" ""))] 3888;; "" "") 3889 3890;;(define_expand "movti" 3891;; [(set (match_operand:TI 0 "general_operand" "") 3892;; (match_operand:TI 1 "general_operand" ""))] 3893;; "" 3894;; " 3895;;{ 3896;; rtx insn; 3897;; 3898;; if (GET_CODE (operands[0]) == MEM && GET_CODE (operands[1]) == MEM) 3899;; operands[1] = copy_to_reg (operands[1]); 3900;; if (GET_CODE (operands[0]) == MEM) 3901;; insn = gen_storeti (XEXP (operands[0], 0), operands[1]); 3902;; else if (GET_CODE (operands[1]) == MEM) 3903;; insn = gen_loadti (operands[0], XEXP (operands[1], 0)); 3904;; else 3905;; FAIL; 3906;; 3907;; emit_insn (insn); 3908;; DONE; 3909;;}") 3910 3911;; Recognise garbage generated above. 3912 3913;;(define_insn "" 3914;; [(set (match_operand:TI 0 "general_operand" "=r,r,r,<,>,m") 3915;; (match_operand:TI 1 "general_operand" "<,>,m,r,r,r"))] 3916;; "" 3917;; "* 3918;; { 3919;; register mem = (which_alternative < 3); 3920;; register const char *template; 3921;; 3922;; operands[mem] = XEXP (operands[mem], 0); 3923;; switch (which_alternative) 3924;; { 3925;; case 0: template = \"ldmdb\\t%1!, %M0\"; break; 3926;; case 1: template = \"ldmia\\t%1!, %M0\"; break; 3927;; case 2: template = \"ldmia\\t%1, %M0\"; break; 3928;; case 3: template = \"stmdb\\t%0!, %M1\"; break; 3929;; case 4: template = \"stmia\\t%0!, %M1\"; break; 3930;; case 5: template = \"stmia\\t%0, %M1\"; break; 3931;; } 3932;; output_asm_insn (template, operands); 3933;; return \"\"; 3934;; }") 3935 3936(define_expand "movdi" 3937 [(set (match_operand:DI 0 "general_operand" "") 3938 (match_operand:DI 1 "general_operand" ""))] 3939 "TARGET_EITHER" 3940 " 3941 if (TARGET_THUMB) 3942 { 3943 if (!no_new_pseudos) 3944 { 3945 if (GET_CODE (operands[0]) != REG) 3946 operands[1] = force_reg (DImode, operands[1]); 3947 } 3948 } 3949 " 3950) 3951 3952(define_insn "*arm_movdi" 3953 [(set (match_operand:DI 0 "nonimmediate_di_operand" "=r, r, o<>") 3954 (match_operand:DI 1 "di_operand" "rIK,mi,r"))] 3955 "TARGET_ARM" 3956 "* 3957 return (output_move_double (operands)); 3958 " 3959 [(set_attr "length" "8") 3960 (set_attr "type" "*,load,store2") 3961 (set_attr "pool_range" "*,1020,*") 3962 (set_attr "neg_pool_range" "*,1012,*")] 3963) 3964 3965;;; ??? This should have alternatives for constants. 3966;;; ??? This was originally identical to the movdf_insn pattern. 3967;;; ??? The 'i' constraint looks funny, but it should always be replaced by 3968;;; thumb_reorg with a memory reference. 3969(define_insn "*thumb_movdi_insn" 3970 [(set (match_operand:DI 0 "nonimmediate_operand" "=l,l,l,l,>,l, m,*r") 3971 (match_operand:DI 1 "general_operand" "l, I,J,>,l,mi,l,*r"))] 3972 "TARGET_THUMB 3973 && ( register_operand (operands[0], DImode) 3974 || register_operand (operands[1], DImode))" 3975 "* 3976 { 3977 switch (which_alternative) 3978 { 3979 default: 3980 case 0: 3981 if (REGNO (operands[1]) == REGNO (operands[0]) + 1) 3982 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\"; 3983 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\"; 3984 case 1: 3985 return \"mov\\t%Q0, %1\;mov\\t%R0, #0\"; 3986 case 2: 3987 operands[1] = GEN_INT (- INTVAL (operands[1])); 3988 return \"mov\\t%Q0, %1\;neg\\t%Q0, %Q0\;asr\\t%R0, %Q0, #31\"; 3989 case 3: 3990 return \"ldmia\\t%1, {%0, %H0}\"; 3991 case 4: 3992 return \"stmia\\t%0, {%1, %H1}\"; 3993 case 5: 3994 return thumb_load_double_from_address (operands); 3995 case 6: 3996 operands[2] = gen_rtx (MEM, SImode, 3997 plus_constant (XEXP (operands[0], 0), 4)); 3998 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands); 3999 return \"\"; 4000 case 7: 4001 if (REGNO (operands[1]) == REGNO (operands[0]) + 1) 4002 return \"mov\\t%0, %1\;mov\\t%H0, %H1\"; 4003 return \"mov\\t%H0, %H1\;mov\\t%0, %1\"; 4004 } 4005 }" 4006 [(set_attr "length" "4,4,6,2,2,6,4,4") 4007 (set_attr "type" "*,*,*,load,store2,load,store2,*") 4008 (set_attr "pool_range" "*,*,*,*,*,1020,*,*")] 4009) 4010 4011(define_expand "movsi" 4012 [(set (match_operand:SI 0 "general_operand" "") 4013 (match_operand:SI 1 "general_operand" ""))] 4014 "TARGET_EITHER" 4015 " 4016 if (TARGET_ARM) 4017 { 4018 /* Everything except mem = const or mem = mem can be done easily */ 4019 if (GET_CODE (operands[0]) == MEM) 4020 operands[1] = force_reg (SImode, operands[1]); 4021 if (GET_CODE (operands[1]) == CONST_INT 4022 && !(const_ok_for_arm (INTVAL (operands[1])) 4023 || const_ok_for_arm (~INTVAL (operands[1])))) 4024 { 4025 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0], 4026 NULL_RTX, 4027 (no_new_pseudos ? 0 4028 : preserve_subexpressions_p ())); 4029 DONE; 4030 } 4031 } 4032 else /* TARGET_THUMB.... */ 4033 { 4034 if (!no_new_pseudos) 4035 { 4036 if (GET_CODE (operands[0]) != REG) 4037 operands[1] = force_reg (SImode, operands[1]); 4038 } 4039 } 4040 4041 if (flag_pic 4042 && (CONSTANT_P (operands[1]) 4043 || symbol_mentioned_p (operands[1]) 4044 || label_mentioned_p (operands[1]))) 4045 operands[1] = legitimize_pic_address (operands[1], SImode, 4046 (no_new_pseudos ? operands[0] : 0)); 4047 " 4048) 4049 4050(define_insn "*arm_movsi_insn" 4051 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r, m") 4052 (match_operand:SI 1 "general_operand" "rI,K,mi,r"))] 4053 "TARGET_ARM 4054 && ( register_operand (operands[0], SImode) 4055 || register_operand (operands[1], SImode))" 4056 "@ 4057 mov%?\\t%0, %1 4058 mvn%?\\t%0, #%B1 4059 ldr%?\\t%0, %1 4060 str%?\\t%1, %0" 4061 [(set_attr "type" "*,*,load,store1") 4062 (set_attr "predicable" "yes") 4063 (set_attr "pool_range" "*,*,4096,*") 4064 (set_attr "neg_pool_range" "*,*,4084,*")] 4065) 4066 4067(define_split 4068 [(set (match_operand:SI 0 "s_register_operand" "") 4069 (match_operand:SI 1 "const_int_operand" ""))] 4070 "TARGET_ARM 4071 && (!(const_ok_for_arm (INTVAL (operands[1])) 4072 || const_ok_for_arm (~INTVAL (operands[1]))))" 4073 [(clobber (const_int 0))] 4074 " 4075 arm_split_constant (SET, SImode, INTVAL (operands[1]), operands[0], 4076 NULL_RTX, 0); 4077 DONE; 4078 " 4079) 4080 4081(define_insn "*thumb_movsi_insn" 4082 [(set (match_operand:SI 0 "nonimmediate_operand" "=l,l,l,l,l,>,l, m,*lh") 4083 (match_operand:SI 1 "general_operand" "l, I,J,K,>,l,mi,l,*lh"))] 4084 "TARGET_THUMB 4085 && ( register_operand (operands[0], SImode) 4086 || register_operand (operands[1], SImode))" 4087 "@ 4088 mov %0, %1 4089 mov %0, %1 4090 # 4091 # 4092 ldmia\\t%1, {%0} 4093 stmia\\t%0, {%1} 4094 ldr\\t%0, %1 4095 str\\t%1, %0 4096 mov\\t%0, %1" 4097 [(set_attr "length" "2,2,4,4,2,2,2,2,2") 4098 (set_attr "type" "*,*,*,*,load,store1,load,store1,*") 4099 (set_attr "pool_range" "*,*,*,*,*,*,1020,*,*")] 4100) 4101 4102(define_split 4103 [(set (match_operand:SI 0 "register_operand" "") 4104 (match_operand:SI 1 "const_int_operand" ""))] 4105 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'J')" 4106 [(set (match_dup 0) (match_dup 1)) 4107 (set (match_dup 0) (neg:SI (match_dup 0)))] 4108 "operands[1] = GEN_INT (- INTVAL (operands[1]));" 4109) 4110 4111(define_split 4112 [(set (match_operand:SI 0 "register_operand" "") 4113 (match_operand:SI 1 "const_int_operand" ""))] 4114 "TARGET_THUMB && CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'K')" 4115 [(set (match_dup 0) (match_dup 1)) 4116 (set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))] 4117 " 4118 { 4119 unsigned HOST_WIDE_INT val = INTVAL (operands[1]); 4120 unsigned HOST_WIDE_INT mask = 0xff; 4121 int i; 4122 4123 for (i = 0; i < 25; i++) 4124 if ((val & (mask << i)) == val) 4125 break; 4126 4127 if (i == 0) 4128 FAIL; 4129 4130 operands[1] = GEN_INT (val >> i); 4131 operands[2] = GEN_INT (i); 4132 }" 4133) 4134 4135(define_expand "movaddr" 4136 [(set (match_operand:SI 0 "s_register_operand" "") 4137 (match_operand:DI 1 "address_operand" ""))] 4138 "TARGET_ARM" 4139 "" 4140) 4141 4142(define_insn "*movaddr_insn" 4143 [(set (match_operand:SI 0 "s_register_operand" "=r") 4144 (match_operand:DI 1 "address_operand" "p"))] 4145 "TARGET_ARM 4146 && reload_completed 4147 && (GET_CODE (operands[1]) == LABEL_REF 4148 || (GET_CODE (operands[1]) == CONST 4149 && GET_CODE (XEXP (operands[1], 0)) == PLUS 4150 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == LABEL_REF 4151 && GET_CODE (XEXP (XEXP (operands[1], 0), 1)) == CONST_INT))" 4152 "adr%?\\t%0, %a1" 4153 [(set_attr "predicable" "yes")] 4154) 4155 4156;; When generating pic, we need to load the symbol offset into a register. 4157;; So that the optimizer does not confuse this with a normal symbol load 4158;; we use an unspec. The offset will be loaded from a constant pool entry, 4159;; since that is the only type of relocation we can use. 4160 4161;; The rather odd constraints on the following are to force reload to leave 4162;; the insn alone, and to force the minipool generation pass to then move 4163;; the GOT symbol to memory. 4164 4165(define_insn "pic_load_addr_arm" 4166 [(set (match_operand:SI 0 "s_register_operand" "=r") 4167 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))] 4168 "TARGET_ARM && flag_pic" 4169 "ldr%?\\t%0, %1" 4170 [(set_attr "type" "load") 4171 (set (attr "pool_range") (const_int 4096)) 4172 (set (attr "neg_pool_range") (const_int 4084))] 4173) 4174 4175(define_insn "pic_load_addr_thumb" 4176 [(set (match_operand:SI 0 "s_register_operand" "=l") 4177 (unspec:SI [(match_operand:SI 1 "" "mX")] UNSPEC_PIC_SYM))] 4178 "TARGET_THUMB && flag_pic" 4179 "ldr\\t%0, %1" 4180 [(set_attr "type" "load") 4181 (set (attr "pool_range") (const_int 1024))] 4182) 4183 4184;; This variant is used for AOF assembly, since it needs to mention the 4185;; pic register in the rtl. 4186(define_expand "pic_load_addr_based" 4187 [(set (match_operand:SI 0 "s_register_operand" "=r") 4188 (unspec:SI [(match_operand 1 "" "") (match_dup 2)] UNSPEC_PIC_SYM))] 4189 "TARGET_ARM && flag_pic" 4190 "operands[2] = pic_offset_table_rtx;" 4191) 4192 4193(define_insn "*pic_load_addr_based_insn" 4194 [(set (match_operand:SI 0 "s_register_operand" "=r") 4195 (unspec:SI [(match_operand 1 "" "") 4196 (match_operand 2 "s_register_operand" "r")] 4197 UNSPEC_PIC_SYM))] 4198 "TARGET_EITHER && flag_pic && operands[2] == pic_offset_table_rtx" 4199 "* 4200#ifdef AOF_ASSEMBLER 4201 operands[1] = aof_pic_entry (operands[1]); 4202#endif 4203 output_asm_insn (\"ldr%?\\t%0, %a1\", operands); 4204 return \"\"; 4205 " 4206 [(set_attr "type" "load") 4207 (set (attr "pool_range") 4208 (if_then_else (eq_attr "is_thumb" "yes") 4209 (const_int 1024) 4210 (const_int 4096))) 4211 (set (attr "neg_pool_range") 4212 (if_then_else (eq_attr "is_thumb" "yes") 4213 (const_int 0) 4214 (const_int 4084)))] 4215) 4216 4217(define_insn "pic_add_dot_plus_four" 4218 [(set (match_operand:SI 0 "register_operand" "+r") 4219 (plus:SI (match_dup 0) (const (plus:SI (pc) (const_int 4))))) 4220 (use (label_ref (match_operand 1 "" "")))] 4221 "TARGET_THUMB && flag_pic" 4222 "* 4223 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", 4224 CODE_LABEL_NUMBER (operands[1])); 4225 return \"add\\t%0, %|pc\"; 4226 " 4227 [(set_attr "length" "2")] 4228) 4229 4230(define_insn "pic_add_dot_plus_eight" 4231 [(set (match_operand:SI 0 "register_operand" "+r") 4232 (plus:SI (match_dup 0) (const (plus:SI (pc) (const_int 8))))) 4233 (use (label_ref (match_operand 1 "" "")))] 4234 "TARGET_ARM && flag_pic" 4235 "* 4236 ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\", 4237 CODE_LABEL_NUMBER (operands[1])); 4238 return \"add%?\\t%0, %|pc, %0\"; 4239 " 4240 [(set_attr "predicable" "yes")] 4241) 4242 4243(define_expand "builtin_setjmp_receiver" 4244 [(label_ref (match_operand 0 "" ""))] 4245 "flag_pic" 4246 " 4247{ 4248 arm_finalize_pic (0); 4249 DONE; 4250}") 4251 4252;; If copying one reg to another we can set the condition codes according to 4253;; its value. Such a move is common after a return from subroutine and the 4254;; result is being tested against zero. 4255 4256(define_insn "*movsi_compare0" 4257 [(set (reg:CC CC_REGNUM) 4258 (compare:CC (match_operand:SI 1 "s_register_operand" "0,r") 4259 (const_int 0))) 4260 (set (match_operand:SI 0 "s_register_operand" "=r,r") 4261 (match_dup 1))] 4262 "TARGET_ARM" 4263 "@ 4264 cmp%?\\t%0, #0 4265 sub%?s\\t%0, %1, #0" 4266 [(set_attr "conds" "set")] 4267) 4268 4269;; Subroutine to store a half word from a register into memory. 4270;; Operand 0 is the source register (HImode) 4271;; Operand 1 is the destination address in a register (SImode) 4272 4273;; In both this routine and the next, we must be careful not to spill 4274;; a memory address of reg+large_const into a separate PLUS insn, since this 4275;; can generate unrecognizable rtl. 4276 4277(define_expand "storehi" 4278 [;; store the low byte 4279 (set (match_operand 1 "" "") (match_dup 3)) 4280 ;; extract the high byte 4281 (set (match_dup 2) 4282 (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) 4283 ;; store the high byte 4284 (set (match_dup 4) (subreg:QI (match_dup 2) 0))] ;explicit subreg safe 4285 "TARGET_ARM" 4286 " 4287 { 4288 rtx op1 = operands[1]; 4289 rtx addr = XEXP (op1, 0); 4290 enum rtx_code code = GET_CODE (addr); 4291 4292 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT) 4293 || code == MINUS) 4294 op1 = replace_equiv_address (operands[1], force_reg (SImode, addr)); 4295 4296 operands[4] = adjust_address (op1, QImode, 1); 4297 operands[1] = adjust_address (operands[1], QImode, 0); 4298 operands[3] = gen_lowpart (QImode, operands[0]); 4299 operands[0] = gen_lowpart (SImode, operands[0]); 4300 operands[2] = gen_reg_rtx (SImode); 4301 }" 4302) 4303 4304(define_expand "storehi_bigend" 4305 [(set (match_dup 4) (match_dup 3)) 4306 (set (match_dup 2) 4307 (ashiftrt:SI (match_operand 0 "" "") (const_int 8))) 4308 (set (match_operand 1 "" "") (subreg:QI (match_dup 2) 0))] 4309 "TARGET_ARM" 4310 " 4311 { 4312 rtx op1 = operands[1]; 4313 rtx addr = XEXP (op1, 0); 4314 enum rtx_code code = GET_CODE (addr); 4315 4316 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT) 4317 || code == MINUS) 4318 op1 = replace_equiv_address (op1, force_reg (SImode, addr)); 4319 4320 operands[4] = adjust_address (op1, QImode, 1); 4321 operands[1] = adjust_address (operands[1], QImode, 0); 4322 operands[3] = gen_lowpart (QImode, operands[0]); 4323 operands[0] = gen_lowpart (SImode, operands[0]); 4324 operands[2] = gen_reg_rtx (SImode); 4325 }" 4326) 4327 4328;; Subroutine to store a half word integer constant into memory. 4329(define_expand "storeinthi" 4330 [(set (match_operand 0 "" "") 4331 (subreg:QI (match_operand 1 "" "") 0)) 4332 (set (match_dup 3) (subreg:QI (match_dup 2) 0))] 4333 "TARGET_ARM" 4334 " 4335 { 4336 HOST_WIDE_INT value = INTVAL (operands[1]); 4337 rtx addr = XEXP (operands[0], 0); 4338 rtx op0 = operands[0]; 4339 enum rtx_code code = GET_CODE (addr); 4340 4341 if ((code == PLUS && GET_CODE (XEXP (addr, 1)) != CONST_INT) 4342 || code == MINUS) 4343 op0 = replace_equiv_address (op0, force_reg (SImode, addr)); 4344 4345 operands[1] = gen_reg_rtx (SImode); 4346 if (BYTES_BIG_ENDIAN) 4347 { 4348 emit_insn (gen_movsi (operands[1], GEN_INT ((value >> 8) & 255))); 4349 if ((value & 255) == ((value >> 8) & 255)) 4350 operands[2] = operands[1]; 4351 else 4352 { 4353 operands[2] = gen_reg_rtx (SImode); 4354 emit_insn (gen_movsi (operands[2], GEN_INT (value & 255))); 4355 } 4356 } 4357 else 4358 { 4359 emit_insn (gen_movsi (operands[1], GEN_INT (value & 255))); 4360 if ((value & 255) == ((value >> 8) & 255)) 4361 operands[2] = operands[1]; 4362 else 4363 { 4364 operands[2] = gen_reg_rtx (SImode); 4365 emit_insn (gen_movsi (operands[2], GEN_INT ((value >> 8) & 255))); 4366 } 4367 } 4368 4369 operands[3] = adjust_address (op0, QImode, 1); 4370 operands[0] = adjust_address (operands[0], QImode, 0); 4371 }" 4372) 4373 4374(define_expand "storehi_single_op" 4375 [(set (match_operand:HI 0 "memory_operand" "") 4376 (match_operand:HI 1 "general_operand" ""))] 4377 "TARGET_ARM && arm_arch4" 4378 " 4379 if (!s_register_operand (operands[1], HImode)) 4380 operands[1] = copy_to_mode_reg (HImode, operands[1]); 4381 " 4382) 4383 4384(define_expand "movhi" 4385 [(set (match_operand:HI 0 "general_operand" "") 4386 (match_operand:HI 1 "general_operand" ""))] 4387 "TARGET_EITHER" 4388 " 4389 if (TARGET_ARM) 4390 { 4391 if (!no_new_pseudos) 4392 { 4393 if (GET_CODE (operands[0]) == MEM) 4394 { 4395 if (arm_arch4) 4396 { 4397 emit_insn (gen_storehi_single_op (operands[0], operands[1])); 4398 DONE; 4399 } 4400 if (GET_CODE (operands[1]) == CONST_INT) 4401 emit_insn (gen_storeinthi (operands[0], operands[1])); 4402 else 4403 { 4404 if (GET_CODE (operands[1]) == MEM) 4405 operands[1] = force_reg (HImode, operands[1]); 4406 if (BYTES_BIG_ENDIAN) 4407 emit_insn (gen_storehi_bigend (operands[1], operands[0])); 4408 else 4409 emit_insn (gen_storehi (operands[1], operands[0])); 4410 } 4411 DONE; 4412 } 4413 /* Sign extend a constant, and keep it in an SImode reg. */ 4414 else if (GET_CODE (operands[1]) == CONST_INT) 4415 { 4416 rtx reg = gen_reg_rtx (SImode); 4417 HOST_WIDE_INT val = INTVAL (operands[1]) & 0xffff; 4418 4419 /* If the constant is already valid, leave it alone. */ 4420 if (!const_ok_for_arm (val)) 4421 { 4422 /* If setting all the top bits will make the constant 4423 loadable in a single instruction, then set them. 4424 Otherwise, sign extend the number. */ 4425 4426 if (const_ok_for_arm (~(val | ~0xffff))) 4427 val |= ~0xffff; 4428 else if (val & 0x8000) 4429 val |= ~0xffff; 4430 } 4431 4432 emit_insn (gen_movsi (reg, GEN_INT (val))); 4433 operands[1] = gen_rtx_SUBREG (HImode, reg, 0); 4434 } 4435 else if (!arm_arch4) 4436 { 4437 /* Note: We do not have to worry about TARGET_MMU_TRAPS 4438 for v4 and up architectures because LDRH instructions will 4439 be used to access the HI values, and these cannot generate 4440 unaligned word access faults in the MMU. */ 4441 if (GET_CODE (operands[1]) == MEM) 4442 { 4443 if (TARGET_MMU_TRAPS) 4444 { 4445 rtx base; 4446 rtx offset = const0_rtx; 4447 rtx reg = gen_reg_rtx (SImode); 4448 4449 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG 4450 || (GET_CODE (base) == PLUS 4451 && (GET_CODE (offset = XEXP (base, 1)) 4452 == CONST_INT) 4453 && ((INTVAL(offset) & 1) != 1) 4454 && GET_CODE (base = XEXP (base, 0)) == REG)) 4455 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32) 4456 { 4457 HOST_WIDE_INT new_offset = INTVAL (offset) & ~3; 4458 rtx new; 4459 4460 new = gen_rtx_MEM (SImode, 4461 plus_constant (base, new_offset)); 4462 MEM_COPY_ATTRIBUTES (new, operands[1]); 4463 emit_insn (gen_movsi (reg, new)); 4464 if (((INTVAL (offset) & 2) != 0) 4465 ^ (BYTES_BIG_ENDIAN ? 1 : 0)) 4466 { 4467 rtx reg2 = gen_reg_rtx (SImode); 4468 4469 emit_insn (gen_lshrsi3 (reg2, reg, 4470 GEN_INT (16))); 4471 reg = reg2; 4472 } 4473 } 4474 else 4475 emit_insn (gen_movhi_bytes (reg, operands[1])); 4476 4477 operands[1] = gen_lowpart (HImode, reg); 4478 } 4479 else if (BYTES_BIG_ENDIAN) 4480 { 4481 rtx base; 4482 rtx offset = const0_rtx; 4483 4484 if ((GET_CODE (base = XEXP (operands[1], 0)) == REG 4485 || (GET_CODE (base) == PLUS 4486 && (GET_CODE (offset = XEXP (base, 1)) 4487 == CONST_INT) 4488 && GET_CODE (base = XEXP (base, 0)) == REG)) 4489 && REGNO_POINTER_ALIGN (REGNO (base)) >= 32) 4490 { 4491 rtx reg = gen_reg_rtx (SImode); 4492 rtx new; 4493 4494 if ((INTVAL (offset) & 2) == 2) 4495 { 4496 HOST_WIDE_INT new_offset = INTVAL (offset) ^ 2; 4497 new = gen_rtx_MEM (SImode, 4498 plus_constant (base, 4499 new_offset)); 4500 MEM_COPY_ATTRIBUTES (new, operands[1]); 4501 emit_insn (gen_movsi (reg, new)); 4502 } 4503 else 4504 { 4505 new = gen_rtx_MEM (SImode, 4506 XEXP (operands[1], 0)); 4507 MEM_COPY_ATTRIBUTES (new, operands[1]); 4508 emit_insn (gen_rotated_loadsi (reg, new)); 4509 } 4510 4511 operands[1] = gen_lowpart (HImode, reg); 4512 } 4513 else 4514 { 4515 emit_insn (gen_movhi_bigend (operands[0], 4516 operands[1])); 4517 DONE; 4518 } 4519 } 4520 } 4521 } 4522 } 4523 /* Handle loading a large integer during reload */ 4524 else if (GET_CODE (operands[1]) == CONST_INT 4525 && !const_ok_for_arm (INTVAL (operands[1])) 4526 && !const_ok_for_arm (~INTVAL (operands[1]))) 4527 { 4528 /* Writing a constant to memory needs a scratch, which should 4529 be handled with SECONDARY_RELOADs. */ 4530 if (GET_CODE (operands[0]) != REG) 4531 abort (); 4532 4533 operands[0] = gen_rtx_SUBREG (SImode, operands[0], 0); 4534 emit_insn (gen_movsi (operands[0], operands[1])); 4535 DONE; 4536 } 4537 } 4538 else /* TARGET_THUMB */ 4539 { 4540 if (!no_new_pseudos) 4541 { 4542 if (GET_CODE (operands[0]) != REG) 4543 operands[1] = force_reg (HImode, operands[1]); 4544 4545 /* ??? We shouldn't really get invalid addresses here, but this can 4546 happen if we are passed a SP (never OK for HImode/QImode) or 4547 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for 4548 HImode/QImode) relative address. */ 4549 /* ??? This should perhaps be fixed elsewhere, for instance, in 4550 fixup_stack_1, by checking for other kinds of invalid addresses, 4551 e.g. a bare reference to a virtual register. This may confuse the 4552 alpha though, which must handle this case differently. */ 4553 if (GET_CODE (operands[0]) == MEM 4554 && !memory_address_p (GET_MODE (operands[0]), 4555 XEXP (operands[0], 0))) 4556 operands[0] 4557 = replace_equiv_address (operands[0], 4558 copy_to_reg (XEXP (operands[0], 0))); 4559 4560 if (GET_CODE (operands[1]) == MEM 4561 && !memory_address_p (GET_MODE (operands[1]), 4562 XEXP (operands[1], 0))) 4563 operands[1] 4564 = replace_equiv_address (operands[1], 4565 copy_to_reg (XEXP (operands[1], 0))); 4566 } 4567 /* Handle loading a large integer during reload */ 4568 else if (GET_CODE (operands[1]) == CONST_INT 4569 && !CONST_OK_FOR_THUMB_LETTER (INTVAL (operands[1]), 'I')) 4570 { 4571 /* Writing a constant to memory needs a scratch, which should 4572 be handled with SECONDARY_RELOADs. */ 4573 if (GET_CODE (operands[0]) != REG) 4574 abort (); 4575 4576 operands[0] = gen_rtx (SUBREG, SImode, operands[0], 0); 4577 emit_insn (gen_movsi (operands[0], operands[1])); 4578 DONE; 4579 } 4580 } 4581 " 4582) 4583 4584(define_insn "*thumb_movhi_insn" 4585 [(set (match_operand:HI 0 "nonimmediate_operand" "=l,l, m,*r,*h,l") 4586 (match_operand:HI 1 "general_operand" "l,mn,l,*h,*r,I"))] 4587 "TARGET_THUMB 4588 && ( register_operand (operands[0], HImode) 4589 || register_operand (operands[1], HImode))" 4590 "* 4591 switch (which_alternative) 4592 { 4593 case 0: return \"add %0, %1, #0\"; 4594 case 2: return \"strh %1, %0\"; 4595 case 3: return \"mov %0, %1\"; 4596 case 4: return \"mov %0, %1\"; 4597 case 5: return \"mov %0, %1\"; 4598 default: abort (); 4599 case 1: 4600 /* The stack pointer can end up being taken as an index register. 4601 Catch this case here and deal with it. */ 4602 if (GET_CODE (XEXP (operands[1], 0)) == PLUS 4603 && GET_CODE (XEXP (XEXP (operands[1], 0), 0)) == REG 4604 && REGNO (XEXP (XEXP (operands[1], 0), 0)) == SP_REGNUM) 4605 { 4606 rtx ops[2]; 4607 ops[0] = operands[0]; 4608 ops[1] = XEXP (XEXP (operands[1], 0), 0); 4609 4610 output_asm_insn (\"mov %0, %1\", ops); 4611 4612 XEXP (XEXP (operands[1], 0), 0) = operands[0]; 4613 4614 } 4615 return \"ldrh %0, %1\"; 4616 }" 4617 [(set_attr "length" "2,4,2,2,2,2") 4618 (set_attr "type" "*,load,store1,*,*,*") 4619 (set_attr "pool_range" "*,64,*,*,*,*")] 4620) 4621 4622 4623(define_insn "rotated_loadsi" 4624 [(set (match_operand:SI 0 "s_register_operand" "=r") 4625 (rotate:SI (match_operand:SI 1 "offsettable_memory_operand" "o") 4626 (const_int 16)))] 4627 "TARGET_ARM && (!TARGET_MMU_TRAPS)" 4628 "* 4629 { 4630 rtx ops[2]; 4631 4632 ops[0] = operands[0]; 4633 ops[1] = gen_rtx_MEM (SImode, plus_constant (XEXP (operands[1], 0), 2)); 4634 output_asm_insn (\"ldr%?\\t%0, %1\\t%@ load-rotate\", ops); 4635 return \"\"; 4636 }" 4637 [(set_attr "type" "load") 4638 (set_attr "predicable" "yes")] 4639) 4640 4641(define_expand "movhi_bytes" 4642 [(set (match_dup 2) (zero_extend:SI (match_operand:HI 1 "" ""))) 4643 (set (match_dup 3) 4644 (zero_extend:SI (match_dup 6))) 4645 (set (match_operand:SI 0 "" "") 4646 (ior:SI (ashift:SI (match_dup 4) (const_int 8)) (match_dup 5)))] 4647 "TARGET_ARM" 4648 " 4649 { 4650 rtx mem1, mem2; 4651 rtx addr = copy_to_mode_reg (SImode, XEXP (operands[1], 0)); 4652 4653 mem1 = gen_rtx_MEM (QImode, addr); 4654 MEM_COPY_ATTRIBUTES (mem1, operands[1]); 4655 mem2 = gen_rtx_MEM (QImode, plus_constant (addr, 1)); 4656 MEM_COPY_ATTRIBUTES (mem2, operands[1]); 4657 operands[0] = gen_lowpart (SImode, operands[0]); 4658 operands[1] = mem1; 4659 operands[2] = gen_reg_rtx (SImode); 4660 operands[3] = gen_reg_rtx (SImode); 4661 operands[6] = mem2; 4662 4663 if (BYTES_BIG_ENDIAN) 4664 { 4665 operands[4] = operands[2]; 4666 operands[5] = operands[3]; 4667 } 4668 else 4669 { 4670 operands[4] = operands[3]; 4671 operands[5] = operands[2]; 4672 } 4673 }" 4674) 4675 4676(define_expand "movhi_bigend" 4677 [(set (match_dup 2) 4678 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "") 0) 4679 (const_int 16))) 4680 (set (match_dup 3) 4681 (ashiftrt:SI (match_dup 2) (const_int 16))) 4682 (set (match_operand:HI 0 "s_register_operand" "") 4683 (subreg:HI (match_dup 3) 0))] 4684 "TARGET_ARM" 4685 " 4686 operands[2] = gen_reg_rtx (SImode); 4687 operands[3] = gen_reg_rtx (SImode); 4688 " 4689) 4690 4691;; Pattern to recognise insn generated default case above 4692(define_insn "*movhi_insn_arch4" 4693 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r") 4694 (match_operand:HI 1 "general_operand" "rI,K,r,m"))] 4695 "TARGET_ARM 4696 && arm_arch4 4697 && (GET_CODE (operands[1]) != CONST_INT 4698 || const_ok_for_arm (INTVAL (operands[1])) 4699 || const_ok_for_arm (~INTVAL (operands[1])))" 4700 "@ 4701 mov%?\\t%0, %1\\t%@ movhi 4702 mvn%?\\t%0, #%B1\\t%@ movhi 4703 str%?h\\t%1, %0\\t%@ movhi 4704 ldr%?h\\t%0, %1\\t%@ movhi" 4705 [(set_attr "type" "*,*,store1,load") 4706 (set_attr "predicable" "yes") 4707 (set_attr "pool_range" "*,*,*,256") 4708 (set_attr "neg_pool_range" "*,*,*,244")] 4709) 4710 4711(define_insn "*movhi_insn_littleend" 4712 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r") 4713 (match_operand:HI 1 "general_operand" "rI,K,m"))] 4714 "TARGET_ARM 4715 && !arm_arch4 4716 && !BYTES_BIG_ENDIAN 4717 && !TARGET_MMU_TRAPS 4718 && (GET_CODE (operands[1]) != CONST_INT 4719 || const_ok_for_arm (INTVAL (operands[1])) 4720 || const_ok_for_arm (~INTVAL (operands[1])))" 4721 "@ 4722 mov%?\\t%0, %1\\t%@ movhi 4723 mvn%?\\t%0, #%B1\\t%@ movhi 4724 ldr%?\\t%0, %1\\t%@ movhi" 4725 [(set_attr "type" "*,*,load") 4726 (set_attr "predicable" "yes") 4727 (set_attr "pool_range" "4096") 4728 (set_attr "neg_pool_range" "4084")] 4729) 4730 4731(define_insn "*movhi_insn_bigend" 4732 [(set (match_operand:HI 0 "s_register_operand" "=r,r,r") 4733 (match_operand:HI 1 "general_operand" "rI,K,m"))] 4734 "TARGET_ARM 4735 && !arm_arch4 4736 && BYTES_BIG_ENDIAN 4737 && !TARGET_MMU_TRAPS 4738 && (GET_CODE (operands[1]) != CONST_INT 4739 || const_ok_for_arm (INTVAL (operands[1])) 4740 || const_ok_for_arm (~INTVAL (operands[1])))" 4741 "@ 4742 mov%?\\t%0, %1\\t%@ movhi 4743 mvn%?\\t%0, #%B1\\t%@ movhi 4744 ldr%?\\t%0, %1\\t%@ movhi_bigend\;mov%?\\t%0, %0, asr #16" 4745 [(set_attr "type" "*,*,load") 4746 (set_attr "predicable" "yes") 4747 (set_attr "length" "4,4,8") 4748 (set_attr "pool_range" "*,*,4092") 4749 (set_attr "neg_pool_range" "*,*,4084")] 4750) 4751 4752(define_insn "*loadhi_si_bigend" 4753 [(set (match_operand:SI 0 "s_register_operand" "=r") 4754 (rotate:SI (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0) 4755 (const_int 16)))] 4756 "TARGET_ARM 4757 && BYTES_BIG_ENDIAN 4758 && !TARGET_MMU_TRAPS" 4759 "ldr%?\\t%0, %1\\t%@ movhi_bigend" 4760 [(set_attr "type" "load") 4761 (set_attr "predicable" "yes") 4762 (set_attr "pool_range" "4096") 4763 (set_attr "neg_pool_range" "4084")] 4764) 4765 4766(define_insn "*movhi_bytes" 4767 [(set (match_operand:HI 0 "s_register_operand" "=r,r") 4768 (match_operand:HI 1 "arm_rhs_operand" "rI,K"))] 4769 "TARGET_ARM && TARGET_MMU_TRAPS" 4770 "@ 4771 mov%?\\t%0, %1\\t%@ movhi 4772 mvn%?\\t%0, #%B1\\t%@ movhi" 4773 [(set_attr "predicable" "yes")] 4774) 4775 4776(define_insn "thumb_movhi_clobber" 4777 [(set (match_operand:HI 0 "memory_operand" "=m") 4778 (match_operand:HI 1 "register_operand" "l")) 4779 (clobber (match_operand:SI 2 "register_operand" "=&l"))] 4780 "TARGET_THUMB" 4781 "* 4782 abort ();" 4783) 4784 4785;; We use a DImode scratch because we may occasionally need an additional 4786;; temporary if the address isn't offsettable -- push_reload doesn't seem 4787;; to take any notice of the "o" constraints on reload_memory_operand operand. 4788(define_expand "reload_outhi" 4789 [(parallel [(match_operand:HI 0 "arm_reload_memory_operand" "=o") 4790 (match_operand:HI 1 "s_register_operand" "r") 4791 (match_operand:DI 2 "s_register_operand" "=&l")])] 4792 "TARGET_EITHER" 4793 "if (TARGET_ARM) 4794 arm_reload_out_hi (operands); 4795 else 4796 thumb_reload_out_hi (operands); 4797 DONE; 4798 " 4799) 4800 4801(define_expand "reload_inhi" 4802 [(parallel [(match_operand:HI 0 "s_register_operand" "=r") 4803 (match_operand:HI 1 "arm_reload_memory_operand" "o") 4804 (match_operand:DI 2 "s_register_operand" "=&r")])] 4805 "TARGET_THUMB || (TARGET_ARM && TARGET_MMU_TRAPS)" 4806 " 4807 if (TARGET_ARM) 4808 arm_reload_in_hi (operands); 4809 else 4810 thumb_reload_out_hi (operands); 4811 DONE; 4812") 4813 4814(define_expand "movqi" 4815 [(set (match_operand:QI 0 "general_operand" "") 4816 (match_operand:QI 1 "general_operand" ""))] 4817 "TARGET_EITHER" 4818 " 4819 if (TARGET_ARM) 4820 { 4821 /* Everything except mem = const or mem = mem can be done easily */ 4822 4823 if (!no_new_pseudos) 4824 { 4825 if (GET_CODE (operands[1]) == CONST_INT) 4826 { 4827 rtx reg = gen_reg_rtx (SImode); 4828 4829 emit_insn (gen_movsi (reg, operands[1])); 4830 operands[1] = gen_rtx_SUBREG (QImode, reg, 0); 4831 } 4832 if (GET_CODE (operands[0]) == MEM) 4833 operands[1] = force_reg (QImode, operands[1]); 4834 } 4835 } 4836 else /* TARGET_THUMB */ 4837 { 4838 if (!no_new_pseudos) 4839 { 4840 if (GET_CODE (operands[0]) != REG) 4841 operands[1] = force_reg (QImode, operands[1]); 4842 4843 /* ??? We shouldn't really get invalid addresses here, but this can 4844 happen if we are passed a SP (never OK for HImode/QImode) or 4845 virtual register (rejected by GO_IF_LEGITIMATE_ADDRESS for 4846 HImode/QImode) relative address. */ 4847 /* ??? This should perhaps be fixed elsewhere, for instance, in 4848 fixup_stack_1, by checking for other kinds of invalid addresses, 4849 e.g. a bare reference to a virtual register. This may confuse the 4850 alpha though, which must handle this case differently. */ 4851 if (GET_CODE (operands[0]) == MEM 4852 && !memory_address_p (GET_MODE (operands[0]), 4853 XEXP (operands[0], 0))) 4854 operands[0] 4855 = replace_equiv_address (operands[0], 4856 copy_to_reg (XEXP (operands[0], 0))); 4857 if (GET_CODE (operands[1]) == MEM 4858 && !memory_address_p (GET_MODE (operands[1]), 4859 XEXP (operands[1], 0))) 4860 operands[1] 4861 = replace_equiv_address (operands[1], 4862 copy_to_reg (XEXP (operands[1], 0))); 4863 } 4864 /* Handle loading a large integer during reload */ 4865 else if (GET_CODE (operands[1]) == CONST_INT 4866 && !CONST_OK_FOR_LETTER_P (INTVAL (operands[1]), 'I')) 4867 { 4868 /* Writing a constant to memory needs a scratch, which should 4869 be handled with SECONDARY_RELOADs. */ 4870 if (GET_CODE (operands[0]) != REG) 4871 abort (); 4872 4873 operands[0] = gen_rtx (SUBREG, SImode, operands[0], 0); 4874 emit_insn (gen_movsi (operands[0], operands[1])); 4875 DONE; 4876 } 4877 } 4878 " 4879) 4880 4881 4882(define_insn "*arm_movqi_insn" 4883 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,r,m") 4884 (match_operand:QI 1 "general_operand" "rI,K,m,r"))] 4885 "TARGET_ARM 4886 && ( register_operand (operands[0], QImode) 4887 || register_operand (operands[1], QImode))" 4888 "@ 4889 mov%?\\t%0, %1 4890 mvn%?\\t%0, #%B1 4891 ldr%?b\\t%0, %1 4892 str%?b\\t%1, %0" 4893 [(set_attr "type" "*,*,load,store1") 4894 (set_attr "predicable" "yes")] 4895) 4896 4897(define_insn "*thumb_movqi_insn" 4898 [(set (match_operand:QI 0 "nonimmediate_operand" "=l,l,m,*r,*h,l") 4899 (match_operand:QI 1 "general_operand" "l, m,l,*h,*r,I"))] 4900 "TARGET_THUMB 4901 && ( register_operand (operands[0], QImode) 4902 || register_operand (operands[1], QImode))" 4903 "@ 4904 add\\t%0, %1, #0 4905 ldrb\\t%0, %1 4906 strb\\t%1, %0 4907 mov\\t%0, %1 4908 mov\\t%0, %1 4909 mov\\t%0, %1" 4910 [(set_attr "length" "2") 4911 (set_attr "type" "*,load,store1,*,*,*") 4912 (set_attr "pool_range" "*,32,*,*,*,*")] 4913) 4914 4915(define_expand "movsf" 4916 [(set (match_operand:SF 0 "general_operand" "") 4917 (match_operand:SF 1 "general_operand" ""))] 4918 "TARGET_EITHER" 4919 " 4920 if (TARGET_ARM) 4921 { 4922 if (GET_CODE (operands[0]) == MEM) 4923 operands[1] = force_reg (SFmode, operands[1]); 4924 } 4925 else /* TARGET_THUMB */ 4926 { 4927 if (!no_new_pseudos) 4928 { 4929 if (GET_CODE (operands[0]) != REG) 4930 operands[1] = force_reg (SFmode, operands[1]); 4931 } 4932 } 4933 " 4934) 4935 4936(define_split 4937 [(set (match_operand:SF 0 "nonimmediate_operand" "") 4938 (match_operand:SF 1 "immediate_operand" ""))] 4939 "TARGET_ARM 4940 && !TARGET_HARD_FLOAT 4941 && reload_completed 4942 && GET_CODE (operands[1]) == CONST_DOUBLE" 4943 [(set (match_dup 2) (match_dup 3))] 4944 " 4945 operands[2] = gen_lowpart (SImode, operands[0]); 4946 operands[3] = gen_lowpart (SImode, operands[1]); 4947 if (operands[2] == 0 || operands[3] == 0) 4948 FAIL; 4949 " 4950) 4951 4952(define_insn "*arm_movsf_hard_insn" 4953 [(set (match_operand:SF 0 "nonimmediate_operand" "=f,f,f, m,f,r,r,r, m") 4954 (match_operand:SF 1 "general_operand" "fG,H,mE,f,r,f,r,mE,r"))] 4955 "TARGET_ARM 4956 && TARGET_HARD_FLOAT 4957 && (GET_CODE (operands[0]) != MEM 4958 || register_operand (operands[1], SFmode))" 4959 "@ 4960 mvf%?s\\t%0, %1 4961 mnf%?s\\t%0, #%N1 4962 ldf%?s\\t%0, %1 4963 stf%?s\\t%1, %0 4964 str%?\\t%1, [%|sp, #-4]!\;ldf%?s\\t%0, [%|sp], #4 4965 stf%?s\\t%1, [%|sp, #-4]!\;ldr%?\\t%0, [%|sp], #4 4966 mov%?\\t%0, %1 4967 ldr%?\\t%0, %1\\t%@ float 4968 str%?\\t%1, %0\\t%@ float" 4969 [(set_attr "length" "4,4,4,4,8,8,4,4,4") 4970 (set_attr "predicable" "yes") 4971 (set_attr "type" 4972 "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*,load,store1") 4973 (set_attr "pool_range" "*,*,1024,*,*,*,*,4096,*") 4974 (set_attr "neg_pool_range" "*,*,1012,*,*,*,*,4084,*")] 4975) 4976 4977;; Exactly the same as above, except that all `f' cases are deleted. 4978;; This is necessary to prevent reload from ever trying to use a `f' reg 4979;; when -msoft-float. 4980 4981(define_insn "*arm_movsf_soft_insn" 4982 [(set (match_operand:SF 0 "nonimmediate_operand" "=r,r,m") 4983 (match_operand:SF 1 "general_operand" "r,mE,r"))] 4984 "TARGET_ARM 4985 && TARGET_SOFT_FLOAT 4986 && (GET_CODE (operands[0]) != MEM 4987 || register_operand (operands[1], SFmode))" 4988 "@ 4989 mov%?\\t%0, %1 4990 ldr%?\\t%0, %1\\t%@ float 4991 str%?\\t%1, %0\\t%@ float" 4992 [(set_attr "length" "4,4,4") 4993 (set_attr "predicable" "yes") 4994 (set_attr "type" "*,load,store1") 4995 (set_attr "pool_range" "*,4096,*") 4996 (set_attr "neg_pool_range" "*,4084,*")] 4997) 4998 4999;;; ??? This should have alternatives for constants. 5000(define_insn "*thumb_movsf_insn" 5001 [(set (match_operand:SF 0 "nonimmediate_operand" "=l,l,>,l, m,*r,*h") 5002 (match_operand:SF 1 "general_operand" "l, >,l,mF,l,*h,*r"))] 5003 "TARGET_THUMB 5004 && ( register_operand (operands[0], SFmode) 5005 || register_operand (operands[1], SFmode))" 5006 "@ 5007 add\\t%0, %1, #0 5008 ldmia\\t%1, {%0} 5009 stmia\\t%0, {%1} 5010 ldr\\t%0, %1 5011 str\\t%1, %0 5012 mov\\t%0, %1 5013 mov\\t%0, %1" 5014 [(set_attr "length" "2") 5015 (set_attr "type" "*,load,store1,load,store1,*,*") 5016 (set_attr "pool_range" "*,*,*,1020,*,*,*")] 5017) 5018 5019(define_expand "movdf" 5020 [(set (match_operand:DF 0 "general_operand" "") 5021 (match_operand:DF 1 "general_operand" ""))] 5022 "TARGET_EITHER" 5023 " 5024 if (TARGET_ARM) 5025 { 5026 if (GET_CODE (operands[0]) == MEM) 5027 operands[1] = force_reg (DFmode, operands[1]); 5028 } 5029 else /* TARGET_THUMB */ 5030 { 5031 if (!no_new_pseudos) 5032 { 5033 if (GET_CODE (operands[0]) != REG) 5034 operands[1] = force_reg (DFmode, operands[1]); 5035 } 5036 } 5037 " 5038) 5039 5040;; Reloading a df mode value stored in integer regs to memory can require a 5041;; scratch reg. 5042(define_expand "reload_outdf" 5043 [(match_operand:DF 0 "arm_reload_memory_operand" "=o") 5044 (match_operand:DF 1 "s_register_operand" "r") 5045 (match_operand:SI 2 "s_register_operand" "=&r")] 5046 "TARGET_ARM" 5047 " 5048 { 5049 enum rtx_code code = GET_CODE (XEXP (operands[0], 0)); 5050 5051 if (code == REG) 5052 operands[2] = XEXP (operands[0], 0); 5053 else if (code == POST_INC || code == PRE_DEC) 5054 { 5055 operands[0] = gen_rtx_SUBREG (DImode, operands[0], 0); 5056 operands[1] = gen_rtx_SUBREG (DImode, operands[1], 0); 5057 emit_insn (gen_movdi (operands[0], operands[1])); 5058 DONE; 5059 } 5060 else if (code == PRE_INC) 5061 { 5062 rtx reg = XEXP (XEXP (operands[0], 0), 0); 5063 5064 emit_insn (gen_addsi3 (reg, reg, GEN_INT (8))); 5065 operands[2] = reg; 5066 } 5067 else if (code == POST_DEC) 5068 operands[2] = XEXP (XEXP (operands[0], 0), 0); 5069 else 5070 emit_insn (gen_addsi3 (operands[2], XEXP (XEXP (operands[0], 0), 0), 5071 XEXP (XEXP (operands[0], 0), 1))); 5072 5073 emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (DFmode, operands[2]), 5074 operands[1])); 5075 5076 if (code == POST_DEC) 5077 emit_insn (gen_addsi3 (operands[2], operands[2], GEN_INT (-8))); 5078 5079 DONE; 5080 }" 5081) 5082 5083(define_insn "*movdf_hard_insn" 5084 [(set (match_operand:DF 0 "nonimmediate_operand" 5085 "=r,Q,r,m,r, f, f,f, m,!f,!r") 5086 (match_operand:DF 1 "general_operand" 5087 "Q, r,r,r,mF,fG,H,mF,f,r, f"))] 5088 "TARGET_ARM 5089 && TARGET_HARD_FLOAT 5090 && (GET_CODE (operands[0]) != MEM 5091 || register_operand (operands[1], DFmode))" 5092 "* 5093 { 5094 switch (which_alternative) 5095 { 5096 default: 5097 case 0: return \"ldm%?ia\\t%m1, %M0\\t%@ double\"; 5098 case 1: return \"stm%?ia\\t%m0, %M1\\t%@ double\"; 5099 case 2: case 3: case 4: return output_move_double (operands); 5100 case 5: return \"mvf%?d\\t%0, %1\"; 5101 case 6: return \"mnf%?d\\t%0, #%N1\"; 5102 case 7: return \"ldf%?d\\t%0, %1\"; 5103 case 8: return \"stf%?d\\t%1, %0\"; 5104 case 9: return output_mov_double_fpu_from_arm (operands); 5105 case 10: return output_mov_double_arm_from_fpu (operands); 5106 } 5107 } 5108 " 5109 [(set_attr "length" "4,4,8,8,8,4,4,4,4,8,8") 5110 (set_attr "predicable" "yes") 5111 (set_attr "type" 5112 "load,store2,*,store2,load,ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r") 5113 (set_attr "pool_range" "*,*,*,*,252,*,*,1024,*,*,*") 5114 (set_attr "neg_pool_range" "*,*,*,*,244,*,*,1012,*,*,*")] 5115) 5116 5117;; Software floating point version. This is essentially the same as movdi. 5118;; Do not use `f' as a constraint to prevent reload from ever trying to use 5119;; an `f' reg. 5120 5121(define_insn "*movdf_soft_insn" 5122 [(set (match_operand:DF 0 "nonimmediate_soft_df_operand" "=r,r,m") 5123 (match_operand:DF 1 "soft_df_operand" "r,mF,r"))] 5124 "TARGET_ARM && TARGET_SOFT_FLOAT 5125 " 5126 "* return output_move_double (operands);" 5127 [(set_attr "length" "8,8,8") 5128 (set_attr "type" "*,load,store2") 5129 (set_attr "pool_range" "252") 5130 (set_attr "neg_pool_range" "244")] 5131) 5132 5133;;; ??? This should have alternatives for constants. 5134;;; ??? This was originally identical to the movdi_insn pattern. 5135;;; ??? The 'F' constraint looks funny, but it should always be replaced by 5136;;; thumb_reorg with a memory reference. 5137(define_insn "*thumb_movdf_insn" 5138 [(set (match_operand:DF 0 "nonimmediate_operand" "=l,l,>,l, m,*r") 5139 (match_operand:DF 1 "general_operand" "l, >,l,mF,l,*r"))] 5140 "TARGET_THUMB 5141 && ( register_operand (operands[0], DFmode) 5142 || register_operand (operands[1], DFmode))" 5143 "* 5144 switch (which_alternative) 5145 { 5146 default: 5147 case 0: 5148 if (REGNO (operands[1]) == REGNO (operands[0]) + 1) 5149 return \"add\\t%0, %1, #0\;add\\t%H0, %H1, #0\"; 5150 return \"add\\t%H0, %H1, #0\;add\\t%0, %1, #0\"; 5151 case 1: 5152 return \"ldmia\\t%1, {%0, %H0}\"; 5153 case 2: 5154 return \"stmia\\t%0, {%1, %H1}\"; 5155 case 3: 5156 return thumb_load_double_from_address (operands); 5157 case 4: 5158 operands[2] = gen_rtx (MEM, SImode, 5159 plus_constant (XEXP (operands[0], 0), 4)); 5160 output_asm_insn (\"str\\t%1, %0\;str\\t%H1, %2\", operands); 5161 return \"\"; 5162 case 5: 5163 if (REGNO (operands[1]) == REGNO (operands[0]) + 1) 5164 return \"mov\\t%0, %1\;mov\\t%H0, %H1\"; 5165 return \"mov\\t%H0, %H1\;mov\\t%0, %1\"; 5166 } 5167 " 5168 [(set_attr "length" "4,2,2,6,4,4") 5169 (set_attr "type" "*,load,store2,load,store2,*") 5170 (set_attr "pool_range" "*,*,*,1020,*,*")] 5171) 5172 5173 5174(define_expand "movxf" 5175 [(set (match_operand:XF 0 "general_operand" "") 5176 (match_operand:XF 1 "general_operand" ""))] 5177 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 5178 "") 5179 5180;; Even when the XFmode patterns aren't enabled, we enable this after 5181;; reloading so that we can push floating point registers in the prologue. 5182 5183(define_insn "*movxf_hard_insn" 5184 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,f,f,m,f,r,r") 5185 (match_operand:XF 1 "general_operand" "fG,H,m,f,r,f,r"))] 5186 "TARGET_ARM && TARGET_HARD_FLOAT && (ENABLE_XF_PATTERNS || reload_completed)" 5187 "* 5188 switch (which_alternative) 5189 { 5190 default: 5191 case 0: return \"mvf%?e\\t%0, %1\"; 5192 case 1: return \"mnf%?e\\t%0, #%N1\"; 5193 case 2: return \"ldf%?e\\t%0, %1\"; 5194 case 3: return \"stf%?e\\t%1, %0\"; 5195 case 4: return output_mov_long_double_fpu_from_arm (operands); 5196 case 5: return output_mov_long_double_arm_from_fpu (operands); 5197 case 6: return output_mov_long_double_arm_from_arm (operands); 5198 } 5199 " 5200 [(set_attr "length" "4,4,4,4,8,8,12") 5201 (set_attr "predicable" "yes") 5202 (set_attr "type" "ffarith,ffarith,f_load,f_store,r_mem_f,f_mem_r,*") 5203 (set_attr "pool_range" "*,*,1024,*,*,*,*") 5204 (set_attr "neg_pool_range" "*,*,1012,*,*,*,*")] 5205) 5206 5207 5208;; load- and store-multiple insns 5209;; The arm can load/store any set of registers, provided that they are in 5210;; ascending order; but that is beyond GCC so stick with what it knows. 5211 5212(define_expand "load_multiple" 5213 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 5214 (match_operand:SI 1 "" "")) 5215 (use (match_operand:SI 2 "" ""))])] 5216 "TARGET_ARM" 5217 " 5218 /* Support only fixed point registers. */ 5219 if (GET_CODE (operands[2]) != CONST_INT 5220 || INTVAL (operands[2]) > 14 5221 || INTVAL (operands[2]) < 2 5222 || GET_CODE (operands[1]) != MEM 5223 || GET_CODE (operands[0]) != REG 5224 || REGNO (operands[0]) > (LAST_ARM_REGNUM - 1) 5225 || REGNO (operands[0]) + INTVAL (operands[2]) > LAST_ARM_REGNUM) 5226 FAIL; 5227 5228 operands[3] 5229 = arm_gen_load_multiple (REGNO (operands[0]), INTVAL (operands[2]), 5230 force_reg (SImode, XEXP (operands[1], 0)), 5231 TRUE, FALSE, RTX_UNCHANGING_P(operands[1]), 5232 MEM_IN_STRUCT_P(operands[1]), 5233 MEM_SCALAR_P (operands[1])); 5234 " 5235) 5236 5237;; Load multiple with write-back 5238 5239(define_insn "*ldmsi_postinc4" 5240 [(match_parallel 0 "load_multiple_operation" 5241 [(set (match_operand:SI 1 "s_register_operand" "=r") 5242 (plus:SI (match_operand:SI 2 "s_register_operand" "1") 5243 (const_int 16))) 5244 (set (match_operand:SI 3 "arm_hard_register_operand" "") 5245 (mem:SI (match_dup 2))) 5246 (set (match_operand:SI 4 "arm_hard_register_operand" "") 5247 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 5248 (set (match_operand:SI 5 "arm_hard_register_operand" "") 5249 (mem:SI (plus:SI (match_dup 2) (const_int 8)))) 5250 (set (match_operand:SI 6 "arm_hard_register_operand" "") 5251 (mem:SI (plus:SI (match_dup 2) (const_int 12))))])] 5252 "TARGET_ARM && XVECLEN (operands[0], 0) == 5" 5253 "ldm%?ia\\t%1!, {%3, %4, %5, %6}" 5254 [(set_attr "type" "load") 5255 (set_attr "predicable" "yes")] 5256) 5257 5258(define_insn "*ldmsi_postinc3" 5259 [(match_parallel 0 "load_multiple_operation" 5260 [(set (match_operand:SI 1 "s_register_operand" "=r") 5261 (plus:SI (match_operand:SI 2 "s_register_operand" "1") 5262 (const_int 12))) 5263 (set (match_operand:SI 3 "arm_hard_register_operand" "") 5264 (mem:SI (match_dup 2))) 5265 (set (match_operand:SI 4 "arm_hard_register_operand" "") 5266 (mem:SI (plus:SI (match_dup 2) (const_int 4)))) 5267 (set (match_operand:SI 5 "arm_hard_register_operand" "") 5268 (mem:SI (plus:SI (match_dup 2) (const_int 8))))])] 5269 "TARGET_ARM && XVECLEN (operands[0], 0) == 4" 5270 "ldm%?ia\\t%1!, {%3, %4, %5}" 5271 [(set_attr "type" "load") 5272 (set_attr "predicable" "yes")] 5273) 5274 5275(define_insn "*ldmsi_postinc2" 5276 [(match_parallel 0 "load_multiple_operation" 5277 [(set (match_operand:SI 1 "s_register_operand" "=r") 5278 (plus:SI (match_operand:SI 2 "s_register_operand" "1") 5279 (const_int 8))) 5280 (set (match_operand:SI 3 "arm_hard_register_operand" "") 5281 (mem:SI (match_dup 2))) 5282 (set (match_operand:SI 4 "arm_hard_register_operand" "") 5283 (mem:SI (plus:SI (match_dup 2) (const_int 4))))])] 5284 "TARGET_ARM && XVECLEN (operands[0], 0) == 3" 5285 "ldm%?ia\\t%1!, {%3, %4}" 5286 [(set_attr "type" "load") 5287 (set_attr "predicable" "yes")] 5288) 5289 5290;; Ordinary load multiple 5291 5292(define_insn "*ldmsi4" 5293 [(match_parallel 0 "load_multiple_operation" 5294 [(set (match_operand:SI 2 "arm_hard_register_operand" "") 5295 (mem:SI (match_operand:SI 1 "s_register_operand" "r"))) 5296 (set (match_operand:SI 3 "arm_hard_register_operand" "") 5297 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 5298 (set (match_operand:SI 4 "arm_hard_register_operand" "") 5299 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 5300 (set (match_operand:SI 5 "arm_hard_register_operand" "") 5301 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])] 5302 "TARGET_ARM && XVECLEN (operands[0], 0) == 4" 5303 "ldm%?ia\\t%1, {%2, %3, %4, %5}" 5304 [(set_attr "type" "load") 5305 (set_attr "predicable" "yes")] 5306) 5307 5308(define_insn "*ldmsi3" 5309 [(match_parallel 0 "load_multiple_operation" 5310 [(set (match_operand:SI 2 "arm_hard_register_operand" "") 5311 (mem:SI (match_operand:SI 1 "s_register_operand" "r"))) 5312 (set (match_operand:SI 3 "arm_hard_register_operand" "") 5313 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 5314 (set (match_operand:SI 4 "arm_hard_register_operand" "") 5315 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])] 5316 "TARGET_ARM && XVECLEN (operands[0], 0) == 3" 5317 "ldm%?ia\\t%1, {%2, %3, %4}" 5318 [(set_attr "type" "load") 5319 (set_attr "predicable" "yes")] 5320) 5321 5322(define_insn "*ldmsi2" 5323 [(match_parallel 0 "load_multiple_operation" 5324 [(set (match_operand:SI 2 "arm_hard_register_operand" "") 5325 (mem:SI (match_operand:SI 1 "s_register_operand" "r"))) 5326 (set (match_operand:SI 3 "arm_hard_register_operand" "") 5327 (mem:SI (plus:SI (match_dup 1) (const_int 4))))])] 5328 "TARGET_ARM && XVECLEN (operands[0], 0) == 2" 5329 "ldm%?ia\\t%1, {%2, %3}" 5330 [(set_attr "type" "load") 5331 (set_attr "predicable" "yes")] 5332) 5333 5334(define_expand "store_multiple" 5335 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 5336 (match_operand:SI 1 "" "")) 5337 (use (match_operand:SI 2 "" ""))])] 5338 "TARGET_ARM" 5339 " 5340 /* Support only fixed point registers */ 5341 if (GET_CODE (operands[2]) != CONST_INT 5342 || INTVAL (operands[2]) > 14 5343 || INTVAL (operands[2]) < 2 5344 || GET_CODE (operands[1]) != REG 5345 || GET_CODE (operands[0]) != MEM 5346 || REGNO (operands[1]) > (LAST_ARM_REGNUM - 1) 5347 || REGNO (operands[1]) + INTVAL (operands[2]) > LAST_ARM_REGNUM) 5348 FAIL; 5349 5350 operands[3] 5351 = arm_gen_store_multiple (REGNO (operands[1]), INTVAL (operands[2]), 5352 force_reg (SImode, XEXP (operands[0], 0)), 5353 TRUE, FALSE, RTX_UNCHANGING_P (operands[0]), 5354 MEM_IN_STRUCT_P(operands[0]), 5355 MEM_SCALAR_P (operands[0])); 5356 " 5357) 5358 5359;; Store multiple with write-back 5360 5361(define_insn "*stmsi_postinc4" 5362 [(match_parallel 0 "store_multiple_operation" 5363 [(set (match_operand:SI 1 "s_register_operand" "=r") 5364 (plus:SI (match_operand:SI 2 "s_register_operand" "1") 5365 (const_int 16))) 5366 (set (mem:SI (match_dup 2)) 5367 (match_operand:SI 3 "arm_hard_register_operand" "")) 5368 (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) 5369 (match_operand:SI 4 "arm_hard_register_operand" "")) 5370 (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) 5371 (match_operand:SI 5 "arm_hard_register_operand" "")) 5372 (set (mem:SI (plus:SI (match_dup 2) (const_int 12))) 5373 (match_operand:SI 6 "arm_hard_register_operand" ""))])] 5374 "TARGET_ARM && XVECLEN (operands[0], 0) == 5" 5375 "stm%?ia\\t%1!, {%3, %4, %5, %6}" 5376 [(set_attr "predicable" "yes") 5377 (set_attr "type" "store4")] 5378) 5379 5380(define_insn "*stmsi_postinc3" 5381 [(match_parallel 0 "store_multiple_operation" 5382 [(set (match_operand:SI 1 "s_register_operand" "=r") 5383 (plus:SI (match_operand:SI 2 "s_register_operand" "1") 5384 (const_int 12))) 5385 (set (mem:SI (match_dup 2)) 5386 (match_operand:SI 3 "arm_hard_register_operand" "")) 5387 (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) 5388 (match_operand:SI 4 "arm_hard_register_operand" "")) 5389 (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) 5390 (match_operand:SI 5 "arm_hard_register_operand" ""))])] 5391 "TARGET_ARM && XVECLEN (operands[0], 0) == 4" 5392 "stm%?ia\\t%1!, {%3, %4, %5}" 5393 [(set_attr "predicable" "yes") 5394 (set_attr "type" "store3")] 5395) 5396 5397(define_insn "*stmsi_postinc2" 5398 [(match_parallel 0 "store_multiple_operation" 5399 [(set (match_operand:SI 1 "s_register_operand" "=r") 5400 (plus:SI (match_operand:SI 2 "s_register_operand" "1") 5401 (const_int 8))) 5402 (set (mem:SI (match_dup 2)) 5403 (match_operand:SI 3 "arm_hard_register_operand" "")) 5404 (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) 5405 (match_operand:SI 4 "arm_hard_register_operand" ""))])] 5406 "TARGET_ARM && XVECLEN (operands[0], 0) == 3" 5407 "stm%?ia\\t%1!, {%3, %4}" 5408 [(set_attr "predicable" "yes") 5409 (set_attr "type" "store2")] 5410) 5411 5412;; Ordinary store multiple 5413 5414(define_insn "*stmsi4" 5415 [(match_parallel 0 "store_multiple_operation" 5416 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r")) 5417 (match_operand:SI 2 "arm_hard_register_operand" "")) 5418 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 5419 (match_operand:SI 3 "arm_hard_register_operand" "")) 5420 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 5421 (match_operand:SI 4 "arm_hard_register_operand" "")) 5422 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 5423 (match_operand:SI 5 "arm_hard_register_operand" ""))])] 5424 "TARGET_ARM && XVECLEN (operands[0], 0) == 4" 5425 "stm%?ia\\t%1, {%2, %3, %4, %5}" 5426 [(set_attr "predicable" "yes") 5427 (set_attr "type" "store4")] 5428) 5429 5430(define_insn "*stmsi3" 5431 [(match_parallel 0 "store_multiple_operation" 5432 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r")) 5433 (match_operand:SI 2 "arm_hard_register_operand" "")) 5434 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 5435 (match_operand:SI 3 "arm_hard_register_operand" "")) 5436 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 5437 (match_operand:SI 4 "arm_hard_register_operand" ""))])] 5438 "TARGET_ARM && XVECLEN (operands[0], 0) == 3" 5439 "stm%?ia\\t%1, {%2, %3, %4}" 5440 [(set_attr "predicable" "yes") 5441 (set_attr "type" "store3")] 5442) 5443 5444(define_insn "*stmsi2" 5445 [(match_parallel 0 "store_multiple_operation" 5446 [(set (mem:SI (match_operand:SI 1 "s_register_operand" "r")) 5447 (match_operand:SI 2 "arm_hard_register_operand" "")) 5448 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 5449 (match_operand:SI 3 "arm_hard_register_operand" ""))])] 5450 "TARGET_ARM && XVECLEN (operands[0], 0) == 2" 5451 "stm%?ia\\t%1, {%2, %3}" 5452 [(set_attr "predicable" "yes") 5453 (set_attr "type" "store2")] 5454) 5455 5456;; Move a block of memory if it is word aligned and MORE than 2 words long. 5457;; We could let this apply for blocks of less than this, but it clobbers so 5458;; many registers that there is then probably a better way. 5459 5460(define_expand "movstrqi" 5461 [(match_operand:BLK 0 "general_operand" "") 5462 (match_operand:BLK 1 "general_operand" "") 5463 (match_operand:SI 2 "const_int_operand" "") 5464 (match_operand:SI 3 "const_int_operand" "")] 5465 "TARGET_EITHER" 5466 " 5467 if (TARGET_ARM) 5468 { 5469 if (arm_gen_movstrqi (operands)) 5470 DONE; 5471 FAIL; 5472 } 5473 else /* TARGET_THUMB */ 5474 { 5475 if ( INTVAL (operands[3]) != 4 5476 || INTVAL (operands[2]) > 48) 5477 FAIL; 5478 5479 thumb_expand_movstrqi (operands); 5480 DONE; 5481 } 5482 " 5483) 5484 5485;; Thumb block-move insns 5486 5487(define_insn "movmem12b" 5488 [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) 5489 (mem:SI (match_operand:SI 3 "register_operand" "1"))) 5490 (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) 5491 (mem:SI (plus:SI (match_dup 3) (const_int 4)))) 5492 (set (mem:SI (plus:SI (match_dup 2) (const_int 8))) 5493 (mem:SI (plus:SI (match_dup 3) (const_int 8)))) 5494 (set (match_operand:SI 0 "register_operand" "=l") 5495 (plus:SI (match_dup 2) (const_int 12))) 5496 (set (match_operand:SI 1 "register_operand" "=l") 5497 (plus:SI (match_dup 3) (const_int 12))) 5498 (clobber (match_scratch:SI 4 "=&l")) 5499 (clobber (match_scratch:SI 5 "=&l")) 5500 (clobber (match_scratch:SI 6 "=&l"))] 5501 "TARGET_THUMB" 5502 "* return thumb_output_move_mem_multiple (3, operands);" 5503 [(set_attr "length" "4") 5504 ; This isn't entirely accurate... It loads as well, but in terms of 5505 ; scheduling the following insn it is better to consider it as a store 5506 (set_attr "type" "store3")] 5507) 5508 5509(define_insn "movmem8b" 5510 [(set (mem:SI (match_operand:SI 2 "register_operand" "0")) 5511 (mem:SI (match_operand:SI 3 "register_operand" "1"))) 5512 (set (mem:SI (plus:SI (match_dup 2) (const_int 4))) 5513 (mem:SI (plus:SI (match_dup 3) (const_int 4)))) 5514 (set (match_operand:SI 0 "register_operand" "=l") 5515 (plus:SI (match_dup 2) (const_int 8))) 5516 (set (match_operand:SI 1 "register_operand" "=l") 5517 (plus:SI (match_dup 3) (const_int 8))) 5518 (clobber (match_scratch:SI 4 "=&l")) 5519 (clobber (match_scratch:SI 5 "=&l"))] 5520 "TARGET_THUMB" 5521 "* return thumb_output_move_mem_multiple (2, operands);" 5522 [(set_attr "length" "4") 5523 ; This isn't entirely accurate... It loads as well, but in terms of 5524 ; scheduling the following insn it is better to consider it as a store 5525 (set_attr "type" "store2")] 5526) 5527 5528 5529 5530;; Compare & branch insns 5531;; The range calcualations are based as follows: 5532;; For forward branches, the address calculation returns the address of 5533;; the next instruction. This is 2 beyond the branch instruction. 5534;; For backward branches, the address calculation returns the address of 5535;; the first instruction in this pattern (cmp). This is 2 before the branch 5536;; instruction for the shortest sequence, and 4 before the branch instruction 5537;; if we have to jump around an unconditional branch. 5538;; To the basic branch range the PC offset must be added (this is +4). 5539;; So for forward branches we have 5540;; (pos_range - pos_base_offs + pc_offs) = (pos_range - 2 + 4). 5541;; And for backward branches we have 5542;; (neg_range - neg_base_offs + pc_offs) = (neg_range - (-2 or -4) + 4). 5543;; 5544;; For a 'b' pos_range = 2046, neg_range = -2048 giving (-2040->2048). 5545;; For a 'b<cond>' pos_range = 254, neg_range = -256 giving (-250 ->256). 5546 5547(define_insn "cbranchsi4" 5548 [(set (pc) 5549 (if_then_else 5550 (match_operator 0 "arm_comparison_operator" 5551 [(match_operand:SI 1 "register_operand" "l,r") 5552 (match_operand:SI 2 "nonmemory_operand" "rI,r")]) 5553 (label_ref (match_operand 3 "" "")) 5554 (pc)))] 5555 "TARGET_THUMB" 5556 "* 5557 output_asm_insn (\"cmp\\t%1, %2\", operands); 5558 switch (get_attr_length (insn)) 5559 { 5560 case 4: return \"b%d0\\t%l3\"; 5561 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; 5562 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; 5563 } 5564 " 5565 [(set (attr "far_jump") 5566 (if_then_else 5567 (eq_attr "length" "8") 5568 (const_string "yes") 5569 (const_string "no"))) 5570 (set (attr "length") 5571 (if_then_else 5572 (and (ge (minus (match_dup 3) (pc)) (const_int -250)) 5573 (le (minus (match_dup 3) (pc)) (const_int 256))) 5574 (const_int 4) 5575 (if_then_else 5576 (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) 5577 (le (minus (match_dup 3) (pc)) (const_int 2048))) 5578 (const_int 6) 5579 (const_int 8))))] 5580) 5581 5582(define_insn "*negated_cbranchsi4" 5583 [(set (pc) 5584 (if_then_else 5585 (match_operator 0 "arm_comparison_operator" 5586 [(match_operand:SI 1 "register_operand" "l") 5587 (neg:SI (match_operand:SI 2 "nonmemory_operand" "l"))]) 5588 (label_ref (match_operand 3 "" "")) 5589 (pc)))] 5590 "TARGET_THUMB" 5591 "* 5592 output_asm_insn (\"cmn\\t%1, %2\", operands); 5593 switch (get_attr_length (insn)) 5594 { 5595 case 4: return \"b%d0\\t%l3\"; 5596 case 6: return \"b%D0\\t.LCB%=\;b\\t%l3\\t%@long jump\\n.LCB%=:\"; 5597 default: return \"b%D0\\t.LCB%=\;bl\\t%l3\\t%@far jump\\n.LCB%=:\"; 5598 } 5599 " 5600 [(set (attr "far_jump") 5601 (if_then_else 5602 (eq_attr "length" "8") 5603 (const_string "yes") 5604 (const_string "no"))) 5605 (set (attr "length") 5606 (if_then_else 5607 (and (ge (minus (match_dup 3) (pc)) (const_int -250)) 5608 (le (minus (match_dup 3) (pc)) (const_int 256))) 5609 (const_int 4) 5610 (if_then_else 5611 (and (ge (minus (match_dup 3) (pc)) (const_int -2040)) 5612 (le (minus (match_dup 3) (pc)) (const_int 2048))) 5613 (const_int 6) 5614 (const_int 8))))] 5615) 5616 5617 5618;; Comparison and test insns 5619 5620(define_expand "cmpsi" 5621 [(match_operand:SI 0 "s_register_operand" "") 5622 (match_operand:SI 1 "arm_add_operand" "")] 5623 "TARGET_ARM" 5624 "{ 5625 arm_compare_op0 = operands[0]; 5626 arm_compare_op1 = operands[1]; 5627 DONE; 5628 }" 5629) 5630 5631(define_expand "cmpsf" 5632 [(match_operand:SF 0 "s_register_operand" "") 5633 (match_operand:SF 1 "fpu_rhs_operand" "")] 5634 "TARGET_ARM && TARGET_HARD_FLOAT" 5635 " 5636 arm_compare_op0 = operands[0]; 5637 arm_compare_op1 = operands[1]; 5638 DONE; 5639 " 5640) 5641 5642(define_expand "cmpdf" 5643 [(match_operand:DF 0 "s_register_operand" "") 5644 (match_operand:DF 1 "fpu_rhs_operand" "")] 5645 "TARGET_ARM && TARGET_HARD_FLOAT" 5646 " 5647 arm_compare_op0 = operands[0]; 5648 arm_compare_op1 = operands[1]; 5649 DONE; 5650 " 5651) 5652 5653(define_expand "cmpxf" 5654 [(match_operand:XF 0 "s_register_operand" "") 5655 (match_operand:XF 1 "fpu_rhs_operand" "")] 5656 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 5657 " 5658 arm_compare_op0 = operands[0]; 5659 arm_compare_op1 = operands[1]; 5660 DONE; 5661 " 5662) 5663 5664(define_insn "*arm_cmpsi_insn" 5665 [(set (reg:CC CC_REGNUM) 5666 (compare:CC (match_operand:SI 0 "s_register_operand" "r,r") 5667 (match_operand:SI 1 "arm_add_operand" "rI,L")))] 5668 "TARGET_ARM" 5669 "@ 5670 cmp%?\\t%0, %1 5671 cmn%?\\t%0, #%n1" 5672 [(set_attr "conds" "set")] 5673) 5674 5675(define_insn "*cmpsi_shiftsi" 5676 [(set (reg:CC CC_REGNUM) 5677 (compare:CC (match_operand:SI 0 "s_register_operand" "r") 5678 (match_operator:SI 3 "shift_operator" 5679 [(match_operand:SI 1 "s_register_operand" "r") 5680 (match_operand:SI 2 "arm_rhs_operand" "rM")])))] 5681 "TARGET_ARM" 5682 "cmp%?\\t%0, %1%S3" 5683 [(set_attr "conds" "set") 5684 (set_attr "shift" "1") 5685 ] 5686) 5687 5688(define_insn "*cmpsi_shiftsi_swp" 5689 [(set (reg:CC_SWP CC_REGNUM) 5690 (compare:CC_SWP (match_operator:SI 3 "shift_operator" 5691 [(match_operand:SI 1 "s_register_operand" "r") 5692 (match_operand:SI 2 "reg_or_int_operand" "rM")]) 5693 (match_operand:SI 0 "s_register_operand" "r")))] 5694 "TARGET_ARM" 5695 "cmp%?\\t%0, %1%S3" 5696 [(set_attr "conds" "set") 5697 (set_attr "shift" "1") 5698 ] 5699) 5700 5701(define_insn "*cmpsi_neg_shiftsi" 5702 [(set (reg:CC CC_REGNUM) 5703 (compare:CC (match_operand:SI 0 "s_register_operand" "r") 5704 (neg:SI (match_operator:SI 3 "shift_operator" 5705 [(match_operand:SI 1 "s_register_operand" "r") 5706 (match_operand:SI 2 "arm_rhs_operand" "rM")]))))] 5707 "TARGET_ARM" 5708 "cmn%?\\t%0, %1%S3" 5709 [(set_attr "conds" "set") 5710 (set_attr "shift" "1") 5711 ] 5712) 5713 5714(define_insn "*cmpsf_insn" 5715 [(set (reg:CCFP CC_REGNUM) 5716 (compare:CCFP (match_operand:SF 0 "s_register_operand" "f,f") 5717 (match_operand:SF 1 "fpu_add_operand" "fG,H")))] 5718 "TARGET_ARM && TARGET_HARD_FLOAT" 5719 "@ 5720 cmf%?\\t%0, %1 5721 cnf%?\\t%0, #%N1" 5722 [(set_attr "conds" "set") 5723 (set_attr "type" "f_2_r")] 5724) 5725 5726(define_insn "*cmpdf_insn" 5727 [(set (reg:CCFP CC_REGNUM) 5728 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f,f") 5729 (match_operand:DF 1 "fpu_add_operand" "fG,H")))] 5730 "TARGET_ARM && TARGET_HARD_FLOAT" 5731 "@ 5732 cmf%?\\t%0, %1 5733 cnf%?\\t%0, #%N1" 5734 [(set_attr "conds" "set") 5735 (set_attr "type" "f_2_r")] 5736) 5737 5738(define_insn "*cmpesfdf_df" 5739 [(set (reg:CCFP CC_REGNUM) 5740 (compare:CCFP (float_extend:DF 5741 (match_operand:SF 0 "s_register_operand" "f,f")) 5742 (match_operand:DF 1 "fpu_add_operand" "fG,H")))] 5743 "TARGET_ARM && TARGET_HARD_FLOAT" 5744 "@ 5745 cmf%?\\t%0, %1 5746 cnf%?\\t%0, #%N1" 5747 [(set_attr "conds" "set") 5748 (set_attr "type" "f_2_r")] 5749) 5750 5751(define_insn "*cmpdf_esfdf" 5752 [(set (reg:CCFP CC_REGNUM) 5753 (compare:CCFP (match_operand:DF 0 "s_register_operand" "f") 5754 (float_extend:DF 5755 (match_operand:SF 1 "s_register_operand" "f"))))] 5756 "TARGET_ARM && TARGET_HARD_FLOAT" 5757 "cmf%?\\t%0, %1" 5758 [(set_attr "conds" "set") 5759 (set_attr "type" "f_2_r")] 5760) 5761 5762(define_insn "*cmpxf_insn" 5763 [(set (reg:CCFP CC_REGNUM) 5764 (compare:CCFP (match_operand:XF 0 "s_register_operand" "f,f") 5765 (match_operand:XF 1 "fpu_add_operand" "fG,H")))] 5766 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 5767 "@ 5768 cmf%?\\t%0, %1 5769 cnf%?\\t%0, #%N1" 5770 [(set_attr "conds" "set") 5771 (set_attr "type" "f_2_r")] 5772) 5773 5774(define_insn "*cmpsf_trap" 5775 [(set (reg:CCFPE CC_REGNUM) 5776 (compare:CCFPE (match_operand:SF 0 "s_register_operand" "f,f") 5777 (match_operand:SF 1 "fpu_add_operand" "fG,H")))] 5778 "TARGET_ARM && TARGET_HARD_FLOAT" 5779 "@ 5780 cmf%?e\\t%0, %1 5781 cnf%?e\\t%0, #%N1" 5782 [(set_attr "conds" "set") 5783 (set_attr "type" "f_2_r")] 5784) 5785 5786(define_insn "*cmpdf_trap" 5787 [(set (reg:CCFPE CC_REGNUM) 5788 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f,f") 5789 (match_operand:DF 1 "fpu_add_operand" "fG,H")))] 5790 "TARGET_ARM && TARGET_HARD_FLOAT" 5791 "@ 5792 cmf%?e\\t%0, %1 5793 cnf%?e\\t%0, #%N1" 5794 [(set_attr "conds" "set") 5795 (set_attr "type" "f_2_r")] 5796) 5797 5798(define_insn "*cmp_esfdf_df_trap" 5799 [(set (reg:CCFPE CC_REGNUM) 5800 (compare:CCFPE (float_extend:DF 5801 (match_operand:SF 0 "s_register_operand" "f,f")) 5802 (match_operand:DF 1 "fpu_add_operand" "fG,H")))] 5803 "TARGET_ARM && TARGET_HARD_FLOAT" 5804 "@ 5805 cmf%?e\\t%0, %1 5806 cnf%?e\\t%0, #%N1" 5807 [(set_attr "conds" "set") 5808 (set_attr "type" "f_2_r")] 5809) 5810 5811(define_insn "*cmp_df_esfdf_trap" 5812 [(set (reg:CCFPE CC_REGNUM) 5813 (compare:CCFPE (match_operand:DF 0 "s_register_operand" "f") 5814 (float_extend:DF 5815 (match_operand:SF 1 "s_register_operand" "f"))))] 5816 "TARGET_ARM && TARGET_HARD_FLOAT" 5817 "cmf%?e\\t%0, %1" 5818 [(set_attr "conds" "set") 5819 (set_attr "type" "f_2_r")] 5820) 5821 5822(define_insn "*cmpxf_trap" 5823 [(set (reg:CCFPE CC_REGNUM) 5824 (compare:CCFPE (match_operand:XF 0 "s_register_operand" "f,f") 5825 (match_operand:XF 1 "fpu_add_operand" "fG,H")))] 5826 "TARGET_ARM && ENABLE_XF_PATTERNS && TARGET_HARD_FLOAT" 5827 "@ 5828 cmf%?e\\t%0, %1 5829 cnf%?e\\t%0, #%N1" 5830 [(set_attr "conds" "set") 5831 (set_attr "type" "f_2_r")] 5832) 5833 5834; This insn allows redundant compares to be removed by cse, nothing should 5835; ever appear in the output file since (set (reg x) (reg x)) is a no-op that 5836; is deleted later on. The match_dup will match the mode here, so that 5837; mode changes of the condition codes aren't lost by this even though we don't 5838; specify what they are. 5839 5840(define_insn "*deleted_compare" 5841 [(set (match_operand 0 "cc_register" "") (match_dup 0))] 5842 "TARGET_ARM" 5843 "\\t%@ deleted compare" 5844 [(set_attr "conds" "set") 5845 (set_attr "length" "0")] 5846) 5847 5848 5849;; Conditional branch insns 5850 5851(define_expand "beq" 5852 [(set (pc) 5853 (if_then_else (eq (match_dup 1) (const_int 0)) 5854 (label_ref (match_operand 0 "" "")) 5855 (pc)))] 5856 "TARGET_ARM" 5857 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);" 5858) 5859 5860(define_expand "bne" 5861 [(set (pc) 5862 (if_then_else (ne (match_dup 1) (const_int 0)) 5863 (label_ref (match_operand 0 "" "")) 5864 (pc)))] 5865 "TARGET_ARM" 5866 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);" 5867) 5868 5869(define_expand "bgt" 5870 [(set (pc) 5871 (if_then_else (gt (match_dup 1) (const_int 0)) 5872 (label_ref (match_operand 0 "" "")) 5873 (pc)))] 5874 "TARGET_ARM" 5875 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);" 5876) 5877 5878(define_expand "ble" 5879 [(set (pc) 5880 (if_then_else (le (match_dup 1) (const_int 0)) 5881 (label_ref (match_operand 0 "" "")) 5882 (pc)))] 5883 "TARGET_ARM" 5884 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);" 5885) 5886 5887(define_expand "bge" 5888 [(set (pc) 5889 (if_then_else (ge (match_dup 1) (const_int 0)) 5890 (label_ref (match_operand 0 "" "")) 5891 (pc)))] 5892 "TARGET_ARM" 5893 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);" 5894) 5895 5896(define_expand "blt" 5897 [(set (pc) 5898 (if_then_else (lt (match_dup 1) (const_int 0)) 5899 (label_ref (match_operand 0 "" "")) 5900 (pc)))] 5901 "TARGET_ARM" 5902 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);" 5903) 5904 5905(define_expand "bgtu" 5906 [(set (pc) 5907 (if_then_else (gtu (match_dup 1) (const_int 0)) 5908 (label_ref (match_operand 0 "" "")) 5909 (pc)))] 5910 "TARGET_ARM" 5911 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);" 5912) 5913 5914(define_expand "bleu" 5915 [(set (pc) 5916 (if_then_else (leu (match_dup 1) (const_int 0)) 5917 (label_ref (match_operand 0 "" "")) 5918 (pc)))] 5919 "TARGET_ARM" 5920 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);" 5921) 5922 5923(define_expand "bgeu" 5924 [(set (pc) 5925 (if_then_else (geu (match_dup 1) (const_int 0)) 5926 (label_ref (match_operand 0 "" "")) 5927 (pc)))] 5928 "TARGET_ARM" 5929 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);" 5930) 5931 5932(define_expand "bltu" 5933 [(set (pc) 5934 (if_then_else (ltu (match_dup 1) (const_int 0)) 5935 (label_ref (match_operand 0 "" "")) 5936 (pc)))] 5937 "TARGET_ARM" 5938 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);" 5939) 5940 5941(define_expand "bunordered" 5942 [(set (pc) 5943 (if_then_else (unordered (match_dup 1) (const_int 0)) 5944 (label_ref (match_operand 0 "" "")) 5945 (pc)))] 5946 "TARGET_ARM && TARGET_HARD_FLOAT" 5947 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0, 5948 arm_compare_op1);" 5949) 5950 5951(define_expand "bordered" 5952 [(set (pc) 5953 (if_then_else (ordered (match_dup 1) (const_int 0)) 5954 (label_ref (match_operand 0 "" "")) 5955 (pc)))] 5956 "TARGET_ARM && TARGET_HARD_FLOAT" 5957 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0, 5958 arm_compare_op1);" 5959) 5960 5961(define_expand "bungt" 5962 [(set (pc) 5963 (if_then_else (ungt (match_dup 1) (const_int 0)) 5964 (label_ref (match_operand 0 "" "")) 5965 (pc)))] 5966 "TARGET_ARM && TARGET_HARD_FLOAT" 5967 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, arm_compare_op1);" 5968) 5969 5970(define_expand "bunlt" 5971 [(set (pc) 5972 (if_then_else (unlt (match_dup 1) (const_int 0)) 5973 (label_ref (match_operand 0 "" "")) 5974 (pc)))] 5975 "TARGET_ARM && TARGET_HARD_FLOAT" 5976 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, arm_compare_op1);" 5977) 5978 5979(define_expand "bunge" 5980 [(set (pc) 5981 (if_then_else (unge (match_dup 1) (const_int 0)) 5982 (label_ref (match_operand 0 "" "")) 5983 (pc)))] 5984 "TARGET_ARM && TARGET_HARD_FLOAT" 5985 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, arm_compare_op1);" 5986) 5987 5988(define_expand "bunle" 5989 [(set (pc) 5990 (if_then_else (unle (match_dup 1) (const_int 0)) 5991 (label_ref (match_operand 0 "" "")) 5992 (pc)))] 5993 "TARGET_ARM && TARGET_HARD_FLOAT" 5994 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, arm_compare_op1);" 5995) 5996 5997;; The following two patterns need two branch instructions, since there is 5998;; no single instruction that will handle all cases. 5999(define_expand "buneq" 6000 [(set (pc) 6001 (if_then_else (uneq (match_dup 1) (const_int 0)) 6002 (label_ref (match_operand 0 "" "")) 6003 (pc)))] 6004 "TARGET_ARM && TARGET_HARD_FLOAT" 6005 "operands[1] = arm_gen_compare_reg (UNEQ, arm_compare_op0, arm_compare_op1);" 6006) 6007 6008(define_expand "bltgt" 6009 [(set (pc) 6010 (if_then_else (ltgt (match_dup 1) (const_int 0)) 6011 (label_ref (match_operand 0 "" "")) 6012 (pc)))] 6013 "TARGET_ARM && TARGET_HARD_FLOAT" 6014 "operands[1] = arm_gen_compare_reg (LTGT, arm_compare_op0, arm_compare_op1);" 6015) 6016 6017;; 6018;; Patterns to match conditional branch insns. 6019;; 6020 6021; Special pattern to match UNEQ. 6022(define_insn "*arm_buneq" 6023 [(set (pc) 6024 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0)) 6025 (label_ref (match_operand 0 "" "")) 6026 (pc)))] 6027 "TARGET_ARM && TARGET_HARD_FLOAT" 6028 "* 6029 if (arm_ccfsm_state != 0) 6030 abort (); 6031 6032 return \"bvs\\t%l0;beq\\t%l0\"; 6033 " 6034 [(set_attr "conds" "jump_clob") 6035 (set_attr "length" "8")] 6036) 6037 6038; Special pattern to match LTGT. 6039(define_insn "*arm_bltgt" 6040 [(set (pc) 6041 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0)) 6042 (label_ref (match_operand 0 "" "")) 6043 (pc)))] 6044 "TARGET_ARM && TARGET_HARD_FLOAT" 6045 "* 6046 if (arm_ccfsm_state != 0) 6047 abort (); 6048 6049 return \"bmi\\t%l0;bgt\\t%l0\"; 6050 " 6051 [(set_attr "conds" "jump_clob") 6052 (set_attr "length" "8")] 6053) 6054 6055(define_insn "*arm_cond_branch" 6056 [(set (pc) 6057 (if_then_else (match_operator 1 "arm_comparison_operator" 6058 [(match_operand 2 "cc_register" "") (const_int 0)]) 6059 (label_ref (match_operand 0 "" "")) 6060 (pc)))] 6061 "TARGET_ARM" 6062 "* 6063 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 6064 { 6065 arm_ccfsm_state += 2; 6066 return \"\"; 6067 } 6068 return \"b%d1\\t%l0\"; 6069 " 6070 [(set_attr "conds" "use")] 6071) 6072 6073; Special pattern to match reversed UNEQ. 6074(define_insn "*arm_buneq_reversed" 6075 [(set (pc) 6076 (if_then_else (uneq (match_operand 1 "cc_register" "") (const_int 0)) 6077 (pc) 6078 (label_ref (match_operand 0 "" ""))))] 6079 "TARGET_ARM && TARGET_HARD_FLOAT" 6080 "* 6081 if (arm_ccfsm_state != 0) 6082 abort (); 6083 6084 return \"bmi\\t%l0;bgt\\t%l0\"; 6085 " 6086 [(set_attr "conds" "jump_clob") 6087 (set_attr "length" "8")] 6088) 6089 6090; Special pattern to match reversed LTGT. 6091(define_insn "*arm_bltgt_reversed" 6092 [(set (pc) 6093 (if_then_else (ltgt (match_operand 1 "cc_register" "") (const_int 0)) 6094 (pc) 6095 (label_ref (match_operand 0 "" ""))))] 6096 "TARGET_ARM && TARGET_HARD_FLOAT" 6097 "* 6098 if (arm_ccfsm_state != 0) 6099 abort (); 6100 6101 return \"bvs\\t%l0;beq\\t%l0\"; 6102 " 6103 [(set_attr "conds" "jump_clob") 6104 (set_attr "length" "8")] 6105) 6106 6107(define_insn "*arm_cond_branch_reversed" 6108 [(set (pc) 6109 (if_then_else (match_operator 1 "arm_comparison_operator" 6110 [(match_operand 2 "cc_register" "") (const_int 0)]) 6111 (pc) 6112 (label_ref (match_operand 0 "" ""))))] 6113 "TARGET_ARM" 6114 "* 6115 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 6116 { 6117 arm_ccfsm_state += 2; 6118 return \"\"; 6119 } 6120 return \"b%D1\\t%l0\"; 6121 " 6122 [(set_attr "conds" "use")] 6123) 6124 6125 6126 6127; scc insns 6128 6129(define_expand "seq" 6130 [(set (match_operand:SI 0 "s_register_operand" "=r") 6131 (eq:SI (match_dup 1) (const_int 0)))] 6132 "TARGET_ARM" 6133 "operands[1] = arm_gen_compare_reg (EQ, arm_compare_op0, arm_compare_op1);" 6134) 6135 6136(define_expand "sne" 6137 [(set (match_operand:SI 0 "s_register_operand" "=r") 6138 (ne:SI (match_dup 1) (const_int 0)))] 6139 "TARGET_ARM" 6140 "operands[1] = arm_gen_compare_reg (NE, arm_compare_op0, arm_compare_op1);" 6141) 6142 6143(define_expand "sgt" 6144 [(set (match_operand:SI 0 "s_register_operand" "=r") 6145 (gt:SI (match_dup 1) (const_int 0)))] 6146 "TARGET_ARM" 6147 "operands[1] = arm_gen_compare_reg (GT, arm_compare_op0, arm_compare_op1);" 6148) 6149 6150(define_expand "sle" 6151 [(set (match_operand:SI 0 "s_register_operand" "=r") 6152 (le:SI (match_dup 1) (const_int 0)))] 6153 "TARGET_ARM" 6154 "operands[1] = arm_gen_compare_reg (LE, arm_compare_op0, arm_compare_op1);" 6155) 6156 6157(define_expand "sge" 6158 [(set (match_operand:SI 0 "s_register_operand" "=r") 6159 (ge:SI (match_dup 1) (const_int 0)))] 6160 "TARGET_ARM" 6161 "operands[1] = arm_gen_compare_reg (GE, arm_compare_op0, arm_compare_op1);" 6162) 6163 6164(define_expand "slt" 6165 [(set (match_operand:SI 0 "s_register_operand" "=r") 6166 (lt:SI (match_dup 1) (const_int 0)))] 6167 "TARGET_ARM" 6168 "operands[1] = arm_gen_compare_reg (LT, arm_compare_op0, arm_compare_op1);" 6169) 6170 6171(define_expand "sgtu" 6172 [(set (match_operand:SI 0 "s_register_operand" "=r") 6173 (gtu:SI (match_dup 1) (const_int 0)))] 6174 "TARGET_ARM" 6175 "operands[1] = arm_gen_compare_reg (GTU, arm_compare_op0, arm_compare_op1);" 6176) 6177 6178(define_expand "sleu" 6179 [(set (match_operand:SI 0 "s_register_operand" "=r") 6180 (leu:SI (match_dup 1) (const_int 0)))] 6181 "TARGET_ARM" 6182 "operands[1] = arm_gen_compare_reg (LEU, arm_compare_op0, arm_compare_op1);" 6183) 6184 6185(define_expand "sgeu" 6186 [(set (match_operand:SI 0 "s_register_operand" "=r") 6187 (geu:SI (match_dup 1) (const_int 0)))] 6188 "TARGET_ARM" 6189 "operands[1] = arm_gen_compare_reg (GEU, arm_compare_op0, arm_compare_op1);" 6190) 6191 6192(define_expand "sltu" 6193 [(set (match_operand:SI 0 "s_register_operand" "=r") 6194 (ltu:SI (match_dup 1) (const_int 0)))] 6195 "TARGET_ARM" 6196 "operands[1] = arm_gen_compare_reg (LTU, arm_compare_op0, arm_compare_op1);" 6197) 6198 6199(define_expand "sunordered" 6200 [(set (match_operand:SI 0 "s_register_operand" "=r") 6201 (unordered:SI (match_dup 1) (const_int 0)))] 6202 "TARGET_ARM && TARGET_HARD_FLOAT" 6203 "operands[1] = arm_gen_compare_reg (UNORDERED, arm_compare_op0, 6204 arm_compare_op1);" 6205) 6206 6207(define_expand "sordered" 6208 [(set (match_operand:SI 0 "s_register_operand" "=r") 6209 (ordered:SI (match_dup 1) (const_int 0)))] 6210 "TARGET_ARM && TARGET_HARD_FLOAT" 6211 "operands[1] = arm_gen_compare_reg (ORDERED, arm_compare_op0, 6212 arm_compare_op1);" 6213) 6214 6215(define_expand "sungt" 6216 [(set (match_operand:SI 0 "s_register_operand" "=r") 6217 (ungt:SI (match_dup 1) (const_int 0)))] 6218 "TARGET_ARM && TARGET_HARD_FLOAT" 6219 "operands[1] = arm_gen_compare_reg (UNGT, arm_compare_op0, 6220 arm_compare_op1);" 6221) 6222 6223(define_expand "sunge" 6224 [(set (match_operand:SI 0 "s_register_operand" "=r") 6225 (unge:SI (match_dup 1) (const_int 0)))] 6226 "TARGET_ARM && TARGET_HARD_FLOAT" 6227 "operands[1] = arm_gen_compare_reg (UNGE, arm_compare_op0, 6228 arm_compare_op1);" 6229) 6230 6231(define_expand "sunlt" 6232 [(set (match_operand:SI 0 "s_register_operand" "=r") 6233 (unlt:SI (match_dup 1) (const_int 0)))] 6234 "TARGET_ARM && TARGET_HARD_FLOAT" 6235 "operands[1] = arm_gen_compare_reg (UNLT, arm_compare_op0, 6236 arm_compare_op1);" 6237) 6238 6239(define_expand "sunle" 6240 [(set (match_operand:SI 0 "s_register_operand" "=r") 6241 (unle:SI (match_dup 1) (const_int 0)))] 6242 "TARGET_ARM && TARGET_HARD_FLOAT" 6243 "operands[1] = arm_gen_compare_reg (UNLE, arm_compare_op0, 6244 arm_compare_op1);" 6245) 6246 6247;;; DO NOT add patterns for SUNEQ or SLTGT, these can't be represented with 6248;;; simple ARM instructions. 6249; 6250; (define_expand "suneq" 6251; [(set (match_operand:SI 0 "s_register_operand" "=r") 6252; (uneq:SI (match_dup 1) (const_int 0)))] 6253; "TARGET_ARM && TARGET_HARD_FLOAT" 6254; "abort ();" 6255; ) 6256; 6257; (define_expand "sltgt" 6258; [(set (match_operand:SI 0 "s_register_operand" "=r") 6259; (ltgt:SI (match_dup 1) (const_int 0)))] 6260; "TARGET_ARM && TARGET_HARD_FLOAT" 6261; "abort ();" 6262; ) 6263 6264(define_insn "*mov_scc" 6265 [(set (match_operand:SI 0 "s_register_operand" "=r") 6266 (match_operator:SI 1 "arm_comparison_operator" 6267 [(match_operand 2 "cc_register" "") (const_int 0)]))] 6268 "TARGET_ARM" 6269 "mov%D1\\t%0, #0\;mov%d1\\t%0, #1" 6270 [(set_attr "conds" "use") 6271 (set_attr "length" "8")] 6272) 6273 6274(define_insn "*mov_negscc" 6275 [(set (match_operand:SI 0 "s_register_operand" "=r") 6276 (neg:SI (match_operator:SI 1 "arm_comparison_operator" 6277 [(match_operand 2 "cc_register" "") (const_int 0)])))] 6278 "TARGET_ARM" 6279 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #0" 6280 [(set_attr "conds" "use") 6281 (set_attr "length" "8")] 6282) 6283 6284(define_insn "*mov_notscc" 6285 [(set (match_operand:SI 0 "s_register_operand" "=r") 6286 (not:SI (match_operator:SI 1 "arm_comparison_operator" 6287 [(match_operand 2 "cc_register" "") (const_int 0)])))] 6288 "TARGET_ARM" 6289 "mov%D1\\t%0, #0\;mvn%d1\\t%0, #1" 6290 [(set_attr "conds" "use") 6291 (set_attr "length" "8")] 6292) 6293 6294 6295;; Conditional move insns 6296 6297(define_expand "movsicc" 6298 [(set (match_operand:SI 0 "s_register_operand" "") 6299 (if_then_else:SI (match_operand 1 "arm_comparison_operator" "") 6300 (match_operand:SI 2 "arm_not_operand" "") 6301 (match_operand:SI 3 "arm_not_operand" "")))] 6302 "TARGET_ARM" 6303 " 6304 { 6305 enum rtx_code code = GET_CODE (operands[1]); 6306 rtx ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1); 6307 6308 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx); 6309 }" 6310) 6311 6312(define_expand "movsfcc" 6313 [(set (match_operand:SF 0 "s_register_operand" "") 6314 (if_then_else:SF (match_operand 1 "arm_comparison_operator" "") 6315 (match_operand:SF 2 "s_register_operand" "") 6316 (match_operand:SF 3 "nonmemory_operand" "")))] 6317 "TARGET_ARM" 6318 " 6319 { 6320 enum rtx_code code = GET_CODE (operands[1]); 6321 rtx ccreg; 6322 6323 /* When compiling for SOFT_FLOAT, ensure both arms are in registers. 6324 Otherwise, ensure it is a valid FP add operand */ 6325 if ((!TARGET_HARD_FLOAT) 6326 || (!fpu_add_operand (operands[3], SFmode))) 6327 operands[3] = force_reg (SFmode, operands[3]); 6328 6329 ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1); 6330 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx); 6331 }" 6332) 6333 6334(define_expand "movdfcc" 6335 [(set (match_operand:DF 0 "s_register_operand" "") 6336 (if_then_else:DF (match_operand 1 "arm_comparison_operator" "") 6337 (match_operand:DF 2 "s_register_operand" "") 6338 (match_operand:DF 3 "fpu_add_operand" "")))] 6339 "TARGET_ARM && TARGET_HARD_FLOAT" 6340 " 6341 { 6342 enum rtx_code code = GET_CODE (operands[1]); 6343 rtx ccreg = arm_gen_compare_reg (code, arm_compare_op0, arm_compare_op1); 6344 6345 operands[1] = gen_rtx (code, VOIDmode, ccreg, const0_rtx); 6346 }" 6347) 6348 6349(define_insn "*movsicc_insn" 6350 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r,r,r,r,r") 6351 (if_then_else:SI 6352 (match_operator 3 "arm_comparison_operator" 6353 [(match_operand 4 "cc_register" "") (const_int 0)]) 6354 (match_operand:SI 1 "arm_not_operand" "0,0,rI,K,rI,rI,K,K") 6355 (match_operand:SI 2 "arm_not_operand" "rI,K,0,0,rI,K,rI,K")))] 6356 "TARGET_ARM" 6357 "@ 6358 mov%D3\\t%0, %2 6359 mvn%D3\\t%0, #%B2 6360 mov%d3\\t%0, %1 6361 mvn%d3\\t%0, #%B1 6362 mov%d3\\t%0, %1\;mov%D3\\t%0, %2 6363 mov%d3\\t%0, %1\;mvn%D3\\t%0, #%B2 6364 mvn%d3\\t%0, #%B1\;mov%D3\\t%0, %2 6365 mvn%d3\\t%0, #%B1\;mvn%D3\\t%0, #%B2" 6366 [(set_attr "length" "4,4,4,4,8,8,8,8") 6367 (set_attr "conds" "use")] 6368) 6369 6370(define_insn "*movsfcc_hard_insn" 6371 [(set (match_operand:SF 0 "s_register_operand" "=f,f,f,f,f,f,f,f") 6372 (if_then_else:SF 6373 (match_operator 3 "arm_comparison_operator" 6374 [(match_operand 4 "cc_register" "") (const_int 0)]) 6375 (match_operand:SF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H") 6376 (match_operand:SF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))] 6377 "TARGET_ARM && TARGET_HARD_FLOAT" 6378 "@ 6379 mvf%D3s\\t%0, %2 6380 mnf%D3s\\t%0, #%N2 6381 mvf%d3s\\t%0, %1 6382 mnf%d3s\\t%0, #%N1 6383 mvf%d3s\\t%0, %1\;mvf%D3s\\t%0, %2 6384 mvf%d3s\\t%0, %1\;mnf%D3s\\t%0, #%N2 6385 mnf%d3s\\t%0, #%N1\;mvf%D3s\\t%0, %2 6386 mnf%d3s\\t%0, #%N1\;mnf%D3s\\t%0, #%N2" 6387 [(set_attr "length" "4,4,4,4,8,8,8,8") 6388 (set_attr "type" "ffarith") 6389 (set_attr "conds" "use")] 6390) 6391 6392(define_insn "*movsfcc_soft_insn" 6393 [(set (match_operand:SF 0 "s_register_operand" "=r,r") 6394 (if_then_else:SF (match_operator 3 "arm_comparison_operator" 6395 [(match_operand 4 "cc_register" "") (const_int 0)]) 6396 (match_operand:SF 1 "s_register_operand" "0,r") 6397 (match_operand:SF 2 "s_register_operand" "r,0")))] 6398 "TARGET_ARM && TARGET_SOFT_FLOAT" 6399 "@ 6400 mov%D3\\t%0, %2 6401 mov%d3\\t%0, %1" 6402 [(set_attr "conds" "use")] 6403) 6404 6405(define_insn "*movdfcc_insn" 6406 [(set (match_operand:DF 0 "s_register_operand" "=f,f,f,f,f,f,f,f") 6407 (if_then_else:DF 6408 (match_operator 3 "arm_comparison_operator" 6409 [(match_operand 4 "cc_register" "") (const_int 0)]) 6410 (match_operand:DF 1 "fpu_add_operand" "0,0,fG,H,fG,fG,H,H") 6411 (match_operand:DF 2 "fpu_add_operand" "fG,H,0,0,fG,H,fG,H")))] 6412 "TARGET_ARM && TARGET_HARD_FLOAT" 6413 "@ 6414 mvf%D3d\\t%0, %2 6415 mnf%D3d\\t%0, #%N2 6416 mvf%d3d\\t%0, %1 6417 mnf%d3d\\t%0, #%N1 6418 mvf%d3d\\t%0, %1\;mvf%D3d\\t%0, %2 6419 mvf%d3d\\t%0, %1\;mnf%D3d\\t%0, #%N2 6420 mnf%d3d\\t%0, #%N1\;mvf%D3d\\t%0, %2 6421 mnf%d3d\\t%0, #%N1\;mnf%D3d\\t%0, #%N2" 6422 [(set_attr "length" "4,4,4,4,8,8,8,8") 6423 (set_attr "type" "ffarith") 6424 (set_attr "conds" "use")] 6425) 6426 6427 6428;; Jump and linkage insns 6429 6430(define_expand "jump" 6431 [(set (pc) 6432 (label_ref (match_operand 0 "" "")))] 6433 "TARGET_EITHER" 6434 "" 6435) 6436 6437(define_insn "*arm_jump" 6438 [(set (pc) 6439 (label_ref (match_operand 0 "" "")))] 6440 "TARGET_ARM" 6441 "* 6442 { 6443 if (arm_ccfsm_state == 1 || arm_ccfsm_state == 2) 6444 { 6445 arm_ccfsm_state += 2; 6446 return \"\"; 6447 } 6448 return \"b%?\\t%l0\"; 6449 } 6450 " 6451 [(set_attr "predicable" "yes")] 6452) 6453 6454(define_insn "*thumb_jump" 6455 [(set (pc) 6456 (label_ref (match_operand 0 "" "")))] 6457 "TARGET_THUMB" 6458 "* 6459 if (get_attr_length (insn) == 2) 6460 return \"b\\t%l0\"; 6461 return \"bl\\t%l0\\t%@ far jump\"; 6462 " 6463 [(set (attr "far_jump") 6464 (if_then_else 6465 (eq_attr "length" "4") 6466 (const_string "yes") 6467 (const_string "no"))) 6468 (set (attr "length") 6469 (if_then_else 6470 (and (ge (minus (match_dup 0) (pc)) (const_int -2048)) 6471 (le (minus (match_dup 0) (pc)) (const_int 2044))) 6472 (const_int 2) 6473 (const_int 4)))] 6474) 6475 6476(define_expand "call" 6477 [(parallel [(call (match_operand 0 "memory_operand" "") 6478 (match_operand 1 "general_operand" "")) 6479 (use (match_operand 2 "" "")) 6480 (clobber (reg:SI LR_REGNUM))])] 6481 "TARGET_EITHER" 6482 " 6483 { 6484 rtx callee; 6485 6486 /* In an untyped call, we can get NULL for operand 2. */ 6487 if (operands[2] == NULL_RTX) 6488 operands[2] = const0_rtx; 6489 6490 /* This is to decide if we should generate indirect calls by loading the 6491 32 bit address of the callee into a register before performing the 6492 branch and link. operand[2] encodes the long_call/short_call 6493 attribute of the function being called. This attribute is set whenever 6494 __attribute__((long_call/short_call)) or #pragma long_call/no_long_call 6495 is used, and the short_call attribute can also be set if function is 6496 declared as static or if it has already been defined in the current 6497 compilation unit. See arm.c and arm.h for info about this. The third 6498 parameter to arm_is_longcall_p is used to tell it which pattern 6499 invoked it. */ 6500 callee = XEXP (operands[0], 0); 6501 6502 if (GET_CODE (callee) != REG 6503 && arm_is_longcall_p (operands[0], INTVAL (operands[2]), 0)) 6504 XEXP (operands[0], 0) = force_reg (Pmode, callee); 6505 }" 6506) 6507 6508(define_insn "*call_reg" 6509 [(call (mem:SI (match_operand:SI 0 "s_register_operand" "r")) 6510 (match_operand 1 "" "")) 6511 (use (match_operand 2 "" "")) 6512 (clobber (reg:SI LR_REGNUM))] 6513 "TARGET_ARM" 6514 "* 6515 return output_call (operands); 6516 " 6517 ;; length is worst case, normally it is only two 6518 [(set_attr "length" "12") 6519 (set_attr "type" "call")] 6520) 6521 6522(define_insn "*call_mem" 6523 [(call (mem:SI (match_operand:SI 0 "memory_operand" "m")) 6524 (match_operand 1 "" "")) 6525 (use (match_operand 2 "" "")) 6526 (clobber (reg:SI LR_REGNUM))] 6527 "TARGET_ARM" 6528 "* 6529 return output_call_mem (operands); 6530 " 6531 [(set_attr "length" "12") 6532 (set_attr "type" "call")] 6533) 6534 6535(define_insn "*call_indirect" 6536 [(call (mem:SI (match_operand:SI 0 "register_operand" "l*r")) 6537 (match_operand 1 "" "")) 6538 (use (match_operand 2 "" "")) 6539 (clobber (reg:SI LR_REGNUM))] 6540 "TARGET_THUMB" 6541 "* 6542 { 6543 if (TARGET_CALLER_INTERWORKING) 6544 return \"bl\\t%__interwork_call_via_%0\"; 6545 else 6546 return \"bl\\t%__call_via_%0\"; 6547 }" 6548 [(set_attr "type" "call")] 6549) 6550 6551(define_insn "*call_value_indirect" 6552 [(set (match_operand 0 "" "=l") 6553 (call (mem:SI (match_operand:SI 1 "register_operand" "l*r")) 6554 (match_operand 2 "" ""))) 6555 (use (match_operand 3 "" "")) 6556 (clobber (reg:SI LR_REGNUM))] 6557 "TARGET_THUMB" 6558 "* 6559 { 6560 if (TARGET_CALLER_INTERWORKING) 6561 return \"bl\\t%__interwork_call_via_%1\"; 6562 else 6563 return \"bl\\t%__call_via_%1\"; 6564 }" 6565 [(set_attr "type" "call")] 6566) 6567 6568(define_expand "call_value" 6569 [(parallel [(set (match_operand 0 "" "") 6570 (call (match_operand 1 "memory_operand" "") 6571 (match_operand 2 "general_operand" ""))) 6572 (use (match_operand 3 "" "")) 6573 (clobber (reg:SI LR_REGNUM))])] 6574 "TARGET_EITHER" 6575 " 6576 { 6577 rtx callee = XEXP (operands[1], 0); 6578 6579 /* In an untyped call, we can get NULL for operand 2. */ 6580 if (operands[3] == 0) 6581 operands[3] = const0_rtx; 6582 6583 /* See the comment in define_expand \"call\". */ 6584 if (GET_CODE (callee) != REG 6585 && arm_is_longcall_p (operands[1], INTVAL (operands[3]), 0)) 6586 XEXP (operands[1], 0) = force_reg (Pmode, callee); 6587 }" 6588) 6589 6590(define_insn "*call_value_reg" 6591 [(set (match_operand 0 "" "=r,f") 6592 (call (mem:SI (match_operand:SI 1 "s_register_operand" "r,r")) 6593 (match_operand 2 "" ""))) 6594 (use (match_operand 3 "" "")) 6595 (clobber (reg:SI LR_REGNUM))] 6596 "TARGET_ARM" 6597 "* 6598 return output_call (&operands[1]); 6599 " 6600 [(set_attr "length" "12") 6601 (set_attr "type" "call")] 6602) 6603 6604(define_insn "*call_value_mem" 6605 [(set (match_operand 0 "" "=r,f") 6606 (call (mem:SI (match_operand:SI 1 "memory_operand" "m,m")) 6607 (match_operand 2 "" ""))) 6608 (use (match_operand 3 "" "")) 6609 (clobber (reg:SI LR_REGNUM))] 6610 "TARGET_ARM && (!CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))" 6611 "* 6612 return output_call_mem (&operands[1]); 6613 " 6614 [(set_attr "length" "12") 6615 (set_attr "type" "call")] 6616) 6617 6618;; Allow calls to SYMBOL_REFs specially as they are not valid general addresses 6619;; The 'a' causes the operand to be treated as an address, i.e. no '#' output. 6620 6621(define_insn "*call_symbol" 6622 [(call (mem:SI (match_operand:SI 0 "" "X")) 6623 (match_operand 1 "" "")) 6624 (use (match_operand 2 "" "")) 6625 (clobber (reg:SI LR_REGNUM))] 6626 "TARGET_ARM 6627 && (GET_CODE (operands[0]) == SYMBOL_REF) 6628 && !arm_is_longcall_p (operands[0], INTVAL (operands[2]), 1)" 6629 "* 6630 { 6631 return NEED_PLT_RELOC ? \"bl%?\\t%a0(PLT)\" : \"bl%?\\t%a0\"; 6632 }" 6633 [(set_attr "type" "call")] 6634) 6635 6636(define_insn "*call_value_symbol" 6637 [(set (match_operand 0 "s_register_operand" "=r,f") 6638 (call (mem:SI (match_operand:SI 1 "" "X,X")) 6639 (match_operand:SI 2 "" ""))) 6640 (use (match_operand 3 "" "")) 6641 (clobber (reg:SI LR_REGNUM))] 6642 "TARGET_ARM 6643 && (GET_CODE (operands[1]) == SYMBOL_REF) 6644 && !arm_is_longcall_p (operands[1], INTVAL (operands[3]), 1)" 6645 "* 6646 { 6647 return NEED_PLT_RELOC ? \"bl%?\\t%a1(PLT)\" : \"bl%?\\t%a1\"; 6648 }" 6649 [(set_attr "type" "call")] 6650) 6651 6652(define_insn "*call_insn" 6653 [(call (mem:SI (match_operand:SI 0 "" "X")) 6654 (match_operand:SI 1 "" "")) 6655 (use (match_operand 2 "" "")) 6656 (clobber (reg:SI LR_REGNUM))] 6657 "TARGET_THUMB 6658 && operands[2] == const0_rtx && (GET_CODE (operands[0]) == SYMBOL_REF)" 6659 "bl\\t%a0" 6660 [(set_attr "length" "4") 6661 (set_attr "type" "call")] 6662) 6663 6664(define_insn "*call_value_insn" 6665 [(set (match_operand 0 "register_operand" "=l") 6666 (call (mem:SI (match_operand 1 "" "X")) 6667 (match_operand 2 "" ""))) 6668 (use (match_operand 3 "" "")) 6669 (clobber (reg:SI LR_REGNUM))] 6670 "TARGET_THUMB 6671 && operands[3] == const0_rtx && (GET_CODE (operands[1]) == SYMBOL_REF)" 6672 "bl\\t%a1" 6673 [(set_attr "length" "4") 6674 (set_attr "type" "call")] 6675) 6676 6677;; We may also be able to do sibcalls for Thumb, but it's much harder... 6678(define_expand "sibcall" 6679 [(parallel [(call (match_operand 0 "memory_operand" "") 6680 (match_operand 1 "general_operand" "")) 6681 (use (match_operand 2 "" "")) 6682 (use (reg:SI LR_REGNUM))])] 6683 "TARGET_ARM" 6684 " 6685 { 6686 if (operands[2] == NULL_RTX) 6687 operands[2] = const0_rtx; 6688 }" 6689) 6690 6691(define_expand "sibcall_value" 6692 [(parallel [(set (match_operand 0 "register_operand" "") 6693 (call (match_operand 1 "memory_operand" "") 6694 (match_operand 2 "general_operand" ""))) 6695 (use (match_operand 3 "" "")) 6696 (use (reg:SI LR_REGNUM))])] 6697 "TARGET_ARM" 6698 " 6699 { 6700 if (operands[3] == NULL_RTX) 6701 operands[3] = const0_rtx; 6702 }" 6703) 6704 6705(define_insn "*sibcall_insn" 6706 [(call (mem:SI (match_operand:SI 0 "" "X")) 6707 (match_operand 1 "" "")) 6708 (use (match_operand 2 "" "")) 6709 (use (reg:SI LR_REGNUM))] 6710 "TARGET_ARM && GET_CODE (operands[0]) == SYMBOL_REF" 6711 "* 6712 return NEED_PLT_RELOC ? \"b%?\\t%a0(PLT)\" : \"b%?\\t%a0\"; 6713 " 6714 [(set_attr "type" "call")] 6715) 6716 6717(define_insn "*sibcall_value_insn" 6718 [(set (match_operand 0 "s_register_operand" "=r,f") 6719 (call (mem:SI (match_operand:SI 1 "" "X,X")) 6720 (match_operand 2 "" ""))) 6721 (use (match_operand 3 "" "")) 6722 (use (reg:SI LR_REGNUM))] 6723 "TARGET_ARM && GET_CODE (operands[1]) == SYMBOL_REF" 6724 "* 6725 return NEED_PLT_RELOC ? \"b%?\\t%a1(PLT)\" : \"b%?\\t%a1\"; 6726 " 6727 [(set_attr "type" "call")] 6728) 6729 6730;; Often the return insn will be the same as loading from memory, so set attr 6731(define_insn "return" 6732 [(return)] 6733 "TARGET_ARM && USE_RETURN_INSN (FALSE)" 6734 "* 6735 { 6736 if (arm_ccfsm_state == 2) 6737 { 6738 arm_ccfsm_state += 2; 6739 return \"\"; 6740 } 6741 return output_return_instruction (NULL, TRUE, FALSE); 6742 }" 6743 [(set_attr "type" "load") 6744 (set_attr "predicable" "yes")] 6745) 6746 6747(define_insn "*cond_return" 6748 [(set (pc) 6749 (if_then_else (match_operator 0 "arm_comparison_operator" 6750 [(match_operand 1 "cc_register" "") (const_int 0)]) 6751 (return) 6752 (pc)))] 6753 "TARGET_ARM && USE_RETURN_INSN (TRUE)" 6754 "* 6755 { 6756 if (arm_ccfsm_state == 2) 6757 { 6758 arm_ccfsm_state += 2; 6759 return \"\"; 6760 } 6761 return output_return_instruction (operands[0], TRUE, FALSE); 6762 }" 6763 [(set_attr "conds" "use") 6764 (set_attr "type" "load")] 6765) 6766 6767(define_insn "*cond_return_inverted" 6768 [(set (pc) 6769 (if_then_else (match_operator 0 "arm_comparison_operator" 6770 [(match_operand 1 "cc_register" "") (const_int 0)]) 6771 (pc) 6772 (return)))] 6773 "TARGET_ARM && USE_RETURN_INSN (TRUE)" 6774 "* 6775 { 6776 if (arm_ccfsm_state == 2) 6777 { 6778 arm_ccfsm_state += 2; 6779 return \"\"; 6780 } 6781 return output_return_instruction (operands[0], TRUE, TRUE); 6782 }" 6783 [(set_attr "conds" "use") 6784 (set_attr "type" "load")] 6785) 6786 6787;; Call subroutine returning any type. 6788 6789(define_expand "untyped_call" 6790 [(parallel [(call (match_operand 0 "" "") 6791 (const_int 0)) 6792 (match_operand 1 "" "") 6793 (match_operand 2 "" "")])] 6794 "TARGET_ARM" 6795 " 6796 { 6797 int i; 6798 6799 emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, const0_rtx)); 6800 6801 for (i = 0; i < XVECLEN (operands[2], 0); i++) 6802 { 6803 rtx set = XVECEXP (operands[2], 0, i); 6804 6805 emit_move_insn (SET_DEST (set), SET_SRC (set)); 6806 } 6807 6808 /* The optimizer does not know that the call sets the function value 6809 registers we stored in the result block. We avoid problems by 6810 claiming that all hard registers are used and clobbered at this 6811 point. */ 6812 emit_insn (gen_blockage ()); 6813 6814 DONE; 6815 }" 6816) 6817 6818;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 6819;; all of memory. This blocks insns from being moved across this point. 6820 6821(define_insn "blockage" 6822 [(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)] 6823 "TARGET_EITHER" 6824 "" 6825 [(set_attr "length" "0") 6826 (set_attr "type" "block")] 6827) 6828 6829(define_expand "casesi" 6830 [(match_operand:SI 0 "s_register_operand" "") ; index to jump on 6831 (match_operand:SI 1 "const_int_operand" "") ; lower bound 6832 (match_operand:SI 2 "const_int_operand" "") ; total range 6833 (match_operand:SI 3 "" "") ; table label 6834 (match_operand:SI 4 "" "")] ; Out of range label 6835 "TARGET_ARM" 6836 " 6837 { 6838 rtx reg; 6839 if (operands[1] != const0_rtx) 6840 { 6841 reg = gen_reg_rtx (SImode); 6842 6843 emit_insn (gen_addsi3 (reg, operands[0], 6844 GEN_INT (-INTVAL (operands[1])))); 6845 operands[0] = reg; 6846 } 6847 6848 if (!const_ok_for_arm (INTVAL (operands[2]))) 6849 operands[2] = force_reg (SImode, operands[2]); 6850 6851 emit_jump_insn (gen_casesi_internal (operands[0], operands[2], operands[3], 6852 operands[4])); 6853 DONE; 6854 }" 6855) 6856 6857;; The USE in this pattern is needed to tell flow analysis that this is 6858;; a CASESI insn. It has no other purpose. 6859(define_insn "casesi_internal" 6860 [(parallel [(set (pc) 6861 (if_then_else 6862 (leu (match_operand:SI 0 "s_register_operand" "r") 6863 (match_operand:SI 1 "arm_rhs_operand" "rI")) 6864 (mem:SI (plus:SI (mult:SI (match_dup 0) (const_int 4)) 6865 (label_ref (match_operand 2 "" "")))) 6866 (label_ref (match_operand 3 "" "")))) 6867 (clobber (reg:CC CC_REGNUM)) 6868 (use (label_ref (match_dup 2)))])] 6869 "TARGET_ARM" 6870 "* 6871 if (flag_pic) 6872 return \"cmp\\t%0, %1\;addls\\t%|pc, %|pc, %0, asl #2\;b\\t%l3\"; 6873 return \"cmp\\t%0, %1\;ldrls\\t%|pc, [%|pc, %0, asl #2]\;b\\t%l3\"; 6874 " 6875 [(set_attr "conds" "clob") 6876 (set_attr "length" "12")] 6877) 6878 6879(define_expand "indirect_jump" 6880 [(set (pc) 6881 (match_operand:SI 0 "s_register_operand" ""))] 6882 "TARGET_EITHER" 6883 "" 6884) 6885 6886(define_insn "*arm_indirect_jump" 6887 [(set (pc) 6888 (match_operand:SI 0 "s_register_operand" "r"))] 6889 "TARGET_ARM" 6890 "mov%?\\t%|pc, %0\\t%@ indirect register jump" 6891 [(set_attr "predicable" "yes")] 6892) 6893 6894;; Although not supported by the define_expand above, 6895;; cse/combine may generate this form. 6896(define_insn "*load_indirect_jump" 6897 [(set (pc) 6898 (match_operand:SI 0 "memory_operand" "m"))] 6899 "TARGET_ARM" 6900 "ldr%?\\t%|pc, %0\\t%@ indirect memory jump" 6901 [(set_attr "type" "load") 6902 (set_attr "pool_range" "4096") 6903 (set_attr "neg_pool_range" "4084") 6904 (set_attr "predicable" "yes")] 6905) 6906 6907(define_insn "*thumb_indirect_jump" 6908 [(set (pc) 6909 (match_operand:SI 0 "register_operand" "l*r"))] 6910 "TARGET_THUMB" 6911 "mov\\tpc, %0" 6912 [(set_attr "conds" "clob") 6913 (set_attr "length" "2")] 6914) 6915 6916 6917;; Misc insns 6918 6919(define_insn "nop" 6920 [(const_int 0)] 6921 "TARGET_EITHER" 6922 "* 6923 if (TARGET_ARM) 6924 return \"mov%?\\t%|r0, %|r0\\t%@ nop\"; 6925 return \"mov\\tr8, r8\"; 6926 " 6927 [(set (attr "length") 6928 (if_then_else (eq_attr "is_thumb" "yes") 6929 (const_int 2) 6930 (const_int 4)))] 6931) 6932 6933 6934;; Patterns to allow combination of arithmetic, cond code and shifts 6935 6936(define_insn "*arith_shiftsi" 6937 [(set (match_operand:SI 0 "s_register_operand" "=r") 6938 (match_operator:SI 1 "shiftable_operator" 6939 [(match_operator:SI 3 "shift_operator" 6940 [(match_operand:SI 4 "s_register_operand" "r") 6941 (match_operand:SI 5 "reg_or_int_operand" "rI")]) 6942 (match_operand:SI 2 "s_register_operand" "r")]))] 6943 "TARGET_ARM" 6944 "%i1%?\\t%0, %2, %4%S3" 6945 [(set_attr "predicable" "yes") 6946 (set_attr "shift" "4") 6947 ] 6948) 6949 6950(define_insn "*arith_shiftsi_compare0" 6951 [(set (reg:CC_NOOV CC_REGNUM) 6952 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator" 6953 [(match_operator:SI 3 "shift_operator" 6954 [(match_operand:SI 4 "s_register_operand" "r") 6955 (match_operand:SI 5 "reg_or_int_operand" "rI")]) 6956 (match_operand:SI 2 "s_register_operand" "r")]) 6957 (const_int 0))) 6958 (set (match_operand:SI 0 "s_register_operand" "=r") 6959 (match_op_dup 1 [(match_op_dup 3 [(match_dup 4) (match_dup 5)]) 6960 (match_dup 2)]))] 6961 "TARGET_ARM" 6962 "%i1%?s\\t%0, %2, %4%S3" 6963 [(set_attr "conds" "set") 6964 (set_attr "shift" "4") 6965 ] 6966) 6967 6968(define_insn "*arith_shiftsi_compare0_scratch" 6969 [(set (reg:CC_NOOV CC_REGNUM) 6970 (compare:CC_NOOV (match_operator:SI 1 "shiftable_operator" 6971 [(match_operator:SI 3 "shift_operator" 6972 [(match_operand:SI 4 "s_register_operand" "r") 6973 (match_operand:SI 5 "reg_or_int_operand" "rI")]) 6974 (match_operand:SI 2 "s_register_operand" "r")]) 6975 (const_int 0))) 6976 (clobber (match_scratch:SI 0 "=r"))] 6977 "TARGET_ARM" 6978 "%i1%?s\\t%0, %2, %4%S3" 6979 [(set_attr "conds" "set") 6980 (set_attr "shift" "4") 6981 ] 6982) 6983 6984(define_insn "*sub_shiftsi" 6985 [(set (match_operand:SI 0 "s_register_operand" "=r") 6986 (minus:SI (match_operand:SI 1 "s_register_operand" "r") 6987 (match_operator:SI 2 "shift_operator" 6988 [(match_operand:SI 3 "s_register_operand" "r") 6989 (match_operand:SI 4 "reg_or_int_operand" "rM")])))] 6990 "TARGET_ARM" 6991 "sub%?\\t%0, %1, %3%S2" 6992 [(set_attr "predicable" "yes") 6993 (set_attr "shift" "3") 6994 ] 6995) 6996 6997(define_insn "*sub_shiftsi_compare0" 6998 [(set (reg:CC_NOOV CC_REGNUM) 6999 (compare:CC_NOOV 7000 (minus:SI (match_operand:SI 1 "s_register_operand" "r") 7001 (match_operator:SI 2 "shift_operator" 7002 [(match_operand:SI 3 "s_register_operand" "r") 7003 (match_operand:SI 4 "reg_or_int_operand" "rM")])) 7004 (const_int 0))) 7005 (set (match_operand:SI 0 "s_register_operand" "=r") 7006 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) 7007 (match_dup 4)])))] 7008 "TARGET_ARM" 7009 "sub%?s\\t%0, %1, %3%S2" 7010 [(set_attr "conds" "set") 7011 (set_attr "shift" "3") 7012 ] 7013) 7014 7015(define_insn "*sub_shiftsi_compare0_scratch" 7016 [(set (reg:CC_NOOV CC_REGNUM) 7017 (compare:CC_NOOV 7018 (minus:SI (match_operand:SI 1 "s_register_operand" "r") 7019 (match_operator:SI 2 "shift_operator" 7020 [(match_operand:SI 3 "s_register_operand" "r") 7021 (match_operand:SI 4 "reg_or_int_operand" "rM")])) 7022 (const_int 0))) 7023 (clobber (match_scratch:SI 0 "=r"))] 7024 "TARGET_ARM" 7025 "sub%?s\\t%0, %1, %3%S2" 7026 [(set_attr "conds" "set") 7027 (set_attr "shift" "3") 7028 ] 7029) 7030 7031;; These variants of the above insns can occur if the first operand is the 7032;; frame pointer and we eliminate that. This is a kludge, but there doesn't 7033;; seem to be a way around it. Most of the predicates have to be null 7034;; because the format can be generated part way through reload, so 7035;; if we don't match it as soon as it becomes available, reload doesn't know 7036;; how to reload pseudos that haven't got hard registers; the constraints will 7037;; sort everything out. 7038 7039(define_insn "*reload_mulsi3" 7040 [(set (match_operand:SI 0 "" "=&r") 7041 (plus:SI (plus:SI (match_operator:SI 5 "shift_operator" 7042 [(match_operand:SI 3 "" "r") 7043 (match_operand:SI 4 "" "rM")]) 7044 (match_operand:SI 2 "" "r")) 7045 (match_operand:SI 1 "const_int_operand" "n")))] 7046 "TARGET_ARM && reload_in_progress" 7047 "* 7048 output_asm_insn (\"add%?\\t%0, %2, %3%S5\", operands); 7049 operands[2] = operands[1]; 7050 operands[1] = operands[0]; 7051 return output_add_immediate (operands); 7052 " 7053 [ 7054 ; we have no idea how long the add_immediate is, it could be up to 4. 7055 (set_attr "length" "20")] 7056) 7057 7058(define_insn "*reload_mulsi_compare0" 7059 [(set (reg:CC_NOOV CC_REGNUM) 7060 (compare:CC_NOOV (plus:SI 7061 (plus:SI 7062 (match_operator:SI 5 "shift_operator" 7063 [(match_operand:SI 3 "" "r") 7064 (match_operand:SI 4 "" "rM")]) 7065 (match_operand:SI 1 "" "r")) 7066 (match_operand:SI 2 "const_int_operand" "n")) 7067 (const_int 0))) 7068 (set (match_operand:SI 0 "" "=&r") 7069 (plus:SI (plus:SI (match_op_dup 5 [(match_dup 3) (match_dup 4)]) 7070 (match_dup 1)) 7071 (match_dup 2)))] 7072 "TARGET_ARM && reload_in_progress && !arm_is_xscale" 7073 "* 7074 output_add_immediate (operands); 7075 return \"add%?s\\t%0, %0, %3%S5\"; 7076 " 7077 [(set_attr "conds" "set") 7078 (set_attr "shift" "3") 7079 (set_attr "length" "20")] 7080) 7081 7082(define_insn "*reload_mulsi_compare0_scratch" 7083 [(set (reg:CC_NOOV CC_REGNUM) 7084 (compare:CC_NOOV (plus:SI 7085 (plus:SI 7086 (match_operator:SI 5 "shift_operator" 7087 [(match_operand:SI 3 "" "r") 7088 (match_operand:SI 4 "" "rM")]) 7089 (match_operand:SI 1 "" "r")) 7090 (match_operand:SI 2 "const_int_operand" "n")) 7091 (const_int 0))) 7092 (clobber (match_scratch:SI 0 "=&r"))] 7093 "TARGET_ARM && reload_in_progress && !arm_is_xscale" 7094 "* 7095 output_add_immediate (operands); 7096 return \"add%?s\\t%0, %0, %3%S5\"; 7097 " 7098 [(set_attr "conds" "set") 7099 (set_attr "shift" "3") 7100 (set_attr "length" "20")] 7101) 7102 7103;; These are similar, but are needed when the mla pattern contains the 7104;; eliminated register as operand 3. 7105 7106(define_insn "*reload_muladdsi" 7107 [(set (match_operand:SI 0 "" "=&r,&r") 7108 (plus:SI (plus:SI (mult:SI (match_operand:SI 1 "" "%0,r") 7109 (match_operand:SI 2 "" "r,r")) 7110 (match_operand:SI 3 "" "r,r")) 7111 (match_operand:SI 4 "const_int_operand" "n,n")))] 7112 "TARGET_ARM && reload_in_progress" 7113 "* 7114 output_asm_insn (\"mla%?\\t%0, %2, %1, %3\", operands); 7115 operands[2] = operands[4]; 7116 operands[1] = operands[0]; 7117 return output_add_immediate (operands); 7118 " 7119 [(set_attr "length" "20") 7120 (set_attr "type" "mult")] 7121) 7122 7123(define_insn "*reload_muladdsi_compare0" 7124 [(set (reg:CC_NOOV CC_REGNUM) 7125 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI 7126 (match_operand:SI 3 "" "r") 7127 (match_operand:SI 4 "" "r")) 7128 (match_operand:SI 1 "" "r")) 7129 (match_operand:SI 2 "const_int_operand" "n")) 7130 (const_int 0))) 7131 (set (match_operand:SI 0 "" "=&r") 7132 (plus:SI (plus:SI (mult:SI (match_dup 3) (match_dup 4)) (match_dup 1)) 7133 (match_dup 2)))] 7134 "TARGET_ARM && reload_in_progress && !arm_is_xscale" 7135 "* 7136 output_add_immediate (operands); 7137 output_asm_insn (\"mla%?s\\t%0, %3, %4, %0\", operands); 7138 return \"\"; 7139 " 7140 [(set_attr "length" "20") 7141 (set_attr "conds" "set") 7142 (set_attr "type" "mult")] 7143) 7144 7145(define_insn "*reload_muladdsi_compare0_scratch" 7146 [(set (reg:CC_NOOV CC_REGNUM) 7147 (compare:CC_NOOV (plus:SI (plus:SI (mult:SI 7148 (match_operand:SI 3 "" "r") 7149 (match_operand:SI 4 "" "r")) 7150 (match_operand:SI 1 "" "r")) 7151 (match_operand:SI 2 "const_int_operand" "n")) 7152 (const_int 0))) 7153 (clobber (match_scratch:SI 0 "=&r"))] 7154 "TARGET_ARM && reload_in_progress" 7155 "* 7156 output_add_immediate (operands); 7157 return \"mla%?s\\t%0, %3, %4, %0\"; 7158 " 7159 [(set_attr "length" "20") 7160 (set_attr "conds" "set") 7161 (set_attr "type" "mult")] 7162) 7163 7164 7165 7166(define_insn "*and_scc" 7167 [(set (match_operand:SI 0 "s_register_operand" "=r") 7168 (and:SI (match_operator:SI 1 "arm_comparison_operator" 7169 [(match_operand 3 "cc_register" "") (const_int 0)]) 7170 (match_operand:SI 2 "s_register_operand" "r")))] 7171 "TARGET_ARM" 7172 "mov%D1\\t%0, #0\;and%d1\\t%0, %2, #1" 7173 [(set_attr "conds" "use") 7174 (set_attr "length" "8")] 7175) 7176 7177(define_insn "*ior_scc" 7178 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7179 (ior:SI (match_operator:SI 2 "arm_comparison_operator" 7180 [(match_operand 3 "cc_register" "") (const_int 0)]) 7181 (match_operand:SI 1 "s_register_operand" "0,?r")))] 7182 "TARGET_ARM" 7183 "@ 7184 orr%d2\\t%0, %1, #1 7185 mov%D2\\t%0, %1\;orr%d2\\t%0, %1, #1" 7186 [(set_attr "conds" "use") 7187 (set_attr "length" "4,8")] 7188) 7189 7190(define_insn "*compare_scc" 7191 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7192 (match_operator:SI 1 "arm_comparison_operator" 7193 [(match_operand:SI 2 "s_register_operand" "r,r") 7194 (match_operand:SI 3 "arm_add_operand" "rI,L")])) 7195 (clobber (reg:CC CC_REGNUM))] 7196 "TARGET_ARM" 7197 "* 7198 if (GET_CODE (operands[1]) == LT && operands[3] == const0_rtx) 7199 return \"mov\\t%0, %2, lsr #31\"; 7200 7201 if (GET_CODE (operands[1]) == GE && operands[3] == const0_rtx) 7202 return \"mvn\\t%0, %2\;mov\\t%0, %0, lsr #31\"; 7203 7204 if (GET_CODE (operands[1]) == NE) 7205 { 7206 if (which_alternative == 1) 7207 return \"adds\\t%0, %2, #%n3\;movne\\t%0, #1\"; 7208 return \"subs\\t%0, %2, %3\;movne\\t%0, #1\"; 7209 } 7210 if (which_alternative == 1) 7211 output_asm_insn (\"cmn\\t%2, #%n3\", operands); 7212 else 7213 output_asm_insn (\"cmp\\t%2, %3\", operands); 7214 return \"mov%D1\\t%0, #0\;mov%d1\\t%0, #1\"; 7215 " 7216 [(set_attr "conds" "clob") 7217 (set_attr "length" "12")] 7218) 7219 7220(define_insn "*cond_move" 7221 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 7222 (if_then_else:SI (match_operator 3 "equality_operator" 7223 [(match_operator 4 "arm_comparison_operator" 7224 [(match_operand 5 "cc_register" "") (const_int 0)]) 7225 (const_int 0)]) 7226 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") 7227 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI")))] 7228 "TARGET_ARM" 7229 "* 7230 if (GET_CODE (operands[3]) == NE) 7231 { 7232 if (which_alternative != 1) 7233 output_asm_insn (\"mov%D4\\t%0, %2\", operands); 7234 if (which_alternative != 0) 7235 output_asm_insn (\"mov%d4\\t%0, %1\", operands); 7236 return \"\"; 7237 } 7238 if (which_alternative != 0) 7239 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 7240 if (which_alternative != 1) 7241 output_asm_insn (\"mov%d4\\t%0, %2\", operands); 7242 return \"\"; 7243 " 7244 [(set_attr "conds" "use") 7245 (set_attr "length" "4,4,8")] 7246) 7247 7248(define_insn "*cond_arith" 7249 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7250 (match_operator:SI 5 "shiftable_operator" 7251 [(match_operator:SI 4 "arm_comparison_operator" 7252 [(match_operand:SI 2 "s_register_operand" "r,r") 7253 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 7254 (match_operand:SI 1 "s_register_operand" "0,?r")])) 7255 (clobber (reg:CC CC_REGNUM))] 7256 "TARGET_ARM" 7257 "* 7258 if (GET_CODE (operands[4]) == LT && operands[3] == const0_rtx) 7259 return \"%i5\\t%0, %1, %2, lsr #31\"; 7260 7261 output_asm_insn (\"cmp\\t%2, %3\", operands); 7262 if (GET_CODE (operands[5]) == AND) 7263 output_asm_insn (\"mov%D4\\t%0, #0\", operands); 7264 else if (GET_CODE (operands[5]) == MINUS) 7265 output_asm_insn (\"rsb%D4\\t%0, %1, #0\", operands); 7266 else if (which_alternative != 0) 7267 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 7268 return \"%i5%d4\\t%0, %1, #1\"; 7269 " 7270 [(set_attr "conds" "clob") 7271 (set_attr "length" "12")] 7272) 7273 7274(define_insn "*cond_sub" 7275 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7276 (minus:SI (match_operand:SI 1 "s_register_operand" "0,?r") 7277 (match_operator:SI 4 "arm_comparison_operator" 7278 [(match_operand:SI 2 "s_register_operand" "r,r") 7279 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) 7280 (clobber (reg:CC CC_REGNUM))] 7281 "TARGET_ARM" 7282 "* 7283 output_asm_insn (\"cmp\\t%2, %3\", operands); 7284 if (which_alternative != 0) 7285 output_asm_insn (\"mov%D4\\t%0, %1\", operands); 7286 return \"sub%d4\\t%0, %1, #1\"; 7287 " 7288 [(set_attr "conds" "clob") 7289 (set_attr "length" "8,12")] 7290) 7291 7292(define_insn "*cmp_ite0" 7293 [(set (match_operand 6 "dominant_cc_register" "") 7294 (compare 7295 (if_then_else:SI 7296 (match_operator 4 "arm_comparison_operator" 7297 [(match_operand:SI 0 "s_register_operand" "r,r,r,r") 7298 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) 7299 (match_operator:SI 5 "arm_comparison_operator" 7300 [(match_operand:SI 2 "s_register_operand" "r,r,r,r") 7301 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]) 7302 (const_int 0)) 7303 (const_int 0)))] 7304 "TARGET_ARM" 7305 "* 7306 { 7307 static const char * const opcodes[4][2] = 7308 { 7309 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\", 7310 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"}, 7311 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", 7312 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"}, 7313 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", 7314 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"}, 7315 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\", 7316 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"} 7317 }; 7318 int swap = 7319 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 7320 7321 return opcodes[which_alternative][swap]; 7322 }" 7323 [(set_attr "conds" "set") 7324 (set_attr "length" "8")] 7325) 7326 7327(define_insn "*cmp_ite1" 7328 [(set (match_operand 6 "dominant_cc_register" "") 7329 (compare 7330 (if_then_else:SI 7331 (match_operator 4 "arm_comparison_operator" 7332 [(match_operand:SI 0 "s_register_operand" "r,r,r,r") 7333 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) 7334 (match_operator:SI 5 "arm_comparison_operator" 7335 [(match_operand:SI 2 "s_register_operand" "r,r,r,r") 7336 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")]) 7337 (const_int 1)) 7338 (const_int 0)))] 7339 "TARGET_ARM" 7340 "* 7341 { 7342 static const char * const opcodes[4][2] = 7343 { 7344 {\"cmp\\t%0, %1\;cmp%d4\\t%2, %3\", 7345 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"}, 7346 {\"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\", 7347 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"}, 7348 {\"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\", 7349 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"}, 7350 {\"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\", 7351 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"} 7352 }; 7353 int swap = 7354 comparison_dominates_p (GET_CODE (operands[5]), 7355 reverse_condition (GET_CODE (operands[4]))); 7356 7357 return opcodes[which_alternative][swap]; 7358 }" 7359 [(set_attr "conds" "set") 7360 (set_attr "length" "8")] 7361) 7362 7363(define_insn "*cmp_and" 7364 [(set (match_operand 6 "dominant_cc_register" "") 7365 (compare 7366 (and:SI 7367 (match_operator 4 "arm_comparison_operator" 7368 [(match_operand:SI 0 "s_register_operand" "r,r,r,r") 7369 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) 7370 (match_operator:SI 5 "arm_comparison_operator" 7371 [(match_operand:SI 2 "s_register_operand" "r,r,r,r") 7372 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])) 7373 (const_int 0)))] 7374 "TARGET_ARM" 7375 "* 7376 { 7377 static const char *const opcodes[4][2] = 7378 { 7379 {\"cmp\\t%2, %3\;cmp%d5\\t%0, %1\", 7380 \"cmp\\t%0, %1\;cmp%d4\\t%2, %3\"}, 7381 {\"cmp\\t%2, %3\;cmn%d5\\t%0, #%n1\", 7382 \"cmn\\t%0, #%n1\;cmp%d4\\t%2, %3\"}, 7383 {\"cmn\\t%2, #%n3\;cmp%d5\\t%0, %1\", 7384 \"cmp\\t%0, %1\;cmn%d4\\t%2, #%n3\"}, 7385 {\"cmn\\t%2, #%n3\;cmn%d5\\t%0, #%n1\", 7386 \"cmn\\t%0, #%n1\;cmn%d4\\t%2, #%n3\"} 7387 }; 7388 int swap = 7389 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 7390 7391 return opcodes[which_alternative][swap]; 7392 }" 7393 [(set_attr "conds" "set") 7394 (set_attr "predicable" "no") 7395 (set_attr "length" "8")] 7396) 7397 7398(define_insn "*cmp_ior" 7399 [(set (match_operand 6 "dominant_cc_register" "") 7400 (compare 7401 (ior:SI 7402 (match_operator 4 "arm_comparison_operator" 7403 [(match_operand:SI 0 "s_register_operand" "r,r,r,r") 7404 (match_operand:SI 1 "arm_add_operand" "rI,L,rI,L")]) 7405 (match_operator:SI 5 "arm_comparison_operator" 7406 [(match_operand:SI 2 "s_register_operand" "r,r,r,r") 7407 (match_operand:SI 3 "arm_add_operand" "rI,rI,L,L")])) 7408 (const_int 0)))] 7409 "TARGET_ARM" 7410 "* 7411{ 7412 static const char *const opcodes[4][2] = 7413 { 7414 {\"cmp\\t%0, %1\;cmp%D4\\t%2, %3\", 7415 \"cmp\\t%2, %3\;cmp%D5\\t%0, %1\"}, 7416 {\"cmn\\t%0, #%n1\;cmp%D4\\t%2, %3\", 7417 \"cmp\\t%2, %3\;cmn%D5\\t%0, #%n1\"}, 7418 {\"cmp\\t%0, %1\;cmn%D4\\t%2, #%n3\", 7419 \"cmn\\t%2, #%n3\;cmp%D5\\t%0, %1\"}, 7420 {\"cmn\\t%0, #%n1\;cmn%D4\\t%2, #%n3\", 7421 \"cmn\\t%2, #%n3\;cmn%D5\\t%0, #%n1\"} 7422 }; 7423 int swap = 7424 comparison_dominates_p (GET_CODE (operands[5]), GET_CODE (operands[4])); 7425 7426 return opcodes[which_alternative][swap]; 7427} 7428" 7429 [(set_attr "conds" "set") 7430 (set_attr "length" "8")] 7431) 7432 7433(define_insn "*negscc" 7434 [(set (match_operand:SI 0 "s_register_operand" "=r") 7435 (neg:SI (match_operator 3 "arm_comparison_operator" 7436 [(match_operand:SI 1 "s_register_operand" "r") 7437 (match_operand:SI 2 "arm_rhs_operand" "rI")]))) 7438 (clobber (reg:CC CC_REGNUM))] 7439 "TARGET_ARM" 7440 "* 7441 if (GET_CODE (operands[3]) == LT && operands[3] == const0_rtx) 7442 return \"mov\\t%0, %1, asr #31\"; 7443 7444 if (GET_CODE (operands[3]) == NE) 7445 return \"subs\\t%0, %1, %2\;mvnne\\t%0, #0\"; 7446 7447 if (GET_CODE (operands[3]) == GT) 7448 return \"subs\\t%0, %1, %2\;mvnne\\t%0, %0, asr #31\"; 7449 7450 output_asm_insn (\"cmp\\t%1, %2\", operands); 7451 output_asm_insn (\"mov%D3\\t%0, #0\", operands); 7452 return \"mvn%d3\\t%0, #0\"; 7453 " 7454 [(set_attr "conds" "clob") 7455 (set_attr "length" "12")] 7456) 7457 7458(define_insn "movcond" 7459 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 7460 (if_then_else:SI 7461 (match_operator 5 "arm_comparison_operator" 7462 [(match_operand:SI 3 "s_register_operand" "r,r,r") 7463 (match_operand:SI 4 "arm_add_operand" "rIL,rIL,rIL")]) 7464 (match_operand:SI 1 "arm_rhs_operand" "0,rI,?rI") 7465 (match_operand:SI 2 "arm_rhs_operand" "rI,0,rI"))) 7466 (clobber (reg:CC CC_REGNUM))] 7467 "TARGET_ARM" 7468 "* 7469 if (GET_CODE (operands[5]) == LT 7470 && (operands[4] == const0_rtx)) 7471 { 7472 if (which_alternative != 1 && GET_CODE (operands[1]) == REG) 7473 { 7474 if (operands[2] == const0_rtx) 7475 return \"and\\t%0, %1, %3, asr #31\"; 7476 return \"ands\\t%0, %1, %3, asr #32\;movcc\\t%0, %2\"; 7477 } 7478 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG) 7479 { 7480 if (operands[1] == const0_rtx) 7481 return \"bic\\t%0, %2, %3, asr #31\"; 7482 return \"bics\\t%0, %2, %3, asr #32\;movcs\\t%0, %1\"; 7483 } 7484 /* The only case that falls through to here is when both ops 1 & 2 7485 are constants */ 7486 } 7487 7488 if (GET_CODE (operands[5]) == GE 7489 && (operands[4] == const0_rtx)) 7490 { 7491 if (which_alternative != 1 && GET_CODE (operands[1]) == REG) 7492 { 7493 if (operands[2] == const0_rtx) 7494 return \"bic\\t%0, %1, %3, asr #31\"; 7495 return \"bics\\t%0, %1, %3, asr #32\;movcs\\t%0, %2\"; 7496 } 7497 else if (which_alternative != 0 && GET_CODE (operands[2]) == REG) 7498 { 7499 if (operands[1] == const0_rtx) 7500 return \"and\\t%0, %2, %3, asr #31\"; 7501 return \"ands\\t%0, %2, %3, asr #32\;movcc\\t%0, %1\"; 7502 } 7503 /* The only case that falls through to here is when both ops 1 & 2 7504 are constants */ 7505 } 7506 if (GET_CODE (operands[4]) == CONST_INT 7507 && !const_ok_for_arm (INTVAL (operands[4]))) 7508 output_asm_insn (\"cmn\\t%3, #%n4\", operands); 7509 else 7510 output_asm_insn (\"cmp\\t%3, %4\", operands); 7511 if (which_alternative != 0) 7512 output_asm_insn (\"mov%d5\\t%0, %1\", operands); 7513 if (which_alternative != 1) 7514 output_asm_insn (\"mov%D5\\t%0, %2\", operands); 7515 return \"\"; 7516 " 7517 [(set_attr "conds" "clob") 7518 (set_attr "length" "8,8,12")] 7519) 7520 7521(define_insn "*ifcompare_plus_move" 7522 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7523 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 7524 [(match_operand:SI 4 "s_register_operand" "r,r") 7525 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 7526 (plus:SI 7527 (match_operand:SI 2 "s_register_operand" "r,r") 7528 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")) 7529 (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) 7530 (clobber (reg:CC CC_REGNUM))] 7531 "TARGET_ARM" 7532 "#" 7533 [(set_attr "conds" "clob") 7534 (set_attr "length" "8,12")] 7535) 7536 7537(define_insn "*if_plus_move" 7538 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") 7539 (if_then_else:SI 7540 (match_operator 4 "arm_comparison_operator" 7541 [(match_operand 5 "cc_register" "") (const_int 0)]) 7542 (plus:SI 7543 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 7544 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L")) 7545 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI")))] 7546 "TARGET_ARM" 7547 "@ 7548 add%d4\\t%0, %2, %3 7549 sub%d4\\t%0, %2, #%n3 7550 add%d4\\t%0, %2, %3\;mov%D4\\t%0, %1 7551 sub%d4\\t%0, %2, #%n3\;mov%D4\\t%0, %1" 7552 [(set_attr "conds" "use") 7553 (set_attr "length" "4,4,8,8") 7554 (set_attr "type" "*,*,*,*")] 7555) 7556 7557(define_insn "*ifcompare_move_plus" 7558 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7559 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 7560 [(match_operand:SI 4 "s_register_operand" "r,r") 7561 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 7562 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 7563 (plus:SI 7564 (match_operand:SI 2 "s_register_operand" "r,r") 7565 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")))) 7566 (clobber (reg:CC CC_REGNUM))] 7567 "TARGET_ARM" 7568 "#" 7569 [(set_attr "conds" "clob") 7570 (set_attr "length" "8,12")] 7571) 7572 7573(define_insn "*if_move_plus" 7574 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r,r") 7575 (if_then_else:SI 7576 (match_operator 4 "arm_comparison_operator" 7577 [(match_operand 5 "cc_register" "") (const_int 0)]) 7578 (match_operand:SI 1 "arm_rhs_operand" "0,0,?rI,?rI") 7579 (plus:SI 7580 (match_operand:SI 2 "s_register_operand" "r,r,r,r") 7581 (match_operand:SI 3 "arm_add_operand" "rI,L,rI,L"))))] 7582 "TARGET_ARM" 7583 "@ 7584 add%D4\\t%0, %2, %3 7585 sub%D4\\t%0, %2, #%n3 7586 add%D4\\t%0, %2, %3\;mov%d4\\t%0, %1 7587 sub%D4\\t%0, %2, #%n3\;mov%d4\\t%0, %1" 7588 [(set_attr "conds" "use") 7589 (set_attr "length" "4,4,8,8") 7590 (set_attr "type" "*,*,*,*")] 7591) 7592 7593(define_insn "*ifcompare_arith_arith" 7594 [(set (match_operand:SI 0 "s_register_operand" "=r") 7595 (if_then_else:SI (match_operator 9 "arm_comparison_operator" 7596 [(match_operand:SI 5 "s_register_operand" "r") 7597 (match_operand:SI 6 "arm_add_operand" "rIL")]) 7598 (match_operator:SI 8 "shiftable_operator" 7599 [(match_operand:SI 1 "s_register_operand" "r") 7600 (match_operand:SI 2 "arm_rhs_operand" "rI")]) 7601 (match_operator:SI 7 "shiftable_operator" 7602 [(match_operand:SI 3 "s_register_operand" "r") 7603 (match_operand:SI 4 "arm_rhs_operand" "rI")]))) 7604 (clobber (reg:CC CC_REGNUM))] 7605 "TARGET_ARM" 7606 "#" 7607 [(set_attr "conds" "clob") 7608 (set_attr "length" "12")] 7609) 7610 7611(define_insn "*if_arith_arith" 7612 [(set (match_operand:SI 0 "s_register_operand" "=r") 7613 (if_then_else:SI (match_operator 5 "arm_comparison_operator" 7614 [(match_operand 8 "cc_register" "") (const_int 0)]) 7615 (match_operator:SI 6 "shiftable_operator" 7616 [(match_operand:SI 1 "s_register_operand" "r") 7617 (match_operand:SI 2 "arm_rhs_operand" "rI")]) 7618 (match_operator:SI 7 "shiftable_operator" 7619 [(match_operand:SI 3 "s_register_operand" "r") 7620 (match_operand:SI 4 "arm_rhs_operand" "rI")])))] 7621 "TARGET_ARM" 7622 "%I6%d5\\t%0, %1, %2\;%I7%D5\\t%0, %3, %4" 7623 [(set_attr "conds" "use") 7624 (set_attr "length" "8")] 7625) 7626 7627(define_insn "*ifcompare_arith_move" 7628 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7629 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 7630 [(match_operand:SI 2 "s_register_operand" "r,r") 7631 (match_operand:SI 3 "arm_add_operand" "rIL,rIL")]) 7632 (match_operator:SI 7 "shiftable_operator" 7633 [(match_operand:SI 4 "s_register_operand" "r,r") 7634 (match_operand:SI 5 "arm_rhs_operand" "rI,rI")]) 7635 (match_operand:SI 1 "arm_rhs_operand" "0,?rI"))) 7636 (clobber (reg:CC CC_REGNUM))] 7637 "TARGET_ARM" 7638 "* 7639 /* If we have an operation where (op x 0) is the identity operation and 7640 the conditional operator is LT or GE and we are comparing against zero and 7641 everything is in registers then we can do this in two instructions */ 7642 if (operands[3] == const0_rtx 7643 && GET_CODE (operands[7]) != AND 7644 && GET_CODE (operands[5]) == REG 7645 && GET_CODE (operands[1]) == REG 7646 && REGNO (operands[1]) == REGNO (operands[4]) 7647 && REGNO (operands[4]) != REGNO (operands[0])) 7648 { 7649 if (GET_CODE (operands[6]) == LT) 7650 return \"and\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; 7651 else if (GET_CODE (operands[6]) == GE) 7652 return \"bic\\t%0, %5, %2, asr #31\;%I7\\t%0, %4, %0\"; 7653 } 7654 if (GET_CODE (operands[3]) == CONST_INT 7655 && !const_ok_for_arm (INTVAL (operands[3]))) 7656 output_asm_insn (\"cmn\\t%2, #%n3\", operands); 7657 else 7658 output_asm_insn (\"cmp\\t%2, %3\", operands); 7659 output_asm_insn (\"%I7%d6\\t%0, %4, %5\", operands); 7660 if (which_alternative != 0) 7661 return \"mov%D6\\t%0, %1\"; 7662 return \"\"; 7663 " 7664 [(set_attr "conds" "clob") 7665 (set_attr "length" "8,12")] 7666) 7667 7668(define_insn "*if_arith_move" 7669 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7670 (if_then_else:SI (match_operator 4 "arm_comparison_operator" 7671 [(match_operand 6 "cc_register" "") (const_int 0)]) 7672 (match_operator:SI 5 "shiftable_operator" 7673 [(match_operand:SI 2 "s_register_operand" "r,r") 7674 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]) 7675 (match_operand:SI 1 "arm_rhs_operand" "0,?rI")))] 7676 "TARGET_ARM" 7677 "@ 7678 %I5%d4\\t%0, %2, %3 7679 %I5%d4\\t%0, %2, %3\;mov%D4\\t%0, %1" 7680 [(set_attr "conds" "use") 7681 (set_attr "length" "4,8") 7682 (set_attr "type" "*,*")] 7683) 7684 7685(define_insn "*ifcompare_move_arith" 7686 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7687 (if_then_else:SI (match_operator 6 "arm_comparison_operator" 7688 [(match_operand:SI 4 "s_register_operand" "r,r") 7689 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 7690 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 7691 (match_operator:SI 7 "shiftable_operator" 7692 [(match_operand:SI 2 "s_register_operand" "r,r") 7693 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")]))) 7694 (clobber (reg:CC CC_REGNUM))] 7695 "TARGET_ARM" 7696 "* 7697 /* If we have an operation where (op x 0) is the identity operation and 7698 the conditional operator is LT or GE and we are comparing against zero and 7699 everything is in registers then we can do this in two instructions */ 7700 if (operands[5] == const0_rtx 7701 && GET_CODE (operands[7]) != AND 7702 && GET_CODE (operands[3]) == REG 7703 && GET_CODE (operands[1]) == REG 7704 && REGNO (operands[1]) == REGNO (operands[2]) 7705 && REGNO (operands[2]) != REGNO (operands[0])) 7706 { 7707 if (GET_CODE (operands[6]) == GE) 7708 return \"and\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; 7709 else if (GET_CODE (operands[6]) == LT) 7710 return \"bic\\t%0, %3, %4, asr #31\;%I7\\t%0, %2, %0\"; 7711 } 7712 7713 if (GET_CODE (operands[5]) == CONST_INT 7714 && !const_ok_for_arm (INTVAL (operands[5]))) 7715 output_asm_insn (\"cmn\\t%4, #%n5\", operands); 7716 else 7717 output_asm_insn (\"cmp\\t%4, %5\", operands); 7718 7719 if (which_alternative != 0) 7720 output_asm_insn (\"mov%d6\\t%0, %1\", operands); 7721 return \"%I7%D6\\t%0, %2, %3\"; 7722 " 7723 [(set_attr "conds" "clob") 7724 (set_attr "length" "8,12")] 7725) 7726 7727(define_insn "*if_move_arith" 7728 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7729 (if_then_else:SI 7730 (match_operator 4 "arm_comparison_operator" 7731 [(match_operand 6 "cc_register" "") (const_int 0)]) 7732 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 7733 (match_operator:SI 5 "shiftable_operator" 7734 [(match_operand:SI 2 "s_register_operand" "r,r") 7735 (match_operand:SI 3 "arm_rhs_operand" "rI,rI")])))] 7736 "TARGET_ARM" 7737 "@ 7738 %I5%D4\\t%0, %2, %3 7739 %I5%D4\\t%0, %2, %3\;mov%d4\\t%0, %1" 7740 [(set_attr "conds" "use") 7741 (set_attr "length" "4,8") 7742 (set_attr "type" "*,*")] 7743) 7744 7745(define_insn "*ifcompare_move_not" 7746 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7747 (if_then_else:SI 7748 (match_operator 5 "arm_comparison_operator" 7749 [(match_operand:SI 3 "s_register_operand" "r,r") 7750 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 7751 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 7752 (not:SI 7753 (match_operand:SI 2 "s_register_operand" "r,r")))) 7754 (clobber (reg:CC CC_REGNUM))] 7755 "TARGET_ARM" 7756 "#" 7757 [(set_attr "conds" "clob") 7758 (set_attr "length" "8,12")] 7759) 7760 7761(define_insn "*if_move_not" 7762 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 7763 (if_then_else:SI 7764 (match_operator 4 "arm_comparison_operator" 7765 [(match_operand 3 "cc_register" "") (const_int 0)]) 7766 (match_operand:SI 1 "arm_not_operand" "0,?rI,K") 7767 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))] 7768 "TARGET_ARM" 7769 "@ 7770 mvn%D4\\t%0, %2 7771 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2 7772 mvn%d4\\t%0, #%B1\;mvn%D4\\t%0, %2" 7773 [(set_attr "conds" "use") 7774 (set_attr "length" "4,8,8")] 7775) 7776 7777(define_insn "*ifcompare_not_move" 7778 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7779 (if_then_else:SI 7780 (match_operator 5 "arm_comparison_operator" 7781 [(match_operand:SI 3 "s_register_operand" "r,r") 7782 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 7783 (not:SI 7784 (match_operand:SI 2 "s_register_operand" "r,r")) 7785 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 7786 (clobber (reg:CC CC_REGNUM))] 7787 "TARGET_ARM" 7788 "#" 7789 [(set_attr "conds" "clob") 7790 (set_attr "length" "8,12")] 7791) 7792 7793(define_insn "*if_not_move" 7794 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 7795 (if_then_else:SI 7796 (match_operator 4 "arm_comparison_operator" 7797 [(match_operand 3 "cc_register" "") (const_int 0)]) 7798 (not:SI (match_operand:SI 2 "s_register_operand" "r,r,r")) 7799 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] 7800 "TARGET_ARM" 7801 "@ 7802 mvn%d4\\t%0, %2 7803 mov%D4\\t%0, %1\;mvn%d4\\t%0, %2 7804 mvn%D4\\t%0, #%B1\;mvn%d4\\t%0, %2" 7805 [(set_attr "conds" "use") 7806 (set_attr "length" "4,8,8")] 7807) 7808 7809(define_insn "*ifcompare_shift_move" 7810 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7811 (if_then_else:SI 7812 (match_operator 6 "arm_comparison_operator" 7813 [(match_operand:SI 4 "s_register_operand" "r,r") 7814 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 7815 (match_operator:SI 7 "shift_operator" 7816 [(match_operand:SI 2 "s_register_operand" "r,r") 7817 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]) 7818 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 7819 (clobber (reg:CC CC_REGNUM))] 7820 "TARGET_ARM" 7821 "#" 7822 [(set_attr "conds" "clob") 7823 (set_attr "length" "8,12")] 7824) 7825 7826(define_insn "*if_shift_move" 7827 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 7828 (if_then_else:SI 7829 (match_operator 5 "arm_comparison_operator" 7830 [(match_operand 6 "cc_register" "") (const_int 0)]) 7831 (match_operator:SI 4 "shift_operator" 7832 [(match_operand:SI 2 "s_register_operand" "r,r,r") 7833 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")]) 7834 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] 7835 "TARGET_ARM" 7836 "@ 7837 mov%d5\\t%0, %2%S4 7838 mov%D5\\t%0, %1\;mov%d5\\t%0, %2%S4 7839 mvn%D5\\t%0, #%B1\;mov%d5\\t%0, %2%S4" 7840 [(set_attr "conds" "use") 7841 (set_attr "shift" "2") 7842 (set_attr "length" "4,8,8")] 7843) 7844 7845(define_insn "*ifcompare_move_shift" 7846 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7847 (if_then_else:SI 7848 (match_operator 6 "arm_comparison_operator" 7849 [(match_operand:SI 4 "s_register_operand" "r,r") 7850 (match_operand:SI 5 "arm_add_operand" "rIL,rIL")]) 7851 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 7852 (match_operator:SI 7 "shift_operator" 7853 [(match_operand:SI 2 "s_register_operand" "r,r") 7854 (match_operand:SI 3 "arm_rhs_operand" "rM,rM")]))) 7855 (clobber (reg:CC CC_REGNUM))] 7856 "TARGET_ARM" 7857 "#" 7858 [(set_attr "conds" "clob") 7859 (set_attr "length" "8,12")] 7860) 7861 7862(define_insn "*if_move_shift" 7863 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 7864 (if_then_else:SI 7865 (match_operator 5 "arm_comparison_operator" 7866 [(match_operand 6 "cc_register" "") (const_int 0)]) 7867 (match_operand:SI 1 "arm_not_operand" "0,?rI,K") 7868 (match_operator:SI 4 "shift_operator" 7869 [(match_operand:SI 2 "s_register_operand" "r,r,r") 7870 (match_operand:SI 3 "arm_rhs_operand" "rM,rM,rM")])))] 7871 "TARGET_ARM" 7872 "@ 7873 mov%D5\\t%0, %2%S4 7874 mov%d5\\t%0, %1\;mov%D5\\t%0, %2%S4 7875 mvn%d5\\t%0, #%B1\;mov%D5\\t%0, %2%S4" 7876 [(set_attr "conds" "use") 7877 (set_attr "shift" "2") 7878 (set_attr "length" "4,8,8")] 7879) 7880 7881(define_insn "*ifcompare_shift_shift" 7882 [(set (match_operand:SI 0 "s_register_operand" "=r") 7883 (if_then_else:SI 7884 (match_operator 7 "arm_comparison_operator" 7885 [(match_operand:SI 5 "s_register_operand" "r") 7886 (match_operand:SI 6 "arm_add_operand" "rIL")]) 7887 (match_operator:SI 8 "shift_operator" 7888 [(match_operand:SI 1 "s_register_operand" "r") 7889 (match_operand:SI 2 "arm_rhs_operand" "rM")]) 7890 (match_operator:SI 9 "shift_operator" 7891 [(match_operand:SI 3 "s_register_operand" "r") 7892 (match_operand:SI 4 "arm_rhs_operand" "rM")]))) 7893 (clobber (reg:CC CC_REGNUM))] 7894 "TARGET_ARM" 7895 "#" 7896 [(set_attr "conds" "clob") 7897 (set_attr "length" "12")] 7898) 7899 7900(define_insn "*if_shift_shift" 7901 [(set (match_operand:SI 0 "s_register_operand" "=r") 7902 (if_then_else:SI 7903 (match_operator 5 "arm_comparison_operator" 7904 [(match_operand 8 "cc_register" "") (const_int 0)]) 7905 (match_operator:SI 6 "shift_operator" 7906 [(match_operand:SI 1 "s_register_operand" "r") 7907 (match_operand:SI 2 "arm_rhs_operand" "rM")]) 7908 (match_operator:SI 7 "shift_operator" 7909 [(match_operand:SI 3 "s_register_operand" "r") 7910 (match_operand:SI 4 "arm_rhs_operand" "rM")])))] 7911 "TARGET_ARM" 7912 "mov%d5\\t%0, %1%S6\;mov%D5\\t%0, %3%S7" 7913 [(set_attr "conds" "use") 7914 (set_attr "shift" "1") 7915 (set_attr "length" "8")] 7916) 7917 7918(define_insn "*ifcompare_not_arith" 7919 [(set (match_operand:SI 0 "s_register_operand" "=r") 7920 (if_then_else:SI 7921 (match_operator 6 "arm_comparison_operator" 7922 [(match_operand:SI 4 "s_register_operand" "r") 7923 (match_operand:SI 5 "arm_add_operand" "rIL")]) 7924 (not:SI (match_operand:SI 1 "s_register_operand" "r")) 7925 (match_operator:SI 7 "shiftable_operator" 7926 [(match_operand:SI 2 "s_register_operand" "r") 7927 (match_operand:SI 3 "arm_rhs_operand" "rI")]))) 7928 (clobber (reg:CC CC_REGNUM))] 7929 "TARGET_ARM" 7930 "#" 7931 [(set_attr "conds" "clob") 7932 (set_attr "length" "12")] 7933) 7934 7935(define_insn "*if_not_arith" 7936 [(set (match_operand:SI 0 "s_register_operand" "=r") 7937 (if_then_else:SI 7938 (match_operator 5 "arm_comparison_operator" 7939 [(match_operand 4 "cc_register" "") (const_int 0)]) 7940 (not:SI (match_operand:SI 1 "s_register_operand" "r")) 7941 (match_operator:SI 6 "shiftable_operator" 7942 [(match_operand:SI 2 "s_register_operand" "r") 7943 (match_operand:SI 3 "arm_rhs_operand" "rI")])))] 7944 "TARGET_ARM" 7945 "mvn%d5\\t%0, %1\;%I6%D5\\t%0, %2, %3" 7946 [(set_attr "conds" "use") 7947 (set_attr "length" "8")] 7948) 7949 7950(define_insn "*ifcompare_arith_not" 7951 [(set (match_operand:SI 0 "s_register_operand" "=r") 7952 (if_then_else:SI 7953 (match_operator 6 "arm_comparison_operator" 7954 [(match_operand:SI 4 "s_register_operand" "r") 7955 (match_operand:SI 5 "arm_add_operand" "rIL")]) 7956 (match_operator:SI 7 "shiftable_operator" 7957 [(match_operand:SI 2 "s_register_operand" "r") 7958 (match_operand:SI 3 "arm_rhs_operand" "rI")]) 7959 (not:SI (match_operand:SI 1 "s_register_operand" "r")))) 7960 (clobber (reg:CC CC_REGNUM))] 7961 "TARGET_ARM" 7962 "#" 7963 [(set_attr "conds" "clob") 7964 (set_attr "length" "12")] 7965) 7966 7967(define_insn "*if_arith_not" 7968 [(set (match_operand:SI 0 "s_register_operand" "=r") 7969 (if_then_else:SI 7970 (match_operator 5 "arm_comparison_operator" 7971 [(match_operand 4 "cc_register" "") (const_int 0)]) 7972 (match_operator:SI 6 "shiftable_operator" 7973 [(match_operand:SI 2 "s_register_operand" "r") 7974 (match_operand:SI 3 "arm_rhs_operand" "rI")]) 7975 (not:SI (match_operand:SI 1 "s_register_operand" "r"))))] 7976 "TARGET_ARM" 7977 "mvn%D5\\t%0, %1\;%I6%d5\\t%0, %2, %3" 7978 [(set_attr "conds" "use") 7979 (set_attr "length" "8")] 7980) 7981 7982(define_insn "*ifcompare_neg_move" 7983 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 7984 (if_then_else:SI 7985 (match_operator 5 "arm_comparison_operator" 7986 [(match_operand:SI 3 "s_register_operand" "r,r") 7987 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 7988 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")) 7989 (match_operand:SI 1 "arm_not_operand" "0,?rIK"))) 7990 (clobber (reg:CC CC_REGNUM))] 7991 "TARGET_ARM" 7992 "#" 7993 [(set_attr "conds" "clob") 7994 (set_attr "length" "8,12")] 7995) 7996 7997(define_insn "*if_neg_move" 7998 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 7999 (if_then_else:SI 8000 (match_operator 4 "arm_comparison_operator" 8001 [(match_operand 3 "cc_register" "") (const_int 0)]) 8002 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r")) 8003 (match_operand:SI 1 "arm_not_operand" "0,?rI,K")))] 8004 "TARGET_ARM" 8005 "@ 8006 rsb%d4\\t%0, %2, #0 8007 mov%D4\\t%0, %1\;rsb%d4\\t%0, %2, #0 8008 mvn%D4\\t%0, #%B1\;rsb%d4\\t%0, %2, #0" 8009 [(set_attr "conds" "use") 8010 (set_attr "length" "4,8,8")] 8011) 8012 8013(define_insn "*ifcompare_move_neg" 8014 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 8015 (if_then_else:SI 8016 (match_operator 5 "arm_comparison_operator" 8017 [(match_operand:SI 3 "s_register_operand" "r,r") 8018 (match_operand:SI 4 "arm_add_operand" "rIL,rIL")]) 8019 (match_operand:SI 1 "arm_not_operand" "0,?rIK") 8020 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r")))) 8021 (clobber (reg:CC CC_REGNUM))] 8022 "TARGET_ARM" 8023 "#" 8024 [(set_attr "conds" "clob") 8025 (set_attr "length" "8,12")] 8026) 8027 8028(define_insn "*if_move_neg" 8029 [(set (match_operand:SI 0 "s_register_operand" "=r,r,r") 8030 (if_then_else:SI 8031 (match_operator 4 "arm_comparison_operator" 8032 [(match_operand 3 "cc_register" "") (const_int 0)]) 8033 (match_operand:SI 1 "arm_not_operand" "0,?rI,K") 8034 (neg:SI (match_operand:SI 2 "s_register_operand" "r,r,r"))))] 8035 "TARGET_ARM" 8036 "@ 8037 rsb%D4\\t%0, %2, #0 8038 mov%d4\\t%0, %1\;rsb%D4\\t%0, %2, #0 8039 mvn%d4\\t%0, #%B1\;rsb%D4\\t%0, %2, #0" 8040 [(set_attr "conds" "use") 8041 (set_attr "length" "4,8,8")] 8042) 8043 8044(define_insn "*arith_adjacentmem" 8045 [(set (match_operand:SI 0 "s_register_operand" "=r") 8046 (match_operator:SI 1 "shiftable_operator" 8047 [(match_operand:SI 2 "memory_operand" "m") 8048 (match_operand:SI 3 "memory_operand" "m")])) 8049 (clobber (match_scratch:SI 4 "=r"))] 8050 "TARGET_ARM && adjacent_mem_locations (operands[2], operands[3])" 8051 "* 8052 { 8053 rtx ldm[3]; 8054 rtx arith[4]; 8055 int val1 = 0, val2 = 0; 8056 8057 if (REGNO (operands[0]) > REGNO (operands[4])) 8058 { 8059 ldm[1] = operands[4]; 8060 ldm[2] = operands[0]; 8061 } 8062 else 8063 { 8064 ldm[1] = operands[0]; 8065 ldm[2] = operands[4]; 8066 } 8067 if (GET_CODE (XEXP (operands[2], 0)) != REG) 8068 val1 = INTVAL (XEXP (XEXP (operands[2], 0), 1)); 8069 if (GET_CODE (XEXP (operands[3], 0)) != REG) 8070 val2 = INTVAL (XEXP (XEXP (operands[3], 0), 1)); 8071 arith[0] = operands[0]; 8072 arith[3] = operands[1]; 8073 if (val1 < val2) 8074 { 8075 arith[1] = ldm[1]; 8076 arith[2] = ldm[2]; 8077 } 8078 else 8079 { 8080 arith[1] = ldm[2]; 8081 arith[2] = ldm[1]; 8082 } 8083 if (val1 && val2) 8084 { 8085 rtx ops[3]; 8086 ldm[0] = ops[0] = operands[4]; 8087 ops[1] = XEXP (XEXP (operands[2], 0), 0); 8088 ops[2] = XEXP (XEXP (operands[2], 0), 1); 8089 output_add_immediate (ops); 8090 if (val1 < val2) 8091 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); 8092 else 8093 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); 8094 } 8095 else if (val1) 8096 { 8097 ldm[0] = XEXP (operands[3], 0); 8098 if (val1 < val2) 8099 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); 8100 else 8101 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); 8102 } 8103 else 8104 { 8105 ldm[0] = XEXP (operands[2], 0); 8106 if (val1 < val2) 8107 output_asm_insn (\"ldm%?ia\\t%0, {%1, %2}\", ldm); 8108 else 8109 output_asm_insn (\"ldm%?da\\t%0, {%1, %2}\", ldm); 8110 } 8111 output_asm_insn (\"%I3%?\\t%0, %1, %2\", arith); 8112 return \"\"; 8113 }" 8114 [(set_attr "length" "12") 8115 (set_attr "predicable" "yes") 8116 (set_attr "type" "load")] 8117) 8118 8119;; the arm can support extended pre-inc instructions 8120 8121;; In all these cases, we use operands 0 and 1 for the register being 8122;; incremented because those are the operands that local-alloc will 8123;; tie and these are the pair most likely to be tieable (and the ones 8124;; that will benefit the most). 8125 8126;; We reject the frame pointer if it occurs anywhere in these patterns since 8127;; elimination will cause too many headaches. 8128 8129(define_insn "*strqi_preinc" 8130 [(set (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") 8131 (match_operand:SI 2 "index_operand" "rJ"))) 8132 (match_operand:QI 3 "s_register_operand" "r")) 8133 (set (match_operand:SI 0 "s_register_operand" "=r") 8134 (plus:SI (match_dup 1) (match_dup 2)))] 8135 "TARGET_ARM 8136 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8137 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8138 && (GET_CODE (operands[2]) != REG 8139 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8140 "str%?b\\t%3, [%0, %2]!" 8141 [(set_attr "type" "store1") 8142 (set_attr "predicable" "yes")] 8143) 8144 8145(define_insn "*strqi_predec" 8146 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8147 (match_operand:SI 2 "s_register_operand" "r"))) 8148 (match_operand:QI 3 "s_register_operand" "r")) 8149 (set (match_operand:SI 0 "s_register_operand" "=r") 8150 (minus:SI (match_dup 1) (match_dup 2)))] 8151 "TARGET_ARM 8152 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8153 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8154 && (GET_CODE (operands[2]) != REG 8155 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8156 "str%?b\\t%3, [%0, -%2]!" 8157 [(set_attr "type" "store1") 8158 (set_attr "predicable" "yes")] 8159) 8160 8161(define_insn "*loadqi_preinc" 8162 [(set (match_operand:QI 3 "s_register_operand" "=r") 8163 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") 8164 (match_operand:SI 2 "index_operand" "rJ")))) 8165 (set (match_operand:SI 0 "s_register_operand" "=r") 8166 (plus:SI (match_dup 1) (match_dup 2)))] 8167 "TARGET_ARM 8168 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8169 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8170 && (GET_CODE (operands[2]) != REG 8171 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8172 "ldr%?b\\t%3, [%0, %2]!" 8173 [(set_attr "type" "load") 8174 (set_attr "predicable" "yes")] 8175) 8176 8177(define_insn "*loadqi_predec" 8178 [(set (match_operand:QI 3 "s_register_operand" "=r") 8179 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8180 (match_operand:SI 2 "s_register_operand" "r")))) 8181 (set (match_operand:SI 0 "s_register_operand" "=r") 8182 (minus:SI (match_dup 1) (match_dup 2)))] 8183 "TARGET_ARM 8184 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8185 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8186 && (GET_CODE (operands[2]) != REG 8187 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8188 "ldr%?b\\t%3, [%0, -%2]!" 8189 [(set_attr "type" "load") 8190 (set_attr "predicable" "yes")] 8191) 8192 8193(define_insn "*loadqisi_preinc" 8194 [(set (match_operand:SI 3 "s_register_operand" "=r") 8195 (zero_extend:SI 8196 (mem:QI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") 8197 (match_operand:SI 2 "index_operand" "rJ"))))) 8198 (set (match_operand:SI 0 "s_register_operand" "=r") 8199 (plus:SI (match_dup 1) (match_dup 2)))] 8200 "TARGET_ARM 8201 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8202 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8203 && (GET_CODE (operands[2]) != REG 8204 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8205 "ldr%?b\\t%3, [%0, %2]!\\t%@ z_extendqisi" 8206 [(set_attr "type" "load") 8207 (set_attr "predicable" "yes")] 8208) 8209 8210(define_insn "*loadqisi_predec" 8211 [(set (match_operand:SI 3 "s_register_operand" "=r") 8212 (zero_extend:SI 8213 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8214 (match_operand:SI 2 "s_register_operand" "r"))))) 8215 (set (match_operand:SI 0 "s_register_operand" "=r") 8216 (minus:SI (match_dup 1) (match_dup 2)))] 8217 "TARGET_ARM 8218 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8219 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8220 && (GET_CODE (operands[2]) != REG 8221 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8222 "ldr%?b\\t%3, [%0, -%2]!\\t%@ z_extendqisi" 8223 [(set_attr "type" "load") 8224 (set_attr "predicable" "yes")] 8225) 8226 8227(define_insn "*strsi_preinc" 8228 [(set (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") 8229 (match_operand:SI 2 "index_operand" "rJ"))) 8230 (match_operand:SI 3 "s_register_operand" "r")) 8231 (set (match_operand:SI 0 "s_register_operand" "=r") 8232 (plus:SI (match_dup 1) (match_dup 2)))] 8233 "TARGET_ARM 8234 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8235 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8236 && (GET_CODE (operands[2]) != REG 8237 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8238 "str%?\\t%3, [%0, %2]!" 8239 [(set_attr "type" "store1") 8240 (set_attr "predicable" "yes")] 8241) 8242 8243(define_insn "*strsi_predec" 8244 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8245 (match_operand:SI 2 "s_register_operand" "r"))) 8246 (match_operand:SI 3 "s_register_operand" "r")) 8247 (set (match_operand:SI 0 "s_register_operand" "=r") 8248 (minus:SI (match_dup 1) (match_dup 2)))] 8249 "TARGET_ARM 8250 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8251 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8252 && (GET_CODE (operands[2]) != REG 8253 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8254 "str%?\\t%3, [%0, -%2]!" 8255 [(set_attr "type" "store1") 8256 (set_attr "predicable" "yes")] 8257) 8258 8259(define_insn "*loadsi_preinc" 8260 [(set (match_operand:SI 3 "s_register_operand" "=r") 8261 (mem:SI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") 8262 (match_operand:SI 2 "index_operand" "rJ")))) 8263 (set (match_operand:SI 0 "s_register_operand" "=r") 8264 (plus:SI (match_dup 1) (match_dup 2)))] 8265 "TARGET_ARM 8266 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8267 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8268 && (GET_CODE (operands[2]) != REG 8269 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8270 "ldr%?\\t%3, [%0, %2]!" 8271 [(set_attr "type" "load") 8272 (set_attr "predicable" "yes")] 8273) 8274 8275(define_insn "*loadsi_predec" 8276 [(set (match_operand:SI 3 "s_register_operand" "=r") 8277 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8278 (match_operand:SI 2 "s_register_operand" "r")))) 8279 (set (match_operand:SI 0 "s_register_operand" "=r") 8280 (minus:SI (match_dup 1) (match_dup 2)))] 8281 "TARGET_ARM 8282 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8283 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8284 && (GET_CODE (operands[2]) != REG 8285 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8286 "ldr%?\\t%3, [%0, -%2]!" 8287 [(set_attr "type" "load") 8288 (set_attr "predicable" "yes")] 8289) 8290 8291(define_insn "*loadhi_preinc" 8292 [(set (match_operand:HI 3 "s_register_operand" "=r") 8293 (mem:HI (plus:SI (match_operand:SI 1 "s_register_operand" "%0") 8294 (match_operand:SI 2 "index_operand" "rJ")))) 8295 (set (match_operand:SI 0 "s_register_operand" "=r") 8296 (plus:SI (match_dup 1) (match_dup 2)))] 8297 "TARGET_ARM 8298 && !BYTES_BIG_ENDIAN 8299 && !TARGET_MMU_TRAPS 8300 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8301 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8302 && (GET_CODE (operands[2]) != REG 8303 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8304 "ldr%?\\t%3, [%0, %2]!\\t%@ loadhi" 8305 [(set_attr "type" "load") 8306 (set_attr "predicable" "yes")] 8307) 8308 8309(define_insn "*loadhi_predec" 8310 [(set (match_operand:HI 3 "s_register_operand" "=r") 8311 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8312 (match_operand:SI 2 "s_register_operand" "r")))) 8313 (set (match_operand:SI 0 "s_register_operand" "=r") 8314 (minus:SI (match_dup 1) (match_dup 2)))] 8315 "TARGET_ARM 8316 && !BYTES_BIG_ENDIAN 8317 && !TARGET_MMU_TRAPS 8318 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8319 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8320 && (GET_CODE (operands[2]) != REG 8321 || REGNO (operands[2]) != FRAME_POINTER_REGNUM)" 8322 "ldr%?\\t%3, [%0, -%2]!\\t%@ loadhi" 8323 [(set_attr "type" "load") 8324 (set_attr "predicable" "yes")] 8325) 8326 8327(define_insn "*strqi_shiftpreinc" 8328 [(set (mem:QI (plus:SI (match_operator:SI 2 "shift_operator" 8329 [(match_operand:SI 3 "s_register_operand" "r") 8330 (match_operand:SI 4 "const_shift_operand" "n")]) 8331 (match_operand:SI 1 "s_register_operand" "0"))) 8332 (match_operand:QI 5 "s_register_operand" "r")) 8333 (set (match_operand:SI 0 "s_register_operand" "=r") 8334 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) 8335 (match_dup 1)))] 8336 "TARGET_ARM 8337 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8338 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8339 && REGNO (operands[3]) != FRAME_POINTER_REGNUM" 8340 "str%?b\\t%5, [%0, %3%S2]!" 8341 [(set_attr "type" "store1") 8342 (set_attr "predicable" "yes")] 8343) 8344 8345(define_insn "*strqi_shiftpredec" 8346 [(set (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8347 (match_operator:SI 2 "shift_operator" 8348 [(match_operand:SI 3 "s_register_operand" "r") 8349 (match_operand:SI 4 "const_shift_operand" "n")]))) 8350 (match_operand:QI 5 "s_register_operand" "r")) 8351 (set (match_operand:SI 0 "s_register_operand" "=r") 8352 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) 8353 (match_dup 4)])))] 8354 "TARGET_ARM 8355 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8356 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8357 && REGNO (operands[3]) != FRAME_POINTER_REGNUM" 8358 "str%?b\\t%5, [%0, -%3%S2]!" 8359 [(set_attr "type" "store1") 8360 (set_attr "predicable" "yes")] 8361) 8362 8363(define_insn "*loadqi_shiftpreinc" 8364 [(set (match_operand:QI 5 "s_register_operand" "=r") 8365 (mem:QI (plus:SI (match_operator:SI 2 "shift_operator" 8366 [(match_operand:SI 3 "s_register_operand" "r") 8367 (match_operand:SI 4 "const_shift_operand" "n")]) 8368 (match_operand:SI 1 "s_register_operand" "0")))) 8369 (set (match_operand:SI 0 "s_register_operand" "=r") 8370 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) 8371 (match_dup 1)))] 8372 "TARGET_ARM 8373 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8374 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8375 && REGNO (operands[3]) != FRAME_POINTER_REGNUM" 8376 "ldr%?b\\t%5, [%0, %3%S2]!" 8377 [(set_attr "type" "load") 8378 (set_attr "predicable" "yes")] 8379) 8380 8381(define_insn "*loadqi_shiftpredec" 8382 [(set (match_operand:QI 5 "s_register_operand" "=r") 8383 (mem:QI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8384 (match_operator:SI 2 "shift_operator" 8385 [(match_operand:SI 3 "s_register_operand" "r") 8386 (match_operand:SI 4 "const_shift_operand" "n")])))) 8387 (set (match_operand:SI 0 "s_register_operand" "=r") 8388 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) 8389 (match_dup 4)])))] 8390 "TARGET_ARM 8391 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8392 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8393 && REGNO (operands[3]) != FRAME_POINTER_REGNUM" 8394 "ldr%?b\\t%5, [%0, -%3%S2]!" 8395 [(set_attr "type" "load") 8396 (set_attr "predicable" "yes")] 8397) 8398 8399(define_insn "*strsi_shiftpreinc" 8400 [(set (mem:SI (plus:SI (match_operator:SI 2 "shift_operator" 8401 [(match_operand:SI 3 "s_register_operand" "r") 8402 (match_operand:SI 4 "const_shift_operand" "n")]) 8403 (match_operand:SI 1 "s_register_operand" "0"))) 8404 (match_operand:SI 5 "s_register_operand" "r")) 8405 (set (match_operand:SI 0 "s_register_operand" "=r") 8406 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) 8407 (match_dup 1)))] 8408 "TARGET_ARM 8409 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8410 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8411 && REGNO (operands[3]) != FRAME_POINTER_REGNUM" 8412 "str%?\\t%5, [%0, %3%S2]!" 8413 [(set_attr "type" "store1") 8414 (set_attr "predicable" "yes")] 8415) 8416 8417(define_insn "*strsi_shiftpredec" 8418 [(set (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8419 (match_operator:SI 2 "shift_operator" 8420 [(match_operand:SI 3 "s_register_operand" "r") 8421 (match_operand:SI 4 "const_shift_operand" "n")]))) 8422 (match_operand:SI 5 "s_register_operand" "r")) 8423 (set (match_operand:SI 0 "s_register_operand" "=r") 8424 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) 8425 (match_dup 4)])))] 8426 "TARGET_ARM 8427 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8428 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8429 && REGNO (operands[3]) != FRAME_POINTER_REGNUM" 8430 "str%?\\t%5, [%0, -%3%S2]!" 8431 [(set_attr "type" "store1") 8432 (set_attr "predicable" "yes")] 8433) 8434 8435(define_insn "*loadsi_shiftpreinc" 8436 [(set (match_operand:SI 5 "s_register_operand" "=r") 8437 (mem:SI (plus:SI (match_operator:SI 2 "shift_operator" 8438 [(match_operand:SI 3 "s_register_operand" "r") 8439 (match_operand:SI 4 "const_shift_operand" "n")]) 8440 (match_operand:SI 1 "s_register_operand" "0")))) 8441 (set (match_operand:SI 0 "s_register_operand" "=r") 8442 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) 8443 (match_dup 1)))] 8444 "TARGET_ARM 8445 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8446 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8447 && REGNO (operands[3]) != FRAME_POINTER_REGNUM" 8448 "ldr%?\\t%5, [%0, %3%S2]!" 8449 [(set_attr "type" "load") 8450 (set_attr "predicable" "yes")] 8451) 8452 8453(define_insn "*loadsi_shiftpredec" 8454 [(set (match_operand:SI 5 "s_register_operand" "=r") 8455 (mem:SI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8456 (match_operator:SI 2 "shift_operator" 8457 [(match_operand:SI 3 "s_register_operand" "r") 8458 (match_operand:SI 4 "const_shift_operand" "n")])))) 8459 (set (match_operand:SI 0 "s_register_operand" "=r") 8460 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) 8461 (match_dup 4)])))] 8462 "TARGET_ARM 8463 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8464 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8465 && REGNO (operands[3]) != FRAME_POINTER_REGNUM" 8466 "ldr%?\\t%5, [%0, -%3%S2]!" 8467 [(set_attr "type" "load") 8468 (set_attr "predicable" "yes")]) 8469 8470(define_insn "*loadhi_shiftpreinc" 8471 [(set (match_operand:HI 5 "s_register_operand" "=r") 8472 (mem:HI (plus:SI (match_operator:SI 2 "shift_operator" 8473 [(match_operand:SI 3 "s_register_operand" "r") 8474 (match_operand:SI 4 "const_shift_operand" "n")]) 8475 (match_operand:SI 1 "s_register_operand" "0")))) 8476 (set (match_operand:SI 0 "s_register_operand" "=r") 8477 (plus:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) 8478 (match_dup 1)))] 8479 "TARGET_ARM 8480 && !BYTES_BIG_ENDIAN 8481 && !TARGET_MMU_TRAPS 8482 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8483 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8484 && REGNO (operands[3]) != FRAME_POINTER_REGNUM" 8485 "ldr%?\\t%5, [%0, %3%S2]!\\t%@ loadhi" 8486 [(set_attr "type" "load") 8487 (set_attr "predicable" "yes")] 8488) 8489 8490(define_insn "*loadhi_shiftpredec" 8491 [(set (match_operand:HI 5 "s_register_operand" "=r") 8492 (mem:HI (minus:SI (match_operand:SI 1 "s_register_operand" "0") 8493 (match_operator:SI 2 "shift_operator" 8494 [(match_operand:SI 3 "s_register_operand" "r") 8495 (match_operand:SI 4 "const_shift_operand" "n")])))) 8496 (set (match_operand:SI 0 "s_register_operand" "=r") 8497 (minus:SI (match_dup 1) (match_op_dup 2 [(match_dup 3) 8498 (match_dup 4)])))] 8499 "TARGET_ARM 8500 && !BYTES_BIG_ENDIAN 8501 && !TARGET_MMU_TRAPS 8502 && REGNO (operands[0]) != FRAME_POINTER_REGNUM 8503 && REGNO (operands[1]) != FRAME_POINTER_REGNUM 8504 && REGNO (operands[3]) != FRAME_POINTER_REGNUM" 8505 "ldr%?\\t%5, [%0, -%3%S2]!\\t%@ loadhi" 8506 [(set_attr "type" "load") 8507 (set_attr "predicable" "yes")] 8508) 8509 8510; It can also support extended post-inc expressions, but combine doesn't 8511; try these.... 8512; It doesn't seem worth adding peepholes for anything but the most common 8513; cases since, unlike combine, the increment must immediately follow the load 8514; for this pattern to match. 8515; We must watch to see that the source/destination register isn't also the 8516; same as the base address register, and that if the index is a register, 8517; that it is not the same as the base address register. In such cases the 8518; instruction that we would generate would have UNPREDICTABLE behaviour so 8519; we cannot use it. 8520 8521(define_peephole 8522 [(set (mem:QI (match_operand:SI 0 "s_register_operand" "+r")) 8523 (match_operand:QI 2 "s_register_operand" "r")) 8524 (set (match_dup 0) 8525 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))] 8526 "TARGET_ARM 8527 && (REGNO (operands[2]) != REGNO (operands[0])) 8528 && (GET_CODE (operands[1]) != REG 8529 || (REGNO (operands[1]) != REGNO (operands[0])))" 8530 "str%?b\\t%2, [%0], %1" 8531) 8532 8533(define_peephole 8534 [(set (match_operand:QI 0 "s_register_operand" "=r") 8535 (mem:QI (match_operand:SI 1 "s_register_operand" "+r"))) 8536 (set (match_dup 1) 8537 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))] 8538 "TARGET_ARM 8539 && REGNO (operands[0]) != REGNO(operands[1]) 8540 && (GET_CODE (operands[2]) != REG 8541 || REGNO(operands[0]) != REGNO (operands[2]))" 8542 "ldr%?b\\t%0, [%1], %2" 8543) 8544 8545(define_peephole 8546 [(set (mem:SI (match_operand:SI 0 "s_register_operand" "+r")) 8547 (match_operand:SI 2 "s_register_operand" "r")) 8548 (set (match_dup 0) 8549 (plus:SI (match_dup 0) (match_operand:SI 1 "index_operand" "rJ")))] 8550 "TARGET_ARM 8551 && (REGNO (operands[2]) != REGNO (operands[0])) 8552 && (GET_CODE (operands[1]) != REG 8553 || (REGNO (operands[1]) != REGNO (operands[0])))" 8554 "str%?\\t%2, [%0], %1" 8555) 8556 8557(define_peephole 8558 [(set (match_operand:HI 0 "s_register_operand" "=r") 8559 (mem:HI (match_operand:SI 1 "s_register_operand" "+r"))) 8560 (set (match_dup 1) 8561 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))] 8562 "TARGET_ARM 8563 && !BYTES_BIG_ENDIAN 8564 && !TARGET_MMU_TRAPS 8565 && REGNO (operands[0]) != REGNO(operands[1]) 8566 && (GET_CODE (operands[2]) != REG 8567 || REGNO(operands[0]) != REGNO (operands[2]))" 8568 "ldr%?\\t%0, [%1], %2\\t%@ loadhi" 8569) 8570 8571(define_peephole 8572 [(set (match_operand:SI 0 "s_register_operand" "=r") 8573 (mem:SI (match_operand:SI 1 "s_register_operand" "+r"))) 8574 (set (match_dup 1) 8575 (plus:SI (match_dup 1) (match_operand:SI 2 "index_operand" "rJ")))] 8576 "TARGET_ARM 8577 && REGNO (operands[0]) != REGNO(operands[1]) 8578 && (GET_CODE (operands[2]) != REG 8579 || REGNO(operands[0]) != REGNO (operands[2]))" 8580 "ldr%?\\t%0, [%1], %2" 8581) 8582 8583(define_peephole 8584 [(set (mem:QI (plus:SI (match_operand:SI 0 "s_register_operand" "+r") 8585 (match_operand:SI 1 "index_operand" "rJ"))) 8586 (match_operand:QI 2 "s_register_operand" "r")) 8587 (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))] 8588 "TARGET_ARM 8589 && (REGNO (operands[2]) != REGNO (operands[0])) 8590 && (GET_CODE (operands[1]) != REG 8591 || (REGNO (operands[1]) != REGNO (operands[0])))" 8592 "str%?b\\t%2, [%0, %1]!" 8593) 8594 8595(define_peephole 8596 [(set (mem:QI (plus:SI (match_operator:SI 4 "shift_operator" 8597 [(match_operand:SI 0 "s_register_operand" "r") 8598 (match_operand:SI 1 "const_int_operand" "n")]) 8599 (match_operand:SI 2 "s_register_operand" "+r"))) 8600 (match_operand:QI 3 "s_register_operand" "r")) 8601 (set (match_dup 2) (plus:SI (match_op_dup 4 [(match_dup 0) (match_dup 1)]) 8602 (match_dup 2)))] 8603 "TARGET_ARM 8604 && (REGNO (operands[3]) != REGNO (operands[2])) 8605 && (REGNO (operands[0]) != REGNO (operands[2]))" 8606 "str%?b\\t%3, [%2, %0%S4]!" 8607) 8608 8609; This pattern is never tried by combine, so do it as a peephole 8610 8611(define_peephole2 8612 [(set (match_operand:SI 0 "s_register_operand" "") 8613 (match_operand:SI 1 "s_register_operand" "")) 8614 (set (reg:CC CC_REGNUM) 8615 (compare:CC (match_dup 1) (const_int 0)))] 8616 "TARGET_ARM 8617 " 8618 [(parallel [(set (reg:CC CC_REGNUM) (compare:CC (match_dup 1) (const_int 0))) 8619 (set (match_dup 0) (match_dup 1))])] 8620 "" 8621) 8622 8623; Peepholes to spot possible load- and store-multiples, if the ordering is 8624; reversed, check that the memory references aren't volatile. 8625 8626(define_peephole 8627 [(set (match_operand:SI 0 "s_register_operand" "=r") 8628 (match_operand:SI 4 "memory_operand" "m")) 8629 (set (match_operand:SI 1 "s_register_operand" "=r") 8630 (match_operand:SI 5 "memory_operand" "m")) 8631 (set (match_operand:SI 2 "s_register_operand" "=r") 8632 (match_operand:SI 6 "memory_operand" "m")) 8633 (set (match_operand:SI 3 "s_register_operand" "=r") 8634 (match_operand:SI 7 "memory_operand" "m"))] 8635 "TARGET_ARM && load_multiple_sequence (operands, 4, NULL, NULL, NULL)" 8636 "* 8637 return emit_ldm_seq (operands, 4); 8638 " 8639) 8640 8641(define_peephole 8642 [(set (match_operand:SI 0 "s_register_operand" "=r") 8643 (match_operand:SI 3 "memory_operand" "m")) 8644 (set (match_operand:SI 1 "s_register_operand" "=r") 8645 (match_operand:SI 4 "memory_operand" "m")) 8646 (set (match_operand:SI 2 "s_register_operand" "=r") 8647 (match_operand:SI 5 "memory_operand" "m"))] 8648 "TARGET_ARM && load_multiple_sequence (operands, 3, NULL, NULL, NULL)" 8649 "* 8650 return emit_ldm_seq (operands, 3); 8651 " 8652) 8653 8654(define_peephole 8655 [(set (match_operand:SI 0 "s_register_operand" "=r") 8656 (match_operand:SI 2 "memory_operand" "m")) 8657 (set (match_operand:SI 1 "s_register_operand" "=r") 8658 (match_operand:SI 3 "memory_operand" "m"))] 8659 "TARGET_ARM && load_multiple_sequence (operands, 2, NULL, NULL, NULL)" 8660 "* 8661 return emit_ldm_seq (operands, 2); 8662 " 8663) 8664 8665(define_peephole 8666 [(set (match_operand:SI 4 "memory_operand" "=m") 8667 (match_operand:SI 0 "s_register_operand" "r")) 8668 (set (match_operand:SI 5 "memory_operand" "=m") 8669 (match_operand:SI 1 "s_register_operand" "r")) 8670 (set (match_operand:SI 6 "memory_operand" "=m") 8671 (match_operand:SI 2 "s_register_operand" "r")) 8672 (set (match_operand:SI 7 "memory_operand" "=m") 8673 (match_operand:SI 3 "s_register_operand" "r"))] 8674 "TARGET_ARM && store_multiple_sequence (operands, 4, NULL, NULL, NULL)" 8675 "* 8676 return emit_stm_seq (operands, 4); 8677 " 8678) 8679 8680(define_peephole 8681 [(set (match_operand:SI 3 "memory_operand" "=m") 8682 (match_operand:SI 0 "s_register_operand" "r")) 8683 (set (match_operand:SI 4 "memory_operand" "=m") 8684 (match_operand:SI 1 "s_register_operand" "r")) 8685 (set (match_operand:SI 5 "memory_operand" "=m") 8686 (match_operand:SI 2 "s_register_operand" "r"))] 8687 "TARGET_ARM && store_multiple_sequence (operands, 3, NULL, NULL, NULL)" 8688 "* 8689 return emit_stm_seq (operands, 3); 8690 " 8691) 8692 8693(define_peephole 8694 [(set (match_operand:SI 2 "memory_operand" "=m") 8695 (match_operand:SI 0 "s_register_operand" "r")) 8696 (set (match_operand:SI 3 "memory_operand" "=m") 8697 (match_operand:SI 1 "s_register_operand" "r"))] 8698 "TARGET_ARM && store_multiple_sequence (operands, 2, NULL, NULL, NULL)" 8699 "* 8700 return emit_stm_seq (operands, 2); 8701 " 8702) 8703 8704(define_split 8705 [(set (match_operand:SI 0 "s_register_operand" "") 8706 (and:SI (ge:SI (match_operand:SI 1 "s_register_operand" "") 8707 (const_int 0)) 8708 (neg:SI (match_operator:SI 2 "arm_comparison_operator" 8709 [(match_operand:SI 3 "s_register_operand" "") 8710 (match_operand:SI 4 "arm_rhs_operand" "")])))) 8711 (clobber (match_operand:SI 5 "s_register_operand" ""))] 8712 "TARGET_ARM" 8713 [(set (match_dup 5) (not:SI (ashiftrt:SI (match_dup 1) (const_int 31)))) 8714 (set (match_dup 0) (and:SI (match_op_dup 2 [(match_dup 3) (match_dup 4)]) 8715 (match_dup 5)))] 8716 "" 8717) 8718 8719;; This split can be used because CC_Z mode implies that the following 8720;; branch will be an equality, or an unsigned inequality, so the sign 8721;; extension is not needed. 8722 8723(define_split 8724 [(set (reg:CC_Z CC_REGNUM) 8725 (compare:CC_Z 8726 (ashift:SI (subreg:SI (match_operand:QI 0 "memory_operand" "") 0) 8727 (const_int 24)) 8728 (match_operand 1 "const_int_operand" ""))) 8729 (clobber (match_scratch:SI 2 ""))] 8730 "TARGET_ARM 8731 && (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) 8732 == (((unsigned HOST_WIDE_INT) INTVAL (operands[1])) >> 24) << 24)" 8733 [(set (match_dup 2) (zero_extend:SI (match_dup 0))) 8734 (set (reg:CC CC_REGNUM) (compare:CC (match_dup 2) (match_dup 1)))] 8735 " 8736 operands[1] = GEN_INT (((unsigned long) INTVAL (operands[1])) >> 24); 8737 " 8738) 8739 8740(define_expand "prologue" 8741 [(clobber (const_int 0))] 8742 "TARGET_EITHER" 8743 "if (TARGET_ARM) 8744 arm_expand_prologue (); 8745 else 8746 thumb_expand_prologue (); 8747 DONE; 8748 " 8749) 8750 8751(define_expand "epilogue" 8752 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)] 8753 "TARGET_EITHER" 8754 " 8755 if (TARGET_THUMB) 8756 thumb_expand_epilogue (); 8757 else if (USE_RETURN_INSN (FALSE)) 8758 { 8759 emit_jump_insn (gen_return ()); 8760 DONE; 8761 } 8762 emit_jump_insn (gen_rtx_UNSPEC_VOLATILE (VOIDmode, 8763 gen_rtvec (1, 8764 gen_rtx_RETURN (VOIDmode)), 8765 VUNSPEC_EPILOGUE)); 8766 DONE; 8767 " 8768) 8769 8770(define_insn "sibcall_epilogue" 8771 [(unspec_volatile [(const_int 0)] VUNSPEC_EPILOGUE)] 8772 "TARGET_ARM" 8773 "* 8774 output_asm_insn (\"%@ Sibcall epilogue\", operands); 8775 if (USE_RETURN_INSN (FALSE)) 8776 return output_return_instruction (NULL, FALSE, FALSE); 8777 return arm_output_epilogue (FALSE); 8778 " 8779;; Length is absolute worst case 8780 [(set_attr "length" "44") 8781 (set_attr "type" "block")] 8782) 8783 8784(define_insn "*epilogue_insns" 8785 [(unspec_volatile [(return)] VUNSPEC_EPILOGUE)] 8786 "TARGET_EITHER" 8787 "* 8788 if (TARGET_ARM) 8789 return arm_output_epilogue (TRUE); 8790 else /* TARGET_THUMB */ 8791 return thumb_unexpanded_epilogue (); 8792 " 8793 ; Length is absolute worst case 8794 [(set_attr "length" "44") 8795 (set_attr "type" "block")] 8796) 8797 8798(define_expand "eh_epilogue" 8799 [(use (match_operand:SI 0 "register_operand" "r")) 8800 (use (match_operand:SI 1 "register_operand" "r")) 8801 (use (match_operand:SI 2 "register_operand" "r"))] 8802 "TARGET_EITHER" 8803 " 8804 { 8805 cfun->machine->eh_epilogue_sp_ofs = operands[1]; 8806 if (GET_CODE (operands[2]) != REG || REGNO (operands[2]) != 2) 8807 { 8808 rtx ra = gen_rtx_REG (Pmode, 2); 8809 8810 emit_move_insn (ra, operands[2]); 8811 operands[2] = ra; 8812 } 8813 /* This is a hack -- we may have crystalized the function type too 8814 early. */ 8815 cfun->machine->func_type = 0; 8816 }" 8817) 8818 8819;; This split is only used during output to reduce the number of patterns 8820;; that need assembler instructions adding to them. We allowed the setting 8821;; of the conditions to be implicit during rtl generation so that 8822;; the conditional compare patterns would work. However this conflicts to 8823;; some extent with the conditional data operations, so we have to split them 8824;; up again here. 8825 8826(define_split 8827 [(set (match_operand:SI 0 "s_register_operand" "") 8828 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 8829 [(match_operand 2 "" "") (match_operand 3 "" "")]) 8830 (match_dup 0) 8831 (match_operand 4 "" ""))) 8832 (clobber (reg:CC CC_REGNUM))] 8833 "TARGET_ARM && reload_completed" 8834 [(set (match_dup 5) (match_dup 6)) 8835 (cond_exec (match_dup 7) 8836 (set (match_dup 0) (match_dup 4)))] 8837 " 8838 { 8839 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 8840 operands[2], operands[3]); 8841 enum rtx_code rc = GET_CODE (operands[1]); 8842 8843 operands[5] = gen_rtx_REG (mode, CC_REGNUM); 8844 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 8845 if (mode == CCFPmode || mode == CCFPEmode) 8846 rc = reverse_condition_maybe_unordered (rc); 8847 else 8848 rc = reverse_condition (rc); 8849 8850 operands[7] = gen_rtx_fmt_ee (rc, VOIDmode, operands[5], const0_rtx); 8851 }" 8852) 8853 8854(define_split 8855 [(set (match_operand:SI 0 "s_register_operand" "") 8856 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 8857 [(match_operand 2 "" "") (match_operand 3 "" "")]) 8858 (match_operand 4 "" "") 8859 (match_dup 0))) 8860 (clobber (reg:CC CC_REGNUM))] 8861 "TARGET_ARM && reload_completed" 8862 [(set (match_dup 5) (match_dup 6)) 8863 (cond_exec (match_op_dup 1 [(match_dup 5) (const_int 0)]) 8864 (set (match_dup 0) (match_dup 4)))] 8865 " 8866 { 8867 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 8868 operands[2], operands[3]); 8869 8870 operands[5] = gen_rtx_REG (mode, CC_REGNUM); 8871 operands[6] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 8872 }" 8873) 8874 8875(define_split 8876 [(set (match_operand:SI 0 "s_register_operand" "") 8877 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 8878 [(match_operand 2 "" "") (match_operand 3 "" "")]) 8879 (match_operand 4 "" "") 8880 (match_operand 5 "" ""))) 8881 (clobber (reg:CC CC_REGNUM))] 8882 "TARGET_ARM && reload_completed" 8883 [(set (match_dup 6) (match_dup 7)) 8884 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) 8885 (set (match_dup 0) (match_dup 4))) 8886 (cond_exec (match_dup 8) 8887 (set (match_dup 0) (match_dup 5)))] 8888 " 8889 { 8890 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 8891 operands[2], operands[3]); 8892 enum rtx_code rc = GET_CODE (operands[1]); 8893 8894 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 8895 operands[7] = gen_rtx_COMPARE (mode, operands[2], operands[3]); 8896 if (mode == CCFPmode || mode == CCFPEmode) 8897 rc = reverse_condition_maybe_unordered (rc); 8898 else 8899 rc = reverse_condition (rc); 8900 8901 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 8902 }" 8903) 8904 8905(define_split 8906 [(set (match_operand:SI 0 "s_register_operand" "") 8907 (if_then_else:SI (match_operator 1 "arm_comparison_operator" 8908 [(match_operand:SI 2 "s_register_operand" "") 8909 (match_operand:SI 3 "arm_add_operand" "")]) 8910 (match_operand:SI 4 "arm_rhs_operand" "") 8911 (not:SI 8912 (match_operand:SI 5 "s_register_operand" "")))) 8913 (clobber (reg:CC CC_REGNUM))] 8914 "TARGET_ARM && reload_completed" 8915 [(set (match_dup 6) (match_dup 7)) 8916 (cond_exec (match_op_dup 1 [(match_dup 6) (const_int 0)]) 8917 (set (match_dup 0) (match_dup 4))) 8918 (cond_exec (match_dup 8) 8919 (set (match_dup 0) (not:SI (match_dup 5))))] 8920 " 8921 { 8922 enum machine_mode mode = SELECT_CC_MODE (GET_CODE (operands[1]), 8923 operands[2], operands[3]); 8924 enum rtx_code rc = GET_CODE (operands[1]); 8925 8926 operands[6] = gen_rtx_REG (mode, CC_REGNUM); 8927 operands[7] = gen_rtx (COMPARE, mode, operands[2], operands[3]); 8928 if (mode == CCFPmode || mode == CCFPEmode) 8929 rc = reverse_condition_maybe_unordered (rc); 8930 else 8931 rc = reverse_condition (rc); 8932 8933 operands[8] = gen_rtx_fmt_ee (rc, VOIDmode, operands[6], const0_rtx); 8934 }" 8935) 8936 8937(define_insn "*cond_move_not" 8938 [(set (match_operand:SI 0 "s_register_operand" "=r,r") 8939 (if_then_else:SI (match_operator 4 "arm_comparison_operator" 8940 [(match_operand 3 "cc_register" "") (const_int 0)]) 8941 (match_operand:SI 1 "arm_rhs_operand" "0,?rI") 8942 (not:SI 8943 (match_operand:SI 2 "s_register_operand" "r,r"))))] 8944 "TARGET_ARM" 8945 "@ 8946 mvn%D4\\t%0, %2 8947 mov%d4\\t%0, %1\;mvn%D4\\t%0, %2" 8948 [(set_attr "conds" "use") 8949 (set_attr "length" "4,8")] 8950) 8951 8952;; The next two patterns occur when an AND operation is followed by a 8953;; scc insn sequence 8954 8955(define_insn "*sign_extract_onebit" 8956 [(set (match_operand:SI 0 "s_register_operand" "=r") 8957 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 8958 (const_int 1) 8959 (match_operand:SI 2 "const_int_operand" "n")))] 8960 "TARGET_ARM" 8961 "* 8962 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 8963 output_asm_insn (\"ands\\t%0, %1, %2\", operands); 8964 return \"mvnne\\t%0, #0\"; 8965 " 8966 [(set_attr "conds" "clob") 8967 (set_attr "length" "8")] 8968) 8969 8970(define_insn "*not_signextract_onebit" 8971 [(set (match_operand:SI 0 "s_register_operand" "=r") 8972 (not:SI 8973 (sign_extract:SI (match_operand:SI 1 "s_register_operand" "r") 8974 (const_int 1) 8975 (match_operand:SI 2 "const_int_operand" "n"))))] 8976 "TARGET_ARM" 8977 "* 8978 operands[2] = GEN_INT (1 << INTVAL (operands[2])); 8979 output_asm_insn (\"tst\\t%1, %2\", operands); 8980 output_asm_insn (\"mvneq\\t%0, #0\", operands); 8981 return \"movne\\t%0, #0\"; 8982 " 8983 [(set_attr "conds" "clob") 8984 (set_attr "length" "12")] 8985) 8986 8987;; Push multiple registers to the stack. Registers are in parallel (use ...) 8988;; expressions. For simplicity, the first register is also in the unspec 8989;; part. 8990(define_insn "*push_multi" 8991 [(match_parallel 2 "multi_register_push" 8992 [(set (match_operand:BLK 0 "memory_operand" "=m") 8993 (unspec:BLK [(match_operand:SI 1 "s_register_operand" "r")] 8994 UNSPEC_PUSH_MULT))])] 8995 "TARGET_ARM" 8996 "* 8997 { 8998 int num_saves = XVECLEN (operands[2], 0); 8999 9000 /* For the StrongARM at least it is faster to 9001 use STR to store only a single register. */ 9002 if (num_saves == 1) 9003 output_asm_insn (\"str\\t%1, [%m0, #-4]!\", operands); 9004 else 9005 { 9006 int i; 9007 char pattern[100]; 9008 9009 strcpy (pattern, \"stmfd\\t%m0!, {%1\"); 9010 9011 for (i = 1; i < num_saves; i++) 9012 { 9013 strcat (pattern, \", %|\"); 9014 strcat (pattern, 9015 reg_names[REGNO (XEXP (XVECEXP (operands[2], 0, i), 0))]); 9016 } 9017 9018 strcat (pattern, \"}\"); 9019 output_asm_insn (pattern, operands); 9020 } 9021 9022 return \"\"; 9023 }" 9024 [(set_attr "type" "store4")] 9025) 9026 9027;; Similarly for the floating point registers 9028(define_insn "*push_fp_multi" 9029 [(match_parallel 2 "multi_register_push" 9030 [(set (match_operand:BLK 0 "memory_operand" "=m") 9031 (unspec:BLK [(match_operand:XF 1 "f_register_operand" "f")] 9032 UNSPEC_PUSH_MULT))])] 9033 "TARGET_ARM" 9034 "* 9035 { 9036 char pattern[100]; 9037 9038 sprintf (pattern, \"sfmfd\\t%%1, %d, [%%m0]!\", XVECLEN (operands[2], 0)); 9039 output_asm_insn (pattern, operands); 9040 return \"\"; 9041 }" 9042 [(set_attr "type" "f_store")] 9043) 9044 9045;; Special patterns for dealing with the constant pool 9046 9047(define_insn "align_4" 9048 [(unspec_volatile [(const_int 0)] VUNSPEC_ALIGN)] 9049 "TARGET_EITHER" 9050 "* 9051 assemble_align (32); 9052 return \"\"; 9053 " 9054) 9055 9056(define_insn "consttable_end" 9057 [(unspec_volatile [(const_int 0)] VUNSPEC_POOL_END)] 9058 "TARGET_EITHER" 9059 "* 9060 making_const_table = FALSE; 9061 return \"\"; 9062 " 9063) 9064 9065(define_insn "consttable_1" 9066 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_1)] 9067 "TARGET_THUMB" 9068 "* 9069 making_const_table = TRUE; 9070 assemble_integer (operands[0], 1, BITS_PER_WORD, 1); 9071 assemble_zeros (3); 9072 return \"\"; 9073 " 9074 [(set_attr "length" "4")] 9075) 9076 9077(define_insn "consttable_2" 9078 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_2)] 9079 "TARGET_THUMB" 9080 "* 9081 making_const_table = TRUE; 9082 assemble_integer (operands[0], 2, BITS_PER_WORD, 1); 9083 assemble_zeros (2); 9084 return \"\"; 9085 " 9086 [(set_attr "length" "4")] 9087) 9088 9089(define_insn "consttable_4" 9090 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_4)] 9091 "TARGET_EITHER" 9092 "* 9093 { 9094 making_const_table = TRUE; 9095 switch (GET_MODE_CLASS (GET_MODE (operands[0]))) 9096 { 9097 case MODE_FLOAT: 9098 { 9099 union real_extract u; 9100 memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u); 9101 assemble_real (u.d, GET_MODE (operands[0]), BITS_PER_WORD); 9102 break; 9103 } 9104 default: 9105 assemble_integer (operands[0], 4, BITS_PER_WORD, 1); 9106 break; 9107 } 9108 return \"\"; 9109 }" 9110 [(set_attr "length" "4")] 9111) 9112 9113(define_insn "consttable_8" 9114 [(unspec_volatile [(match_operand 0 "" "")] VUNSPEC_POOL_8)] 9115 "TARGET_EITHER" 9116 "* 9117 { 9118 making_const_table = TRUE; 9119 switch (GET_MODE_CLASS (GET_MODE (operands[0]))) 9120 { 9121 case MODE_FLOAT: 9122 { 9123 union real_extract u; 9124 memcpy (&u, &CONST_DOUBLE_LOW (operands[0]), sizeof u); 9125 assemble_real (u.d, GET_MODE (operands[0]), BITS_PER_WORD); 9126 break; 9127 } 9128 default: 9129 assemble_integer (operands[0], 8, BITS_PER_WORD, 1); 9130 break; 9131 } 9132 return \"\"; 9133 }" 9134 [(set_attr "length" "8")] 9135) 9136 9137;; Miscellaneous Thumb patterns 9138 9139(define_insn "tablejump" 9140 [(set (pc) (match_operand:SI 0 "register_operand" "l*r")) 9141 (use (label_ref (match_operand 1 "" "")))] 9142 "TARGET_THUMB" 9143 "mov pc, %0" 9144 [(set_attr "length" "2")] 9145) 9146 9147;; V5 Instructions, 9148 9149(define_insn "clz" 9150 [(set (match_operand:SI 0 "s_register_operand" "=r") 9151 (unspec:SI [(match_operand:SI 1 "s_register_operand" "r")] 9152 UNSPEC_CLZ))] 9153 "TARGET_ARM && arm_arch5" 9154 "clz\\t%0, %1") 9155 9156(define_expand "ffssi2" 9157 [(set (match_operand:SI 0 "s_register_operand" "") 9158 (ffs:SI (match_operand:SI 1 "s_register_operand" "")))] 9159 "TARGET_ARM && arm_arch5" 9160 " 9161 { 9162 rtx t1, t2, t3; 9163 9164 t1 = gen_reg_rtx (SImode); 9165 t2 = gen_reg_rtx (SImode); 9166 t3 = gen_reg_rtx (SImode); 9167 9168 emit_insn (gen_negsi2 (t1, operands[1])); 9169 emit_insn (gen_andsi3 (t2, operands[1], t1)); 9170 emit_insn (gen_clz (t3, t2)); 9171 emit_insn (gen_subsi3 (operands[0], GEN_INT (32), t3)); 9172 DONE; 9173 }" 9174) 9175 9176;; V5E instructions. 9177 9178(define_insn "prefetch" 9179 [(prefetch (match_operand:SI 0 "address_operand" "p") 9180 (match_operand:SI 1 "" "") 9181 (match_operand:SI 2 "" ""))] 9182 "TARGET_ARM && arm_arch5e" 9183 "pld\\t%a0") 9184 9185;; General predication pattern 9186 9187(define_cond_exec 9188 [(match_operator 0 "arm_comparison_operator" 9189 [(match_operand 1 "cc_register" "") 9190 (const_int 0)])] 9191 "TARGET_ARM" 9192 "" 9193) 9194 9195(define_insn "prologue_use" 9196 [(unspec:SI [(match_operand:SI 0 "register_operand" "")] UNSPEC_PROLOGUE_USE)] 9197 "" 9198 "%@ %0 needed for prologue" 9199) 9200