1;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler 2;; Copyright (C) 1990-2018 Free Software Foundation, Inc. 3;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 22 23;; 24;; REGNOS 25;; 26 27(define_constants 28 [(FIRST_GPR_REGNO 0) 29 (STACK_POINTER_REGNUM 1) 30 (TOC_REGNUM 2) 31 (STATIC_CHAIN_REGNUM 11) 32 (HARD_FRAME_POINTER_REGNUM 31) 33 (LAST_GPR_REGNO 31) 34 (FIRST_FPR_REGNO 32) 35 (LAST_FPR_REGNO 63) 36 (LR_REGNO 65) 37 (CTR_REGNO 66) 38 (ARG_POINTER_REGNUM 67) 39 (CR0_REGNO 68) 40 (CR1_REGNO 69) 41 (CR2_REGNO 70) 42 (CR3_REGNO 71) 43 (CR4_REGNO 72) 44 (CR5_REGNO 73) 45 (CR6_REGNO 74) 46 (CR7_REGNO 75) 47 (MAX_CR_REGNO 75) 48 (CA_REGNO 76) 49 (FIRST_ALTIVEC_REGNO 77) 50 (LAST_ALTIVEC_REGNO 108) 51 (VRSAVE_REGNO 109) 52 (VSCR_REGNO 110) 53 (SPE_ACC_REGNO 111) 54 (SPEFSCR_REGNO 112) 55 (FRAME_POINTER_REGNUM 113) 56 (TFHAR_REGNO 114) 57 (TFIAR_REGNO 115) 58 (TEXASR_REGNO 116) 59 (FIRST_SPE_HIGH_REGNO 117) 60 (LAST_SPE_HIGH_REGNO 148) 61 ]) 62 63;; 64;; UNSPEC usage 65;; 66 67(define_c_enum "unspec" 68 [UNSPEC_FRSP ; frsp for POWER machines 69 UNSPEC_PROBE_STACK ; probe stack memory reference 70 UNSPEC_TOCPTR ; address of a word pointing to the TOC 71 UNSPEC_TOC ; address of the TOC (more-or-less) 72 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot 73 UNSPEC_MOVSI_GOT 74 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit 75 UNSPEC_FCTIWZ 76 UNSPEC_FRIM 77 UNSPEC_FRIN 78 UNSPEC_FRIP 79 UNSPEC_FRIZ 80 UNSPEC_XSRDPI 81 UNSPEC_LD_MPIC ; load_macho_picbase 82 UNSPEC_RELD_MPIC ; re-load_macho_picbase 83 UNSPEC_MPIC_CORRECT ; macho_correct_pic 84 UNSPEC_TLSGD 85 UNSPEC_TLSLD 86 UNSPEC_MOVESI_FROM_CR 87 UNSPEC_MOVESI_TO_CR 88 UNSPEC_TLSDTPREL 89 UNSPEC_TLSDTPRELHA 90 UNSPEC_TLSDTPRELLO 91 UNSPEC_TLSGOTDTPREL 92 UNSPEC_TLSTPREL 93 UNSPEC_TLSTPRELHA 94 UNSPEC_TLSTPRELLO 95 UNSPEC_TLSGOTTPREL 96 UNSPEC_TLSTLS 97 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero 98 UNSPEC_MV_CR_GT ; move_from_CR_gt_bit 99 UNSPEC_STFIWX 100 UNSPEC_POPCNTB 101 UNSPEC_FRES 102 UNSPEC_SP_SET 103 UNSPEC_SP_TEST 104 UNSPEC_SYNC 105 UNSPEC_LWSYNC 106 UNSPEC_SYNC_OP 107 UNSPEC_ATOMIC 108 UNSPEC_CMPXCHG 109 UNSPEC_XCHG 110 UNSPEC_AND 111 UNSPEC_DLMZB 112 UNSPEC_DLMZB_CR 113 UNSPEC_DLMZB_STRLEN 114 UNSPEC_RSQRT 115 UNSPEC_TOCREL 116 UNSPEC_MACHOPIC_OFFSET 117 UNSPEC_BPERM 118 UNSPEC_COPYSIGN 119 UNSPEC_PARITY 120 UNSPEC_FCTIW 121 UNSPEC_FCTID 122 UNSPEC_LFIWAX 123 UNSPEC_LFIWZX 124 UNSPEC_FCTIWUZ 125 UNSPEC_NOP 126 UNSPEC_GRP_END_NOP 127 UNSPEC_P8V_FMRGOW 128 UNSPEC_P8V_MTVSRWZ 129 UNSPEC_P8V_RELOAD_FROM_GPR 130 UNSPEC_P8V_MTVSRD 131 UNSPEC_P8V_XXPERMDI 132 UNSPEC_P8V_RELOAD_FROM_VSX 133 UNSPEC_ADDG6S 134 UNSPEC_CDTBCD 135 UNSPEC_CBCDTD 136 UNSPEC_DIVE 137 UNSPEC_DIVEU 138 UNSPEC_UNPACK_128BIT 139 UNSPEC_PACK_128BIT 140 UNSPEC_LSQ 141 UNSPEC_FUSION_GPR 142 UNSPEC_STACK_CHECK 143 UNSPEC_FUSION_P9 144 UNSPEC_FUSION_ADDIS 145 UNSPEC_ROUND_TO_ODD 146 UNSPEC_IEEE128_MOVE 147 UNSPEC_IEEE128_CONVERT 148 UNSPEC_SIGNBIT 149 UNSPEC_DOLOOP 150 ]) 151 152;; 153;; UNSPEC_VOLATILE usage 154;; 155 156(define_c_enum "unspecv" 157 [UNSPECV_BLOCK 158 UNSPECV_LL ; load-locked 159 UNSPECV_SC ; store-conditional 160 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses 161 UNSPECV_EH_RR ; eh_reg_restore 162 UNSPECV_ISYNC ; isync instruction 163 UNSPECV_MFTB ; move from time base 164 UNSPECV_NLGR ; non-local goto receiver 165 UNSPECV_MFFS ; Move from FPSCR 166 UNSPECV_MTFSF ; Move to FPSCR Fields 167 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return 168 ]) 169 170 171;; Define an insn type attribute. This is used in function unit delay 172;; computations. 173(define_attr "type" 174 "integer,two,three, 175 add,logical,shift,insert, 176 mul,halfmul,div, 177 exts,cntlz,popcnt,isel, 178 load,store,fpload,fpstore,vecload,vecstore, 179 cmp, 180 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c, 181 cr_logical,delayed_cr,mfcr,mfcrf,mtcr, 182 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt, 183 brinc, 184 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm, 185 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto, 186 veclogical,veccmpfx,vecexts,vecmove, 187 htm,htmsimple,dfp" 188 (const_string "integer")) 189 190;; What data size does this instruction work on? 191;; This is used for insert, mul and others as necessary. 192(define_attr "size" "8,16,32,64,128" (const_string "32")) 193 194;; Is this instruction record form ("dot", signed compare to 0, writing CR0)? 195;; This is used for add, logical, shift, exts, mul. 196(define_attr "dot" "no,yes" (const_string "no")) 197 198;; Does this instruction sign-extend its result? 199;; This is used for load insns. 200(define_attr "sign_extend" "no,yes" (const_string "no")) 201 202;; Does this instruction use indexed (that is, reg+reg) addressing? 203;; This is used for load and store insns. If operand 0 or 1 is a MEM 204;; it is automatically set based on that. If a load or store instruction 205;; has fewer than two operands it needs to set this attribute manually 206;; or the compiler will crash. 207(define_attr "indexed" "no,yes" 208 (if_then_else (ior (match_operand 0 "indexed_address_mem") 209 (match_operand 1 "indexed_address_mem")) 210 (const_string "yes") 211 (const_string "no"))) 212 213;; Does this instruction use update addressing? 214;; This is used for load and store insns. See the comments for "indexed". 215(define_attr "update" "no,yes" 216 (if_then_else (ior (match_operand 0 "update_address_mem") 217 (match_operand 1 "update_address_mem")) 218 (const_string "yes") 219 (const_string "no"))) 220 221;; Is this instruction using operands[2] as shift amount, and can that be a 222;; register? 223;; This is used for shift insns. 224(define_attr "maybe_var_shift" "no,yes" (const_string "no")) 225 226;; Is this instruction using a shift amount from a register? 227;; This is used for shift insns. 228(define_attr "var_shift" "no,yes" 229 (if_then_else (and (eq_attr "type" "shift") 230 (eq_attr "maybe_var_shift" "yes")) 231 (if_then_else (match_operand 2 "gpc_reg_operand") 232 (const_string "yes") 233 (const_string "no")) 234 (const_string "no"))) 235 236;; Is copying of this instruction disallowed? 237(define_attr "cannot_copy" "no,yes" (const_string "no")) 238 239;; Define floating point instruction sub-types for use with Xfpu.md 240(define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default")) 241 242;; Length (in bytes). 243; '(pc)' in the following doesn't include the instruction itself; it is 244; calculated as if the instruction had zero size. 245(define_attr "length" "" 246 (if_then_else (eq_attr "type" "branch") 247 (if_then_else (and (ge (minus (match_dup 0) (pc)) 248 (const_int -32768)) 249 (lt (minus (match_dup 0) (pc)) 250 (const_int 32764))) 251 (const_int 4) 252 (const_int 8)) 253 (const_int 4))) 254 255;; Processor type -- this attribute must exactly match the processor_type 256;; enumeration in rs6000-opts.h. 257(define_attr "cpu" 258 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630, 259 ppc750,ppc7400,ppc7450, 260 ppc403,ppc405,ppc440,ppc476, 261 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500, 262 power4,power5,power6,power7,power8,power9, 263 rs64a,mpccore,cell,ppca2,titan" 264 (const (symbol_ref "rs6000_cpu_attr"))) 265 266 267;; If this instruction is microcoded on the CELL processor 268; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded 269(define_attr "cell_micro" "not,conditional,always" 270 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul") 271 (eq_attr "dot" "yes")) 272 (and (eq_attr "type" "load") 273 (eq_attr "sign_extend" "yes")) 274 (and (eq_attr "type" "shift") 275 (eq_attr "var_shift" "yes"))) 276 (const_string "always") 277 (const_string "not"))) 278 279(automata_option "ndfa") 280 281(include "rs64.md") 282(include "mpc.md") 283(include "40x.md") 284(include "440.md") 285(include "476.md") 286(include "601.md") 287(include "603.md") 288(include "6xx.md") 289(include "7xx.md") 290(include "7450.md") 291(include "8540.md") 292(include "e300c2c3.md") 293(include "e500mc.md") 294(include "e500mc64.md") 295(include "e5500.md") 296(include "e6500.md") 297(include "power4.md") 298(include "power5.md") 299(include "power6.md") 300(include "power7.md") 301(include "power8.md") 302(include "power9.md") 303(include "cell.md") 304(include "xfpu.md") 305(include "a2.md") 306(include "titan.md") 307 308(include "predicates.md") 309(include "constraints.md") 310 311(include "darwin.md") 312 313 314;; Mode iterators 315 316; This mode iterator allows :GPR to be used to indicate the allowable size 317; of whole values in GPRs. 318(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")]) 319 320; Any supported integer mode. 321(define_mode_iterator INT [QI HI SI DI TI PTI]) 322 323; Any supported integer mode that fits in one register. 324(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")]) 325 326; Everything we can extend QImode to. 327(define_mode_iterator EXTQI [HI SI (DI "TARGET_POWERPC64")]) 328 329; Everything we can extend HImode to. 330(define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")]) 331 332; Everything we can extend SImode to. 333(define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")]) 334 335; QImode or HImode for small atomic ops 336(define_mode_iterator QHI [QI HI]) 337 338; QImode, HImode, SImode for fused ops only for GPR loads 339(define_mode_iterator QHSI [QI HI SI]) 340 341; HImode or SImode for sign extended fusion ops 342(define_mode_iterator HSI [HI SI]) 343 344; SImode or DImode, even if DImode doesn't fit in GPRs. 345(define_mode_iterator SDI [SI DI]) 346 347; Types that can be fused with an ADDIS instruction to load or store a GPR 348; register that has reg+offset addressing. 349(define_mode_iterator GPR_FUSION [QI 350 HI 351 SI 352 (DI "TARGET_POWERPC64") 353 SF 354 (DF "TARGET_POWERPC64")]) 355 356; Types that can be fused with an ADDIS instruction to load or store a FPR 357; register that has reg+offset addressing. 358(define_mode_iterator FPR_FUSION [DI SF DF]) 359 360; The size of a pointer. Also, the size of the value that a record-condition 361; (one with a '.') will compare; and the size used for arithmetic carries. 362(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")]) 363 364; Iterator to add PTImode along with TImode (TImode can go in VSX registers, 365; PTImode is GPR only) 366(define_mode_iterator TI2 [TI PTI]) 367 368; Any hardware-supported floating-point mode 369(define_mode_iterator FP [ 370 (SF "TARGET_HARD_FLOAT 371 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)") 372 (DF "TARGET_HARD_FLOAT 373 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)") 374 (TF "TARGET_HARD_FLOAT 375 && (TARGET_FPRS || TARGET_E500_DOUBLE) 376 && TARGET_LONG_DOUBLE_128") 377 (IF "TARGET_FLOAT128") 378 (KF "TARGET_FLOAT128") 379 (DD "TARGET_DFP") 380 (TD "TARGET_DFP")]) 381 382; Any fma capable floating-point mode. 383(define_mode_iterator FMA_F [ 384 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT") 385 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) 386 || VECTOR_UNIT_VSX_P (DFmode)") 387 (V2SF "TARGET_PAIRED_FLOAT") 388 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)") 389 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)") 390 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)") 391 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)") 392 ]) 393 394; Floating point move iterators to combine binary and decimal moves 395(define_mode_iterator FMOVE32 [SF SD]) 396(define_mode_iterator FMOVE64 [DF DD]) 397(define_mode_iterator FMOVE64X [DI DF DD]) 398(define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128") 399 (IF "TARGET_LONG_DOUBLE_128") 400 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")]) 401 402(define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)") 403 (IF "FLOAT128_2REG_P (IFmode)") 404 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")]) 405 406; Iterators for 128 bit types for direct move 407(define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE") 408 (V16QI "") 409 (V8HI "") 410 (V4SI "") 411 (V4SF "") 412 (V2DI "") 413 (V2DF "") 414 (V1TI "") 415 (KF "FLOAT128_VECTOR_P (KFmode)") 416 (TF "FLOAT128_VECTOR_P (TFmode)")]) 417 418; Iterator for 128-bit VSX types for pack/unpack 419(define_mode_iterator FMOVE128_VSX [V1TI KF]) 420 421; Whether a floating point move is ok, don't allow SD without hardware FP 422(define_mode_attr fmove_ok [(SF "") 423 (DF "") 424 (SD "TARGET_HARD_FLOAT && TARGET_FPRS") 425 (DD "")]) 426 427; Convert REAL_VALUE to the appropriate bits 428(define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE") 429 (DF "REAL_VALUE_TO_TARGET_DOUBLE") 430 (SD "REAL_VALUE_TO_TARGET_DECIMAL32") 431 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")]) 432 433; Whether 0.0 has an all-zero bit pattern 434(define_mode_attr zero_fp [(SF "j") 435 (DF "j") 436 (TF "j") 437 (IF "j") 438 (KF "j") 439 (SD "wn") 440 (DD "wn") 441 (TD "wn")]) 442 443; Definitions for 64-bit VSX 444(define_mode_attr f64_vsx [(DF "ws") (DD "wn")]) 445 446; Definitions for 64-bit direct move 447(define_mode_attr f64_dm [(DF "wk") (DD "wh")]) 448 449; Definitions for 64-bit use of altivec registers 450(define_mode_attr f64_av [(DF "wv") (DD "wn")]) 451 452; Definitions for 64-bit access to ISA 3.0 (power9) vector 453(define_mode_attr f64_p9 [(DF "wb") (DD "wn")]) 454 455; These modes do not fit in integer registers in 32-bit mode. 456; but on e500v2, the gpr are 64 bit registers 457(define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD]) 458 459; Iterator for reciprocal estimate instructions 460(define_mode_iterator RECIPF [SF DF V4SF V2DF]) 461 462; Iterator for just SF/DF 463(define_mode_iterator SFDF [SF DF]) 464 465; Like SFDF, but a different name to match conditional move where the 466; comparison operands may be a different mode than the input operands. 467(define_mode_iterator SFDF2 [SF DF]) 468 469; Iterator for 128-bit floating point that uses the IBM double-double format 470(define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)") 471 (TF "FLOAT128_IBM_P (TFmode)")]) 472 473; Iterator for 128-bit floating point that uses IEEE 128-bit float 474(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)") 475 (TF "FLOAT128_IEEE_P (TFmode)")]) 476 477; Iterator for 128-bit floating point 478(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128") 479 (IF "TARGET_FLOAT128") 480 (TF "TARGET_LONG_DOUBLE_128")]) 481 482; Iterator for signbit on 64-bit machines with direct move 483(define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)") 484 (TF "FLOAT128_VECTOR_P (TFmode)")]) 485 486; SF/DF suffix for traditional floating instructions 487(define_mode_attr Ftrad [(SF "s") (DF "")]) 488 489; SF/DF suffix for VSX instructions 490(define_mode_attr Fvsx [(SF "sp") (DF "dp")]) 491 492; SF/DF constraint for arithmetic on traditional floating point registers 493(define_mode_attr Ff [(SF "f") (DF "d") (DI "d")]) 494 495; SF/DF constraint for arithmetic on VSX registers using instructions added in 496; ISA 2.06 (power7). This includes instructions that normally target DF mode, 497; but are used on SFmode, since internally SFmode values are kept in the DFmode 498; format. 499(define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")]) 500 501; SF/DF constraint for arithmetic on VSX registers. This is intended to be 502; used for DFmode instructions added in ISA 2.06 (power7) and SFmode 503; instructions added in ISA 2.07 (power8) 504(define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")]) 505 506; SF/DF constraint for arithmetic on altivec registers 507(define_mode_attr Fa [(SF "wu") (DF "wv")]) 508 509; s/d suffix for things like fp_addsub_s/fp_addsub_d 510(define_mode_attr Fs [(SF "s") (DF "d")]) 511 512; FRE/FRES support 513(define_mode_attr Ffre [(SF "fres") (DF "fre")]) 514(define_mode_attr FFRE [(SF "FRES") (DF "FRE")]) 515 516; Conditional returns. 517(define_code_iterator any_return [return simple_return]) 518(define_code_attr return_pred [(return "direct_return ()") 519 (simple_return "1")]) 520(define_code_attr return_str [(return "") (simple_return "simple_")]) 521 522; Logical operators. 523(define_code_iterator iorxor [ior xor]) 524 525; Signed/unsigned variants of ops. 526(define_code_iterator any_extend [sign_extend zero_extend]) 527(define_code_iterator any_fix [fix unsigned_fix]) 528(define_code_iterator any_float [float unsigned_float]) 529 530(define_code_attr u [(sign_extend "") 531 (zero_extend "u")]) 532 533(define_code_attr su [(sign_extend "s") 534 (zero_extend "u") 535 (fix "s") 536 (unsigned_fix "u") 537 (float "s") 538 (unsigned_float "u")]) 539 540(define_code_attr az [(sign_extend "a") 541 (zero_extend "z") 542 (fix "a") 543 (unsigned_fix "z") 544 (float "a") 545 (unsigned_float "z")]) 546 547(define_code_attr uns [(fix "") 548 (unsigned_fix "uns") 549 (float "") 550 (unsigned_float "uns")]) 551 552; Various instructions that come in SI and DI forms. 553; A generic w/d attribute, for things like cmpw/cmpd. 554(define_mode_attr wd [(QI "b") 555 (HI "h") 556 (SI "w") 557 (DI "d") 558 (V16QI "b") 559 (V8HI "h") 560 (V4SI "w") 561 (V2DI "d") 562 (V1TI "q") 563 (TI "q")]) 564 565;; How many bits in this mode? 566(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")]) 567 568; DImode bits 569(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")]) 570 571;; ISEL/ISEL64 target selection 572(define_mode_attr sel [(SI "") (DI "64")]) 573 574;; Bitmask for shift instructions 575(define_mode_attr hH [(SI "h") (DI "H")]) 576 577;; A mode twice the size of the given mode 578(define_mode_attr dmode [(SI "di") (DI "ti")]) 579(define_mode_attr DMODE [(SI "DI") (DI "TI")]) 580 581;; Suffix for reload patterns 582(define_mode_attr ptrsize [(SI "32bit") 583 (DI "64bit")]) 584 585(define_mode_attr tptrsize [(SI "TARGET_32BIT") 586 (DI "TARGET_64BIT")]) 587 588(define_mode_attr mptrsize [(SI "si") 589 (DI "di")]) 590 591(define_mode_attr ptrload [(SI "lwz") 592 (DI "ld")]) 593 594(define_mode_attr ptrm [(SI "m") 595 (DI "Y")]) 596 597(define_mode_attr rreg [(SF "f") 598 (DF "ws") 599 (TF "f") 600 (TD "f") 601 (V4SF "wf") 602 (V2DF "wd")]) 603 604(define_mode_attr rreg2 [(SF "f") 605 (DF "d")]) 606 607(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS") 608 (DF "TARGET_FCFID")]) 609 610(define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS") 611 (DF "TARGET_E500_DOUBLE")]) 612 613(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT") 614 (DF "TARGET_DOUBLE_FLOAT")]) 615 616;; Mode iterator for logical operations on 128-bit types 617(define_mode_iterator BOOL_128 [TI 618 PTI 619 (V16QI "TARGET_ALTIVEC") 620 (V8HI "TARGET_ALTIVEC") 621 (V4SI "TARGET_ALTIVEC") 622 (V4SF "TARGET_ALTIVEC") 623 (V2DI "TARGET_ALTIVEC") 624 (V2DF "TARGET_ALTIVEC") 625 (V1TI "TARGET_ALTIVEC")]) 626 627;; For the GPRs we use 3 constraints for register outputs, two that are the 628;; same as the output register, and a third where the output register is an 629;; early clobber, so we don't have to deal with register overlaps. For the 630;; vector types, we prefer to use the vector registers. For TI mode, allow 631;; either. 632 633;; Mode attribute for boolean operation register constraints for output 634(define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v") 635 (PTI "&r,r,r") 636 (V16QI "wa,v,&?r,?r,?r") 637 (V8HI "wa,v,&?r,?r,?r") 638 (V4SI "wa,v,&?r,?r,?r") 639 (V4SF "wa,v,&?r,?r,?r") 640 (V2DI "wa,v,&?r,?r,?r") 641 (V2DF "wa,v,&?r,?r,?r") 642 (V1TI "wa,v,&?r,?r,?r")]) 643 644;; Mode attribute for boolean operation register constraints for operand1 645(define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v") 646 (PTI "r,0,r") 647 (V16QI "wa,v,r,0,r") 648 (V8HI "wa,v,r,0,r") 649 (V4SI "wa,v,r,0,r") 650 (V4SF "wa,v,r,0,r") 651 (V2DI "wa,v,r,0,r") 652 (V2DF "wa,v,r,0,r") 653 (V1TI "wa,v,r,0,r")]) 654 655;; Mode attribute for boolean operation register constraints for operand2 656(define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v") 657 (PTI "r,r,0") 658 (V16QI "wa,v,r,r,0") 659 (V8HI "wa,v,r,r,0") 660 (V4SI "wa,v,r,r,0") 661 (V4SF "wa,v,r,r,0") 662 (V2DI "wa,v,r,r,0") 663 (V2DF "wa,v,r,r,0") 664 (V1TI "wa,v,r,r,0")]) 665 666;; Mode attribute for boolean operation register constraints for operand1 667;; for one_cmpl. To simplify things, we repeat the constraint where 0 668;; is used for operand1 or operand2 669(define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v") 670 (PTI "r,0,0") 671 (V16QI "wa,v,r,0,0") 672 (V8HI "wa,v,r,0,0") 673 (V4SI "wa,v,r,0,0") 674 (V4SF "wa,v,r,0,0") 675 (V2DI "wa,v,r,0,0") 676 (V2DF "wa,v,r,0,0") 677 (V1TI "wa,v,r,0,0")]) 678 679;; Reload iterator for creating the function to allocate a base register to 680;; supplement addressing modes. 681(define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI 682 SF SD SI DF DD DI TI PTI KF IF TF]) 683 684;; Iterate over smin, smax 685(define_code_iterator fp_minmax [smin smax]) 686 687(define_code_attr minmax [(smin "min") 688 (smax "max")]) 689 690(define_code_attr SMINMAX [(smin "SMIN") 691 (smax "SMAX")]) 692 693;; Iterator to optimize the following cases: 694;; D-form load to FPR register & move to Altivec register 695;; Move Altivec register to FPR register and store 696(define_mode_iterator ALTIVEC_DFORM [DF SF]) 697 698 699;; Start with fixed-point load and store insns. Here we put only the more 700;; complex forms. Basic data transfer is done later. 701 702(define_insn "zero_extendqi<mode>2" 703 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 704 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r")))] 705 "" 706 "@ 707 lbz%U1%X1 %0,%1 708 rlwinm %0,%1,0,0xff" 709 [(set_attr "type" "load,shift")]) 710 711(define_insn "*zero_extendqi<mode>2_dot" 712 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 713 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 714 (const_int 0))) 715 (clobber (match_scratch:EXTQI 0 "=r,r"))] 716 "rs6000_gen_cell_microcode" 717 "@ 718 andi. %0,%1,0xff 719 rlwinm %0,%1,0,0xff\;cmpwi %2,%0,0" 720 [(set_attr "type" "logical") 721 (set_attr "dot" "yes") 722 (set_attr "length" "4,8")]) 723 724(define_insn "*zero_extendqi<mode>2_dot2" 725 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 726 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 727 (const_int 0))) 728 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 729 (zero_extend:EXTQI (match_dup 1)))] 730 "rs6000_gen_cell_microcode" 731 "@ 732 andi. %0,%1,0xff 733 rlwinm %0,%1,0,0xff\;cmpwi %2,%0,0" 734 [(set_attr "type" "logical") 735 (set_attr "dot" "yes") 736 (set_attr "length" "4,8")]) 737 738 739(define_insn "zero_extendhi<mode>2" 740 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 741 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] 742 "" 743 "@ 744 lhz%U1%X1 %0,%1 745 rlwinm %0,%1,0,0xffff" 746 [(set_attr "type" "load,shift")]) 747 748(define_insn_and_split "*zero_extendhi<mode>2_dot" 749 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 750 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 751 (const_int 0))) 752 (clobber (match_scratch:EXTHI 0 "=r,r"))] 753 "rs6000_gen_cell_microcode" 754 "@ 755 andi. %0,%1,0xffff 756 #" 757 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 758 [(set (match_dup 0) 759 (zero_extend:EXTHI (match_dup 1))) 760 (set (match_dup 2) 761 (compare:CC (match_dup 0) 762 (const_int 0)))] 763 "" 764 [(set_attr "type" "logical") 765 (set_attr "dot" "yes") 766 (set_attr "length" "4,8")]) 767 768(define_insn_and_split "*zero_extendhi<mode>2_dot2" 769 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 770 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 771 (const_int 0))) 772 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 773 (zero_extend:EXTHI (match_dup 1)))] 774 "rs6000_gen_cell_microcode" 775 "@ 776 andi. %0,%1,0xffff 777 #" 778 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 779 [(set (match_dup 0) 780 (zero_extend:EXTHI (match_dup 1))) 781 (set (match_dup 2) 782 (compare:CC (match_dup 0) 783 (const_int 0)))] 784 "" 785 [(set_attr "type" "logical") 786 (set_attr "dot" "yes") 787 (set_attr "length" "4,8")]) 788 789 790(define_insn "zero_extendsi<mode>2" 791 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wz,!wu") 792 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,r,Z,Z")))] 793 "" 794 "@ 795 lwz%U1%X1 %0,%1 796 rldicl %0,%1,0,32 797 mtvsrwz %x0,%1 798 lfiwzx %0,%y1 799 lxsiwzx %x0,%y1" 800 [(set_attr "type" "load,shift,mffgpr,fpload,fpload")]) 801 802(define_insn_and_split "*zero_extendsi<mode>2_dot" 803 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 804 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 805 (const_int 0))) 806 (clobber (match_scratch:EXTSI 0 "=r,r"))] 807 "rs6000_gen_cell_microcode" 808 "@ 809 rldicl. %0,%1,0,32 810 #" 811 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 812 [(set (match_dup 0) 813 (zero_extend:DI (match_dup 1))) 814 (set (match_dup 2) 815 (compare:CC (match_dup 0) 816 (const_int 0)))] 817 "" 818 [(set_attr "type" "shift") 819 (set_attr "dot" "yes") 820 (set_attr "length" "4,8")]) 821 822(define_insn_and_split "*zero_extendsi<mode>2_dot2" 823 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 824 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 825 (const_int 0))) 826 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") 827 (zero_extend:EXTSI (match_dup 1)))] 828 "rs6000_gen_cell_microcode" 829 "@ 830 rldicl. %0,%1,0,32 831 #" 832 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 833 [(set (match_dup 0) 834 (zero_extend:EXTSI (match_dup 1))) 835 (set (match_dup 2) 836 (compare:CC (match_dup 0) 837 (const_int 0)))] 838 "" 839 [(set_attr "type" "shift") 840 (set_attr "dot" "yes") 841 (set_attr "length" "4,8")]) 842 843 844(define_insn "extendqi<mode>2" 845 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r") 846 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r")))] 847 "" 848 "extsb %0,%1" 849 [(set_attr "type" "exts")]) 850 851(define_insn "*extendqi<mode>2_dot" 852 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 853 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 854 (const_int 0))) 855 (clobber (match_scratch:EXTQI 0 "=r,r"))] 856 "rs6000_gen_cell_microcode" 857 "@ 858 extsb. %0,%1 859 extsb %0,%1\;cmpwi %2,%0,0" 860 [(set_attr "type" "exts") 861 (set_attr "dot" "yes") 862 (set_attr "length" "4,8")]) 863 864(define_insn "*extendqi<mode>2_dot2" 865 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 866 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 867 (const_int 0))) 868 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 869 (sign_extend:EXTQI (match_dup 1)))] 870 "rs6000_gen_cell_microcode" 871 "@ 872 extsb. %0,%1 873 extsb %0,%1\;cmpwi %2,%0,0" 874 [(set_attr "type" "exts") 875 (set_attr "dot" "yes") 876 (set_attr "length" "4,8")]) 877 878 879(define_expand "extendhi<mode>2" 880 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "") 881 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "")))] 882 "" 883 "") 884 885(define_insn "*extendhi<mode>2" 886 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 887 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r")))] 888 "rs6000_gen_cell_microcode" 889 "@ 890 lha%U1%X1 %0,%1 891 extsh %0,%1" 892 [(set_attr "type" "load,exts") 893 (set_attr "sign_extend" "yes")]) 894 895(define_insn "*extendhi<mode>2_noload" 896 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r") 897 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))] 898 "!rs6000_gen_cell_microcode" 899 "extsh %0,%1" 900 [(set_attr "type" "exts")]) 901 902(define_insn_and_split "*extendhi<mode>2_dot" 903 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 904 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 905 (const_int 0))) 906 (clobber (match_scratch:EXTHI 0 "=r,r"))] 907 "rs6000_gen_cell_microcode" 908 "@ 909 extsh. %0,%1 910 #" 911 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 912 [(set (match_dup 0) 913 (sign_extend:EXTHI (match_dup 1))) 914 (set (match_dup 2) 915 (compare:CC (match_dup 0) 916 (const_int 0)))] 917 "" 918 [(set_attr "type" "exts") 919 (set_attr "dot" "yes") 920 (set_attr "length" "4,8")]) 921 922(define_insn_and_split "*extendhi<mode>2_dot2" 923 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 924 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 925 (const_int 0))) 926 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 927 (sign_extend:EXTHI (match_dup 1)))] 928 "rs6000_gen_cell_microcode" 929 "@ 930 extsh. %0,%1 931 #" 932 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 933 [(set (match_dup 0) 934 (sign_extend:EXTHI (match_dup 1))) 935 (set (match_dup 2) 936 (compare:CC (match_dup 0) 937 (const_int 0)))] 938 "" 939 [(set_attr "type" "exts") 940 (set_attr "dot" "yes") 941 (set_attr "length" "4,8")]) 942 943 944(define_insn "extendsi<mode>2" 945 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,??wj,!wl,!wu") 946 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,r,Z,Z")))] 947 "" 948 "@ 949 lwa%U1%X1 %0,%1 950 extsw %0,%1 951 mtvsrwa %x0,%1 952 lfiwax %0,%y1 953 lxsiwax %x0,%y1" 954 [(set_attr "type" "load,exts,mffgpr,fpload,fpload") 955 (set_attr "sign_extend" "yes")]) 956 957(define_insn_and_split "*extendsi<mode>2_dot" 958 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 959 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 960 (const_int 0))) 961 (clobber (match_scratch:EXTSI 0 "=r,r"))] 962 "rs6000_gen_cell_microcode" 963 "@ 964 extsw. %0,%1 965 #" 966 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 967 [(set (match_dup 0) 968 (sign_extend:EXTSI (match_dup 1))) 969 (set (match_dup 2) 970 (compare:CC (match_dup 0) 971 (const_int 0)))] 972 "" 973 [(set_attr "type" "exts") 974 (set_attr "dot" "yes") 975 (set_attr "length" "4,8")]) 976 977(define_insn_and_split "*extendsi<mode>2_dot2" 978 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 979 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 980 (const_int 0))) 981 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") 982 (sign_extend:EXTSI (match_dup 1)))] 983 "rs6000_gen_cell_microcode" 984 "@ 985 extsw. %0,%1 986 #" 987 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 988 [(set (match_dup 0) 989 (sign_extend:EXTSI (match_dup 1))) 990 (set (match_dup 2) 991 (compare:CC (match_dup 0) 992 (const_int 0)))] 993 "" 994 [(set_attr "type" "exts") 995 (set_attr "dot" "yes") 996 (set_attr "length" "4,8")]) 997 998;; IBM 405, 440, 464 and 476 half-word multiplication operations. 999 1000(define_insn "*macchwc" 1001 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1002 (compare:CC (plus:SI (mult:SI (ashiftrt:SI 1003 (match_operand:SI 2 "gpc_reg_operand" "r") 1004 (const_int 16)) 1005 (sign_extend:SI 1006 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1007 (match_operand:SI 4 "gpc_reg_operand" "0")) 1008 (const_int 0))) 1009 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1010 (plus:SI (mult:SI (ashiftrt:SI 1011 (match_dup 2) 1012 (const_int 16)) 1013 (sign_extend:SI 1014 (match_dup 1))) 1015 (match_dup 4)))] 1016 "TARGET_MULHW" 1017 "macchw. %0,%1,%2" 1018 [(set_attr "type" "halfmul")]) 1019 1020(define_insn "*macchw" 1021 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1022 (plus:SI (mult:SI (ashiftrt:SI 1023 (match_operand:SI 2 "gpc_reg_operand" "r") 1024 (const_int 16)) 1025 (sign_extend:SI 1026 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1027 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1028 "TARGET_MULHW" 1029 "macchw %0,%1,%2" 1030 [(set_attr "type" "halfmul")]) 1031 1032(define_insn "*macchwuc" 1033 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1034 (compare:CC (plus:SI (mult:SI (lshiftrt:SI 1035 (match_operand:SI 2 "gpc_reg_operand" "r") 1036 (const_int 16)) 1037 (zero_extend:SI 1038 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1039 (match_operand:SI 4 "gpc_reg_operand" "0")) 1040 (const_int 0))) 1041 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1042 (plus:SI (mult:SI (lshiftrt:SI 1043 (match_dup 2) 1044 (const_int 16)) 1045 (zero_extend:SI 1046 (match_dup 1))) 1047 (match_dup 4)))] 1048 "TARGET_MULHW" 1049 "macchwu. %0,%1,%2" 1050 [(set_attr "type" "halfmul")]) 1051 1052(define_insn "*macchwu" 1053 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1054 (plus:SI (mult:SI (lshiftrt:SI 1055 (match_operand:SI 2 "gpc_reg_operand" "r") 1056 (const_int 16)) 1057 (zero_extend:SI 1058 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1059 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1060 "TARGET_MULHW" 1061 "macchwu %0,%1,%2" 1062 [(set_attr "type" "halfmul")]) 1063 1064(define_insn "*machhwc" 1065 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1066 (compare:CC (plus:SI (mult:SI (ashiftrt:SI 1067 (match_operand:SI 1 "gpc_reg_operand" "%r") 1068 (const_int 16)) 1069 (ashiftrt:SI 1070 (match_operand:SI 2 "gpc_reg_operand" "r") 1071 (const_int 16))) 1072 (match_operand:SI 4 "gpc_reg_operand" "0")) 1073 (const_int 0))) 1074 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1075 (plus:SI (mult:SI (ashiftrt:SI 1076 (match_dup 1) 1077 (const_int 16)) 1078 (ashiftrt:SI 1079 (match_dup 2) 1080 (const_int 16))) 1081 (match_dup 4)))] 1082 "TARGET_MULHW" 1083 "machhw. %0,%1,%2" 1084 [(set_attr "type" "halfmul")]) 1085 1086(define_insn "*machhw" 1087 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1088 (plus:SI (mult:SI (ashiftrt:SI 1089 (match_operand:SI 1 "gpc_reg_operand" "%r") 1090 (const_int 16)) 1091 (ashiftrt:SI 1092 (match_operand:SI 2 "gpc_reg_operand" "r") 1093 (const_int 16))) 1094 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1095 "TARGET_MULHW" 1096 "machhw %0,%1,%2" 1097 [(set_attr "type" "halfmul")]) 1098 1099(define_insn "*machhwuc" 1100 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1101 (compare:CC (plus:SI (mult:SI (lshiftrt:SI 1102 (match_operand:SI 1 "gpc_reg_operand" "%r") 1103 (const_int 16)) 1104 (lshiftrt:SI 1105 (match_operand:SI 2 "gpc_reg_operand" "r") 1106 (const_int 16))) 1107 (match_operand:SI 4 "gpc_reg_operand" "0")) 1108 (const_int 0))) 1109 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1110 (plus:SI (mult:SI (lshiftrt:SI 1111 (match_dup 1) 1112 (const_int 16)) 1113 (lshiftrt:SI 1114 (match_dup 2) 1115 (const_int 16))) 1116 (match_dup 4)))] 1117 "TARGET_MULHW" 1118 "machhwu. %0,%1,%2" 1119 [(set_attr "type" "halfmul")]) 1120 1121(define_insn "*machhwu" 1122 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1123 (plus:SI (mult:SI (lshiftrt:SI 1124 (match_operand:SI 1 "gpc_reg_operand" "%r") 1125 (const_int 16)) 1126 (lshiftrt:SI 1127 (match_operand:SI 2 "gpc_reg_operand" "r") 1128 (const_int 16))) 1129 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1130 "TARGET_MULHW" 1131 "machhwu %0,%1,%2" 1132 [(set_attr "type" "halfmul")]) 1133 1134(define_insn "*maclhwc" 1135 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1136 (compare:CC (plus:SI (mult:SI (sign_extend:SI 1137 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1138 (sign_extend:SI 1139 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1140 (match_operand:SI 4 "gpc_reg_operand" "0")) 1141 (const_int 0))) 1142 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1143 (plus:SI (mult:SI (sign_extend:SI 1144 (match_dup 1)) 1145 (sign_extend:SI 1146 (match_dup 2))) 1147 (match_dup 4)))] 1148 "TARGET_MULHW" 1149 "maclhw. %0,%1,%2" 1150 [(set_attr "type" "halfmul")]) 1151 1152(define_insn "*maclhw" 1153 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1154 (plus:SI (mult:SI (sign_extend:SI 1155 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1156 (sign_extend:SI 1157 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1158 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1159 "TARGET_MULHW" 1160 "maclhw %0,%1,%2" 1161 [(set_attr "type" "halfmul")]) 1162 1163(define_insn "*maclhwuc" 1164 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1165 (compare:CC (plus:SI (mult:SI (zero_extend:SI 1166 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1167 (zero_extend:SI 1168 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1169 (match_operand:SI 4 "gpc_reg_operand" "0")) 1170 (const_int 0))) 1171 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1172 (plus:SI (mult:SI (zero_extend:SI 1173 (match_dup 1)) 1174 (zero_extend:SI 1175 (match_dup 2))) 1176 (match_dup 4)))] 1177 "TARGET_MULHW" 1178 "maclhwu. %0,%1,%2" 1179 [(set_attr "type" "halfmul")]) 1180 1181(define_insn "*maclhwu" 1182 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1183 (plus:SI (mult:SI (zero_extend:SI 1184 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1185 (zero_extend:SI 1186 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1187 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1188 "TARGET_MULHW" 1189 "maclhwu %0,%1,%2" 1190 [(set_attr "type" "halfmul")]) 1191 1192(define_insn "*nmacchwc" 1193 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1194 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1195 (mult:SI (ashiftrt:SI 1196 (match_operand:SI 2 "gpc_reg_operand" "r") 1197 (const_int 16)) 1198 (sign_extend:SI 1199 (match_operand:HI 1 "gpc_reg_operand" "r")))) 1200 (const_int 0))) 1201 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1202 (minus:SI (match_dup 4) 1203 (mult:SI (ashiftrt:SI 1204 (match_dup 2) 1205 (const_int 16)) 1206 (sign_extend:SI 1207 (match_dup 1)))))] 1208 "TARGET_MULHW" 1209 "nmacchw. %0,%1,%2" 1210 [(set_attr "type" "halfmul")]) 1211 1212(define_insn "*nmacchw" 1213 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1214 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1215 (mult:SI (ashiftrt:SI 1216 (match_operand:SI 2 "gpc_reg_operand" "r") 1217 (const_int 16)) 1218 (sign_extend:SI 1219 (match_operand:HI 1 "gpc_reg_operand" "r")))))] 1220 "TARGET_MULHW" 1221 "nmacchw %0,%1,%2" 1222 [(set_attr "type" "halfmul")]) 1223 1224(define_insn "*nmachhwc" 1225 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1226 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1227 (mult:SI (ashiftrt:SI 1228 (match_operand:SI 1 "gpc_reg_operand" "%r") 1229 (const_int 16)) 1230 (ashiftrt:SI 1231 (match_operand:SI 2 "gpc_reg_operand" "r") 1232 (const_int 16)))) 1233 (const_int 0))) 1234 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1235 (minus:SI (match_dup 4) 1236 (mult:SI (ashiftrt:SI 1237 (match_dup 1) 1238 (const_int 16)) 1239 (ashiftrt:SI 1240 (match_dup 2) 1241 (const_int 16)))))] 1242 "TARGET_MULHW" 1243 "nmachhw. %0,%1,%2" 1244 [(set_attr "type" "halfmul")]) 1245 1246(define_insn "*nmachhw" 1247 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1248 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1249 (mult:SI (ashiftrt:SI 1250 (match_operand:SI 1 "gpc_reg_operand" "%r") 1251 (const_int 16)) 1252 (ashiftrt:SI 1253 (match_operand:SI 2 "gpc_reg_operand" "r") 1254 (const_int 16)))))] 1255 "TARGET_MULHW" 1256 "nmachhw %0,%1,%2" 1257 [(set_attr "type" "halfmul")]) 1258 1259(define_insn "*nmaclhwc" 1260 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1261 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1262 (mult:SI (sign_extend:SI 1263 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1264 (sign_extend:SI 1265 (match_operand:HI 2 "gpc_reg_operand" "r")))) 1266 (const_int 0))) 1267 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1268 (minus:SI (match_dup 4) 1269 (mult:SI (sign_extend:SI 1270 (match_dup 1)) 1271 (sign_extend:SI 1272 (match_dup 2)))))] 1273 "TARGET_MULHW" 1274 "nmaclhw. %0,%1,%2" 1275 [(set_attr "type" "halfmul")]) 1276 1277(define_insn "*nmaclhw" 1278 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1279 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1280 (mult:SI (sign_extend:SI 1281 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1282 (sign_extend:SI 1283 (match_operand:HI 2 "gpc_reg_operand" "r")))))] 1284 "TARGET_MULHW" 1285 "nmaclhw %0,%1,%2" 1286 [(set_attr "type" "halfmul")]) 1287 1288(define_insn "*mulchwc" 1289 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1290 (compare:CC (mult:SI (ashiftrt:SI 1291 (match_operand:SI 2 "gpc_reg_operand" "r") 1292 (const_int 16)) 1293 (sign_extend:SI 1294 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1295 (const_int 0))) 1296 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1297 (mult:SI (ashiftrt:SI 1298 (match_dup 2) 1299 (const_int 16)) 1300 (sign_extend:SI 1301 (match_dup 1))))] 1302 "TARGET_MULHW" 1303 "mulchw. %0,%1,%2" 1304 [(set_attr "type" "halfmul")]) 1305 1306(define_insn "*mulchw" 1307 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1308 (mult:SI (ashiftrt:SI 1309 (match_operand:SI 2 "gpc_reg_operand" "r") 1310 (const_int 16)) 1311 (sign_extend:SI 1312 (match_operand:HI 1 "gpc_reg_operand" "r"))))] 1313 "TARGET_MULHW" 1314 "mulchw %0,%1,%2" 1315 [(set_attr "type" "halfmul")]) 1316 1317(define_insn "*mulchwuc" 1318 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1319 (compare:CC (mult:SI (lshiftrt:SI 1320 (match_operand:SI 2 "gpc_reg_operand" "r") 1321 (const_int 16)) 1322 (zero_extend:SI 1323 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1324 (const_int 0))) 1325 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1326 (mult:SI (lshiftrt:SI 1327 (match_dup 2) 1328 (const_int 16)) 1329 (zero_extend:SI 1330 (match_dup 1))))] 1331 "TARGET_MULHW" 1332 "mulchwu. %0,%1,%2" 1333 [(set_attr "type" "halfmul")]) 1334 1335(define_insn "*mulchwu" 1336 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1337 (mult:SI (lshiftrt:SI 1338 (match_operand:SI 2 "gpc_reg_operand" "r") 1339 (const_int 16)) 1340 (zero_extend:SI 1341 (match_operand:HI 1 "gpc_reg_operand" "r"))))] 1342 "TARGET_MULHW" 1343 "mulchwu %0,%1,%2" 1344 [(set_attr "type" "halfmul")]) 1345 1346(define_insn "*mulhhwc" 1347 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1348 (compare:CC (mult:SI (ashiftrt:SI 1349 (match_operand:SI 1 "gpc_reg_operand" "%r") 1350 (const_int 16)) 1351 (ashiftrt:SI 1352 (match_operand:SI 2 "gpc_reg_operand" "r") 1353 (const_int 16))) 1354 (const_int 0))) 1355 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1356 (mult:SI (ashiftrt:SI 1357 (match_dup 1) 1358 (const_int 16)) 1359 (ashiftrt:SI 1360 (match_dup 2) 1361 (const_int 16))))] 1362 "TARGET_MULHW" 1363 "mulhhw. %0,%1,%2" 1364 [(set_attr "type" "halfmul")]) 1365 1366(define_insn "*mulhhw" 1367 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1368 (mult:SI (ashiftrt:SI 1369 (match_operand:SI 1 "gpc_reg_operand" "%r") 1370 (const_int 16)) 1371 (ashiftrt:SI 1372 (match_operand:SI 2 "gpc_reg_operand" "r") 1373 (const_int 16))))] 1374 "TARGET_MULHW" 1375 "mulhhw %0,%1,%2" 1376 [(set_attr "type" "halfmul")]) 1377 1378(define_insn "*mulhhwuc" 1379 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1380 (compare:CC (mult:SI (lshiftrt:SI 1381 (match_operand:SI 1 "gpc_reg_operand" "%r") 1382 (const_int 16)) 1383 (lshiftrt:SI 1384 (match_operand:SI 2 "gpc_reg_operand" "r") 1385 (const_int 16))) 1386 (const_int 0))) 1387 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1388 (mult:SI (lshiftrt:SI 1389 (match_dup 1) 1390 (const_int 16)) 1391 (lshiftrt:SI 1392 (match_dup 2) 1393 (const_int 16))))] 1394 "TARGET_MULHW" 1395 "mulhhwu. %0,%1,%2" 1396 [(set_attr "type" "halfmul")]) 1397 1398(define_insn "*mulhhwu" 1399 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1400 (mult:SI (lshiftrt:SI 1401 (match_operand:SI 1 "gpc_reg_operand" "%r") 1402 (const_int 16)) 1403 (lshiftrt:SI 1404 (match_operand:SI 2 "gpc_reg_operand" "r") 1405 (const_int 16))))] 1406 "TARGET_MULHW" 1407 "mulhhwu %0,%1,%2" 1408 [(set_attr "type" "halfmul")]) 1409 1410(define_insn "*mullhwc" 1411 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1412 (compare:CC (mult:SI (sign_extend:SI 1413 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1414 (sign_extend:SI 1415 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1416 (const_int 0))) 1417 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1418 (mult:SI (sign_extend:SI 1419 (match_dup 1)) 1420 (sign_extend:SI 1421 (match_dup 2))))] 1422 "TARGET_MULHW" 1423 "mullhw. %0,%1,%2" 1424 [(set_attr "type" "halfmul")]) 1425 1426(define_insn "*mullhw" 1427 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1428 (mult:SI (sign_extend:SI 1429 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1430 (sign_extend:SI 1431 (match_operand:HI 2 "gpc_reg_operand" "r"))))] 1432 "TARGET_MULHW" 1433 "mullhw %0,%1,%2" 1434 [(set_attr "type" "halfmul")]) 1435 1436(define_insn "*mullhwuc" 1437 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1438 (compare:CC (mult:SI (zero_extend:SI 1439 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1440 (zero_extend:SI 1441 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1442 (const_int 0))) 1443 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1444 (mult:SI (zero_extend:SI 1445 (match_dup 1)) 1446 (zero_extend:SI 1447 (match_dup 2))))] 1448 "TARGET_MULHW" 1449 "mullhwu. %0,%1,%2" 1450 [(set_attr "type" "halfmul")]) 1451 1452(define_insn "*mullhwu" 1453 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1454 (mult:SI (zero_extend:SI 1455 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1456 (zero_extend:SI 1457 (match_operand:HI 2 "gpc_reg_operand" "r"))))] 1458 "TARGET_MULHW" 1459 "mullhwu %0,%1,%2" 1460 [(set_attr "type" "halfmul")]) 1461 1462;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support. 1463(define_insn "dlmzb" 1464 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1465 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 1466 (match_operand:SI 2 "gpc_reg_operand" "r")] 1467 UNSPEC_DLMZB_CR)) 1468 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1469 (unspec:SI [(match_dup 1) 1470 (match_dup 2)] 1471 UNSPEC_DLMZB))] 1472 "TARGET_DLMZB" 1473 "dlmzb. %0,%1,%2") 1474 1475(define_expand "strlensi" 1476 [(set (match_operand:SI 0 "gpc_reg_operand" "") 1477 (unspec:SI [(match_operand:BLK 1 "general_operand" "") 1478 (match_operand:QI 2 "const_int_operand" "") 1479 (match_operand 3 "const_int_operand" "")] 1480 UNSPEC_DLMZB_STRLEN)) 1481 (clobber (match_scratch:CC 4 "=x"))] 1482 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size" 1483{ 1484 rtx result = operands[0]; 1485 rtx src = operands[1]; 1486 rtx search_char = operands[2]; 1487 rtx align = operands[3]; 1488 rtx addr, scratch_string, word1, word2, scratch_dlmzb; 1489 rtx loop_label, end_label, mem, cr0, cond; 1490 if (search_char != const0_rtx 1491 || GET_CODE (align) != CONST_INT 1492 || INTVAL (align) < 8) 1493 FAIL; 1494 word1 = gen_reg_rtx (SImode); 1495 word2 = gen_reg_rtx (SImode); 1496 scratch_dlmzb = gen_reg_rtx (SImode); 1497 scratch_string = gen_reg_rtx (Pmode); 1498 loop_label = gen_label_rtx (); 1499 end_label = gen_label_rtx (); 1500 addr = force_reg (Pmode, XEXP (src, 0)); 1501 emit_move_insn (scratch_string, addr); 1502 emit_label (loop_label); 1503 mem = change_address (src, SImode, scratch_string); 1504 emit_move_insn (word1, mem); 1505 emit_move_insn (word2, adjust_address (mem, SImode, 4)); 1506 cr0 = gen_rtx_REG (CCmode, CR0_REGNO); 1507 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0)); 1508 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx); 1509 emit_jump_insn (gen_rtx_SET (pc_rtx, 1510 gen_rtx_IF_THEN_ELSE (VOIDmode, 1511 cond, 1512 gen_rtx_LABEL_REF 1513 (VOIDmode, 1514 end_label), 1515 pc_rtx))); 1516 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8))); 1517 emit_jump_insn (gen_rtx_SET (pc_rtx, 1518 gen_rtx_LABEL_REF (VOIDmode, loop_label))); 1519 emit_barrier (); 1520 emit_label (end_label); 1521 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb)); 1522 emit_insn (gen_subsi3 (result, scratch_string, addr)); 1523 emit_insn (gen_addsi3 (result, result, constm1_rtx)); 1524 DONE; 1525}) 1526 1527;; Fixed-point arithmetic insns. 1528 1529(define_expand "add<mode>3" 1530 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 1531 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "") 1532 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))] 1533 "" 1534{ 1535 if (<MODE>mode == DImode && !TARGET_POWERPC64) 1536 { 1537 rtx lo0 = gen_lowpart (SImode, operands[0]); 1538 rtx lo1 = gen_lowpart (SImode, operands[1]); 1539 rtx lo2 = gen_lowpart (SImode, operands[2]); 1540 rtx hi0 = gen_highpart (SImode, operands[0]); 1541 rtx hi1 = gen_highpart (SImode, operands[1]); 1542 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]); 1543 1544 if (!reg_or_short_operand (lo2, SImode)) 1545 lo2 = force_reg (SImode, lo2); 1546 if (!adde_operand (hi2, SImode)) 1547 hi2 = force_reg (SImode, hi2); 1548 1549 emit_insn (gen_addsi3_carry (lo0, lo1, lo2)); 1550 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2)); 1551 DONE; 1552 } 1553 1554 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode)) 1555 { 1556 rtx tmp = ((!can_create_pseudo_p () 1557 || rtx_equal_p (operands[0], operands[1])) 1558 ? operands[0] : gen_reg_rtx (<MODE>mode)); 1559 1560 /* Adding a constant to r0 is not a valid insn, so use a different 1561 strategy in that case. */ 1562 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0) 1563 { 1564 if (operands[0] == operands[1]) 1565 FAIL; 1566 rs6000_emit_move (operands[0], operands[2], <MODE>mode); 1567 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0])); 1568 DONE; 1569 } 1570 1571 HOST_WIDE_INT val = INTVAL (operands[2]); 1572 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1573 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); 1574 1575 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest))) 1576 FAIL; 1577 1578 /* The ordering here is important for the prolog expander. 1579 When space is allocated from the stack, adding 'low' first may 1580 produce a temporary deallocation (which would be bad). */ 1581 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest))); 1582 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low))); 1583 DONE; 1584 } 1585}) 1586 1587(define_insn "*add<mode>3" 1588 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r") 1589 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b") 1590 (match_operand:GPR 2 "add_operand" "r,I,L")))] 1591 "" 1592 "@ 1593 add %0,%1,%2 1594 addi %0,%1,%2 1595 addis %0,%1,%v2" 1596 [(set_attr "type" "add")]) 1597 1598(define_insn "addsi3_high" 1599 [(set (match_operand:SI 0 "gpc_reg_operand" "=b") 1600 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") 1601 (high:SI (match_operand 2 "" ""))))] 1602 "TARGET_MACHO && !TARGET_64BIT" 1603 "addis %0,%1,ha16(%2)" 1604 [(set_attr "type" "add")]) 1605 1606(define_insn_and_split "*add<mode>3_dot" 1607 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1608 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 1609 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 1610 (const_int 0))) 1611 (clobber (match_scratch:GPR 0 "=r,r"))] 1612 "<MODE>mode == Pmode" 1613 "@ 1614 add. %0,%1,%2 1615 #" 1616 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1617 [(set (match_dup 0) 1618 (plus:GPR (match_dup 1) 1619 (match_dup 2))) 1620 (set (match_dup 3) 1621 (compare:CC (match_dup 0) 1622 (const_int 0)))] 1623 "" 1624 [(set_attr "type" "add") 1625 (set_attr "dot" "yes") 1626 (set_attr "length" "4,8")]) 1627 1628(define_insn_and_split "*add<mode>3_dot2" 1629 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1630 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 1631 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 1632 (const_int 0))) 1633 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1634 (plus:GPR (match_dup 1) 1635 (match_dup 2)))] 1636 "<MODE>mode == Pmode" 1637 "@ 1638 add. %0,%1,%2 1639 #" 1640 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1641 [(set (match_dup 0) 1642 (plus:GPR (match_dup 1) 1643 (match_dup 2))) 1644 (set (match_dup 3) 1645 (compare:CC (match_dup 0) 1646 (const_int 0)))] 1647 "" 1648 [(set_attr "type" "add") 1649 (set_attr "dot" "yes") 1650 (set_attr "length" "4,8")]) 1651 1652(define_insn_and_split "*add<mode>3_imm_dot" 1653 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1654 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b") 1655 (match_operand:GPR 2 "short_cint_operand" "I,I")) 1656 (const_int 0))) 1657 (clobber (match_scratch:GPR 0 "=r,r")) 1658 (clobber (reg:GPR CA_REGNO))] 1659 "<MODE>mode == Pmode" 1660 "@ 1661 addic. %0,%1,%2 1662 #" 1663 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1664 [(set (match_dup 0) 1665 (plus:GPR (match_dup 1) 1666 (match_dup 2))) 1667 (set (match_dup 3) 1668 (compare:CC (match_dup 0) 1669 (const_int 0)))] 1670 "" 1671 [(set_attr "type" "add") 1672 (set_attr "dot" "yes") 1673 (set_attr "length" "4,8")]) 1674 1675(define_insn_and_split "*add<mode>3_imm_dot2" 1676 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1677 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b") 1678 (match_operand:GPR 2 "short_cint_operand" "I,I")) 1679 (const_int 0))) 1680 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1681 (plus:GPR (match_dup 1) 1682 (match_dup 2))) 1683 (clobber (reg:GPR CA_REGNO))] 1684 "<MODE>mode == Pmode" 1685 "@ 1686 addic. %0,%1,%2 1687 #" 1688 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1689 [(set (match_dup 0) 1690 (plus:GPR (match_dup 1) 1691 (match_dup 2))) 1692 (set (match_dup 3) 1693 (compare:CC (match_dup 0) 1694 (const_int 0)))] 1695 "" 1696 [(set_attr "type" "add") 1697 (set_attr "dot" "yes") 1698 (set_attr "length" "4,8")]) 1699 1700;; Split an add that we can't do in one insn into two insns, each of which 1701;; does one 16-bit part. This is used by combine. Note that the low-order 1702;; add should be last in case the result gets used in an address. 1703 1704(define_split 1705 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 1706 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "") 1707 (match_operand:GPR 2 "non_add_cint_operand" "")))] 1708 "" 1709 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3))) 1710 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))] 1711{ 1712 HOST_WIDE_INT val = INTVAL (operands[2]); 1713 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1714 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); 1715 1716 operands[4] = GEN_INT (low); 1717 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest))) 1718 operands[3] = GEN_INT (rest); 1719 else if (can_create_pseudo_p ()) 1720 { 1721 operands[3] = gen_reg_rtx (DImode); 1722 emit_move_insn (operands[3], operands[2]); 1723 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3])); 1724 DONE; 1725 } 1726 else 1727 FAIL; 1728}) 1729 1730 1731(define_insn "add<mode>3_carry" 1732 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1733 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1734 (match_operand:P 2 "reg_or_short_operand" "rI"))) 1735 (set (reg:P CA_REGNO) 1736 (ltu:P (plus:P (match_dup 1) 1737 (match_dup 2)) 1738 (match_dup 1)))] 1739 "" 1740 "add%I2c %0,%1,%2" 1741 [(set_attr "type" "add")]) 1742 1743(define_insn "*add<mode>3_imm_carry_pos" 1744 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1745 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1746 (match_operand:P 2 "short_cint_operand" "n"))) 1747 (set (reg:P CA_REGNO) 1748 (geu:P (match_dup 1) 1749 (match_operand:P 3 "const_int_operand" "n")))] 1750 "INTVAL (operands[2]) > 0 1751 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0" 1752 "addic %0,%1,%2" 1753 [(set_attr "type" "add")]) 1754 1755(define_insn "*add<mode>3_imm_carry_0" 1756 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1757 (match_operand:P 1 "gpc_reg_operand" "r")) 1758 (set (reg:P CA_REGNO) 1759 (const_int 0))] 1760 "" 1761 "addic %0,%1,0" 1762 [(set_attr "type" "add")]) 1763 1764(define_insn "*add<mode>3_imm_carry_m1" 1765 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1766 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1767 (const_int -1))) 1768 (set (reg:P CA_REGNO) 1769 (ne:P (match_dup 1) 1770 (const_int 0)))] 1771 "" 1772 "addic %0,%1,-1" 1773 [(set_attr "type" "add")]) 1774 1775(define_insn "*add<mode>3_imm_carry_neg" 1776 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1777 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1778 (match_operand:P 2 "short_cint_operand" "n"))) 1779 (set (reg:P CA_REGNO) 1780 (gtu:P (match_dup 1) 1781 (match_operand:P 3 "const_int_operand" "n")))] 1782 "INTVAL (operands[2]) < 0 1783 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1" 1784 "addic %0,%1,%2" 1785 [(set_attr "type" "add")]) 1786 1787 1788(define_expand "add<mode>3_carry_in" 1789 [(parallel [ 1790 (set (match_operand:GPR 0 "gpc_reg_operand") 1791 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand") 1792 (match_operand:GPR 2 "adde_operand")) 1793 (reg:GPR CA_REGNO))) 1794 (clobber (reg:GPR CA_REGNO))])] 1795 "" 1796{ 1797 if (operands[2] == const0_rtx) 1798 { 1799 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1])); 1800 DONE; 1801 } 1802 if (operands[2] == constm1_rtx) 1803 { 1804 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1])); 1805 DONE; 1806 } 1807}) 1808 1809(define_insn "*add<mode>3_carry_in_internal" 1810 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1811 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1812 (match_operand:GPR 2 "gpc_reg_operand" "r")) 1813 (reg:GPR CA_REGNO))) 1814 (clobber (reg:GPR CA_REGNO))] 1815 "" 1816 "adde %0,%1,%2" 1817 [(set_attr "type" "add")]) 1818 1819(define_insn "add<mode>3_carry_in_0" 1820 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1821 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1822 (reg:GPR CA_REGNO))) 1823 (clobber (reg:GPR CA_REGNO))] 1824 "" 1825 "addze %0,%1" 1826 [(set_attr "type" "add")]) 1827 1828(define_insn "add<mode>3_carry_in_m1" 1829 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1830 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1831 (reg:GPR CA_REGNO)) 1832 (const_int -1))) 1833 (clobber (reg:GPR CA_REGNO))] 1834 "" 1835 "addme %0,%1" 1836 [(set_attr "type" "add")]) 1837 1838 1839(define_expand "one_cmpl<mode>2" 1840 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 1841 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))] 1842 "" 1843{ 1844 if (<MODE>mode == DImode && !TARGET_POWERPC64) 1845 { 1846 rs6000_split_logical (operands, NOT, false, false, false); 1847 DONE; 1848 } 1849}) 1850 1851(define_insn "*one_cmpl<mode>2" 1852 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1853 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 1854 "" 1855 "not %0,%1") 1856 1857(define_insn_and_split "*one_cmpl<mode>2_dot" 1858 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1859 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 1860 (const_int 0))) 1861 (clobber (match_scratch:GPR 0 "=r,r"))] 1862 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 1863 "@ 1864 not. %0,%1 1865 #" 1866 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1867 [(set (match_dup 0) 1868 (not:GPR (match_dup 1))) 1869 (set (match_dup 2) 1870 (compare:CC (match_dup 0) 1871 (const_int 0)))] 1872 "" 1873 [(set_attr "type" "logical") 1874 (set_attr "dot" "yes") 1875 (set_attr "length" "4,8")]) 1876 1877(define_insn_and_split "*one_cmpl<mode>2_dot2" 1878 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1879 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 1880 (const_int 0))) 1881 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1882 (not:GPR (match_dup 1)))] 1883 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 1884 "@ 1885 not. %0,%1 1886 #" 1887 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1888 [(set (match_dup 0) 1889 (not:GPR (match_dup 1))) 1890 (set (match_dup 2) 1891 (compare:CC (match_dup 0) 1892 (const_int 0)))] 1893 "" 1894 [(set_attr "type" "logical") 1895 (set_attr "dot" "yes") 1896 (set_attr "length" "4,8")]) 1897 1898 1899(define_expand "sub<mode>3" 1900 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 1901 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "") 1902 (match_operand:SDI 2 "gpc_reg_operand" "")))] 1903 "" 1904{ 1905 if (<MODE>mode == DImode && !TARGET_POWERPC64) 1906 { 1907 rtx lo0 = gen_lowpart (SImode, operands[0]); 1908 rtx lo1 = gen_lowpart (SImode, operands[1]); 1909 rtx lo2 = gen_lowpart (SImode, operands[2]); 1910 rtx hi0 = gen_highpart (SImode, operands[0]); 1911 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]); 1912 rtx hi2 = gen_highpart (SImode, operands[2]); 1913 1914 if (!reg_or_short_operand (lo1, SImode)) 1915 lo1 = force_reg (SImode, lo1); 1916 if (!adde_operand (hi1, SImode)) 1917 hi1 = force_reg (SImode, hi1); 1918 1919 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1)); 1920 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1)); 1921 DONE; 1922 } 1923 1924 if (short_cint_operand (operands[1], <MODE>mode)) 1925 { 1926 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1])); 1927 DONE; 1928 } 1929}) 1930 1931(define_insn "*subf<mode>3" 1932 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1933 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r") 1934 (match_operand:GPR 1 "gpc_reg_operand" "r")))] 1935 "" 1936 "subf %0,%1,%2" 1937 [(set_attr "type" "add")]) 1938 1939(define_insn_and_split "*subf<mode>3_dot" 1940 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1941 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r") 1942 (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 1943 (const_int 0))) 1944 (clobber (match_scratch:GPR 0 "=r,r"))] 1945 "<MODE>mode == Pmode" 1946 "@ 1947 subf. %0,%1,%2 1948 #" 1949 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1950 [(set (match_dup 0) 1951 (minus:GPR (match_dup 2) 1952 (match_dup 1))) 1953 (set (match_dup 3) 1954 (compare:CC (match_dup 0) 1955 (const_int 0)))] 1956 "" 1957 [(set_attr "type" "add") 1958 (set_attr "dot" "yes") 1959 (set_attr "length" "4,8")]) 1960 1961(define_insn_and_split "*subf<mode>3_dot2" 1962 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1963 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r") 1964 (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 1965 (const_int 0))) 1966 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1967 (minus:GPR (match_dup 2) 1968 (match_dup 1)))] 1969 "<MODE>mode == Pmode" 1970 "@ 1971 subf. %0,%1,%2 1972 #" 1973 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1974 [(set (match_dup 0) 1975 (minus:GPR (match_dup 2) 1976 (match_dup 1))) 1977 (set (match_dup 3) 1978 (compare:CC (match_dup 0) 1979 (const_int 0)))] 1980 "" 1981 [(set_attr "type" "add") 1982 (set_attr "dot" "yes") 1983 (set_attr "length" "4,8")]) 1984 1985(define_insn "subf<mode>3_imm" 1986 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1987 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I") 1988 (match_operand:GPR 1 "gpc_reg_operand" "r"))) 1989 (clobber (reg:GPR CA_REGNO))] 1990 "" 1991 "subfic %0,%1,%2" 1992 [(set_attr "type" "add")]) 1993 1994 1995(define_insn "subf<mode>3_carry" 1996 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1997 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI") 1998 (match_operand:P 1 "gpc_reg_operand" "r"))) 1999 (set (reg:P CA_REGNO) 2000 (leu:P (match_dup 1) 2001 (match_dup 2)))] 2002 "" 2003 "subf%I2c %0,%1,%2" 2004 [(set_attr "type" "add")]) 2005 2006(define_insn "*subf<mode>3_imm_carry_0" 2007 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2008 (neg:P (match_operand:P 1 "gpc_reg_operand" "r"))) 2009 (set (reg:P CA_REGNO) 2010 (eq:P (match_dup 1) 2011 (const_int 0)))] 2012 "" 2013 "subfic %0,%1,0" 2014 [(set_attr "type" "add")]) 2015 2016(define_insn "*subf<mode>3_imm_carry_m1" 2017 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2018 (not:P (match_operand:P 1 "gpc_reg_operand" "r"))) 2019 (set (reg:P CA_REGNO) 2020 (const_int 1))] 2021 "" 2022 "subfic %0,%1,-1" 2023 [(set_attr "type" "add")]) 2024 2025 2026(define_expand "subf<mode>3_carry_in" 2027 [(parallel [ 2028 (set (match_operand:GPR 0 "gpc_reg_operand") 2029 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand")) 2030 (reg:GPR CA_REGNO)) 2031 (match_operand:GPR 2 "adde_operand"))) 2032 (clobber (reg:GPR CA_REGNO))])] 2033 "" 2034{ 2035 if (operands[2] == const0_rtx) 2036 { 2037 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1])); 2038 DONE; 2039 } 2040 if (operands[2] == constm1_rtx) 2041 { 2042 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1])); 2043 DONE; 2044 } 2045}) 2046 2047(define_insn "*subf<mode>3_carry_in_internal" 2048 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2049 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 2050 (reg:GPR CA_REGNO)) 2051 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 2052 (clobber (reg:GPR CA_REGNO))] 2053 "" 2054 "subfe %0,%1,%2" 2055 [(set_attr "type" "add")]) 2056 2057(define_insn "subf<mode>3_carry_in_0" 2058 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2059 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 2060 (reg:GPR CA_REGNO))) 2061 (clobber (reg:GPR CA_REGNO))] 2062 "" 2063 "subfze %0,%1" 2064 [(set_attr "type" "add")]) 2065 2066(define_insn "subf<mode>3_carry_in_m1" 2067 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2068 (plus:GPR (minus:GPR (reg:GPR CA_REGNO) 2069 (match_operand:GPR 1 "gpc_reg_operand" "r")) 2070 (const_int -2))) 2071 (clobber (reg:GPR CA_REGNO))] 2072 "" 2073 "subfme %0,%1" 2074 [(set_attr "type" "add")]) 2075 2076(define_insn "subf<mode>3_carry_in_xx" 2077 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2078 (plus:GPR (reg:GPR CA_REGNO) 2079 (const_int -1))) 2080 (clobber (reg:GPR CA_REGNO))] 2081 "" 2082 "subfe %0,%0,%0" 2083 [(set_attr "type" "add")]) 2084 2085 2086(define_insn "neg<mode>2" 2087 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2088 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2089 "" 2090 "neg %0,%1" 2091 [(set_attr "type" "add")]) 2092 2093(define_insn_and_split "*neg<mode>2_dot" 2094 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2095 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2096 (const_int 0))) 2097 (clobber (match_scratch:GPR 0 "=r,r"))] 2098 "<MODE>mode == Pmode" 2099 "@ 2100 neg. %0,%1 2101 #" 2102 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2103 [(set (match_dup 0) 2104 (neg:GPR (match_dup 1))) 2105 (set (match_dup 2) 2106 (compare:CC (match_dup 0) 2107 (const_int 0)))] 2108 "" 2109 [(set_attr "type" "add") 2110 (set_attr "dot" "yes") 2111 (set_attr "length" "4,8")]) 2112 2113(define_insn_and_split "*neg<mode>2_dot2" 2114 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2115 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2116 (const_int 0))) 2117 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2118 (neg:GPR (match_dup 1)))] 2119 "<MODE>mode == Pmode" 2120 "@ 2121 neg. %0,%1 2122 #" 2123 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2124 [(set (match_dup 0) 2125 (neg:GPR (match_dup 1))) 2126 (set (match_dup 2) 2127 (compare:CC (match_dup 0) 2128 (const_int 0)))] 2129 "" 2130 [(set_attr "type" "add") 2131 (set_attr "dot" "yes") 2132 (set_attr "length" "4,8")]) 2133 2134 2135(define_insn "clz<mode>2" 2136 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2137 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2138 "" 2139 "cntlz<wd> %0,%1" 2140 [(set_attr "type" "cntlz")]) 2141 2142(define_expand "ctz<mode>2" 2143 [(set (match_dup 2) 2144 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" ""))) 2145 (set (match_dup 3) 2146 (and:GPR (match_dup 1) 2147 (match_dup 2))) 2148 (set (match_dup 4) 2149 (clz:GPR (match_dup 3))) 2150 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "") 2151 (minus:GPR (match_dup 5) 2152 (match_dup 4))) 2153 (clobber (reg:GPR CA_REGNO))])] 2154 "" 2155{ 2156 if (TARGET_CTZ) 2157 { 2158 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1])); 2159 DONE; 2160 } 2161 2162 operands[2] = gen_reg_rtx (<MODE>mode); 2163 operands[3] = gen_reg_rtx (<MODE>mode); 2164 operands[4] = gen_reg_rtx (<MODE>mode); 2165 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1); 2166}) 2167 2168(define_insn "ctz<mode>2_hw" 2169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2170 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2171 "TARGET_CTZ" 2172 "cnttz<wd> %0,%1" 2173 [(set_attr "type" "cntlz")]) 2174 2175(define_expand "ffs<mode>2" 2176 [(set (match_dup 2) 2177 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" ""))) 2178 (set (match_dup 3) 2179 (and:GPR (match_dup 1) 2180 (match_dup 2))) 2181 (set (match_dup 4) 2182 (clz:GPR (match_dup 3))) 2183 (parallel [(set (match_operand:GPR 0 "gpc_reg_operand" "") 2184 (minus:GPR (match_dup 5) 2185 (match_dup 4))) 2186 (clobber (reg:GPR CA_REGNO))])] 2187 "" 2188{ 2189 operands[2] = gen_reg_rtx (<MODE>mode); 2190 operands[3] = gen_reg_rtx (<MODE>mode); 2191 operands[4] = gen_reg_rtx (<MODE>mode); 2192 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)); 2193}) 2194 2195 2196(define_expand "popcount<mode>2" 2197 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 2198 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] 2199 "TARGET_POPCNTB || TARGET_POPCNTD" 2200{ 2201 rs6000_emit_popcount (operands[0], operands[1]); 2202 DONE; 2203}) 2204 2205(define_insn "popcntb<mode>2" 2206 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2207 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] 2208 UNSPEC_POPCNTB))] 2209 "TARGET_POPCNTB" 2210 "popcntb %0,%1" 2211 [(set_attr "type" "popcnt")]) 2212 2213(define_insn "popcntd<mode>2" 2214 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2215 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2216 "TARGET_POPCNTD" 2217 "popcnt<wd> %0,%1" 2218 [(set_attr "type" "popcnt")]) 2219 2220 2221(define_expand "parity<mode>2" 2222 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 2223 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] 2224 "TARGET_POPCNTB" 2225{ 2226 rs6000_emit_parity (operands[0], operands[1]); 2227 DONE; 2228}) 2229 2230(define_insn "parity<mode>2_cmpb" 2231 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2232 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))] 2233 "TARGET_CMPB && TARGET_POPCNTB" 2234 "prty<wd> %0,%1" 2235 [(set_attr "type" "popcnt")]) 2236 2237 2238;; Since the hardware zeros the upper part of the register, save generating the 2239;; AND immediate if we are converting to unsigned 2240(define_insn "*bswap<mode>2_extenddi" 2241 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2242 (zero_extend:DI 2243 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))] 2244 "TARGET_POWERPC64" 2245 "l<wd>brx %0,%y1" 2246 [(set_attr "length" "4") 2247 (set_attr "type" "load")]) 2248 2249(define_insn "*bswaphi2_extendsi" 2250 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2251 (zero_extend:SI 2252 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))] 2253 "" 2254 "lhbrx %0,%y1" 2255 [(set_attr "length" "4") 2256 (set_attr "type" "load")]) 2257 2258;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents 2259;; the register allocator from converting a gpr<-gpr swap into a store and then 2260;; load with byte swap, which can be slower than doing it in the registers. It 2261;; also prevents certain failures with the RELOAD register allocator. 2262 2263(define_expand "bswap<mode>2" 2264 [(use (match_operand:HSI 0 "reg_or_mem_operand")) 2265 (use (match_operand:HSI 1 "reg_or_mem_operand"))] 2266 "" 2267{ 2268 rtx dest = operands[0]; 2269 rtx src = operands[1]; 2270 2271 if (!REG_P (dest) && !REG_P (src)) 2272 src = force_reg (<MODE>mode, src); 2273 2274 if (MEM_P (src)) 2275 emit_insn (gen_bswap<mode>2_load (dest, src)); 2276 else if (MEM_P (dest)) 2277 emit_insn (gen_bswap<mode>2_store (dest, src)); 2278 else 2279 emit_insn (gen_bswap<mode>2_reg (dest, src)); 2280 DONE; 2281}) 2282 2283(define_insn "bswap<mode>2_load" 2284 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r") 2285 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))] 2286 "" 2287 "l<wd>brx %0,%y1" 2288 [(set_attr "type" "load")]) 2289 2290(define_insn "bswap<mode>2_store" 2291 [(set (match_operand:HSI 0 "memory_operand" "=Z") 2292 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))] 2293 "" 2294 "st<wd>brx %1,%y0" 2295 [(set_attr "type" "store")]) 2296 2297(define_insn_and_split "bswaphi2_reg" 2298 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r") 2299 (bswap:HI 2300 (match_operand:HI 1 "gpc_reg_operand" "r"))) 2301 (clobber (match_scratch:SI 2 "=&r"))] 2302 "" 2303 "#" 2304 "reload_completed" 2305 [(set (match_dup 3) 2306 (and:SI (lshiftrt:SI (match_dup 4) 2307 (const_int 8)) 2308 (const_int 255))) 2309 (set (match_dup 2) 2310 (and:SI (ashift:SI (match_dup 4) 2311 (const_int 8)) 2312 (const_int 65280))) ;; 0xff00 2313 (set (match_dup 3) 2314 (ior:SI (match_dup 3) 2315 (match_dup 2)))] 2316{ 2317 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0); 2318 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 2319} 2320 [(set_attr "length" "12") 2321 (set_attr "type" "*")]) 2322 2323;; We are always BITS_BIG_ENDIAN, so the bit positions below in 2324;; zero_extract insns do not change for -mlittle. 2325(define_insn_and_split "bswapsi2_reg" 2326 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") 2327 (bswap:SI 2328 (match_operand:SI 1 "gpc_reg_operand" "r")))] 2329 "" 2330 "#" 2331 "reload_completed" 2332 [(set (match_dup 0) ; DABC 2333 (rotate:SI (match_dup 1) 2334 (const_int 24))) 2335 (set (match_dup 0) ; DCBC 2336 (ior:SI (and:SI (ashift:SI (match_dup 1) 2337 (const_int 8)) 2338 (const_int 16711680)) 2339 (and:SI (match_dup 0) 2340 (const_int -16711681)))) 2341 (set (match_dup 0) ; DCBA 2342 (ior:SI (and:SI (lshiftrt:SI (match_dup 1) 2343 (const_int 24)) 2344 (const_int 255)) 2345 (and:SI (match_dup 0) 2346 (const_int -256))))] 2347 "") 2348 2349;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like 2350;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more 2351;; complex code. 2352 2353(define_expand "bswapdi2" 2354 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "") 2355 (bswap:DI 2356 (match_operand:DI 1 "reg_or_mem_operand" ""))) 2357 (clobber (match_scratch:DI 2 "")) 2358 (clobber (match_scratch:DI 3 ""))])] 2359 "" 2360{ 2361 rtx dest = operands[0]; 2362 rtx src = operands[1]; 2363 2364 if (!REG_P (dest) && !REG_P (src)) 2365 operands[1] = src = force_reg (DImode, src); 2366 2367 if (TARGET_POWERPC64 && TARGET_LDBRX) 2368 { 2369 if (MEM_P (src)) 2370 emit_insn (gen_bswapdi2_load (dest, src)); 2371 else if (MEM_P (dest)) 2372 emit_insn (gen_bswapdi2_store (dest, src)); 2373 else 2374 emit_insn (gen_bswapdi2_reg (dest, src)); 2375 DONE; 2376 } 2377 2378 if (!TARGET_POWERPC64) 2379 { 2380 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode 2381 that uses 64-bit registers needs the same scratch registers as 64-bit 2382 mode. */ 2383 emit_insn (gen_bswapdi2_32bit (dest, src)); 2384 DONE; 2385 } 2386}) 2387 2388;; Power7/cell has ldbrx/stdbrx, so use it directly 2389(define_insn "bswapdi2_load" 2390 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2391 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))] 2392 "TARGET_POWERPC64 && TARGET_LDBRX" 2393 "ldbrx %0,%y1" 2394 [(set_attr "type" "load")]) 2395 2396(define_insn "bswapdi2_store" 2397 [(set (match_operand:DI 0 "memory_operand" "=Z") 2398 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] 2399 "TARGET_POWERPC64 && TARGET_LDBRX" 2400 "stdbrx %1,%y0" 2401 [(set_attr "type" "store")]) 2402 2403(define_insn "bswapdi2_reg" 2404 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") 2405 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) 2406 (clobber (match_scratch:DI 2 "=&r")) 2407 (clobber (match_scratch:DI 3 "=&r"))] 2408 "TARGET_POWERPC64 && TARGET_LDBRX" 2409 "#" 2410 [(set_attr "length" "36")]) 2411 2412;; Non-power7/cell, fall back to use lwbrx/stwbrx 2413(define_insn "*bswapdi2_64bit" 2414 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r") 2415 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) 2416 (clobber (match_scratch:DI 2 "=&b,&b,&r")) 2417 (clobber (match_scratch:DI 3 "=&r,&r,&r"))] 2418 "TARGET_POWERPC64 && !TARGET_LDBRX 2419 && (REG_P (operands[0]) || REG_P (operands[1])) 2420 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) 2421 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))" 2422 "#" 2423 [(set_attr "length" "16,12,36")]) 2424 2425(define_split 2426 [(set (match_operand:DI 0 "gpc_reg_operand" "") 2427 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" ""))) 2428 (clobber (match_operand:DI 2 "gpc_reg_operand" "")) 2429 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] 2430 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" 2431 [(const_int 0)] 2432 " 2433{ 2434 rtx dest = operands[0]; 2435 rtx src = operands[1]; 2436 rtx op2 = operands[2]; 2437 rtx op3 = operands[3]; 2438 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, 2439 BYTES_BIG_ENDIAN ? 4 : 0); 2440 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode, 2441 BYTES_BIG_ENDIAN ? 4 : 0); 2442 rtx addr1; 2443 rtx addr2; 2444 rtx word1; 2445 rtx word2; 2446 2447 addr1 = XEXP (src, 0); 2448 if (GET_CODE (addr1) == PLUS) 2449 { 2450 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2451 if (TARGET_AVOID_XFORM) 2452 { 2453 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2454 addr2 = op2; 2455 } 2456 else 2457 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); 2458 } 2459 else if (TARGET_AVOID_XFORM) 2460 { 2461 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2462 addr2 = op2; 2463 } 2464 else 2465 { 2466 emit_move_insn (op2, GEN_INT (4)); 2467 addr2 = gen_rtx_PLUS (Pmode, op2, addr1); 2468 } 2469 2470 word1 = change_address (src, SImode, addr1); 2471 word2 = change_address (src, SImode, addr2); 2472 2473 if (BYTES_BIG_ENDIAN) 2474 { 2475 emit_insn (gen_bswapsi2 (op3_32, word2)); 2476 emit_insn (gen_bswapsi2 (dest_32, word1)); 2477 } 2478 else 2479 { 2480 emit_insn (gen_bswapsi2 (op3_32, word1)); 2481 emit_insn (gen_bswapsi2 (dest_32, word2)); 2482 } 2483 2484 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32))); 2485 emit_insn (gen_iordi3 (dest, dest, op3)); 2486 DONE; 2487}") 2488 2489(define_split 2490 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "") 2491 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) 2492 (clobber (match_operand:DI 2 "gpc_reg_operand" "")) 2493 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] 2494 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" 2495 [(const_int 0)] 2496 " 2497{ 2498 rtx dest = operands[0]; 2499 rtx src = operands[1]; 2500 rtx op2 = operands[2]; 2501 rtx op3 = operands[3]; 2502 rtx src_si = simplify_gen_subreg (SImode, src, DImode, 2503 BYTES_BIG_ENDIAN ? 4 : 0); 2504 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 2505 BYTES_BIG_ENDIAN ? 4 : 0); 2506 rtx addr1; 2507 rtx addr2; 2508 rtx word1; 2509 rtx word2; 2510 2511 addr1 = XEXP (dest, 0); 2512 if (GET_CODE (addr1) == PLUS) 2513 { 2514 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2515 if (TARGET_AVOID_XFORM) 2516 { 2517 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2518 addr2 = op2; 2519 } 2520 else 2521 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); 2522 } 2523 else if (TARGET_AVOID_XFORM) 2524 { 2525 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2526 addr2 = op2; 2527 } 2528 else 2529 { 2530 emit_move_insn (op2, GEN_INT (4)); 2531 addr2 = gen_rtx_PLUS (Pmode, op2, addr1); 2532 } 2533 2534 word1 = change_address (dest, SImode, addr1); 2535 word2 = change_address (dest, SImode, addr2); 2536 2537 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32))); 2538 2539 if (BYTES_BIG_ENDIAN) 2540 { 2541 emit_insn (gen_bswapsi2 (word1, src_si)); 2542 emit_insn (gen_bswapsi2 (word2, op3_si)); 2543 } 2544 else 2545 { 2546 emit_insn (gen_bswapsi2 (word2, src_si)); 2547 emit_insn (gen_bswapsi2 (word1, op3_si)); 2548 } 2549 DONE; 2550}") 2551 2552(define_split 2553 [(set (match_operand:DI 0 "gpc_reg_operand" "") 2554 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) 2555 (clobber (match_operand:DI 2 "gpc_reg_operand" "")) 2556 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] 2557 "TARGET_POWERPC64 && reload_completed" 2558 [(const_int 0)] 2559 " 2560{ 2561 rtx dest = operands[0]; 2562 rtx src = operands[1]; 2563 rtx op2 = operands[2]; 2564 rtx op3 = operands[3]; 2565 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0; 2566 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off); 2567 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off); 2568 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off); 2569 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off); 2570 2571 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32))); 2572 emit_insn (gen_bswapsi2 (dest_si, src_si)); 2573 emit_insn (gen_bswapsi2 (op3_si, op2_si)); 2574 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32))); 2575 emit_insn (gen_iordi3 (dest, dest, op3)); 2576 DONE; 2577}") 2578 2579(define_insn "bswapdi2_32bit" 2580 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r") 2581 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) 2582 (clobber (match_scratch:SI 2 "=&b,&b,X"))] 2583 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))" 2584 "#" 2585 [(set_attr "length" "16,12,36")]) 2586 2587(define_split 2588 [(set (match_operand:DI 0 "gpc_reg_operand" "") 2589 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" ""))) 2590 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))] 2591 "!TARGET_POWERPC64 && reload_completed" 2592 [(const_int 0)] 2593 " 2594{ 2595 rtx dest = operands[0]; 2596 rtx src = operands[1]; 2597 rtx op2 = operands[2]; 2598 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); 2599 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); 2600 rtx addr1; 2601 rtx addr2; 2602 rtx word1; 2603 rtx word2; 2604 2605 addr1 = XEXP (src, 0); 2606 if (GET_CODE (addr1) == PLUS) 2607 { 2608 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2609 if (TARGET_AVOID_XFORM 2610 || REGNO (XEXP (addr1, 1)) == REGNO (dest2)) 2611 { 2612 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2613 addr2 = op2; 2614 } 2615 else 2616 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); 2617 } 2618 else if (TARGET_AVOID_XFORM 2619 || REGNO (addr1) == REGNO (dest2)) 2620 { 2621 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2622 addr2 = op2; 2623 } 2624 else 2625 { 2626 emit_move_insn (op2, GEN_INT (4)); 2627 addr2 = gen_rtx_PLUS (SImode, op2, addr1); 2628 } 2629 2630 word1 = change_address (src, SImode, addr1); 2631 word2 = change_address (src, SImode, addr2); 2632 2633 emit_insn (gen_bswapsi2 (dest2, word1)); 2634 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed, 2635 thus allowing us to omit an early clobber on the output. */ 2636 emit_insn (gen_bswapsi2 (dest1, word2)); 2637 DONE; 2638}") 2639 2640(define_split 2641 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "") 2642 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) 2643 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))] 2644 "!TARGET_POWERPC64 && reload_completed" 2645 [(const_int 0)] 2646 " 2647{ 2648 rtx dest = operands[0]; 2649 rtx src = operands[1]; 2650 rtx op2 = operands[2]; 2651 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); 2652 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); 2653 rtx addr1; 2654 rtx addr2; 2655 rtx word1; 2656 rtx word2; 2657 2658 addr1 = XEXP (dest, 0); 2659 if (GET_CODE (addr1) == PLUS) 2660 { 2661 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2662 if (TARGET_AVOID_XFORM) 2663 { 2664 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2665 addr2 = op2; 2666 } 2667 else 2668 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); 2669 } 2670 else if (TARGET_AVOID_XFORM) 2671 { 2672 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2673 addr2 = op2; 2674 } 2675 else 2676 { 2677 emit_move_insn (op2, GEN_INT (4)); 2678 addr2 = gen_rtx_PLUS (SImode, op2, addr1); 2679 } 2680 2681 word1 = change_address (dest, SImode, addr1); 2682 word2 = change_address (dest, SImode, addr2); 2683 2684 emit_insn (gen_bswapsi2 (word2, src1)); 2685 emit_insn (gen_bswapsi2 (word1, src2)); 2686 DONE; 2687}") 2688 2689(define_split 2690 [(set (match_operand:DI 0 "gpc_reg_operand" "") 2691 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) 2692 (clobber (match_operand:SI 2 "" ""))] 2693 "!TARGET_POWERPC64 && reload_completed" 2694 [(const_int 0)] 2695 " 2696{ 2697 rtx dest = operands[0]; 2698 rtx src = operands[1]; 2699 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); 2700 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); 2701 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); 2702 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); 2703 2704 emit_insn (gen_bswapsi2 (dest1, src2)); 2705 emit_insn (gen_bswapsi2 (dest2, src1)); 2706 DONE; 2707}") 2708 2709 2710(define_insn "mul<mode>3" 2711 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2712 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 2713 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))] 2714 "" 2715 "@ 2716 mull<wd> %0,%1,%2 2717 mulli %0,%1,%2" 2718 [(set_attr "type" "mul") 2719 (set (attr "size") 2720 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "") 2721 (const_string "8") 2722 (match_operand:GPR 2 "short_cint_operand" "") 2723 (const_string "16")] 2724 (const_string "<bits>")))]) 2725 2726(define_insn_and_split "*mul<mode>3_dot" 2727 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2728 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 2729 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 2730 (const_int 0))) 2731 (clobber (match_scratch:GPR 0 "=r,r"))] 2732 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 2733 "@ 2734 mull<wd>. %0,%1,%2 2735 #" 2736 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2737 [(set (match_dup 0) 2738 (mult:GPR (match_dup 1) 2739 (match_dup 2))) 2740 (set (match_dup 3) 2741 (compare:CC (match_dup 0) 2742 (const_int 0)))] 2743 "" 2744 [(set_attr "type" "mul") 2745 (set_attr "size" "<bits>") 2746 (set_attr "dot" "yes") 2747 (set_attr "length" "4,8")]) 2748 2749(define_insn_and_split "*mul<mode>3_dot2" 2750 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2751 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 2752 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 2753 (const_int 0))) 2754 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2755 (mult:GPR (match_dup 1) 2756 (match_dup 2)))] 2757 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 2758 "@ 2759 mull<wd>. %0,%1,%2 2760 #" 2761 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2762 [(set (match_dup 0) 2763 (mult:GPR (match_dup 1) 2764 (match_dup 2))) 2765 (set (match_dup 3) 2766 (compare:CC (match_dup 0) 2767 (const_int 0)))] 2768 "" 2769 [(set_attr "type" "mul") 2770 (set_attr "size" "<bits>") 2771 (set_attr "dot" "yes") 2772 (set_attr "length" "4,8")]) 2773 2774 2775(define_expand "<su>mul<mode>3_highpart" 2776 [(set (match_operand:GPR 0 "gpc_reg_operand") 2777 (subreg:GPR 2778 (mult:<DMODE> (any_extend:<DMODE> 2779 (match_operand:GPR 1 "gpc_reg_operand")) 2780 (any_extend:<DMODE> 2781 (match_operand:GPR 2 "gpc_reg_operand"))) 2782 0))] 2783 "" 2784{ 2785 if (<MODE>mode == SImode && TARGET_POWERPC64) 2786 { 2787 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1], 2788 operands[2])); 2789 DONE; 2790 } 2791 2792 if (!WORDS_BIG_ENDIAN) 2793 { 2794 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1], 2795 operands[2])); 2796 DONE; 2797 } 2798}) 2799 2800(define_insn "*<su>mul<mode>3_highpart" 2801 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2802 (subreg:GPR 2803 (mult:<DMODE> (any_extend:<DMODE> 2804 (match_operand:GPR 1 "gpc_reg_operand" "r")) 2805 (any_extend:<DMODE> 2806 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 2807 0))] 2808 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)" 2809 "mulh<wd><u> %0,%1,%2" 2810 [(set_attr "type" "mul") 2811 (set_attr "size" "<bits>")]) 2812 2813(define_insn "<su>mulsi3_highpart_le" 2814 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2815 (subreg:SI 2816 (mult:DI (any_extend:DI 2817 (match_operand:SI 1 "gpc_reg_operand" "r")) 2818 (any_extend:DI 2819 (match_operand:SI 2 "gpc_reg_operand" "r"))) 2820 4))] 2821 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64" 2822 "mulhw<u> %0,%1,%2" 2823 [(set_attr "type" "mul")]) 2824 2825(define_insn "<su>muldi3_highpart_le" 2826 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2827 (subreg:DI 2828 (mult:TI (any_extend:TI 2829 (match_operand:DI 1 "gpc_reg_operand" "r")) 2830 (any_extend:TI 2831 (match_operand:DI 2 "gpc_reg_operand" "r"))) 2832 8))] 2833 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64" 2834 "mulhd<u> %0,%1,%2" 2835 [(set_attr "type" "mul") 2836 (set_attr "size" "64")]) 2837 2838(define_insn "<su>mulsi3_highpart_64" 2839 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2840 (truncate:SI 2841 (lshiftrt:DI 2842 (mult:DI (any_extend:DI 2843 (match_operand:SI 1 "gpc_reg_operand" "r")) 2844 (any_extend:DI 2845 (match_operand:SI 2 "gpc_reg_operand" "r"))) 2846 (const_int 32))))] 2847 "TARGET_POWERPC64" 2848 "mulhw<u> %0,%1,%2" 2849 [(set_attr "type" "mul")]) 2850 2851(define_expand "<u>mul<mode><dmode>3" 2852 [(set (match_operand:<DMODE> 0 "gpc_reg_operand") 2853 (mult:<DMODE> (any_extend:<DMODE> 2854 (match_operand:GPR 1 "gpc_reg_operand")) 2855 (any_extend:<DMODE> 2856 (match_operand:GPR 2 "gpc_reg_operand"))))] 2857 "!(<MODE>mode == SImode && TARGET_POWERPC64)" 2858{ 2859 rtx l = gen_reg_rtx (<MODE>mode); 2860 rtx h = gen_reg_rtx (<MODE>mode); 2861 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2])); 2862 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2])); 2863 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l); 2864 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h); 2865 DONE; 2866}) 2867 2868(define_insn "*maddld4" 2869 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2870 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r") 2871 (match_operand:DI 2 "gpc_reg_operand" "r")) 2872 (match_operand:DI 3 "gpc_reg_operand" "r")))] 2873 "TARGET_MADDLD" 2874 "maddld %0,%1,%2,%3" 2875 [(set_attr "type" "mul")]) 2876 2877(define_insn "udiv<mode>3" 2878 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2879 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 2880 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 2881 "" 2882 "div<wd>u %0,%1,%2" 2883 [(set_attr "type" "div") 2884 (set_attr "size" "<bits>")]) 2885 2886 2887;; For powers of two we can do sra[wd]i/addze for divide and then adjust for 2888;; modulus. If it isn't a power of two, force operands into register and do 2889;; a normal divide. 2890(define_expand "div<mode>3" 2891 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 2892 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") 2893 (match_operand:GPR 2 "reg_or_cint_operand" "")))] 2894 "" 2895{ 2896 if (CONST_INT_P (operands[2]) 2897 && INTVAL (operands[2]) > 0 2898 && exact_log2 (INTVAL (operands[2])) >= 0) 2899 { 2900 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2])); 2901 DONE; 2902 } 2903 2904 operands[2] = force_reg (<MODE>mode, operands[2]); 2905}) 2906 2907(define_insn "*div<mode>3" 2908 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2909 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 2910 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 2911 "" 2912 "div<wd> %0,%1,%2" 2913 [(set_attr "type" "div") 2914 (set_attr "size" "<bits>")]) 2915 2916(define_insn "div<mode>3_sra" 2917 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2918 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 2919 (match_operand:GPR 2 "exact_log2_cint_operand" "N"))) 2920 (clobber (reg:GPR CA_REGNO))] 2921 "" 2922 "sra<wd>i %0,%1,%p2\;addze %0,%0" 2923 [(set_attr "type" "two") 2924 (set_attr "length" "8")]) 2925 2926(define_insn_and_split "*div<mode>3_sra_dot" 2927 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2928 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 2929 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")) 2930 (const_int 0))) 2931 (clobber (match_scratch:GPR 0 "=r,r")) 2932 (clobber (reg:GPR CA_REGNO))] 2933 "<MODE>mode == Pmode" 2934 "@ 2935 sra<wd>i %0,%1,%p2\;addze. %0,%0 2936 #" 2937 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2938 [(parallel [(set (match_dup 0) 2939 (div:GPR (match_dup 1) 2940 (match_dup 2))) 2941 (clobber (reg:GPR CA_REGNO))]) 2942 (set (match_dup 3) 2943 (compare:CC (match_dup 0) 2944 (const_int 0)))] 2945 "" 2946 [(set_attr "type" "two") 2947 (set_attr "length" "8,12") 2948 (set_attr "cell_micro" "not")]) 2949 2950(define_insn_and_split "*div<mode>3_sra_dot2" 2951 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2952 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 2953 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")) 2954 (const_int 0))) 2955 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2956 (div:GPR (match_dup 1) 2957 (match_dup 2))) 2958 (clobber (reg:GPR CA_REGNO))] 2959 "<MODE>mode == Pmode" 2960 "@ 2961 sra<wd>i %0,%1,%p2\;addze. %0,%0 2962 #" 2963 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2964 [(parallel [(set (match_dup 0) 2965 (div:GPR (match_dup 1) 2966 (match_dup 2))) 2967 (clobber (reg:GPR CA_REGNO))]) 2968 (set (match_dup 3) 2969 (compare:CC (match_dup 0) 2970 (const_int 0)))] 2971 "" 2972 [(set_attr "type" "two") 2973 (set_attr "length" "8,12") 2974 (set_attr "cell_micro" "not")]) 2975 2976(define_expand "mod<mode>3" 2977 [(set (match_operand:GPR 0 "gpc_reg_operand") 2978 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand") 2979 (match_operand:GPR 2 "reg_or_cint_operand")))] 2980 "" 2981{ 2982 int i; 2983 rtx temp1; 2984 rtx temp2; 2985 2986 if (GET_CODE (operands[2]) != CONST_INT 2987 || INTVAL (operands[2]) <= 0 2988 || (i = exact_log2 (INTVAL (operands[2]))) < 0) 2989 { 2990 if (!TARGET_MODULO) 2991 FAIL; 2992 2993 operands[2] = force_reg (<MODE>mode, operands[2]); 2994 } 2995 else 2996 { 2997 temp1 = gen_reg_rtx (<MODE>mode); 2998 temp2 = gen_reg_rtx (<MODE>mode); 2999 3000 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2])); 3001 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i))); 3002 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2)); 3003 DONE; 3004 } 3005}) 3006 3007;; In order to enable using a peephole2 for combining div/mod to eliminate the 3008;; mod, prefer putting the result of mod into a different register 3009(define_insn "*mod<mode>3" 3010 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 3011 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3012 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3013 "TARGET_MODULO" 3014 "mods<wd> %0,%1,%2" 3015 [(set_attr "type" "div") 3016 (set_attr "size" "<bits>")]) 3017 3018 3019(define_insn "umod<mode>3" 3020 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 3021 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3022 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3023 "TARGET_MODULO" 3024 "modu<wd> %0,%1,%2" 3025 [(set_attr "type" "div") 3026 (set_attr "size" "<bits>")]) 3027 3028;; On machines with modulo support, do a combined div/mod the old fashioned 3029;; method, since the multiply/subtract is faster than doing the mod instruction 3030;; after a divide. 3031 3032(define_peephole2 3033 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 3034 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") 3035 (match_operand:GPR 2 "gpc_reg_operand" ""))) 3036 (set (match_operand:GPR 3 "gpc_reg_operand" "") 3037 (mod:GPR (match_dup 1) 3038 (match_dup 2)))] 3039 "TARGET_MODULO 3040 && ! reg_mentioned_p (operands[0], operands[1]) 3041 && ! reg_mentioned_p (operands[0], operands[2]) 3042 && ! reg_mentioned_p (operands[3], operands[1]) 3043 && ! reg_mentioned_p (operands[3], operands[2])" 3044 [(set (match_dup 0) 3045 (div:GPR (match_dup 1) 3046 (match_dup 2))) 3047 (set (match_dup 3) 3048 (mult:GPR (match_dup 0) 3049 (match_dup 2))) 3050 (set (match_dup 3) 3051 (minus:GPR (match_dup 1) 3052 (match_dup 3)))]) 3053 3054(define_peephole2 3055 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 3056 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "") 3057 (match_operand:GPR 2 "gpc_reg_operand" ""))) 3058 (set (match_operand:GPR 3 "gpc_reg_operand" "") 3059 (umod:GPR (match_dup 1) 3060 (match_dup 2)))] 3061 "TARGET_MODULO 3062 && ! reg_mentioned_p (operands[0], operands[1]) 3063 && ! reg_mentioned_p (operands[0], operands[2]) 3064 && ! reg_mentioned_p (operands[3], operands[1]) 3065 && ! reg_mentioned_p (operands[3], operands[2])" 3066 [(set (match_dup 0) 3067 (udiv:GPR (match_dup 1) 3068 (match_dup 2))) 3069 (set (match_dup 3) 3070 (mult:GPR (match_dup 0) 3071 (match_dup 2))) 3072 (set (match_dup 3) 3073 (minus:GPR (match_dup 1) 3074 (match_dup 3)))]) 3075 3076 3077;; Logical instructions 3078;; The logical instructions are mostly combined by using match_operator, 3079;; but the plain AND insns are somewhat different because there is no 3080;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all 3081;; those rotate-and-mask operations. Thus, the AND insns come first. 3082 3083(define_expand "and<mode>3" 3084 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 3085 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "") 3086 (match_operand:SDI 2 "reg_or_cint_operand" "")))] 3087 "" 3088{ 3089 if (<MODE>mode == DImode && !TARGET_POWERPC64) 3090 { 3091 rs6000_split_logical (operands, AND, false, false, false); 3092 DONE; 3093 } 3094 3095 if (CONST_INT_P (operands[2])) 3096 { 3097 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode)) 3098 { 3099 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2])); 3100 DONE; 3101 } 3102 3103 if (logical_const_operand (operands[2], <MODE>mode) 3104 && rs6000_gen_cell_microcode) 3105 { 3106 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2])); 3107 DONE; 3108 } 3109 3110 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode)) 3111 { 3112 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0); 3113 DONE; 3114 } 3115 3116 operands[2] = force_reg (<MODE>mode, operands[2]); 3117 } 3118}) 3119 3120 3121(define_insn "and<mode>3_imm" 3122 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3123 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3124 (match_operand:GPR 2 "logical_const_operand" "n"))) 3125 (clobber (match_scratch:CC 3 "=x"))] 3126 "rs6000_gen_cell_microcode 3127 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3128 "andi%e2. %0,%1,%u2" 3129 [(set_attr "type" "logical") 3130 (set_attr "dot" "yes")]) 3131 3132(define_insn_and_split "*and<mode>3_imm_dot" 3133 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3134 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3135 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3136 (const_int 0))) 3137 (clobber (match_scratch:GPR 0 "=r,r")) 3138 (clobber (match_scratch:CC 4 "=X,x"))] 3139 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3140 && rs6000_gen_cell_microcode 3141 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3142 "@ 3143 andi%e2. %0,%1,%u2 3144 #" 3145 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3146 [(parallel [(set (match_dup 0) 3147 (and:GPR (match_dup 1) 3148 (match_dup 2))) 3149 (clobber (match_dup 4))]) 3150 (set (match_dup 3) 3151 (compare:CC (match_dup 0) 3152 (const_int 0)))] 3153 "" 3154 [(set_attr "type" "logical") 3155 (set_attr "dot" "yes") 3156 (set_attr "length" "4,8")]) 3157 3158(define_insn_and_split "*and<mode>3_imm_dot2" 3159 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3160 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3161 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3162 (const_int 0))) 3163 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3164 (and:GPR (match_dup 1) 3165 (match_dup 2))) 3166 (clobber (match_scratch:CC 4 "=X,x"))] 3167 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3168 && rs6000_gen_cell_microcode 3169 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3170 "@ 3171 andi%e2. %0,%1,%u2 3172 #" 3173 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3174 [(parallel [(set (match_dup 0) 3175 (and:GPR (match_dup 1) 3176 (match_dup 2))) 3177 (clobber (match_dup 4))]) 3178 (set (match_dup 3) 3179 (compare:CC (match_dup 0) 3180 (const_int 0)))] 3181 "" 3182 [(set_attr "type" "logical") 3183 (set_attr "dot" "yes") 3184 (set_attr "length" "4,8")]) 3185 3186(define_insn_and_split "*and<mode>3_imm_mask_dot" 3187 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3188 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3189 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3190 (const_int 0))) 3191 (clobber (match_scratch:GPR 0 "=r,r"))] 3192 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3193 && rs6000_gen_cell_microcode" 3194 "@ 3195 andi%e2. %0,%1,%u2 3196 #" 3197 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3198 [(set (match_dup 0) 3199 (and:GPR (match_dup 1) 3200 (match_dup 2))) 3201 (set (match_dup 3) 3202 (compare:CC (match_dup 0) 3203 (const_int 0)))] 3204 "" 3205 [(set_attr "type" "logical") 3206 (set_attr "dot" "yes") 3207 (set_attr "length" "4,8")]) 3208 3209(define_insn_and_split "*and<mode>3_imm_mask_dot2" 3210 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3211 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3212 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3213 (const_int 0))) 3214 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3215 (and:GPR (match_dup 1) 3216 (match_dup 2)))] 3217 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3218 && rs6000_gen_cell_microcode" 3219 "@ 3220 andi%e2. %0,%1,%u2 3221 #" 3222 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3223 [(set (match_dup 0) 3224 (and:GPR (match_dup 1) 3225 (match_dup 2))) 3226 (set (match_dup 3) 3227 (compare:CC (match_dup 0) 3228 (const_int 0)))] 3229 "" 3230 [(set_attr "type" "logical") 3231 (set_attr "dot" "yes") 3232 (set_attr "length" "4,8")]) 3233 3234(define_insn "*and<mode>3_imm_dot_shifted" 3235 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 3236 (compare:CC 3237 (and:GPR 3238 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3239 (match_operand:SI 4 "const_int_operand" "n")) 3240 (match_operand:GPR 2 "const_int_operand" "n")) 3241 (const_int 0))) 3242 (clobber (match_scratch:GPR 0 "=r"))] 3243 "logical_const_operand (GEN_INT (UINTVAL (operands[2]) 3244 << INTVAL (operands[4])), 3245 DImode) 3246 && (<MODE>mode == Pmode 3247 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff) 3248 && rs6000_gen_cell_microcode" 3249{ 3250 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4])); 3251 return "andi%e2. %0,%1,%u2"; 3252} 3253 [(set_attr "type" "logical") 3254 (set_attr "dot" "yes")]) 3255 3256 3257(define_insn "and<mode>3_mask" 3258 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3259 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3260 (match_operand:GPR 2 "const_int_operand" "n")))] 3261 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3262{ 3263 return rs6000_insn_for_and_mask (<MODE>mode, operands, false); 3264} 3265 [(set_attr "type" "shift")]) 3266 3267(define_insn_and_split "*and<mode>3_mask_dot" 3268 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3269 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3270 (match_operand:GPR 2 "const_int_operand" "n,n")) 3271 (const_int 0))) 3272 (clobber (match_scratch:GPR 0 "=r,r"))] 3273 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3274 && rs6000_gen_cell_microcode 3275 && !logical_const_operand (operands[2], <MODE>mode) 3276 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3277{ 3278 if (which_alternative == 0) 3279 return rs6000_insn_for_and_mask (<MODE>mode, operands, true); 3280 else 3281 return "#"; 3282} 3283 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3284 [(set (match_dup 0) 3285 (and:GPR (match_dup 1) 3286 (match_dup 2))) 3287 (set (match_dup 3) 3288 (compare:CC (match_dup 0) 3289 (const_int 0)))] 3290 "" 3291 [(set_attr "type" "shift") 3292 (set_attr "dot" "yes") 3293 (set_attr "length" "4,8")]) 3294 3295(define_insn_and_split "*and<mode>3_mask_dot2" 3296 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3297 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3298 (match_operand:GPR 2 "const_int_operand" "n,n")) 3299 (const_int 0))) 3300 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3301 (and:GPR (match_dup 1) 3302 (match_dup 2)))] 3303 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3304 && rs6000_gen_cell_microcode 3305 && !logical_const_operand (operands[2], <MODE>mode) 3306 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3307{ 3308 if (which_alternative == 0) 3309 return rs6000_insn_for_and_mask (<MODE>mode, operands, true); 3310 else 3311 return "#"; 3312} 3313 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3314 [(set (match_dup 0) 3315 (and:GPR (match_dup 1) 3316 (match_dup 2))) 3317 (set (match_dup 3) 3318 (compare:CC (match_dup 0) 3319 (const_int 0)))] 3320 "" 3321 [(set_attr "type" "shift") 3322 (set_attr "dot" "yes") 3323 (set_attr "length" "4,8")]) 3324 3325 3326(define_insn_and_split "*and<mode>3_2insn" 3327 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3328 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3329 (match_operand:GPR 2 "const_int_operand" "n")))] 3330 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3331 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3332 || (logical_const_operand (operands[2], <MODE>mode) 3333 && rs6000_gen_cell_microcode))" 3334 "#" 3335 "&& 1" 3336 [(pc)] 3337{ 3338 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0); 3339 DONE; 3340} 3341 [(set_attr "type" "shift") 3342 (set_attr "length" "8")]) 3343 3344(define_insn_and_split "*and<mode>3_2insn_dot" 3345 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3346 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3347 (match_operand:GPR 2 "const_int_operand" "n,n")) 3348 (const_int 0))) 3349 (clobber (match_scratch:GPR 0 "=r,r"))] 3350 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3351 && rs6000_gen_cell_microcode 3352 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3353 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3354 || (logical_const_operand (operands[2], <MODE>mode) 3355 && rs6000_gen_cell_microcode))" 3356 "#" 3357 "&& reload_completed" 3358 [(pc)] 3359{ 3360 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1); 3361 DONE; 3362} 3363 [(set_attr "type" "shift") 3364 (set_attr "dot" "yes") 3365 (set_attr "length" "8,12")]) 3366 3367(define_insn_and_split "*and<mode>3_2insn_dot2" 3368 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3369 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3370 (match_operand:GPR 2 "const_int_operand" "n,n")) 3371 (const_int 0))) 3372 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3373 (and:GPR (match_dup 1) 3374 (match_dup 2)))] 3375 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3376 && rs6000_gen_cell_microcode 3377 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3378 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3379 || (logical_const_operand (operands[2], <MODE>mode) 3380 && rs6000_gen_cell_microcode))" 3381 "#" 3382 "&& reload_completed" 3383 [(pc)] 3384{ 3385 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2); 3386 DONE; 3387} 3388 [(set_attr "type" "shift") 3389 (set_attr "dot" "yes") 3390 (set_attr "length" "8,12")]) 3391 3392 3393(define_expand "<code><mode>3" 3394 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 3395 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "") 3396 (match_operand:SDI 2 "reg_or_cint_operand" "")))] 3397 "" 3398{ 3399 if (<MODE>mode == DImode && !TARGET_POWERPC64) 3400 { 3401 rs6000_split_logical (operands, <CODE>, false, false, false); 3402 DONE; 3403 } 3404 3405 if (non_logical_cint_operand (operands[2], <MODE>mode)) 3406 { 3407 rtx tmp = ((!can_create_pseudo_p () 3408 || rtx_equal_p (operands[0], operands[1])) 3409 ? operands[0] : gen_reg_rtx (<MODE>mode)); 3410 3411 HOST_WIDE_INT value = INTVAL (operands[2]); 3412 HOST_WIDE_INT lo = value & 0xffff; 3413 HOST_WIDE_INT hi = value - lo; 3414 3415 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi))); 3416 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo))); 3417 DONE; 3418 } 3419 3420 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode)) 3421 operands[2] = force_reg (<MODE>mode, operands[2]); 3422}) 3423 3424(define_split 3425 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 3426 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "") 3427 (match_operand:GPR 2 "non_logical_cint_operand" "")))] 3428 "" 3429 [(set (match_dup 3) 3430 (iorxor:GPR (match_dup 1) 3431 (match_dup 4))) 3432 (set (match_dup 0) 3433 (iorxor:GPR (match_dup 3) 3434 (match_dup 5)))] 3435{ 3436 operands[3] = ((!can_create_pseudo_p () 3437 || rtx_equal_p (operands[0], operands[1])) 3438 ? operands[0] : gen_reg_rtx (<MODE>mode)); 3439 3440 HOST_WIDE_INT value = INTVAL (operands[2]); 3441 HOST_WIDE_INT lo = value & 0xffff; 3442 HOST_WIDE_INT hi = value - lo; 3443 3444 operands[4] = GEN_INT (hi); 3445 operands[5] = GEN_INT (lo); 3446}) 3447 3448(define_insn "*bool<mode>3_imm" 3449 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3450 (match_operator:GPR 3 "boolean_or_operator" 3451 [(match_operand:GPR 1 "gpc_reg_operand" "%r") 3452 (match_operand:GPR 2 "logical_const_operand" "n")]))] 3453 "" 3454 "%q3i%e2 %0,%1,%u2" 3455 [(set_attr "type" "logical")]) 3456 3457(define_insn "*bool<mode>3" 3458 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3459 (match_operator:GPR 3 "boolean_operator" 3460 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3461 (match_operand:GPR 2 "gpc_reg_operand" "r")]))] 3462 "" 3463 "%q3 %0,%1,%2" 3464 [(set_attr "type" "logical")]) 3465 3466(define_insn_and_split "*bool<mode>3_dot" 3467 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3468 (compare:CC (match_operator:GPR 3 "boolean_operator" 3469 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3470 (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) 3471 (const_int 0))) 3472 (clobber (match_scratch:GPR 0 "=r,r"))] 3473 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3474 "@ 3475 %q3. %0,%1,%2 3476 #" 3477 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3478 [(set (match_dup 0) 3479 (match_dup 3)) 3480 (set (match_dup 4) 3481 (compare:CC (match_dup 0) 3482 (const_int 0)))] 3483 "" 3484 [(set_attr "type" "logical") 3485 (set_attr "dot" "yes") 3486 (set_attr "length" "4,8")]) 3487 3488(define_insn_and_split "*bool<mode>3_dot2" 3489 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3490 (compare:CC (match_operator:GPR 3 "boolean_operator" 3491 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3492 (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) 3493 (const_int 0))) 3494 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3495 (match_dup 3))] 3496 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3497 "@ 3498 %q3. %0,%1,%2 3499 #" 3500 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3501 [(set (match_dup 0) 3502 (match_dup 3)) 3503 (set (match_dup 4) 3504 (compare:CC (match_dup 0) 3505 (const_int 0)))] 3506 "" 3507 [(set_attr "type" "logical") 3508 (set_attr "dot" "yes") 3509 (set_attr "length" "4,8")]) 3510 3511 3512(define_insn "*boolc<mode>3" 3513 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3514 (match_operator:GPR 3 "boolean_operator" 3515 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")) 3516 (match_operand:GPR 1 "gpc_reg_operand" "r")]))] 3517 "" 3518 "%q3 %0,%1,%2" 3519 [(set_attr "type" "logical")]) 3520 3521(define_insn_and_split "*boolc<mode>3_dot" 3522 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3523 (compare:CC (match_operator:GPR 3 "boolean_operator" 3524 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3525 (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) 3526 (const_int 0))) 3527 (clobber (match_scratch:GPR 0 "=r,r"))] 3528 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3529 "@ 3530 %q3. %0,%1,%2 3531 #" 3532 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3533 [(set (match_dup 0) 3534 (match_dup 3)) 3535 (set (match_dup 4) 3536 (compare:CC (match_dup 0) 3537 (const_int 0)))] 3538 "" 3539 [(set_attr "type" "logical") 3540 (set_attr "dot" "yes") 3541 (set_attr "length" "4,8")]) 3542 3543(define_insn_and_split "*boolc<mode>3_dot2" 3544 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3545 (compare:CC (match_operator:GPR 3 "boolean_operator" 3546 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3547 (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) 3548 (const_int 0))) 3549 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3550 (match_dup 3))] 3551 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3552 "@ 3553 %q3. %0,%1,%2 3554 #" 3555 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3556 [(set (match_dup 0) 3557 (match_dup 3)) 3558 (set (match_dup 4) 3559 (compare:CC (match_dup 0) 3560 (const_int 0)))] 3561 "" 3562 [(set_attr "type" "logical") 3563 (set_attr "dot" "yes") 3564 (set_attr "length" "4,8")]) 3565 3566 3567(define_insn "*boolcc<mode>3" 3568 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3569 (match_operator:GPR 3 "boolean_operator" 3570 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 3571 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))] 3572 "" 3573 "%q3 %0,%1,%2" 3574 [(set_attr "type" "logical")]) 3575 3576(define_insn_and_split "*boolcc<mode>3_dot" 3577 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3578 (compare:CC (match_operator:GPR 3 "boolean_operator" 3579 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 3580 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) 3581 (const_int 0))) 3582 (clobber (match_scratch:GPR 0 "=r,r"))] 3583 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3584 "@ 3585 %q3. %0,%1,%2 3586 #" 3587 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3588 [(set (match_dup 0) 3589 (match_dup 3)) 3590 (set (match_dup 4) 3591 (compare:CC (match_dup 0) 3592 (const_int 0)))] 3593 "" 3594 [(set_attr "type" "logical") 3595 (set_attr "dot" "yes") 3596 (set_attr "length" "4,8")]) 3597 3598(define_insn_and_split "*boolcc<mode>3_dot2" 3599 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3600 (compare:CC (match_operator:GPR 3 "boolean_operator" 3601 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 3602 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) 3603 (const_int 0))) 3604 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3605 (match_dup 3))] 3606 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3607 "@ 3608 %q3. %0,%1,%2 3609 #" 3610 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3611 [(set (match_dup 0) 3612 (match_dup 3)) 3613 (set (match_dup 4) 3614 (compare:CC (match_dup 0) 3615 (const_int 0)))] 3616 "" 3617 [(set_attr "type" "logical") 3618 (set_attr "dot" "yes") 3619 (set_attr "length" "4,8")]) 3620 3621 3622;; TODO: Should have dots of this as well. 3623(define_insn "*eqv<mode>3" 3624 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3625 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3626 (match_operand:GPR 2 "gpc_reg_operand" "r"))))] 3627 "" 3628 "eqv %0,%1,%2" 3629 [(set_attr "type" "logical")]) 3630 3631;; Rotate-and-mask and insert. 3632 3633(define_insn "*rotl<mode>3_mask" 3634 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3635 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3636 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3637 (match_operand:SI 2 "reg_or_cint_operand" "rn")]) 3638 (match_operand:GPR 3 "const_int_operand" "n")))] 3639 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3640{ 3641 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false); 3642} 3643 [(set_attr "type" "shift") 3644 (set_attr "maybe_var_shift" "yes")]) 3645 3646(define_insn_and_split "*rotl<mode>3_mask_dot" 3647 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") 3648 (compare:CC 3649 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3650 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3651 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")]) 3652 (match_operand:GPR 3 "const_int_operand" "n,n")) 3653 (const_int 0))) 3654 (clobber (match_scratch:GPR 0 "=r,r"))] 3655 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff) 3656 && rs6000_gen_cell_microcode 3657 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3658{ 3659 if (which_alternative == 0) 3660 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true); 3661 else 3662 return "#"; 3663} 3664 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)" 3665 [(set (match_dup 0) 3666 (and:GPR (match_dup 4) 3667 (match_dup 3))) 3668 (set (match_dup 5) 3669 (compare:CC (match_dup 0) 3670 (const_int 0)))] 3671 "" 3672 [(set_attr "type" "shift") 3673 (set_attr "maybe_var_shift" "yes") 3674 (set_attr "dot" "yes") 3675 (set_attr "length" "4,8")]) 3676 3677(define_insn_and_split "*rotl<mode>3_mask_dot2" 3678 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") 3679 (compare:CC 3680 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3681 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3682 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")]) 3683 (match_operand:GPR 3 "const_int_operand" "n,n")) 3684 (const_int 0))) 3685 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3686 (and:GPR (match_dup 4) 3687 (match_dup 3)))] 3688 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff) 3689 && rs6000_gen_cell_microcode 3690 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3691{ 3692 if (which_alternative == 0) 3693 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true); 3694 else 3695 return "#"; 3696} 3697 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)" 3698 [(set (match_dup 0) 3699 (and:GPR (match_dup 4) 3700 (match_dup 3))) 3701 (set (match_dup 5) 3702 (compare:CC (match_dup 0) 3703 (const_int 0)))] 3704 "" 3705 [(set_attr "type" "shift") 3706 (set_attr "maybe_var_shift" "yes") 3707 (set_attr "dot" "yes") 3708 (set_attr "length" "4,8")]) 3709 3710; Special case for less-than-0. We can do it with just one machine 3711; instruction, but the generic optimizers do not realise it is cheap. 3712(define_insn "*lt0_disi" 3713 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3714 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r") 3715 (const_int 0)))] 3716 "TARGET_POWERPC64" 3717 "rlwinm %0,%1,1,31,31" 3718 [(set_attr "type" "shift")]) 3719 3720 3721 3722; Two forms for insert (the two arms of the IOR are not canonicalized, 3723; both are an AND so are the same precedence). 3724(define_insn "*rotl<mode>3_insert" 3725 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3726 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3727 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3728 (match_operand:SI 2 "const_int_operand" "n")]) 3729 (match_operand:GPR 3 "const_int_operand" "n")) 3730 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0") 3731 (match_operand:GPR 6 "const_int_operand" "n"))))] 3732 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode) 3733 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0" 3734{ 3735 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false); 3736} 3737 [(set_attr "type" "insert")]) 3738; FIXME: this needs an attr "size", so that the scheduler can see the 3739; difference between rlwimi and rldimi. We also might want dot forms, 3740; but not for rlwimi on POWER4 and similar processors. 3741 3742(define_insn "*rotl<mode>3_insert_2" 3743 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3744 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0") 3745 (match_operand:GPR 6 "const_int_operand" "n")) 3746 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3747 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3748 (match_operand:SI 2 "const_int_operand" "n")]) 3749 (match_operand:GPR 3 "const_int_operand" "n"))))] 3750 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode) 3751 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0" 3752{ 3753 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false); 3754} 3755 [(set_attr "type" "insert")]) 3756 3757; There are also some forms without one of the ANDs. 3758(define_insn "*rotl<mode>3_insert_3" 3759 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3760 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 3761 (match_operand:GPR 4 "const_int_operand" "n")) 3762 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3763 (match_operand:SI 2 "const_int_operand" "n"))))] 3764 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)" 3765{ 3766 if (<MODE>mode == SImode) 3767 return "rlwimi %0,%1,%h2,0,31-%h2"; 3768 else 3769 return "rldimi %0,%1,%H2,0"; 3770} 3771 [(set_attr "type" "insert")]) 3772 3773(define_insn "*rotl<mode>3_insert_4" 3774 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3775 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 3776 (match_operand:GPR 4 "const_int_operand" "n")) 3777 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3778 (match_operand:SI 2 "const_int_operand" "n"))))] 3779 "<MODE>mode == SImode && 3780 GET_MODE_PRECISION (<MODE>mode) 3781 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))" 3782{ 3783 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode) 3784 - INTVAL (operands[2])); 3785 if (<MODE>mode == SImode) 3786 return "rlwimi %0,%1,%h2,32-%h2,31"; 3787 else 3788 return "rldimi %0,%1,%H2,64-%H2"; 3789} 3790 [(set_attr "type" "insert")]) 3791 3792 3793; This handles the important case of multiple-precision shifts. There is 3794; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns. 3795(define_split 3796 [(set (match_operand:GPR 0 "gpc_reg_operand") 3797 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 3798 (match_operand:SI 3 "const_int_operand")) 3799 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand") 3800 (match_operand:SI 4 "const_int_operand"))))] 3801 "can_create_pseudo_p () 3802 && INTVAL (operands[3]) + INTVAL (operands[4]) 3803 >= GET_MODE_PRECISION (<MODE>mode)" 3804 [(set (match_dup 5) 3805 (lshiftrt:GPR (match_dup 2) 3806 (match_dup 4))) 3807 (set (match_dup 0) 3808 (ior:GPR (and:GPR (match_dup 5) 3809 (match_dup 6)) 3810 (ashift:GPR (match_dup 1) 3811 (match_dup 3))))] 3812{ 3813 unsigned HOST_WIDE_INT mask = 1; 3814 mask = (mask << INTVAL (operands[3])) - 1; 3815 operands[5] = gen_reg_rtx (<MODE>mode); 3816 operands[6] = GEN_INT (mask); 3817}) 3818 3819(define_split 3820 [(set (match_operand:GPR 0 "gpc_reg_operand") 3821 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand") 3822 (match_operand:SI 4 "const_int_operand")) 3823 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 3824 (match_operand:SI 3 "const_int_operand"))))] 3825 "can_create_pseudo_p () 3826 && INTVAL (operands[3]) + INTVAL (operands[4]) 3827 >= GET_MODE_PRECISION (<MODE>mode)" 3828 [(set (match_dup 5) 3829 (lshiftrt:GPR (match_dup 2) 3830 (match_dup 4))) 3831 (set (match_dup 0) 3832 (ior:GPR (and:GPR (match_dup 5) 3833 (match_dup 6)) 3834 (ashift:GPR (match_dup 1) 3835 (match_dup 3))))] 3836{ 3837 unsigned HOST_WIDE_INT mask = 1; 3838 mask = (mask << INTVAL (operands[3])) - 1; 3839 operands[5] = gen_reg_rtx (<MODE>mode); 3840 operands[6] = GEN_INT (mask); 3841}) 3842 3843 3844; Another important case is setting some bits to 1; we can do that with 3845; an insert instruction, in many cases. 3846(define_insn_and_split "*ior<mode>_mask" 3847 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3848 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0") 3849 (match_operand:GPR 2 "const_int_operand" "n"))) 3850 (clobber (match_scratch:GPR 3 "=r"))] 3851 "!logical_const_operand (operands[2], <MODE>mode) 3852 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)" 3853 "#" 3854 "&& 1" 3855 [(set (match_dup 3) 3856 (const_int -1)) 3857 (set (match_dup 0) 3858 (ior:GPR (and:GPR (rotate:GPR (match_dup 3) 3859 (match_dup 4)) 3860 (match_dup 2)) 3861 (and:GPR (match_dup 1) 3862 (match_dup 5))))] 3863{ 3864 int nb, ne; 3865 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode); 3866 if (GET_CODE (operands[3]) == SCRATCH) 3867 operands[3] = gen_reg_rtx (<MODE>mode); 3868 operands[4] = GEN_INT (ne); 3869 operands[5] = GEN_INT (~UINTVAL (operands[2])); 3870} 3871 [(set_attr "type" "two") 3872 (set_attr "length" "8")]) 3873 3874 3875;; Now the simple shifts. 3876 3877(define_insn "rotl<mode>3" 3878 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3879 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3880 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 3881 "" 3882 "rotl<wd>%I2 %0,%1,%<hH>2" 3883 [(set_attr "type" "shift") 3884 (set_attr "maybe_var_shift" "yes")]) 3885 3886(define_insn "*rotlsi3_64" 3887 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3888 (zero_extend:DI 3889 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") 3890 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 3891 "TARGET_POWERPC64" 3892 "rotlw%I2 %0,%1,%h2" 3893 [(set_attr "type" "shift") 3894 (set_attr "maybe_var_shift" "yes")]) 3895 3896(define_insn_and_split "*rotl<mode>3_dot" 3897 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3898 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3899 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3900 (const_int 0))) 3901 (clobber (match_scratch:GPR 0 "=r,r"))] 3902 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3903 "@ 3904 rotl<wd>%I2. %0,%1,%<hH>2 3905 #" 3906 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3907 [(set (match_dup 0) 3908 (rotate:GPR (match_dup 1) 3909 (match_dup 2))) 3910 (set (match_dup 3) 3911 (compare:CC (match_dup 0) 3912 (const_int 0)))] 3913 "" 3914 [(set_attr "type" "shift") 3915 (set_attr "maybe_var_shift" "yes") 3916 (set_attr "dot" "yes") 3917 (set_attr "length" "4,8")]) 3918 3919(define_insn_and_split "*rotl<mode>3_dot2" 3920 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3921 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3922 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3923 (const_int 0))) 3924 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3925 (rotate:GPR (match_dup 1) 3926 (match_dup 2)))] 3927 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3928 "@ 3929 rotl<wd>%I2. %0,%1,%<hH>2 3930 #" 3931 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3932 [(set (match_dup 0) 3933 (rotate:GPR (match_dup 1) 3934 (match_dup 2))) 3935 (set (match_dup 3) 3936 (compare:CC (match_dup 0) 3937 (const_int 0)))] 3938 "" 3939 [(set_attr "type" "shift") 3940 (set_attr "maybe_var_shift" "yes") 3941 (set_attr "dot" "yes") 3942 (set_attr "length" "4,8")]) 3943 3944 3945(define_insn "ashl<mode>3" 3946 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3947 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3948 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 3949 "" 3950 "sl<wd>%I2 %0,%1,%<hH>2" 3951 [(set_attr "type" "shift") 3952 (set_attr "maybe_var_shift" "yes")]) 3953 3954(define_insn "*ashlsi3_64" 3955 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3956 (zero_extend:DI 3957 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") 3958 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 3959 "TARGET_POWERPC64" 3960 "slw%I2 %0,%1,%h2" 3961 [(set_attr "type" "shift") 3962 (set_attr "maybe_var_shift" "yes")]) 3963 3964(define_insn_and_split "*ashl<mode>3_dot" 3965 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3966 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3967 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3968 (const_int 0))) 3969 (clobber (match_scratch:GPR 0 "=r,r"))] 3970 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3971 "@ 3972 sl<wd>%I2. %0,%1,%<hH>2 3973 #" 3974 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3975 [(set (match_dup 0) 3976 (ashift:GPR (match_dup 1) 3977 (match_dup 2))) 3978 (set (match_dup 3) 3979 (compare:CC (match_dup 0) 3980 (const_int 0)))] 3981 "" 3982 [(set_attr "type" "shift") 3983 (set_attr "maybe_var_shift" "yes") 3984 (set_attr "dot" "yes") 3985 (set_attr "length" "4,8")]) 3986 3987(define_insn_and_split "*ashl<mode>3_dot2" 3988 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3989 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3990 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 3991 (const_int 0))) 3992 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3993 (ashift:GPR (match_dup 1) 3994 (match_dup 2)))] 3995 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3996 "@ 3997 sl<wd>%I2. %0,%1,%<hH>2 3998 #" 3999 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4000 [(set (match_dup 0) 4001 (ashift:GPR (match_dup 1) 4002 (match_dup 2))) 4003 (set (match_dup 3) 4004 (compare:CC (match_dup 0) 4005 (const_int 0)))] 4006 "" 4007 [(set_attr "type" "shift") 4008 (set_attr "maybe_var_shift" "yes") 4009 (set_attr "dot" "yes") 4010 (set_attr "length" "4,8")]) 4011 4012;; Pretend we have a memory form of extswsli until register allocation is done 4013;; so that we use LWZ to load the value from memory, instead of LWA. 4014(define_insn_and_split "ashdi3_extswsli" 4015 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 4016 (ashift:DI 4017 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m")) 4018 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))] 4019 "TARGET_EXTSWSLI" 4020 "@ 4021 extswsli %0,%1,%2 4022 #" 4023 "&& reload_completed && MEM_P (operands[1])" 4024 [(set (match_dup 3) 4025 (match_dup 1)) 4026 (set (match_dup 0) 4027 (ashift:DI (sign_extend:DI (match_dup 3)) 4028 (match_dup 2)))] 4029{ 4030 operands[3] = gen_lowpart (SImode, operands[0]); 4031} 4032 [(set_attr "type" "shift") 4033 (set_attr "maybe_var_shift" "no")]) 4034 4035 4036(define_insn_and_split "ashdi3_extswsli_dot" 4037 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y") 4038 (compare:CC 4039 (ashift:DI 4040 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m")) 4041 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n")) 4042 (const_int 0))) 4043 (clobber (match_scratch:DI 0 "=r,r,r,r"))] 4044 "TARGET_EXTSWSLI" 4045 "@ 4046 extswsli. %0,%1,%2 4047 # 4048 # 4049 #" 4050 "&& reload_completed 4051 && (cc_reg_not_cr0_operand (operands[3], CCmode) 4052 || memory_operand (operands[1], SImode))" 4053 [(pc)] 4054{ 4055 rtx dest = operands[0]; 4056 rtx src = operands[1]; 4057 rtx shift = operands[2]; 4058 rtx cr = operands[3]; 4059 rtx src2; 4060 4061 if (!MEM_P (src)) 4062 src2 = src; 4063 else 4064 { 4065 src2 = gen_lowpart (SImode, dest); 4066 emit_move_insn (src2, src); 4067 } 4068 4069 if (REGNO (cr) == CR0_REGNO) 4070 { 4071 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr)); 4072 DONE; 4073 } 4074 4075 emit_insn (gen_ashdi3_extswsli (dest, src2, shift)); 4076 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx))); 4077 DONE; 4078} 4079 [(set_attr "type" "shift") 4080 (set_attr "maybe_var_shift" "no") 4081 (set_attr "dot" "yes") 4082 (set_attr "length" "4,8,8,12")]) 4083 4084(define_insn_and_split "ashdi3_extswsli_dot2" 4085 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y") 4086 (compare:CC 4087 (ashift:DI 4088 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m")) 4089 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n")) 4090 (const_int 0))) 4091 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") 4092 (ashift:DI (sign_extend:DI (match_dup 1)) 4093 (match_dup 2)))] 4094 "TARGET_EXTSWSLI" 4095 "@ 4096 extswsli. %0,%1,%2 4097 # 4098 # 4099 #" 4100 "&& reload_completed 4101 && (cc_reg_not_cr0_operand (operands[3], CCmode) 4102 || memory_operand (operands[1], SImode))" 4103 [(pc)] 4104{ 4105 rtx dest = operands[0]; 4106 rtx src = operands[1]; 4107 rtx shift = operands[2]; 4108 rtx cr = operands[3]; 4109 rtx src2; 4110 4111 if (!MEM_P (src)) 4112 src2 = src; 4113 else 4114 { 4115 src2 = gen_lowpart (SImode, dest); 4116 emit_move_insn (src2, src); 4117 } 4118 4119 if (REGNO (cr) == CR0_REGNO) 4120 { 4121 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr)); 4122 DONE; 4123 } 4124 4125 emit_insn (gen_ashdi3_extswsli (dest, src2, shift)); 4126 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx))); 4127 DONE; 4128} 4129 [(set_attr "type" "shift") 4130 (set_attr "maybe_var_shift" "no") 4131 (set_attr "dot" "yes") 4132 (set_attr "length" "4,8,8,12")]) 4133 4134(define_insn "lshr<mode>3" 4135 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4136 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4137 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4138 "" 4139 "sr<wd>%I2 %0,%1,%<hH>2" 4140 [(set_attr "type" "shift") 4141 (set_attr "maybe_var_shift" "yes")]) 4142 4143(define_insn "*lshrsi3_64" 4144 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4145 (zero_extend:DI 4146 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4147 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4148 "TARGET_POWERPC64" 4149 "srw%I2 %0,%1,%h2" 4150 [(set_attr "type" "shift") 4151 (set_attr "maybe_var_shift" "yes")]) 4152 4153(define_insn_and_split "*lshr<mode>3_dot" 4154 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4155 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4156 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4157 (const_int 0))) 4158 (clobber (match_scratch:GPR 0 "=r,r"))] 4159 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4160 "@ 4161 sr<wd>%I2. %0,%1,%<hH>2 4162 #" 4163 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4164 [(set (match_dup 0) 4165 (lshiftrt:GPR (match_dup 1) 4166 (match_dup 2))) 4167 (set (match_dup 3) 4168 (compare:CC (match_dup 0) 4169 (const_int 0)))] 4170 "" 4171 [(set_attr "type" "shift") 4172 (set_attr "maybe_var_shift" "yes") 4173 (set_attr "dot" "yes") 4174 (set_attr "length" "4,8")]) 4175 4176(define_insn_and_split "*lshr<mode>3_dot2" 4177 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4178 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4179 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4180 (const_int 0))) 4181 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4182 (lshiftrt:GPR (match_dup 1) 4183 (match_dup 2)))] 4184 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4185 "@ 4186 sr<wd>%I2. %0,%1,%<hH>2 4187 #" 4188 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4189 [(set (match_dup 0) 4190 (lshiftrt:GPR (match_dup 1) 4191 (match_dup 2))) 4192 (set (match_dup 3) 4193 (compare:CC (match_dup 0) 4194 (const_int 0)))] 4195 "" 4196 [(set_attr "type" "shift") 4197 (set_attr "maybe_var_shift" "yes") 4198 (set_attr "dot" "yes") 4199 (set_attr "length" "4,8")]) 4200 4201 4202(define_insn "ashr<mode>3" 4203 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4204 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4205 (match_operand:SI 2 "reg_or_cint_operand" "rn"))) 4206 (clobber (reg:GPR CA_REGNO))] 4207 "" 4208 "sra<wd>%I2 %0,%1,%<hH>2" 4209 [(set_attr "type" "shift") 4210 (set_attr "maybe_var_shift" "yes")]) 4211 4212(define_insn "*ashrsi3_64" 4213 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4214 (sign_extend:DI 4215 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4216 (match_operand:SI 2 "reg_or_cint_operand" "rn")))) 4217 (clobber (reg:SI CA_REGNO))] 4218 "TARGET_POWERPC64" 4219 "sraw%I2 %0,%1,%h2" 4220 [(set_attr "type" "shift") 4221 (set_attr "maybe_var_shift" "yes")]) 4222 4223(define_insn_and_split "*ashr<mode>3_dot" 4224 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4225 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4226 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4227 (const_int 0))) 4228 (clobber (match_scratch:GPR 0 "=r,r")) 4229 (clobber (reg:GPR CA_REGNO))] 4230 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4231 "@ 4232 sra<wd>%I2. %0,%1,%<hH>2 4233 #" 4234 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4235 [(parallel [(set (match_dup 0) 4236 (ashiftrt:GPR (match_dup 1) 4237 (match_dup 2))) 4238 (clobber (reg:GPR CA_REGNO))]) 4239 (set (match_dup 3) 4240 (compare:CC (match_dup 0) 4241 (const_int 0)))] 4242 "" 4243 [(set_attr "type" "shift") 4244 (set_attr "maybe_var_shift" "yes") 4245 (set_attr "dot" "yes") 4246 (set_attr "length" "4,8")]) 4247 4248(define_insn_and_split "*ashr<mode>3_dot2" 4249 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4250 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4251 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4252 (const_int 0))) 4253 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4254 (ashiftrt:GPR (match_dup 1) 4255 (match_dup 2))) 4256 (clobber (reg:GPR CA_REGNO))] 4257 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4258 "@ 4259 sra<wd>%I2. %0,%1,%<hH>2 4260 #" 4261 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4262 [(parallel [(set (match_dup 0) 4263 (ashiftrt:GPR (match_dup 1) 4264 (match_dup 2))) 4265 (clobber (reg:GPR CA_REGNO))]) 4266 (set (match_dup 3) 4267 (compare:CC (match_dup 0) 4268 (const_int 0)))] 4269 "" 4270 [(set_attr "type" "shift") 4271 (set_attr "maybe_var_shift" "yes") 4272 (set_attr "dot" "yes") 4273 (set_attr "length" "4,8")]) 4274 4275;; Builtins to replace a division to generate FRE reciprocal estimate 4276;; instructions and the necessary fixup instructions 4277(define_expand "recip<mode>3" 4278 [(match_operand:RECIPF 0 "gpc_reg_operand" "") 4279 (match_operand:RECIPF 1 "gpc_reg_operand" "") 4280 (match_operand:RECIPF 2 "gpc_reg_operand" "")] 4281 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)" 4282{ 4283 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false); 4284 DONE; 4285}) 4286 4287;; Split to create division from FRE/FRES/etc. and fixup instead of the normal 4288;; hardware division. This is only done before register allocation and with 4289;; -ffast-math. This must appear before the divsf3/divdf3 insns. 4290(define_split 4291 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "") 4292 (div:RECIPF (match_operand 1 "gpc_reg_operand" "") 4293 (match_operand 2 "gpc_reg_operand" "")))] 4294 "RS6000_RECIP_AUTO_RE_P (<MODE>mode) 4295 && can_create_pseudo_p () && optimize_insn_for_speed_p () 4296 && flag_finite_math_only && !flag_trapping_math && flag_reciprocal_math" 4297 [(const_int 0)] 4298{ 4299 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); 4300 DONE; 4301}) 4302 4303;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the 4304;; appropriate fixup. 4305(define_expand "rsqrt<mode>2" 4306 [(match_operand:RECIPF 0 "gpc_reg_operand" "") 4307 (match_operand:RECIPF 1 "gpc_reg_operand" "")] 4308 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 4309{ 4310 rs6000_emit_swsqrt (operands[0], operands[1], 1); 4311 DONE; 4312}) 4313 4314;; Floating-point insns, excluding normal data motion. We combine the SF/DF 4315;; modes here, and also add in conditional vsx/power8-vector support to access 4316;; values in the traditional Altivec registers if the appropriate 4317;; -mupper-regs-{df,sf} option is enabled. 4318 4319(define_expand "abs<mode>2" 4320 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4321 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))] 4322 "TARGET_<MODE>_INSN" 4323 "") 4324 4325(define_insn "*abs<mode>2_fpr" 4326 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4327 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 4328 "TARGET_<MODE>_FPR" 4329 "@ 4330 fabs %0,%1 4331 xsabsdp %x0,%x1" 4332 [(set_attr "type" "fpsimple") 4333 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4334 4335(define_insn "*nabs<mode>2_fpr" 4336 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4337 (neg:SFDF 4338 (abs:SFDF 4339 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))] 4340 "TARGET_<MODE>_FPR" 4341 "@ 4342 fnabs %0,%1 4343 xsnabsdp %x0,%x1" 4344 [(set_attr "type" "fpsimple") 4345 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4346 4347(define_expand "neg<mode>2" 4348 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4349 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))] 4350 "TARGET_<MODE>_INSN" 4351 "") 4352 4353(define_insn "*neg<mode>2_fpr" 4354 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4355 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 4356 "TARGET_<MODE>_FPR" 4357 "@ 4358 fneg %0,%1 4359 xsnegdp %x0,%x1" 4360 [(set_attr "type" "fpsimple") 4361 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4362 4363(define_expand "add<mode>3" 4364 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4365 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4366 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4367 "TARGET_<MODE>_INSN" 4368 "") 4369 4370(define_insn "*add<mode>3_fpr" 4371 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4372 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") 4373 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4374 "TARGET_<MODE>_FPR" 4375 "@ 4376 fadd<Ftrad> %0,%1,%2 4377 xsadd<Fvsx> %x0,%x1,%x2" 4378 [(set_attr "type" "fp") 4379 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4380 4381(define_expand "sub<mode>3" 4382 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4383 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4384 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4385 "TARGET_<MODE>_INSN" 4386 "") 4387 4388(define_insn "*sub<mode>3_fpr" 4389 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4390 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") 4391 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4392 "TARGET_<MODE>_FPR" 4393 "@ 4394 fsub<Ftrad> %0,%1,%2 4395 xssub<Fvsx> %x0,%x1,%x2" 4396 [(set_attr "type" "fp") 4397 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4398 4399(define_expand "mul<mode>3" 4400 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4401 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4402 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4403 "TARGET_<MODE>_INSN" 4404 "") 4405 4406(define_insn "*mul<mode>3_fpr" 4407 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4408 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") 4409 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4410 "TARGET_<MODE>_FPR" 4411 "@ 4412 fmul<Ftrad> %0,%1,%2 4413 xsmul<Fvsx> %x0,%x1,%x2" 4414 [(set_attr "type" "dmul") 4415 (set_attr "fp_type" "fp_mul_<Fs>")]) 4416 4417(define_expand "div<mode>3" 4418 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4419 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4420 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4421 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU" 4422 "") 4423 4424(define_insn "*div<mode>3_fpr" 4425 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4426 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") 4427 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4428 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU" 4429 "@ 4430 fdiv<Ftrad> %0,%1,%2 4431 xsdiv<Fvsx> %x0,%x1,%x2" 4432 [(set_attr "type" "<Fs>div") 4433 (set_attr "fp_type" "fp_div_<Fs>")]) 4434 4435(define_insn "*sqrt<mode>2_internal" 4436 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4437 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4438 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU 4439 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))" 4440 "@ 4441 fsqrt<Ftrad> %0,%1 4442 xssqrt<Fvsx> %x0,%x1" 4443 [(set_attr "type" "<Fs>sqrt") 4444 (set_attr "fp_type" "fp_sqrt_<Fs>")]) 4445 4446(define_expand "sqrt<mode>2" 4447 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4448 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))] 4449 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU 4450 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))" 4451{ 4452 if (<MODE>mode == SFmode 4453 && TARGET_RECIP_PRECISION 4454 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode) 4455 && !optimize_function_for_size_p (cfun) 4456 && flag_finite_math_only && !flag_trapping_math 4457 && flag_unsafe_math_optimizations) 4458 { 4459 rs6000_emit_swsqrt (operands[0], operands[1], 0); 4460 DONE; 4461 } 4462}) 4463 4464;; Floating point reciprocal approximation 4465(define_insn "fre<Fs>" 4466 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4467 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")] 4468 UNSPEC_FRES))] 4469 "TARGET_<FFRE>" 4470 "@ 4471 fre<Ftrad> %0,%1 4472 xsre<Fvsx> %x0,%x1" 4473 [(set_attr "type" "fp")]) 4474 4475(define_insn "*rsqrt<mode>2" 4476 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4477 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")] 4478 UNSPEC_RSQRT))] 4479 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 4480 "@ 4481 frsqrte<Ftrad> %0,%1 4482 xsrsqrte<Fvsx> %x0,%x1" 4483 [(set_attr "type" "fp")]) 4484 4485;; Floating point comparisons 4486(define_insn "*cmp<mode>_fpr" 4487 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y") 4488 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") 4489 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4490 "TARGET_<MODE>_FPR" 4491 "@ 4492 fcmpu %0,%1,%2 4493 xscmpudp %0,%x1,%x2" 4494 [(set_attr "type" "fpcompare")]) 4495 4496;; Floating point conversions 4497(define_expand "extendsfdf2" 4498 [(set (match_operand:DF 0 "gpc_reg_operand" "") 4499 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand" "")))] 4500 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" 4501 "") 4502 4503(define_insn_and_split "*extendsfdf2_fpr" 4504 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb") 4505 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))] 4506 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 4507 "@ 4508 # 4509 fmr %0,%1 4510 lfs%U1%X1 %0,%1 4511 # 4512 xscpsgndp %x0,%x1,%x1 4513 lxsspx %x0,%y1 4514 lxssp %0,%1" 4515 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])" 4516 [(const_int 0)] 4517{ 4518 emit_note (NOTE_INSN_DELETED); 4519 DONE; 4520} 4521 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")]) 4522 4523(define_expand "truncdfsf2" 4524 [(set (match_operand:SF 0 "gpc_reg_operand" "") 4525 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))] 4526 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" 4527 "") 4528 4529(define_insn "*truncdfsf2_fpr" 4530 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy") 4531 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))] 4532 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 4533 "@ 4534 frsp %0,%1 4535 xsrsp %x0,%x1" 4536 [(set_attr "type" "fp")]) 4537 4538;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in 4539;; builtins.c and optabs.c that are not correct for IBM long double 4540;; when little-endian. 4541(define_expand "signbit<mode>2" 4542 [(set (match_dup 2) 4543 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" ""))) 4544 (set (match_dup 3) 4545 (subreg:DI (match_dup 2) 0)) 4546 (set (match_dup 4) 4547 (match_dup 5)) 4548 (set (match_operand:SI 0 "gpc_reg_operand" "") 4549 (match_dup 6))] 4550 "TARGET_HARD_FLOAT 4551 && (TARGET_FPRS || TARGET_E500_DOUBLE) 4552 && (!FLOAT128_IEEE_P (<MODE>mode) 4553 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))" 4554{ 4555 if (FLOAT128_IEEE_P (<MODE>mode)) 4556 { 4557 rtx dest = operands[0]; 4558 rtx src = operands[1]; 4559 rtx tmp = gen_reg_rtx (DImode); 4560 rtx dest_di = gen_lowpart (DImode, dest); 4561 4562 if (<MODE>mode == KFmode) 4563 emit_insn (gen_signbitkf2_dm (tmp, src)); 4564 else if (<MODE>mode == TFmode) 4565 emit_insn (gen_signbittf2_dm (tmp, src)); 4566 else 4567 gcc_unreachable (); 4568 4569 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63))); 4570 DONE; 4571 } 4572 operands[2] = gen_reg_rtx (DFmode); 4573 operands[3] = gen_reg_rtx (DImode); 4574 if (TARGET_POWERPC64) 4575 { 4576 operands[4] = gen_reg_rtx (DImode); 4577 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63)); 4578 operands[6] = gen_rtx_SUBREG (SImode, operands[4], 4579 WORDS_BIG_ENDIAN ? 4 : 0); 4580 } 4581 else 4582 { 4583 operands[4] = gen_reg_rtx (SImode); 4584 operands[5] = gen_rtx_SUBREG (SImode, operands[3], 4585 WORDS_BIG_ENDIAN ? 0 : 4); 4586 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31)); 4587 } 4588}) 4589 4590;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid 4591;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the 4592;; register allocator would typically move the entire _Float128 item to GPRs (2 4593;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07). 4594;; 4595;; After register allocation, if the _Float128 had originally been in GPRs, the 4596;; split allows the post reload phases to eliminate the move, and do the shift 4597;; directly with the register that contains the signbit. 4598(define_insn_and_split "signbit<mode>2_dm" 4599 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 4600 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")] 4601 UNSPEC_SIGNBIT))] 4602 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 4603 "@ 4604 mfvsrd %0,%x1 4605 #" 4606 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)" 4607 [(set (match_dup 0) 4608 (match_dup 2))] 4609{ 4610 operands[2] = gen_highpart (DImode, operands[1]); 4611} 4612 [(set_attr "type" "mftgpr,*")]) 4613 4614;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector 4615;; register and then doing a direct move if the value comes from memory. On 4616;; little endian, we have to load the 2nd double-word to get the sign bit. 4617(define_insn_and_split "*signbit<mode>2_dm_mem" 4618 [(set (match_operand:DI 0 "gpc_reg_operand" "=b") 4619 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")] 4620 UNSPEC_SIGNBIT))] 4621 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 4622 "#" 4623 "&& 1" 4624 [(set (match_dup 0) 4625 (match_dup 2))] 4626{ 4627 rtx dest = operands[0]; 4628 rtx src = operands[1]; 4629 rtx addr = XEXP (src, 0); 4630 4631 if (WORDS_BIG_ENDIAN) 4632 operands[2] = adjust_address (src, DImode, 0); 4633 4634 else if (REG_P (addr) || SUBREG_P (addr)) 4635 operands[2] = adjust_address (src, DImode, 8); 4636 4637 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0)) 4638 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode)) 4639 operands[2] = adjust_address (src, DImode, 8); 4640 4641 else 4642 { 4643 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest; 4644 emit_insn (gen_rtx_SET (tmp, addr)); 4645 operands[2] = change_address (src, DImode, 4646 gen_rtx_PLUS (DImode, tmp, GEN_INT (8))); 4647 } 4648}) 4649 4650(define_expand "copysign<mode>3" 4651 [(set (match_dup 3) 4652 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" ""))) 4653 (set (match_dup 4) 4654 (neg:SFDF (abs:SFDF (match_dup 1)))) 4655 (set (match_operand:SFDF 0 "gpc_reg_operand" "") 4656 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "") 4657 (match_dup 5)) 4658 (match_dup 3) 4659 (match_dup 4)))] 4660 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> 4661 && ((TARGET_PPC_GFXOPT 4662 && !HONOR_NANS (<MODE>mode) 4663 && !HONOR_SIGNED_ZEROS (<MODE>mode)) 4664 || TARGET_CMPB 4665 || VECTOR_UNIT_VSX_P (<MODE>mode))" 4666{ 4667 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode)) 4668 { 4669 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1], 4670 operands[2])); 4671 DONE; 4672 } 4673 4674 operands[3] = gen_reg_rtx (<MODE>mode); 4675 operands[4] = gen_reg_rtx (<MODE>mode); 4676 operands[5] = CONST0_RTX (<MODE>mode); 4677 }) 4678 4679;; Use an unspec rather providing an if-then-else in RTL, to prevent the 4680;; compiler from optimizing -0.0 4681(define_insn "copysign<mode>3_fcpsgn" 4682 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4683 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") 4684 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")] 4685 UNSPEC_COPYSIGN))] 4686 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))" 4687 "@ 4688 fcpsgn %0,%2,%1 4689 xscpsgndp %x0,%x2,%x1" 4690 [(set_attr "type" "fpsimple")]) 4691 4692;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a 4693;; fsel instruction and some auxiliary computations. Then we just have a 4694;; single DEFINE_INSN for fsel and the define_splits to make them if made by 4695;; combine. 4696;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we 4697;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary 4698;; computations. Then we just have a single DEFINE_INSN for fsel and the 4699;; define_splits to make them if made by combine. On VSX machines we have the 4700;; min/max instructions. 4701;; 4702;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector 4703;; to allow either DF/SF to use only traditional registers. 4704 4705(define_expand "s<minmax><mode>3" 4706 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4707 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4708 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4709 "TARGET_MINMAX_<MODE>" 4710{ 4711 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 4712 DONE; 4713}) 4714 4715(define_insn "*s<minmax><mode>3_vsx" 4716 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 4717 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>") 4718 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))] 4719 "TARGET_VSX && TARGET_<MODE>_FPR" 4720{ 4721 return (TARGET_P9_MINMAX 4722 ? "xs<minmax>cdp %x0,%x1,%x2" 4723 : "xs<minmax>dp %x0,%x1,%x2"); 4724} 4725 [(set_attr "type" "fp")]) 4726 4727;; The conditional move instructions allow us to perform max and min operations 4728;; even when we don't have the appropriate max/min instruction using the FSEL 4729;; instruction. 4730 4731(define_insn_and_split "*s<minmax><mode>3_fpr" 4732 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4733 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4734 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4735 "!TARGET_VSX && TARGET_MINMAX_<MODE>" 4736 "#" 4737 "&& 1" 4738 [(const_int 0)] 4739{ 4740 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 4741 DONE; 4742}) 4743 4744(define_expand "mov<mode>cc" 4745 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 4746 (if_then_else:GPR (match_operand 1 "comparison_operator" "") 4747 (match_operand:GPR 2 "gpc_reg_operand" "") 4748 (match_operand:GPR 3 "gpc_reg_operand" "")))] 4749 "TARGET_ISEL<sel>" 4750 " 4751{ 4752 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 4753 DONE; 4754 else 4755 FAIL; 4756}") 4757 4758;; We use the BASE_REGS for the isel input operands because, if rA is 4759;; 0, the value of 0 is placed in rD upon truth. Similarly for rB 4760;; because we may switch the operands and rB may end up being rA. 4761;; 4762;; We need 2 patterns: an unsigned and a signed pattern. We could 4763;; leave out the mode in operand 4 and use one pattern, but reload can 4764;; change the mode underneath our feet and then gets confused trying 4765;; to reload the value. 4766(define_insn "isel_signed_<mode>" 4767 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4768 (if_then_else:GPR 4769 (match_operator 1 "scc_comparison_operator" 4770 [(match_operand:CC 4 "cc_reg_operand" "y,y") 4771 (const_int 0)]) 4772 (match_operand:GPR 2 "reg_or_cint_operand" "O,b") 4773 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] 4774 "TARGET_ISEL<sel>" 4775 "* 4776{ return output_isel (operands); }" 4777 [(set_attr "type" "isel") 4778 (set_attr "length" "4")]) 4779 4780(define_insn "isel_unsigned_<mode>" 4781 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4782 (if_then_else:GPR 4783 (match_operator 1 "scc_comparison_operator" 4784 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y") 4785 (const_int 0)]) 4786 (match_operand:GPR 2 "reg_or_cint_operand" "O,b") 4787 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] 4788 "TARGET_ISEL<sel>" 4789 "* 4790{ return output_isel (operands); }" 4791 [(set_attr "type" "isel") 4792 (set_attr "length" "4")]) 4793 4794;; These patterns can be useful for combine; they let combine know that 4795;; isel can handle reversed comparisons so long as the operands are 4796;; registers. 4797 4798(define_insn "*isel_reversed_signed_<mode>" 4799 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4800 (if_then_else:GPR 4801 (match_operator 1 "scc_rev_comparison_operator" 4802 [(match_operand:CC 4 "cc_reg_operand" "y") 4803 (const_int 0)]) 4804 (match_operand:GPR 2 "gpc_reg_operand" "b") 4805 (match_operand:GPR 3 "gpc_reg_operand" "b")))] 4806 "TARGET_ISEL<sel>" 4807 "* 4808{ return output_isel (operands); }" 4809 [(set_attr "type" "isel") 4810 (set_attr "length" "4")]) 4811 4812(define_insn "*isel_reversed_unsigned_<mode>" 4813 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4814 (if_then_else:GPR 4815 (match_operator 1 "scc_rev_comparison_operator" 4816 [(match_operand:CCUNS 4 "cc_reg_operand" "y") 4817 (const_int 0)]) 4818 (match_operand:GPR 2 "gpc_reg_operand" "b") 4819 (match_operand:GPR 3 "gpc_reg_operand" "b")))] 4820 "TARGET_ISEL<sel>" 4821 "* 4822{ return output_isel (operands); }" 4823 [(set_attr "type" "isel") 4824 (set_attr "length" "4")]) 4825 4826;; Floating point conditional move 4827(define_expand "mov<mode>cc" 4828 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4829 (if_then_else:SFDF (match_operand 1 "comparison_operator" "") 4830 (match_operand:SFDF 2 "gpc_reg_operand" "") 4831 (match_operand:SFDF 3 "gpc_reg_operand" "")))] 4832 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT" 4833 " 4834{ 4835 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 4836 DONE; 4837 else 4838 FAIL; 4839}") 4840 4841(define_insn "*fsel<SFDF:mode><SFDF2:mode>4" 4842 [(set (match_operand:SFDF 0 "fpr_reg_operand" "=&<SFDF:rreg2>") 4843 (if_then_else:SFDF 4844 (ge (match_operand:SFDF2 1 "fpr_reg_operand" "<SFDF2:rreg2>") 4845 (match_operand:SFDF2 4 "zero_fp_constant" "F")) 4846 (match_operand:SFDF 2 "fpr_reg_operand" "<SFDF:rreg2>") 4847 (match_operand:SFDF 3 "fpr_reg_operand" "<SFDF:rreg2>")))] 4848 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT" 4849 "fsel %0,%1,%2,%3" 4850 [(set_attr "type" "fp")]) 4851 4852(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9" 4853 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 4854 (if_then_else:SFDF 4855 (match_operator:CCFP 1 "fpmask_comparison_operator" 4856 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 4857 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 4858 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 4859 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 4860 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 4861 "TARGET_P9_MINMAX" 4862 "#" 4863 "" 4864 [(set (match_dup 6) 4865 (if_then_else:V2DI (match_dup 1) 4866 (match_dup 7) 4867 (match_dup 8))) 4868 (set (match_dup 0) 4869 (if_then_else:SFDF (ne (match_dup 6) 4870 (match_dup 8)) 4871 (match_dup 4) 4872 (match_dup 5)))] 4873{ 4874 if (GET_CODE (operands[6]) == SCRATCH) 4875 operands[6] = gen_reg_rtx (V2DImode); 4876 4877 operands[7] = CONSTM1_RTX (V2DImode); 4878 operands[8] = CONST0_RTX (V2DImode); 4879} 4880 [(set_attr "length" "8") 4881 (set_attr "type" "vecperm")]) 4882 4883;; Handle inverting the fpmask comparisons. 4884(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9" 4885 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 4886 (if_then_else:SFDF 4887 (match_operator:CCFP 1 "invert_fpmask_comparison_operator" 4888 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 4889 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 4890 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 4891 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 4892 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 4893 "TARGET_P9_MINMAX" 4894 "#" 4895 "&& 1" 4896 [(set (match_dup 6) 4897 (if_then_else:V2DI (match_dup 9) 4898 (match_dup 7) 4899 (match_dup 8))) 4900 (set (match_dup 0) 4901 (if_then_else:SFDF (ne (match_dup 6) 4902 (match_dup 8)) 4903 (match_dup 5) 4904 (match_dup 4)))] 4905{ 4906 rtx op1 = operands[1]; 4907 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1)); 4908 4909 if (GET_CODE (operands[6]) == SCRATCH) 4910 operands[6] = gen_reg_rtx (V2DImode); 4911 4912 operands[7] = CONSTM1_RTX (V2DImode); 4913 operands[8] = CONST0_RTX (V2DImode); 4914 4915 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]); 4916} 4917 [(set_attr "length" "8") 4918 (set_attr "type" "vecperm")]) 4919 4920(define_insn "*fpmask<mode>" 4921 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa") 4922 (if_then_else:V2DI 4923 (match_operator:CCFP 1 "fpmask_comparison_operator" 4924 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>") 4925 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")]) 4926 (match_operand:V2DI 4 "all_ones_constant" "") 4927 (match_operand:V2DI 5 "zero_constant" "")))] 4928 "TARGET_P9_MINMAX" 4929 "xscmp%V1dp %x0,%x2,%x3" 4930 [(set_attr "type" "fpcompare")]) 4931 4932(define_insn "*xxsel<mode>" 4933 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 4934 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa") 4935 (match_operand:V2DI 2 "zero_constant" "")) 4936 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>") 4937 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))] 4938 "TARGET_P9_MINMAX" 4939 "xxsel %x0,%x4,%x3,%x1" 4940 [(set_attr "type" "vecmove")]) 4941 4942 4943;; Conversions to and from floating-point. 4944 4945; We don't define lfiwax/lfiwzx with the normal definition, because we 4946; don't want to support putting SImode in FPR registers. 4947(define_insn "lfiwax" 4948 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj") 4949 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")] 4950 UNSPEC_LFIWAX))] 4951 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX" 4952 "@ 4953 lfiwax %0,%y1 4954 lxsiwax %x0,%y1 4955 mtvsrwa %x0,%1" 4956 [(set_attr "type" "fpload,fpload,mffgpr")]) 4957 4958; This split must be run before register allocation because it allocates the 4959; memory slot that is needed to move values to/from the FPR. We don't allocate 4960; it earlier to allow for the combiner to merge insns together where it might 4961; not be needed and also in case the insns are deleted as dead code. 4962 4963(define_insn_and_split "floatsi<mode>2_lfiwax" 4964 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 4965 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) 4966 (clobber (match_scratch:DI 2 "=wj"))] 4967 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX 4968 && <SI_CONVERT_FP> && can_create_pseudo_p ()" 4969 "#" 4970 "" 4971 [(pc)] 4972 " 4973{ 4974 rtx dest = operands[0]; 4975 rtx src = operands[1]; 4976 rtx tmp; 4977 4978 if (!MEM_P (src) && TARGET_POWERPC64 4979 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 4980 tmp = convert_to_mode (DImode, src, false); 4981 else 4982 { 4983 tmp = operands[2]; 4984 if (GET_CODE (tmp) == SCRATCH) 4985 tmp = gen_reg_rtx (DImode); 4986 if (MEM_P (src)) 4987 { 4988 src = rs6000_address_for_fpconvert (src); 4989 emit_insn (gen_lfiwax (tmp, src)); 4990 } 4991 else 4992 { 4993 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 4994 emit_move_insn (stack, src); 4995 emit_insn (gen_lfiwax (tmp, stack)); 4996 } 4997 } 4998 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 4999 DONE; 5000}" 5001 [(set_attr "length" "12") 5002 (set_attr "type" "fpload")]) 5003 5004(define_insn_and_split "floatsi<mode>2_lfiwax_mem" 5005 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>") 5006 (float:SFDF 5007 (sign_extend:DI 5008 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z")))) 5009 (clobber (match_scratch:DI 2 "=0,d"))] 5010 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX 5011 && <SI_CONVERT_FP>" 5012 "#" 5013 "" 5014 [(pc)] 5015 " 5016{ 5017 operands[1] = rs6000_address_for_fpconvert (operands[1]); 5018 if (GET_CODE (operands[2]) == SCRATCH) 5019 operands[2] = gen_reg_rtx (DImode); 5020 emit_insn (gen_lfiwax (operands[2], operands[1])); 5021 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5022 DONE; 5023}" 5024 [(set_attr "length" "8") 5025 (set_attr "type" "fpload")]) 5026 5027(define_insn "lfiwzx" 5028 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,!wj") 5029 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r")] 5030 UNSPEC_LFIWZX))] 5031 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX" 5032 "@ 5033 lfiwzx %0,%y1 5034 lxsiwzx %x0,%y1 5035 mtvsrwz %x0,%1" 5036 [(set_attr "type" "fpload,fpload,mftgpr")]) 5037 5038(define_insn_and_split "floatunssi<mode>2_lfiwzx" 5039 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5040 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) 5041 (clobber (match_scratch:DI 2 "=wj"))] 5042 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX 5043 && <SI_CONVERT_FP>" 5044 "#" 5045 "" 5046 [(pc)] 5047 " 5048{ 5049 rtx dest = operands[0]; 5050 rtx src = operands[1]; 5051 rtx tmp; 5052 5053 if (!MEM_P (src) && TARGET_POWERPC64 5054 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5055 tmp = convert_to_mode (DImode, src, true); 5056 else 5057 { 5058 tmp = operands[2]; 5059 if (GET_CODE (tmp) == SCRATCH) 5060 tmp = gen_reg_rtx (DImode); 5061 if (MEM_P (src)) 5062 { 5063 src = rs6000_address_for_fpconvert (src); 5064 emit_insn (gen_lfiwzx (tmp, src)); 5065 } 5066 else 5067 { 5068 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5069 emit_move_insn (stack, src); 5070 emit_insn (gen_lfiwzx (tmp, stack)); 5071 } 5072 } 5073 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5074 DONE; 5075}" 5076 [(set_attr "length" "12") 5077 (set_attr "type" "fpload")]) 5078 5079(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem" 5080 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fa>") 5081 (unsigned_float:SFDF 5082 (zero_extend:DI 5083 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z")))) 5084 (clobber (match_scratch:DI 2 "=0,d"))] 5085 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX 5086 && <SI_CONVERT_FP>" 5087 "#" 5088 "" 5089 [(pc)] 5090 " 5091{ 5092 operands[1] = rs6000_address_for_fpconvert (operands[1]); 5093 if (GET_CODE (operands[2]) == SCRATCH) 5094 operands[2] = gen_reg_rtx (DImode); 5095 emit_insn (gen_lfiwzx (operands[2], operands[1])); 5096 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5097 DONE; 5098}" 5099 [(set_attr "length" "8") 5100 (set_attr "type" "fpload")]) 5101 5102; For each of these conversions, there is a define_expand, a define_insn 5103; with a '#' template, and a define_split (with C code). The idea is 5104; to allow constant folding with the template of the define_insn, 5105; then to have the insns split later (between sched1 and final). 5106 5107(define_expand "floatsidf2" 5108 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") 5109 (float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) 5110 (use (match_dup 2)) 5111 (use (match_dup 3)) 5112 (clobber (match_dup 4)) 5113 (clobber (match_dup 5)) 5114 (clobber (match_dup 6))])] 5115 "TARGET_HARD_FLOAT 5116 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" 5117 " 5118{ 5119 if (TARGET_E500_DOUBLE) 5120 { 5121 if (!REG_P (operands[1])) 5122 operands[1] = force_reg (SImode, operands[1]); 5123 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1])); 5124 DONE; 5125 } 5126 else if (TARGET_LFIWAX && TARGET_FCFID) 5127 { 5128 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1])); 5129 DONE; 5130 } 5131 else if (TARGET_FCFID) 5132 { 5133 rtx dreg = operands[1]; 5134 if (!REG_P (dreg)) 5135 dreg = force_reg (SImode, dreg); 5136 dreg = convert_to_mode (DImode, dreg, false); 5137 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5138 DONE; 5139 } 5140 5141 if (!REG_P (operands[1])) 5142 operands[1] = force_reg (SImode, operands[1]); 5143 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5144 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); 5145 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5146 operands[5] = gen_reg_rtx (DFmode); 5147 operands[6] = gen_reg_rtx (SImode); 5148}") 5149 5150(define_insn_and_split "*floatsidf2_internal" 5151 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5152 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5153 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5154 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5155 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5156 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) 5157 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] 5158 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 5159 "#" 5160 "" 5161 [(pc)] 5162 " 5163{ 5164 rtx lowword, highword; 5165 gcc_assert (MEM_P (operands[4])); 5166 highword = adjust_address (operands[4], SImode, 0); 5167 lowword = adjust_address (operands[4], SImode, 4); 5168 if (! WORDS_BIG_ENDIAN) 5169 std::swap (lowword, highword); 5170 5171 emit_insn (gen_xorsi3 (operands[6], operands[1], 5172 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff))); 5173 emit_move_insn (lowword, operands[6]); 5174 emit_move_insn (highword, operands[2]); 5175 emit_move_insn (operands[5], operands[4]); 5176 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5177 DONE; 5178}" 5179 [(set_attr "length" "24") 5180 (set_attr "type" "fp")]) 5181 5182;; If we don't have a direct conversion to single precision, don't enable this 5183;; conversion for 32-bit without fast math, because we don't have the insn to 5184;; generate the fixup swizzle to avoid double rounding problems. 5185(define_expand "floatunssisf2" 5186 [(set (match_operand:SF 0 "gpc_reg_operand" "") 5187 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] 5188 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 5189 && (!TARGET_FPRS 5190 || (TARGET_FPRS 5191 && ((TARGET_FCFIDUS && TARGET_LFIWZX) 5192 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID 5193 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))" 5194 " 5195{ 5196 if (!TARGET_FPRS) 5197 { 5198 if (!REG_P (operands[1])) 5199 operands[1] = force_reg (SImode, operands[1]); 5200 } 5201 else if (TARGET_LFIWZX && TARGET_FCFIDUS) 5202 { 5203 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1])); 5204 DONE; 5205 } 5206 else 5207 { 5208 rtx dreg = operands[1]; 5209 if (!REG_P (dreg)) 5210 dreg = force_reg (SImode, dreg); 5211 dreg = convert_to_mode (DImode, dreg, true); 5212 emit_insn (gen_floatdisf2 (operands[0], dreg)); 5213 DONE; 5214 } 5215}") 5216 5217(define_expand "floatunssidf2" 5218 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") 5219 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) 5220 (use (match_dup 2)) 5221 (use (match_dup 3)) 5222 (clobber (match_dup 4)) 5223 (clobber (match_dup 5))])] 5224 "TARGET_HARD_FLOAT 5225 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" 5226 " 5227{ 5228 if (TARGET_E500_DOUBLE) 5229 { 5230 if (!REG_P (operands[1])) 5231 operands[1] = force_reg (SImode, operands[1]); 5232 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1])); 5233 DONE; 5234 } 5235 else if (TARGET_LFIWZX && TARGET_FCFID) 5236 { 5237 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1])); 5238 DONE; 5239 } 5240 else if (TARGET_FCFID) 5241 { 5242 rtx dreg = operands[1]; 5243 if (!REG_P (dreg)) 5244 dreg = force_reg (SImode, dreg); 5245 dreg = convert_to_mode (DImode, dreg, true); 5246 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5247 DONE; 5248 } 5249 5250 if (!REG_P (operands[1])) 5251 operands[1] = force_reg (SImode, operands[1]); 5252 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5253 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); 5254 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5255 operands[5] = gen_reg_rtx (DFmode); 5256}") 5257 5258(define_insn_and_split "*floatunssidf2_internal" 5259 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5260 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5261 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5262 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5263 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5264 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] 5265 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5266 && !(TARGET_FCFID && TARGET_POWERPC64)" 5267 "#" 5268 "" 5269 [(pc)] 5270 " 5271{ 5272 rtx lowword, highword; 5273 gcc_assert (MEM_P (operands[4])); 5274 highword = adjust_address (operands[4], SImode, 0); 5275 lowword = adjust_address (operands[4], SImode, 4); 5276 if (! WORDS_BIG_ENDIAN) 5277 std::swap (lowword, highword); 5278 5279 emit_move_insn (lowword, operands[1]); 5280 emit_move_insn (highword, operands[2]); 5281 emit_move_insn (operands[5], operands[4]); 5282 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5283 DONE; 5284}" 5285 [(set_attr "length" "20") 5286 (set_attr "type" "fp")]) 5287 5288(define_expand "fix_trunc<mode>si2" 5289 [(set (match_operand:SI 0 "gpc_reg_operand" "") 5290 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))] 5291 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)" 5292 " 5293{ 5294 if (!<E500_CONVERT>) 5295 { 5296 rtx tmp, stack; 5297 5298 if (TARGET_STFIWX) 5299 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], operands[1])); 5300 else 5301 { 5302 tmp = gen_reg_rtx (DImode); 5303 stack = rs6000_allocate_stack_temp (DImode, true, false); 5304 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], operands[1], 5305 tmp, stack)); 5306 } 5307 DONE; 5308 } 5309}") 5310 5311; Like the convert to float patterns, this insn must be split before 5312; register allocation so that it can allocate the memory slot if it 5313; needed 5314(define_insn_and_split "fix_trunc<mode>si2_stfiwx" 5315 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5316 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 5317 (clobber (match_scratch:DI 2 "=d"))] 5318 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5319 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT) 5320 && TARGET_STFIWX && can_create_pseudo_p ()" 5321 "#" 5322 "" 5323 [(pc)] 5324{ 5325 rtx dest = operands[0]; 5326 rtx src = operands[1]; 5327 rtx tmp = operands[2]; 5328 5329 if (GET_CODE (tmp) == SCRATCH) 5330 tmp = gen_reg_rtx (DImode); 5331 5332 emit_insn (gen_fctiwz_<mode> (tmp, src)); 5333 if (MEM_P (dest)) 5334 { 5335 dest = rs6000_address_for_fpconvert (dest); 5336 emit_insn (gen_stfiwx (dest, tmp)); 5337 DONE; 5338 } 5339 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5340 { 5341 dest = gen_lowpart (DImode, dest); 5342 emit_move_insn (dest, tmp); 5343 DONE; 5344 } 5345 else 5346 { 5347 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5348 emit_insn (gen_stfiwx (stack, tmp)); 5349 emit_move_insn (dest, stack); 5350 DONE; 5351 } 5352} 5353 [(set_attr "length" "12") 5354 (set_attr "type" "fp")]) 5355 5356(define_insn_and_split "fix_trunc<mode>si2_internal" 5357 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r") 5358 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>"))) 5359 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d")) 5360 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))] 5361 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 5362 "#" 5363 "" 5364 [(pc)] 5365 " 5366{ 5367 rtx lowword; 5368 gcc_assert (MEM_P (operands[3])); 5369 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 5370 5371 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1])); 5372 emit_move_insn (operands[3], operands[2]); 5373 emit_move_insn (operands[0], lowword); 5374 DONE; 5375}" 5376 [(set_attr "length" "16") 5377 (set_attr "type" "fp")]) 5378 5379(define_expand "fix_trunc<mode>di2" 5380 [(set (match_operand:DI 0 "gpc_reg_operand" "") 5381 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))] 5382 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS 5383 && TARGET_FCFID" 5384 "") 5385 5386(define_insn "*fix_trunc<mode>di2_fctidz" 5387 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5388 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))] 5389 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS 5390 && TARGET_FCFID" 5391 "@ 5392 fctidz %0,%1 5393 xscvdpsxds %x0,%x1" 5394 [(set_attr "type" "fp")]) 5395 5396(define_expand "fixuns_trunc<mode>si2" 5397 [(set (match_operand:SI 0 "gpc_reg_operand" "") 5398 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))] 5399 "TARGET_HARD_FLOAT 5400 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX) 5401 || <E500_CONVERT>)" 5402 " 5403{ 5404 if (!<E500_CONVERT>) 5405 { 5406 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1])); 5407 DONE; 5408 } 5409}") 5410 5411(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx" 5412 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5413 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 5414 (clobber (match_scratch:DI 2 "=d"))] 5415 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ 5416 && TARGET_STFIWX && can_create_pseudo_p ()" 5417 "#" 5418 "" 5419 [(pc)] 5420{ 5421 rtx dest = operands[0]; 5422 rtx src = operands[1]; 5423 rtx tmp = operands[2]; 5424 5425 if (GET_CODE (tmp) == SCRATCH) 5426 tmp = gen_reg_rtx (DImode); 5427 5428 emit_insn (gen_fctiwuz_<mode> (tmp, src)); 5429 if (MEM_P (dest)) 5430 { 5431 dest = rs6000_address_for_fpconvert (dest); 5432 emit_insn (gen_stfiwx (dest, tmp)); 5433 DONE; 5434 } 5435 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5436 { 5437 dest = gen_lowpart (DImode, dest); 5438 emit_move_insn (dest, tmp); 5439 DONE; 5440 } 5441 else 5442 { 5443 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5444 emit_insn (gen_stfiwx (stack, tmp)); 5445 emit_move_insn (dest, stack); 5446 DONE; 5447 } 5448} 5449 [(set_attr "length" "12") 5450 (set_attr "type" "fp")]) 5451 5452(define_insn "fixuns_trunc<mode>di2" 5453 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5454 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fa>")))] 5455 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ" 5456 "@ 5457 fctiduz %0,%1 5458 xscvdpuxds %x0,%x1" 5459 [(set_attr "type" "fp")]) 5460 5461; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) 5462; rather than (set (subreg:SI (reg)) (fix:SI ...)) 5463; because the first makes it clear that operand 0 is not live 5464; before the instruction. 5465(define_insn "fctiwz_<mode>" 5466 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5467 (unspec:DI [(fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 5468 UNSPEC_FCTIWZ))] 5469 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 5470 "@ 5471 fctiwz %0,%1 5472 xscvdpsxws %x0,%x1" 5473 [(set_attr "type" "fp")]) 5474 5475(define_insn "fctiwuz_<mode>" 5476 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5477 (unspec:DI [(unsigned_fix:SI 5478 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 5479 UNSPEC_FCTIWUZ))] 5480 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ" 5481 "@ 5482 fctiwuz %0,%1 5483 xscvdpuxws %x0,%x1" 5484 [(set_attr "type" "fp")]) 5485 5486;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since 5487;; since the friz instruction does not truncate the value if the floating 5488;; point value is < LONG_MIN or > LONG_MAX. 5489(define_insn "*friz" 5490 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 5491 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))] 5492 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND 5493 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ" 5494 "@ 5495 friz %0,%1 5496 xsrdpiz %x0,%x1" 5497 [(set_attr "type" "fp")]) 5498 5499;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This 5500;; optimization prevents on ISA 2.06 systems and earlier having to store the 5501;; value from the FPR/vector unit to the stack, load the value into a GPR, sign 5502;; extend it, store it back on the stack from the GPR, load it back into the 5503;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07), 5504;; disable using store and load to sign/zero extend the value. 5505(define_insn_and_split "*round32<mode>2_fprs" 5506 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 5507 (float:SFDF 5508 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 5509 (clobber (match_scratch:DI 2 "=d")) 5510 (clobber (match_scratch:DI 3 "=d"))] 5511 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5512 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID 5513 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()" 5514 "#" 5515 "" 5516 [(pc)] 5517{ 5518 rtx dest = operands[0]; 5519 rtx src = operands[1]; 5520 rtx tmp1 = operands[2]; 5521 rtx tmp2 = operands[3]; 5522 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5523 5524 if (GET_CODE (tmp1) == SCRATCH) 5525 tmp1 = gen_reg_rtx (DImode); 5526 if (GET_CODE (tmp2) == SCRATCH) 5527 tmp2 = gen_reg_rtx (DImode); 5528 5529 emit_insn (gen_fctiwz_<mode> (tmp1, src)); 5530 emit_insn (gen_stfiwx (stack, tmp1)); 5531 emit_insn (gen_lfiwax (tmp2, stack)); 5532 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 5533 DONE; 5534} 5535 [(set_attr "type" "fpload") 5536 (set_attr "length" "16")]) 5537 5538(define_insn_and_split "*roundu32<mode>2_fprs" 5539 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 5540 (unsigned_float:SFDF 5541 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 5542 (clobber (match_scratch:DI 2 "=d")) 5543 (clobber (match_scratch:DI 3 "=d"))] 5544 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5545 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE 5546 && can_create_pseudo_p ()" 5547 "#" 5548 "" 5549 [(pc)] 5550{ 5551 rtx dest = operands[0]; 5552 rtx src = operands[1]; 5553 rtx tmp1 = operands[2]; 5554 rtx tmp2 = operands[3]; 5555 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5556 5557 if (GET_CODE (tmp1) == SCRATCH) 5558 tmp1 = gen_reg_rtx (DImode); 5559 if (GET_CODE (tmp2) == SCRATCH) 5560 tmp2 = gen_reg_rtx (DImode); 5561 5562 emit_insn (gen_fctiwuz_<mode> (tmp1, src)); 5563 emit_insn (gen_stfiwx (stack, tmp1)); 5564 emit_insn (gen_lfiwzx (tmp2, stack)); 5565 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 5566 DONE; 5567} 5568 [(set_attr "type" "fpload") 5569 (set_attr "length" "16")]) 5570 5571;; No VSX equivalent to fctid 5572(define_insn "lrint<mode>di2" 5573 [(set (match_operand:DI 0 "gpc_reg_operand" "=d") 5574 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 5575 UNSPEC_FCTID))] 5576 "TARGET_<MODE>_FPR && TARGET_FPRND" 5577 "fctid %0,%1" 5578 [(set_attr "type" "fp")]) 5579 5580(define_insn "btrunc<mode>2" 5581 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5582 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 5583 UNSPEC_FRIZ))] 5584 "TARGET_<MODE>_FPR && TARGET_FPRND" 5585 "@ 5586 friz %0,%1 5587 xsrdpiz %x0,%x1" 5588 [(set_attr "type" "fp") 5589 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5590 5591(define_insn "ceil<mode>2" 5592 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5593 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 5594 UNSPEC_FRIP))] 5595 "TARGET_<MODE>_FPR && TARGET_FPRND" 5596 "@ 5597 frip %0,%1 5598 xsrdpip %x0,%x1" 5599 [(set_attr "type" "fp") 5600 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5601 5602(define_insn "floor<mode>2" 5603 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5604 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 5605 UNSPEC_FRIM))] 5606 "TARGET_<MODE>_FPR && TARGET_FPRND" 5607 "@ 5608 frim %0,%1 5609 xsrdpim %x0,%x1" 5610 [(set_attr "type" "fp") 5611 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5612 5613;; No VSX equivalent to frin 5614(define_insn "round<mode>2" 5615 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") 5616 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 5617 UNSPEC_FRIN))] 5618 "TARGET_<MODE>_FPR && TARGET_FPRND" 5619 "frin %0,%1" 5620 [(set_attr "type" "fp") 5621 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5622 5623(define_insn "*xsrdpi<mode>2" 5624 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5625 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")] 5626 UNSPEC_XSRDPI))] 5627 "TARGET_<MODE>_FPR && TARGET_VSX" 5628 "xsrdpi %x0,%x1" 5629 [(set_attr "type" "fp") 5630 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5631 5632(define_expand "lround<mode>di2" 5633 [(set (match_dup 2) 5634 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")] 5635 UNSPEC_XSRDPI)) 5636 (set (match_operand:DI 0 "gpc_reg_operand" "") 5637 (unspec:DI [(match_dup 2)] 5638 UNSPEC_FCTID))] 5639 "TARGET_<MODE>_FPR && TARGET_VSX" 5640{ 5641 operands[2] = gen_reg_rtx (<MODE>mode); 5642}) 5643 5644; An UNSPEC is used so we don't have to support SImode in FP registers. 5645(define_insn "stfiwx" 5646 [(set (match_operand:SI 0 "memory_operand" "=Z") 5647 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d")] 5648 UNSPEC_STFIWX))] 5649 "TARGET_PPC_GFXOPT" 5650 "stfiwx %1,%y0" 5651 [(set_attr "type" "fpstore")]) 5652 5653;; If we don't have a direct conversion to single precision, don't enable this 5654;; conversion for 32-bit without fast math, because we don't have the insn to 5655;; generate the fixup swizzle to avoid double rounding problems. 5656(define_expand "floatsisf2" 5657 [(set (match_operand:SF 0 "gpc_reg_operand" "") 5658 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] 5659 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 5660 && (!TARGET_FPRS 5661 || (TARGET_FPRS 5662 && ((TARGET_FCFIDS && TARGET_LFIWAX) 5663 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID 5664 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))" 5665 " 5666{ 5667 if (!TARGET_FPRS) 5668 { 5669 if (!REG_P (operands[1])) 5670 operands[1] = force_reg (SImode, operands[1]); 5671 } 5672 else if (TARGET_FCFIDS && TARGET_LFIWAX) 5673 { 5674 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1])); 5675 DONE; 5676 } 5677 else if (TARGET_FCFID && TARGET_LFIWAX) 5678 { 5679 rtx dfreg = gen_reg_rtx (DFmode); 5680 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1])); 5681 emit_insn (gen_truncdfsf2 (operands[0], dfreg)); 5682 DONE; 5683 } 5684 else 5685 { 5686 rtx dreg = operands[1]; 5687 if (!REG_P (dreg)) 5688 dreg = force_reg (SImode, dreg); 5689 dreg = convert_to_mode (DImode, dreg, false); 5690 emit_insn (gen_floatdisf2 (operands[0], dreg)); 5691 DONE; 5692 } 5693}") 5694 5695(define_expand "floatdidf2" 5696 [(set (match_operand:DF 0 "gpc_reg_operand" "") 5697 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))] 5698 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" 5699 "") 5700 5701(define_insn "*floatdidf2_fpr" 5702 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 5703 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 5704 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" 5705 "@ 5706 fcfid %0,%1 5707 xscvsxddp %x0,%x1" 5708 [(set_attr "type" "fp")]) 5709 5710; Allow the combiner to merge source memory operands to the conversion so that 5711; the optimizer/register allocator doesn't try to load the value too early in a 5712; GPR and then use store/load to move it to a FPR and suffer from a store-load 5713; hit. We will split after reload to avoid the trip through the GPRs 5714 5715(define_insn_and_split "*floatdidf2_mem" 5716 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 5717 (float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 5718 (clobber (match_scratch:DI 2 "=d,wi"))] 5719 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID" 5720 "#" 5721 "&& reload_completed" 5722 [(set (match_dup 2) (match_dup 1)) 5723 (set (match_dup 0) (float:DF (match_dup 2)))] 5724 "" 5725 [(set_attr "length" "8") 5726 (set_attr "type" "fpload")]) 5727 5728(define_expand "floatunsdidf2" 5729 [(set (match_operand:DF 0 "gpc_reg_operand" "") 5730 (unsigned_float:DF 5731 (match_operand:DI 1 "gpc_reg_operand" "")))] 5732 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 5733 "") 5734 5735(define_insn "*floatunsdidf2_fcfidu" 5736 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 5737 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 5738 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 5739 "@ 5740 fcfidu %0,%1 5741 xscvuxddp %x0,%x1" 5742 [(set_attr "type" "fp") 5743 (set_attr "length" "4")]) 5744 5745(define_insn_and_split "*floatunsdidf2_mem" 5746 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 5747 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 5748 (clobber (match_scratch:DI 2 "=d,wi"))] 5749 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))" 5750 "#" 5751 "&& reload_completed" 5752 [(set (match_dup 2) (match_dup 1)) 5753 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))] 5754 "" 5755 [(set_attr "length" "8") 5756 (set_attr "type" "fpload")]) 5757 5758(define_expand "floatdisf2" 5759 [(set (match_operand:SF 0 "gpc_reg_operand" "") 5760 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] 5761 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 5762 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)" 5763 " 5764{ 5765 if (!TARGET_FCFIDS) 5766 { 5767 rtx val = operands[1]; 5768 if (!flag_unsafe_math_optimizations) 5769 { 5770 rtx label = gen_label_rtx (); 5771 val = gen_reg_rtx (DImode); 5772 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label)); 5773 emit_label (label); 5774 } 5775 emit_insn (gen_floatdisf2_internal1 (operands[0], val)); 5776 DONE; 5777 } 5778}") 5779 5780(define_insn "floatdisf2_fcfids" 5781 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy") 5782 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 5783 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 5784 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS" 5785 "@ 5786 fcfids %0,%1 5787 xscvsxdsp %x0,%x1" 5788 [(set_attr "type" "fp")]) 5789 5790(define_insn_and_split "*floatdisf2_mem" 5791 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy") 5792 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 5793 (clobber (match_scratch:DI 2 "=d,d,wi"))] 5794 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 5795 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS" 5796 "#" 5797 "&& reload_completed" 5798 [(pc)] 5799 " 5800{ 5801 emit_move_insn (operands[2], operands[1]); 5802 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2])); 5803 DONE; 5804}" 5805 [(set_attr "length" "8")]) 5806 5807;; This is not IEEE compliant if rounding mode is "round to nearest". 5808;; If the DI->DF conversion is inexact, then it's possible to suffer 5809;; from double rounding. 5810;; Instead of creating a new cpu type for two FP operations, just use fp 5811(define_insn_and_split "floatdisf2_internal1" 5812 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 5813 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d"))) 5814 (clobber (match_scratch:DF 2 "=d"))] 5815 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 5816 && !TARGET_FCFIDS" 5817 "#" 5818 "&& reload_completed" 5819 [(set (match_dup 2) 5820 (float:DF (match_dup 1))) 5821 (set (match_dup 0) 5822 (float_truncate:SF (match_dup 2)))] 5823 "" 5824 [(set_attr "length" "8") 5825 (set_attr "type" "fp")]) 5826 5827;; Twiddles bits to avoid double rounding. 5828;; Bits that might be truncated when converting to DFmode are replaced 5829;; by a bit that won't be lost at that stage, but is below the SFmode 5830;; rounding position. 5831(define_expand "floatdisf2_internal2" 5832 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "") 5833 (const_int 53))) 5834 (clobber (reg:DI CA_REGNO))]) 5835 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1) 5836 (const_int 2047))) 5837 (set (match_dup 3) (plus:DI (match_dup 3) 5838 (const_int 1))) 5839 (set (match_dup 0) (plus:DI (match_dup 0) 5840 (const_int 2047))) 5841 (set (match_dup 4) (compare:CCUNS (match_dup 3) 5842 (const_int 2))) 5843 (set (match_dup 0) (ior:DI (match_dup 0) 5844 (match_dup 1))) 5845 (set (match_dup 0) (and:DI (match_dup 0) 5846 (const_int -2048))) 5847 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) 5848 (label_ref (match_operand:DI 2 "" "")) 5849 (pc))) 5850 (set (match_dup 0) (match_dup 1))] 5851 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 5852 && !TARGET_FCFIDS" 5853 " 5854{ 5855 operands[3] = gen_reg_rtx (DImode); 5856 operands[4] = gen_reg_rtx (CCUNSmode); 5857}") 5858 5859(define_expand "floatunsdisf2" 5860 [(set (match_operand:SF 0 "gpc_reg_operand" "") 5861 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] 5862 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 5863 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" 5864 "") 5865 5866(define_insn "floatunsdisf2_fcfidus" 5867 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu") 5868 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 5869 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 5870 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" 5871 "@ 5872 fcfidus %0,%1 5873 xscvuxdsp %x0,%x1" 5874 [(set_attr "type" "fp")]) 5875 5876(define_insn_and_split "*floatunsdisf2_mem" 5877 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy") 5878 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 5879 (clobber (match_scratch:DI 2 "=d,d,wi"))] 5880 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 5881 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" 5882 "#" 5883 "&& reload_completed" 5884 [(pc)] 5885 " 5886{ 5887 emit_move_insn (operands[2], operands[1]); 5888 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2])); 5889 DONE; 5890}" 5891 [(set_attr "length" "8") 5892 (set_attr "type" "fpload")]) 5893 5894;; Define the TImode operations that can be done in a small number 5895;; of instructions. The & constraints are to prevent the register 5896;; allocator from allocating registers that overlap with the inputs 5897;; (for example, having an input in 7,8 and an output in 6,7). We 5898;; also allow for the output being the same as one of the inputs. 5899 5900(define_expand "addti3" 5901 [(set (match_operand:TI 0 "gpc_reg_operand" "") 5902 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "") 5903 (match_operand:TI 2 "reg_or_short_operand" "")))] 5904 "TARGET_64BIT" 5905{ 5906 rtx lo0 = gen_lowpart (DImode, operands[0]); 5907 rtx lo1 = gen_lowpart (DImode, operands[1]); 5908 rtx lo2 = gen_lowpart (DImode, operands[2]); 5909 rtx hi0 = gen_highpart (DImode, operands[0]); 5910 rtx hi1 = gen_highpart (DImode, operands[1]); 5911 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]); 5912 5913 if (!reg_or_short_operand (lo2, DImode)) 5914 lo2 = force_reg (DImode, lo2); 5915 if (!adde_operand (hi2, DImode)) 5916 hi2 = force_reg (DImode, hi2); 5917 5918 emit_insn (gen_adddi3_carry (lo0, lo1, lo2)); 5919 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2)); 5920 DONE; 5921}) 5922 5923(define_expand "subti3" 5924 [(set (match_operand:TI 0 "gpc_reg_operand" "") 5925 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "") 5926 (match_operand:TI 2 "gpc_reg_operand" "")))] 5927 "TARGET_64BIT" 5928{ 5929 rtx lo0 = gen_lowpart (DImode, operands[0]); 5930 rtx lo1 = gen_lowpart (DImode, operands[1]); 5931 rtx lo2 = gen_lowpart (DImode, operands[2]); 5932 rtx hi0 = gen_highpart (DImode, operands[0]); 5933 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]); 5934 rtx hi2 = gen_highpart (DImode, operands[2]); 5935 5936 if (!reg_or_short_operand (lo1, DImode)) 5937 lo1 = force_reg (DImode, lo1); 5938 if (!adde_operand (hi1, DImode)) 5939 hi1 = force_reg (DImode, hi1); 5940 5941 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1)); 5942 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1)); 5943 DONE; 5944}) 5945 5946;; 128-bit logical operations expanders 5947 5948(define_expand "and<mode>3" 5949 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 5950 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") 5951 (match_operand:BOOL_128 2 "vlogical_operand" "")))] 5952 "" 5953 "") 5954 5955(define_expand "ior<mode>3" 5956 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 5957 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") 5958 (match_operand:BOOL_128 2 "vlogical_operand" "")))] 5959 "" 5960 "") 5961 5962(define_expand "xor<mode>3" 5963 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 5964 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") 5965 (match_operand:BOOL_128 2 "vlogical_operand" "")))] 5966 "" 5967 "") 5968 5969(define_expand "one_cmpl<mode>2" 5970 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 5971 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))] 5972 "" 5973 "") 5974 5975(define_expand "nor<mode>3" 5976 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 5977 (and:BOOL_128 5978 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")) 5979 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))] 5980 "" 5981 "") 5982 5983(define_expand "andc<mode>3" 5984 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 5985 (and:BOOL_128 5986 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" "")) 5987 (match_operand:BOOL_128 1 "vlogical_operand" "")))] 5988 "" 5989 "") 5990 5991;; Power8 vector logical instructions. 5992(define_expand "eqv<mode>3" 5993 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 5994 (not:BOOL_128 5995 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") 5996 (match_operand:BOOL_128 2 "vlogical_operand" ""))))] 5997 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 5998 "") 5999 6000;; Rewrite nand into canonical form 6001(define_expand "nand<mode>3" 6002 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6003 (ior:BOOL_128 6004 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")) 6005 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))] 6006 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6007 "") 6008 6009;; The canonical form is to have the negated element first, so we need to 6010;; reverse arguments. 6011(define_expand "orc<mode>3" 6012 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6013 (ior:BOOL_128 6014 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" "")) 6015 (match_operand:BOOL_128 1 "vlogical_operand" "")))] 6016 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6017 "") 6018 6019;; 128-bit logical operations insns and split operations 6020(define_insn_and_split "*and<mode>3_internal" 6021 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6022 (and:BOOL_128 6023 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 6024 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))] 6025 "" 6026{ 6027 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6028 return "xxland %x0,%x1,%x2"; 6029 6030 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6031 return "vand %0,%1,%2"; 6032 6033 return "#"; 6034} 6035 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6036 [(const_int 0)] 6037{ 6038 rs6000_split_logical (operands, AND, false, false, false); 6039 DONE; 6040} 6041 [(set (attr "type") 6042 (if_then_else 6043 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6044 (const_string "veclogical") 6045 (const_string "integer"))) 6046 (set (attr "length") 6047 (if_then_else 6048 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6049 (const_string "4") 6050 (if_then_else 6051 (match_test "TARGET_POWERPC64") 6052 (const_string "8") 6053 (const_string "16"))))]) 6054 6055;; 128-bit IOR/XOR 6056(define_insn_and_split "*bool<mode>3_internal" 6057 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6058 (match_operator:BOOL_128 3 "boolean_or_operator" 6059 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 6060 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))] 6061 "" 6062{ 6063 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6064 return "xxl%q3 %x0,%x1,%x2"; 6065 6066 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6067 return "v%q3 %0,%1,%2"; 6068 6069 return "#"; 6070} 6071 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6072 [(const_int 0)] 6073{ 6074 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false); 6075 DONE; 6076} 6077 [(set (attr "type") 6078 (if_then_else 6079 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6080 (const_string "veclogical") 6081 (const_string "integer"))) 6082 (set (attr "length") 6083 (if_then_else 6084 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6085 (const_string "4") 6086 (if_then_else 6087 (match_test "TARGET_POWERPC64") 6088 (const_string "8") 6089 (const_string "16"))))]) 6090 6091;; 128-bit ANDC/ORC 6092(define_insn_and_split "*boolc<mode>3_internal1" 6093 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6094 (match_operator:BOOL_128 3 "boolean_operator" 6095 [(not:BOOL_128 6096 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")) 6097 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))] 6098 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 6099{ 6100 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6101 return "xxl%q3 %x0,%x1,%x2"; 6102 6103 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6104 return "v%q3 %0,%1,%2"; 6105 6106 return "#"; 6107} 6108 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 6109 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6110 [(const_int 0)] 6111{ 6112 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 6113 DONE; 6114} 6115 [(set (attr "type") 6116 (if_then_else 6117 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6118 (const_string "veclogical") 6119 (const_string "integer"))) 6120 (set (attr "length") 6121 (if_then_else 6122 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6123 (const_string "4") 6124 (if_then_else 6125 (match_test "TARGET_POWERPC64") 6126 (const_string "8") 6127 (const_string "16"))))]) 6128 6129(define_insn_and_split "*boolc<mode>3_internal2" 6130 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6131 (match_operator:TI2 3 "boolean_operator" 6132 [(not:TI2 6133 (match_operand:TI2 2 "int_reg_operand" "r,0,r")) 6134 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))] 6135 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6136 "#" 6137 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6138 [(const_int 0)] 6139{ 6140 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 6141 DONE; 6142} 6143 [(set_attr "type" "integer") 6144 (set (attr "length") 6145 (if_then_else 6146 (match_test "TARGET_POWERPC64") 6147 (const_string "8") 6148 (const_string "16")))]) 6149 6150;; 128-bit NAND/NOR 6151(define_insn_and_split "*boolcc<mode>3_internal1" 6152 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6153 (match_operator:BOOL_128 3 "boolean_operator" 6154 [(not:BOOL_128 6155 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")) 6156 (not:BOOL_128 6157 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))] 6158 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 6159{ 6160 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6161 return "xxl%q3 %x0,%x1,%x2"; 6162 6163 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6164 return "v%q3 %0,%1,%2"; 6165 6166 return "#"; 6167} 6168 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 6169 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6170 [(const_int 0)] 6171{ 6172 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 6173 DONE; 6174} 6175 [(set (attr "type") 6176 (if_then_else 6177 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6178 (const_string "veclogical") 6179 (const_string "integer"))) 6180 (set (attr "length") 6181 (if_then_else 6182 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6183 (const_string "4") 6184 (if_then_else 6185 (match_test "TARGET_POWERPC64") 6186 (const_string "8") 6187 (const_string "16"))))]) 6188 6189(define_insn_and_split "*boolcc<mode>3_internal2" 6190 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6191 (match_operator:TI2 3 "boolean_operator" 6192 [(not:TI2 6193 (match_operand:TI2 1 "int_reg_operand" "r,0,r")) 6194 (not:TI2 6195 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))] 6196 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6197 "#" 6198 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6199 [(const_int 0)] 6200{ 6201 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 6202 DONE; 6203} 6204 [(set_attr "type" "integer") 6205 (set (attr "length") 6206 (if_then_else 6207 (match_test "TARGET_POWERPC64") 6208 (const_string "8") 6209 (const_string "16")))]) 6210 6211 6212;; 128-bit EQV 6213(define_insn_and_split "*eqv<mode>3_internal1" 6214 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6215 (not:BOOL_128 6216 (xor:BOOL_128 6217 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>") 6218 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))] 6219 "TARGET_P8_VECTOR" 6220{ 6221 if (vsx_register_operand (operands[0], <MODE>mode)) 6222 return "xxleqv %x0,%x1,%x2"; 6223 6224 return "#"; 6225} 6226 "TARGET_P8_VECTOR && reload_completed 6227 && int_reg_operand (operands[0], <MODE>mode)" 6228 [(const_int 0)] 6229{ 6230 rs6000_split_logical (operands, XOR, true, false, false); 6231 DONE; 6232} 6233 [(set (attr "type") 6234 (if_then_else 6235 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6236 (const_string "veclogical") 6237 (const_string "integer"))) 6238 (set (attr "length") 6239 (if_then_else 6240 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6241 (const_string "4") 6242 (if_then_else 6243 (match_test "TARGET_POWERPC64") 6244 (const_string "8") 6245 (const_string "16"))))]) 6246 6247(define_insn_and_split "*eqv<mode>3_internal2" 6248 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6249 (not:TI2 6250 (xor:TI2 6251 (match_operand:TI2 1 "int_reg_operand" "r,0,r") 6252 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))] 6253 "!TARGET_P8_VECTOR" 6254 "#" 6255 "reload_completed && !TARGET_P8_VECTOR" 6256 [(const_int 0)] 6257{ 6258 rs6000_split_logical (operands, XOR, true, false, false); 6259 DONE; 6260} 6261 [(set_attr "type" "integer") 6262 (set (attr "length") 6263 (if_then_else 6264 (match_test "TARGET_POWERPC64") 6265 (const_string "8") 6266 (const_string "16")))]) 6267 6268;; 128-bit one's complement 6269(define_insn_and_split "*one_cmpl<mode>3_internal" 6270 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6271 (not:BOOL_128 6272 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))] 6273 "" 6274{ 6275 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6276 return "xxlnor %x0,%x1,%x1"; 6277 6278 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6279 return "vnor %0,%1,%1"; 6280 6281 return "#"; 6282} 6283 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6284 [(const_int 0)] 6285{ 6286 rs6000_split_logical (operands, NOT, false, false, false); 6287 DONE; 6288} 6289 [(set (attr "type") 6290 (if_then_else 6291 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6292 (const_string "veclogical") 6293 (const_string "integer"))) 6294 (set (attr "length") 6295 (if_then_else 6296 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6297 (const_string "4") 6298 (if_then_else 6299 (match_test "TARGET_POWERPC64") 6300 (const_string "8") 6301 (const_string "16"))))]) 6302 6303 6304;; Now define ways of moving data around. 6305 6306;; Set up a register with a value from the GOT table 6307 6308(define_expand "movsi_got" 6309 [(set (match_operand:SI 0 "gpc_reg_operand" "") 6310 (unspec:SI [(match_operand:SI 1 "got_operand" "") 6311 (match_dup 2)] UNSPEC_MOVSI_GOT))] 6312 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 6313 " 6314{ 6315 if (GET_CODE (operands[1]) == CONST) 6316 { 6317 rtx offset = const0_rtx; 6318 HOST_WIDE_INT value; 6319 6320 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset); 6321 value = INTVAL (offset); 6322 if (value != 0) 6323 { 6324 rtx tmp = (!can_create_pseudo_p () 6325 ? operands[0] 6326 : gen_reg_rtx (Pmode)); 6327 emit_insn (gen_movsi_got (tmp, operands[1])); 6328 emit_insn (gen_addsi3 (operands[0], tmp, offset)); 6329 DONE; 6330 } 6331 } 6332 6333 operands[2] = rs6000_got_register (operands[1]); 6334}") 6335 6336(define_insn "*movsi_got_internal" 6337 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 6338 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") 6339 (match_operand:SI 2 "gpc_reg_operand" "b")] 6340 UNSPEC_MOVSI_GOT))] 6341 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 6342 "lwz %0,%a1@got(%2)" 6343 [(set_attr "type" "load")]) 6344 6345;; Used by sched, shorten_branches and final when the GOT pseudo reg 6346;; didn't get allocated to a hard register. 6347(define_split 6348 [(set (match_operand:SI 0 "gpc_reg_operand" "") 6349 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") 6350 (match_operand:SI 2 "memory_operand" "")] 6351 UNSPEC_MOVSI_GOT))] 6352 "DEFAULT_ABI == ABI_V4 6353 && flag_pic == 1 6354 && (reload_in_progress || reload_completed)" 6355 [(set (match_dup 0) (match_dup 2)) 6356 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 6357 UNSPEC_MOVSI_GOT))] 6358 "") 6359 6360;; For SI, we special-case integers that can't be loaded in one insn. We 6361;; do the load 16-bits at a time. We could do this by loading from memory, 6362;; and this is even supposed to be faster, but it is simpler not to get 6363;; integers in the TOC. 6364(define_insn "movsi_low" 6365 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 6366 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 6367 (match_operand 2 "" ""))))] 6368 "TARGET_MACHO && ! TARGET_64BIT" 6369 "lwz %0,lo16(%2)(%1)" 6370 [(set_attr "type" "load") 6371 (set_attr "length" "4")]) 6372 6373(define_insn "*movsi_internal1" 6374 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h") 6375 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0"))] 6376 "!TARGET_SINGLE_FPU && 6377 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" 6378 "@ 6379 mr %0,%1 6380 la %0,%a1 6381 lwz%U1%X1 %0,%1 6382 stw%U0%X0 %1,%0 6383 li %0,%1 6384 lis %0,%v1 6385 # 6386 mf%1 %0 6387 mt%0 %1 6388 mt%0 %1 6389 nop" 6390 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*") 6391 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4")]) 6392 6393(define_insn "*movsi_internal1_single" 6394 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f") 6395 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))] 6396 "TARGET_SINGLE_FPU && 6397 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" 6398 "@ 6399 mr %0,%1 6400 la %0,%a1 6401 lwz%U1%X1 %0,%1 6402 stw%U0%X0 %1,%0 6403 li %0,%1 6404 lis %0,%v1 6405 # 6406 mf%1 %0 6407 mt%0 %1 6408 mt%0 %1 6409 nop 6410 stfs%U0%X0 %1,%0 6411 lfs%U1%X1 %0,%1" 6412 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload") 6413 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")]) 6414 6415;; Split a load of a large constant into the appropriate two-insn 6416;; sequence. 6417 6418(define_split 6419 [(set (match_operand:SI 0 "gpc_reg_operand" "") 6420 (match_operand:SI 1 "const_int_operand" ""))] 6421 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000 6422 && (INTVAL (operands[1]) & 0xffff) != 0" 6423 [(set (match_dup 0) 6424 (match_dup 2)) 6425 (set (match_dup 0) 6426 (ior:SI (match_dup 0) 6427 (match_dup 3)))] 6428 " 6429{ 6430 if (rs6000_emit_set_const (operands[0], operands[1])) 6431 DONE; 6432 else 6433 FAIL; 6434}") 6435 6436(define_insn "*mov<mode>_internal2" 6437 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y") 6438 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r") 6439 (const_int 0))) 6440 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))] 6441 "" 6442 "@ 6443 cmp<wd>i %2,%0,0 6444 mr. %0,%1 6445 #" 6446 [(set_attr "type" "cmp,logical,cmp") 6447 (set_attr "dot" "yes") 6448 (set_attr "length" "4,4,8")]) 6449 6450(define_split 6451 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") 6452 (compare:CC (match_operand:P 1 "gpc_reg_operand" "") 6453 (const_int 0))) 6454 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))] 6455 "reload_completed" 6456 [(set (match_dup 0) (match_dup 1)) 6457 (set (match_dup 2) 6458 (compare:CC (match_dup 0) 6459 (const_int 0)))] 6460 "") 6461 6462(define_insn "*movhi_internal" 6463 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h") 6464 (match_operand:HI 1 "input_operand" "r,m,r,i,*h,r,0"))] 6465 "gpc_reg_operand (operands[0], HImode) 6466 || gpc_reg_operand (operands[1], HImode)" 6467 "@ 6468 mr %0,%1 6469 lhz%U1%X1 %0,%1 6470 sth%U0%X0 %1,%0 6471 li %0,%w1 6472 mf%1 %0 6473 mt%0 %1 6474 nop" 6475 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")]) 6476 6477(define_expand "mov<mode>" 6478 [(set (match_operand:INT 0 "general_operand" "") 6479 (match_operand:INT 1 "any_operand" ""))] 6480 "" 6481 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") 6482 6483(define_insn "*movqi_internal" 6484 [(set (match_operand:QI 0 "nonimmediate_operand" "=r,r,m,r,r,*c*l,*h") 6485 (match_operand:QI 1 "input_operand" "r,m,r,i,*h,r,0"))] 6486 "gpc_reg_operand (operands[0], QImode) 6487 || gpc_reg_operand (operands[1], QImode)" 6488 "@ 6489 mr %0,%1 6490 lbz%U1%X1 %0,%1 6491 stb%U0%X0 %1,%0 6492 li %0,%1 6493 mf%1 %0 6494 mt%0 %1 6495 nop" 6496 [(set_attr "type" "*,load,store,*,mfjmpr,mtjmpr,*")]) 6497 6498;; Here is how to move condition codes around. When we store CC data in 6499;; an integer register or memory, we store just the high-order 4 bits. 6500;; This lets us not shift in the most common case of CR0. 6501(define_expand "movcc" 6502 [(set (match_operand:CC 0 "nonimmediate_operand" "") 6503 (match_operand:CC 1 "nonimmediate_operand" ""))] 6504 "" 6505 "") 6506 6507(define_insn "*movcc_internal1" 6508 [(set (match_operand:CC 0 "nonimmediate_operand" "=y,x,?y,y,r,r,r,r,r,cl,r,m") 6509 (match_operand:CC 1 "general_operand" "y,r,r,O,x,y,r,I,h,r,m,r"))] 6510 "register_operand (operands[0], CCmode) 6511 || register_operand (operands[1], CCmode)" 6512 "@ 6513 mcrf %0,%1 6514 mtcrf 128,%1 6515 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff 6516 crxor %0,%0,%0 6517 mfcr %0%Q1 6518 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000 6519 mr %0,%1 6520 li %0,%1 6521 mf%1 %0 6522 mt%0 %1 6523 lwz%U1%X1 %0,%1 6524 stw%U0%X0 %1,%0" 6525 [(set (attr "type") 6526 (cond [(eq_attr "alternative" "0,3") 6527 (const_string "cr_logical") 6528 (eq_attr "alternative" "1,2") 6529 (const_string "mtcr") 6530 (eq_attr "alternative" "6,7") 6531 (const_string "integer") 6532 (eq_attr "alternative" "8") 6533 (const_string "mfjmpr") 6534 (eq_attr "alternative" "9") 6535 (const_string "mtjmpr") 6536 (eq_attr "alternative" "10") 6537 (const_string "load") 6538 (eq_attr "alternative" "11") 6539 (const_string "store") 6540 (match_test "TARGET_MFCRF") 6541 (const_string "mfcrf") 6542 ] 6543 (const_string "mfcr"))) 6544 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")]) 6545 6546;; For floating-point, we normally deal with the floating-point registers 6547;; unless -msoft-float is used. The sole exception is that parameter passing 6548;; can produce floating-point values in fixed-point registers. Unless the 6549;; value is a simple constant or already in memory, we deal with this by 6550;; allocating memory and copying the value explicitly via that memory location. 6551 6552;; Move 32-bit binary/decimal floating point 6553(define_expand "mov<mode>" 6554 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "") 6555 (match_operand:FMOVE32 1 "any_operand" ""))] 6556 "<fmove_ok>" 6557 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") 6558 6559(define_split 6560 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "") 6561 (match_operand:FMOVE32 1 "const_double_operand" ""))] 6562 "reload_completed 6563 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 6564 || (GET_CODE (operands[0]) == SUBREG 6565 && GET_CODE (SUBREG_REG (operands[0])) == REG 6566 && REGNO (SUBREG_REG (operands[0])) <= 31))" 6567 [(set (match_dup 2) (match_dup 3))] 6568 " 6569{ 6570 long l; 6571 6572 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 6573 6574 if (! TARGET_POWERPC64) 6575 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); 6576 else 6577 operands[2] = gen_lowpart (SImode, operands[0]); 6578 6579 operands[3] = gen_int_mode (l, SImode); 6580}") 6581 6582;; Originally, we tried to keep movsf and movsd common, but the differences 6583;; addressing was making it rather difficult to hide with mode attributes. In 6584;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store 6585;; before the VSX stores meant that the register allocator would tend to do a 6586;; direct move to the GPR (which involves conversion from scalar to 6587;; vector/memory formats) to save values in the traditional Altivec registers, 6588;; while SDmode had problems on power6 if the GPR store was not first due to 6589;; the power6 not having an integer store operation. 6590;; 6591;; LWZ LFS LXSSP LXSSPX STFS STXSSP 6592;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP 6593;; MR MT<x> MF<x> NOP 6594 6595(define_insn "movsf_hardfloat" 6596 [(set (match_operand:SF 0 "nonimmediate_operand" 6597 "=!r, f, wb, wu, m, wY, 6598 Z, m, ww, !r, f, ww, 6599 !r, *c*l, !r, *h") 6600 (match_operand:SF 1 "input_operand" 6601 "m, m, wY, Z, f, wb, 6602 wu, r, j, j, f, ww, 6603 r, r, *h, 0"))] 6604 "(register_operand (operands[0], SFmode) 6605 || register_operand (operands[1], SFmode)) 6606 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" 6607 "@ 6608 lwz%U1%X1 %0,%1 6609 lfs%U1%X1 %0,%1 6610 lxssp %0,%1 6611 lxsspx %x0,%y1 6612 stfs%U0%X0 %1,%0 6613 stxssp %1,%0 6614 stxsspx %x1,%y0 6615 stw%U0%X0 %1,%0 6616 xxlxor %x0,%x0,%x0 6617 li %0,0 6618 fmr %0,%1 6619 xscpsgndp %x0,%x1,%x1 6620 mr %0,%1 6621 mt%0 %1 6622 mf%1 %0 6623 nop" 6624 [(set_attr "type" 6625 "load, fpload, fpload, fpload, fpstore, fpstore, 6626 fpstore, store, veclogical, integer, fpsimple, fpsimple, 6627 *, mtjmpr, mfjmpr, *")]) 6628 6629;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ 6630;; FMR MR MT%0 MF%1 NOP 6631(define_insn "movsd_hardfloat" 6632 [(set (match_operand:SD 0 "nonimmediate_operand" 6633 "=!r, wz, m, Z, ?wh, ?r, 6634 f, !r, *c*l, !r, *h") 6635 (match_operand:SD 1 "input_operand" 6636 "m, Z, r, wx, r, wh, 6637 f, r, r, *h, 0"))] 6638 "(register_operand (operands[0], SDmode) 6639 || register_operand (operands[1], SDmode)) 6640 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" 6641 "@ 6642 lwz%U1%X1 %0,%1 6643 lfiwzx %0,%y1 6644 stw%U0%X0 %1,%0 6645 stfiwx %1,%y0 6646 mtvsrwz %x0,%1 6647 mfvsrwz %0,%x1 6648 fmr %0,%1 6649 mr %0,%1 6650 mt%0 %1 6651 mf%1 %0 6652 nop" 6653 [(set_attr "type" 6654 "load, fpload, store, fpstore, mffgpr, mftgpr, 6655 fpsimple, *, mtjmpr, mfjmpr, *")]) 6656 6657(define_insn "*mov<mode>_softfloat" 6658 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h") 6659 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))] 6660 "(gpc_reg_operand (operands[0], <MODE>mode) 6661 || gpc_reg_operand (operands[1], <MODE>mode)) 6662 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)" 6663 "@ 6664 mr %0,%1 6665 mt%0 %1 6666 mf%1 %0 6667 lwz%U1%X1 %0,%1 6668 stw%U0%X0 %1,%0 6669 li %0,%1 6670 lis %0,%v1 6671 # 6672 # 6673 nop" 6674 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*") 6675 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")]) 6676 6677 6678;; Move 64-bit binary/decimal floating point 6679(define_expand "mov<mode>" 6680 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "") 6681 (match_operand:FMOVE64 1 "any_operand" ""))] 6682 "" 6683 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") 6684 6685(define_split 6686 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "") 6687 (match_operand:FMOVE64 1 "const_int_operand" ""))] 6688 "! TARGET_POWERPC64 && reload_completed 6689 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 6690 || (GET_CODE (operands[0]) == SUBREG 6691 && GET_CODE (SUBREG_REG (operands[0])) == REG 6692 && REGNO (SUBREG_REG (operands[0])) <= 31))" 6693 [(set (match_dup 2) (match_dup 4)) 6694 (set (match_dup 3) (match_dup 1))] 6695 " 6696{ 6697 int endian = (WORDS_BIG_ENDIAN == 0); 6698 HOST_WIDE_INT value = INTVAL (operands[1]); 6699 6700 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 6701 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 6702 operands[4] = GEN_INT (value >> 32); 6703 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 6704}") 6705 6706(define_split 6707 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "") 6708 (match_operand:FMOVE64 1 "const_double_operand" ""))] 6709 "! TARGET_POWERPC64 && reload_completed 6710 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 6711 || (GET_CODE (operands[0]) == SUBREG 6712 && GET_CODE (SUBREG_REG (operands[0])) == REG 6713 && REGNO (SUBREG_REG (operands[0])) <= 31))" 6714 [(set (match_dup 2) (match_dup 4)) 6715 (set (match_dup 3) (match_dup 5))] 6716 " 6717{ 6718 int endian = (WORDS_BIG_ENDIAN == 0); 6719 long l[2]; 6720 6721 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 6722 6723 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 6724 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 6725 operands[4] = gen_int_mode (l[endian], SImode); 6726 operands[5] = gen_int_mode (l[1 - endian], SImode); 6727}") 6728 6729(define_split 6730 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "") 6731 (match_operand:FMOVE64 1 "const_double_operand" ""))] 6732 "TARGET_POWERPC64 && reload_completed 6733 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 6734 || (GET_CODE (operands[0]) == SUBREG 6735 && GET_CODE (SUBREG_REG (operands[0])) == REG 6736 && REGNO (SUBREG_REG (operands[0])) <= 31))" 6737 [(set (match_dup 2) (match_dup 3))] 6738 " 6739{ 6740 int endian = (WORDS_BIG_ENDIAN == 0); 6741 long l[2]; 6742 HOST_WIDE_INT val; 6743 6744 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 6745 6746 operands[2] = gen_lowpart (DImode, operands[0]); 6747 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ 6748 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 6749 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); 6750 6751 operands[3] = gen_int_mode (val, DImode); 6752}") 6753 6754;; Don't have reload use general registers to load a constant. It is 6755;; less efficient than loading the constant into an FP register, since 6756;; it will probably be used there. 6757 6758;; The move constraints are ordered to prefer floating point registers before 6759;; general purpose registers to avoid doing a store and a load to get the value 6760;; into a floating point register when it is needed for a floating point 6761;; operation. Prefer traditional floating point registers over VSX registers, 6762;; since the D-form version of the memory instructions does not need a GPR for 6763;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec 6764;; registers. 6765 6766;; If we have FPR registers, rs6000_emit_move has moved all constants to memory, 6767;; except for 0.0 which can be created on VSX with an xor instruction. 6768 6769(define_insn "*mov<mode>_hardfloat32" 6770 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r") 6771 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))] 6772 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 6773 && (gpc_reg_operand (operands[0], <MODE>mode) 6774 || gpc_reg_operand (operands[1], <MODE>mode))" 6775 "@ 6776 stfd%U0%X0 %1,%0 6777 lfd%U1%X1 %0,%1 6778 fmr %0,%1 6779 lxsd %0,%1 6780 stxsd %1,%0 6781 lxsd%U1x %x0,%y1 6782 stxsd%U0x %x1,%y0 6783 xxlor %x0,%x1,%x1 6784 xxlxor %x0,%x0,%x0 6785 # 6786 # 6787 # 6788 #" 6789 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two") 6790 (set_attr "size" "64") 6791 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")]) 6792 6793(define_insn "*mov<mode>_softfloat32" 6794 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r") 6795 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))] 6796 "! TARGET_POWERPC64 6797 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 6798 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE 6799 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE)) 6800 && (gpc_reg_operand (operands[0], <MODE>mode) 6801 || gpc_reg_operand (operands[1], <MODE>mode))" 6802 "#" 6803 [(set_attr "type" "store,load,two,*,*,*") 6804 (set_attr "length" "8,8,8,8,12,16")]) 6805 6806; ld/std require word-aligned displacements -> 'Y' constraint. 6807; List Y->r and r->Y before r->r for reload. 6808(define_insn "*mov<mode>_hardfloat64" 6809 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,o,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>") 6810 (match_operand:FMOVE64 1 "input_operand" "d,m,d,o,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))] 6811 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 6812 && (gpc_reg_operand (operands[0], <MODE>mode) 6813 || gpc_reg_operand (operands[1], <MODE>mode))" 6814 "@ 6815 stfd%U0%X0 %1,%0 6816 lfd%U1%X1 %0,%1 6817 fmr %0,%1 6818 lxsd %0,%1 6819 stxsd %1,%0 6820 lxsd%U1x %x0,%y1 6821 stxsd%U0x %x1,%y0 6822 xxlor %x0,%x1,%x1 6823 xxlxor %x0,%x0,%x0 6824 li %0,0 6825 std%U0%X0 %1,%0 6826 ld%U1%X1 %0,%1 6827 mr %0,%1 6828 mt%0 %1 6829 mf%1 %0 6830 nop 6831 mftgpr %0,%1 6832 mffgpr %0,%1 6833 mfvsrd %0,%x1 6834 mtvsrd %x0,%1" 6835 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr") 6836 (set_attr "size" "64") 6837 (set_attr "length" "4")]) 6838 6839(define_insn "*mov<mode>_softfloat64" 6840 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h") 6841 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))] 6842 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) 6843 && (gpc_reg_operand (operands[0], <MODE>mode) 6844 || gpc_reg_operand (operands[1], <MODE>mode))" 6845 "@ 6846 std%U0%X0 %1,%0 6847 ld%U1%X1 %0,%1 6848 mr %0,%1 6849 mt%0 %1 6850 mf%1 %0 6851 # 6852 # 6853 # 6854 nop" 6855 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*") 6856 (set_attr "length" "4,4,4,4,4,8,12,16,4")]) 6857 6858(define_expand "mov<mode>" 6859 [(set (match_operand:FMOVE128 0 "general_operand" "") 6860 (match_operand:FMOVE128 1 "any_operand" ""))] 6861 "" 6862 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") 6863 6864;; It's important to list Y->r and r->Y before r->r because otherwise 6865;; reload, given m->r, will try to pick r->r and reload it, which 6866;; doesn't make progress. 6867 6868;; We can't split little endian direct moves of TDmode, because the words are 6869;; not swapped like they are for TImode or TFmode. Subregs therefore are 6870;; problematical. Don't allow direct move for this case. 6871 6872(define_insn_and_split "*mov<mode>_64bit_dm" 6873 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh") 6874 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))] 6875 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 6876 && FLOAT128_2REG_P (<MODE>mode) 6877 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN) 6878 && (gpc_reg_operand (operands[0], <MODE>mode) 6879 || gpc_reg_operand (operands[1], <MODE>mode))" 6880 "#" 6881 "&& reload_completed" 6882 [(pc)] 6883{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 6884 [(set_attr "length" "8,8,8,8,12,12,8,8,8")]) 6885 6886(define_insn_and_split "*movtd_64bit_nodm" 6887 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r") 6888 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))] 6889 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN 6890 && (gpc_reg_operand (operands[0], TDmode) 6891 || gpc_reg_operand (operands[1], TDmode))" 6892 "#" 6893 "&& reload_completed" 6894 [(pc)] 6895{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 6896 [(set_attr "length" "8,8,8,12,12,8")]) 6897 6898(define_insn_and_split "*mov<mode>_32bit" 6899 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r") 6900 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))] 6901 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64 6902 && (FLOAT128_2REG_P (<MODE>mode) 6903 || int_reg_operand_not_pseudo (operands[0], <MODE>mode) 6904 || int_reg_operand_not_pseudo (operands[1], <MODE>mode)) 6905 && (gpc_reg_operand (operands[0], <MODE>mode) 6906 || gpc_reg_operand (operands[1], <MODE>mode))" 6907 "#" 6908 "&& reload_completed" 6909 [(pc)] 6910{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 6911 [(set_attr "length" "8,8,8,8,20,20,16")]) 6912 6913(define_insn_and_split "*mov<mode>_softfloat" 6914 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r") 6915 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))] 6916 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) 6917 && (gpc_reg_operand (operands[0], <MODE>mode) 6918 || gpc_reg_operand (operands[1], <MODE>mode))" 6919 "#" 6920 "&& reload_completed" 6921 [(pc)] 6922{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 6923 [(set_attr "length" "20,20,16")]) 6924 6925(define_expand "extenddf<mode>2" 6926 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") 6927 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))] 6928 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE) 6929 && TARGET_LONG_DOUBLE_128" 6930{ 6931 if (FLOAT128_IEEE_P (<MODE>mode)) 6932 rs6000_expand_float128_convert (operands[0], operands[1], false); 6933 else if (TARGET_E500_DOUBLE) 6934 { 6935 gcc_assert (<MODE>mode == TFmode); 6936 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1])); 6937 } 6938 else if (TARGET_VSX) 6939 { 6940 if (<MODE>mode == TFmode) 6941 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1])); 6942 else if (<MODE>mode == IFmode) 6943 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1])); 6944 else 6945 gcc_unreachable (); 6946 } 6947 else 6948 { 6949 rtx zero = gen_reg_rtx (DFmode); 6950 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode); 6951 6952 if (<MODE>mode == TFmode) 6953 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero)); 6954 else if (<MODE>mode == IFmode) 6955 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero)); 6956 else 6957 gcc_unreachable (); 6958 } 6959 DONE; 6960}) 6961 6962;; Allow memory operands for the source to be created by the combiner. 6963(define_insn_and_split "extenddf<mode>2_fprs" 6964 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d") 6965 (float_extend:IBM128 6966 (match_operand:DF 1 "nonimmediate_operand" "d,m,d"))) 6967 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))] 6968 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 6969 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" 6970 "#" 6971 "&& reload_completed" 6972 [(set (match_dup 3) (match_dup 1)) 6973 (set (match_dup 4) (match_dup 2))] 6974{ 6975 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 6976 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 6977 6978 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 6979 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 6980}) 6981 6982(define_insn_and_split "extenddf<mode>2_vsx" 6983 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d") 6984 (float_extend:IBM128 6985 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))] 6986 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)" 6987 "#" 6988 "&& reload_completed" 6989 [(set (match_dup 2) (match_dup 1)) 6990 (set (match_dup 3) (match_dup 4))] 6991{ 6992 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 6993 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 6994 6995 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 6996 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 6997 operands[4] = CONST0_RTX (DFmode); 6998}) 6999 7000(define_expand "extendsf<mode>2" 7001 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") 7002 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))] 7003 "TARGET_HARD_FLOAT 7004 && (TARGET_FPRS || TARGET_E500_DOUBLE) 7005 && TARGET_LONG_DOUBLE_128" 7006{ 7007 if (FLOAT128_IEEE_P (<MODE>mode)) 7008 rs6000_expand_float128_convert (operands[0], operands[1], false); 7009 else 7010 { 7011 rtx tmp = gen_reg_rtx (DFmode); 7012 emit_insn (gen_extendsfdf2 (tmp, operands[1])); 7013 emit_insn (gen_extenddf<mode>2 (operands[0], tmp)); 7014 } 7015 DONE; 7016}) 7017 7018(define_expand "trunc<mode>df2" 7019 [(set (match_operand:DF 0 "gpc_reg_operand" "") 7020 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] 7021 "TARGET_HARD_FLOAT 7022 && (TARGET_FPRS || TARGET_E500_DOUBLE) 7023 && TARGET_LONG_DOUBLE_128" 7024{ 7025 if (FLOAT128_IEEE_P (<MODE>mode)) 7026 { 7027 rs6000_expand_float128_convert (operands[0], operands[1], false); 7028 DONE; 7029 } 7030}) 7031 7032(define_insn_and_split "trunc<mode>df2_internal1" 7033 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d") 7034 (float_truncate:DF 7035 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))] 7036 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT 7037 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" 7038 "@ 7039 # 7040 fmr %0,%1" 7041 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 7042 [(const_int 0)] 7043{ 7044 emit_note (NOTE_INSN_DELETED); 7045 DONE; 7046} 7047 [(set_attr "type" "fpsimple")]) 7048 7049(define_insn "trunc<mode>df2_internal2" 7050 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7051 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 7052 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT 7053 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 7054 "fadd %0,%1,%L1" 7055 [(set_attr "type" "fp") 7056 (set_attr "fp_type" "fp_addsub_d")]) 7057 7058(define_expand "trunc<mode>sf2" 7059 [(set (match_operand:SF 0 "gpc_reg_operand" "") 7060 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] 7061 "TARGET_HARD_FLOAT 7062 && (TARGET_FPRS || TARGET_E500_DOUBLE) 7063 && TARGET_LONG_DOUBLE_128" 7064{ 7065 if (FLOAT128_IEEE_P (<MODE>mode)) 7066 rs6000_expand_float128_convert (operands[0], operands[1], false); 7067 else if (TARGET_E500_DOUBLE) 7068 { 7069 gcc_assert (<MODE>mode == TFmode); 7070 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1])); 7071 } 7072 else if (<MODE>mode == TFmode) 7073 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1])); 7074 else if (<MODE>mode == IFmode) 7075 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1])); 7076 else 7077 gcc_unreachable (); 7078 DONE; 7079}) 7080 7081(define_insn_and_split "trunc<mode>sf2_fprs" 7082 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 7083 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d"))) 7084 (clobber (match_scratch:DF 2 "=d"))] 7085 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 7086 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" 7087 "#" 7088 "&& reload_completed" 7089 [(set (match_dup 2) 7090 (float_truncate:DF (match_dup 1))) 7091 (set (match_dup 0) 7092 (float_truncate:SF (match_dup 2)))] 7093 "") 7094 7095(define_expand "floatsi<mode>2" 7096 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") 7097 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand" "")))] 7098 "TARGET_HARD_FLOAT 7099 && (TARGET_FPRS || TARGET_E500_DOUBLE) 7100 && TARGET_LONG_DOUBLE_128" 7101{ 7102 if (FLOAT128_IEEE_P (<MODE>mode)) 7103 rs6000_expand_float128_convert (operands[0], operands[1], false); 7104 else 7105 { 7106 rtx tmp = gen_reg_rtx (DFmode); 7107 expand_float (tmp, operands[1], false); 7108 if (<MODE>mode == TFmode) 7109 emit_insn (gen_extenddftf2 (operands[0], tmp)); 7110 else if (<MODE>mode == IFmode) 7111 emit_insn (gen_extenddfif2 (operands[0], tmp)); 7112 else 7113 gcc_unreachable (); 7114 } 7115 DONE; 7116}) 7117 7118; fadd, but rounding towards zero. 7119; This is probably not the optimal code sequence. 7120(define_insn "fix_trunc_helper<mode>" 7121 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7122 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")] 7123 UNSPEC_FIX_TRUNC_TF)) 7124 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))] 7125 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 7126 && FLOAT128_IBM_P (<MODE>mode)" 7127 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" 7128 [(set_attr "type" "fp") 7129 (set_attr "length" "20")]) 7130 7131(define_expand "fix_trunc<mode>si2" 7132 [(set (match_operand:SI 0 "gpc_reg_operand" "") 7133 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] 7134 "TARGET_HARD_FLOAT 7135 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128" 7136{ 7137 if (FLOAT128_IEEE_P (<MODE>mode)) 7138 rs6000_expand_float128_convert (operands[0], operands[1], false); 7139 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode) 7140 emit_insn (gen_spe_fix_trunctfsi2 (operands[0], operands[1])); 7141 else if (<MODE>mode == TFmode) 7142 emit_insn (gen_fix_trunctfsi2_fprs (operands[0], operands[1])); 7143 else if (<MODE>mode == IFmode) 7144 emit_insn (gen_fix_truncifsi2_fprs (operands[0], operands[1])); 7145 else 7146 gcc_unreachable (); 7147 DONE; 7148}) 7149 7150(define_expand "fix_trunc<mode>si2_fprs" 7151 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") 7152 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" ""))) 7153 (clobber (match_dup 2)) 7154 (clobber (match_dup 3)) 7155 (clobber (match_dup 4)) 7156 (clobber (match_dup 5))])] 7157 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" 7158{ 7159 operands[2] = gen_reg_rtx (DFmode); 7160 operands[3] = gen_reg_rtx (DFmode); 7161 operands[4] = gen_reg_rtx (DImode); 7162 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode)); 7163}) 7164 7165(define_insn_and_split "*fix_trunc<mode>si2_internal" 7166 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 7167 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d"))) 7168 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d")) 7169 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d")) 7170 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d")) 7171 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))] 7172 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" 7173 "#" 7174 "" 7175 [(pc)] 7176{ 7177 rtx lowword; 7178 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1], 7179 operands[3])); 7180 7181 gcc_assert (MEM_P (operands[5])); 7182 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 7183 7184 emit_insn (gen_fctiwz_df (operands[4], operands[2])); 7185 emit_move_insn (operands[5], operands[4]); 7186 emit_move_insn (operands[0], lowword); 7187 DONE; 7188}) 7189 7190(define_expand "fix_trunc<mode>di2" 7191 [(set (match_operand:DI 0 "gpc_reg_operand" "") 7192 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))] 7193 "TARGET_FLOAT128" 7194{ 7195 rs6000_expand_float128_convert (operands[0], operands[1], false); 7196 DONE; 7197}) 7198 7199(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2" 7200 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 7201 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))] 7202 "TARGET_FLOAT128" 7203{ 7204 rs6000_expand_float128_convert (operands[0], operands[1], true); 7205 DONE; 7206}) 7207 7208(define_expand "floatdi<mode>2" 7209 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "") 7210 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))] 7211 "TARGET_FLOAT128" 7212{ 7213 rs6000_expand_float128_convert (operands[0], operands[1], false); 7214 DONE; 7215}) 7216 7217(define_expand "floatuns<SDI:mode><IEEE128:mode>2" 7218 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "") 7219 (unsigned_float:IEEE128 (match_operand:SDI 1 "gpc_reg_operand" "")))] 7220 "TARGET_FLOAT128" 7221{ 7222 rs6000_expand_float128_convert (operands[0], operands[1], true); 7223 DONE; 7224}) 7225 7226(define_expand "neg<mode>2" 7227 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") 7228 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] 7229 "FLOAT128_IEEE_P (<MODE>mode) 7230 || (FLOAT128_IBM_P (<MODE>mode) 7231 && TARGET_HARD_FLOAT 7232 && (TARGET_FPRS || TARGET_E500_DOUBLE))" 7233 " 7234{ 7235 if (FLOAT128_IEEE_P (<MODE>mode)) 7236 { 7237 if (TARGET_FLOAT128_HW) 7238 { 7239 if (<MODE>mode == TFmode) 7240 emit_insn (gen_negtf2_hw (operands[0], operands[1])); 7241 else if (<MODE>mode == KFmode) 7242 emit_insn (gen_negkf2_hw (operands[0], operands[1])); 7243 else 7244 gcc_unreachable (); 7245 } 7246 else if (TARGET_FLOAT128) 7247 { 7248 if (<MODE>mode == TFmode) 7249 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1])); 7250 else if (<MODE>mode == KFmode) 7251 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1])); 7252 else 7253 gcc_unreachable (); 7254 } 7255 else 7256 { 7257 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode); 7258 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST, 7259 <MODE>mode, 1, 7260 operands[1], <MODE>mode); 7261 7262 if (target && !rtx_equal_p (target, operands[0])) 7263 emit_move_insn (operands[0], target); 7264 } 7265 DONE; 7266 } 7267}") 7268 7269(define_insn "neg<mode>2_internal" 7270 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d") 7271 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 7272 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)" 7273 "* 7274{ 7275 if (REGNO (operands[0]) == REGNO (operands[1]) + 1) 7276 return \"fneg %L0,%L1\;fneg %0,%1\"; 7277 else 7278 return \"fneg %0,%1\;fneg %L0,%L1\"; 7279}" 7280 [(set_attr "type" "fpsimple") 7281 (set_attr "length" "8")]) 7282 7283(define_expand "abs<mode>2" 7284 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") 7285 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] 7286 "FLOAT128_IEEE_P (<MODE>mode) 7287 || (FLOAT128_IBM_P (<MODE>mode) 7288 && TARGET_HARD_FLOAT 7289 && (TARGET_FPRS || TARGET_E500_DOUBLE))" 7290 " 7291{ 7292 rtx label; 7293 7294 if (FLOAT128_IEEE_P (<MODE>mode)) 7295 { 7296 if (TARGET_FLOAT128_HW) 7297 { 7298 if (<MODE>mode == TFmode) 7299 emit_insn (gen_abstf2_hw (operands[0], operands[1])); 7300 else if (<MODE>mode == KFmode) 7301 emit_insn (gen_abskf2_hw (operands[0], operands[1])); 7302 else 7303 FAIL; 7304 DONE; 7305 } 7306 else if (TARGET_FLOAT128) 7307 { 7308 if (<MODE>mode == TFmode) 7309 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1])); 7310 else if (<MODE>mode == KFmode) 7311 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1])); 7312 else 7313 FAIL; 7314 DONE; 7315 } 7316 else 7317 FAIL; 7318 } 7319 7320 label = gen_label_rtx (); 7321 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode) 7322 { 7323 if (flag_finite_math_only && !flag_trapping_math) 7324 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label)); 7325 else 7326 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label)); 7327 } 7328 else if (<MODE>mode == TFmode) 7329 emit_insn (gen_abstf2_internal (operands[0], operands[1], label)); 7330 else if (<MODE>mode == TFmode) 7331 emit_insn (gen_absif2_internal (operands[0], operands[1], label)); 7332 else 7333 FAIL; 7334 emit_label (label); 7335 DONE; 7336}") 7337 7338(define_expand "abs<mode>2_internal" 7339 [(set (match_operand:IBM128 0 "gpc_reg_operand" "") 7340 (match_operand:IBM128 1 "gpc_reg_operand" "")) 7341 (set (match_dup 3) (match_dup 5)) 7342 (set (match_dup 5) (abs:DF (match_dup 5))) 7343 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5))) 7344 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0)) 7345 (label_ref (match_operand 2 "" "")) 7346 (pc))) 7347 (set (match_dup 6) (neg:DF (match_dup 6)))] 7348 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 7349 && TARGET_LONG_DOUBLE_128" 7350 " 7351{ 7352 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 7353 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 7354 operands[3] = gen_reg_rtx (DFmode); 7355 operands[4] = gen_reg_rtx (CCFPmode); 7356 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 7357 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 7358}") 7359 7360 7361;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector 7362;; register 7363 7364(define_expand "ieee_128bit_negative_zero" 7365 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))] 7366 "TARGET_FLOAT128" 7367{ 7368 rtvec v = rtvec_alloc (16); 7369 int i, high; 7370 7371 for (i = 0; i < 16; i++) 7372 RTVEC_ELT (v, i) = const0_rtx; 7373 7374 high = (BYTES_BIG_ENDIAN) ? 0 : 15; 7375 RTVEC_ELT (v, high) = GEN_INT (0x80); 7376 7377 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v)); 7378 DONE; 7379}) 7380 7381;; IEEE 128-bit negate 7382 7383;; We have 2 insns here for negate and absolute value. The first uses 7384;; match_scratch so that phases like combine can recognize neg/abs as generic 7385;; insns, and second insn after the first split pass loads up the bit to 7386;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of 7387;; neg/abs to create the constant just once. 7388 7389(define_insn_and_split "ieee_128bit_vsx_neg<mode>2" 7390 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 7391 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 7392 (clobber (match_scratch:V16QI 2 "=v"))] 7393 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW" 7394 "#" 7395 "&& 1" 7396 [(parallel [(set (match_dup 0) 7397 (neg:IEEE128 (match_dup 1))) 7398 (use (match_dup 2))])] 7399{ 7400 if (GET_CODE (operands[2]) == SCRATCH) 7401 operands[2] = gen_reg_rtx (V16QImode); 7402 7403 operands[3] = gen_reg_rtx (V16QImode); 7404 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 7405} 7406 [(set_attr "length" "8") 7407 (set_attr "type" "vecsimple")]) 7408 7409(define_insn "*ieee_128bit_vsx_neg<mode>2_internal" 7410 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 7411 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 7412 (use (match_operand:V16QI 2 "register_operand" "v"))] 7413 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW" 7414 "xxlxor %x0,%x1,%x2" 7415 [(set_attr "type" "veclogical")]) 7416 7417;; IEEE 128-bit absolute value 7418(define_insn_and_split "ieee_128bit_vsx_abs<mode>2" 7419 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 7420 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 7421 (clobber (match_scratch:V16QI 2 "=v"))] 7422 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 7423 "#" 7424 "&& 1" 7425 [(parallel [(set (match_dup 0) 7426 (abs:IEEE128 (match_dup 1))) 7427 (use (match_dup 2))])] 7428{ 7429 if (GET_CODE (operands[2]) == SCRATCH) 7430 operands[2] = gen_reg_rtx (V16QImode); 7431 7432 operands[3] = gen_reg_rtx (V16QImode); 7433 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 7434} 7435 [(set_attr "length" "8") 7436 (set_attr "type" "vecsimple")]) 7437 7438(define_insn "*ieee_128bit_vsx_abs<mode>2_internal" 7439 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 7440 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 7441 (use (match_operand:V16QI 2 "register_operand" "v"))] 7442 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW" 7443 "xxlandc %x0,%x1,%x2" 7444 [(set_attr "type" "veclogical")]) 7445 7446;; IEEE 128-bit negative absolute value 7447(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2" 7448 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 7449 (neg:IEEE128 7450 (abs:IEEE128 7451 (match_operand:IEEE128 1 "register_operand" "wa")))) 7452 (clobber (match_scratch:V16QI 2 "=v"))] 7453 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 7454 "#" 7455 "&& 1" 7456 [(parallel [(set (match_dup 0) 7457 (neg:IEEE128 (abs:IEEE128 (match_dup 1)))) 7458 (use (match_dup 2))])] 7459{ 7460 if (GET_CODE (operands[2]) == SCRATCH) 7461 operands[2] = gen_reg_rtx (V16QImode); 7462 7463 operands[3] = gen_reg_rtx (V16QImode); 7464 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 7465} 7466 [(set_attr "length" "8") 7467 (set_attr "type" "vecsimple")]) 7468 7469(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal" 7470 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 7471 (neg:IEEE128 7472 (abs:IEEE128 7473 (match_operand:IEEE128 1 "register_operand" "wa")))) 7474 (use (match_operand:V16QI 2 "register_operand" "v"))] 7475 "TARGET_FLOAT128 && !TARGET_FLOAT128_HW" 7476 "xxlor %x0,%x1,%x2" 7477 [(set_attr "type" "veclogical")]) 7478 7479;; Float128 conversion functions. These expand to library function calls. 7480;; We use expand to convert from IBM double double to IEEE 128-bit 7481;; and trunc for the opposite. 7482(define_expand "extendiftf2" 7483 [(set (match_operand:TF 0 "gpc_reg_operand" "") 7484 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))] 7485 "TARGET_FLOAT128" 7486{ 7487 rs6000_expand_float128_convert (operands[0], operands[1], false); 7488 DONE; 7489}) 7490 7491(define_expand "extendifkf2" 7492 [(set (match_operand:KF 0 "gpc_reg_operand" "") 7493 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))] 7494 "TARGET_FLOAT128" 7495{ 7496 rs6000_expand_float128_convert (operands[0], operands[1], false); 7497 DONE; 7498}) 7499 7500(define_expand "extendtfkf2" 7501 [(set (match_operand:KF 0 "gpc_reg_operand" "") 7502 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))] 7503 "TARGET_FLOAT128" 7504{ 7505 rs6000_expand_float128_convert (operands[0], operands[1], false); 7506 DONE; 7507}) 7508 7509(define_expand "trunciftf2" 7510 [(set (match_operand:IF 0 "gpc_reg_operand" "") 7511 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))] 7512 "TARGET_FLOAT128" 7513{ 7514 rs6000_expand_float128_convert (operands[0], operands[1], false); 7515 DONE; 7516}) 7517 7518(define_expand "truncifkf2" 7519 [(set (match_operand:IF 0 "gpc_reg_operand" "") 7520 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))] 7521 "TARGET_FLOAT128" 7522{ 7523 rs6000_expand_float128_convert (operands[0], operands[1], false); 7524 DONE; 7525}) 7526 7527(define_expand "trunckftf2" 7528 [(set (match_operand:TF 0 "gpc_reg_operand" "") 7529 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))] 7530 "TARGET_FLOAT128" 7531{ 7532 rs6000_expand_float128_convert (operands[0], operands[1], false); 7533 DONE; 7534}) 7535 7536(define_expand "trunctfif2" 7537 [(set (match_operand:IF 0 "gpc_reg_operand" "") 7538 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))] 7539 "TARGET_FLOAT128" 7540{ 7541 rs6000_expand_float128_convert (operands[0], operands[1], false); 7542 DONE; 7543}) 7544 7545 7546;; Reload helper functions used by rs6000_secondary_reload. The patterns all 7547;; must have 3 arguments, and scratch register constraint must be a single 7548;; constraint. 7549 7550;; Reload patterns to support gpr load/store with misaligned mem. 7551;; and multiple gpr load/store at offset >= 0xfffc 7552(define_expand "reload_<mode>_store" 7553 [(parallel [(match_operand 0 "memory_operand" "=m") 7554 (match_operand 1 "gpc_reg_operand" "r") 7555 (match_operand:GPR 2 "register_operand" "=&b")])] 7556 "" 7557{ 7558 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true); 7559 DONE; 7560}) 7561 7562(define_expand "reload_<mode>_load" 7563 [(parallel [(match_operand 0 "gpc_reg_operand" "=r") 7564 (match_operand 1 "memory_operand" "m") 7565 (match_operand:GPR 2 "register_operand" "=b")])] 7566 "" 7567{ 7568 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false); 7569 DONE; 7570}) 7571 7572 7573;; Reload patterns for various types using the vector registers. We may need 7574;; an additional base register to convert the reg+offset addressing to reg+reg 7575;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an 7576;; index register for gpr registers. 7577(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store" 7578 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m") 7579 (match_operand:RELOAD 1 "gpc_reg_operand" "wa") 7580 (match_operand:P 2 "register_operand" "=b")])] 7581 "<P:tptrsize>" 7582{ 7583 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true); 7584 DONE; 7585}) 7586 7587(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load" 7588 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa") 7589 (match_operand:RELOAD 1 "memory_operand" "m") 7590 (match_operand:P 2 "register_operand" "=b")])] 7591 "<P:tptrsize>" 7592{ 7593 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false); 7594 DONE; 7595}) 7596 7597 7598;; Reload sometimes tries to move the address to a GPR, and can generate 7599;; invalid RTL for addresses involving AND -16. Allow addresses involving 7600;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16. 7601 7602(define_insn_and_split "*vec_reload_and_plus_<mptrsize>" 7603 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 7604 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 7605 (match_operand:P 2 "reg_or_cint_operand" "rI")) 7606 (const_int -16)))] 7607 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)" 7608 "#" 7609 "&& reload_completed" 7610 [(set (match_dup 0) 7611 (plus:P (match_dup 1) 7612 (match_dup 2))) 7613 (set (match_dup 0) 7614 (and:P (match_dup 0) 7615 (const_int -16)))]) 7616 7617;; Power8 merge instructions to allow direct move to/from floating point 7618;; registers in 32-bit mode. We use TF mode to get two registers to move the 7619;; individual 32-bit parts across. Subreg doesn't work too well on the TF 7620;; value, since it is allocated in reload and not all of the flow information 7621;; is setup for it. We have two patterns to do the two moves between gprs and 7622;; fprs. There isn't a dependancy between the two, but we could potentially 7623;; schedule other instructions between the two instructions. 7624 7625(define_insn "p8_fmrgow_<mode>" 7626 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 7627 (unspec:FMOVE64X [ 7628 (match_operand:DF 1 "register_operand" "d") 7629 (match_operand:DF 2 "register_operand" "d")] 7630 UNSPEC_P8V_FMRGOW))] 7631 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7632 "fmrgow %0,%1,%2" 7633 [(set_attr "type" "fpsimple")]) 7634 7635(define_insn "p8_mtvsrwz" 7636 [(set (match_operand:DF 0 "register_operand" "=d") 7637 (unspec:DF [(match_operand:SI 1 "register_operand" "r")] 7638 UNSPEC_P8V_MTVSRWZ))] 7639 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7640 "mtvsrwz %x0,%1" 7641 [(set_attr "type" "mftgpr")]) 7642 7643(define_insn_and_split "reload_fpr_from_gpr<mode>" 7644 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 7645 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")] 7646 UNSPEC_P8V_RELOAD_FROM_GPR)) 7647 (clobber (match_operand:IF 2 "register_operand" "=d"))] 7648 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7649 "#" 7650 "&& reload_completed" 7651 [(const_int 0)] 7652{ 7653 rtx dest = operands[0]; 7654 rtx src = operands[1]; 7655 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 7656 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 7657 rtx gpr_hi_reg = gen_highpart (SImode, src); 7658 rtx gpr_lo_reg = gen_lowpart (SImode, src); 7659 7660 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg)); 7661 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg)); 7662 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo)); 7663 DONE; 7664} 7665 [(set_attr "length" "12") 7666 (set_attr "type" "three")]) 7667 7668;; Move 128 bit values from GPRs to VSX registers in 64-bit mode 7669(define_insn "p8_mtvsrd_df" 7670 [(set (match_operand:DF 0 "register_operand" "=wa") 7671 (unspec:DF [(match_operand:DI 1 "register_operand" "r")] 7672 UNSPEC_P8V_MTVSRD))] 7673 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7674 "mtvsrd %x0,%1" 7675 [(set_attr "type" "mftgpr")]) 7676 7677(define_insn "p8_xxpermdi_<mode>" 7678 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 7679 (unspec:FMOVE128_GPR [ 7680 (match_operand:DF 1 "register_operand" "wa") 7681 (match_operand:DF 2 "register_operand" "wa")] 7682 UNSPEC_P8V_XXPERMDI))] 7683 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7684 "xxpermdi %x0,%x1,%x2,0" 7685 [(set_attr "type" "vecperm")]) 7686 7687(define_insn_and_split "reload_vsx_from_gpr<mode>" 7688 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 7689 (unspec:FMOVE128_GPR 7690 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")] 7691 UNSPEC_P8V_RELOAD_FROM_GPR)) 7692 (clobber (match_operand:IF 2 "register_operand" "=wa"))] 7693 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7694 "#" 7695 "&& reload_completed" 7696 [(const_int 0)] 7697{ 7698 rtx dest = operands[0]; 7699 rtx src = operands[1]; 7700 /* You might think that we could use op0 as one temp and a DF clobber 7701 as op2, but you'd be wrong. Secondary reload move patterns don't 7702 check for overlap of the clobber and the destination. */ 7703 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 7704 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 7705 rtx gpr_hi_reg = gen_highpart (DImode, src); 7706 rtx gpr_lo_reg = gen_lowpart (DImode, src); 7707 7708 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg)); 7709 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg)); 7710 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo)); 7711 DONE; 7712} 7713 [(set_attr "length" "12") 7714 (set_attr "type" "three")]) 7715 7716(define_split 7717 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "") 7718 (match_operand:FMOVE128_GPR 1 "input_operand" ""))] 7719 "reload_completed 7720 && (int_reg_operand (operands[0], <MODE>mode) 7721 || int_reg_operand (operands[1], <MODE>mode)) 7722 && (!TARGET_DIRECT_MOVE_128 7723 || (!vsx_register_operand (operands[0], <MODE>mode) 7724 && !vsx_register_operand (operands[1], <MODE>mode)))" 7725 [(pc)] 7726{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) 7727 7728;; Move SFmode to a VSX from a GPR register. Because scalar floating point 7729;; type is stored internally as double precision in the VSX registers, we have 7730;; to convert it from the vector format. 7731(define_insn "p8_mtvsrd_sf" 7732 [(set (match_operand:SF 0 "register_operand" "=wa") 7733 (unspec:SF [(match_operand:DI 1 "register_operand" "r")] 7734 UNSPEC_P8V_MTVSRD))] 7735 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7736 "mtvsrd %x0,%1" 7737 [(set_attr "type" "mftgpr")]) 7738 7739(define_insn_and_split "reload_vsx_from_gprsf" 7740 [(set (match_operand:SF 0 "register_operand" "=wa") 7741 (unspec:SF [(match_operand:SF 1 "register_operand" "r")] 7742 UNSPEC_P8V_RELOAD_FROM_GPR)) 7743 (clobber (match_operand:DI 2 "register_operand" "=r"))] 7744 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7745 "#" 7746 "&& reload_completed" 7747 [(const_int 0)] 7748{ 7749 rtx op0 = operands[0]; 7750 rtx op1 = operands[1]; 7751 rtx op2 = operands[2]; 7752 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0); 7753 7754 /* Move SF value to upper 32-bits for xscvspdpn. */ 7755 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 7756 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 7757 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 7758 DONE; 7759} 7760 [(set_attr "length" "8") 7761 (set_attr "type" "two")]) 7762 7763;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a 7764;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value, 7765;; and then doing a move of that. 7766(define_insn "p8_mfvsrd_3_<mode>" 7767 [(set (match_operand:DF 0 "register_operand" "=r") 7768 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 7769 UNSPEC_P8V_RELOAD_FROM_VSX))] 7770 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7771 "mfvsrd %0,%x1" 7772 [(set_attr "type" "mftgpr")]) 7773 7774(define_insn_and_split "reload_gpr_from_vsx<mode>" 7775 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r") 7776 (unspec:FMOVE128_GPR 7777 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 7778 UNSPEC_P8V_RELOAD_FROM_VSX)) 7779 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))] 7780 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7781 "#" 7782 "&& reload_completed" 7783 [(const_int 0)] 7784{ 7785 rtx dest = operands[0]; 7786 rtx src = operands[1]; 7787 rtx tmp = operands[2]; 7788 rtx gpr_hi_reg = gen_highpart (DFmode, dest); 7789 rtx gpr_lo_reg = gen_lowpart (DFmode, dest); 7790 7791 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src)); 7792 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3))); 7793 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp)); 7794 DONE; 7795} 7796 [(set_attr "length" "12") 7797 (set_attr "type" "three")]) 7798 7799;; Move SFmode to a GPR from a VSX register. Because scalar floating point 7800;; type is stored internally as double precision, we have to convert it to the 7801;; vector format. 7802 7803(define_insn_and_split "reload_gpr_from_vsxsf" 7804 [(set (match_operand:SF 0 "register_operand" "=r") 7805 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")] 7806 UNSPEC_P8V_RELOAD_FROM_VSX)) 7807 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))] 7808 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7809 "#" 7810 "&& reload_completed" 7811 [(const_int 0)] 7812{ 7813 rtx op0 = operands[0]; 7814 rtx op1 = operands[1]; 7815 rtx op2 = operands[2]; 7816 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0); 7817 7818 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 7819 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2)); 7820 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32))); 7821 DONE; 7822} 7823 [(set_attr "length" "12") 7824 (set_attr "type" "three")]) 7825 7826(define_insn "p8_mfvsrd_4_disf" 7827 [(set (match_operand:DI 0 "register_operand" "=r") 7828 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")] 7829 UNSPEC_P8V_RELOAD_FROM_VSX))] 7830 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 7831 "mfvsrd %0,%x1" 7832 [(set_attr "type" "mftgpr")]) 7833 7834 7835;; Next come the multi-word integer load and store and the load and store 7836;; multiple insns. 7837 7838;; List r->r after r->Y, otherwise reload will try to reload a 7839;; non-offsettable address by using r->r which won't make progress. 7840;; Use of fprs is disparaged slightly otherwise reload prefers to reload 7841;; a gpr into a fpr instead of reloading an invalid 'Y' address 7842(define_insn "*movdi_internal32" 7843 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" "=Y,r,r,?m,?*d,?*d,r") 7844 (match_operand:DI 1 "input_operand" "r,Y,r,d,m,d,IJKnGHF"))] 7845 "! TARGET_POWERPC64 7846 && (gpc_reg_operand (operands[0], DImode) 7847 || gpc_reg_operand (operands[1], DImode))" 7848 "@ 7849 # 7850 # 7851 # 7852 stfd%U0%X0 %1,%0 7853 lfd%U1%X1 %0,%1 7854 fmr %0,%1 7855 #" 7856 [(set_attr "type" "store,load,*,fpstore,fpload,fpsimple,*") 7857 (set_attr "size" "64")]) 7858 7859(define_split 7860 [(set (match_operand:DI 0 "gpc_reg_operand" "") 7861 (match_operand:DI 1 "const_int_operand" ""))] 7862 "! TARGET_POWERPC64 && reload_completed 7863 && gpr_or_gpr_p (operands[0], operands[1]) 7864 && !direct_move_p (operands[0], operands[1])" 7865 [(set (match_dup 2) (match_dup 4)) 7866 (set (match_dup 3) (match_dup 1))] 7867 " 7868{ 7869 HOST_WIDE_INT value = INTVAL (operands[1]); 7870 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 7871 DImode); 7872 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 7873 DImode); 7874 operands[4] = GEN_INT (value >> 32); 7875 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 7876}") 7877 7878(define_split 7879 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "") 7880 (match_operand:DIFD 1 "input_operand" ""))] 7881 "reload_completed && !TARGET_POWERPC64 7882 && gpr_or_gpr_p (operands[0], operands[1]) 7883 && !direct_move_p (operands[0], operands[1])" 7884 [(pc)] 7885{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) 7886 7887(define_insn "*movdi_internal64" 7888 [(set (match_operand:DI 0 "nonimmediate_operand" "=Y,r,r,r,r,r,?m,?*d,?*d,r,*h,*h,r,?*wg,r,?*wj,?*wi") 7889 (match_operand:DI 1 "input_operand" "r,Y,r,I,L,nF,d,m,d,*h,r,0,*wg,r,*wj,r,O"))] 7890 "TARGET_POWERPC64 7891 && (gpc_reg_operand (operands[0], DImode) 7892 || gpc_reg_operand (operands[1], DImode))" 7893 "@ 7894 std%U0%X0 %1,%0 7895 ld%U1%X1 %0,%1 7896 mr %0,%1 7897 li %0,%1 7898 lis %0,%v1 7899 # 7900 stfd%U0%X0 %1,%0 7901 lfd%U1%X1 %0,%1 7902 fmr %0,%1 7903 mf%1 %0 7904 mt%0 %1 7905 nop 7906 mftgpr %0,%1 7907 mffgpr %0,%1 7908 mfvsrd %0,%x1 7909 mtvsrd %x0,%1 7910 xxlxor %x0,%x0,%x0" 7911 [(set_attr "type" "store,load,*,*,*,*,fpstore,fpload,fpsimple,mfjmpr,mtjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr,veclogical") 7912 (set_attr "size" "64") 7913 (set_attr "length" "4,4,4,4,4,20,4,4,4,4,4,4,4,4,4,4,4")]) 7914 7915; Some DImode loads are best done as a load of -1 followed by a mask 7916; instruction. 7917(define_split 7918 [(set (match_operand:DI 0 "gpc_reg_operand") 7919 (match_operand:DI 1 "const_int_operand"))] 7920 "TARGET_POWERPC64 7921 && num_insns_constant (operands[1], DImode) > 1 7922 && rs6000_is_valid_and_mask (operands[1], DImode)" 7923 [(set (match_dup 0) 7924 (const_int -1)) 7925 (set (match_dup 0) 7926 (and:DI (match_dup 0) 7927 (match_dup 1)))] 7928 "") 7929 7930;; Split a load of a large constant into the appropriate five-instruction 7931;; sequence. Handle anything in a constant number of insns. 7932;; When non-easy constants can go in the TOC, this should use 7933;; easy_fp_constant predicate. 7934(define_split 7935 [(set (match_operand:DI 0 "gpc_reg_operand" "") 7936 (match_operand:DI 1 "const_int_operand" ""))] 7937 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 7938 [(set (match_dup 0) (match_dup 2)) 7939 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 7940 " 7941{ 7942 if (rs6000_emit_set_const (operands[0], operands[1])) 7943 DONE; 7944 else 7945 FAIL; 7946}") 7947 7948(define_split 7949 [(set (match_operand:DI 0 "gpc_reg_operand" "") 7950 (match_operand:DI 1 "const_scalar_int_operand" ""))] 7951 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 7952 [(set (match_dup 0) (match_dup 2)) 7953 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 7954 " 7955{ 7956 if (rs6000_emit_set_const (operands[0], operands[1])) 7957 DONE; 7958 else 7959 FAIL; 7960}") 7961 7962;; TImode/PTImode is similar, except that we usually want to compute the 7963;; address into a register and use lsi/stsi (the exception is during reload). 7964 7965(define_insn "*mov<mode>_string" 7966 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r") 7967 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))] 7968 "! TARGET_POWERPC64 7969 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode)) 7970 && (gpc_reg_operand (operands[0], <MODE>mode) 7971 || gpc_reg_operand (operands[1], <MODE>mode))" 7972 "* 7973{ 7974 switch (which_alternative) 7975 { 7976 default: 7977 gcc_unreachable (); 7978 case 0: 7979 if (TARGET_STRING) 7980 return \"stswi %1,%P0,16\"; 7981 case 1: 7982 return \"#\"; 7983 case 2: 7984 /* If the address is not used in the output, we can use lsi. Otherwise, 7985 fall through to generating four loads. */ 7986 if (TARGET_STRING 7987 && ! reg_overlap_mentioned_p (operands[0], operands[1])) 7988 return \"lswi %0,%P1,16\"; 7989 /* ... fall through ... */ 7990 case 3: 7991 case 4: 7992 case 5: 7993 return \"#\"; 7994 } 7995}" 7996 [(set_attr "type" "store,store,load,load,*,*") 7997 (set_attr "update" "yes") 7998 (set_attr "indexed" "yes") 7999 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING") 8000 (const_string "always") 8001 (const_string "conditional")))]) 8002 8003(define_insn "*mov<mode>_ppc64" 8004 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r") 8005 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))] 8006 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode) 8007 && (gpc_reg_operand (operands[0], <MODE>mode) 8008 || gpc_reg_operand (operands[1], <MODE>mode)))" 8009{ 8010 return rs6000_output_move_128bit (operands); 8011} 8012 [(set_attr "type" "store,store,load,load,*,*") 8013 (set_attr "length" "8")]) 8014 8015(define_split 8016 [(set (match_operand:TI2 0 "int_reg_operand" "") 8017 (match_operand:TI2 1 "const_scalar_int_operand" ""))] 8018 "TARGET_POWERPC64 8019 && (VECTOR_MEM_NONE_P (<MODE>mode) 8020 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))" 8021 [(set (match_dup 2) (match_dup 4)) 8022 (set (match_dup 3) (match_dup 5))] 8023 " 8024{ 8025 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 8026 <MODE>mode); 8027 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 8028 <MODE>mode); 8029 if (CONST_WIDE_INT_P (operands[1])) 8030 { 8031 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1)); 8032 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0)); 8033 } 8034 else if (CONST_INT_P (operands[1])) 8035 { 8036 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); 8037 operands[5] = operands[1]; 8038 } 8039 else 8040 FAIL; 8041}") 8042 8043(define_split 8044 [(set (match_operand:TI2 0 "nonimmediate_operand" "") 8045 (match_operand:TI2 1 "input_operand" ""))] 8046 "reload_completed 8047 && gpr_or_gpr_p (operands[0], operands[1]) 8048 && !direct_move_p (operands[0], operands[1]) 8049 && !quad_load_store_p (operands[0], operands[1])" 8050 [(pc)] 8051{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) 8052 8053(define_expand "load_multiple" 8054 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 8055 (match_operand:SI 1 "" "")) 8056 (use (match_operand:SI 2 "" ""))])] 8057 "TARGET_STRING && !TARGET_POWERPC64" 8058 " 8059{ 8060 int regno; 8061 int count; 8062 rtx op1; 8063 int i; 8064 8065 /* Support only loading a constant number of fixed-point registers from 8066 memory and only bother with this if more than two; the machine 8067 doesn't support more than eight. */ 8068 if (GET_CODE (operands[2]) != CONST_INT 8069 || INTVAL (operands[2]) <= 2 8070 || INTVAL (operands[2]) > 8 8071 || GET_CODE (operands[1]) != MEM 8072 || GET_CODE (operands[0]) != REG 8073 || REGNO (operands[0]) >= 32) 8074 FAIL; 8075 8076 count = INTVAL (operands[2]); 8077 regno = REGNO (operands[0]); 8078 8079 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); 8080 op1 = replace_equiv_address (operands[1], 8081 force_reg (SImode, XEXP (operands[1], 0))); 8082 8083 for (i = 0; i < count; i++) 8084 XVECEXP (operands[3], 0, i) 8085 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i), 8086 adjust_address_nv (op1, SImode, i * 4)); 8087}") 8088 8089(define_insn "*ldmsi8" 8090 [(match_parallel 0 "load_multiple_operation" 8091 [(set (match_operand:SI 2 "gpc_reg_operand" "") 8092 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 8093 (set (match_operand:SI 3 "gpc_reg_operand" "") 8094 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 8095 (set (match_operand:SI 4 "gpc_reg_operand" "") 8096 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 8097 (set (match_operand:SI 5 "gpc_reg_operand" "") 8098 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) 8099 (set (match_operand:SI 6 "gpc_reg_operand" "") 8100 (mem:SI (plus:SI (match_dup 1) (const_int 16)))) 8101 (set (match_operand:SI 7 "gpc_reg_operand" "") 8102 (mem:SI (plus:SI (match_dup 1) (const_int 20)))) 8103 (set (match_operand:SI 8 "gpc_reg_operand" "") 8104 (mem:SI (plus:SI (match_dup 1) (const_int 24)))) 8105 (set (match_operand:SI 9 "gpc_reg_operand" "") 8106 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])] 8107 "TARGET_STRING && XVECLEN (operands[0], 0) == 8" 8108 "* 8109{ return rs6000_output_load_multiple (operands); }" 8110 [(set_attr "type" "load") 8111 (set_attr "update" "yes") 8112 (set_attr "indexed" "yes") 8113 (set_attr "length" "32")]) 8114 8115(define_insn "*ldmsi7" 8116 [(match_parallel 0 "load_multiple_operation" 8117 [(set (match_operand:SI 2 "gpc_reg_operand" "") 8118 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 8119 (set (match_operand:SI 3 "gpc_reg_operand" "") 8120 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 8121 (set (match_operand:SI 4 "gpc_reg_operand" "") 8122 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 8123 (set (match_operand:SI 5 "gpc_reg_operand" "") 8124 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) 8125 (set (match_operand:SI 6 "gpc_reg_operand" "") 8126 (mem:SI (plus:SI (match_dup 1) (const_int 16)))) 8127 (set (match_operand:SI 7 "gpc_reg_operand" "") 8128 (mem:SI (plus:SI (match_dup 1) (const_int 20)))) 8129 (set (match_operand:SI 8 "gpc_reg_operand" "") 8130 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])] 8131 "TARGET_STRING && XVECLEN (operands[0], 0) == 7" 8132 "* 8133{ return rs6000_output_load_multiple (operands); }" 8134 [(set_attr "type" "load") 8135 (set_attr "update" "yes") 8136 (set_attr "indexed" "yes") 8137 (set_attr "length" "32")]) 8138 8139(define_insn "*ldmsi6" 8140 [(match_parallel 0 "load_multiple_operation" 8141 [(set (match_operand:SI 2 "gpc_reg_operand" "") 8142 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 8143 (set (match_operand:SI 3 "gpc_reg_operand" "") 8144 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 8145 (set (match_operand:SI 4 "gpc_reg_operand" "") 8146 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 8147 (set (match_operand:SI 5 "gpc_reg_operand" "") 8148 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) 8149 (set (match_operand:SI 6 "gpc_reg_operand" "") 8150 (mem:SI (plus:SI (match_dup 1) (const_int 16)))) 8151 (set (match_operand:SI 7 "gpc_reg_operand" "") 8152 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])] 8153 "TARGET_STRING && XVECLEN (operands[0], 0) == 6" 8154 "* 8155{ return rs6000_output_load_multiple (operands); }" 8156 [(set_attr "type" "load") 8157 (set_attr "update" "yes") 8158 (set_attr "indexed" "yes") 8159 (set_attr "length" "32")]) 8160 8161(define_insn "*ldmsi5" 8162 [(match_parallel 0 "load_multiple_operation" 8163 [(set (match_operand:SI 2 "gpc_reg_operand" "") 8164 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 8165 (set (match_operand:SI 3 "gpc_reg_operand" "") 8166 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 8167 (set (match_operand:SI 4 "gpc_reg_operand" "") 8168 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 8169 (set (match_operand:SI 5 "gpc_reg_operand" "") 8170 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) 8171 (set (match_operand:SI 6 "gpc_reg_operand" "") 8172 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])] 8173 "TARGET_STRING && XVECLEN (operands[0], 0) == 5" 8174 "* 8175{ return rs6000_output_load_multiple (operands); }" 8176 [(set_attr "type" "load") 8177 (set_attr "update" "yes") 8178 (set_attr "indexed" "yes") 8179 (set_attr "length" "32")]) 8180 8181(define_insn "*ldmsi4" 8182 [(match_parallel 0 "load_multiple_operation" 8183 [(set (match_operand:SI 2 "gpc_reg_operand" "") 8184 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 8185 (set (match_operand:SI 3 "gpc_reg_operand" "") 8186 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 8187 (set (match_operand:SI 4 "gpc_reg_operand" "") 8188 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 8189 (set (match_operand:SI 5 "gpc_reg_operand" "") 8190 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])] 8191 "TARGET_STRING && XVECLEN (operands[0], 0) == 4" 8192 "* 8193{ return rs6000_output_load_multiple (operands); }" 8194 [(set_attr "type" "load") 8195 (set_attr "update" "yes") 8196 (set_attr "indexed" "yes") 8197 (set_attr "length" "32")]) 8198 8199(define_insn "*ldmsi3" 8200 [(match_parallel 0 "load_multiple_operation" 8201 [(set (match_operand:SI 2 "gpc_reg_operand" "") 8202 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 8203 (set (match_operand:SI 3 "gpc_reg_operand" "") 8204 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 8205 (set (match_operand:SI 4 "gpc_reg_operand" "") 8206 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])] 8207 "TARGET_STRING && XVECLEN (operands[0], 0) == 3" 8208 "* 8209{ return rs6000_output_load_multiple (operands); }" 8210 [(set_attr "type" "load") 8211 (set_attr "update" "yes") 8212 (set_attr "indexed" "yes") 8213 (set_attr "length" "32")]) 8214 8215(define_expand "store_multiple" 8216 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 8217 (match_operand:SI 1 "" "")) 8218 (clobber (scratch:SI)) 8219 (use (match_operand:SI 2 "" ""))])] 8220 "TARGET_STRING && !TARGET_POWERPC64" 8221 " 8222{ 8223 int regno; 8224 int count; 8225 rtx to; 8226 rtx op0; 8227 int i; 8228 8229 /* Support only storing a constant number of fixed-point registers to 8230 memory and only bother with this if more than two; the machine 8231 doesn't support more than eight. */ 8232 if (GET_CODE (operands[2]) != CONST_INT 8233 || INTVAL (operands[2]) <= 2 8234 || INTVAL (operands[2]) > 8 8235 || GET_CODE (operands[0]) != MEM 8236 || GET_CODE (operands[1]) != REG 8237 || REGNO (operands[1]) >= 32) 8238 FAIL; 8239 8240 count = INTVAL (operands[2]); 8241 regno = REGNO (operands[1]); 8242 8243 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1)); 8244 to = force_reg (SImode, XEXP (operands[0], 0)); 8245 op0 = replace_equiv_address (operands[0], to); 8246 8247 XVECEXP (operands[3], 0, 0) 8248 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]); 8249 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode, 8250 gen_rtx_SCRATCH (SImode)); 8251 8252 for (i = 1; i < count; i++) 8253 XVECEXP (operands[3], 0, i + 1) 8254 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4), 8255 gen_rtx_REG (SImode, regno + i)); 8256}") 8257 8258(define_insn "*stmsi8" 8259 [(match_parallel 0 "store_multiple_operation" 8260 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 8261 (match_operand:SI 2 "gpc_reg_operand" "r")) 8262 (clobber (match_scratch:SI 3 "=X")) 8263 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 8264 (match_operand:SI 4 "gpc_reg_operand" "r")) 8265 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 8266 (match_operand:SI 5 "gpc_reg_operand" "r")) 8267 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 8268 (match_operand:SI 6 "gpc_reg_operand" "r")) 8269 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 8270 (match_operand:SI 7 "gpc_reg_operand" "r")) 8271 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 8272 (match_operand:SI 8 "gpc_reg_operand" "r")) 8273 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) 8274 (match_operand:SI 9 "gpc_reg_operand" "r")) 8275 (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) 8276 (match_operand:SI 10 "gpc_reg_operand" "r"))])] 8277 "TARGET_STRING && XVECLEN (operands[0], 0) == 9" 8278 "stswi %2,%1,%O0" 8279 [(set_attr "type" "store") 8280 (set_attr "update" "yes") 8281 (set_attr "indexed" "yes") 8282 (set_attr "cell_micro" "always")]) 8283 8284(define_insn "*stmsi7" 8285 [(match_parallel 0 "store_multiple_operation" 8286 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 8287 (match_operand:SI 2 "gpc_reg_operand" "r")) 8288 (clobber (match_scratch:SI 3 "=X")) 8289 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 8290 (match_operand:SI 4 "gpc_reg_operand" "r")) 8291 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 8292 (match_operand:SI 5 "gpc_reg_operand" "r")) 8293 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 8294 (match_operand:SI 6 "gpc_reg_operand" "r")) 8295 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 8296 (match_operand:SI 7 "gpc_reg_operand" "r")) 8297 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 8298 (match_operand:SI 8 "gpc_reg_operand" "r")) 8299 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) 8300 (match_operand:SI 9 "gpc_reg_operand" "r"))])] 8301 "TARGET_STRING && XVECLEN (operands[0], 0) == 8" 8302 "stswi %2,%1,%O0" 8303 [(set_attr "type" "store") 8304 (set_attr "update" "yes") 8305 (set_attr "indexed" "yes") 8306 (set_attr "cell_micro" "always")]) 8307 8308(define_insn "*stmsi6" 8309 [(match_parallel 0 "store_multiple_operation" 8310 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 8311 (match_operand:SI 2 "gpc_reg_operand" "r")) 8312 (clobber (match_scratch:SI 3 "=X")) 8313 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 8314 (match_operand:SI 4 "gpc_reg_operand" "r")) 8315 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 8316 (match_operand:SI 5 "gpc_reg_operand" "r")) 8317 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 8318 (match_operand:SI 6 "gpc_reg_operand" "r")) 8319 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 8320 (match_operand:SI 7 "gpc_reg_operand" "r")) 8321 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 8322 (match_operand:SI 8 "gpc_reg_operand" "r"))])] 8323 "TARGET_STRING && XVECLEN (operands[0], 0) == 7" 8324 "stswi %2,%1,%O0" 8325 [(set_attr "type" "store") 8326 (set_attr "update" "yes") 8327 (set_attr "indexed" "yes") 8328 (set_attr "cell_micro" "always")]) 8329 8330(define_insn "*stmsi5" 8331 [(match_parallel 0 "store_multiple_operation" 8332 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 8333 (match_operand:SI 2 "gpc_reg_operand" "r")) 8334 (clobber (match_scratch:SI 3 "=X")) 8335 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 8336 (match_operand:SI 4 "gpc_reg_operand" "r")) 8337 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 8338 (match_operand:SI 5 "gpc_reg_operand" "r")) 8339 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 8340 (match_operand:SI 6 "gpc_reg_operand" "r")) 8341 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 8342 (match_operand:SI 7 "gpc_reg_operand" "r"))])] 8343 "TARGET_STRING && XVECLEN (operands[0], 0) == 6" 8344 "stswi %2,%1,%O0" 8345 [(set_attr "type" "store") 8346 (set_attr "update" "yes") 8347 (set_attr "indexed" "yes") 8348 (set_attr "cell_micro" "always")]) 8349 8350(define_insn "*stmsi4" 8351 [(match_parallel 0 "store_multiple_operation" 8352 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 8353 (match_operand:SI 2 "gpc_reg_operand" "r")) 8354 (clobber (match_scratch:SI 3 "=X")) 8355 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 8356 (match_operand:SI 4 "gpc_reg_operand" "r")) 8357 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 8358 (match_operand:SI 5 "gpc_reg_operand" "r")) 8359 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 8360 (match_operand:SI 6 "gpc_reg_operand" "r"))])] 8361 "TARGET_STRING && XVECLEN (operands[0], 0) == 5" 8362 "stswi %2,%1,%O0" 8363 [(set_attr "type" "store") 8364 (set_attr "update" "yes") 8365 (set_attr "indexed" "yes") 8366 (set_attr "cell_micro" "always")]) 8367 8368(define_insn "*stmsi3" 8369 [(match_parallel 0 "store_multiple_operation" 8370 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 8371 (match_operand:SI 2 "gpc_reg_operand" "r")) 8372 (clobber (match_scratch:SI 3 "=X")) 8373 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 8374 (match_operand:SI 4 "gpc_reg_operand" "r")) 8375 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 8376 (match_operand:SI 5 "gpc_reg_operand" "r"))])] 8377 "TARGET_STRING && XVECLEN (operands[0], 0) == 4" 8378 "stswi %2,%1,%O0" 8379 [(set_attr "type" "store") 8380 (set_attr "update" "yes") 8381 (set_attr "indexed" "yes") 8382 (set_attr "cell_micro" "always")]) 8383 8384(define_expand "setmemsi" 8385 [(parallel [(set (match_operand:BLK 0 "" "") 8386 (match_operand 2 "const_int_operand" "")) 8387 (use (match_operand:SI 1 "" "")) 8388 (use (match_operand:SI 3 "" ""))])] 8389 "" 8390 " 8391{ 8392 /* If value to set is not zero, use the library routine. */ 8393 if (operands[2] != const0_rtx) 8394 FAIL; 8395 8396 if (expand_block_clear (operands)) 8397 DONE; 8398 else 8399 FAIL; 8400}") 8401 8402;; String/block move insn. 8403;; Argument 0 is the destination 8404;; Argument 1 is the source 8405;; Argument 2 is the length 8406;; Argument 3 is the alignment 8407 8408(define_expand "movmemsi" 8409 [(parallel [(set (match_operand:BLK 0 "" "") 8410 (match_operand:BLK 1 "" "")) 8411 (use (match_operand:SI 2 "" "")) 8412 (use (match_operand:SI 3 "" ""))])] 8413 "" 8414 " 8415{ 8416 if (expand_block_move (operands)) 8417 DONE; 8418 else 8419 FAIL; 8420}") 8421 8422;; Move up to 32 bytes at a time. The fixed registers are needed because the 8423;; register allocator doesn't have a clue about allocating 8 word registers. 8424;; rD/rS = r5 is preferred, efficient form. 8425(define_expand "movmemsi_8reg" 8426 [(parallel [(set (match_operand 0 "" "") 8427 (match_operand 1 "" "")) 8428 (use (match_operand 2 "" "")) 8429 (use (match_operand 3 "" "")) 8430 (clobber (reg:SI 5)) 8431 (clobber (reg:SI 6)) 8432 (clobber (reg:SI 7)) 8433 (clobber (reg:SI 8)) 8434 (clobber (reg:SI 9)) 8435 (clobber (reg:SI 10)) 8436 (clobber (reg:SI 11)) 8437 (clobber (reg:SI 12)) 8438 (clobber (match_scratch:SI 4 ""))])] 8439 "TARGET_STRING" 8440 "") 8441 8442(define_insn "" 8443 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) 8444 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) 8445 (use (match_operand:SI 2 "immediate_operand" "i")) 8446 (use (match_operand:SI 3 "immediate_operand" "i")) 8447 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) 8448 (clobber (reg:SI 6)) 8449 (clobber (reg:SI 7)) 8450 (clobber (reg:SI 8)) 8451 (clobber (reg:SI 9)) 8452 (clobber (reg:SI 10)) 8453 (clobber (reg:SI 11)) 8454 (clobber (reg:SI 12)) 8455 (clobber (match_scratch:SI 5 "=X"))] 8456 "TARGET_STRING 8457 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) 8458 || INTVAL (operands[2]) == 0) 8459 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12) 8460 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) 8461 && REGNO (operands[4]) == 5" 8462 "lswi %4,%1,%2\;stswi %4,%0,%2" 8463 [(set_attr "type" "store") 8464 (set_attr "update" "yes") 8465 (set_attr "indexed" "yes") 8466 (set_attr "cell_micro" "always") 8467 (set_attr "length" "8")]) 8468 8469;; Move up to 24 bytes at a time. The fixed registers are needed because the 8470;; register allocator doesn't have a clue about allocating 6 word registers. 8471;; rD/rS = r5 is preferred, efficient form. 8472(define_expand "movmemsi_6reg" 8473 [(parallel [(set (match_operand 0 "" "") 8474 (match_operand 1 "" "")) 8475 (use (match_operand 2 "" "")) 8476 (use (match_operand 3 "" "")) 8477 (clobber (reg:SI 5)) 8478 (clobber (reg:SI 6)) 8479 (clobber (reg:SI 7)) 8480 (clobber (reg:SI 8)) 8481 (clobber (reg:SI 9)) 8482 (clobber (reg:SI 10)) 8483 (clobber (match_scratch:SI 4 ""))])] 8484 "TARGET_STRING" 8485 "") 8486 8487(define_insn "" 8488 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) 8489 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) 8490 (use (match_operand:SI 2 "immediate_operand" "i")) 8491 (use (match_operand:SI 3 "immediate_operand" "i")) 8492 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) 8493 (clobber (reg:SI 6)) 8494 (clobber (reg:SI 7)) 8495 (clobber (reg:SI 8)) 8496 (clobber (reg:SI 9)) 8497 (clobber (reg:SI 10)) 8498 (clobber (match_scratch:SI 5 "=X"))] 8499 "TARGET_STRING 8500 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32 8501 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10) 8502 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10) 8503 && REGNO (operands[4]) == 5" 8504 "lswi %4,%1,%2\;stswi %4,%0,%2" 8505 [(set_attr "type" "store") 8506 (set_attr "update" "yes") 8507 (set_attr "indexed" "yes") 8508 (set_attr "cell_micro" "always") 8509 (set_attr "length" "8")]) 8510 8511;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill 8512;; problems with TImode. 8513;; rD/rS = r5 is preferred, efficient form. 8514(define_expand "movmemsi_4reg" 8515 [(parallel [(set (match_operand 0 "" "") 8516 (match_operand 1 "" "")) 8517 (use (match_operand 2 "" "")) 8518 (use (match_operand 3 "" "")) 8519 (clobber (reg:SI 5)) 8520 (clobber (reg:SI 6)) 8521 (clobber (reg:SI 7)) 8522 (clobber (reg:SI 8)) 8523 (clobber (match_scratch:SI 4 ""))])] 8524 "TARGET_STRING" 8525 "") 8526 8527(define_insn "" 8528 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) 8529 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) 8530 (use (match_operand:SI 2 "immediate_operand" "i")) 8531 (use (match_operand:SI 3 "immediate_operand" "i")) 8532 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) 8533 (clobber (reg:SI 6)) 8534 (clobber (reg:SI 7)) 8535 (clobber (reg:SI 8)) 8536 (clobber (match_scratch:SI 5 "=X"))] 8537 "TARGET_STRING 8538 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 8539 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8) 8540 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8) 8541 && REGNO (operands[4]) == 5" 8542 "lswi %4,%1,%2\;stswi %4,%0,%2" 8543 [(set_attr "type" "store") 8544 (set_attr "update" "yes") 8545 (set_attr "indexed" "yes") 8546 (set_attr "cell_micro" "always") 8547 (set_attr "length" "8")]) 8548 8549;; Move up to 8 bytes at a time. 8550(define_expand "movmemsi_2reg" 8551 [(parallel [(set (match_operand 0 "" "") 8552 (match_operand 1 "" "")) 8553 (use (match_operand 2 "" "")) 8554 (use (match_operand 3 "" "")) 8555 (clobber (match_scratch:DI 4 "")) 8556 (clobber (match_scratch:SI 5 ""))])] 8557 "TARGET_STRING && ! TARGET_POWERPC64" 8558 "") 8559 8560(define_insn "" 8561 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b")) 8562 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) 8563 (use (match_operand:SI 2 "immediate_operand" "i")) 8564 (use (match_operand:SI 3 "immediate_operand" "i")) 8565 (clobber (match_scratch:DI 4 "=&r")) 8566 (clobber (match_scratch:SI 5 "=X"))] 8567 "TARGET_STRING && ! TARGET_POWERPC64 8568 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" 8569 "lswi %4,%1,%2\;stswi %4,%0,%2" 8570 [(set_attr "type" "store") 8571 (set_attr "update" "yes") 8572 (set_attr "indexed" "yes") 8573 (set_attr "cell_micro" "always") 8574 (set_attr "length" "8")]) 8575 8576;; Move up to 4 bytes at a time. 8577(define_expand "movmemsi_1reg" 8578 [(parallel [(set (match_operand 0 "" "") 8579 (match_operand 1 "" "")) 8580 (use (match_operand 2 "" "")) 8581 (use (match_operand 3 "" "")) 8582 (clobber (match_scratch:SI 4 "")) 8583 (clobber (match_scratch:SI 5 ""))])] 8584 "TARGET_STRING" 8585 "") 8586 8587(define_insn "" 8588 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) 8589 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) 8590 (use (match_operand:SI 2 "immediate_operand" "i")) 8591 (use (match_operand:SI 3 "immediate_operand" "i")) 8592 (clobber (match_scratch:SI 4 "=&r")) 8593 (clobber (match_scratch:SI 5 "=X"))] 8594 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" 8595 "lswi %4,%1,%2\;stswi %4,%0,%2" 8596 [(set_attr "type" "store") 8597 (set_attr "update" "yes") 8598 (set_attr "indexed" "yes") 8599 (set_attr "cell_micro" "always") 8600 (set_attr "length" "8")]) 8601 8602;; Define insns that do load or store with update. Some of these we can 8603;; get by using pre-decrement or pre-increment, but the hardware can also 8604;; do cases where the increment is not the size of the object. 8605;; 8606;; In all these cases, we use operands 0 and 1 for the register being 8607;; incremented because those are the operands that local-alloc will 8608;; tie and these are the pair most likely to be tieable (and the ones 8609;; that will benefit the most). 8610 8611(define_insn "*movdi_update1" 8612 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r") 8613 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") 8614 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))) 8615 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") 8616 (plus:DI (match_dup 1) (match_dup 2)))] 8617 "TARGET_POWERPC64 && TARGET_UPDATE 8618 && (!avoiding_indexed_address_p (DImode) 8619 || !gpc_reg_operand (operands[2], DImode))" 8620 "@ 8621 ldux %3,%0,%2 8622 ldu %3,%2(%0)" 8623 [(set_attr "type" "load") 8624 (set_attr "update" "yes") 8625 (set_attr "indexed" "yes,no")]) 8626 8627(define_insn "movdi_<mode>_update" 8628 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 8629 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) 8630 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 8631 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 8632 (plus:P (match_dup 1) (match_dup 2)))] 8633 "TARGET_POWERPC64 && TARGET_UPDATE 8634 && (!avoiding_indexed_address_p (Pmode) 8635 || !gpc_reg_operand (operands[2], Pmode) 8636 || (REG_P (operands[0]) 8637 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 8638 "@ 8639 stdux %3,%0,%2 8640 stdu %3,%2(%0)" 8641 [(set_attr "type" "store") 8642 (set_attr "update" "yes") 8643 (set_attr "indexed" "yes,no")]) 8644 8645;; This pattern is only conditional on TARGET_POWERPC64, as it is 8646;; needed for stack allocation, even if the user passes -mno-update. 8647(define_insn "movdi_<mode>_update_stack" 8648 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 8649 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) 8650 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 8651 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 8652 (plus:P (match_dup 1) (match_dup 2)))] 8653 "TARGET_POWERPC64" 8654 "@ 8655 stdux %3,%0,%2 8656 stdu %3,%2(%0)" 8657 [(set_attr "type" "store") 8658 (set_attr "update" "yes") 8659 (set_attr "indexed" "yes,no")]) 8660 8661(define_insn "*movsi_update1" 8662 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 8663 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8664 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 8665 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8666 (plus:SI (match_dup 1) (match_dup 2)))] 8667 "TARGET_UPDATE 8668 && (!avoiding_indexed_address_p (SImode) 8669 || !gpc_reg_operand (operands[2], SImode))" 8670 "@ 8671 lwzux %3,%0,%2 8672 lwzu %3,%2(%0)" 8673 [(set_attr "type" "load") 8674 (set_attr "update" "yes") 8675 (set_attr "indexed" "yes,no")]) 8676 8677(define_insn "*movsi_update2" 8678 [(set (match_operand:DI 3 "gpc_reg_operand" "=r") 8679 (sign_extend:DI 8680 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0") 8681 (match_operand:DI 2 "gpc_reg_operand" "r"))))) 8682 (set (match_operand:DI 0 "gpc_reg_operand" "=b") 8683 (plus:DI (match_dup 1) (match_dup 2)))] 8684 "TARGET_POWERPC64 && rs6000_gen_cell_microcode 8685 && !avoiding_indexed_address_p (DImode)" 8686 "lwaux %3,%0,%2" 8687 [(set_attr "type" "load") 8688 (set_attr "sign_extend" "yes") 8689 (set_attr "update" "yes") 8690 (set_attr "indexed" "yes")]) 8691 8692(define_insn "movsi_update" 8693 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8694 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 8695 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 8696 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8697 (plus:SI (match_dup 1) (match_dup 2)))] 8698 "TARGET_UPDATE 8699 && (!avoiding_indexed_address_p (SImode) 8700 || !gpc_reg_operand (operands[2], SImode) 8701 || (REG_P (operands[0]) 8702 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 8703 "@ 8704 stwux %3,%0,%2 8705 stwu %3,%2(%0)" 8706 [(set_attr "type" "store") 8707 (set_attr "update" "yes") 8708 (set_attr "indexed" "yes,no")]) 8709 8710;; This is an unconditional pattern; needed for stack allocation, even 8711;; if the user passes -mno-update. 8712(define_insn "movsi_update_stack" 8713 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8714 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 8715 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 8716 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8717 (plus:SI (match_dup 1) (match_dup 2)))] 8718 "" 8719 "@ 8720 stwux %3,%0,%2 8721 stwu %3,%2(%0)" 8722 [(set_attr "type" "store") 8723 (set_attr "update" "yes") 8724 (set_attr "indexed" "yes,no")]) 8725 8726(define_insn "*movhi_update1" 8727 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r") 8728 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8729 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 8730 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8731 (plus:SI (match_dup 1) (match_dup 2)))] 8732 "TARGET_UPDATE 8733 && (!avoiding_indexed_address_p (SImode) 8734 || !gpc_reg_operand (operands[2], SImode))" 8735 "@ 8736 lhzux %3,%0,%2 8737 lhzu %3,%2(%0)" 8738 [(set_attr "type" "load") 8739 (set_attr "update" "yes") 8740 (set_attr "indexed" "yes,no")]) 8741 8742(define_insn "*movhi_update2" 8743 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 8744 (zero_extend:SI 8745 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8746 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) 8747 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8748 (plus:SI (match_dup 1) (match_dup 2)))] 8749 "TARGET_UPDATE 8750 && (!avoiding_indexed_address_p (SImode) 8751 || !gpc_reg_operand (operands[2], SImode))" 8752 "@ 8753 lhzux %3,%0,%2 8754 lhzu %3,%2(%0)" 8755 [(set_attr "type" "load") 8756 (set_attr "update" "yes") 8757 (set_attr "indexed" "yes,no")]) 8758 8759(define_insn "*movhi_update3" 8760 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 8761 (sign_extend:SI 8762 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8763 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) 8764 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8765 (plus:SI (match_dup 1) (match_dup 2)))] 8766 "TARGET_UPDATE && rs6000_gen_cell_microcode 8767 && (!avoiding_indexed_address_p (SImode) 8768 || !gpc_reg_operand (operands[2], SImode))" 8769 "@ 8770 lhaux %3,%0,%2 8771 lhau %3,%2(%0)" 8772 [(set_attr "type" "load") 8773 (set_attr "sign_extend" "yes") 8774 (set_attr "update" "yes") 8775 (set_attr "indexed" "yes,no")]) 8776 8777(define_insn "*movhi_update4" 8778 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8779 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 8780 (match_operand:HI 3 "gpc_reg_operand" "r,r")) 8781 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8782 (plus:SI (match_dup 1) (match_dup 2)))] 8783 "TARGET_UPDATE 8784 && (!avoiding_indexed_address_p (SImode) 8785 || !gpc_reg_operand (operands[2], SImode))" 8786 "@ 8787 sthux %3,%0,%2 8788 sthu %3,%2(%0)" 8789 [(set_attr "type" "store") 8790 (set_attr "update" "yes") 8791 (set_attr "indexed" "yes,no")]) 8792 8793(define_insn "*movqi_update1" 8794 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r") 8795 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8796 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 8797 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8798 (plus:SI (match_dup 1) (match_dup 2)))] 8799 "TARGET_UPDATE 8800 && (!avoiding_indexed_address_p (SImode) 8801 || !gpc_reg_operand (operands[2], SImode))" 8802 "@ 8803 lbzux %3,%0,%2 8804 lbzu %3,%2(%0)" 8805 [(set_attr "type" "load") 8806 (set_attr "update" "yes") 8807 (set_attr "indexed" "yes,no")]) 8808 8809(define_insn "*movqi_update2" 8810 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 8811 (zero_extend:SI 8812 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8813 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) 8814 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8815 (plus:SI (match_dup 1) (match_dup 2)))] 8816 "TARGET_UPDATE 8817 && (!avoiding_indexed_address_p (SImode) 8818 || !gpc_reg_operand (operands[2], SImode))" 8819 "@ 8820 lbzux %3,%0,%2 8821 lbzu %3,%2(%0)" 8822 [(set_attr "type" "load") 8823 (set_attr "update" "yes") 8824 (set_attr "indexed" "yes,no")]) 8825 8826(define_insn "*movqi_update3" 8827 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8828 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 8829 (match_operand:QI 3 "gpc_reg_operand" "r,r")) 8830 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8831 (plus:SI (match_dup 1) (match_dup 2)))] 8832 "TARGET_UPDATE 8833 && (!avoiding_indexed_address_p (SImode) 8834 || !gpc_reg_operand (operands[2], SImode))" 8835 "@ 8836 stbux %3,%0,%2 8837 stbu %3,%2(%0)" 8838 [(set_attr "type" "store") 8839 (set_attr "update" "yes") 8840 (set_attr "indexed" "yes,no")]) 8841 8842(define_insn "*movsf_update1" 8843 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f") 8844 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8845 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 8846 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8847 (plus:SI (match_dup 1) (match_dup 2)))] 8848 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE 8849 && (!avoiding_indexed_address_p (SImode) 8850 || !gpc_reg_operand (operands[2], SImode))" 8851 "@ 8852 lfsux %3,%0,%2 8853 lfsu %3,%2(%0)" 8854 [(set_attr "type" "fpload") 8855 (set_attr "update" "yes") 8856 (set_attr "indexed" "yes,no")]) 8857 8858(define_insn "*movsf_update2" 8859 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8860 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 8861 (match_operand:SF 3 "gpc_reg_operand" "f,f")) 8862 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8863 (plus:SI (match_dup 1) (match_dup 2)))] 8864 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE 8865 && (!avoiding_indexed_address_p (SImode) 8866 || !gpc_reg_operand (operands[2], SImode))" 8867 "@ 8868 stfsux %3,%0,%2 8869 stfsu %3,%2(%0)" 8870 [(set_attr "type" "fpstore") 8871 (set_attr "update" "yes") 8872 (set_attr "indexed" "yes,no")]) 8873 8874(define_insn "*movsf_update3" 8875 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r") 8876 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8877 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 8878 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8879 (plus:SI (match_dup 1) (match_dup 2)))] 8880 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE 8881 && (!avoiding_indexed_address_p (SImode) 8882 || !gpc_reg_operand (operands[2], SImode))" 8883 "@ 8884 lwzux %3,%0,%2 8885 lwzu %3,%2(%0)" 8886 [(set_attr "type" "load") 8887 (set_attr "update" "yes") 8888 (set_attr "indexed" "yes,no")]) 8889 8890(define_insn "*movsf_update4" 8891 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8892 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 8893 (match_operand:SF 3 "gpc_reg_operand" "r,r")) 8894 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8895 (plus:SI (match_dup 1) (match_dup 2)))] 8896 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE 8897 && (!avoiding_indexed_address_p (SImode) 8898 || !gpc_reg_operand (operands[2], SImode))" 8899 "@ 8900 stwux %3,%0,%2 8901 stwu %3,%2(%0)" 8902 [(set_attr "type" "store") 8903 (set_attr "update" "yes") 8904 (set_attr "indexed" "yes,no")]) 8905 8906(define_insn "*movdf_update1" 8907 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d") 8908 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8909 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 8910 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8911 (plus:SI (match_dup 1) (match_dup 2)))] 8912 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE 8913 && (!avoiding_indexed_address_p (SImode) 8914 || !gpc_reg_operand (operands[2], SImode))" 8915 "@ 8916 lfdux %3,%0,%2 8917 lfdu %3,%2(%0)" 8918 [(set_attr "type" "fpload") 8919 (set_attr "update" "yes") 8920 (set_attr "indexed" "yes,no") 8921 (set_attr "size" "64")]) 8922 8923(define_insn "*movdf_update2" 8924 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8925 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 8926 (match_operand:DF 3 "gpc_reg_operand" "d,d")) 8927 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8928 (plus:SI (match_dup 1) (match_dup 2)))] 8929 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE 8930 && (!avoiding_indexed_address_p (SImode) 8931 || !gpc_reg_operand (operands[2], SImode))" 8932 "@ 8933 stfdux %3,%0,%2 8934 stfdu %3,%2(%0)" 8935 [(set_attr "type" "fpstore") 8936 (set_attr "update" "yes") 8937 (set_attr "indexed" "yes,no")]) 8938 8939 8940;; After inserting conditional returns we can sometimes have 8941;; unnecessary register moves. Unfortunately we cannot have a 8942;; modeless peephole here, because some single SImode sets have early 8943;; clobber outputs. Although those sets expand to multi-ppc-insn 8944;; sequences, using get_attr_length here will smash the operands 8945;; array. Neither is there an early_cobbler_p predicate. 8946;; Disallow subregs for E500 so we don't munge frob_di_df_2. 8947;; Also this optimization interferes with scalars going into 8948;; altivec registers (the code does reloading through the FPRs). 8949(define_peephole2 8950 [(set (match_operand:DF 0 "gpc_reg_operand" "") 8951 (match_operand:DF 1 "any_operand" "")) 8952 (set (match_operand:DF 2 "gpc_reg_operand" "") 8953 (match_dup 0))] 8954 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG) 8955 && !TARGET_UPPER_REGS_DF 8956 && peep2_reg_dead_p (2, operands[0])" 8957 [(set (match_dup 2) (match_dup 1))]) 8958 8959(define_peephole2 8960 [(set (match_operand:SF 0 "gpc_reg_operand" "") 8961 (match_operand:SF 1 "any_operand" "")) 8962 (set (match_operand:SF 2 "gpc_reg_operand" "") 8963 (match_dup 0))] 8964 "!TARGET_UPPER_REGS_SF 8965 && peep2_reg_dead_p (2, operands[0])" 8966 [(set (match_dup 2) (match_dup 1))]) 8967 8968 8969;; TLS support. 8970 8971;; Mode attributes for different ABIs. 8972(define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")]) 8973(define_mode_attr tls_abi_suffix [(SI "32") (DI "64")]) 8974(define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")]) 8975(define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")]) 8976 8977(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>" 8978 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 8979 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) 8980 (match_operand 4 "" "g"))) 8981 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 8982 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 8983 UNSPEC_TLSGD) 8984 (clobber (reg:SI LR_REGNO))] 8985 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 8986{ 8987 if (TARGET_CMODEL != CMODEL_SMALL) 8988 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;" 8989 "bl %z3\;nop"; 8990 else 8991 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop"; 8992} 8993 "&& TARGET_TLS_MARKERS" 8994 [(set (match_dup 0) 8995 (unspec:TLSmode [(match_dup 1) 8996 (match_dup 2)] 8997 UNSPEC_TLSGD)) 8998 (parallel [(set (match_dup 0) 8999 (call (mem:TLSmode (match_dup 3)) 9000 (match_dup 4))) 9001 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) 9002 (clobber (reg:SI LR_REGNO))])] 9003 "" 9004 [(set_attr "type" "two") 9005 (set (attr "length") 9006 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9007 (const_int 16) 9008 (const_int 12)))]) 9009 9010(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>" 9011 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9012 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) 9013 (match_operand 4 "" "g"))) 9014 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9015 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9016 UNSPEC_TLSGD) 9017 (clobber (reg:SI LR_REGNO))] 9018 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" 9019{ 9020 if (flag_pic) 9021 { 9022 if (TARGET_SECURE_PLT && flag_pic == 2) 9023 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt"; 9024 else 9025 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt"; 9026 } 9027 else 9028 return "addi %0,%1,%2@got@tlsgd\;bl %z3"; 9029} 9030 "&& TARGET_TLS_MARKERS" 9031 [(set (match_dup 0) 9032 (unspec:TLSmode [(match_dup 1) 9033 (match_dup 2)] 9034 UNSPEC_TLSGD)) 9035 (parallel [(set (match_dup 0) 9036 (call (mem:TLSmode (match_dup 3)) 9037 (match_dup 4))) 9038 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) 9039 (clobber (reg:SI LR_REGNO))])] 9040 "" 9041 [(set_attr "type" "two") 9042 (set_attr "length" "8")]) 9043 9044(define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>" 9045 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9046 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9047 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9048 UNSPEC_TLSGD))] 9049 "HAVE_AS_TLS && TARGET_TLS_MARKERS" 9050 "addi %0,%1,%2@got@tlsgd" 9051 "&& TARGET_CMODEL != CMODEL_SMALL" 9052 [(set (match_dup 3) 9053 (high:TLSmode 9054 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) 9055 (set (match_dup 0) 9056 (lo_sum:TLSmode (match_dup 3) 9057 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))] 9058 " 9059{ 9060 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9061}" 9062 [(set (attr "length") 9063 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9064 (const_int 8) 9065 (const_int 4)))]) 9066 9067(define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>" 9068 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9069 (high:TLSmode 9070 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9071 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9072 UNSPEC_TLSGD)))] 9073 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 9074 "addis %0,%1,%2@got@tlsgd@ha" 9075 [(set_attr "length" "4")]) 9076 9077(define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>" 9078 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9079 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 9080 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") 9081 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9082 UNSPEC_TLSGD)))] 9083 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 9084 "addi %0,%1,%2@got@tlsgd@l" 9085 [(set_attr "length" "4")]) 9086 9087(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>" 9088 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9089 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 9090 (match_operand 2 "" "g"))) 9091 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] 9092 UNSPEC_TLSGD) 9093 (clobber (reg:SI LR_REGNO))] 9094 "HAVE_AS_TLS && TARGET_TLS_MARKERS 9095 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 9096 "bl %z1(%3@tlsgd)\;nop" 9097 [(set_attr "type" "branch") 9098 (set_attr "length" "8")]) 9099 9100(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>" 9101 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9102 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 9103 (match_operand 2 "" "g"))) 9104 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] 9105 UNSPEC_TLSGD) 9106 (clobber (reg:SI LR_REGNO))] 9107 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" 9108{ 9109 if (flag_pic) 9110 { 9111 if (TARGET_SECURE_PLT && flag_pic == 2) 9112 return "bl %z1+32768(%3@tlsgd)@plt"; 9113 return "bl %z1(%3@tlsgd)@plt"; 9114 } 9115 return "bl %z1(%3@tlsgd)"; 9116} 9117 [(set_attr "type" "branch") 9118 (set_attr "length" "4")]) 9119 9120(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>" 9121 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9122 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) 9123 (match_operand 3 "" "g"))) 9124 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 9125 UNSPEC_TLSLD) 9126 (clobber (reg:SI LR_REGNO))] 9127 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 9128{ 9129 if (TARGET_CMODEL != CMODEL_SMALL) 9130 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;" 9131 "bl %z2\;nop"; 9132 else 9133 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop"; 9134} 9135 "&& TARGET_TLS_MARKERS" 9136 [(set (match_dup 0) 9137 (unspec:TLSmode [(match_dup 1)] 9138 UNSPEC_TLSLD)) 9139 (parallel [(set (match_dup 0) 9140 (call (mem:TLSmode (match_dup 2)) 9141 (match_dup 3))) 9142 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 9143 (clobber (reg:SI LR_REGNO))])] 9144 "" 9145 [(set_attr "type" "two") 9146 (set (attr "length") 9147 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9148 (const_int 16) 9149 (const_int 12)))]) 9150 9151(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>" 9152 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9153 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) 9154 (match_operand 3 "" "g"))) 9155 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 9156 UNSPEC_TLSLD) 9157 (clobber (reg:SI LR_REGNO))] 9158 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" 9159{ 9160 if (flag_pic) 9161 { 9162 if (TARGET_SECURE_PLT && flag_pic == 2) 9163 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt"; 9164 else 9165 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt"; 9166 } 9167 else 9168 return "addi %0,%1,%&@got@tlsld\;bl %z2"; 9169} 9170 "&& TARGET_TLS_MARKERS" 9171 [(set (match_dup 0) 9172 (unspec:TLSmode [(match_dup 1)] 9173 UNSPEC_TLSLD)) 9174 (parallel [(set (match_dup 0) 9175 (call (mem:TLSmode (match_dup 2)) 9176 (match_dup 3))) 9177 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 9178 (clobber (reg:SI LR_REGNO))])] 9179 "" 9180 [(set_attr "length" "8")]) 9181 9182(define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>" 9183 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9184 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 9185 UNSPEC_TLSLD))] 9186 "HAVE_AS_TLS && TARGET_TLS_MARKERS" 9187 "addi %0,%1,%&@got@tlsld" 9188 "&& TARGET_CMODEL != CMODEL_SMALL" 9189 [(set (match_dup 2) 9190 (high:TLSmode 9191 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD))) 9192 (set (match_dup 0) 9193 (lo_sum:TLSmode (match_dup 2) 9194 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))] 9195 " 9196{ 9197 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9198}" 9199 [(set (attr "length") 9200 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9201 (const_int 8) 9202 (const_int 4)))]) 9203 9204(define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>" 9205 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9206 (high:TLSmode 9207 (unspec:TLSmode [(const_int 0) 9208 (match_operand:TLSmode 1 "gpc_reg_operand" "b")] 9209 UNSPEC_TLSLD)))] 9210 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 9211 "addis %0,%1,%&@got@tlsld@ha" 9212 [(set_attr "length" "4")]) 9213 9214(define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>" 9215 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9216 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 9217 (unspec:TLSmode [(const_int 0) 9218 (match_operand:TLSmode 2 "gpc_reg_operand" "b")] 9219 UNSPEC_TLSLD)))] 9220 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 9221 "addi %0,%1,%&@got@tlsld@l" 9222 [(set_attr "length" "4")]) 9223 9224(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>" 9225 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9226 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 9227 (match_operand 2 "" "g"))) 9228 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 9229 (clobber (reg:SI LR_REGNO))] 9230 "HAVE_AS_TLS && TARGET_TLS_MARKERS 9231 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 9232 "bl %z1(%&@tlsld)\;nop" 9233 [(set_attr "type" "branch") 9234 (set_attr "length" "8")]) 9235 9236(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>" 9237 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9238 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 9239 (match_operand 2 "" "g"))) 9240 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 9241 (clobber (reg:SI LR_REGNO))] 9242 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" 9243{ 9244 if (flag_pic) 9245 { 9246 if (TARGET_SECURE_PLT && flag_pic == 2) 9247 return "bl %z1+32768(%&@tlsld)@plt"; 9248 return "bl %z1(%&@tlsld)@plt"; 9249 } 9250 return "bl %z1(%&@tlsld)"; 9251} 9252 [(set_attr "type" "branch") 9253 (set_attr "length" "4")]) 9254 9255(define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>" 9256 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9257 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9258 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9259 UNSPEC_TLSDTPREL))] 9260 "HAVE_AS_TLS" 9261 "addi %0,%1,%2@dtprel") 9262 9263(define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>" 9264 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9265 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9266 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9267 UNSPEC_TLSDTPRELHA))] 9268 "HAVE_AS_TLS" 9269 "addis %0,%1,%2@dtprel@ha") 9270 9271(define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>" 9272 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9273 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9274 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9275 UNSPEC_TLSDTPRELLO))] 9276 "HAVE_AS_TLS" 9277 "addi %0,%1,%2@dtprel@l") 9278 9279(define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>" 9280 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9281 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9282 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9283 UNSPEC_TLSGOTDTPREL))] 9284 "HAVE_AS_TLS" 9285 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)" 9286 "&& TARGET_CMODEL != CMODEL_SMALL" 9287 [(set (match_dup 3) 9288 (high:TLSmode 9289 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) 9290 (set (match_dup 0) 9291 (lo_sum:TLSmode (match_dup 3) 9292 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))] 9293 " 9294{ 9295 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9296}" 9297 [(set (attr "length") 9298 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9299 (const_int 8) 9300 (const_int 4)))]) 9301 9302(define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>" 9303 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9304 (high:TLSmode 9305 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9306 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9307 UNSPEC_TLSGOTDTPREL)))] 9308 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9309 "addis %0,%1,%2@got@dtprel@ha" 9310 [(set_attr "length" "4")]) 9311 9312(define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>" 9313 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9314 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 9315 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") 9316 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9317 UNSPEC_TLSGOTDTPREL)))] 9318 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9319 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)" 9320 [(set_attr "length" "4")]) 9321 9322(define_insn "tls_tprel_<TLSmode:tls_abi_suffix>" 9323 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9324 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9325 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9326 UNSPEC_TLSTPREL))] 9327 "HAVE_AS_TLS" 9328 "addi %0,%1,%2@tprel") 9329 9330(define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>" 9331 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9332 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9333 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9334 UNSPEC_TLSTPRELHA))] 9335 "HAVE_AS_TLS" 9336 "addis %0,%1,%2@tprel@ha") 9337 9338(define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>" 9339 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9340 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9341 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9342 UNSPEC_TLSTPRELLO))] 9343 "HAVE_AS_TLS" 9344 "addi %0,%1,%2@tprel@l") 9345 9346;; "b" output constraint here and on tls_tls input to support linker tls 9347;; optimization. The linker may edit the instructions emitted by a 9348;; tls_got_tprel/tls_tls pair to addis,addi. 9349(define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>" 9350 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9351 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9352 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9353 UNSPEC_TLSGOTTPREL))] 9354 "HAVE_AS_TLS" 9355 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)" 9356 "&& TARGET_CMODEL != CMODEL_SMALL" 9357 [(set (match_dup 3) 9358 (high:TLSmode 9359 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) 9360 (set (match_dup 0) 9361 (lo_sum:TLSmode (match_dup 3) 9362 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))] 9363 " 9364{ 9365 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9366}" 9367 [(set (attr "length") 9368 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9369 (const_int 8) 9370 (const_int 4)))]) 9371 9372(define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>" 9373 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9374 (high:TLSmode 9375 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9376 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9377 UNSPEC_TLSGOTTPREL)))] 9378 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9379 "addis %0,%1,%2@got@tprel@ha" 9380 [(set_attr "length" "4")]) 9381 9382(define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>" 9383 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9384 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 9385 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") 9386 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9387 UNSPEC_TLSGOTTPREL)))] 9388 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9389 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)" 9390 [(set_attr "length" "4")]) 9391 9392(define_insn "tls_tls_<TLSmode:tls_abi_suffix>" 9393 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9394 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9395 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9396 UNSPEC_TLSTLS))] 9397 "TARGET_ELF && HAVE_AS_TLS" 9398 "add %0,%1,%2@tls") 9399 9400(define_expand "tls_get_tpointer" 9401 [(set (match_operand:SI 0 "gpc_reg_operand" "") 9402 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))] 9403 "TARGET_XCOFF && HAVE_AS_TLS" 9404 " 9405{ 9406 emit_insn (gen_tls_get_tpointer_internal ()); 9407 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); 9408 DONE; 9409}") 9410 9411(define_insn "tls_get_tpointer_internal" 9412 [(set (reg:SI 3) 9413 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS)) 9414 (clobber (reg:SI LR_REGNO))] 9415 "TARGET_XCOFF && HAVE_AS_TLS" 9416 "bla __get_tpointer") 9417 9418(define_expand "tls_get_addr<mode>" 9419 [(set (match_operand:P 0 "gpc_reg_operand" "") 9420 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "") 9421 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))] 9422 "TARGET_XCOFF && HAVE_AS_TLS" 9423 " 9424{ 9425 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]); 9426 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]); 9427 emit_insn (gen_tls_get_addr_internal<mode> ()); 9428 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3)); 9429 DONE; 9430}") 9431 9432(define_insn "tls_get_addr_internal<mode>" 9433 [(set (reg:P 3) 9434 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS)) 9435 (clobber (reg:P 0)) 9436 (clobber (reg:P 4)) 9437 (clobber (reg:P 5)) 9438 (clobber (reg:P 11)) 9439 (clobber (reg:CC CR0_REGNO)) 9440 (clobber (reg:P LR_REGNO))] 9441 "TARGET_XCOFF && HAVE_AS_TLS" 9442 "bla __tls_get_addr") 9443 9444;; Next come insns related to the calling sequence. 9445;; 9446;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). 9447;; We move the back-chain and decrement the stack pointer. 9448 9449(define_expand "allocate_stack" 9450 [(set (match_operand 0 "gpc_reg_operand" "") 9451 (minus (reg 1) (match_operand 1 "reg_or_short_operand" ""))) 9452 (set (reg 1) 9453 (minus (reg 1) (match_dup 1)))] 9454 "" 9455 " 9456{ rtx chain = gen_reg_rtx (Pmode); 9457 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); 9458 rtx neg_op0; 9459 rtx insn, par, set, mem; 9460 9461 emit_move_insn (chain, stack_bot); 9462 9463 /* Check stack bounds if necessary. */ 9464 if (crtl->limit_stack) 9465 { 9466 rtx available; 9467 available = expand_binop (Pmode, sub_optab, 9468 stack_pointer_rtx, stack_limit_rtx, 9469 NULL_RTX, 1, OPTAB_WIDEN); 9470 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx)); 9471 } 9472 9473 if (GET_CODE (operands[1]) != CONST_INT 9474 || INTVAL (operands[1]) < -32767 9475 || INTVAL (operands[1]) > 32768) 9476 { 9477 neg_op0 = gen_reg_rtx (Pmode); 9478 if (TARGET_32BIT) 9479 emit_insn (gen_negsi2 (neg_op0, operands[1])); 9480 else 9481 emit_insn (gen_negdi2 (neg_op0, operands[1])); 9482 } 9483 else 9484 neg_op0 = GEN_INT (- INTVAL (operands[1])); 9485 9486 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack 9487 : gen_movdi_di_update_stack)) 9488 (stack_pointer_rtx, stack_pointer_rtx, neg_op0, 9489 chain)); 9490 /* Since we didn't use gen_frame_mem to generate the MEM, grab 9491 it now and set the alias set/attributes. The above gen_*_update 9492 calls will generate a PARALLEL with the MEM set being the first 9493 operation. */ 9494 par = PATTERN (insn); 9495 gcc_assert (GET_CODE (par) == PARALLEL); 9496 set = XVECEXP (par, 0, 0); 9497 gcc_assert (GET_CODE (set) == SET); 9498 mem = SET_DEST (set); 9499 gcc_assert (MEM_P (mem)); 9500 MEM_NOTRAP_P (mem) = 1; 9501 set_mem_alias_set (mem, get_frame_alias_set ()); 9502 9503 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 9504 DONE; 9505}") 9506 9507;; These patterns say how to save and restore the stack pointer. We need not 9508;; save the stack pointer at function level since we are careful to 9509;; preserve the backchain. At block level, we have to restore the backchain 9510;; when we restore the stack pointer. 9511;; 9512;; For nonlocal gotos, we must save both the stack pointer and its 9513;; backchain and restore both. Note that in the nonlocal case, the 9514;; save area is a memory location. 9515 9516(define_expand "save_stack_function" 9517 [(match_operand 0 "any_operand" "") 9518 (match_operand 1 "any_operand" "")] 9519 "" 9520 "DONE;") 9521 9522(define_expand "restore_stack_function" 9523 [(match_operand 0 "any_operand" "") 9524 (match_operand 1 "any_operand" "")] 9525 "" 9526 "DONE;") 9527 9528;; Adjust stack pointer (op0) to a new value (op1). 9529;; First copy old stack backchain to new location, and ensure that the 9530;; scheduler won't reorder the sp assignment before the backchain write. 9531(define_expand "restore_stack_block" 9532 [(set (match_dup 2) (match_dup 3)) 9533 (set (match_dup 4) (match_dup 2)) 9534 (match_dup 5) 9535 (set (match_operand 0 "register_operand" "") 9536 (match_operand 1 "register_operand" ""))] 9537 "" 9538 " 9539{ 9540 rtvec p; 9541 9542 operands[1] = force_reg (Pmode, operands[1]); 9543 operands[2] = gen_reg_rtx (Pmode); 9544 operands[3] = gen_frame_mem (Pmode, operands[0]); 9545 operands[4] = gen_frame_mem (Pmode, operands[1]); 9546 p = rtvec_alloc (1); 9547 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 9548 const0_rtx); 9549 operands[5] = gen_rtx_PARALLEL (VOIDmode, p); 9550}") 9551 9552(define_expand "save_stack_nonlocal" 9553 [(set (match_dup 3) (match_dup 4)) 9554 (set (match_operand 0 "memory_operand" "") (match_dup 3)) 9555 (set (match_dup 2) (match_operand 1 "register_operand" ""))] 9556 "" 9557 " 9558{ 9559 int units_per_word = (TARGET_32BIT) ? 4 : 8; 9560 9561 /* Copy the backchain to the first word, sp to the second. */ 9562 operands[0] = adjust_address_nv (operands[0], Pmode, 0); 9563 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word); 9564 operands[3] = gen_reg_rtx (Pmode); 9565 operands[4] = gen_frame_mem (Pmode, operands[1]); 9566}") 9567 9568(define_expand "restore_stack_nonlocal" 9569 [(set (match_dup 2) (match_operand 1 "memory_operand" "")) 9570 (set (match_dup 3) (match_dup 4)) 9571 (set (match_dup 5) (match_dup 2)) 9572 (match_dup 6) 9573 (set (match_operand 0 "register_operand" "") (match_dup 3))] 9574 "" 9575 " 9576{ 9577 int units_per_word = (TARGET_32BIT) ? 4 : 8; 9578 rtvec p; 9579 9580 /* Restore the backchain from the first word, sp from the second. */ 9581 operands[2] = gen_reg_rtx (Pmode); 9582 operands[3] = gen_reg_rtx (Pmode); 9583 operands[1] = adjust_address_nv (operands[1], Pmode, 0); 9584 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word); 9585 operands[5] = gen_frame_mem (Pmode, operands[3]); 9586 p = rtvec_alloc (1); 9587 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 9588 const0_rtx); 9589 operands[6] = gen_rtx_PARALLEL (VOIDmode, p); 9590}") 9591 9592;; TOC register handling. 9593 9594;; Code to initialize the TOC register... 9595 9596(define_insn "load_toc_aix_si" 9597 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 9598 (unspec:SI [(const_int 0)] UNSPEC_TOC)) 9599 (use (reg:SI 2))])] 9600 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT" 9601 "* 9602{ 9603 char buf[30]; 9604 extern int need_toc_init; 9605 need_toc_init = 1; 9606 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1); 9607 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 9608 operands[2] = gen_rtx_REG (Pmode, 2); 9609 return \"lwz %0,%1(%2)\"; 9610}" 9611 [(set_attr "type" "load") 9612 (set_attr "update" "no") 9613 (set_attr "indexed" "no")]) 9614 9615(define_insn "load_toc_aix_di" 9616 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 9617 (unspec:DI [(const_int 0)] UNSPEC_TOC)) 9618 (use (reg:DI 2))])] 9619 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT" 9620 "* 9621{ 9622 char buf[30]; 9623 extern int need_toc_init; 9624 need_toc_init = 1; 9625#ifdef TARGET_RELOCATABLE 9626 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 9627 !TARGET_MINIMAL_TOC || TARGET_RELOCATABLE); 9628#else 9629 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1); 9630#endif 9631 if (TARGET_ELF) 9632 strcat (buf, \"@toc\"); 9633 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 9634 operands[2] = gen_rtx_REG (Pmode, 2); 9635 return \"ld %0,%1(%2)\"; 9636}" 9637 [(set_attr "type" "load") 9638 (set_attr "update" "no") 9639 (set_attr "indexed" "no")]) 9640 9641(define_insn "load_toc_v4_pic_si" 9642 [(set (reg:SI LR_REGNO) 9643 (unspec:SI [(const_int 0)] UNSPEC_TOC))] 9644 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT" 9645 "bl _GLOBAL_OFFSET_TABLE_@local-4" 9646 [(set_attr "type" "branch") 9647 (set_attr "length" "4")]) 9648 9649(define_expand "load_toc_v4_PIC_1" 9650 [(parallel [(set (reg:SI LR_REGNO) 9651 (match_operand:SI 0 "immediate_operand" "s")) 9652 (use (unspec [(match_dup 0)] UNSPEC_TOC))])] 9653 "TARGET_ELF && DEFAULT_ABI == ABI_V4 9654 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 9655 "") 9656 9657(define_insn "load_toc_v4_PIC_1_normal" 9658 [(set (reg:SI LR_REGNO) 9659 (match_operand:SI 0 "immediate_operand" "s")) 9660 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 9661 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 9662 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 9663 "bcl 20,31,%0\\n%0:" 9664 [(set_attr "type" "branch") 9665 (set_attr "length" "4") 9666 (set_attr "cannot_copy" "yes")]) 9667 9668(define_insn "load_toc_v4_PIC_1_476" 9669 [(set (reg:SI LR_REGNO) 9670 (match_operand:SI 0 "immediate_operand" "s")) 9671 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 9672 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 9673 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 9674 "* 9675{ 9676 char name[32]; 9677 static char templ[32]; 9678 9679 get_ppc476_thunk_name (name); 9680 sprintf (templ, \"bl %s\\n%%0:\", name); 9681 return templ; 9682}" 9683 [(set_attr "type" "branch") 9684 (set_attr "length" "4") 9685 (set_attr "cannot_copy" "yes")]) 9686 9687(define_expand "load_toc_v4_PIC_1b" 9688 [(parallel [(set (reg:SI LR_REGNO) 9689 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 9690 (label_ref (match_operand 1 "" ""))] 9691 UNSPEC_TOCPTR)) 9692 (match_dup 1)])] 9693 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 9694 "") 9695 9696(define_insn "load_toc_v4_PIC_1b_normal" 9697 [(set (reg:SI LR_REGNO) 9698 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 9699 (label_ref (match_operand 1 "" ""))] 9700 UNSPEC_TOCPTR)) 9701 (match_dup 1)] 9702 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 9703 "bcl 20,31,$+8\;.long %0-$" 9704 [(set_attr "type" "branch") 9705 (set_attr "length" "8")]) 9706 9707(define_insn "load_toc_v4_PIC_1b_476" 9708 [(set (reg:SI LR_REGNO) 9709 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 9710 (label_ref (match_operand 1 "" ""))] 9711 UNSPEC_TOCPTR)) 9712 (match_dup 1)] 9713 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 9714 "* 9715{ 9716 char name[32]; 9717 static char templ[32]; 9718 9719 get_ppc476_thunk_name (name); 9720 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name); 9721 return templ; 9722}" 9723 [(set_attr "type" "branch") 9724 (set_attr "length" "16")]) 9725 9726(define_insn "load_toc_v4_PIC_2" 9727 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 9728 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") 9729 (minus:SI (match_operand:SI 2 "immediate_operand" "s") 9730 (match_operand:SI 3 "immediate_operand" "s")))))] 9731 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 9732 "lwz %0,%2-%3(%1)" 9733 [(set_attr "type" "load")]) 9734 9735(define_insn "load_toc_v4_PIC_3b" 9736 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 9737 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") 9738 (high:SI 9739 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 9740 (match_operand:SI 3 "symbol_ref_operand" "s")))))] 9741 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 9742 "addis %0,%1,%2-%3@ha") 9743 9744(define_insn "load_toc_v4_PIC_3c" 9745 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 9746 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 9747 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 9748 (match_operand:SI 3 "symbol_ref_operand" "s"))))] 9749 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 9750 "addi %0,%1,%2-%3@l") 9751 9752;; If the TOC is shared over a translation unit, as happens with all 9753;; the kinds of PIC that we support, we need to restore the TOC 9754;; pointer only when jumping over units of translation. 9755;; On Darwin, we need to reload the picbase. 9756 9757(define_expand "builtin_setjmp_receiver" 9758 [(use (label_ref (match_operand 0 "" "")))] 9759 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1) 9760 || (TARGET_TOC && TARGET_MINIMAL_TOC) 9761 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)" 9762 " 9763{ 9764#if TARGET_MACHO 9765 if (DEFAULT_ABI == ABI_DARWIN) 9766 { 9767 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); 9768 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 9769 rtx tmplabrtx; 9770 char tmplab[20]; 9771 9772 crtl->uses_pic_offset_table = 1; 9773 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\", 9774 CODE_LABEL_NUMBER (operands[0])); 9775 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); 9776 9777 emit_insn (gen_load_macho_picbase (tmplabrtx)); 9778 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); 9779 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx)); 9780 } 9781 else 9782#endif 9783 rs6000_emit_load_toc_table (FALSE); 9784 DONE; 9785}") 9786 9787;; Largetoc support 9788(define_insn "*largetoc_high" 9789 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 9790 (high:DI 9791 (unspec [(match_operand:DI 1 "" "") 9792 (match_operand:DI 2 "gpc_reg_operand" "b")] 9793 UNSPEC_TOCREL)))] 9794 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9795 "addis %0,%2,%1@toc@ha") 9796 9797(define_insn "*largetoc_high_aix<mode>" 9798 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 9799 (high:P 9800 (unspec [(match_operand:P 1 "" "") 9801 (match_operand:P 2 "gpc_reg_operand" "b")] 9802 UNSPEC_TOCREL)))] 9803 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 9804 "addis %0,%1@u(%2)") 9805 9806(define_insn "*largetoc_high_plus" 9807 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 9808 (high:DI 9809 (plus:DI 9810 (unspec [(match_operand:DI 1 "" "") 9811 (match_operand:DI 2 "gpc_reg_operand" "b")] 9812 UNSPEC_TOCREL) 9813 (match_operand:DI 3 "add_cint_operand" "n"))))] 9814 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9815 "addis %0,%2,%1+%3@toc@ha") 9816 9817(define_insn "*largetoc_high_plus_aix<mode>" 9818 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 9819 (high:P 9820 (plus:P 9821 (unspec [(match_operand:P 1 "" "") 9822 (match_operand:P 2 "gpc_reg_operand" "b")] 9823 UNSPEC_TOCREL) 9824 (match_operand:P 3 "add_cint_operand" "n"))))] 9825 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 9826 "addis %0,%1+%3@u(%2)") 9827 9828(define_insn "*largetoc_low" 9829 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 9830 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 9831 (match_operand:DI 2 "" "")))] 9832 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9833 "addi %0,%1,%2@l") 9834 9835(define_insn "*largetoc_low_aix<mode>" 9836 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9837 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 9838 (match_operand:P 2 "" "")))] 9839 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 9840 "la %0,%2@l(%1)") 9841 9842(define_insn_and_split "*tocref<mode>" 9843 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9844 (match_operand:P 1 "small_toc_ref" "R"))] 9845 "TARGET_TOC" 9846 "la %0,%a1" 9847 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed" 9848 [(set (match_dup 0) (high:P (match_dup 1))) 9849 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))]) 9850 9851;; Elf specific ways of loading addresses for non-PIC code. 9852;; The output of this could be r0, but we make a very strong 9853;; preference for a base register because it will usually 9854;; be needed there. 9855(define_insn "elf_high" 9856 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") 9857 (high:SI (match_operand 1 "" "")))] 9858 "TARGET_ELF && ! TARGET_64BIT" 9859 "lis %0,%1@ha") 9860 9861(define_insn "elf_low" 9862 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 9863 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 9864 (match_operand 2 "" "")))] 9865 "TARGET_ELF && ! TARGET_64BIT" 9866 "la %0,%2@l(%1)") 9867 9868;; Call and call_value insns 9869(define_expand "call" 9870 [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) 9871 (match_operand 1 "" "")) 9872 (use (match_operand 2 "" "")) 9873 (clobber (reg:SI LR_REGNO))])] 9874 "" 9875 " 9876{ 9877#if TARGET_MACHO 9878 if (MACHOPIC_INDIRECT) 9879 operands[0] = machopic_indirect_call_target (operands[0]); 9880#endif 9881 9882 gcc_assert (GET_CODE (operands[0]) == MEM); 9883 gcc_assert (GET_CODE (operands[1]) == CONST_INT); 9884 9885 operands[0] = XEXP (operands[0], 0); 9886 9887 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 9888 { 9889 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]); 9890 DONE; 9891 } 9892 9893 if (GET_CODE (operands[0]) != SYMBOL_REF 9894 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0)) 9895 { 9896 if (INTVAL (operands[2]) & CALL_LONG) 9897 operands[0] = rs6000_longcall_ref (operands[0]); 9898 9899 switch (DEFAULT_ABI) 9900 { 9901 case ABI_V4: 9902 case ABI_DARWIN: 9903 operands[0] = force_reg (Pmode, operands[0]); 9904 break; 9905 9906 default: 9907 gcc_unreachable (); 9908 } 9909 } 9910}") 9911 9912(define_expand "call_value" 9913 [(parallel [(set (match_operand 0 "" "") 9914 (call (mem:SI (match_operand 1 "address_operand" "")) 9915 (match_operand 2 "" ""))) 9916 (use (match_operand 3 "" "")) 9917 (clobber (reg:SI LR_REGNO))])] 9918 "" 9919 " 9920{ 9921#if TARGET_MACHO 9922 if (MACHOPIC_INDIRECT) 9923 operands[1] = machopic_indirect_call_target (operands[1]); 9924#endif 9925 9926 gcc_assert (GET_CODE (operands[1]) == MEM); 9927 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 9928 9929 operands[1] = XEXP (operands[1], 0); 9930 9931 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 9932 { 9933 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]); 9934 DONE; 9935 } 9936 9937 if (GET_CODE (operands[1]) != SYMBOL_REF 9938 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0)) 9939 { 9940 if (INTVAL (operands[3]) & CALL_LONG) 9941 operands[1] = rs6000_longcall_ref (operands[1]); 9942 9943 switch (DEFAULT_ABI) 9944 { 9945 case ABI_V4: 9946 case ABI_DARWIN: 9947 operands[1] = force_reg (Pmode, operands[1]); 9948 break; 9949 9950 default: 9951 gcc_unreachable (); 9952 } 9953 } 9954}") 9955 9956;; Call to function in current module. No TOC pointer reload needed. 9957;; Operand2 is nonzero if we are using the V.4 calling sequence and 9958;; either the function was not prototyped, or it was prototyped as a 9959;; variable argument function. It is > 0 if FP registers were passed 9960;; and < 0 if they were not. 9961 9962(define_insn "*call_local32" 9963 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) 9964 (match_operand 1 "" "g,g")) 9965 (use (match_operand:SI 2 "immediate_operand" "O,n")) 9966 (clobber (reg:SI LR_REGNO))] 9967 "(INTVAL (operands[2]) & CALL_LONG) == 0" 9968 "* 9969{ 9970 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 9971 output_asm_insn (\"crxor 6,6,6\", operands); 9972 9973 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 9974 output_asm_insn (\"creqv 6,6,6\", operands); 9975 9976 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; 9977}" 9978 [(set_attr "type" "branch") 9979 (set_attr "length" "4,8")]) 9980 9981(define_insn "*call_local64" 9982 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) 9983 (match_operand 1 "" "g,g")) 9984 (use (match_operand:SI 2 "immediate_operand" "O,n")) 9985 (clobber (reg:SI LR_REGNO))] 9986 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" 9987 "* 9988{ 9989 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 9990 output_asm_insn (\"crxor 6,6,6\", operands); 9991 9992 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 9993 output_asm_insn (\"creqv 6,6,6\", operands); 9994 9995 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; 9996}" 9997 [(set_attr "type" "branch") 9998 (set_attr "length" "4,8")]) 9999 10000(define_insn "*call_value_local32" 10001 [(set (match_operand 0 "" "") 10002 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) 10003 (match_operand 2 "" "g,g"))) 10004 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10005 (clobber (reg:SI LR_REGNO))] 10006 "(INTVAL (operands[3]) & CALL_LONG) == 0" 10007 "* 10008{ 10009 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10010 output_asm_insn (\"crxor 6,6,6\", operands); 10011 10012 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10013 output_asm_insn (\"creqv 6,6,6\", operands); 10014 10015 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; 10016}" 10017 [(set_attr "type" "branch") 10018 (set_attr "length" "4,8")]) 10019 10020 10021(define_insn "*call_value_local64" 10022 [(set (match_operand 0 "" "") 10023 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) 10024 (match_operand 2 "" "g,g"))) 10025 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10026 (clobber (reg:SI LR_REGNO))] 10027 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" 10028 "* 10029{ 10030 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10031 output_asm_insn (\"crxor 6,6,6\", operands); 10032 10033 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10034 output_asm_insn (\"creqv 6,6,6\", operands); 10035 10036 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; 10037}" 10038 [(set_attr "type" "branch") 10039 (set_attr "length" "4,8")]) 10040 10041 10042;; A function pointer under System V is just a normal pointer 10043;; operands[0] is the function pointer 10044;; operands[1] is the stack size to clean up 10045;; operands[2] is the value FUNCTION_ARG returns for the VOID argument 10046;; which indicates how to set cr1 10047 10048(define_insn "*call_indirect_nonlocal_sysv<mode>" 10049 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l")) 10050 (match_operand 1 "" "g,g,g,g")) 10051 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) 10052 (clobber (reg:SI LR_REGNO))] 10053 "DEFAULT_ABI == ABI_V4 10054 || DEFAULT_ABI == ABI_DARWIN" 10055{ 10056 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10057 output_asm_insn ("crxor 6,6,6", operands); 10058 10059 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10060 output_asm_insn ("creqv 6,6,6", operands); 10061 10062 return "b%T0l"; 10063} 10064 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") 10065 (set_attr "length" "4,4,8,8")]) 10066 10067(define_insn_and_split "*call_nonlocal_sysv<mode>" 10068 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 10069 (match_operand 1 "" "g,g")) 10070 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10071 (clobber (reg:SI LR_REGNO))] 10072 "(DEFAULT_ABI == ABI_DARWIN 10073 || (DEFAULT_ABI == ABI_V4 10074 && (INTVAL (operands[2]) & CALL_LONG) == 0))" 10075{ 10076 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10077 output_asm_insn ("crxor 6,6,6", operands); 10078 10079 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10080 output_asm_insn ("creqv 6,6,6", operands); 10081 10082#if TARGET_MACHO 10083 return output_call(insn, operands, 0, 2); 10084#else 10085 if (DEFAULT_ABI == ABI_V4 && flag_pic) 10086 { 10087 gcc_assert (!TARGET_SECURE_PLT); 10088 return "bl %z0@plt"; 10089 } 10090 else 10091 return "bl %z0"; 10092#endif 10093} 10094 "DEFAULT_ABI == ABI_V4 10095 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) 10096 && (INTVAL (operands[2]) & CALL_LONG) == 0" 10097 [(parallel [(call (mem:SI (match_dup 0)) 10098 (match_dup 1)) 10099 (use (match_dup 2)) 10100 (use (match_dup 3)) 10101 (clobber (reg:SI LR_REGNO))])] 10102{ 10103 operands[3] = pic_offset_table_rtx; 10104} 10105 [(set_attr "type" "branch,branch") 10106 (set_attr "length" "4,8")]) 10107 10108(define_insn "*call_nonlocal_sysv_secure<mode>" 10109 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 10110 (match_operand 1 "" "g,g")) 10111 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10112 (use (match_operand:SI 3 "register_operand" "r,r")) 10113 (clobber (reg:SI LR_REGNO))] 10114 "(DEFAULT_ABI == ABI_V4 10115 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) 10116 && (INTVAL (operands[2]) & CALL_LONG) == 0)" 10117{ 10118 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10119 output_asm_insn ("crxor 6,6,6", operands); 10120 10121 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10122 output_asm_insn ("creqv 6,6,6", operands); 10123 10124 if (flag_pic == 2) 10125 /* The magic 32768 offset here and in the other sysv call insns 10126 corresponds to the offset of r30 in .got2, as given by LCTOC1. 10127 See sysv4.h:toc_section. */ 10128 return "bl %z0+32768@plt"; 10129 else 10130 return "bl %z0@plt"; 10131} 10132 [(set_attr "type" "branch,branch") 10133 (set_attr "length" "4,8")]) 10134 10135(define_insn "*call_value_indirect_nonlocal_sysv<mode>" 10136 [(set (match_operand 0 "" "") 10137 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l")) 10138 (match_operand 2 "" "g,g,g,g"))) 10139 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) 10140 (clobber (reg:SI LR_REGNO))] 10141 "DEFAULT_ABI == ABI_V4 10142 || DEFAULT_ABI == ABI_DARWIN" 10143{ 10144 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10145 output_asm_insn ("crxor 6,6,6", operands); 10146 10147 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10148 output_asm_insn ("creqv 6,6,6", operands); 10149 10150 return "b%T1l"; 10151} 10152 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") 10153 (set_attr "length" "4,4,8,8")]) 10154 10155(define_insn_and_split "*call_value_nonlocal_sysv<mode>" 10156 [(set (match_operand 0 "" "") 10157 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) 10158 (match_operand 2 "" "g,g"))) 10159 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10160 (clobber (reg:SI LR_REGNO))] 10161 "(DEFAULT_ABI == ABI_DARWIN 10162 || (DEFAULT_ABI == ABI_V4 10163 && (INTVAL (operands[3]) & CALL_LONG) == 0))" 10164{ 10165 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10166 output_asm_insn ("crxor 6,6,6", operands); 10167 10168 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10169 output_asm_insn ("creqv 6,6,6", operands); 10170 10171#if TARGET_MACHO 10172 return output_call(insn, operands, 1, 3); 10173#else 10174 if (DEFAULT_ABI == ABI_V4 && flag_pic) 10175 { 10176 gcc_assert (!TARGET_SECURE_PLT); 10177 return "bl %z1@plt"; 10178 } 10179 else 10180 return "bl %z1"; 10181#endif 10182} 10183 "DEFAULT_ABI == ABI_V4 10184 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) 10185 && (INTVAL (operands[3]) & CALL_LONG) == 0" 10186 [(parallel [(set (match_dup 0) 10187 (call (mem:SI (match_dup 1)) 10188 (match_dup 2))) 10189 (use (match_dup 3)) 10190 (use (match_dup 4)) 10191 (clobber (reg:SI LR_REGNO))])] 10192{ 10193 operands[4] = pic_offset_table_rtx; 10194} 10195 [(set_attr "type" "branch,branch") 10196 (set_attr "length" "4,8")]) 10197 10198(define_insn "*call_value_nonlocal_sysv_secure<mode>" 10199 [(set (match_operand 0 "" "") 10200 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) 10201 (match_operand 2 "" "g,g"))) 10202 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10203 (use (match_operand:SI 4 "register_operand" "r,r")) 10204 (clobber (reg:SI LR_REGNO))] 10205 "(DEFAULT_ABI == ABI_V4 10206 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) 10207 && (INTVAL (operands[3]) & CALL_LONG) == 0)" 10208{ 10209 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10210 output_asm_insn ("crxor 6,6,6", operands); 10211 10212 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10213 output_asm_insn ("creqv 6,6,6", operands); 10214 10215 if (flag_pic == 2) 10216 return "bl %z1+32768@plt"; 10217 else 10218 return "bl %z1@plt"; 10219} 10220 [(set_attr "type" "branch,branch") 10221 (set_attr "length" "4,8")]) 10222 10223 10224;; Call to AIX abi function in the same module. 10225 10226(define_insn "*call_local_aix<mode>" 10227 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s")) 10228 (match_operand 1 "" "g")) 10229 (clobber (reg:P LR_REGNO))] 10230 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10231 "bl %z0" 10232 [(set_attr "type" "branch") 10233 (set_attr "length" "4")]) 10234 10235(define_insn "*call_value_local_aix<mode>" 10236 [(set (match_operand 0 "" "") 10237 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s")) 10238 (match_operand 2 "" "g"))) 10239 (clobber (reg:P LR_REGNO))] 10240 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10241 "bl %z1" 10242 [(set_attr "type" "branch") 10243 (set_attr "length" "4")]) 10244 10245;; Call to AIX abi function which may be in another module. 10246;; Restore the TOC pointer (r2) after the call. 10247 10248(define_insn "*call_nonlocal_aix<mode>" 10249 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s")) 10250 (match_operand 1 "" "g")) 10251 (clobber (reg:P LR_REGNO))] 10252 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10253 "bl %z0\;nop" 10254 [(set_attr "type" "branch") 10255 (set_attr "length" "8")]) 10256 10257(define_insn "*call_value_nonlocal_aix<mode>" 10258 [(set (match_operand 0 "" "") 10259 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 10260 (match_operand 2 "" "g"))) 10261 (clobber (reg:P LR_REGNO))] 10262 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10263 "bl %z1\;nop" 10264 [(set_attr "type" "branch") 10265 (set_attr "length" "8")]) 10266 10267;; Call to indirect functions with the AIX abi using a 3 word descriptor. 10268;; Operand0 is the addresss of the function to call 10269;; Operand2 is the location in the function descriptor to load r2 from 10270;; Operand3 is the offset of the stack location holding the current TOC pointer 10271 10272(define_insn "*call_indirect_aix<mode>" 10273 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) 10274 (match_operand 1 "" "g,g")) 10275 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>")) 10276 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10277 (clobber (reg:P LR_REGNO))] 10278 "DEFAULT_ABI == ABI_AIX" 10279 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)" 10280 [(set_attr "type" "jmpreg") 10281 (set_attr "length" "12")]) 10282 10283(define_insn "*call_value_indirect_aix<mode>" 10284 [(set (match_operand 0 "" "") 10285 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) 10286 (match_operand 2 "" "g,g"))) 10287 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) 10288 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10289 (clobber (reg:P LR_REGNO))] 10290 "DEFAULT_ABI == ABI_AIX" 10291 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)" 10292 [(set_attr "type" "jmpreg") 10293 (set_attr "length" "12")]) 10294 10295;; Call to indirect functions with the ELFv2 ABI. 10296;; Operand0 is the addresss of the function to call 10297;; Operand2 is the offset of the stack location holding the current TOC pointer 10298 10299(define_insn "*call_indirect_elfv2<mode>" 10300 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) 10301 (match_operand 1 "" "g,g")) 10302 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10303 (clobber (reg:P LR_REGNO))] 10304 "DEFAULT_ABI == ABI_ELFv2" 10305 "b%T0l\;<ptrload> 2,%2(1)" 10306 [(set_attr "type" "jmpreg") 10307 (set_attr "length" "8")]) 10308 10309(define_insn "*call_value_indirect_elfv2<mode>" 10310 [(set (match_operand 0 "" "") 10311 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) 10312 (match_operand 2 "" "g,g"))) 10313 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10314 (clobber (reg:P LR_REGNO))] 10315 "DEFAULT_ABI == ABI_ELFv2" 10316 "b%T1l\;<ptrload> 2,%3(1)" 10317 [(set_attr "type" "jmpreg") 10318 (set_attr "length" "8")]) 10319 10320 10321;; Call subroutine returning any type. 10322(define_expand "untyped_call" 10323 [(parallel [(call (match_operand 0 "" "") 10324 (const_int 0)) 10325 (match_operand 1 "" "") 10326 (match_operand 2 "" "")])] 10327 "" 10328 " 10329{ 10330 int i; 10331 10332 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); 10333 10334 for (i = 0; i < XVECLEN (operands[2], 0); i++) 10335 { 10336 rtx set = XVECEXP (operands[2], 0, i); 10337 emit_move_insn (SET_DEST (set), SET_SRC (set)); 10338 } 10339 10340 /* The optimizer does not know that the call sets the function value 10341 registers we stored in the result block. We avoid problems by 10342 claiming that all hard registers are used and clobbered at this 10343 point. */ 10344 emit_insn (gen_blockage ()); 10345 10346 DONE; 10347}") 10348 10349;; sibling call patterns 10350(define_expand "sibcall" 10351 [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) 10352 (match_operand 1 "" "")) 10353 (use (match_operand 2 "" "")) 10354 (use (reg:SI LR_REGNO)) 10355 (simple_return)])] 10356 "" 10357 " 10358{ 10359#if TARGET_MACHO 10360 if (MACHOPIC_INDIRECT) 10361 operands[0] = machopic_indirect_call_target (operands[0]); 10362#endif 10363 10364 gcc_assert (GET_CODE (operands[0]) == MEM); 10365 gcc_assert (GET_CODE (operands[1]) == CONST_INT); 10366 10367 operands[0] = XEXP (operands[0], 0); 10368 10369 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10370 { 10371 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); 10372 DONE; 10373 } 10374}") 10375 10376(define_expand "sibcall_value" 10377 [(parallel [(set (match_operand 0 "register_operand" "") 10378 (call (mem:SI (match_operand 1 "address_operand" "")) 10379 (match_operand 2 "" ""))) 10380 (use (match_operand 3 "" "")) 10381 (use (reg:SI LR_REGNO)) 10382 (simple_return)])] 10383 "" 10384 " 10385{ 10386#if TARGET_MACHO 10387 if (MACHOPIC_INDIRECT) 10388 operands[1] = machopic_indirect_call_target (operands[1]); 10389#endif 10390 10391 gcc_assert (GET_CODE (operands[1]) == MEM); 10392 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 10393 10394 operands[1] = XEXP (operands[1], 0); 10395 10396 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10397 { 10398 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]); 10399 DONE; 10400 } 10401}") 10402 10403;; this and similar patterns must be marked as using LR, otherwise 10404;; dataflow will try to delete the store into it. This is true 10405;; even when the actual reg to jump to is in CTR, when LR was 10406;; saved and restored around the PIC-setting BCL. 10407(define_insn "*sibcall_local32" 10408 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) 10409 (match_operand 1 "" "g,g")) 10410 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10411 (use (reg:SI LR_REGNO)) 10412 (simple_return)] 10413 "(INTVAL (operands[2]) & CALL_LONG) == 0" 10414 "* 10415{ 10416 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10417 output_asm_insn (\"crxor 6,6,6\", operands); 10418 10419 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10420 output_asm_insn (\"creqv 6,6,6\", operands); 10421 10422 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; 10423}" 10424 [(set_attr "type" "branch") 10425 (set_attr "length" "4,8")]) 10426 10427(define_insn "*sibcall_local64" 10428 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) 10429 (match_operand 1 "" "g,g")) 10430 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10431 (use (reg:SI LR_REGNO)) 10432 (simple_return)] 10433 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" 10434 "* 10435{ 10436 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10437 output_asm_insn (\"crxor 6,6,6\", operands); 10438 10439 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10440 output_asm_insn (\"creqv 6,6,6\", operands); 10441 10442 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; 10443}" 10444 [(set_attr "type" "branch") 10445 (set_attr "length" "4,8")]) 10446 10447(define_insn "*sibcall_value_local32" 10448 [(set (match_operand 0 "" "") 10449 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) 10450 (match_operand 2 "" "g,g"))) 10451 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10452 (use (reg:SI LR_REGNO)) 10453 (simple_return)] 10454 "(INTVAL (operands[3]) & CALL_LONG) == 0" 10455 "* 10456{ 10457 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10458 output_asm_insn (\"crxor 6,6,6\", operands); 10459 10460 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10461 output_asm_insn (\"creqv 6,6,6\", operands); 10462 10463 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; 10464}" 10465 [(set_attr "type" "branch") 10466 (set_attr "length" "4,8")]) 10467 10468(define_insn "*sibcall_value_local64" 10469 [(set (match_operand 0 "" "") 10470 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) 10471 (match_operand 2 "" "g,g"))) 10472 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10473 (use (reg:SI LR_REGNO)) 10474 (simple_return)] 10475 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" 10476 "* 10477{ 10478 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10479 output_asm_insn (\"crxor 6,6,6\", operands); 10480 10481 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10482 output_asm_insn (\"creqv 6,6,6\", operands); 10483 10484 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; 10485}" 10486 [(set_attr "type" "branch") 10487 (set_attr "length" "4,8")]) 10488 10489(define_insn "*sibcall_nonlocal_sysv<mode>" 10490 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c")) 10491 (match_operand 1 "" "")) 10492 (use (match_operand 2 "immediate_operand" "O,n,O,n")) 10493 (use (reg:SI LR_REGNO)) 10494 (simple_return)] 10495 "(DEFAULT_ABI == ABI_DARWIN 10496 || DEFAULT_ABI == ABI_V4) 10497 && (INTVAL (operands[2]) & CALL_LONG) == 0" 10498 "* 10499{ 10500 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10501 output_asm_insn (\"crxor 6,6,6\", operands); 10502 10503 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10504 output_asm_insn (\"creqv 6,6,6\", operands); 10505 10506 if (which_alternative >= 2) 10507 return \"b%T0\"; 10508 else if (DEFAULT_ABI == ABI_V4 && flag_pic) 10509 { 10510 gcc_assert (!TARGET_SECURE_PLT); 10511 return \"b %z0@plt\"; 10512 } 10513 else 10514 return \"b %z0\"; 10515}" 10516 [(set_attr "type" "branch") 10517 (set_attr "length" "4,8,4,8")]) 10518 10519(define_insn "*sibcall_value_nonlocal_sysv<mode>" 10520 [(set (match_operand 0 "" "") 10521 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c")) 10522 (match_operand 2 "" ""))) 10523 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) 10524 (use (reg:SI LR_REGNO)) 10525 (simple_return)] 10526 "(DEFAULT_ABI == ABI_DARWIN 10527 || DEFAULT_ABI == ABI_V4) 10528 && (INTVAL (operands[3]) & CALL_LONG) == 0" 10529 "* 10530{ 10531 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10532 output_asm_insn (\"crxor 6,6,6\", operands); 10533 10534 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10535 output_asm_insn (\"creqv 6,6,6\", operands); 10536 10537 if (which_alternative >= 2) 10538 return \"b%T1\"; 10539 else if (DEFAULT_ABI == ABI_V4 && flag_pic) 10540 { 10541 gcc_assert (!TARGET_SECURE_PLT); 10542 return \"b %z1@plt\"; 10543 } 10544 else 10545 return \"b %z1\"; 10546}" 10547 [(set_attr "type" "branch") 10548 (set_attr "length" "4,8,4,8")]) 10549 10550;; AIX ABI sibling call patterns. 10551 10552(define_insn "*sibcall_aix<mode>" 10553 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) 10554 (match_operand 1 "" "g,g")) 10555 (simple_return)] 10556 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10557 "@ 10558 b %z0 10559 b%T0" 10560 [(set_attr "type" "branch") 10561 (set_attr "length" "4")]) 10562 10563(define_insn "*sibcall_value_aix<mode>" 10564 [(set (match_operand 0 "" "") 10565 (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) 10566 (match_operand 2 "" "g,g"))) 10567 (simple_return)] 10568 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10569 "@ 10570 b %z1 10571 b%T1" 10572 [(set_attr "type" "branch") 10573 (set_attr "length" "4")]) 10574 10575(define_expand "sibcall_epilogue" 10576 [(use (const_int 0))] 10577 "" 10578{ 10579 if (!TARGET_SCHED_PROLOG) 10580 emit_insn (gen_blockage ()); 10581 rs6000_emit_epilogue (TRUE); 10582 DONE; 10583}) 10584 10585;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 10586;; all of memory. This blocks insns from being moved across this point. 10587 10588(define_insn "blockage" 10589 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] 10590 "" 10591 "") 10592 10593(define_expand "probe_stack_address" 10594 [(use (match_operand 0 "address_operand"))] 10595 "" 10596{ 10597 operands[0] = gen_rtx_MEM (Pmode, operands[0]); 10598 MEM_VOLATILE_P (operands[0]) = 1; 10599 10600 if (TARGET_64BIT) 10601 emit_insn (gen_probe_stack_di (operands[0])); 10602 else 10603 emit_insn (gen_probe_stack_si (operands[0])); 10604 DONE; 10605}) 10606 10607(define_insn "probe_stack_<mode>" 10608 [(set (match_operand:P 0 "memory_operand" "=m") 10609 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))] 10610 "" 10611{ 10612 operands[1] = gen_rtx_REG (Pmode, 0); 10613 return "st<wd>%U0%X0 %1,%0"; 10614} 10615 [(set_attr "type" "store") 10616 (set (attr "update") 10617 (if_then_else (match_operand 0 "update_address_mem") 10618 (const_string "yes") 10619 (const_string "no"))) 10620 (set (attr "indexed") 10621 (if_then_else (match_operand 0 "indexed_address_mem") 10622 (const_string "yes") 10623 (const_string "no"))) 10624 (set_attr "length" "4")]) 10625 10626(define_insn "probe_stack_range<P:mode>" 10627 [(set (match_operand:P 0 "register_operand" "=r") 10628 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 10629 (match_operand:P 2 "register_operand" "r")] 10630 UNSPECV_PROBE_STACK_RANGE))] 10631 "" 10632 "* return output_probe_stack_range (operands[0], operands[2]);" 10633 [(set_attr "type" "three")]) 10634 10635;; Compare insns are next. Note that the RS/6000 has two types of compares, 10636;; signed & unsigned, and one type of branch. 10637;; 10638;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc 10639;; insns, and branches. 10640 10641(define_expand "cbranch<mode>4" 10642 [(use (match_operator 0 "rs6000_cbranch_operator" 10643 [(match_operand:GPR 1 "gpc_reg_operand" "") 10644 (match_operand:GPR 2 "reg_or_short_operand" "")])) 10645 (use (match_operand 3 ""))] 10646 "" 10647 " 10648{ 10649 /* Take care of the possibility that operands[2] might be negative but 10650 this might be a logical operation. That insn doesn't exist. */ 10651 if (GET_CODE (operands[2]) == CONST_INT 10652 && INTVAL (operands[2]) < 0) 10653 { 10654 operands[2] = force_reg (<MODE>mode, operands[2]); 10655 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]), 10656 GET_MODE (operands[0]), 10657 operands[1], operands[2]); 10658 } 10659 10660 rs6000_emit_cbranch (<MODE>mode, operands); 10661 DONE; 10662}") 10663 10664(define_expand "cbranch<mode>4" 10665 [(use (match_operator 0 "rs6000_cbranch_operator" 10666 [(match_operand:FP 1 "gpc_reg_operand" "") 10667 (match_operand:FP 2 "gpc_reg_operand" "")])) 10668 (use (match_operand 3 ""))] 10669 "" 10670 " 10671{ 10672 rs6000_emit_cbranch (<MODE>mode, operands); 10673 DONE; 10674}") 10675 10676(define_expand "cstore<mode>4_signed" 10677 [(use (match_operator 1 "signed_comparison_operator" 10678 [(match_operand:P 2 "gpc_reg_operand") 10679 (match_operand:P 3 "gpc_reg_operand")])) 10680 (clobber (match_operand:P 0 "gpc_reg_operand"))] 10681 "" 10682{ 10683 enum rtx_code cond_code = GET_CODE (operands[1]); 10684 10685 rtx op0 = operands[0]; 10686 rtx op1 = operands[2]; 10687 rtx op2 = operands[3]; 10688 10689 if (cond_code == GE || cond_code == LT) 10690 { 10691 cond_code = swap_condition (cond_code); 10692 std::swap (op1, op2); 10693 } 10694 10695 rtx tmp1 = gen_reg_rtx (<MODE>mode); 10696 rtx tmp2 = gen_reg_rtx (<MODE>mode); 10697 rtx tmp3 = gen_reg_rtx (<MODE>mode); 10698 10699 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 10700 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh))); 10701 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh))); 10702 10703 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2)); 10704 10705 if (cond_code == LE) 10706 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2)); 10707 else 10708 { 10709 rtx tmp4 = gen_reg_rtx (<MODE>mode); 10710 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2)); 10711 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx)); 10712 } 10713 10714 DONE; 10715}) 10716 10717(define_expand "cstore<mode>4_unsigned" 10718 [(use (match_operator 1 "unsigned_comparison_operator" 10719 [(match_operand:P 2 "gpc_reg_operand") 10720 (match_operand:P 3 "reg_or_short_operand")])) 10721 (clobber (match_operand:P 0 "gpc_reg_operand"))] 10722 "" 10723{ 10724 enum rtx_code cond_code = GET_CODE (operands[1]); 10725 10726 rtx op0 = operands[0]; 10727 rtx op1 = operands[2]; 10728 rtx op2 = operands[3]; 10729 10730 if (cond_code == GEU || cond_code == LTU) 10731 { 10732 cond_code = swap_condition (cond_code); 10733 std::swap (op1, op2); 10734 } 10735 10736 if (!gpc_reg_operand (op1, <MODE>mode)) 10737 op1 = force_reg (<MODE>mode, op1); 10738 if (!reg_or_short_operand (op2, <MODE>mode)) 10739 op2 = force_reg (<MODE>mode, op2); 10740 10741 rtx tmp = gen_reg_rtx (<MODE>mode); 10742 rtx tmp2 = gen_reg_rtx (<MODE>mode); 10743 10744 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2)); 10745 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2)); 10746 10747 if (cond_code == LEU) 10748 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx)); 10749 else 10750 emit_insn (gen_neg<mode>2 (op0, tmp2)); 10751 10752 DONE; 10753}) 10754 10755(define_expand "cstore_si_as_di" 10756 [(use (match_operator 1 "unsigned_comparison_operator" 10757 [(match_operand:SI 2 "gpc_reg_operand") 10758 (match_operand:SI 3 "reg_or_short_operand")])) 10759 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 10760 "" 10761{ 10762 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0; 10763 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1])); 10764 10765 operands[2] = force_reg (SImode, operands[2]); 10766 operands[3] = force_reg (SImode, operands[3]); 10767 rtx op1 = gen_reg_rtx (DImode); 10768 rtx op2 = gen_reg_rtx (DImode); 10769 convert_move (op1, operands[2], uns_flag); 10770 convert_move (op2, operands[3], uns_flag); 10771 10772 if (cond_code == GT || cond_code == LE) 10773 { 10774 cond_code = swap_condition (cond_code); 10775 std::swap (op1, op2); 10776 } 10777 10778 rtx tmp = gen_reg_rtx (DImode); 10779 rtx tmp2 = gen_reg_rtx (DImode); 10780 emit_insn (gen_subdi3 (tmp, op1, op2)); 10781 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63))); 10782 10783 rtx tmp3; 10784 switch (cond_code) 10785 { 10786 default: 10787 gcc_unreachable (); 10788 case LT: 10789 tmp3 = tmp2; 10790 break; 10791 case GE: 10792 tmp3 = gen_reg_rtx (DImode); 10793 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx)); 10794 break; 10795 } 10796 10797 convert_move (operands[0], tmp3, 1); 10798 10799 DONE; 10800}) 10801 10802(define_expand "cstore<mode>4_signed_imm" 10803 [(use (match_operator 1 "signed_comparison_operator" 10804 [(match_operand:GPR 2 "gpc_reg_operand") 10805 (match_operand:GPR 3 "immediate_operand")])) 10806 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 10807 "" 10808{ 10809 bool invert = false; 10810 10811 enum rtx_code cond_code = GET_CODE (operands[1]); 10812 10813 rtx op0 = operands[0]; 10814 rtx op1 = operands[2]; 10815 HOST_WIDE_INT val = INTVAL (operands[3]); 10816 10817 if (cond_code == GE || cond_code == GT) 10818 { 10819 cond_code = reverse_condition (cond_code); 10820 invert = true; 10821 } 10822 10823 if (cond_code == LE) 10824 val++; 10825 10826 rtx tmp = gen_reg_rtx (<MODE>mode); 10827 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 10828 rtx x = gen_reg_rtx (<MODE>mode); 10829 if (val < 0) 10830 emit_insn (gen_and<mode>3 (x, op1, tmp)); 10831 else 10832 emit_insn (gen_ior<mode>3 (x, op1, tmp)); 10833 10834 if (invert) 10835 { 10836 rtx tmp = gen_reg_rtx (<MODE>mode); 10837 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 10838 x = tmp; 10839 } 10840 10841 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 10842 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 10843 10844 DONE; 10845}) 10846 10847(define_expand "cstore<mode>4_unsigned_imm" 10848 [(use (match_operator 1 "unsigned_comparison_operator" 10849 [(match_operand:GPR 2 "gpc_reg_operand") 10850 (match_operand:GPR 3 "immediate_operand")])) 10851 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 10852 "" 10853{ 10854 bool invert = false; 10855 10856 enum rtx_code cond_code = GET_CODE (operands[1]); 10857 10858 rtx op0 = operands[0]; 10859 rtx op1 = operands[2]; 10860 HOST_WIDE_INT val = INTVAL (operands[3]); 10861 10862 if (cond_code == GEU || cond_code == GTU) 10863 { 10864 cond_code = reverse_condition (cond_code); 10865 invert = true; 10866 } 10867 10868 if (cond_code == LEU) 10869 val++; 10870 10871 rtx tmp = gen_reg_rtx (<MODE>mode); 10872 rtx tmp2 = gen_reg_rtx (<MODE>mode); 10873 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 10874 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1)); 10875 rtx x = gen_reg_rtx (<MODE>mode); 10876 if (val < 0) 10877 emit_insn (gen_ior<mode>3 (x, tmp, tmp2)); 10878 else 10879 emit_insn (gen_and<mode>3 (x, tmp, tmp2)); 10880 10881 if (invert) 10882 { 10883 rtx tmp = gen_reg_rtx (<MODE>mode); 10884 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 10885 x = tmp; 10886 } 10887 10888 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 10889 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 10890 10891 DONE; 10892}) 10893 10894(define_expand "cstore<mode>4" 10895 [(use (match_operator 1 "rs6000_cbranch_operator" 10896 [(match_operand:GPR 2 "gpc_reg_operand") 10897 (match_operand:GPR 3 "reg_or_short_operand")])) 10898 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 10899 "" 10900{ 10901 /* Use ISEL if the user asked for it. */ 10902 if (TARGET_ISEL) 10903 rs6000_emit_sISEL (<MODE>mode, operands); 10904 10905 /* Expanding EQ and NE directly to some machine instructions does not help 10906 but does hurt combine. So don't. */ 10907 else if (GET_CODE (operands[1]) == EQ) 10908 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3])); 10909 else if (<MODE>mode == Pmode 10910 && GET_CODE (operands[1]) == NE) 10911 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3])); 10912 else if (GET_CODE (operands[1]) == NE) 10913 { 10914 rtx tmp = gen_reg_rtx (<MODE>mode); 10915 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3])); 10916 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); 10917 } 10918 10919 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu 10920 etc. combinations magically work out just right. */ 10921 else if (<MODE>mode == Pmode 10922 && unsigned_comparison_operator (operands[1], VOIDmode)) 10923 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1], 10924 operands[2], operands[3])); 10925 10926 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */ 10927 else if (<MODE>mode == SImode && Pmode == DImode) 10928 emit_insn (gen_cstore_si_as_di (operands[0], operands[1], 10929 operands[2], operands[3])); 10930 10931 /* For signed comparisons against a constant, we can do some simple 10932 bit-twiddling. */ 10933 else if (signed_comparison_operator (operands[1], VOIDmode) 10934 && CONST_INT_P (operands[3])) 10935 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1], 10936 operands[2], operands[3])); 10937 10938 /* And similarly for unsigned comparisons. */ 10939 else if (unsigned_comparison_operator (operands[1], VOIDmode) 10940 && CONST_INT_P (operands[3])) 10941 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1], 10942 operands[2], operands[3])); 10943 10944 /* We also do not want to use mfcr for signed comparisons. */ 10945 else if (<MODE>mode == Pmode 10946 && signed_comparison_operator (operands[1], VOIDmode)) 10947 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1], 10948 operands[2], operands[3])); 10949 10950 /* Everything else, use the mfcr brute force. */ 10951 else 10952 rs6000_emit_sCOND (<MODE>mode, operands); 10953 10954 DONE; 10955}) 10956 10957(define_expand "cstore<mode>4" 10958 [(use (match_operator 1 "rs6000_cbranch_operator" 10959 [(match_operand:FP 2 "gpc_reg_operand") 10960 (match_operand:FP 3 "gpc_reg_operand")])) 10961 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 10962 "" 10963{ 10964 rs6000_emit_sCOND (<MODE>mode, operands); 10965 DONE; 10966}) 10967 10968 10969(define_expand "stack_protect_set" 10970 [(match_operand 0 "memory_operand" "") 10971 (match_operand 1 "memory_operand" "")] 10972 "" 10973{ 10974#ifdef TARGET_THREAD_SSP_OFFSET 10975 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2); 10976 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); 10977 operands[1] = gen_rtx_MEM (Pmode, addr); 10978#endif 10979 if (TARGET_64BIT) 10980 emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); 10981 else 10982 emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); 10983 DONE; 10984}) 10985 10986(define_insn "stack_protect_setsi" 10987 [(set (match_operand:SI 0 "memory_operand" "=m") 10988 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 10989 (set (match_scratch:SI 2 "=&r") (const_int 0))] 10990 "TARGET_32BIT" 10991 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0" 10992 [(set_attr "type" "three") 10993 (set_attr "length" "12")]) 10994 10995(define_insn "stack_protect_setdi" 10996 [(set (match_operand:DI 0 "memory_operand" "=Y") 10997 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET)) 10998 (set (match_scratch:DI 2 "=&r") (const_int 0))] 10999 "TARGET_64BIT" 11000 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0" 11001 [(set_attr "type" "three") 11002 (set_attr "length" "12")]) 11003 11004(define_expand "stack_protect_test" 11005 [(match_operand 0 "memory_operand" "") 11006 (match_operand 1 "memory_operand" "") 11007 (match_operand 2 "" "")] 11008 "" 11009{ 11010 rtx test, op0, op1; 11011#ifdef TARGET_THREAD_SSP_OFFSET 11012 rtx tlsreg = gen_rtx_REG (Pmode, TARGET_64BIT ? 13 : 2); 11013 rtx addr = gen_rtx_PLUS (Pmode, tlsreg, GEN_INT (TARGET_THREAD_SSP_OFFSET)); 11014 operands[1] = gen_rtx_MEM (Pmode, addr); 11015#endif 11016 op0 = operands[0]; 11017 op1 = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, operands[1]), UNSPEC_SP_TEST); 11018 test = gen_rtx_EQ (VOIDmode, op0, op1); 11019 emit_jump_insn (gen_cbranchsi4 (test, op0, op1, operands[2])); 11020 DONE; 11021}) 11022 11023(define_insn "stack_protect_testsi" 11024 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 11025 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m") 11026 (match_operand:SI 2 "memory_operand" "m,m")] 11027 UNSPEC_SP_TEST)) 11028 (set (match_scratch:SI 4 "=r,r") (const_int 0)) 11029 (clobber (match_scratch:SI 3 "=&r,&r"))] 11030 "TARGET_32BIT" 11031 "@ 11032 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 11033 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0" 11034 [(set_attr "length" "16,20")]) 11035 11036(define_insn "stack_protect_testdi" 11037 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 11038 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y") 11039 (match_operand:DI 2 "memory_operand" "Y,Y")] 11040 UNSPEC_SP_TEST)) 11041 (set (match_scratch:DI 4 "=r,r") (const_int 0)) 11042 (clobber (match_scratch:DI 3 "=&r,&r"))] 11043 "TARGET_64BIT" 11044 "@ 11045 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 11046 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0" 11047 [(set_attr "length" "16,20")]) 11048 11049 11050;; Here are the actual compare insns. 11051(define_insn "*cmp<mode>_signed" 11052 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 11053 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r") 11054 (match_operand:GPR 2 "reg_or_short_operand" "rI")))] 11055 "" 11056 "cmp<wd>%I2 %0,%1,%2" 11057 [(set_attr "type" "cmp")]) 11058 11059(define_insn "*cmp<mode>_unsigned" 11060 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") 11061 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r") 11062 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))] 11063 "" 11064 "cmpl<wd>%I2 %0,%1,%2" 11065 [(set_attr "type" "cmp")]) 11066 11067;; If we are comparing a register for equality with a large constant, 11068;; we can do this with an XOR followed by a compare. But this is profitable 11069;; only if the large constant is only used for the comparison (and in this 11070;; case we already have a register to reuse as scratch). 11071;; 11072;; For 64-bit registers, we could only do so if the constant's bit 15 is clear: 11073;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available. 11074 11075(define_peephole2 11076 [(set (match_operand:SI 0 "register_operand") 11077 (match_operand:SI 1 "logical_const_operand" "")) 11078 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator" 11079 [(match_dup 0) 11080 (match_operand:SI 2 "logical_const_operand" "")])) 11081 (set (match_operand:CC 4 "cc_reg_operand" "") 11082 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "") 11083 (match_dup 0))) 11084 (set (pc) 11085 (if_then_else (match_operator 6 "equality_operator" 11086 [(match_dup 4) (const_int 0)]) 11087 (match_operand 7 "" "") 11088 (match_operand 8 "" "")))] 11089 "peep2_reg_dead_p (3, operands[0]) 11090 && peep2_reg_dead_p (4, operands[4]) 11091 && REGNO (operands[0]) != REGNO (operands[5])" 11092 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9))) 11093 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10))) 11094 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))] 11095 11096{ 11097 /* Get the constant we are comparing against, and see what it looks like 11098 when sign-extended from 16 to 32 bits. Then see what constant we could 11099 XOR with SEXTC to get the sign-extended value. */ 11100 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]), 11101 SImode, 11102 operands[1], operands[2]); 11103 HOST_WIDE_INT c = INTVAL (cnst); 11104 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000; 11105 HOST_WIDE_INT xorv = c ^ sextc; 11106 11107 operands[9] = GEN_INT (xorv); 11108 operands[10] = GEN_INT (sextc); 11109}) 11110 11111;; The following two insns don't exist as single insns, but if we provide 11112;; them, we can swap an add and compare, which will enable us to overlap more 11113;; of the required delay between a compare and branch. We generate code for 11114;; them by splitting. 11115 11116(define_insn "" 11117 [(set (match_operand:CC 3 "cc_reg_operand" "=y") 11118 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r") 11119 (match_operand:SI 2 "short_cint_operand" "i"))) 11120 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 11121 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] 11122 "" 11123 "#" 11124 [(set_attr "length" "8")]) 11125 11126(define_insn "" 11127 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y") 11128 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") 11129 (match_operand:SI 2 "u_short_cint_operand" "i"))) 11130 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 11131 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] 11132 "" 11133 "#" 11134 [(set_attr "length" "8")]) 11135 11136(define_split 11137 [(set (match_operand:CC 3 "cc_reg_operand" "") 11138 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") 11139 (match_operand:SI 2 "short_cint_operand" ""))) 11140 (set (match_operand:SI 0 "gpc_reg_operand" "") 11141 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))] 11142 "" 11143 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2))) 11144 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) 11145 11146(define_split 11147 [(set (match_operand:CCUNS 3 "cc_reg_operand" "") 11148 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "") 11149 (match_operand:SI 2 "u_short_cint_operand" ""))) 11150 (set (match_operand:SI 0 "gpc_reg_operand" "") 11151 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))] 11152 "" 11153 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2))) 11154 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) 11155 11156;; Only need to compare second words if first words equal 11157(define_insn "*cmp<mode>_internal1" 11158 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 11159 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 11160 (match_operand:IBM128 2 "gpc_reg_operand" "d")))] 11161 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) 11162 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 11163 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" 11164 [(set_attr "type" "fpcompare") 11165 (set_attr "length" "12")]) 11166 11167(define_insn_and_split "*cmp<mode>_internal2" 11168 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 11169 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 11170 (match_operand:IBM128 2 "gpc_reg_operand" "d"))) 11171 (clobber (match_scratch:DF 3 "=d")) 11172 (clobber (match_scratch:DF 4 "=d")) 11173 (clobber (match_scratch:DF 5 "=d")) 11174 (clobber (match_scratch:DF 6 "=d")) 11175 (clobber (match_scratch:DF 7 "=d")) 11176 (clobber (match_scratch:DF 8 "=d")) 11177 (clobber (match_scratch:DF 9 "=d")) 11178 (clobber (match_scratch:DF 10 "=d")) 11179 (clobber (match_scratch:GPR 11 "=b"))] 11180 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) 11181 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 11182 "#" 11183 "&& reload_completed" 11184 [(set (match_dup 3) (match_dup 14)) 11185 (set (match_dup 4) (match_dup 15)) 11186 (set (match_dup 9) (abs:DF (match_dup 5))) 11187 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) 11188 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) 11189 (label_ref (match_dup 12)) 11190 (pc))) 11191 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) 11192 (set (pc) (label_ref (match_dup 13))) 11193 (match_dup 12) 11194 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) 11195 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) 11196 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) 11197 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4))) 11198 (match_dup 13)] 11199{ 11200 REAL_VALUE_TYPE rv; 11201 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 11202 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 11203 11204 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word); 11205 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word); 11206 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word); 11207 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word); 11208 operands[12] = gen_label_rtx (); 11209 operands[13] = gen_label_rtx (); 11210 real_inf (&rv); 11211 operands[14] = force_const_mem (DFmode, 11212 const_double_from_real_value (rv, DFmode)); 11213 operands[15] = force_const_mem (DFmode, 11214 const_double_from_real_value (dconst0, 11215 DFmode)); 11216 if (TARGET_TOC) 11217 { 11218 rtx tocref; 11219 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]); 11220 operands[14] = gen_const_mem (DFmode, tocref); 11221 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]); 11222 operands[15] = gen_const_mem (DFmode, tocref); 11223 set_mem_alias_set (operands[14], get_TOC_alias_set ()); 11224 set_mem_alias_set (operands[15], get_TOC_alias_set ()); 11225 } 11226}) 11227 11228;; Now we have the scc insns. We can do some combinations because of the 11229;; way the machine works. 11230;; 11231;; Note that this is probably faster if we can put an insn between the 11232;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most 11233;; cases the insns below which don't use an intermediate CR field will 11234;; be used instead. 11235(define_insn "" 11236 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 11237 (match_operator:SI 1 "scc_comparison_operator" 11238 [(match_operand 2 "cc_reg_operand" "y") 11239 (const_int 0)]))] 11240 "" 11241 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" 11242 [(set (attr "type") 11243 (cond [(match_test "TARGET_MFCRF") 11244 (const_string "mfcrf") 11245 ] 11246 (const_string "mfcr"))) 11247 (set_attr "length" "8")]) 11248 11249;; Same as above, but get the GT bit. 11250(define_insn "move_from_CR_gt_bit" 11251 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 11252 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))] 11253 "TARGET_HARD_FLOAT && !TARGET_FPRS" 11254 "mfcr %0\;rlwinm %0,%0,%D1,31,31" 11255 [(set_attr "type" "mfcr") 11256 (set_attr "length" "8")]) 11257 11258;; Same as above, but get the OV/ORDERED bit. 11259(define_insn "move_from_CR_ov_bit" 11260 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 11261 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")] 11262 UNSPEC_MV_CR_OV))] 11263 "TARGET_ISEL" 11264 "mfcr %0\;rlwinm %0,%0,%t1,1" 11265 [(set_attr "type" "mfcr") 11266 (set_attr "length" "8")]) 11267 11268(define_insn "" 11269 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 11270 (match_operator:DI 1 "scc_comparison_operator" 11271 [(match_operand 2 "cc_reg_operand" "y") 11272 (const_int 0)]))] 11273 "TARGET_POWERPC64" 11274 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" 11275 [(set (attr "type") 11276 (cond [(match_test "TARGET_MFCRF") 11277 (const_string "mfcrf") 11278 ] 11279 (const_string "mfcr"))) 11280 (set_attr "length" "8")]) 11281 11282(define_insn "" 11283 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") 11284 (compare:CC (match_operator:SI 1 "scc_comparison_operator" 11285 [(match_operand 2 "cc_reg_operand" "y,y") 11286 (const_int 0)]) 11287 (const_int 0))) 11288 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 11289 (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 11290 "TARGET_32BIT" 11291 "@ 11292 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1 11293 #" 11294 [(set_attr "type" "shift") 11295 (set_attr "dot" "yes") 11296 (set_attr "length" "8,16")]) 11297 11298(define_split 11299 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") 11300 (compare:CC (match_operator:SI 1 "scc_comparison_operator" 11301 [(match_operand 2 "cc_reg_operand" "") 11302 (const_int 0)]) 11303 (const_int 0))) 11304 (set (match_operand:SI 3 "gpc_reg_operand" "") 11305 (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 11306 "TARGET_32BIT && reload_completed" 11307 [(set (match_dup 3) 11308 (match_op_dup 1 [(match_dup 2) (const_int 0)])) 11309 (set (match_dup 0) 11310 (compare:CC (match_dup 3) 11311 (const_int 0)))] 11312 "") 11313 11314(define_insn "" 11315 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 11316 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" 11317 [(match_operand 2 "cc_reg_operand" "y") 11318 (const_int 0)]) 11319 (match_operand:SI 3 "const_int_operand" "n")))] 11320 "" 11321 "* 11322{ 11323 int is_bit = ccr_bit (operands[1], 1); 11324 int put_bit = 31 - (INTVAL (operands[3]) & 31); 11325 int count; 11326 11327 if (is_bit >= put_bit) 11328 count = is_bit - put_bit; 11329 else 11330 count = 32 - (put_bit - is_bit); 11331 11332 operands[4] = GEN_INT (count); 11333 operands[5] = GEN_INT (put_bit); 11334 11335 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\"; 11336}" 11337 [(set (attr "type") 11338 (cond [(match_test "TARGET_MFCRF") 11339 (const_string "mfcrf") 11340 ] 11341 (const_string "mfcr"))) 11342 (set_attr "length" "8")]) 11343 11344(define_insn "" 11345 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") 11346 (compare:CC 11347 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" 11348 [(match_operand 2 "cc_reg_operand" "y,y") 11349 (const_int 0)]) 11350 (match_operand:SI 3 "const_int_operand" "n,n")) 11351 (const_int 0))) 11352 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r") 11353 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) 11354 (match_dup 3)))] 11355 "" 11356 "* 11357{ 11358 int is_bit = ccr_bit (operands[1], 1); 11359 int put_bit = 31 - (INTVAL (operands[3]) & 31); 11360 int count; 11361 11362 /* Force split for non-cc0 compare. */ 11363 if (which_alternative == 1) 11364 return \"#\"; 11365 11366 if (is_bit >= put_bit) 11367 count = is_bit - put_bit; 11368 else 11369 count = 32 - (put_bit - is_bit); 11370 11371 operands[5] = GEN_INT (count); 11372 operands[6] = GEN_INT (put_bit); 11373 11374 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\"; 11375}" 11376 [(set_attr "type" "shift") 11377 (set_attr "dot" "yes") 11378 (set_attr "length" "8,16")]) 11379 11380(define_split 11381 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") 11382 (compare:CC 11383 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" 11384 [(match_operand 2 "cc_reg_operand" "") 11385 (const_int 0)]) 11386 (match_operand:SI 3 "const_int_operand" "")) 11387 (const_int 0))) 11388 (set (match_operand:SI 4 "gpc_reg_operand" "") 11389 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) 11390 (match_dup 3)))] 11391 "reload_completed" 11392 [(set (match_dup 4) 11393 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) 11394 (match_dup 3))) 11395 (set (match_dup 0) 11396 (compare:CC (match_dup 4) 11397 (const_int 0)))] 11398 "") 11399 11400;; There is a 3 cycle delay between consecutive mfcr instructions 11401;; so it is useful to combine 2 scc instructions to use only one mfcr. 11402 11403(define_peephole 11404 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 11405 (match_operator:SI 1 "scc_comparison_operator" 11406 [(match_operand 2 "cc_reg_operand" "y") 11407 (const_int 0)])) 11408 (set (match_operand:SI 3 "gpc_reg_operand" "=r") 11409 (match_operator:SI 4 "scc_comparison_operator" 11410 [(match_operand 5 "cc_reg_operand" "y") 11411 (const_int 0)]))] 11412 "REGNO (operands[2]) != REGNO (operands[5])" 11413 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1" 11414 [(set_attr "type" "mfcr") 11415 (set_attr "length" "12")]) 11416 11417(define_peephole 11418 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 11419 (match_operator:DI 1 "scc_comparison_operator" 11420 [(match_operand 2 "cc_reg_operand" "y") 11421 (const_int 0)])) 11422 (set (match_operand:DI 3 "gpc_reg_operand" "=r") 11423 (match_operator:DI 4 "scc_comparison_operator" 11424 [(match_operand 5 "cc_reg_operand" "y") 11425 (const_int 0)]))] 11426 "TARGET_POWERPC64 && REGNO (operands[2]) != REGNO (operands[5])" 11427 "mfcr %3\;rlwinm %0,%3,%J1,1\;rlwinm %3,%3,%J4,1" 11428 [(set_attr "type" "mfcr") 11429 (set_attr "length" "12")]) 11430 11431 11432(define_mode_attr scc_eq_op2 [(SI "rKLI") 11433 (DI "rKJI")]) 11434 11435(define_insn_and_split "eq<mode>3" 11436 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11437 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 11438 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 11439 (clobber (match_scratch:GPR 3 "=r")) 11440 (clobber (match_scratch:GPR 4 "=r"))] 11441 "" 11442 "#" 11443 "" 11444 [(set (match_dup 4) 11445 (clz:GPR (match_dup 3))) 11446 (set (match_dup 0) 11447 (lshiftrt:GPR (match_dup 4) 11448 (match_dup 5)))] 11449{ 11450 operands[3] = rs6000_emit_eqne (<MODE>mode, 11451 operands[1], operands[2], operands[3]); 11452 11453 if (GET_CODE (operands[4]) == SCRATCH) 11454 operands[4] = gen_reg_rtx (<MODE>mode); 11455 11456 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode))); 11457} 11458 [(set (attr "length") 11459 (if_then_else (match_test "operands[2] == const0_rtx") 11460 (const_string "8") 11461 (const_string "12")))]) 11462 11463(define_insn_and_split "ne<mode>3" 11464 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11465 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 11466 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) 11467 (clobber (match_scratch:P 3 "=r")) 11468 (clobber (match_scratch:P 4 "=r")) 11469 (clobber (reg:P CA_REGNO))] 11470 "!TARGET_ISEL" 11471 "#" 11472 "" 11473 [(parallel [(set (match_dup 4) 11474 (plus:P (match_dup 3) 11475 (const_int -1))) 11476 (set (reg:P CA_REGNO) 11477 (ne:P (match_dup 3) 11478 (const_int 0)))]) 11479 (parallel [(set (match_dup 0) 11480 (plus:P (plus:P (not:P (match_dup 4)) 11481 (reg:P CA_REGNO)) 11482 (match_dup 3))) 11483 (clobber (reg:P CA_REGNO))])] 11484{ 11485 operands[3] = rs6000_emit_eqne (<MODE>mode, 11486 operands[1], operands[2], operands[3]); 11487 11488 if (GET_CODE (operands[4]) == SCRATCH) 11489 operands[4] = gen_reg_rtx (<MODE>mode); 11490} 11491 [(set (attr "length") 11492 (if_then_else (match_test "operands[2] == const0_rtx") 11493 (const_string "8") 11494 (const_string "12")))]) 11495 11496(define_insn_and_split "*neg_eq_<mode>" 11497 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11498 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 11499 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 11500 (clobber (match_scratch:P 3 "=r")) 11501 (clobber (match_scratch:P 4 "=r")) 11502 (clobber (reg:P CA_REGNO))] 11503 "" 11504 "#" 11505 "" 11506 [(parallel [(set (match_dup 4) 11507 (plus:P (match_dup 3) 11508 (const_int -1))) 11509 (set (reg:P CA_REGNO) 11510 (ne:P (match_dup 3) 11511 (const_int 0)))]) 11512 (parallel [(set (match_dup 0) 11513 (plus:P (reg:P CA_REGNO) 11514 (const_int -1))) 11515 (clobber (reg:P CA_REGNO))])] 11516{ 11517 operands[3] = rs6000_emit_eqne (<MODE>mode, 11518 operands[1], operands[2], operands[3]); 11519 11520 if (GET_CODE (operands[4]) == SCRATCH) 11521 operands[4] = gen_reg_rtx (<MODE>mode); 11522} 11523 [(set (attr "length") 11524 (if_then_else (match_test "operands[2] == const0_rtx") 11525 (const_string "8") 11526 (const_string "12")))]) 11527 11528(define_insn_and_split "*neg_ne_<mode>" 11529 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11530 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 11531 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 11532 (clobber (match_scratch:P 3 "=r")) 11533 (clobber (match_scratch:P 4 "=r")) 11534 (clobber (reg:P CA_REGNO))] 11535 "" 11536 "#" 11537 "" 11538 [(parallel [(set (match_dup 4) 11539 (neg:P (match_dup 3))) 11540 (set (reg:P CA_REGNO) 11541 (eq:P (match_dup 3) 11542 (const_int 0)))]) 11543 (parallel [(set (match_dup 0) 11544 (plus:P (reg:P CA_REGNO) 11545 (const_int -1))) 11546 (clobber (reg:P CA_REGNO))])] 11547{ 11548 operands[3] = rs6000_emit_eqne (<MODE>mode, 11549 operands[1], operands[2], operands[3]); 11550 11551 if (GET_CODE (operands[4]) == SCRATCH) 11552 operands[4] = gen_reg_rtx (<MODE>mode); 11553} 11554 [(set (attr "length") 11555 (if_then_else (match_test "operands[2] == const0_rtx") 11556 (const_string "8") 11557 (const_string "12")))]) 11558 11559(define_insn_and_split "*plus_eq_<mode>" 11560 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11561 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 11562 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 11563 (match_operand:P 3 "gpc_reg_operand" "r"))) 11564 (clobber (match_scratch:P 4 "=r")) 11565 (clobber (match_scratch:P 5 "=r")) 11566 (clobber (reg:P CA_REGNO))] 11567 "" 11568 "#" 11569 "" 11570 [(parallel [(set (match_dup 5) 11571 (neg:P (match_dup 4))) 11572 (set (reg:P CA_REGNO) 11573 (eq:P (match_dup 4) 11574 (const_int 0)))]) 11575 (parallel [(set (match_dup 0) 11576 (plus:P (match_dup 3) 11577 (reg:P CA_REGNO))) 11578 (clobber (reg:P CA_REGNO))])] 11579{ 11580 operands[4] = rs6000_emit_eqne (<MODE>mode, 11581 operands[1], operands[2], operands[4]); 11582 11583 if (GET_CODE (operands[5]) == SCRATCH) 11584 operands[5] = gen_reg_rtx (<MODE>mode); 11585} 11586 [(set (attr "length") 11587 (if_then_else (match_test "operands[2] == const0_rtx") 11588 (const_string "8") 11589 (const_string "12")))]) 11590 11591(define_insn_and_split "*plus_ne_<mode>" 11592 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11593 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 11594 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 11595 (match_operand:P 3 "gpc_reg_operand" "r"))) 11596 (clobber (match_scratch:P 4 "=r")) 11597 (clobber (match_scratch:P 5 "=r")) 11598 (clobber (reg:P CA_REGNO))] 11599 "" 11600 "#" 11601 "" 11602 [(parallel [(set (match_dup 5) 11603 (plus:P (match_dup 4) 11604 (const_int -1))) 11605 (set (reg:P CA_REGNO) 11606 (ne:P (match_dup 4) 11607 (const_int 0)))]) 11608 (parallel [(set (match_dup 0) 11609 (plus:P (match_dup 3) 11610 (reg:P CA_REGNO))) 11611 (clobber (reg:P CA_REGNO))])] 11612{ 11613 operands[4] = rs6000_emit_eqne (<MODE>mode, 11614 operands[1], operands[2], operands[4]); 11615 11616 if (GET_CODE (operands[5]) == SCRATCH) 11617 operands[5] = gen_reg_rtx (<MODE>mode); 11618} 11619 [(set (attr "length") 11620 (if_then_else (match_test "operands[2] == const0_rtx") 11621 (const_string "8") 11622 (const_string "12")))]) 11623 11624(define_insn_and_split "*minus_eq_<mode>" 11625 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11626 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 11627 (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 11628 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 11629 (clobber (match_scratch:P 4 "=r")) 11630 (clobber (match_scratch:P 5 "=r")) 11631 (clobber (reg:P CA_REGNO))] 11632 "" 11633 "#" 11634 "" 11635 [(parallel [(set (match_dup 5) 11636 (plus:P (match_dup 4) 11637 (const_int -1))) 11638 (set (reg:P CA_REGNO) 11639 (ne:P (match_dup 4) 11640 (const_int 0)))]) 11641 (parallel [(set (match_dup 0) 11642 (plus:P (plus:P (match_dup 3) 11643 (reg:P CA_REGNO)) 11644 (const_int -1))) 11645 (clobber (reg:P CA_REGNO))])] 11646{ 11647 operands[4] = rs6000_emit_eqne (<MODE>mode, 11648 operands[1], operands[2], operands[4]); 11649 11650 if (GET_CODE (operands[5]) == SCRATCH) 11651 operands[5] = gen_reg_rtx (<MODE>mode); 11652} 11653 [(set (attr "length") 11654 (if_then_else (match_test "operands[2] == const0_rtx") 11655 (const_string "8") 11656 (const_string "12")))]) 11657 11658(define_insn_and_split "*minus_ne_<mode>" 11659 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11660 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 11661 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 11662 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 11663 (clobber (match_scratch:P 4 "=r")) 11664 (clobber (match_scratch:P 5 "=r")) 11665 (clobber (reg:P CA_REGNO))] 11666 "" 11667 "#" 11668 "" 11669 [(parallel [(set (match_dup 5) 11670 (neg:P (match_dup 4))) 11671 (set (reg:P CA_REGNO) 11672 (eq:P (match_dup 4) 11673 (const_int 0)))]) 11674 (parallel [(set (match_dup 0) 11675 (plus:P (plus:P (match_dup 3) 11676 (reg:P CA_REGNO)) 11677 (const_int -1))) 11678 (clobber (reg:P CA_REGNO))])] 11679{ 11680 operands[4] = rs6000_emit_eqne (<MODE>mode, 11681 operands[1], operands[2], operands[4]); 11682 11683 if (GET_CODE (operands[5]) == SCRATCH) 11684 operands[5] = gen_reg_rtx (<MODE>mode); 11685} 11686 [(set (attr "length") 11687 (if_then_else (match_test "operands[2] == const0_rtx") 11688 (const_string "8") 11689 (const_string "12")))]) 11690 11691(define_insn_and_split "*eqsi3_ext<mode>" 11692 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 11693 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 11694 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 11695 (clobber (match_scratch:SI 3 "=r")) 11696 (clobber (match_scratch:SI 4 "=r"))] 11697 "" 11698 "#" 11699 "" 11700 [(set (match_dup 4) 11701 (clz:SI (match_dup 3))) 11702 (set (match_dup 0) 11703 (zero_extend:EXTSI 11704 (lshiftrt:SI (match_dup 4) 11705 (const_int 5))))] 11706{ 11707 operands[3] = rs6000_emit_eqne (SImode, 11708 operands[1], operands[2], operands[3]); 11709 11710 if (GET_CODE (operands[4]) == SCRATCH) 11711 operands[4] = gen_reg_rtx (SImode); 11712} 11713 [(set (attr "length") 11714 (if_then_else (match_test "operands[2] == const0_rtx") 11715 (const_string "8") 11716 (const_string "12")))]) 11717 11718(define_insn_and_split "*nesi3_ext<mode>" 11719 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 11720 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 11721 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 11722 (clobber (match_scratch:SI 3 "=r")) 11723 (clobber (match_scratch:SI 4 "=r")) 11724 (clobber (match_scratch:EXTSI 5 "=r"))] 11725 "" 11726 "#" 11727 "" 11728 [(set (match_dup 4) 11729 (clz:SI (match_dup 3))) 11730 (set (match_dup 5) 11731 (zero_extend:EXTSI 11732 (lshiftrt:SI (match_dup 4) 11733 (const_int 5)))) 11734 (set (match_dup 0) 11735 (xor:EXTSI (match_dup 5) 11736 (const_int 1)))] 11737{ 11738 operands[3] = rs6000_emit_eqne (SImode, 11739 operands[1], operands[2], operands[3]); 11740 11741 if (GET_CODE (operands[4]) == SCRATCH) 11742 operands[4] = gen_reg_rtx (SImode); 11743 if (GET_CODE (operands[5]) == SCRATCH) 11744 operands[5] = gen_reg_rtx (<MODE>mode); 11745} 11746 [(set (attr "length") 11747 (if_then_else (match_test "operands[2] == const0_rtx") 11748 (const_string "12") 11749 (const_string "16")))]) 11750 11751;; Define both directions of branch and return. If we need a reload 11752;; register, we'd rather use CR0 since it is much easier to copy a 11753;; register CC value to there. 11754 11755(define_insn "" 11756 [(set (pc) 11757 (if_then_else (match_operator 1 "branch_comparison_operator" 11758 [(match_operand 2 11759 "cc_reg_operand" "y") 11760 (const_int 0)]) 11761 (label_ref (match_operand 0 "" "")) 11762 (pc)))] 11763 "" 11764 "* 11765{ 11766 return output_cbranch (operands[1], \"%l0\", 0, insn); 11767}" 11768 [(set_attr "type" "branch")]) 11769 11770(define_insn "" 11771 [(set (pc) 11772 (if_then_else (match_operator 0 "branch_comparison_operator" 11773 [(match_operand 1 11774 "cc_reg_operand" "y") 11775 (const_int 0)]) 11776 (any_return) 11777 (pc)))] 11778 "<return_pred>" 11779 "* 11780{ 11781 return output_cbranch (operands[0], NULL, 0, insn); 11782}" 11783 [(set_attr "type" "jmpreg") 11784 (set_attr "length" "4")]) 11785 11786(define_insn "" 11787 [(set (pc) 11788 (if_then_else (match_operator 1 "branch_comparison_operator" 11789 [(match_operand 2 11790 "cc_reg_operand" "y") 11791 (const_int 0)]) 11792 (pc) 11793 (label_ref (match_operand 0 "" ""))))] 11794 "" 11795 "* 11796{ 11797 return output_cbranch (operands[1], \"%l0\", 1, insn); 11798}" 11799 [(set_attr "type" "branch")]) 11800 11801(define_insn "" 11802 [(set (pc) 11803 (if_then_else (match_operator 0 "branch_comparison_operator" 11804 [(match_operand 1 11805 "cc_reg_operand" "y") 11806 (const_int 0)]) 11807 (pc) 11808 (any_return)))] 11809 "<return_pred>" 11810 "* 11811{ 11812 return output_cbranch (operands[0], NULL, 1, insn); 11813}" 11814 [(set_attr "type" "jmpreg") 11815 (set_attr "length" "4")]) 11816 11817;; Logic on condition register values. 11818 11819; This pattern matches things like 11820; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0)) 11821; (eq:SI (reg:CCFP 68) (const_int 0))) 11822; (const_int 1))) 11823; which are generated by the branch logic. 11824; Prefer destructive operations where BT = BB (for crXX BT,BA,BB) 11825 11826(define_insn "*cceq_ior_compare" 11827 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 11828 (compare:CCEQ (match_operator:SI 1 "boolean_operator" 11829 [(match_operator:SI 2 11830 "branch_positive_comparison_operator" 11831 [(match_operand 3 11832 "cc_reg_operand" "y,y") 11833 (const_int 0)]) 11834 (match_operator:SI 4 11835 "branch_positive_comparison_operator" 11836 [(match_operand 5 11837 "cc_reg_operand" "0,y") 11838 (const_int 0)])]) 11839 (const_int 1)))] 11840 "" 11841 "cr%q1 %E0,%j2,%j4" 11842 [(set_attr "type" "cr_logical,delayed_cr")]) 11843 11844; Why is the constant -1 here, but 1 in the previous pattern? 11845; Because ~1 has all but the low bit set. 11846(define_insn "" 11847 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 11848 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator" 11849 [(not:SI (match_operator:SI 2 11850 "branch_positive_comparison_operator" 11851 [(match_operand 3 11852 "cc_reg_operand" "y,y") 11853 (const_int 0)])) 11854 (match_operator:SI 4 11855 "branch_positive_comparison_operator" 11856 [(match_operand 5 11857 "cc_reg_operand" "0,y") 11858 (const_int 0)])]) 11859 (const_int -1)))] 11860 "" 11861 "cr%q1 %E0,%j2,%j4" 11862 [(set_attr "type" "cr_logical,delayed_cr")]) 11863 11864(define_insn "*cceq_rev_compare" 11865 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 11866 (compare:CCEQ (match_operator:SI 1 11867 "branch_positive_comparison_operator" 11868 [(match_operand 2 11869 "cc_reg_operand" "0,y") 11870 (const_int 0)]) 11871 (const_int 0)))] 11872 "" 11873 "crnot %E0,%j1" 11874 [(set_attr "type" "cr_logical,delayed_cr")]) 11875 11876;; If we are comparing the result of two comparisons, this can be done 11877;; using creqv or crxor. 11878 11879(define_insn_and_split "" 11880 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y") 11881 (compare:CCEQ (match_operator 1 "branch_comparison_operator" 11882 [(match_operand 2 "cc_reg_operand" "y") 11883 (const_int 0)]) 11884 (match_operator 3 "branch_comparison_operator" 11885 [(match_operand 4 "cc_reg_operand" "y") 11886 (const_int 0)])))] 11887 "" 11888 "#" 11889 "" 11890 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3)) 11891 (match_dup 5)))] 11892 " 11893{ 11894 int positive_1, positive_2; 11895 11896 positive_1 = branch_positive_comparison_operator (operands[1], 11897 GET_MODE (operands[1])); 11898 positive_2 = branch_positive_comparison_operator (operands[3], 11899 GET_MODE (operands[3])); 11900 11901 if (! positive_1) 11902 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]), 11903 GET_CODE (operands[1])), 11904 SImode, 11905 operands[2], const0_rtx); 11906 else if (GET_MODE (operands[1]) != SImode) 11907 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, 11908 operands[2], const0_rtx); 11909 11910 if (! positive_2) 11911 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]), 11912 GET_CODE (operands[3])), 11913 SImode, 11914 operands[4], const0_rtx); 11915 else if (GET_MODE (operands[3]) != SImode) 11916 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, 11917 operands[4], const0_rtx); 11918 11919 if (positive_1 == positive_2) 11920 { 11921 operands[1] = gen_rtx_NOT (SImode, operands[1]); 11922 operands[5] = constm1_rtx; 11923 } 11924 else 11925 { 11926 operands[5] = const1_rtx; 11927 } 11928}") 11929 11930;; Unconditional branch and return. 11931 11932(define_insn "jump" 11933 [(set (pc) 11934 (label_ref (match_operand 0 "" "")))] 11935 "" 11936 "b %l0" 11937 [(set_attr "type" "branch")]) 11938 11939(define_insn "<return_str>return" 11940 [(any_return)] 11941 "<return_pred>" 11942 "blr" 11943 [(set_attr "type" "jmpreg")]) 11944 11945(define_expand "indirect_jump" 11946 [(set (pc) (match_operand 0 "register_operand" ""))]) 11947 11948(define_insn "*indirect_jump<mode>" 11949 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))] 11950 "" 11951 "@ 11952 bctr 11953 blr" 11954 [(set_attr "type" "jmpreg")]) 11955 11956;; Table jump for switch statements: 11957(define_expand "tablejump" 11958 [(use (match_operand 0 "" "")) 11959 (use (label_ref (match_operand 1 "" "")))] 11960 "" 11961 " 11962{ 11963 if (TARGET_32BIT) 11964 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); 11965 else 11966 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); 11967 DONE; 11968}") 11969 11970(define_expand "tablejumpsi" 11971 [(set (match_dup 3) 11972 (plus:SI (match_operand:SI 0 "" "") 11973 (match_dup 2))) 11974 (parallel [(set (pc) (match_dup 3)) 11975 (use (label_ref (match_operand 1 "" "")))])] 11976 "TARGET_32BIT" 11977 " 11978{ operands[0] = force_reg (SImode, operands[0]); 11979 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); 11980 operands[3] = gen_reg_rtx (SImode); 11981}") 11982 11983(define_expand "tablejumpdi" 11984 [(set (match_dup 4) 11985 (sign_extend:DI (match_operand:SI 0 "lwa_operand" ""))) 11986 (set (match_dup 3) 11987 (plus:DI (match_dup 4) 11988 (match_dup 2))) 11989 (parallel [(set (pc) (match_dup 3)) 11990 (use (label_ref (match_operand 1 "" "")))])] 11991 "TARGET_64BIT" 11992 " 11993{ operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); 11994 operands[3] = gen_reg_rtx (DImode); 11995 operands[4] = gen_reg_rtx (DImode); 11996}") 11997 11998(define_insn "*tablejump<mode>_internal1" 11999 [(set (pc) 12000 (match_operand:P 0 "register_operand" "c,*l")) 12001 (use (label_ref (match_operand 1 "" "")))] 12002 "" 12003 "@ 12004 bctr 12005 blr" 12006 [(set_attr "type" "jmpreg")]) 12007 12008(define_insn "nop" 12009 [(unspec [(const_int 0)] UNSPEC_NOP)] 12010 "" 12011 "nop") 12012 12013(define_insn "group_ending_nop" 12014 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)] 12015 "" 12016 "* 12017{ 12018 if (rs6000_cpu_attr == CPU_POWER6) 12019 return \"ori 1,1,0\"; 12020 return \"ori 2,2,0\"; 12021}") 12022 12023;; Define the subtract-one-and-jump insns, starting with the template 12024;; so loop.c knows what to generate. 12025 12026(define_expand "doloop_end" 12027 [(use (match_operand 0 "" "")) ; loop pseudo 12028 (use (match_operand 1 "" ""))] ; label 12029 "" 12030 " 12031{ 12032 if (TARGET_64BIT) 12033 { 12034 if (GET_MODE (operands[0]) != DImode) 12035 FAIL; 12036 emit_jump_insn (gen_ctrdi (operands[0], operands[1])); 12037 } 12038 else 12039 { 12040 if (GET_MODE (operands[0]) != SImode) 12041 FAIL; 12042 emit_jump_insn (gen_ctrsi (operands[0], operands[1])); 12043 } 12044 DONE; 12045}") 12046 12047(define_expand "ctr<mode>" 12048 [(parallel [(set (pc) 12049 (if_then_else (ne (match_operand:P 0 "register_operand" "") 12050 (const_int 1)) 12051 (label_ref (match_operand 1 "" "")) 12052 (pc))) 12053 (set (match_dup 0) 12054 (plus:P (match_dup 0) 12055 (const_int -1))) 12056 (unspec [(const_int 0)] UNSPEC_DOLOOP) 12057 (clobber (match_scratch:CC 2 "")) 12058 (clobber (match_scratch:P 3 ""))])] 12059 "" 12060 "") 12061 12062;; We need to be able to do this for any operand, including MEM, or we 12063;; will cause reload to blow up since we don't allow output reloads on 12064;; JUMP_INSNs. 12065;; For the length attribute to be calculated correctly, the 12066;; label MUST be operand 0. 12067;; The UNSPEC is present to prevent combine creating this pattern. 12068 12069(define_insn "*ctr<mode>_internal1" 12070 [(set (pc) 12071 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12072 (const_int 1)) 12073 (label_ref (match_operand 0 "" "")) 12074 (pc))) 12075 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") 12076 (plus:P (match_dup 1) 12077 (const_int -1))) 12078 (unspec [(const_int 0)] UNSPEC_DOLOOP) 12079 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 12080 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 12081 "" 12082 "* 12083{ 12084 if (which_alternative != 0) 12085 return \"#\"; 12086 else if (get_attr_length (insn) == 4) 12087 return \"bdnz %l0\"; 12088 else 12089 return \"bdz $+8\;b %l0\"; 12090}" 12091 [(set_attr "type" "branch") 12092 (set_attr "length" "*,16,20,20")]) 12093 12094(define_insn "*ctr<mode>_internal2" 12095 [(set (pc) 12096 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12097 (const_int 1)) 12098 (pc) 12099 (label_ref (match_operand 0 "" "")))) 12100 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") 12101 (plus:P (match_dup 1) 12102 (const_int -1))) 12103 (unspec [(const_int 0)] UNSPEC_DOLOOP) 12104 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 12105 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 12106 "" 12107 "* 12108{ 12109 if (which_alternative != 0) 12110 return \"#\"; 12111 else if (get_attr_length (insn) == 4) 12112 return \"bdz %l0\"; 12113 else 12114 return \"bdnz $+8\;b %l0\"; 12115}" 12116 [(set_attr "type" "branch") 12117 (set_attr "length" "*,16,20,20")]) 12118 12119;; Similar but use EQ 12120 12121(define_insn "*ctr<mode>_internal5" 12122 [(set (pc) 12123 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12124 (const_int 1)) 12125 (label_ref (match_operand 0 "" "")) 12126 (pc))) 12127 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") 12128 (plus:P (match_dup 1) 12129 (const_int -1))) 12130 (unspec [(const_int 0)] UNSPEC_DOLOOP) 12131 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 12132 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 12133 "" 12134 "* 12135{ 12136 if (which_alternative != 0) 12137 return \"#\"; 12138 else if (get_attr_length (insn) == 4) 12139 return \"bdz %l0\"; 12140 else 12141 return \"bdnz $+8\;b %l0\"; 12142}" 12143 [(set_attr "type" "branch") 12144 (set_attr "length" "*,16,20,20")]) 12145 12146(define_insn "*ctr<mode>_internal6" 12147 [(set (pc) 12148 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12149 (const_int 1)) 12150 (pc) 12151 (label_ref (match_operand 0 "" "")))) 12152 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") 12153 (plus:P (match_dup 1) 12154 (const_int -1))) 12155 (unspec [(const_int 0)] UNSPEC_DOLOOP) 12156 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 12157 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 12158 "" 12159 "* 12160{ 12161 if (which_alternative != 0) 12162 return \"#\"; 12163 else if (get_attr_length (insn) == 4) 12164 return \"bdnz %l0\"; 12165 else 12166 return \"bdz $+8\;b %l0\"; 12167}" 12168 [(set_attr "type" "branch") 12169 (set_attr "length" "*,16,20,20")]) 12170 12171;; Now the splitters if we could not allocate the CTR register 12172 12173(define_split 12174 [(set (pc) 12175 (if_then_else (match_operator 2 "comparison_operator" 12176 [(match_operand:P 1 "gpc_reg_operand" "") 12177 (const_int 1)]) 12178 (match_operand 5 "" "") 12179 (match_operand 6 "" ""))) 12180 (set (match_operand:P 0 "int_reg_operand" "") 12181 (plus:P (match_dup 1) (const_int -1))) 12182 (unspec [(const_int 0)] UNSPEC_DOLOOP) 12183 (clobber (match_scratch:CC 3 "")) 12184 (clobber (match_scratch:P 4 ""))] 12185 "reload_completed" 12186 [(set (match_dup 3) 12187 (compare:CC (match_dup 1) 12188 (const_int 1))) 12189 (set (match_dup 0) 12190 (plus:P (match_dup 1) 12191 (const_int -1))) 12192 (set (pc) (if_then_else (match_dup 7) 12193 (match_dup 5) 12194 (match_dup 6)))] 12195 " 12196{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, 12197 operands[3], const0_rtx); }") 12198 12199(define_split 12200 [(set (pc) 12201 (if_then_else (match_operator 2 "comparison_operator" 12202 [(match_operand:P 1 "gpc_reg_operand" "") 12203 (const_int 1)]) 12204 (match_operand 5 "" "") 12205 (match_operand 6 "" ""))) 12206 (set (match_operand:P 0 "nonimmediate_operand" "") 12207 (plus:P (match_dup 1) (const_int -1))) 12208 (unspec [(const_int 0)] UNSPEC_DOLOOP) 12209 (clobber (match_scratch:CC 3 "")) 12210 (clobber (match_scratch:P 4 ""))] 12211 "reload_completed && ! gpc_reg_operand (operands[0], SImode)" 12212 [(set (match_dup 3) 12213 (compare:CC (match_dup 1) 12214 (const_int 1))) 12215 (set (match_dup 4) 12216 (plus:P (match_dup 1) 12217 (const_int -1))) 12218 (set (match_dup 0) 12219 (match_dup 4)) 12220 (set (pc) (if_then_else (match_dup 7) 12221 (match_dup 5) 12222 (match_dup 6)))] 12223 " 12224{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, 12225 operands[3], const0_rtx); }") 12226 12227(define_insn "trap" 12228 [(trap_if (const_int 1) (const_int 0))] 12229 "" 12230 "trap" 12231 [(set_attr "type" "trap")]) 12232 12233(define_expand "ctrap<mode>4" 12234 [(trap_if (match_operator 0 "ordered_comparison_operator" 12235 [(match_operand:GPR 1 "register_operand") 12236 (match_operand:GPR 2 "reg_or_short_operand")]) 12237 (match_operand 3 "zero_constant" ""))] 12238 "" 12239 "") 12240 12241(define_insn "" 12242 [(trap_if (match_operator 0 "ordered_comparison_operator" 12243 [(match_operand:GPR 1 "register_operand" "r") 12244 (match_operand:GPR 2 "reg_or_short_operand" "rI")]) 12245 (const_int 0))] 12246 "" 12247 "t<wd>%V0%I2 %1,%2" 12248 [(set_attr "type" "trap")]) 12249 12250;; Insns related to generating the function prologue and epilogue. 12251 12252(define_expand "prologue" 12253 [(use (const_int 0))] 12254 "" 12255{ 12256 rs6000_emit_prologue (); 12257 if (!TARGET_SCHED_PROLOG) 12258 emit_insn (gen_blockage ()); 12259 DONE; 12260}) 12261 12262(define_insn "*movesi_from_cr_one" 12263 [(match_parallel 0 "mfcr_operation" 12264 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 12265 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y") 12266 (match_operand 3 "immediate_operand" "n")] 12267 UNSPEC_MOVESI_FROM_CR))])] 12268 "TARGET_MFCRF" 12269 "* 12270{ 12271 int mask = 0; 12272 int i; 12273 for (i = 0; i < XVECLEN (operands[0], 0); i++) 12274 { 12275 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 12276 operands[4] = GEN_INT (mask); 12277 output_asm_insn (\"mfcr %1,%4\", operands); 12278 } 12279 return \"\"; 12280}" 12281 [(set_attr "type" "mfcrf")]) 12282 12283(define_insn "movesi_from_cr" 12284 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 12285 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO) 12286 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO) 12287 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO) 12288 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)] 12289 UNSPEC_MOVESI_FROM_CR))] 12290 "" 12291 "mfcr %0" 12292 [(set_attr "type" "mfcr")]) 12293 12294(define_insn "*crsave" 12295 [(match_parallel 0 "crsave_operation" 12296 [(set (match_operand:SI 1 "memory_operand" "=m") 12297 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 12298 "" 12299 "stw %2,%1" 12300 [(set_attr "type" "store")]) 12301 12302(define_insn "*stmw" 12303 [(match_parallel 0 "stmw_operation" 12304 [(set (match_operand:SI 1 "memory_operand" "=m") 12305 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 12306 "TARGET_MULTIPLE" 12307 "stmw %2,%1" 12308 [(set_attr "type" "store") 12309 (set_attr "update" "yes") 12310 (set_attr "indexed" "yes")]) 12311 12312; The following comment applies to: 12313; save_gpregs_* 12314; save_fpregs_* 12315; restore_gpregs* 12316; return_and_restore_gpregs* 12317; return_and_restore_fpregs* 12318; return_and_restore_fpregs_aix* 12319; 12320; The out-of-line save / restore functions expects one input argument. 12321; Since those are not standard call_insn's, we must avoid using 12322; MATCH_OPERAND for that argument. That way the register rename 12323; optimization will not try to rename this register. 12324; Each pattern is repeated for each possible register number used in 12325; various ABIs (r11, r1, and for some functions r12) 12326 12327(define_insn "*save_gpregs_<mode>_r11" 12328 [(match_parallel 0 "any_parallel_operand" 12329 [(clobber (reg:P 65)) 12330 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12331 (use (reg:P 11)) 12332 (set (match_operand:P 2 "memory_operand" "=m") 12333 (match_operand:P 3 "gpc_reg_operand" "r"))])] 12334 "" 12335 "bl %1" 12336 [(set_attr "type" "branch") 12337 (set_attr "length" "4")]) 12338 12339(define_insn "*save_gpregs_<mode>_r12" 12340 [(match_parallel 0 "any_parallel_operand" 12341 [(clobber (reg:P 65)) 12342 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12343 (use (reg:P 12)) 12344 (set (match_operand:P 2 "memory_operand" "=m") 12345 (match_operand:P 3 "gpc_reg_operand" "r"))])] 12346 "" 12347 "bl %1" 12348 [(set_attr "type" "branch") 12349 (set_attr "length" "4")]) 12350 12351(define_insn "*save_gpregs_<mode>_r1" 12352 [(match_parallel 0 "any_parallel_operand" 12353 [(clobber (reg:P 65)) 12354 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12355 (use (reg:P 1)) 12356 (set (match_operand:P 2 "memory_operand" "=m") 12357 (match_operand:P 3 "gpc_reg_operand" "r"))])] 12358 "" 12359 "bl %1" 12360 [(set_attr "type" "branch") 12361 (set_attr "length" "4")]) 12362 12363(define_insn "*save_fpregs_<mode>_r11" 12364 [(match_parallel 0 "any_parallel_operand" 12365 [(clobber (reg:P 65)) 12366 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12367 (use (reg:P 11)) 12368 (set (match_operand:DF 2 "memory_operand" "=m") 12369 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 12370 "" 12371 "bl %1" 12372 [(set_attr "type" "branch") 12373 (set_attr "length" "4")]) 12374 12375(define_insn "*save_fpregs_<mode>_r12" 12376 [(match_parallel 0 "any_parallel_operand" 12377 [(clobber (reg:P 65)) 12378 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12379 (use (reg:P 12)) 12380 (set (match_operand:DF 2 "memory_operand" "=m") 12381 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 12382 "" 12383 "bl %1" 12384 [(set_attr "type" "branch") 12385 (set_attr "length" "4")]) 12386 12387(define_insn "*save_fpregs_<mode>_r1" 12388 [(match_parallel 0 "any_parallel_operand" 12389 [(clobber (reg:P 65)) 12390 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12391 (use (reg:P 1)) 12392 (set (match_operand:DF 2 "memory_operand" "=m") 12393 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 12394 "" 12395 "bl %1" 12396 [(set_attr "type" "branch") 12397 (set_attr "length" "4")]) 12398 12399; This is to explain that changes to the stack pointer should 12400; not be moved over loads from or stores to stack memory. 12401(define_insn "stack_tie" 12402 [(match_parallel 0 "tie_operand" 12403 [(set (mem:BLK (reg 1)) (const_int 0))])] 12404 "" 12405 "" 12406 [(set_attr "length" "0")]) 12407 12408(define_expand "epilogue" 12409 [(use (const_int 0))] 12410 "" 12411{ 12412 if (!TARGET_SCHED_PROLOG) 12413 emit_insn (gen_blockage ()); 12414 rs6000_emit_epilogue (FALSE); 12415 DONE; 12416}) 12417 12418; On some processors, doing the mtcrf one CC register at a time is 12419; faster (like on the 604e). On others, doing them all at once is 12420; faster; for instance, on the 601 and 750. 12421 12422(define_expand "movsi_to_cr_one" 12423 [(set (match_operand:CC 0 "cc_reg_operand" "") 12424 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "") 12425 (match_dup 2)] UNSPEC_MOVESI_TO_CR))] 12426 "" 12427 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") 12428 12429(define_insn "*movsi_to_cr" 12430 [(match_parallel 0 "mtcrf_operation" 12431 [(set (match_operand:CC 1 "cc_reg_operand" "=y") 12432 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r") 12433 (match_operand 3 "immediate_operand" "n")] 12434 UNSPEC_MOVESI_TO_CR))])] 12435 "" 12436 "* 12437{ 12438 int mask = 0; 12439 int i; 12440 for (i = 0; i < XVECLEN (operands[0], 0); i++) 12441 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 12442 operands[4] = GEN_INT (mask); 12443 return \"mtcrf %4,%2\"; 12444}" 12445 [(set_attr "type" "mtcr")]) 12446 12447(define_insn "*mtcrfsi" 12448 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 12449 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 12450 (match_operand 2 "immediate_operand" "n")] 12451 UNSPEC_MOVESI_TO_CR))] 12452 "GET_CODE (operands[0]) == REG 12453 && CR_REGNO_P (REGNO (operands[0])) 12454 && GET_CODE (operands[2]) == CONST_INT 12455 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))" 12456 "mtcrf %R0,%1" 12457 [(set_attr "type" "mtcr")]) 12458 12459; The load-multiple instructions have similar properties. 12460; Note that "load_multiple" is a name known to the machine-independent 12461; code that actually corresponds to the PowerPC load-string. 12462 12463(define_insn "*lmw" 12464 [(match_parallel 0 "lmw_operation" 12465 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 12466 (match_operand:SI 2 "memory_operand" "m"))])] 12467 "TARGET_MULTIPLE" 12468 "lmw %1,%2" 12469 [(set_attr "type" "load") 12470 (set_attr "update" "yes") 12471 (set_attr "indexed" "yes") 12472 (set_attr "cell_micro" "always")]) 12473 12474(define_insn "*return_internal_<mode>" 12475 [(simple_return) 12476 (use (match_operand:P 0 "register_operand" "lc"))] 12477 "" 12478 "b%T0" 12479 [(set_attr "type" "jmpreg")]) 12480 12481; FIXME: This would probably be somewhat simpler if the Cygnus sibcall 12482; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... 12483 12484; The following comment applies to: 12485; save_gpregs_* 12486; save_fpregs_* 12487; restore_gpregs* 12488; return_and_restore_gpregs* 12489; return_and_restore_fpregs* 12490; return_and_restore_fpregs_aix* 12491; 12492; The out-of-line save / restore functions expects one input argument. 12493; Since those are not standard call_insn's, we must avoid using 12494; MATCH_OPERAND for that argument. That way the register rename 12495; optimization will not try to rename this register. 12496; Each pattern is repeated for each possible register number used in 12497; various ABIs (r11, r1, and for some functions r12) 12498 12499(define_insn "*restore_gpregs_<mode>_r11" 12500 [(match_parallel 0 "any_parallel_operand" 12501 [(clobber (match_operand:P 1 "register_operand" "=l")) 12502 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12503 (use (reg:P 11)) 12504 (set (match_operand:P 3 "gpc_reg_operand" "=r") 12505 (match_operand:P 4 "memory_operand" "m"))])] 12506 "" 12507 "bl %2" 12508 [(set_attr "type" "branch") 12509 (set_attr "length" "4")]) 12510 12511(define_insn "*restore_gpregs_<mode>_r12" 12512 [(match_parallel 0 "any_parallel_operand" 12513 [(clobber (match_operand:P 1 "register_operand" "=l")) 12514 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12515 (use (reg:P 12)) 12516 (set (match_operand:P 3 "gpc_reg_operand" "=r") 12517 (match_operand:P 4 "memory_operand" "m"))])] 12518 "" 12519 "bl %2" 12520 [(set_attr "type" "branch") 12521 (set_attr "length" "4")]) 12522 12523(define_insn "*restore_gpregs_<mode>_r1" 12524 [(match_parallel 0 "any_parallel_operand" 12525 [(clobber (match_operand:P 1 "register_operand" "=l")) 12526 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12527 (use (reg:P 1)) 12528 (set (match_operand:P 3 "gpc_reg_operand" "=r") 12529 (match_operand:P 4 "memory_operand" "m"))])] 12530 "" 12531 "bl %2" 12532 [(set_attr "type" "branch") 12533 (set_attr "length" "4")]) 12534 12535(define_insn "*return_and_restore_gpregs_<mode>_r11" 12536 [(match_parallel 0 "any_parallel_operand" 12537 [(return) 12538 (clobber (match_operand:P 1 "register_operand" "=l")) 12539 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12540 (use (reg:P 11)) 12541 (set (match_operand:P 3 "gpc_reg_operand" "=r") 12542 (match_operand:P 4 "memory_operand" "m"))])] 12543 "" 12544 "b %2" 12545 [(set_attr "type" "branch") 12546 (set_attr "length" "4")]) 12547 12548(define_insn "*return_and_restore_gpregs_<mode>_r12" 12549 [(match_parallel 0 "any_parallel_operand" 12550 [(return) 12551 (clobber (match_operand:P 1 "register_operand" "=l")) 12552 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12553 (use (reg:P 12)) 12554 (set (match_operand:P 3 "gpc_reg_operand" "=r") 12555 (match_operand:P 4 "memory_operand" "m"))])] 12556 "" 12557 "b %2" 12558 [(set_attr "type" "branch") 12559 (set_attr "length" "4")]) 12560 12561(define_insn "*return_and_restore_gpregs_<mode>_r1" 12562 [(match_parallel 0 "any_parallel_operand" 12563 [(return) 12564 (clobber (match_operand:P 1 "register_operand" "=l")) 12565 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12566 (use (reg:P 1)) 12567 (set (match_operand:P 3 "gpc_reg_operand" "=r") 12568 (match_operand:P 4 "memory_operand" "m"))])] 12569 "" 12570 "b %2" 12571 [(set_attr "type" "branch") 12572 (set_attr "length" "4")]) 12573 12574(define_insn "*return_and_restore_fpregs_<mode>_r11" 12575 [(match_parallel 0 "any_parallel_operand" 12576 [(return) 12577 (clobber (match_operand:P 1 "register_operand" "=l")) 12578 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12579 (use (reg:P 11)) 12580 (set (match_operand:DF 3 "gpc_reg_operand" "=d") 12581 (match_operand:DF 4 "memory_operand" "m"))])] 12582 "" 12583 "b %2" 12584 [(set_attr "type" "branch") 12585 (set_attr "length" "4")]) 12586 12587(define_insn "*return_and_restore_fpregs_<mode>_r12" 12588 [(match_parallel 0 "any_parallel_operand" 12589 [(return) 12590 (clobber (match_operand:P 1 "register_operand" "=l")) 12591 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12592 (use (reg:P 12)) 12593 (set (match_operand:DF 3 "gpc_reg_operand" "=d") 12594 (match_operand:DF 4 "memory_operand" "m"))])] 12595 "" 12596 "b %2" 12597 [(set_attr "type" "branch") 12598 (set_attr "length" "4")]) 12599 12600(define_insn "*return_and_restore_fpregs_<mode>_r1" 12601 [(match_parallel 0 "any_parallel_operand" 12602 [(return) 12603 (clobber (match_operand:P 1 "register_operand" "=l")) 12604 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12605 (use (reg:P 1)) 12606 (set (match_operand:DF 3 "gpc_reg_operand" "=d") 12607 (match_operand:DF 4 "memory_operand" "m"))])] 12608 "" 12609 "b %2" 12610 [(set_attr "type" "branch") 12611 (set_attr "length" "4")]) 12612 12613(define_insn "*return_and_restore_fpregs_aix_<mode>_r11" 12614 [(match_parallel 0 "any_parallel_operand" 12615 [(return) 12616 (use (match_operand:P 1 "register_operand" "l")) 12617 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12618 (use (reg:P 11)) 12619 (set (match_operand:DF 3 "gpc_reg_operand" "=d") 12620 (match_operand:DF 4 "memory_operand" "m"))])] 12621 "" 12622 "b %2" 12623 [(set_attr "type" "branch") 12624 (set_attr "length" "4")]) 12625 12626(define_insn "*return_and_restore_fpregs_aix_<mode>_r1" 12627 [(match_parallel 0 "any_parallel_operand" 12628 [(return) 12629 (use (match_operand:P 1 "register_operand" "l")) 12630 (use (match_operand:P 2 "symbol_ref_operand" "s")) 12631 (use (reg:P 1)) 12632 (set (match_operand:DF 3 "gpc_reg_operand" "=d") 12633 (match_operand:DF 4 "memory_operand" "m"))])] 12634 "" 12635 "b %2" 12636 [(set_attr "type" "branch") 12637 (set_attr "length" "4")]) 12638 12639; This is used in compiling the unwind routines. 12640(define_expand "eh_return" 12641 [(use (match_operand 0 "general_operand" ""))] 12642 "" 12643 " 12644{ 12645 if (TARGET_32BIT) 12646 emit_insn (gen_eh_set_lr_si (operands[0])); 12647 else 12648 emit_insn (gen_eh_set_lr_di (operands[0])); 12649 DONE; 12650}") 12651 12652; We can't expand this before we know where the link register is stored. 12653(define_insn "eh_set_lr_<mode>" 12654 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 12655 UNSPECV_EH_RR) 12656 (clobber (match_scratch:P 1 "=&b"))] 12657 "" 12658 "#") 12659 12660(define_split 12661 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR) 12662 (clobber (match_scratch 1 ""))] 12663 "reload_completed" 12664 [(const_int 0)] 12665 " 12666{ 12667 rs6000_emit_eh_reg_restore (operands[0], operands[1]); 12668 DONE; 12669}") 12670 12671(define_insn "prefetch" 12672 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a") 12673 (match_operand:SI 1 "const_int_operand" "n") 12674 (match_operand:SI 2 "const_int_operand" "n"))] 12675 "" 12676 "* 12677{ 12678 if (GET_CODE (operands[0]) == REG) 12679 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\"; 12680 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\"; 12681}" 12682 [(set_attr "type" "load")]) 12683 12684;; Handle -fsplit-stack. 12685 12686(define_expand "split_stack_prologue" 12687 [(const_int 0)] 12688 "" 12689{ 12690 rs6000_expand_split_stack_prologue (); 12691 DONE; 12692}) 12693 12694(define_expand "load_split_stack_limit" 12695 [(set (match_operand 0) 12696 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))] 12697 "" 12698{ 12699 emit_insn (gen_rtx_SET (operands[0], 12700 gen_rtx_UNSPEC (Pmode, 12701 gen_rtvec (1, const0_rtx), 12702 UNSPEC_STACK_CHECK))); 12703 DONE; 12704}) 12705 12706(define_insn "load_split_stack_limit_di" 12707 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 12708 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))] 12709 "TARGET_64BIT" 12710 "ld %0,-0x7040(13)" 12711 [(set_attr "type" "load") 12712 (set_attr "update" "no") 12713 (set_attr "indexed" "no")]) 12714 12715(define_insn "load_split_stack_limit_si" 12716 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 12717 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))] 12718 "!TARGET_64BIT" 12719 "lwz %0,-0x7020(2)" 12720 [(set_attr "type" "load") 12721 (set_attr "update" "no") 12722 (set_attr "indexed" "no")]) 12723 12724;; A return instruction which the middle-end doesn't see. 12725;; Use r0 to stop regrename twiddling with lr restore insns emitted 12726;; after the call to __morestack. 12727(define_insn "split_stack_return" 12728 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)] 12729 "" 12730 "blr" 12731 [(set_attr "type" "jmpreg")]) 12732 12733;; If there are operand 0 bytes available on the stack, jump to 12734;; operand 1. 12735(define_expand "split_stack_space_check" 12736 [(set (match_dup 2) 12737 (unspec [(const_int 0)] UNSPEC_STACK_CHECK)) 12738 (set (match_dup 3) 12739 (minus (reg STACK_POINTER_REGNUM) 12740 (match_operand 0))) 12741 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2))) 12742 (set (pc) (if_then_else 12743 (geu (match_dup 4) (const_int 0)) 12744 (label_ref (match_operand 1)) 12745 (pc)))] 12746 "" 12747{ 12748 rs6000_split_stack_space_check (operands[0], operands[1]); 12749 DONE; 12750}) 12751 12752(define_insn "bpermd_<mode>" 12753 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12754 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") 12755 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))] 12756 "TARGET_POPCNTD" 12757 "bpermd %0,%1,%2" 12758 [(set_attr "type" "popcnt")]) 12759 12760 12761;; Builtin fma support. Handle 12762;; Note that the conditions for expansion are in the FMA_F iterator. 12763 12764(define_expand "fma<mode>4" 12765 [(set (match_operand:FMA_F 0 "register_operand" "") 12766 (fma:FMA_F 12767 (match_operand:FMA_F 1 "register_operand" "") 12768 (match_operand:FMA_F 2 "register_operand" "") 12769 (match_operand:FMA_F 3 "register_operand" "")))] 12770 "" 12771 "") 12772 12773(define_insn "*fma<mode>4_fpr" 12774 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 12775 (fma:SFDF 12776 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>") 12777 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 12778 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))] 12779 "TARGET_<MODE>_FPR" 12780 "@ 12781 fmadd<Ftrad> %0,%1,%2,%3 12782 xsmadda<Fvsx> %x0,%x1,%x2 12783 xsmaddm<Fvsx> %x0,%x1,%x3" 12784 [(set_attr "type" "fp") 12785 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 12786 12787; Altivec only has fma and nfms. 12788(define_expand "fms<mode>4" 12789 [(set (match_operand:FMA_F 0 "register_operand" "") 12790 (fma:FMA_F 12791 (match_operand:FMA_F 1 "register_operand" "") 12792 (match_operand:FMA_F 2 "register_operand" "") 12793 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" ""))))] 12794 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 12795 "") 12796 12797(define_insn "*fms<mode>4_fpr" 12798 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 12799 (fma:SFDF 12800 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") 12801 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 12802 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] 12803 "TARGET_<MODE>_FPR" 12804 "@ 12805 fmsub<Ftrad> %0,%1,%2,%3 12806 xsmsuba<Fvsx> %x0,%x1,%x2 12807 xsmsubm<Fvsx> %x0,%x1,%x3" 12808 [(set_attr "type" "fp") 12809 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 12810 12811;; If signed zeros are ignored, -(a * b - c) = -a * b + c. 12812(define_expand "fnma<mode>4" 12813 [(set (match_operand:FMA_F 0 "register_operand" "") 12814 (neg:FMA_F 12815 (fma:FMA_F 12816 (match_operand:FMA_F 1 "register_operand" "") 12817 (match_operand:FMA_F 2 "register_operand" "") 12818 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))] 12819 "!HONOR_SIGNED_ZEROS (<MODE>mode)" 12820 "") 12821 12822;; If signed zeros are ignored, -(a * b + c) = -a * b - c. 12823(define_expand "fnms<mode>4" 12824 [(set (match_operand:FMA_F 0 "register_operand" "") 12825 (neg:FMA_F 12826 (fma:FMA_F 12827 (match_operand:FMA_F 1 "register_operand" "") 12828 (match_operand:FMA_F 2 "register_operand" "") 12829 (match_operand:FMA_F 3 "register_operand" ""))))] 12830 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 12831 "") 12832 12833; Not an official optab name, but used from builtins. 12834(define_expand "nfma<mode>4" 12835 [(set (match_operand:FMA_F 0 "register_operand" "") 12836 (neg:FMA_F 12837 (fma:FMA_F 12838 (match_operand:FMA_F 1 "register_operand" "") 12839 (match_operand:FMA_F 2 "register_operand" "") 12840 (match_operand:FMA_F 3 "register_operand" ""))))] 12841 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 12842 "") 12843 12844(define_insn "*nfma<mode>4_fpr" 12845 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 12846 (neg:SFDF 12847 (fma:SFDF 12848 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") 12849 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 12850 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] 12851 "TARGET_<MODE>_FPR" 12852 "@ 12853 fnmadd<Ftrad> %0,%1,%2,%3 12854 xsnmadda<Fvsx> %x0,%x1,%x2 12855 xsnmaddm<Fvsx> %x0,%x1,%x3" 12856 [(set_attr "type" "fp") 12857 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 12858 12859; Not an official optab name, but used from builtins. 12860(define_expand "nfms<mode>4" 12861 [(set (match_operand:FMA_F 0 "register_operand" "") 12862 (neg:FMA_F 12863 (fma:FMA_F 12864 (match_operand:FMA_F 1 "register_operand" "") 12865 (match_operand:FMA_F 2 "register_operand" "") 12866 (neg:FMA_F (match_operand:FMA_F 3 "register_operand" "")))))] 12867 "" 12868 "") 12869 12870(define_insn "*nfmssf4_fpr" 12871 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 12872 (neg:SFDF 12873 (fma:SFDF 12874 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") 12875 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 12876 (neg:SFDF 12877 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))] 12878 "TARGET_<MODE>_FPR" 12879 "@ 12880 fnmsub<Ftrad> %0,%1,%2,%3 12881 xsnmsuba<Fvsx> %x0,%x1,%x2 12882 xsnmsubm<Fvsx> %x0,%x1,%x3" 12883 [(set_attr "type" "fp") 12884 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 12885 12886 12887(define_expand "rs6000_get_timebase" 12888 [(use (match_operand:DI 0 "gpc_reg_operand" ""))] 12889 "" 12890{ 12891 if (TARGET_POWERPC64) 12892 emit_insn (gen_rs6000_mftb_di (operands[0])); 12893 else 12894 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0])); 12895 DONE; 12896}) 12897 12898(define_insn "rs6000_get_timebase_ppc32" 12899 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 12900 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB)) 12901 (clobber (match_scratch:SI 1 "=r")) 12902 (clobber (match_scratch:CC 2 "=y"))] 12903 "!TARGET_POWERPC64" 12904{ 12905 if (WORDS_BIG_ENDIAN) 12906 if (TARGET_MFCRF) 12907 { 12908 return "mfspr %0,269\;" 12909 "mfspr %L0,268\;" 12910 "mfspr %1,269\;" 12911 "cmpw %2,%0,%1\;" 12912 "bne- %2,$-16"; 12913 } 12914 else 12915 { 12916 return "mftbu %0\;" 12917 "mftb %L0\;" 12918 "mftbu %1\;" 12919 "cmpw %2,%0,%1\;" 12920 "bne- %2,$-16"; 12921 } 12922 else 12923 if (TARGET_MFCRF) 12924 { 12925 return "mfspr %L0,269\;" 12926 "mfspr %0,268\;" 12927 "mfspr %1,269\;" 12928 "cmpw %2,%L0,%1\;" 12929 "bne- %2,$-16"; 12930 } 12931 else 12932 { 12933 return "mftbu %L0\;" 12934 "mftb %0\;" 12935 "mftbu %1\;" 12936 "cmpw %2,%L0,%1\;" 12937 "bne- %2,$-16"; 12938 } 12939} 12940 [(set_attr "length" "20")]) 12941 12942(define_insn "rs6000_mftb_<mode>" 12943 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12944 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))] 12945 "" 12946{ 12947 if (TARGET_MFCRF) 12948 return "mfspr %0,268"; 12949 else 12950 return "mftb %0"; 12951}) 12952 12953 12954(define_insn "rs6000_mffs" 12955 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 12956 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))] 12957 "TARGET_HARD_FLOAT && TARGET_FPRS" 12958 "mffs %0") 12959 12960(define_insn "rs6000_mtfsf" 12961 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i") 12962 (match_operand:DF 1 "gpc_reg_operand" "d")] 12963 UNSPECV_MTFSF)] 12964 "TARGET_HARD_FLOAT && TARGET_FPRS" 12965 "mtfsf %0,%1") 12966 12967 12968;; Power8 fusion support for fusing an addis instruction with a D-form load of 12969;; a GPR. The addis instruction must be adjacent to the load, and use the same 12970;; register that is being loaded. The fused ops must be physically adjacent. 12971 12972;; There are two parts to addis fusion. The support for fused TOCs occur 12973;; before register allocation, and is meant to reduce the lifetime for the 12974;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try 12975;; to use the register that is being load. The peephole2 then gathers any 12976;; other fused possibilities that it can find after register allocation. If 12977;; power9 fusion is selected, we also fuse floating point loads/stores. 12978 12979;; Fused TOC support: Replace simple GPR loads with a fused form. This is done 12980;; before register allocation, so that we can avoid allocating a temporary base 12981;; register that won't be used, and that we try to load into base registers, 12982;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion 12983;; (addis followed by load) even on power8. 12984 12985(define_split 12986 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "") 12987 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))] 12988 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()" 12989 [(parallel [(set (match_dup 0) (match_dup 2)) 12990 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) 12991 (use (match_dup 3)) 12992 (clobber (scratch:DI))])] 12993{ 12994 operands[2] = fusion_wrap_memory_address (operands[1]); 12995 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER); 12996}) 12997 12998(define_insn "*toc_fusionload_<mode>" 12999 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r") 13000 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG")) 13001 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) 13002 (use (match_operand:DI 2 "base_reg_operand" "r,r")) 13003 (clobber (match_scratch:DI 3 "=X,&b"))] 13004 "TARGET_TOC_FUSION_INT" 13005{ 13006 if (base_reg_operand (operands[0], <MODE>mode)) 13007 return emit_fusion_gpr_load (operands[0], operands[1]); 13008 13009 return emit_fusion_p9_load (operands[0], operands[1], operands[3]); 13010} 13011 [(set_attr "type" "load") 13012 (set_attr "length" "8")]) 13013 13014(define_insn "*toc_fusionload_di" 13015 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d") 13016 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG")) 13017 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) 13018 (use (match_operand:DI 2 "base_reg_operand" "r,r,r")) 13019 (clobber (match_scratch:DI 3 "=X,&b,&b"))] 13020 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64 13021 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))" 13022{ 13023 if (base_reg_operand (operands[0], DImode)) 13024 return emit_fusion_gpr_load (operands[0], operands[1]); 13025 13026 return emit_fusion_p9_load (operands[0], operands[1], operands[3]); 13027} 13028 [(set_attr "type" "load") 13029 (set_attr "length" "8")]) 13030 13031 13032;; Find cases where the addis that feeds into a load instruction is either used 13033;; once or is the same as the target register, and replace it with the fusion 13034;; insn 13035 13036(define_peephole2 13037 [(set (match_operand:P 0 "base_reg_operand" "") 13038 (match_operand:P 1 "fusion_gpr_addis" "")) 13039 (set (match_operand:INT1 2 "base_reg_operand" "") 13040 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))] 13041 "TARGET_P8_FUSION 13042 && fusion_gpr_load_p (operands[0], operands[1], operands[2], 13043 operands[3])" 13044 [(const_int 0)] 13045{ 13046 expand_fusion_gpr_load (operands); 13047 DONE; 13048}) 13049 13050;; Fusion insn, created by the define_peephole2 above (and eventually by 13051;; reload) 13052 13053(define_insn "fusion_gpr_load_<mode>" 13054 [(set (match_operand:INT1 0 "base_reg_operand" "=b") 13055 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")] 13056 UNSPEC_FUSION_GPR))] 13057 "TARGET_P8_FUSION" 13058{ 13059 return emit_fusion_gpr_load (operands[0], operands[1]); 13060} 13061 [(set_attr "type" "load") 13062 (set_attr "length" "8")]) 13063 13064 13065;; ISA 3.0 (power9) fusion support 13066;; Merge addis with floating load/store to FPRs (or GPRs). 13067(define_peephole2 13068 [(set (match_operand:P 0 "base_reg_operand" "") 13069 (match_operand:P 1 "fusion_gpr_addis" "")) 13070 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "") 13071 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))] 13072 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0]) 13073 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])" 13074 [(const_int 0)] 13075{ 13076 expand_fusion_p9_load (operands); 13077 DONE; 13078}) 13079 13080(define_peephole2 13081 [(set (match_operand:P 0 "base_reg_operand" "") 13082 (match_operand:P 1 "fusion_gpr_addis" "")) 13083 (set (match_operand:SFDF 2 "offsettable_mem_operand" "") 13084 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))] 13085 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0]) 13086 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3]) 13087 && !rtx_equal_p (operands[0], operands[3])" 13088 [(const_int 0)] 13089{ 13090 expand_fusion_p9_store (operands); 13091 DONE; 13092}) 13093 13094(define_peephole2 13095 [(set (match_operand:SDI 0 "int_reg_operand" "") 13096 (match_operand:SDI 1 "upper16_cint_operand" "")) 13097 (set (match_dup 0) 13098 (ior:SDI (match_dup 0) 13099 (match_operand:SDI 2 "u_short_cint_operand" "")))] 13100 "TARGET_P9_FUSION" 13101 [(set (match_dup 0) 13102 (unspec:SDI [(match_dup 1) 13103 (match_dup 2)] UNSPEC_FUSION_P9))]) 13104 13105(define_peephole2 13106 [(set (match_operand:SDI 0 "int_reg_operand" "") 13107 (match_operand:SDI 1 "upper16_cint_operand" "")) 13108 (set (match_operand:SDI 2 "int_reg_operand" "") 13109 (ior:SDI (match_dup 0) 13110 (match_operand:SDI 3 "u_short_cint_operand" "")))] 13111 "TARGET_P9_FUSION 13112 && !rtx_equal_p (operands[0], operands[2]) 13113 && peep2_reg_dead_p (2, operands[0])" 13114 [(set (match_dup 2) 13115 (unspec:SDI [(match_dup 1) 13116 (match_dup 3)] UNSPEC_FUSION_P9))]) 13117 13118;; Fusion insns, created by the define_peephole2 above (and eventually by 13119;; reload). Because we want to eventually have secondary_reload generate 13120;; these, they have to have a single alternative that gives the register 13121;; classes. This means we need to have separate gpr/fpr/altivec versions. 13122(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load" 13123 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r") 13124 (unspec:GPR_FUSION 13125 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")] 13126 UNSPEC_FUSION_P9)) 13127 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 13128 "TARGET_P9_FUSION" 13129{ 13130 /* This insn is a secondary reload insn, which cannot have alternatives. 13131 If we are not loading up register 0, use the power8 fusion instead. */ 13132 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode)) 13133 return emit_fusion_gpr_load (operands[0], operands[1]); 13134 13135 return emit_fusion_p9_load (operands[0], operands[1], operands[2]); 13136} 13137 [(set_attr "type" "load") 13138 (set_attr "length" "8")]) 13139 13140(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store" 13141 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF") 13142 (unspec:GPR_FUSION 13143 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")] 13144 UNSPEC_FUSION_P9)) 13145 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 13146 "TARGET_P9_FUSION" 13147{ 13148 return emit_fusion_p9_store (operands[0], operands[1], operands[2]); 13149} 13150 [(set_attr "type" "store") 13151 (set_attr "length" "8")]) 13152 13153(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load" 13154 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb") 13155 (unspec:FPR_FUSION 13156 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")] 13157 UNSPEC_FUSION_P9)) 13158 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 13159 "TARGET_P9_FUSION" 13160{ 13161 return emit_fusion_p9_load (operands[0], operands[1], operands[2]); 13162} 13163 [(set_attr "type" "fpload") 13164 (set_attr "length" "8")]) 13165 13166(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store" 13167 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF") 13168 (unspec:FPR_FUSION 13169 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")] 13170 UNSPEC_FUSION_P9)) 13171 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 13172 "TARGET_P9_FUSION" 13173{ 13174 return emit_fusion_p9_store (operands[0], operands[1], operands[2]); 13175} 13176 [(set_attr "type" "fpstore") 13177 (set_attr "length" "8")]) 13178 13179(define_insn "*fusion_p9_<mode>_constant" 13180 [(set (match_operand:SDI 0 "int_reg_operand" "=r") 13181 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L") 13182 (match_operand:SDI 2 "u_short_cint_operand" "K")] 13183 UNSPEC_FUSION_P9))] 13184 "TARGET_P9_FUSION" 13185{ 13186 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>"); 13187 return "ori %0,%0,%2"; 13188} 13189 [(set_attr "type" "two") 13190 (set_attr "length" "8")]) 13191 13192 13193;; Optimize cases where we want to do a D-form load (register+offset) on 13194;; ISA 2.06/2.07 to an Altivec register, and the register allocator 13195;; has generated: 13196;; load fpr 13197;; move fpr->altivec 13198 13199(define_peephole2 13200 [(match_scratch:P 0 "b") 13201 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 13202 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand")) 13203 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand") 13204 (match_dup 1))] 13205 "TARGET_VSX && TARGET_UPPER_REGS_<MODE> && !TARGET_P9_DFORM_SCALAR 13206 && peep2_reg_dead_p (2, operands[1])" 13207 [(set (match_dup 0) 13208 (match_dup 4)) 13209 (set (match_dup 3) 13210 (match_dup 5))] 13211{ 13212 rtx tmp_reg = operands[0]; 13213 rtx mem = operands[2]; 13214 rtx addr = XEXP (mem, 0); 13215 rtx add_op0, add_op1, new_addr; 13216 13217 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 13218 add_op0 = XEXP (addr, 0); 13219 add_op1 = XEXP (addr, 1); 13220 gcc_assert (REG_P (add_op0)); 13221 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); 13222 13223 operands[4] = add_op1; 13224 operands[5] = change_address (mem, <MODE>mode, new_addr); 13225}) 13226 13227;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an 13228;; Altivec register, and the register allocator has generated: 13229;; move altivec->fpr 13230;; store fpr 13231 13232(define_peephole2 13233 [(match_scratch:P 0 "b") 13234 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 13235 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand")) 13236 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand") 13237 (match_dup 1))] 13238 "TARGET_VSX && TARGET_UPPER_REGS_<MODE> && !TARGET_P9_DFORM_SCALAR 13239 && peep2_reg_dead_p (2, operands[1])" 13240 [(set (match_dup 0) 13241 (match_dup 4)) 13242 (set (match_dup 5) 13243 (match_dup 2))] 13244{ 13245 rtx tmp_reg = operands[0]; 13246 rtx mem = operands[3]; 13247 rtx addr = XEXP (mem, 0); 13248 rtx add_op0, add_op1, new_addr; 13249 13250 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 13251 add_op0 = XEXP (addr, 0); 13252 add_op1 = XEXP (addr, 1); 13253 gcc_assert (REG_P (add_op0)); 13254 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); 13255 13256 operands[4] = add_op1; 13257 operands[5] = change_address (mem, <MODE>mode, new_addr); 13258}) 13259 13260 13261;; Miscellaneous ISA 2.06 (power7) instructions 13262(define_insn "addg6s" 13263 [(set (match_operand:SI 0 "register_operand" "=r") 13264 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 13265 (match_operand:SI 2 "register_operand" "r")] 13266 UNSPEC_ADDG6S))] 13267 "TARGET_POPCNTD" 13268 "addg6s %0,%1,%2" 13269 [(set_attr "type" "integer") 13270 (set_attr "length" "4")]) 13271 13272(define_insn "cdtbcd" 13273 [(set (match_operand:SI 0 "register_operand" "=r") 13274 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 13275 UNSPEC_CDTBCD))] 13276 "TARGET_POPCNTD" 13277 "cdtbcd %0,%1" 13278 [(set_attr "type" "integer") 13279 (set_attr "length" "4")]) 13280 13281(define_insn "cbcdtd" 13282 [(set (match_operand:SI 0 "register_operand" "=r") 13283 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 13284 UNSPEC_CBCDTD))] 13285 "TARGET_POPCNTD" 13286 "cbcdtd %0,%1" 13287 [(set_attr "type" "integer") 13288 (set_attr "length" "4")]) 13289 13290(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE 13291 UNSPEC_DIVEU]) 13292 13293(define_int_attr div_extend [(UNSPEC_DIVE "e") 13294 (UNSPEC_DIVEU "eu")]) 13295 13296(define_insn "div<div_extend>_<mode>" 13297 [(set (match_operand:GPR 0 "register_operand" "=r") 13298 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r") 13299 (match_operand:GPR 2 "register_operand" "r")] 13300 UNSPEC_DIV_EXTEND))] 13301 "TARGET_POPCNTD" 13302 "div<wd><div_extend> %0,%1,%2" 13303 [(set_attr "type" "div") 13304 (set_attr "size" "<bits>")]) 13305 13306 13307;; Pack/unpack 128-bit floating point types that take 2 scalar registers 13308 13309; Type of the 64-bit part when packing/unpacking 128-bit floating point types 13310(define_mode_attr FP128_64 [(TF "DF") 13311 (IF "DF") 13312 (TD "DI") 13313 (KF "DI")]) 13314 13315(define_expand "unpack<mode>" 13316 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "") 13317 (unspec:<FP128_64> 13318 [(match_operand:FMOVE128 1 "register_operand" "") 13319 (match_operand:QI 2 "const_0_to_1_operand" "")] 13320 UNSPEC_UNPACK_128BIT))] 13321 "FLOAT128_2REG_P (<MODE>mode)" 13322 "") 13323 13324(define_insn_and_split "unpack<mode>_dm" 13325 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m") 13326 (unspec:<FP128_64> 13327 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r") 13328 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")] 13329 UNSPEC_UNPACK_128BIT))] 13330 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)" 13331 "#" 13332 "&& reload_completed" 13333 [(set (match_dup 0) (match_dup 3))] 13334{ 13335 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 13336 13337 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 13338 { 13339 emit_note (NOTE_INSN_DELETED); 13340 DONE; 13341 } 13342 13343 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 13344} 13345 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store") 13346 (set_attr "length" "4")]) 13347 13348(define_insn_and_split "unpack<mode>_nodm" 13349 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m") 13350 (unspec:<FP128_64> 13351 [(match_operand:FMOVE128 1 "register_operand" "d,d") 13352 (match_operand:QI 2 "const_0_to_1_operand" "i,i")] 13353 UNSPEC_UNPACK_128BIT))] 13354 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)" 13355 "#" 13356 "&& reload_completed" 13357 [(set (match_dup 0) (match_dup 3))] 13358{ 13359 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 13360 13361 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 13362 { 13363 emit_note (NOTE_INSN_DELETED); 13364 DONE; 13365 } 13366 13367 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 13368} 13369 [(set_attr "type" "fp,fpstore") 13370 (set_attr "length" "4")]) 13371 13372(define_insn_and_split "pack<mode>" 13373 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d") 13374 (unspec:FMOVE128 13375 [(match_operand:<FP128_64> 1 "register_operand" "0,d") 13376 (match_operand:<FP128_64> 2 "register_operand" "d,d")] 13377 UNSPEC_PACK_128BIT))] 13378 "FLOAT128_2REG_P (<MODE>mode)" 13379 "@ 13380 fmr %L0,%2 13381 #" 13382 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])" 13383 [(set (match_dup 3) (match_dup 1)) 13384 (set (match_dup 4) (match_dup 2))] 13385{ 13386 unsigned dest_hi = REGNO (operands[0]); 13387 unsigned dest_lo = dest_hi + 1; 13388 13389 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo)); 13390 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); 13391 13392 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); 13393 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); 13394} 13395 [(set_attr "type" "fpsimple,fp") 13396 (set_attr "length" "4,8")]) 13397 13398(define_insn "unpack<mode>" 13399 [(set (match_operand:DI 0 "register_operand" "=d,d") 13400 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa") 13401 (match_operand:QI 2 "const_0_to_1_operand" "O,i")] 13402 UNSPEC_UNPACK_128BIT))] 13403 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 13404{ 13405 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0) 13406 return ASM_COMMENT_START " xxpermdi to same register"; 13407 13408 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3); 13409 return "xxpermdi %x0,%x1,%x1,%3"; 13410} 13411 [(set_attr "type" "vecperm")]) 13412 13413(define_insn "pack<mode>" 13414 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa") 13415 (unspec:FMOVE128_VSX 13416 [(match_operand:DI 1 "register_operand" "d") 13417 (match_operand:DI 2 "register_operand" "d")] 13418 UNSPEC_PACK_128BIT))] 13419 "TARGET_VSX" 13420 "xxpermdi %x0,%x1,%x2,0" 13421 [(set_attr "type" "vecperm")]) 13422 13423 13424 13425;; ISA 2.08 IEEE 128-bit floating point support. 13426 13427(define_insn "add<mode>3" 13428 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13429 (plus:IEEE128 13430 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13431 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13432 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13433 "xsaddqp %0,%1,%2" 13434 [(set_attr "type" "vecfloat") 13435 (set_attr "size" "128")]) 13436 13437(define_insn "sub<mode>3" 13438 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13439 (minus:IEEE128 13440 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13441 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13442 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13443 "xssubqp %0,%1,%2" 13444 [(set_attr "type" "vecfloat") 13445 (set_attr "size" "128")]) 13446 13447(define_insn "mul<mode>3" 13448 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13449 (mult:IEEE128 13450 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13451 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13452 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13453 "xsmulqp %0,%1,%2" 13454 [(set_attr "type" "vecfloat") 13455 (set_attr "size" "128")]) 13456 13457(define_insn "div<mode>3" 13458 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13459 (div:IEEE128 13460 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13461 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13462 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13463 "xsdivqp %0,%1,%2" 13464 [(set_attr "type" "vecdiv") 13465 (set_attr "size" "128")]) 13466 13467(define_insn "sqrt<mode>2" 13468 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13469 (sqrt:IEEE128 13470 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 13471 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13472 "xssqrtqp %0,%1" 13473 [(set_attr "type" "vecdiv") 13474 (set_attr "size" "128")]) 13475 13476(define_expand "copysign<mode>3" 13477 [(use (match_operand:IEEE128 0 "altivec_register_operand")) 13478 (use (match_operand:IEEE128 1 "altivec_register_operand")) 13479 (use (match_operand:IEEE128 2 "altivec_register_operand"))] 13480 "FLOAT128_IEEE_P (<MODE>mode)" 13481{ 13482 if (TARGET_FLOAT128_HW) 13483 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1], 13484 operands[2])); 13485 else 13486 { 13487 rtx tmp = gen_reg_rtx (<MODE>mode); 13488 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1], 13489 operands[2], tmp)); 13490 } 13491 DONE; 13492}) 13493 13494(define_insn "copysign<mode>3_hard" 13495 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13496 (unspec:IEEE128 13497 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 13498 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 13499 UNSPEC_COPYSIGN))] 13500 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13501 "xscpsgnqp %0,%2,%1" 13502 [(set_attr "type" "vecmove") 13503 (set_attr "size" "128")]) 13504 13505(define_insn "copysign<mode>3_soft" 13506 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13507 (unspec:IEEE128 13508 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 13509 (match_operand:IEEE128 2 "altivec_register_operand" "v") 13510 (match_operand:IEEE128 3 "altivec_register_operand" "+v")] 13511 UNSPEC_COPYSIGN))] 13512 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13513 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1" 13514 [(set_attr "type" "veccomplex") 13515 (set_attr "length" "8")]) 13516 13517(define_insn "neg<mode>2_hw" 13518 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13519 (neg:IEEE128 13520 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 13521 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13522 "xsnegqp %0,%1" 13523 [(set_attr "type" "vecmove") 13524 (set_attr "size" "128")]) 13525 13526 13527(define_insn "abs<mode>2_hw" 13528 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13529 (abs:IEEE128 13530 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 13531 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13532 "xsabsqp %0,%1" 13533 [(set_attr "type" "vecmove") 13534 (set_attr "size" "128")]) 13535 13536 13537(define_insn "*nabs<mode>2_hw" 13538 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13539 (neg:IEEE128 13540 (abs:IEEE128 13541 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))] 13542 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13543 "xsnabsqp %0,%1" 13544 [(set_attr "type" "vecmove") 13545 (set_attr "size" "128")]) 13546 13547;; Initially don't worry about doing fusion 13548(define_insn "*fma<mode>4_hw" 13549 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13550 (fma:IEEE128 13551 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 13552 (match_operand:IEEE128 2 "altivec_register_operand" "v") 13553 (match_operand:IEEE128 3 "altivec_register_operand" "0")))] 13554 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13555 "xsmaddqp %0,%1,%2" 13556 [(set_attr "type" "vecfloat") 13557 (set_attr "size" "128")]) 13558 13559(define_insn "*fms<mode>4_hw" 13560 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13561 (fma:IEEE128 13562 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 13563 (match_operand:IEEE128 2 "altivec_register_operand" "v") 13564 (neg:IEEE128 13565 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 13566 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13567 "xsmsubqp %0,%1,%2" 13568 [(set_attr "type" "vecfloat") 13569 (set_attr "size" "128")]) 13570 13571(define_insn "*nfma<mode>4_hw" 13572 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13573 (neg:IEEE128 13574 (fma:IEEE128 13575 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 13576 (match_operand:IEEE128 2 "altivec_register_operand" "v") 13577 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 13578 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13579 "xsnmaddqp %0,%1,%2" 13580 [(set_attr "type" "vecfloat") 13581 (set_attr "size" "128")]) 13582 13583(define_insn "*nfms<mode>4_hw" 13584 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13585 (neg:IEEE128 13586 (fma:IEEE128 13587 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 13588 (match_operand:IEEE128 2 "altivec_register_operand" "v") 13589 (neg:IEEE128 13590 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))] 13591 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13592 "xsnmsubqp %0,%1,%2" 13593 [(set_attr "type" "vecfloat") 13594 (set_attr "size" "128")]) 13595 13596(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw" 13597 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13598 (float_extend:IEEE128 13599 (match_operand:SFDF 1 "altivec_register_operand" "v")))] 13600 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 13601 "xscvdpqp %0,%1" 13602 [(set_attr "type" "vecfloat") 13603 (set_attr "size" "128")]) 13604 13605;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating 13606;; point is a simple copy. 13607(define_insn_and_split "extendkftf2" 13608 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa") 13609 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))] 13610 "TARGET_FLOAT128 && TARGET_IEEEQUAD" 13611 "@ 13612 # 13613 xxlor %x0,%x1,%x1" 13614 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 13615 [(const_int 0)] 13616{ 13617 emit_note (NOTE_INSN_DELETED); 13618 DONE; 13619} 13620 [(set_attr "type" "*,veclogical") 13621 (set_attr "length" "0,4")]) 13622 13623(define_insn_and_split "trunctfkf2" 13624 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa") 13625 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))] 13626 "TARGET_FLOAT128 && TARGET_IEEEQUAD" 13627 "@ 13628 # 13629 xxlor %x0,%x1,%x1" 13630 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 13631 [(const_int 0)] 13632{ 13633 emit_note (NOTE_INSN_DELETED); 13634 DONE; 13635} 13636 [(set_attr "type" "*,veclogical") 13637 (set_attr "length" "0,4")]) 13638 13639(define_insn "trunc<mode>df2_hw" 13640 [(set (match_operand:DF 0 "altivec_register_operand" "=v") 13641 (float_truncate:DF 13642 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 13643 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13644 "xscvqpdp %0,%1" 13645 [(set_attr "type" "vecfloat") 13646 (set_attr "size" "128")]) 13647 13648;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing 13649;; the KFmode -> DFmode conversion using round to odd rather than the normal 13650;; conversion 13651(define_insn_and_split "trunc<mode>sf2_hw" 13652 [(set (match_operand:SF 0 "vsx_register_operand" "=wy") 13653 (float_truncate:SF 13654 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 13655 (clobber (match_scratch:DF 2 "=v"))] 13656 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13657 "#" 13658 "&& 1" 13659 [(set (match_dup 2) 13660 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD)) 13661 (set (match_dup 0) 13662 (float_truncate:SF (match_dup 2)))] 13663{ 13664 if (GET_CODE (operands[2]) == SCRATCH) 13665 operands[2] = gen_reg_rtx (DFmode); 13666} 13667 [(set_attr "type" "vecfloat") 13668 (set_attr "length" "8")]) 13669 13670;; At present SImode is not allowed in VSX registers at all, and DImode is only 13671;; allowed in the traditional floating point registers. Use V2DImode so that 13672;; we can get a value in an Altivec register. 13673 13674(define_insn_and_split "fix<uns>_<mode>si2_hw" 13675 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,Z") 13676 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v,v"))) 13677 (clobber (match_scratch:V2DI 2 "=v,v"))] 13678 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13679 "#" 13680 "&& 1" 13681 [(pc)] 13682{ 13683 convert_float128_to_int (operands, <CODE>); 13684 DONE; 13685} 13686 [(set_attr "length" "8") 13687 (set_attr "type" "mftgpr,fpstore")]) 13688 13689(define_insn_and_split "fix<uns>_<mode>di2_hw" 13690 [(set (match_operand:DI 0 "nonimmediate_operand" "=wr,wi,Z") 13691 (any_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v,v,v"))) 13692 (clobber (match_scratch:V2DI 2 "=v,v,v"))] 13693 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13694 "#" 13695 "&& 1" 13696 [(pc)] 13697{ 13698 convert_float128_to_int (operands, <CODE>); 13699 DONE; 13700} 13701 [(set_attr "length" "8") 13702 (set_attr "type" "mftgpr,vecsimple,fpstore")]) 13703 13704(define_insn_and_split "float<uns>_<mode>si2_hw" 13705 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v") 13706 (any_float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "r,Z"))) 13707 (clobber (match_scratch:V2DI 2 "=v,v"))] 13708 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13709 "#" 13710 "&& 1" 13711 [(pc)] 13712{ 13713 convert_int_to_float128 (operands, <CODE>); 13714 DONE; 13715} 13716 [(set_attr "length" "8") 13717 (set_attr "type" "vecfloat")]) 13718 13719(define_insn_and_split "float<uns>_<mode>di2_hw" 13720 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 13721 (any_float:IEEE128 (match_operand:DI 1 "nonimmediate_operand" "wi,wr,Z"))) 13722 (clobber (match_scratch:V2DI 2 "=v,v,v"))] 13723 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13724 "#" 13725 "&& 1" 13726 [(pc)] 13727{ 13728 convert_int_to_float128 (operands, <CODE>); 13729 DONE; 13730} 13731 [(set_attr "length" "8") 13732 (set_attr "type" "vecfloat")]) 13733 13734;; Integer conversion instructions, using V2DImode to get an Altivec register 13735(define_insn "*xscvqp<su>wz_<mode>" 13736 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v") 13737 (unspec:V2DI 13738 [(any_fix:SI 13739 (match_operand:IEEE128 1 "altivec_register_operand" "v"))] 13740 UNSPEC_IEEE128_CONVERT))] 13741 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13742 "xscvqp<su>wz %0,%1" 13743 [(set_attr "type" "vecfloat") 13744 (set_attr "size" "128")]) 13745 13746(define_insn "*xscvqp<su>dz_<mode>" 13747 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v") 13748 (unspec:V2DI 13749 [(any_fix:DI 13750 (match_operand:IEEE128 1 "altivec_register_operand" "v"))] 13751 UNSPEC_IEEE128_CONVERT))] 13752 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13753 "xscvqp<su>dz %0,%1" 13754 [(set_attr "type" "vecfloat") 13755 (set_attr "size" "128")]) 13756 13757(define_insn "*xscv<su>dqp_<mode>" 13758 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13759 (any_float:IEEE128 13760 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v")] 13761 UNSPEC_IEEE128_CONVERT)))] 13762 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13763 "xscv<su>dqp %0,%1" 13764 [(set_attr "type" "vecfloat") 13765 (set_attr "size" "128")]) 13766 13767(define_insn "*ieee128_mfvsrd_64bit" 13768 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=wr,Z,wi") 13769 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v,v")] 13770 UNSPEC_IEEE128_MOVE))] 13771 "TARGET_FLOAT128_HW && TARGET_POWERPC64" 13772 "@ 13773 mfvsrd %0,%x1 13774 stxsdx %x1,%y0 13775 xxlor %x0,%x1,%x1" 13776 [(set_attr "type" "mftgpr,fpstore,veclogical")]) 13777 13778 13779(define_insn "*ieee128_mfvsrd_32bit" 13780 [(set (match_operand:DI 0 "reg_or_indexed_operand" "=Z,wi") 13781 (unspec:DI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")] 13782 UNSPEC_IEEE128_MOVE))] 13783 "TARGET_FLOAT128_HW && !TARGET_POWERPC64" 13784 "@ 13785 stxsdx %x1,%y0 13786 xxlor %x0,%x1,%x1" 13787 [(set_attr "type" "fpstore,veclogical")]) 13788 13789(define_insn "*ieee128_mfvsrwz" 13790 [(set (match_operand:SI 0 "reg_or_indexed_operand" "=r,Z") 13791 (unspec:SI [(match_operand:V2DI 1 "altivec_register_operand" "v,v")] 13792 UNSPEC_IEEE128_MOVE))] 13793 "TARGET_FLOAT128_HW" 13794 "@ 13795 mfvsrwz %0,%x1 13796 stxsiwx %x1,%y0" 13797 [(set_attr "type" "mftgpr,fpstore")]) 13798 13799;; 0 says do sign-extension, 1 says zero-extension 13800(define_insn "*ieee128_mtvsrw" 13801 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v,v") 13802 (unspec:V2DI [(match_operand:SI 1 "nonimmediate_operand" "r,Z,r,Z") 13803 (match_operand:SI 2 "const_0_to_1_operand" "O,O,n,n")] 13804 UNSPEC_IEEE128_MOVE))] 13805 "TARGET_FLOAT128_HW" 13806 "@ 13807 mtvsrwa %x0,%1 13808 lxsiwax %x0,%y1 13809 mtvsrwz %x0,%1 13810 lxsiwzx %x0,%y1" 13811 [(set_attr "type" "mffgpr,fpload,mffgpr,fpload")]) 13812 13813 13814(define_insn "*ieee128_mtvsrd_64bit" 13815 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v,v") 13816 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "wr,Z,wi")] 13817 UNSPEC_IEEE128_MOVE))] 13818 "TARGET_FLOAT128_HW && TARGET_POWERPC64" 13819 "@ 13820 mtvsrd %x0,%1 13821 lxsdx %x0,%y1 13822 xxlor %x0,%x1,%x1" 13823 [(set_attr "type" "mffgpr,fpload,veclogical")]) 13824 13825(define_insn "*ieee128_mtvsrd_32bit" 13826 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v,v") 13827 (unspec:V2DI [(match_operand:DI 1 "nonimmediate_operand" "Z,wi")] 13828 UNSPEC_IEEE128_MOVE))] 13829 "TARGET_FLOAT128_HW && !TARGET_POWERPC64" 13830 "@ 13831 lxsdx %x0,%y1 13832 xxlor %x0,%x1,%x1" 13833 [(set_attr "type" "fpload,veclogical")]) 13834 13835;; IEEE 128-bit instructions with round to odd semantics 13836(define_insn "*trunc<mode>df2_odd" 13837 [(set (match_operand:DF 0 "vsx_register_operand" "=v") 13838 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 13839 UNSPEC_ROUND_TO_ODD))] 13840 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13841 "xscvqpdpo %0,%1" 13842 [(set_attr "type" "vecfloat") 13843 (set_attr "size" "128")]) 13844 13845;; IEEE 128-bit comparisons 13846(define_insn "*cmp<mode>_hw" 13847 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 13848 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v") 13849 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13850 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13851 "xscmpuqp %0,%1,%2" 13852 [(set_attr "type" "veccmp") 13853 (set_attr "size" "128")]) 13854 13855 13856 13857(include "sync.md") 13858(include "vector.md") 13859(include "vsx.md") 13860(include "altivec.md") 13861(include "spe.md") 13862(include "dfp.md") 13863(include "paired.md") 13864(include "crypto.md") 13865(include "htm.md") 13866