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 (FRAME_POINTER_REGNUM 111) 54 (TFHAR_REGNO 112) 55 (TFIAR_REGNO 113) 56 (TEXASR_REGNO 114) 57 ]) 58 59;; 60;; UNSPEC usage 61;; 62 63(define_c_enum "unspec" 64 [UNSPEC_FRSP ; frsp for POWER machines 65 UNSPEC_PROBE_STACK ; probe stack memory reference 66 UNSPEC_TOCPTR ; address of a word pointing to the TOC 67 UNSPEC_TOC ; address of the TOC (more-or-less) 68 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot 69 UNSPEC_MOVSI_GOT 70 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit 71 UNSPEC_FCTIWZ 72 UNSPEC_FRIM 73 UNSPEC_FRIN 74 UNSPEC_FRIP 75 UNSPEC_FRIZ 76 UNSPEC_XSRDPI 77 UNSPEC_LD_MPIC ; load_macho_picbase 78 UNSPEC_RELD_MPIC ; re-load_macho_picbase 79 UNSPEC_MPIC_CORRECT ; macho_correct_pic 80 UNSPEC_TLSGD 81 UNSPEC_TLSLD 82 UNSPEC_MOVESI_FROM_CR 83 UNSPEC_MOVESI_TO_CR 84 UNSPEC_TLSDTPREL 85 UNSPEC_TLSDTPRELHA 86 UNSPEC_TLSDTPRELLO 87 UNSPEC_TLSGOTDTPREL 88 UNSPEC_TLSTPREL 89 UNSPEC_TLSTPRELHA 90 UNSPEC_TLSTPRELLO 91 UNSPEC_TLSGOTTPREL 92 UNSPEC_TLSTLS 93 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero 94 UNSPEC_STFIWX 95 UNSPEC_POPCNTB 96 UNSPEC_FRES 97 UNSPEC_SP_SET 98 UNSPEC_SP_TEST 99 UNSPEC_SYNC 100 UNSPEC_LWSYNC 101 UNSPEC_SYNC_OP 102 UNSPEC_ATOMIC 103 UNSPEC_CMPXCHG 104 UNSPEC_XCHG 105 UNSPEC_AND 106 UNSPEC_DLMZB 107 UNSPEC_DLMZB_CR 108 UNSPEC_DLMZB_STRLEN 109 UNSPEC_RSQRT 110 UNSPEC_TOCREL 111 UNSPEC_MACHOPIC_OFFSET 112 UNSPEC_BPERM 113 UNSPEC_COPYSIGN 114 UNSPEC_PARITY 115 UNSPEC_CMPB 116 UNSPEC_FCTIW 117 UNSPEC_FCTID 118 UNSPEC_LFIWAX 119 UNSPEC_LFIWZX 120 UNSPEC_FCTIWUZ 121 UNSPEC_NOP 122 UNSPEC_GRP_END_NOP 123 UNSPEC_P8V_FMRGOW 124 UNSPEC_P8V_MTVSRWZ 125 UNSPEC_P8V_RELOAD_FROM_GPR 126 UNSPEC_P8V_MTVSRD 127 UNSPEC_P8V_XXPERMDI 128 UNSPEC_P8V_RELOAD_FROM_VSX 129 UNSPEC_ADDG6S 130 UNSPEC_CDTBCD 131 UNSPEC_CBCDTD 132 UNSPEC_DIVE 133 UNSPEC_DIVEU 134 UNSPEC_UNPACK_128BIT 135 UNSPEC_PACK_128BIT 136 UNSPEC_LSQ 137 UNSPEC_FUSION_GPR 138 UNSPEC_STACK_CHECK 139 UNSPEC_CMPRB 140 UNSPEC_CMPRB2 141 UNSPEC_CMPEQB 142 UNSPEC_FUSION_P9 143 UNSPEC_FUSION_ADDIS 144 UNSPEC_ADD_ROUND_TO_ODD 145 UNSPEC_SUB_ROUND_TO_ODD 146 UNSPEC_MUL_ROUND_TO_ODD 147 UNSPEC_DIV_ROUND_TO_ODD 148 UNSPEC_FMA_ROUND_TO_ODD 149 UNSPEC_SQRT_ROUND_TO_ODD 150 UNSPEC_TRUNC_ROUND_TO_ODD 151 UNSPEC_SIGNBIT 152 UNSPEC_SF_FROM_SI 153 UNSPEC_SI_FROM_SF 154 ]) 155 156;; 157;; UNSPEC_VOLATILE usage 158;; 159 160(define_c_enum "unspecv" 161 [UNSPECV_BLOCK 162 UNSPECV_LL ; load-locked 163 UNSPECV_SC ; store-conditional 164 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses 165 UNSPECV_EH_RR ; eh_reg_restore 166 UNSPECV_ISYNC ; isync instruction 167 UNSPECV_MFTB ; move from time base 168 UNSPECV_DARN ; darn 1 (deliver a random number) 169 UNSPECV_DARN_32 ; darn 2 170 UNSPECV_DARN_RAW ; darn 0 171 UNSPECV_NLGR ; non-local goto receiver 172 UNSPECV_MFFS ; Move from FPSCR 173 UNSPECV_MTFSF ; Move to FPSCR Fields 174 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return 175 UNSPECV_SPEC_BARRIER ; Speculation barrier 176 ]) 177 178 179;; Define an insn type attribute. This is used in function unit delay 180;; computations. 181(define_attr "type" 182 "integer,two,three, 183 add,logical,shift,insert, 184 mul,halfmul,div, 185 exts,cntlz,popcnt,isel, 186 load,store,fpload,fpstore,vecload,vecstore, 187 cmp, 188 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c, 189 cr_logical,mfcr,mfcrf,mtcr, 190 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt, 191 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm, 192 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto, 193 veclogical,veccmpfx,vecexts,vecmove, 194 htm,htmsimple,dfp" 195 (const_string "integer")) 196 197;; What data size does this instruction work on? 198;; This is used for insert, mul and others as necessary. 199(define_attr "size" "8,16,32,64,128" (const_string "32")) 200 201;; What is the insn_cost for this insn? The target hook can still override 202;; this. For optimizing for size the "length" attribute is used instead. 203(define_attr "cost" "" (const_int 0)) 204 205;; Is this instruction record form ("dot", signed compare to 0, writing CR0)? 206;; This is used for add, logical, shift, exts, mul. 207(define_attr "dot" "no,yes" (const_string "no")) 208 209;; Does this instruction sign-extend its result? 210;; This is used for load insns. 211(define_attr "sign_extend" "no,yes" (const_string "no")) 212 213;; Does this cr_logical instruction have three operands? That is, BT != BB. 214(define_attr "cr_logical_3op" "no,yes" (const_string "no")) 215 216;; Does this instruction use indexed (that is, reg+reg) addressing? 217;; This is used for load and store insns. If operand 0 or 1 is a MEM 218;; it is automatically set based on that. If a load or store instruction 219;; has fewer than two operands it needs to set this attribute manually 220;; or the compiler will crash. 221(define_attr "indexed" "no,yes" 222 (if_then_else (ior (match_operand 0 "indexed_address_mem") 223 (match_operand 1 "indexed_address_mem")) 224 (const_string "yes") 225 (const_string "no"))) 226 227;; Does this instruction use update addressing? 228;; This is used for load and store insns. See the comments for "indexed". 229(define_attr "update" "no,yes" 230 (if_then_else (ior (match_operand 0 "update_address_mem") 231 (match_operand 1 "update_address_mem")) 232 (const_string "yes") 233 (const_string "no"))) 234 235;; Is this instruction using operands[2] as shift amount, and can that be a 236;; register? 237;; This is used for shift insns. 238(define_attr "maybe_var_shift" "no,yes" (const_string "no")) 239 240;; Is this instruction using a shift amount from a register? 241;; This is used for shift insns. 242(define_attr "var_shift" "no,yes" 243 (if_then_else (and (eq_attr "type" "shift") 244 (eq_attr "maybe_var_shift" "yes")) 245 (if_then_else (match_operand 2 "gpc_reg_operand") 246 (const_string "yes") 247 (const_string "no")) 248 (const_string "no"))) 249 250;; Is copying of this instruction disallowed? 251(define_attr "cannot_copy" "no,yes" (const_string "no")) 252 253;; Define floating point instruction sub-types for use with Xfpu.md 254(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")) 255 256;; Length (in bytes). 257; '(pc)' in the following doesn't include the instruction itself; it is 258; calculated as if the instruction had zero size. 259(define_attr "length" "" 260 (if_then_else (eq_attr "type" "branch") 261 (if_then_else (and (ge (minus (match_dup 0) (pc)) 262 (const_int -32768)) 263 (lt (minus (match_dup 0) (pc)) 264 (const_int 32764))) 265 (const_int 4) 266 (const_int 8)) 267 (const_int 4))) 268 269;; Processor type -- this attribute must exactly match the processor_type 270;; enumeration in rs6000-opts.h. 271(define_attr "cpu" 272 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630, 273 ppc750,ppc7400,ppc7450, 274 ppc403,ppc405,ppc440,ppc476, 275 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500, 276 power4,power5,power6,power7,power8,power9, 277 rs64a,mpccore,cell,ppca2,titan" 278 (const (symbol_ref "(enum attr_cpu) rs6000_tune"))) 279 280 281;; If this instruction is microcoded on the CELL processor 282; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded 283(define_attr "cell_micro" "not,conditional,always" 284 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul") 285 (eq_attr "dot" "yes")) 286 (and (eq_attr "type" "load") 287 (eq_attr "sign_extend" "yes")) 288 (and (eq_attr "type" "shift") 289 (eq_attr "var_shift" "yes"))) 290 (const_string "always") 291 (const_string "not"))) 292 293(automata_option "ndfa") 294 295(include "rs64.md") 296(include "mpc.md") 297(include "40x.md") 298(include "440.md") 299(include "476.md") 300(include "601.md") 301(include "603.md") 302(include "6xx.md") 303(include "7xx.md") 304(include "7450.md") 305(include "8540.md") 306(include "e300c2c3.md") 307(include "e500mc.md") 308(include "e500mc64.md") 309(include "e5500.md") 310(include "e6500.md") 311(include "power4.md") 312(include "power5.md") 313(include "power6.md") 314(include "power7.md") 315(include "power8.md") 316(include "power9.md") 317(include "cell.md") 318(include "xfpu.md") 319(include "a2.md") 320(include "titan.md") 321 322(include "predicates.md") 323(include "constraints.md") 324 325(include "darwin.md") 326 327 328;; Mode iterators 329 330; This mode iterator allows :GPR to be used to indicate the allowable size 331; of whole values in GPRs. 332(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")]) 333 334; And again, for patterns that need two (potentially) different integer modes. 335(define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")]) 336 337; Any supported integer mode. 338(define_mode_iterator INT [QI HI SI DI TI PTI]) 339 340; Any supported integer mode that fits in one register. 341(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")]) 342 343; Integer modes supported in VSX registers with ISA 3.0 instructions 344(define_mode_iterator INT_ISA3 [QI HI SI DI]) 345 346; Everything we can extend QImode to. 347(define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")]) 348 349; Everything we can extend HImode to. 350(define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")]) 351 352; Everything we can extend SImode to. 353(define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")]) 354 355; QImode or HImode for small integer moves and small atomic ops 356(define_mode_iterator QHI [QI HI]) 357 358; QImode, HImode, SImode for fused ops only for GPR loads 359(define_mode_iterator QHSI [QI HI SI]) 360 361; HImode or SImode for sign extended fusion ops 362(define_mode_iterator HSI [HI SI]) 363 364; SImode or DImode, even if DImode doesn't fit in GPRs. 365(define_mode_iterator SDI [SI DI]) 366 367; Types that can be fused with an ADDIS instruction to load or store a GPR 368; register that has reg+offset addressing. 369(define_mode_iterator GPR_FUSION [QI 370 HI 371 SI 372 (DI "TARGET_POWERPC64") 373 SF 374 (DF "TARGET_POWERPC64")]) 375 376; Types that can be fused with an ADDIS instruction to load or store a FPR 377; register that has reg+offset addressing. 378(define_mode_iterator FPR_FUSION [DI SF DF]) 379 380; The size of a pointer. Also, the size of the value that a record-condition 381; (one with a '.') will compare; and the size used for arithmetic carries. 382(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")]) 383 384; Iterator to add PTImode along with TImode (TImode can go in VSX registers, 385; PTImode is GPR only) 386(define_mode_iterator TI2 [TI PTI]) 387 388; Any hardware-supported floating-point mode 389(define_mode_iterator FP [ 390 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT") 391 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT") 392 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128") 393 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128") 394 (KF "TARGET_FLOAT128_TYPE") 395 (DD "TARGET_DFP") 396 (TD "TARGET_DFP")]) 397 398; Any fma capable floating-point mode. 399(define_mode_iterator FMA_F [ 400 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT") 401 (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT) 402 || VECTOR_UNIT_VSX_P (DFmode)") 403 (V2SF "TARGET_PAIRED_FLOAT") 404 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)") 405 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)") 406 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)") 407 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)") 408 ]) 409 410; Floating point move iterators to combine binary and decimal moves 411(define_mode_iterator FMOVE32 [SF SD]) 412(define_mode_iterator FMOVE64 [DF DD]) 413(define_mode_iterator FMOVE64X [DI DF DD]) 414(define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128") 415 (IF "FLOAT128_IBM_P (IFmode)") 416 (TD "TARGET_HARD_FLOAT")]) 417 418(define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)") 419 (IF "FLOAT128_2REG_P (IFmode)") 420 (TD "TARGET_HARD_FLOAT")]) 421 422; Iterators for 128 bit types for direct move 423(define_mode_iterator FMOVE128_GPR [TI 424 V16QI 425 V8HI 426 V4SI 427 V4SF 428 V2DI 429 V2DF 430 V1TI 431 (KF "FLOAT128_VECTOR_P (KFmode)") 432 (TF "FLOAT128_VECTOR_P (TFmode)")]) 433 434; Iterator for 128-bit VSX types for pack/unpack 435(define_mode_iterator FMOVE128_VSX [V1TI KF]) 436 437; Iterators for converting to/from TFmode 438(define_mode_iterator IFKF [IF KF]) 439 440; Constraints for moving IF/KFmode. 441(define_mode_attr IFKF_reg [(IF "d") (KF "wa")]) 442 443; Whether a floating point move is ok, don't allow SD without hardware FP 444(define_mode_attr fmove_ok [(SF "") 445 (DF "") 446 (SD "TARGET_HARD_FLOAT") 447 (DD "")]) 448 449; Convert REAL_VALUE to the appropriate bits 450(define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE") 451 (DF "REAL_VALUE_TO_TARGET_DOUBLE") 452 (SD "REAL_VALUE_TO_TARGET_DECIMAL32") 453 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")]) 454 455; Whether 0.0 has an all-zero bit pattern 456(define_mode_attr zero_fp [(SF "j") 457 (DF "j") 458 (TF "j") 459 (IF "j") 460 (KF "j") 461 (SD "wn") 462 (DD "wn") 463 (TD "wn")]) 464 465; Definitions for 64-bit VSX 466(define_mode_attr f64_vsx [(DF "ws") (DD "wn")]) 467 468; Definitions for 64-bit direct move 469(define_mode_attr f64_dm [(DF "wk") (DD "wh")]) 470 471; Definitions for 64-bit use of altivec registers 472(define_mode_attr f64_av [(DF "wv") (DD "wn")]) 473 474; Definitions for 64-bit access to ISA 3.0 (power9) vector 475(define_mode_attr f64_p9 [(DF "wb") (DD "wn")]) 476 477; These modes do not fit in integer registers in 32-bit mode. 478(define_mode_iterator DIFD [DI DF DD]) 479 480; Iterator for reciprocal estimate instructions 481(define_mode_iterator RECIPF [SF DF V4SF V2DF]) 482 483; Iterator for just SF/DF 484(define_mode_iterator SFDF [SF DF]) 485 486; Like SFDF, but a different name to match conditional move where the 487; comparison operands may be a different mode than the input operands. 488(define_mode_iterator SFDF2 [SF DF]) 489 490; Iterator for 128-bit floating point that uses the IBM double-double format 491(define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)") 492 (TF "FLOAT128_IBM_P (TFmode)")]) 493 494; Iterator for 128-bit floating point that uses IEEE 128-bit float 495(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)") 496 (TF "FLOAT128_IEEE_P (TFmode)")]) 497 498; Iterator for 128-bit floating point 499(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE") 500 (IF "TARGET_FLOAT128_TYPE") 501 (TF "TARGET_LONG_DOUBLE_128")]) 502 503; Iterator for signbit on 64-bit machines with direct move 504(define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)") 505 (TF "FLOAT128_VECTOR_P (TFmode)")]) 506 507; Iterator for ISA 3.0 supported floating point types 508(define_mode_iterator FP_ISA3 [SF DF]) 509 510; SF/DF suffix for traditional floating instructions 511(define_mode_attr Ftrad [(SF "s") (DF "")]) 512 513; SF/DF suffix for VSX instructions 514(define_mode_attr Fvsx [(SF "sp") (DF "dp")]) 515 516; SF/DF constraint for arithmetic on traditional floating point registers 517(define_mode_attr Ff [(SF "f") (DF "d") (DI "d")]) 518 519; SF/DF constraint for arithmetic on VSX registers using instructions added in 520; ISA 2.06 (power7). This includes instructions that normally target DF mode, 521; but are used on SFmode, since internally SFmode values are kept in the DFmode 522; format. 523(define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")]) 524 525; SF/DF constraint for arithmetic on VSX registers. This is intended to be 526; used for DFmode instructions added in ISA 2.06 (power7) and SFmode 527; instructions added in ISA 2.07 (power8) 528(define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")]) 529 530; SF/DF constraint for arithmetic on altivec registers 531(define_mode_attr Fa [(SF "wu") (DF "wv")]) 532 533; s/d suffix for things like fp_addsub_s/fp_addsub_d 534(define_mode_attr Fs [(SF "s") (DF "d")]) 535 536; FRE/FRES support 537(define_mode_attr Ffre [(SF "fres") (DF "fre")]) 538(define_mode_attr FFRE [(SF "FRES") (DF "FRE")]) 539 540; Conditional returns. 541(define_code_iterator any_return [return simple_return]) 542(define_code_attr return_pred [(return "direct_return ()") 543 (simple_return "1")]) 544(define_code_attr return_str [(return "") (simple_return "simple_")]) 545 546; Logical operators. 547(define_code_iterator iorxor [ior xor]) 548(define_code_iterator and_ior_xor [and ior xor]) 549 550; Signed/unsigned variants of ops. 551(define_code_iterator any_extend [sign_extend zero_extend]) 552(define_code_iterator any_fix [fix unsigned_fix]) 553(define_code_iterator any_float [float unsigned_float]) 554 555(define_code_attr u [(sign_extend "") 556 (zero_extend "u") 557 (fix "") 558 (unsigned_fix "u")]) 559 560(define_code_attr su [(sign_extend "s") 561 (zero_extend "u") 562 (fix "s") 563 (unsigned_fix "u") 564 (float "s") 565 (unsigned_float "u")]) 566 567(define_code_attr az [(sign_extend "a") 568 (zero_extend "z") 569 (fix "a") 570 (unsigned_fix "z") 571 (float "a") 572 (unsigned_float "z")]) 573 574(define_code_attr uns [(fix "") 575 (unsigned_fix "uns") 576 (float "") 577 (unsigned_float "uns")]) 578 579; Various instructions that come in SI and DI forms. 580; A generic w/d attribute, for things like cmpw/cmpd. 581(define_mode_attr wd [(QI "b") 582 (HI "h") 583 (SI "w") 584 (DI "d") 585 (V16QI "b") 586 (V8HI "h") 587 (V4SI "w") 588 (V2DI "d") 589 (V1TI "q") 590 (TI "q")]) 591 592;; How many bits in this mode? 593(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")]) 594 595; DImode bits 596(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")]) 597 598;; Bitmask for shift instructions 599(define_mode_attr hH [(SI "h") (DI "H")]) 600 601;; A mode twice the size of the given mode 602(define_mode_attr dmode [(SI "di") (DI "ti")]) 603(define_mode_attr DMODE [(SI "DI") (DI "TI")]) 604 605;; Suffix for reload patterns 606(define_mode_attr ptrsize [(SI "32bit") 607 (DI "64bit")]) 608 609(define_mode_attr tptrsize [(SI "TARGET_32BIT") 610 (DI "TARGET_64BIT")]) 611 612(define_mode_attr mptrsize [(SI "si") 613 (DI "di")]) 614 615(define_mode_attr ptrload [(SI "lwz") 616 (DI "ld")]) 617 618(define_mode_attr ptrm [(SI "m") 619 (DI "Y")]) 620 621(define_mode_attr rreg [(SF "f") 622 (DF "ws") 623 (TF "f") 624 (TD "f") 625 (V4SF "wf") 626 (V2DF "wd")]) 627 628(define_mode_attr rreg2 [(SF "f") 629 (DF "d")]) 630 631(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS") 632 (DF "TARGET_FCFID")]) 633 634(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT") 635 (DF "TARGET_DOUBLE_FLOAT")]) 636 637;; Mode iterator for logical operations on 128-bit types 638(define_mode_iterator BOOL_128 [TI 639 PTI 640 (V16QI "TARGET_ALTIVEC") 641 (V8HI "TARGET_ALTIVEC") 642 (V4SI "TARGET_ALTIVEC") 643 (V4SF "TARGET_ALTIVEC") 644 (V2DI "TARGET_ALTIVEC") 645 (V2DF "TARGET_ALTIVEC") 646 (V1TI "TARGET_ALTIVEC")]) 647 648;; For the GPRs we use 3 constraints for register outputs, two that are the 649;; same as the output register, and a third where the output register is an 650;; early clobber, so we don't have to deal with register overlaps. For the 651;; vector types, we prefer to use the vector registers. For TI mode, allow 652;; either. 653 654;; Mode attribute for boolean operation register constraints for output 655(define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v") 656 (PTI "&r,r,r") 657 (V16QI "wa,v,&?r,?r,?r") 658 (V8HI "wa,v,&?r,?r,?r") 659 (V4SI "wa,v,&?r,?r,?r") 660 (V4SF "wa,v,&?r,?r,?r") 661 (V2DI "wa,v,&?r,?r,?r") 662 (V2DF "wa,v,&?r,?r,?r") 663 (V1TI "wa,v,&?r,?r,?r")]) 664 665;; Mode attribute for boolean operation register constraints for operand1 666(define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v") 667 (PTI "r,0,r") 668 (V16QI "wa,v,r,0,r") 669 (V8HI "wa,v,r,0,r") 670 (V4SI "wa,v,r,0,r") 671 (V4SF "wa,v,r,0,r") 672 (V2DI "wa,v,r,0,r") 673 (V2DF "wa,v,r,0,r") 674 (V1TI "wa,v,r,0,r")]) 675 676;; Mode attribute for boolean operation register constraints for operand2 677(define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v") 678 (PTI "r,r,0") 679 (V16QI "wa,v,r,r,0") 680 (V8HI "wa,v,r,r,0") 681 (V4SI "wa,v,r,r,0") 682 (V4SF "wa,v,r,r,0") 683 (V2DI "wa,v,r,r,0") 684 (V2DF "wa,v,r,r,0") 685 (V1TI "wa,v,r,r,0")]) 686 687;; Mode attribute for boolean operation register constraints for operand1 688;; for one_cmpl. To simplify things, we repeat the constraint where 0 689;; is used for operand1 or operand2 690(define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v") 691 (PTI "r,0,0") 692 (V16QI "wa,v,r,0,0") 693 (V8HI "wa,v,r,0,0") 694 (V4SI "wa,v,r,0,0") 695 (V4SF "wa,v,r,0,0") 696 (V2DI "wa,v,r,0,0") 697 (V2DF "wa,v,r,0,0") 698 (V1TI "wa,v,r,0,0")]) 699 700;; Reload iterator for creating the function to allocate a base register to 701;; supplement addressing modes. 702(define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI 703 SF SD SI DF DD DI TI PTI KF IF TF]) 704 705;; Iterate over smin, smax 706(define_code_iterator fp_minmax [smin smax]) 707 708(define_code_attr minmax [(smin "min") 709 (smax "max")]) 710 711(define_code_attr SMINMAX [(smin "SMIN") 712 (smax "SMAX")]) 713 714;; Iterator to optimize the following cases: 715;; D-form load to FPR register & move to Altivec register 716;; Move Altivec register to FPR register and store 717(define_mode_iterator ALTIVEC_DFORM [DF 718 (SF "TARGET_P8_VECTOR") 719 (DI "TARGET_POWERPC64")]) 720 721 722;; Start with fixed-point load and store insns. Here we put only the more 723;; complex forms. Basic data transfer is done later. 724 725(define_insn "zero_extendqi<mode>2" 726 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK") 727 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))] 728 "" 729 "@ 730 lbz%U1%X1 %0,%1 731 rlwinm %0,%1,0,0xff 732 lxsibzx %x0,%y1 733 vextractub %0,%1,7" 734 [(set_attr "type" "load,shift,fpload,vecperm")]) 735 736(define_insn_and_split "*zero_extendqi<mode>2_dot" 737 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 738 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 739 (const_int 0))) 740 (clobber (match_scratch:EXTQI 0 "=r,r"))] 741 "" 742 "@ 743 andi. %0,%1,0xff 744 #" 745 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 746 [(set (match_dup 0) 747 (zero_extend:EXTQI (match_dup 1))) 748 (set (match_dup 2) 749 (compare:CC (match_dup 0) 750 (const_int 0)))] 751 "" 752 [(set_attr "type" "logical") 753 (set_attr "dot" "yes") 754 (set_attr "length" "4,8")]) 755 756(define_insn_and_split "*zero_extendqi<mode>2_dot2" 757 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 758 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 759 (const_int 0))) 760 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 761 (zero_extend:EXTQI (match_dup 1)))] 762 "" 763 "@ 764 andi. %0,%1,0xff 765 #" 766 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 767 [(set (match_dup 0) 768 (zero_extend:EXTQI (match_dup 1))) 769 (set (match_dup 2) 770 (compare:CC (match_dup 0) 771 (const_int 0)))] 772 "" 773 [(set_attr "type" "logical") 774 (set_attr "dot" "yes") 775 (set_attr "length" "4,8")]) 776 777 778(define_insn "zero_extendhi<mode>2" 779 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK") 780 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))] 781 "" 782 "@ 783 lhz%U1%X1 %0,%1 784 rlwinm %0,%1,0,0xffff 785 lxsihzx %x0,%y1 786 vextractuh %0,%1,6" 787 [(set_attr "type" "load,shift,fpload,vecperm")]) 788 789(define_insn_and_split "*zero_extendhi<mode>2_dot" 790 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 791 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 792 (const_int 0))) 793 (clobber (match_scratch:EXTHI 0 "=r,r"))] 794 "" 795 "@ 796 andi. %0,%1,0xffff 797 #" 798 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 799 [(set (match_dup 0) 800 (zero_extend:EXTHI (match_dup 1))) 801 (set (match_dup 2) 802 (compare:CC (match_dup 0) 803 (const_int 0)))] 804 "" 805 [(set_attr "type" "logical") 806 (set_attr "dot" "yes") 807 (set_attr "length" "4,8")]) 808 809(define_insn_and_split "*zero_extendhi<mode>2_dot2" 810 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 811 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 812 (const_int 0))) 813 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 814 (zero_extend:EXTHI (match_dup 1)))] 815 "" 816 "@ 817 andi. %0,%1,0xffff 818 #" 819 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 820 [(set (match_dup 0) 821 (zero_extend:EXTHI (match_dup 1))) 822 (set (match_dup 2) 823 (compare:CC (match_dup 0) 824 (const_int 0)))] 825 "" 826 [(set_attr "type" "logical") 827 (set_attr "dot" "yes") 828 (set_attr "length" "4,8")]) 829 830 831(define_insn "zero_extendsi<mode>2" 832 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK") 833 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))] 834 "" 835 "@ 836 lwz%U1%X1 %0,%1 837 rldicl %0,%1,0,32 838 lfiwzx %0,%y1 839 lxsiwzx %x0,%y1 840 mtvsrwz %x0,%1 841 mfvsrwz %0,%x1 842 xxextractuw %x0,%x1,4" 843 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")]) 844 845(define_insn_and_split "*zero_extendsi<mode>2_dot" 846 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 847 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 848 (const_int 0))) 849 (clobber (match_scratch:EXTSI 0 "=r,r"))] 850 "" 851 "@ 852 rldicl. %0,%1,0,32 853 #" 854 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 855 [(set (match_dup 0) 856 (zero_extend:DI (match_dup 1))) 857 (set (match_dup 2) 858 (compare:CC (match_dup 0) 859 (const_int 0)))] 860 "" 861 [(set_attr "type" "shift") 862 (set_attr "dot" "yes") 863 (set_attr "length" "4,8")]) 864 865(define_insn_and_split "*zero_extendsi<mode>2_dot2" 866 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 867 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 868 (const_int 0))) 869 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") 870 (zero_extend:EXTSI (match_dup 1)))] 871 "" 872 "@ 873 rldicl. %0,%1,0,32 874 #" 875 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 876 [(set (match_dup 0) 877 (zero_extend:EXTSI (match_dup 1))) 878 (set (match_dup 2) 879 (compare:CC (match_dup 0) 880 (const_int 0)))] 881 "" 882 [(set_attr "type" "shift") 883 (set_attr "dot" "yes") 884 (set_attr "length" "4,8")]) 885 886 887(define_insn "extendqi<mode>2" 888 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK") 889 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))] 890 "" 891 "@ 892 extsb %0,%1 893 vextsb2d %0,%1" 894 [(set_attr "type" "exts,vecperm")]) 895 896(define_insn_and_split "*extendqi<mode>2_dot" 897 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 898 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 899 (const_int 0))) 900 (clobber (match_scratch:EXTQI 0 "=r,r"))] 901 "" 902 "@ 903 extsb. %0,%1 904 #" 905 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 906 [(set (match_dup 0) 907 (sign_extend:EXTQI (match_dup 1))) 908 (set (match_dup 2) 909 (compare:CC (match_dup 0) 910 (const_int 0)))] 911 "" 912 [(set_attr "type" "exts") 913 (set_attr "dot" "yes") 914 (set_attr "length" "4,8")]) 915 916(define_insn_and_split "*extendqi<mode>2_dot2" 917 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 918 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 919 (const_int 0))) 920 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 921 (sign_extend:EXTQI (match_dup 1)))] 922 "" 923 "@ 924 extsb. %0,%1 925 #" 926 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 927 [(set (match_dup 0) 928 (sign_extend:EXTQI (match_dup 1))) 929 (set (match_dup 2) 930 (compare:CC (match_dup 0) 931 (const_int 0)))] 932 "" 933 [(set_attr "type" "exts") 934 (set_attr "dot" "yes") 935 (set_attr "length" "4,8")]) 936 937 938(define_expand "extendhi<mode>2" 939 [(set (match_operand:EXTHI 0 "gpc_reg_operand") 940 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))] 941 "" 942 "") 943 944(define_insn "*extendhi<mode>2" 945 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK") 946 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))] 947 "" 948 "@ 949 lha%U1%X1 %0,%1 950 extsh %0,%1 951 # 952 vextsh2d %0,%1" 953 [(set_attr "type" "load,exts,fpload,vecperm") 954 (set_attr "sign_extend" "yes") 955 (set_attr "length" "4,4,8,4")]) 956 957(define_split 958 [(set (match_operand:EXTHI 0 "altivec_register_operand") 959 (sign_extend:EXTHI 960 (match_operand:HI 1 "indexed_or_indirect_operand")))] 961 "TARGET_P9_VECTOR && reload_completed" 962 [(set (match_dup 2) 963 (match_dup 1)) 964 (set (match_dup 0) 965 (sign_extend:EXTHI (match_dup 2)))] 966{ 967 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0])); 968}) 969 970(define_insn_and_split "*extendhi<mode>2_dot" 971 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 972 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 973 (const_int 0))) 974 (clobber (match_scratch:EXTHI 0 "=r,r"))] 975 "" 976 "@ 977 extsh. %0,%1 978 #" 979 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 980 [(set (match_dup 0) 981 (sign_extend:EXTHI (match_dup 1))) 982 (set (match_dup 2) 983 (compare:CC (match_dup 0) 984 (const_int 0)))] 985 "" 986 [(set_attr "type" "exts") 987 (set_attr "dot" "yes") 988 (set_attr "length" "4,8")]) 989 990(define_insn_and_split "*extendhi<mode>2_dot2" 991 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 992 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 993 (const_int 0))) 994 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 995 (sign_extend:EXTHI (match_dup 1)))] 996 "" 997 "@ 998 extsh. %0,%1 999 #" 1000 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1001 [(set (match_dup 0) 1002 (sign_extend:EXTHI (match_dup 1))) 1003 (set (match_dup 2) 1004 (compare:CC (match_dup 0) 1005 (const_int 0)))] 1006 "" 1007 [(set_attr "type" "exts") 1008 (set_attr "dot" "yes") 1009 (set_attr "length" "4,8")]) 1010 1011 1012(define_insn "extendsi<mode>2" 1013 [(set (match_operand:EXTSI 0 "gpc_reg_operand" 1014 "=r, r, wl, wu, wj, wK, wH, wr") 1015 1016 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" 1017 "YZ, r, Z, Z, r, wK, wH, ?wIwH")))] 1018 "" 1019 "@ 1020 lwa%U1%X1 %0,%1 1021 extsw %0,%1 1022 lfiwax %0,%y1 1023 lxsiwax %x0,%y1 1024 mtvsrwa %x0,%1 1025 vextsw2d %0,%1 1026 # 1027 #" 1028 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr") 1029 (set_attr "sign_extend" "yes") 1030 (set_attr "length" "4,4,4,4,4,4,8,8")]) 1031 1032(define_split 1033 [(set (match_operand:EXTSI 0 "int_reg_operand") 1034 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))] 1035 "TARGET_DIRECT_MOVE_64BIT && reload_completed" 1036 [(set (match_dup 2) 1037 (match_dup 1)) 1038 (set (match_dup 0) 1039 (sign_extend:DI (match_dup 2)))] 1040{ 1041 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0])); 1042}) 1043 1044(define_split 1045 [(set (match_operand:DI 0 "altivec_register_operand") 1046 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))] 1047 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed" 1048 [(const_int 0)] 1049{ 1050 rtx dest = operands[0]; 1051 rtx src = operands[1]; 1052 int dest_regno = REGNO (dest); 1053 int src_regno = REGNO (src); 1054 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno); 1055 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno); 1056 1057 if (VECTOR_ELT_ORDER_BIG) 1058 { 1059 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si)); 1060 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx)); 1061 } 1062 else 1063 { 1064 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si)); 1065 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx)); 1066 } 1067 DONE; 1068}) 1069 1070(define_insn_and_split "*extendsi<mode>2_dot" 1071 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1072 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 1073 (const_int 0))) 1074 (clobber (match_scratch:EXTSI 0 "=r,r"))] 1075 "" 1076 "@ 1077 extsw. %0,%1 1078 #" 1079 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1080 [(set (match_dup 0) 1081 (sign_extend:EXTSI (match_dup 1))) 1082 (set (match_dup 2) 1083 (compare:CC (match_dup 0) 1084 (const_int 0)))] 1085 "" 1086 [(set_attr "type" "exts") 1087 (set_attr "dot" "yes") 1088 (set_attr "length" "4,8")]) 1089 1090(define_insn_and_split "*extendsi<mode>2_dot2" 1091 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1092 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 1093 (const_int 0))) 1094 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") 1095 (sign_extend:EXTSI (match_dup 1)))] 1096 "" 1097 "@ 1098 extsw. %0,%1 1099 #" 1100 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1101 [(set (match_dup 0) 1102 (sign_extend:EXTSI (match_dup 1))) 1103 (set (match_dup 2) 1104 (compare:CC (match_dup 0) 1105 (const_int 0)))] 1106 "" 1107 [(set_attr "type" "exts") 1108 (set_attr "dot" "yes") 1109 (set_attr "length" "4,8")]) 1110 1111;; IBM 405, 440, 464 and 476 half-word multiplication operations. 1112 1113(define_insn "*macchwc" 1114 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1115 (compare:CC (plus:SI (mult:SI (ashiftrt:SI 1116 (match_operand:SI 2 "gpc_reg_operand" "r") 1117 (const_int 16)) 1118 (sign_extend:SI 1119 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1120 (match_operand:SI 4 "gpc_reg_operand" "0")) 1121 (const_int 0))) 1122 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1123 (plus:SI (mult:SI (ashiftrt:SI 1124 (match_dup 2) 1125 (const_int 16)) 1126 (sign_extend:SI 1127 (match_dup 1))) 1128 (match_dup 4)))] 1129 "TARGET_MULHW" 1130 "macchw. %0,%1,%2" 1131 [(set_attr "type" "halfmul")]) 1132 1133(define_insn "*macchw" 1134 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1135 (plus:SI (mult:SI (ashiftrt:SI 1136 (match_operand:SI 2 "gpc_reg_operand" "r") 1137 (const_int 16)) 1138 (sign_extend:SI 1139 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1140 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1141 "TARGET_MULHW" 1142 "macchw %0,%1,%2" 1143 [(set_attr "type" "halfmul")]) 1144 1145(define_insn "*macchwuc" 1146 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1147 (compare:CC (plus:SI (mult:SI (lshiftrt:SI 1148 (match_operand:SI 2 "gpc_reg_operand" "r") 1149 (const_int 16)) 1150 (zero_extend:SI 1151 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1152 (match_operand:SI 4 "gpc_reg_operand" "0")) 1153 (const_int 0))) 1154 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1155 (plus:SI (mult:SI (lshiftrt:SI 1156 (match_dup 2) 1157 (const_int 16)) 1158 (zero_extend:SI 1159 (match_dup 1))) 1160 (match_dup 4)))] 1161 "TARGET_MULHW" 1162 "macchwu. %0,%1,%2" 1163 [(set_attr "type" "halfmul")]) 1164 1165(define_insn "*macchwu" 1166 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1167 (plus:SI (mult:SI (lshiftrt:SI 1168 (match_operand:SI 2 "gpc_reg_operand" "r") 1169 (const_int 16)) 1170 (zero_extend:SI 1171 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1172 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1173 "TARGET_MULHW" 1174 "macchwu %0,%1,%2" 1175 [(set_attr "type" "halfmul")]) 1176 1177(define_insn "*machhwc" 1178 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1179 (compare:CC (plus:SI (mult:SI (ashiftrt:SI 1180 (match_operand:SI 1 "gpc_reg_operand" "%r") 1181 (const_int 16)) 1182 (ashiftrt:SI 1183 (match_operand:SI 2 "gpc_reg_operand" "r") 1184 (const_int 16))) 1185 (match_operand:SI 4 "gpc_reg_operand" "0")) 1186 (const_int 0))) 1187 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1188 (plus:SI (mult:SI (ashiftrt:SI 1189 (match_dup 1) 1190 (const_int 16)) 1191 (ashiftrt:SI 1192 (match_dup 2) 1193 (const_int 16))) 1194 (match_dup 4)))] 1195 "TARGET_MULHW" 1196 "machhw. %0,%1,%2" 1197 [(set_attr "type" "halfmul")]) 1198 1199(define_insn "*machhw" 1200 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1201 (plus:SI (mult:SI (ashiftrt:SI 1202 (match_operand:SI 1 "gpc_reg_operand" "%r") 1203 (const_int 16)) 1204 (ashiftrt:SI 1205 (match_operand:SI 2 "gpc_reg_operand" "r") 1206 (const_int 16))) 1207 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1208 "TARGET_MULHW" 1209 "machhw %0,%1,%2" 1210 [(set_attr "type" "halfmul")]) 1211 1212(define_insn "*machhwuc" 1213 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1214 (compare:CC (plus:SI (mult:SI (lshiftrt:SI 1215 (match_operand:SI 1 "gpc_reg_operand" "%r") 1216 (const_int 16)) 1217 (lshiftrt:SI 1218 (match_operand:SI 2 "gpc_reg_operand" "r") 1219 (const_int 16))) 1220 (match_operand:SI 4 "gpc_reg_operand" "0")) 1221 (const_int 0))) 1222 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1223 (plus:SI (mult:SI (lshiftrt:SI 1224 (match_dup 1) 1225 (const_int 16)) 1226 (lshiftrt:SI 1227 (match_dup 2) 1228 (const_int 16))) 1229 (match_dup 4)))] 1230 "TARGET_MULHW" 1231 "machhwu. %0,%1,%2" 1232 [(set_attr "type" "halfmul")]) 1233 1234(define_insn "*machhwu" 1235 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1236 (plus:SI (mult:SI (lshiftrt:SI 1237 (match_operand:SI 1 "gpc_reg_operand" "%r") 1238 (const_int 16)) 1239 (lshiftrt:SI 1240 (match_operand:SI 2 "gpc_reg_operand" "r") 1241 (const_int 16))) 1242 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1243 "TARGET_MULHW" 1244 "machhwu %0,%1,%2" 1245 [(set_attr "type" "halfmul")]) 1246 1247(define_insn "*maclhwc" 1248 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1249 (compare:CC (plus:SI (mult:SI (sign_extend:SI 1250 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1251 (sign_extend:SI 1252 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1253 (match_operand:SI 4 "gpc_reg_operand" "0")) 1254 (const_int 0))) 1255 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1256 (plus:SI (mult:SI (sign_extend:SI 1257 (match_dup 1)) 1258 (sign_extend:SI 1259 (match_dup 2))) 1260 (match_dup 4)))] 1261 "TARGET_MULHW" 1262 "maclhw. %0,%1,%2" 1263 [(set_attr "type" "halfmul")]) 1264 1265(define_insn "*maclhw" 1266 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1267 (plus:SI (mult:SI (sign_extend:SI 1268 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1269 (sign_extend:SI 1270 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1271 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1272 "TARGET_MULHW" 1273 "maclhw %0,%1,%2" 1274 [(set_attr "type" "halfmul")]) 1275 1276(define_insn "*maclhwuc" 1277 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1278 (compare:CC (plus:SI (mult:SI (zero_extend:SI 1279 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1280 (zero_extend:SI 1281 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1282 (match_operand:SI 4 "gpc_reg_operand" "0")) 1283 (const_int 0))) 1284 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1285 (plus:SI (mult:SI (zero_extend:SI 1286 (match_dup 1)) 1287 (zero_extend:SI 1288 (match_dup 2))) 1289 (match_dup 4)))] 1290 "TARGET_MULHW" 1291 "maclhwu. %0,%1,%2" 1292 [(set_attr "type" "halfmul")]) 1293 1294(define_insn "*maclhwu" 1295 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1296 (plus:SI (mult:SI (zero_extend:SI 1297 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1298 (zero_extend:SI 1299 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1300 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1301 "TARGET_MULHW" 1302 "maclhwu %0,%1,%2" 1303 [(set_attr "type" "halfmul")]) 1304 1305(define_insn "*nmacchwc" 1306 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1307 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 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 (const_int 0))) 1314 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1315 (minus:SI (match_dup 4) 1316 (mult:SI (ashiftrt:SI 1317 (match_dup 2) 1318 (const_int 16)) 1319 (sign_extend:SI 1320 (match_dup 1)))))] 1321 "TARGET_MULHW" 1322 "nmacchw. %0,%1,%2" 1323 [(set_attr "type" "halfmul")]) 1324 1325(define_insn "*nmacchw" 1326 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1327 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1328 (mult:SI (ashiftrt:SI 1329 (match_operand:SI 2 "gpc_reg_operand" "r") 1330 (const_int 16)) 1331 (sign_extend:SI 1332 (match_operand:HI 1 "gpc_reg_operand" "r")))))] 1333 "TARGET_MULHW" 1334 "nmacchw %0,%1,%2" 1335 [(set_attr "type" "halfmul")]) 1336 1337(define_insn "*nmachhwc" 1338 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1339 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1340 (mult:SI (ashiftrt:SI 1341 (match_operand:SI 1 "gpc_reg_operand" "%r") 1342 (const_int 16)) 1343 (ashiftrt:SI 1344 (match_operand:SI 2 "gpc_reg_operand" "r") 1345 (const_int 16)))) 1346 (const_int 0))) 1347 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1348 (minus:SI (match_dup 4) 1349 (mult:SI (ashiftrt:SI 1350 (match_dup 1) 1351 (const_int 16)) 1352 (ashiftrt:SI 1353 (match_dup 2) 1354 (const_int 16)))))] 1355 "TARGET_MULHW" 1356 "nmachhw. %0,%1,%2" 1357 [(set_attr "type" "halfmul")]) 1358 1359(define_insn "*nmachhw" 1360 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1361 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1362 (mult:SI (ashiftrt:SI 1363 (match_operand:SI 1 "gpc_reg_operand" "%r") 1364 (const_int 16)) 1365 (ashiftrt:SI 1366 (match_operand:SI 2 "gpc_reg_operand" "r") 1367 (const_int 16)))))] 1368 "TARGET_MULHW" 1369 "nmachhw %0,%1,%2" 1370 [(set_attr "type" "halfmul")]) 1371 1372(define_insn "*nmaclhwc" 1373 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1374 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1375 (mult:SI (sign_extend:SI 1376 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1377 (sign_extend:SI 1378 (match_operand:HI 2 "gpc_reg_operand" "r")))) 1379 (const_int 0))) 1380 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1381 (minus:SI (match_dup 4) 1382 (mult:SI (sign_extend:SI 1383 (match_dup 1)) 1384 (sign_extend:SI 1385 (match_dup 2)))))] 1386 "TARGET_MULHW" 1387 "nmaclhw. %0,%1,%2" 1388 [(set_attr "type" "halfmul")]) 1389 1390(define_insn "*nmaclhw" 1391 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1392 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1393 (mult:SI (sign_extend:SI 1394 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1395 (sign_extend:SI 1396 (match_operand:HI 2 "gpc_reg_operand" "r")))))] 1397 "TARGET_MULHW" 1398 "nmaclhw %0,%1,%2" 1399 [(set_attr "type" "halfmul")]) 1400 1401(define_insn "*mulchwc" 1402 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1403 (compare:CC (mult:SI (ashiftrt:SI 1404 (match_operand:SI 2 "gpc_reg_operand" "r") 1405 (const_int 16)) 1406 (sign_extend:SI 1407 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1408 (const_int 0))) 1409 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1410 (mult:SI (ashiftrt:SI 1411 (match_dup 2) 1412 (const_int 16)) 1413 (sign_extend:SI 1414 (match_dup 1))))] 1415 "TARGET_MULHW" 1416 "mulchw. %0,%1,%2" 1417 [(set_attr "type" "halfmul")]) 1418 1419(define_insn "*mulchw" 1420 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1421 (mult:SI (ashiftrt:SI 1422 (match_operand:SI 2 "gpc_reg_operand" "r") 1423 (const_int 16)) 1424 (sign_extend:SI 1425 (match_operand:HI 1 "gpc_reg_operand" "r"))))] 1426 "TARGET_MULHW" 1427 "mulchw %0,%1,%2" 1428 [(set_attr "type" "halfmul")]) 1429 1430(define_insn "*mulchwuc" 1431 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1432 (compare:CC (mult:SI (lshiftrt:SI 1433 (match_operand:SI 2 "gpc_reg_operand" "r") 1434 (const_int 16)) 1435 (zero_extend:SI 1436 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1437 (const_int 0))) 1438 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1439 (mult:SI (lshiftrt:SI 1440 (match_dup 2) 1441 (const_int 16)) 1442 (zero_extend:SI 1443 (match_dup 1))))] 1444 "TARGET_MULHW" 1445 "mulchwu. %0,%1,%2" 1446 [(set_attr "type" "halfmul")]) 1447 1448(define_insn "*mulchwu" 1449 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1450 (mult:SI (lshiftrt:SI 1451 (match_operand:SI 2 "gpc_reg_operand" "r") 1452 (const_int 16)) 1453 (zero_extend:SI 1454 (match_operand:HI 1 "gpc_reg_operand" "r"))))] 1455 "TARGET_MULHW" 1456 "mulchwu %0,%1,%2" 1457 [(set_attr "type" "halfmul")]) 1458 1459(define_insn "*mulhhwc" 1460 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1461 (compare:CC (mult:SI (ashiftrt:SI 1462 (match_operand:SI 1 "gpc_reg_operand" "%r") 1463 (const_int 16)) 1464 (ashiftrt:SI 1465 (match_operand:SI 2 "gpc_reg_operand" "r") 1466 (const_int 16))) 1467 (const_int 0))) 1468 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1469 (mult:SI (ashiftrt:SI 1470 (match_dup 1) 1471 (const_int 16)) 1472 (ashiftrt:SI 1473 (match_dup 2) 1474 (const_int 16))))] 1475 "TARGET_MULHW" 1476 "mulhhw. %0,%1,%2" 1477 [(set_attr "type" "halfmul")]) 1478 1479(define_insn "*mulhhw" 1480 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1481 (mult:SI (ashiftrt:SI 1482 (match_operand:SI 1 "gpc_reg_operand" "%r") 1483 (const_int 16)) 1484 (ashiftrt:SI 1485 (match_operand:SI 2 "gpc_reg_operand" "r") 1486 (const_int 16))))] 1487 "TARGET_MULHW" 1488 "mulhhw %0,%1,%2" 1489 [(set_attr "type" "halfmul")]) 1490 1491(define_insn "*mulhhwuc" 1492 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1493 (compare:CC (mult:SI (lshiftrt:SI 1494 (match_operand:SI 1 "gpc_reg_operand" "%r") 1495 (const_int 16)) 1496 (lshiftrt:SI 1497 (match_operand:SI 2 "gpc_reg_operand" "r") 1498 (const_int 16))) 1499 (const_int 0))) 1500 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1501 (mult:SI (lshiftrt:SI 1502 (match_dup 1) 1503 (const_int 16)) 1504 (lshiftrt:SI 1505 (match_dup 2) 1506 (const_int 16))))] 1507 "TARGET_MULHW" 1508 "mulhhwu. %0,%1,%2" 1509 [(set_attr "type" "halfmul")]) 1510 1511(define_insn "*mulhhwu" 1512 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1513 (mult:SI (lshiftrt:SI 1514 (match_operand:SI 1 "gpc_reg_operand" "%r") 1515 (const_int 16)) 1516 (lshiftrt:SI 1517 (match_operand:SI 2 "gpc_reg_operand" "r") 1518 (const_int 16))))] 1519 "TARGET_MULHW" 1520 "mulhhwu %0,%1,%2" 1521 [(set_attr "type" "halfmul")]) 1522 1523(define_insn "*mullhwc" 1524 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1525 (compare:CC (mult:SI (sign_extend:SI 1526 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1527 (sign_extend:SI 1528 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1529 (const_int 0))) 1530 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1531 (mult:SI (sign_extend:SI 1532 (match_dup 1)) 1533 (sign_extend:SI 1534 (match_dup 2))))] 1535 "TARGET_MULHW" 1536 "mullhw. %0,%1,%2" 1537 [(set_attr "type" "halfmul")]) 1538 1539(define_insn "*mullhw" 1540 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1541 (mult:SI (sign_extend:SI 1542 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1543 (sign_extend:SI 1544 (match_operand:HI 2 "gpc_reg_operand" "r"))))] 1545 "TARGET_MULHW" 1546 "mullhw %0,%1,%2" 1547 [(set_attr "type" "halfmul")]) 1548 1549(define_insn "*mullhwuc" 1550 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1551 (compare:CC (mult:SI (zero_extend:SI 1552 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1553 (zero_extend:SI 1554 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1555 (const_int 0))) 1556 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1557 (mult:SI (zero_extend:SI 1558 (match_dup 1)) 1559 (zero_extend:SI 1560 (match_dup 2))))] 1561 "TARGET_MULHW" 1562 "mullhwu. %0,%1,%2" 1563 [(set_attr "type" "halfmul")]) 1564 1565(define_insn "*mullhwu" 1566 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1567 (mult:SI (zero_extend:SI 1568 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1569 (zero_extend:SI 1570 (match_operand:HI 2 "gpc_reg_operand" "r"))))] 1571 "TARGET_MULHW" 1572 "mullhwu %0,%1,%2" 1573 [(set_attr "type" "halfmul")]) 1574 1575;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support. 1576(define_insn "dlmzb" 1577 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1578 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 1579 (match_operand:SI 2 "gpc_reg_operand" "r")] 1580 UNSPEC_DLMZB_CR)) 1581 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1582 (unspec:SI [(match_dup 1) 1583 (match_dup 2)] 1584 UNSPEC_DLMZB))] 1585 "TARGET_DLMZB" 1586 "dlmzb. %0,%1,%2") 1587 1588(define_expand "strlensi" 1589 [(set (match_operand:SI 0 "gpc_reg_operand") 1590 (unspec:SI [(match_operand:BLK 1 "general_operand") 1591 (match_operand:QI 2 "const_int_operand") 1592 (match_operand 3 "const_int_operand")] 1593 UNSPEC_DLMZB_STRLEN)) 1594 (clobber (match_scratch:CC 4))] 1595 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size" 1596{ 1597 rtx result = operands[0]; 1598 rtx src = operands[1]; 1599 rtx search_char = operands[2]; 1600 rtx align = operands[3]; 1601 rtx addr, scratch_string, word1, word2, scratch_dlmzb; 1602 rtx loop_label, end_label, mem, cr0, cond; 1603 if (search_char != const0_rtx 1604 || GET_CODE (align) != CONST_INT 1605 || INTVAL (align) < 8) 1606 FAIL; 1607 word1 = gen_reg_rtx (SImode); 1608 word2 = gen_reg_rtx (SImode); 1609 scratch_dlmzb = gen_reg_rtx (SImode); 1610 scratch_string = gen_reg_rtx (Pmode); 1611 loop_label = gen_label_rtx (); 1612 end_label = gen_label_rtx (); 1613 addr = force_reg (Pmode, XEXP (src, 0)); 1614 emit_move_insn (scratch_string, addr); 1615 emit_label (loop_label); 1616 mem = change_address (src, SImode, scratch_string); 1617 emit_move_insn (word1, mem); 1618 emit_move_insn (word2, adjust_address (mem, SImode, 4)); 1619 cr0 = gen_rtx_REG (CCmode, CR0_REGNO); 1620 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0)); 1621 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx); 1622 emit_jump_insn (gen_rtx_SET (pc_rtx, 1623 gen_rtx_IF_THEN_ELSE (VOIDmode, 1624 cond, 1625 gen_rtx_LABEL_REF 1626 (VOIDmode, 1627 end_label), 1628 pc_rtx))); 1629 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8))); 1630 emit_jump_insn (gen_rtx_SET (pc_rtx, 1631 gen_rtx_LABEL_REF (VOIDmode, loop_label))); 1632 emit_barrier (); 1633 emit_label (end_label); 1634 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb)); 1635 emit_insn (gen_subsi3 (result, scratch_string, addr)); 1636 emit_insn (gen_addsi3 (result, result, constm1_rtx)); 1637 DONE; 1638}) 1639 1640;; Fixed-point arithmetic insns. 1641 1642(define_expand "add<mode>3" 1643 [(set (match_operand:SDI 0 "gpc_reg_operand") 1644 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand") 1645 (match_operand:SDI 2 "reg_or_add_cint_operand")))] 1646 "" 1647{ 1648 if (<MODE>mode == DImode && !TARGET_POWERPC64) 1649 { 1650 rtx lo0 = gen_lowpart (SImode, operands[0]); 1651 rtx lo1 = gen_lowpart (SImode, operands[1]); 1652 rtx lo2 = gen_lowpart (SImode, operands[2]); 1653 rtx hi0 = gen_highpart (SImode, operands[0]); 1654 rtx hi1 = gen_highpart (SImode, operands[1]); 1655 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]); 1656 1657 if (!reg_or_short_operand (lo2, SImode)) 1658 lo2 = force_reg (SImode, lo2); 1659 if (!adde_operand (hi2, SImode)) 1660 hi2 = force_reg (SImode, hi2); 1661 1662 emit_insn (gen_addsi3_carry (lo0, lo1, lo2)); 1663 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2)); 1664 DONE; 1665 } 1666 1667 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode)) 1668 { 1669 rtx tmp = ((!can_create_pseudo_p () 1670 || rtx_equal_p (operands[0], operands[1])) 1671 ? operands[0] : gen_reg_rtx (<MODE>mode)); 1672 1673 /* Adding a constant to r0 is not a valid insn, so use a different 1674 strategy in that case. */ 1675 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0) 1676 { 1677 if (operands[0] == operands[1]) 1678 FAIL; 1679 rs6000_emit_move (operands[0], operands[2], <MODE>mode); 1680 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0])); 1681 DONE; 1682 } 1683 1684 HOST_WIDE_INT val = INTVAL (operands[2]); 1685 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1686 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); 1687 1688 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest))) 1689 FAIL; 1690 1691 /* The ordering here is important for the prolog expander. 1692 When space is allocated from the stack, adding 'low' first may 1693 produce a temporary deallocation (which would be bad). */ 1694 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest))); 1695 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low))); 1696 DONE; 1697 } 1698}) 1699 1700(define_insn "*add<mode>3" 1701 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r") 1702 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b") 1703 (match_operand:GPR 2 "add_operand" "r,I,L")))] 1704 "" 1705 "@ 1706 add %0,%1,%2 1707 addi %0,%1,%2 1708 addis %0,%1,%v2" 1709 [(set_attr "type" "add")]) 1710 1711(define_insn "addsi3_high" 1712 [(set (match_operand:SI 0 "gpc_reg_operand" "=b") 1713 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") 1714 (high:SI (match_operand 2 "" ""))))] 1715 "TARGET_MACHO && !TARGET_64BIT" 1716 "addis %0,%1,ha16(%2)" 1717 [(set_attr "type" "add")]) 1718 1719(define_insn_and_split "*add<mode>3_dot" 1720 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1721 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 1722 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 1723 (const_int 0))) 1724 (clobber (match_scratch:GPR 0 "=r,r"))] 1725 "<MODE>mode == Pmode" 1726 "@ 1727 add. %0,%1,%2 1728 #" 1729 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1730 [(set (match_dup 0) 1731 (plus:GPR (match_dup 1) 1732 (match_dup 2))) 1733 (set (match_dup 3) 1734 (compare:CC (match_dup 0) 1735 (const_int 0)))] 1736 "" 1737 [(set_attr "type" "add") 1738 (set_attr "dot" "yes") 1739 (set_attr "length" "4,8")]) 1740 1741(define_insn_and_split "*add<mode>3_dot2" 1742 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1743 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 1744 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 1745 (const_int 0))) 1746 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1747 (plus:GPR (match_dup 1) 1748 (match_dup 2)))] 1749 "<MODE>mode == Pmode" 1750 "@ 1751 add. %0,%1,%2 1752 #" 1753 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1754 [(set (match_dup 0) 1755 (plus:GPR (match_dup 1) 1756 (match_dup 2))) 1757 (set (match_dup 3) 1758 (compare:CC (match_dup 0) 1759 (const_int 0)))] 1760 "" 1761 [(set_attr "type" "add") 1762 (set_attr "dot" "yes") 1763 (set_attr "length" "4,8")]) 1764 1765(define_insn_and_split "*add<mode>3_imm_dot" 1766 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1767 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b") 1768 (match_operand:GPR 2 "short_cint_operand" "I,I")) 1769 (const_int 0))) 1770 (clobber (match_scratch:GPR 0 "=r,r")) 1771 (clobber (reg:GPR CA_REGNO))] 1772 "<MODE>mode == Pmode" 1773 "@ 1774 addic. %0,%1,%2 1775 #" 1776 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1777 [(set (match_dup 0) 1778 (plus:GPR (match_dup 1) 1779 (match_dup 2))) 1780 (set (match_dup 3) 1781 (compare:CC (match_dup 0) 1782 (const_int 0)))] 1783 "" 1784 [(set_attr "type" "add") 1785 (set_attr "dot" "yes") 1786 (set_attr "length" "4,8")]) 1787 1788(define_insn_and_split "*add<mode>3_imm_dot2" 1789 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1790 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b") 1791 (match_operand:GPR 2 "short_cint_operand" "I,I")) 1792 (const_int 0))) 1793 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1794 (plus:GPR (match_dup 1) 1795 (match_dup 2))) 1796 (clobber (reg:GPR CA_REGNO))] 1797 "<MODE>mode == Pmode" 1798 "@ 1799 addic. %0,%1,%2 1800 #" 1801 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1802 [(set (match_dup 0) 1803 (plus:GPR (match_dup 1) 1804 (match_dup 2))) 1805 (set (match_dup 3) 1806 (compare:CC (match_dup 0) 1807 (const_int 0)))] 1808 "" 1809 [(set_attr "type" "add") 1810 (set_attr "dot" "yes") 1811 (set_attr "length" "4,8")]) 1812 1813;; Split an add that we can't do in one insn into two insns, each of which 1814;; does one 16-bit part. This is used by combine. Note that the low-order 1815;; add should be last in case the result gets used in an address. 1816 1817(define_split 1818 [(set (match_operand:GPR 0 "gpc_reg_operand") 1819 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand") 1820 (match_operand:GPR 2 "non_add_cint_operand")))] 1821 "" 1822 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3))) 1823 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))] 1824{ 1825 HOST_WIDE_INT val = INTVAL (operands[2]); 1826 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1827 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); 1828 1829 operands[4] = GEN_INT (low); 1830 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest))) 1831 operands[3] = GEN_INT (rest); 1832 else if (can_create_pseudo_p ()) 1833 { 1834 operands[3] = gen_reg_rtx (DImode); 1835 emit_move_insn (operands[3], operands[2]); 1836 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3])); 1837 DONE; 1838 } 1839 else 1840 FAIL; 1841}) 1842 1843 1844(define_insn "add<mode>3_carry" 1845 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1846 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1847 (match_operand:P 2 "reg_or_short_operand" "rI"))) 1848 (set (reg:P CA_REGNO) 1849 (ltu:P (plus:P (match_dup 1) 1850 (match_dup 2)) 1851 (match_dup 1)))] 1852 "" 1853 "add%I2c %0,%1,%2" 1854 [(set_attr "type" "add")]) 1855 1856(define_insn "*add<mode>3_imm_carry_pos" 1857 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1858 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1859 (match_operand:P 2 "short_cint_operand" "n"))) 1860 (set (reg:P CA_REGNO) 1861 (geu:P (match_dup 1) 1862 (match_operand:P 3 "const_int_operand" "n")))] 1863 "INTVAL (operands[2]) > 0 1864 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0" 1865 "addic %0,%1,%2" 1866 [(set_attr "type" "add")]) 1867 1868(define_insn "*add<mode>3_imm_carry_0" 1869 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1870 (match_operand:P 1 "gpc_reg_operand" "r")) 1871 (set (reg:P CA_REGNO) 1872 (const_int 0))] 1873 "" 1874 "addic %0,%1,0" 1875 [(set_attr "type" "add")]) 1876 1877(define_insn "*add<mode>3_imm_carry_m1" 1878 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1879 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1880 (const_int -1))) 1881 (set (reg:P CA_REGNO) 1882 (ne:P (match_dup 1) 1883 (const_int 0)))] 1884 "" 1885 "addic %0,%1,-1" 1886 [(set_attr "type" "add")]) 1887 1888(define_insn "*add<mode>3_imm_carry_neg" 1889 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1890 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1891 (match_operand:P 2 "short_cint_operand" "n"))) 1892 (set (reg:P CA_REGNO) 1893 (gtu:P (match_dup 1) 1894 (match_operand:P 3 "const_int_operand" "n")))] 1895 "INTVAL (operands[2]) < 0 1896 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1" 1897 "addic %0,%1,%2" 1898 [(set_attr "type" "add")]) 1899 1900 1901(define_expand "add<mode>3_carry_in" 1902 [(parallel [ 1903 (set (match_operand:GPR 0 "gpc_reg_operand") 1904 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand") 1905 (match_operand:GPR 2 "adde_operand")) 1906 (reg:GPR CA_REGNO))) 1907 (clobber (reg:GPR CA_REGNO))])] 1908 "" 1909{ 1910 if (operands[2] == const0_rtx) 1911 { 1912 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1])); 1913 DONE; 1914 } 1915 if (operands[2] == constm1_rtx) 1916 { 1917 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1])); 1918 DONE; 1919 } 1920}) 1921 1922(define_insn "*add<mode>3_carry_in_internal" 1923 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1924 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1925 (match_operand:GPR 2 "gpc_reg_operand" "r")) 1926 (reg:GPR CA_REGNO))) 1927 (clobber (reg:GPR CA_REGNO))] 1928 "" 1929 "adde %0,%1,%2" 1930 [(set_attr "type" "add")]) 1931 1932(define_insn "*add<mode>3_carry_in_internal2" 1933 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1934 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1935 (reg:GPR CA_REGNO)) 1936 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 1937 (clobber (reg:GPR CA_REGNO))] 1938 "" 1939 "adde %0,%1,%2" 1940 [(set_attr "type" "add")]) 1941 1942(define_insn "add<mode>3_carry_in_0" 1943 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1944 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1945 (reg:GPR CA_REGNO))) 1946 (clobber (reg:GPR CA_REGNO))] 1947 "" 1948 "addze %0,%1" 1949 [(set_attr "type" "add")]) 1950 1951(define_insn "add<mode>3_carry_in_m1" 1952 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1953 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1954 (reg:GPR CA_REGNO)) 1955 (const_int -1))) 1956 (clobber (reg:GPR CA_REGNO))] 1957 "" 1958 "addme %0,%1" 1959 [(set_attr "type" "add")]) 1960 1961 1962(define_expand "one_cmpl<mode>2" 1963 [(set (match_operand:SDI 0 "gpc_reg_operand") 1964 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))] 1965 "" 1966{ 1967 if (<MODE>mode == DImode && !TARGET_POWERPC64) 1968 { 1969 rs6000_split_logical (operands, NOT, false, false, false); 1970 DONE; 1971 } 1972}) 1973 1974(define_insn "*one_cmpl<mode>2" 1975 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1976 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 1977 "" 1978 "not %0,%1") 1979 1980(define_insn_and_split "*one_cmpl<mode>2_dot" 1981 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1982 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 1983 (const_int 0))) 1984 (clobber (match_scratch:GPR 0 "=r,r"))] 1985 "<MODE>mode == Pmode" 1986 "@ 1987 not. %0,%1 1988 #" 1989 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1990 [(set (match_dup 0) 1991 (not:GPR (match_dup 1))) 1992 (set (match_dup 2) 1993 (compare:CC (match_dup 0) 1994 (const_int 0)))] 1995 "" 1996 [(set_attr "type" "logical") 1997 (set_attr "dot" "yes") 1998 (set_attr "length" "4,8")]) 1999 2000(define_insn_and_split "*one_cmpl<mode>2_dot2" 2001 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2002 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2003 (const_int 0))) 2004 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2005 (not:GPR (match_dup 1)))] 2006 "<MODE>mode == Pmode" 2007 "@ 2008 not. %0,%1 2009 #" 2010 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2011 [(set (match_dup 0) 2012 (not:GPR (match_dup 1))) 2013 (set (match_dup 2) 2014 (compare:CC (match_dup 0) 2015 (const_int 0)))] 2016 "" 2017 [(set_attr "type" "logical") 2018 (set_attr "dot" "yes") 2019 (set_attr "length" "4,8")]) 2020 2021 2022(define_expand "sub<mode>3" 2023 [(set (match_operand:SDI 0 "gpc_reg_operand") 2024 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand") 2025 (match_operand:SDI 2 "gpc_reg_operand")))] 2026 "" 2027{ 2028 if (<MODE>mode == DImode && !TARGET_POWERPC64) 2029 { 2030 rtx lo0 = gen_lowpart (SImode, operands[0]); 2031 rtx lo1 = gen_lowpart (SImode, operands[1]); 2032 rtx lo2 = gen_lowpart (SImode, operands[2]); 2033 rtx hi0 = gen_highpart (SImode, operands[0]); 2034 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]); 2035 rtx hi2 = gen_highpart (SImode, operands[2]); 2036 2037 if (!reg_or_short_operand (lo1, SImode)) 2038 lo1 = force_reg (SImode, lo1); 2039 if (!adde_operand (hi1, SImode)) 2040 hi1 = force_reg (SImode, hi1); 2041 2042 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1)); 2043 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1)); 2044 DONE; 2045 } 2046 2047 if (short_cint_operand (operands[1], <MODE>mode)) 2048 { 2049 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1])); 2050 DONE; 2051 } 2052}) 2053 2054(define_insn "*subf<mode>3" 2055 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2056 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r") 2057 (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2058 "" 2059 "subf %0,%1,%2" 2060 [(set_attr "type" "add")]) 2061 2062(define_insn_and_split "*subf<mode>3_dot" 2063 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2064 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r") 2065 (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2066 (const_int 0))) 2067 (clobber (match_scratch:GPR 0 "=r,r"))] 2068 "<MODE>mode == Pmode" 2069 "@ 2070 subf. %0,%1,%2 2071 #" 2072 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2073 [(set (match_dup 0) 2074 (minus:GPR (match_dup 2) 2075 (match_dup 1))) 2076 (set (match_dup 3) 2077 (compare:CC (match_dup 0) 2078 (const_int 0)))] 2079 "" 2080 [(set_attr "type" "add") 2081 (set_attr "dot" "yes") 2082 (set_attr "length" "4,8")]) 2083 2084(define_insn_and_split "*subf<mode>3_dot2" 2085 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2086 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r") 2087 (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2088 (const_int 0))) 2089 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2090 (minus:GPR (match_dup 2) 2091 (match_dup 1)))] 2092 "<MODE>mode == Pmode" 2093 "@ 2094 subf. %0,%1,%2 2095 #" 2096 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2097 [(set (match_dup 0) 2098 (minus:GPR (match_dup 2) 2099 (match_dup 1))) 2100 (set (match_dup 3) 2101 (compare:CC (match_dup 0) 2102 (const_int 0)))] 2103 "" 2104 [(set_attr "type" "add") 2105 (set_attr "dot" "yes") 2106 (set_attr "length" "4,8")]) 2107 2108(define_insn "subf<mode>3_imm" 2109 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2110 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I") 2111 (match_operand:GPR 1 "gpc_reg_operand" "r"))) 2112 (clobber (reg:GPR CA_REGNO))] 2113 "" 2114 "subfic %0,%1,%2" 2115 [(set_attr "type" "add")]) 2116 2117(define_insn_and_split "subf<mode>3_carry_dot2" 2118 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2119 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r") 2120 (match_operand:P 1 "gpc_reg_operand" "r,r")) 2121 (const_int 0))) 2122 (set (match_operand:P 0 "gpc_reg_operand" "=r,r") 2123 (minus:P (match_dup 2) 2124 (match_dup 1))) 2125 (set (reg:P CA_REGNO) 2126 (leu:P (match_dup 1) 2127 (match_dup 2)))] 2128 "<MODE>mode == Pmode" 2129 "@ 2130 subfc. %0,%1,%2 2131 #" 2132 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2133 [(parallel [(set (match_dup 0) 2134 (minus:P (match_dup 2) 2135 (match_dup 1))) 2136 (set (reg:P CA_REGNO) 2137 (leu:P (match_dup 1) 2138 (match_dup 2)))]) 2139 (set (match_dup 3) 2140 (compare:CC (match_dup 0) 2141 (const_int 0)))] 2142 "" 2143 [(set_attr "type" "add") 2144 (set_attr "dot" "yes") 2145 (set_attr "length" "4,8")]) 2146 2147(define_insn "subf<mode>3_carry" 2148 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2149 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI") 2150 (match_operand:P 1 "gpc_reg_operand" "r"))) 2151 (set (reg:P CA_REGNO) 2152 (leu:P (match_dup 1) 2153 (match_dup 2)))] 2154 "" 2155 "subf%I2c %0,%1,%2" 2156 [(set_attr "type" "add")]) 2157 2158(define_insn "*subf<mode>3_imm_carry_0" 2159 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2160 (neg:P (match_operand:P 1 "gpc_reg_operand" "r"))) 2161 (set (reg:P CA_REGNO) 2162 (eq:P (match_dup 1) 2163 (const_int 0)))] 2164 "" 2165 "subfic %0,%1,0" 2166 [(set_attr "type" "add")]) 2167 2168(define_insn "*subf<mode>3_imm_carry_m1" 2169 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2170 (not:P (match_operand:P 1 "gpc_reg_operand" "r"))) 2171 (set (reg:P CA_REGNO) 2172 (const_int 1))] 2173 "" 2174 "subfic %0,%1,-1" 2175 [(set_attr "type" "add")]) 2176 2177 2178(define_expand "subf<mode>3_carry_in" 2179 [(parallel [ 2180 (set (match_operand:GPR 0 "gpc_reg_operand") 2181 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand")) 2182 (reg:GPR CA_REGNO)) 2183 (match_operand:GPR 2 "adde_operand"))) 2184 (clobber (reg:GPR CA_REGNO))])] 2185 "" 2186{ 2187 if (operands[2] == const0_rtx) 2188 { 2189 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1])); 2190 DONE; 2191 } 2192 if (operands[2] == constm1_rtx) 2193 { 2194 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1])); 2195 DONE; 2196 } 2197}) 2198 2199(define_insn "*subf<mode>3_carry_in_internal" 2200 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2201 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 2202 (reg:GPR CA_REGNO)) 2203 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 2204 (clobber (reg:GPR CA_REGNO))] 2205 "" 2206 "subfe %0,%1,%2" 2207 [(set_attr "type" "add")]) 2208 2209(define_insn "subf<mode>3_carry_in_0" 2210 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2211 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 2212 (reg:GPR CA_REGNO))) 2213 (clobber (reg:GPR CA_REGNO))] 2214 "" 2215 "subfze %0,%1" 2216 [(set_attr "type" "add")]) 2217 2218(define_insn "subf<mode>3_carry_in_m1" 2219 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2220 (plus:GPR (minus:GPR (reg:GPR CA_REGNO) 2221 (match_operand:GPR 1 "gpc_reg_operand" "r")) 2222 (const_int -2))) 2223 (clobber (reg:GPR CA_REGNO))] 2224 "" 2225 "subfme %0,%1" 2226 [(set_attr "type" "add")]) 2227 2228(define_insn "subf<mode>3_carry_in_xx" 2229 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2230 (plus:GPR (reg:GPR CA_REGNO) 2231 (const_int -1))) 2232 (clobber (reg:GPR CA_REGNO))] 2233 "" 2234 "subfe %0,%0,%0" 2235 [(set_attr "type" "add")]) 2236 2237 2238(define_insn "neg<mode>2" 2239 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2240 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2241 "" 2242 "neg %0,%1" 2243 [(set_attr "type" "add")]) 2244 2245(define_insn_and_split "*neg<mode>2_dot" 2246 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2247 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2248 (const_int 0))) 2249 (clobber (match_scratch:GPR 0 "=r,r"))] 2250 "<MODE>mode == Pmode" 2251 "@ 2252 neg. %0,%1 2253 #" 2254 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2255 [(set (match_dup 0) 2256 (neg:GPR (match_dup 1))) 2257 (set (match_dup 2) 2258 (compare:CC (match_dup 0) 2259 (const_int 0)))] 2260 "" 2261 [(set_attr "type" "add") 2262 (set_attr "dot" "yes") 2263 (set_attr "length" "4,8")]) 2264 2265(define_insn_and_split "*neg<mode>2_dot2" 2266 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2267 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2268 (const_int 0))) 2269 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2270 (neg:GPR (match_dup 1)))] 2271 "<MODE>mode == Pmode" 2272 "@ 2273 neg. %0,%1 2274 #" 2275 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2276 [(set (match_dup 0) 2277 (neg:GPR (match_dup 1))) 2278 (set (match_dup 2) 2279 (compare:CC (match_dup 0) 2280 (const_int 0)))] 2281 "" 2282 [(set_attr "type" "add") 2283 (set_attr "dot" "yes") 2284 (set_attr "length" "4,8")]) 2285 2286 2287(define_insn "clz<mode>2" 2288 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2289 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2290 "" 2291 "cntlz<wd> %0,%1" 2292 [(set_attr "type" "cntlz")]) 2293 2294(define_expand "ctz<mode>2" 2295 [(set (match_operand:GPR 0 "gpc_reg_operand") 2296 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2297 "" 2298{ 2299 if (TARGET_CTZ) 2300 { 2301 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1])); 2302 DONE; 2303 } 2304 2305 rtx tmp1 = gen_reg_rtx (<MODE>mode); 2306 rtx tmp2 = gen_reg_rtx (<MODE>mode); 2307 rtx tmp3 = gen_reg_rtx (<MODE>mode); 2308 2309 if (TARGET_POPCNTD) 2310 { 2311 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx)); 2312 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1])); 2313 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2)); 2314 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3)); 2315 } 2316 else 2317 { 2318 emit_insn (gen_neg<mode>2 (tmp1, operands[1])); 2319 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1)); 2320 emit_insn (gen_clz<mode>2 (tmp3, tmp2)); 2321 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3)); 2322 } 2323 2324 DONE; 2325}) 2326 2327(define_insn "ctz<mode>2_hw" 2328 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2329 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2330 "TARGET_CTZ" 2331 "cnttz<wd> %0,%1" 2332 [(set_attr "type" "cntlz")]) 2333 2334(define_expand "ffs<mode>2" 2335 [(set (match_operand:GPR 0 "gpc_reg_operand") 2336 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2337 "" 2338{ 2339 rtx tmp1 = gen_reg_rtx (<MODE>mode); 2340 rtx tmp2 = gen_reg_rtx (<MODE>mode); 2341 rtx tmp3 = gen_reg_rtx (<MODE>mode); 2342 emit_insn (gen_neg<mode>2 (tmp1, operands[1])); 2343 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1)); 2344 emit_insn (gen_clz<mode>2 (tmp3, tmp2)); 2345 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3)); 2346 DONE; 2347}) 2348 2349 2350(define_expand "popcount<mode>2" 2351 [(set (match_operand:GPR 0 "gpc_reg_operand") 2352 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2353 "TARGET_POPCNTB || TARGET_POPCNTD" 2354{ 2355 rs6000_emit_popcount (operands[0], operands[1]); 2356 DONE; 2357}) 2358 2359(define_insn "popcntb<mode>2" 2360 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2361 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] 2362 UNSPEC_POPCNTB))] 2363 "TARGET_POPCNTB" 2364 "popcntb %0,%1" 2365 [(set_attr "type" "popcnt")]) 2366 2367(define_insn "popcntd<mode>2" 2368 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2369 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2370 "TARGET_POPCNTD" 2371 "popcnt<wd> %0,%1" 2372 [(set_attr "type" "popcnt")]) 2373 2374 2375(define_expand "parity<mode>2" 2376 [(set (match_operand:GPR 0 "gpc_reg_operand") 2377 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2378 "TARGET_POPCNTB" 2379{ 2380 rs6000_emit_parity (operands[0], operands[1]); 2381 DONE; 2382}) 2383 2384(define_insn "parity<mode>2_cmpb" 2385 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2386 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))] 2387 "TARGET_CMPB && TARGET_POPCNTB" 2388 "prty<wd> %0,%1" 2389 [(set_attr "type" "popcnt")]) 2390 2391(define_insn "cmpb<mode>3" 2392 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2393 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r") 2394 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))] 2395 "TARGET_CMPB" 2396 "cmpb %0,%1,%2" 2397 [(set_attr "type" "cmp")]) 2398 2399;; Since the hardware zeros the upper part of the register, save generating the 2400;; AND immediate if we are converting to unsigned 2401(define_insn "*bswap<mode>2_extenddi" 2402 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2403 (zero_extend:DI 2404 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))] 2405 "TARGET_POWERPC64" 2406 "l<wd>brx %0,%y1" 2407 [(set_attr "length" "4") 2408 (set_attr "type" "load")]) 2409 2410(define_insn "*bswaphi2_extendsi" 2411 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2412 (zero_extend:SI 2413 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))] 2414 "" 2415 "lhbrx %0,%y1" 2416 [(set_attr "length" "4") 2417 (set_attr "type" "load")]) 2418 2419;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents 2420;; the register allocator from converting a gpr<-gpr swap into a store and then 2421;; load with byte swap, which can be slower than doing it in the registers. It 2422;; also prevents certain failures with the RELOAD register allocator. 2423 2424(define_expand "bswap<mode>2" 2425 [(use (match_operand:HSI 0 "reg_or_mem_operand")) 2426 (use (match_operand:HSI 1 "reg_or_mem_operand"))] 2427 "" 2428{ 2429 rtx dest = operands[0]; 2430 rtx src = operands[1]; 2431 2432 if (!REG_P (dest) && !REG_P (src)) 2433 src = force_reg (<MODE>mode, src); 2434 2435 if (MEM_P (src)) 2436 emit_insn (gen_bswap<mode>2_load (dest, src)); 2437 else if (MEM_P (dest)) 2438 emit_insn (gen_bswap<mode>2_store (dest, src)); 2439 else 2440 emit_insn (gen_bswap<mode>2_reg (dest, src)); 2441 DONE; 2442}) 2443 2444(define_insn "bswap<mode>2_load" 2445 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r") 2446 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))] 2447 "" 2448 "l<wd>brx %0,%y1" 2449 [(set_attr "type" "load")]) 2450 2451(define_insn "bswap<mode>2_store" 2452 [(set (match_operand:HSI 0 "memory_operand" "=Z") 2453 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))] 2454 "" 2455 "st<wd>brx %1,%y0" 2456 [(set_attr "type" "store")]) 2457 2458(define_insn_and_split "bswaphi2_reg" 2459 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo") 2460 (bswap:HI 2461 (match_operand:HI 1 "gpc_reg_operand" "r,wo"))) 2462 (clobber (match_scratch:SI 2 "=&r,X"))] 2463 "" 2464 "@ 2465 # 2466 xxbrh %x0,%x1" 2467 "reload_completed && int_reg_operand (operands[0], HImode)" 2468 [(set (match_dup 3) 2469 (and:SI (lshiftrt:SI (match_dup 4) 2470 (const_int 8)) 2471 (const_int 255))) 2472 (set (match_dup 2) 2473 (and:SI (ashift:SI (match_dup 4) 2474 (const_int 8)) 2475 (const_int 65280))) ;; 0xff00 2476 (set (match_dup 3) 2477 (ior:SI (match_dup 3) 2478 (match_dup 2)))] 2479{ 2480 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0); 2481 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 2482} 2483 [(set_attr "length" "12,4") 2484 (set_attr "type" "*,vecperm")]) 2485 2486;; We are always BITS_BIG_ENDIAN, so the bit positions below in 2487;; zero_extract insns do not change for -mlittle. 2488(define_insn_and_split "bswapsi2_reg" 2489 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo") 2490 (bswap:SI 2491 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))] 2492 "" 2493 "@ 2494 # 2495 xxbrw %x0,%x1" 2496 "reload_completed && int_reg_operand (operands[0], SImode)" 2497 [(set (match_dup 0) ; DABC 2498 (rotate:SI (match_dup 1) 2499 (const_int 24))) 2500 (set (match_dup 0) ; DCBC 2501 (ior:SI (and:SI (ashift:SI (match_dup 1) 2502 (const_int 8)) 2503 (const_int 16711680)) 2504 (and:SI (match_dup 0) 2505 (const_int -16711681)))) 2506 (set (match_dup 0) ; DCBA 2507 (ior:SI (and:SI (lshiftrt:SI (match_dup 1) 2508 (const_int 24)) 2509 (const_int 255)) 2510 (and:SI (match_dup 0) 2511 (const_int -256))))] 2512 "" 2513 [(set_attr "length" "12,4") 2514 (set_attr "type" "*,vecperm")]) 2515 2516;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like 2517;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more 2518;; complex code. 2519 2520(define_expand "bswapdi2" 2521 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand") 2522 (bswap:DI 2523 (match_operand:DI 1 "reg_or_mem_operand"))) 2524 (clobber (match_scratch:DI 2)) 2525 (clobber (match_scratch:DI 3))])] 2526 "" 2527{ 2528 rtx dest = operands[0]; 2529 rtx src = operands[1]; 2530 2531 if (!REG_P (dest) && !REG_P (src)) 2532 operands[1] = src = force_reg (DImode, src); 2533 2534 if (TARGET_POWERPC64 && TARGET_LDBRX) 2535 { 2536 if (MEM_P (src)) 2537 emit_insn (gen_bswapdi2_load (dest, src)); 2538 else if (MEM_P (dest)) 2539 emit_insn (gen_bswapdi2_store (dest, src)); 2540 else if (TARGET_P9_VECTOR) 2541 emit_insn (gen_bswapdi2_xxbrd (dest, src)); 2542 else 2543 emit_insn (gen_bswapdi2_reg (dest, src)); 2544 DONE; 2545 } 2546 2547 if (!TARGET_POWERPC64) 2548 { 2549 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode 2550 that uses 64-bit registers needs the same scratch registers as 64-bit 2551 mode. */ 2552 emit_insn (gen_bswapdi2_32bit (dest, src)); 2553 DONE; 2554 } 2555}) 2556 2557;; Power7/cell has ldbrx/stdbrx, so use it directly 2558(define_insn "bswapdi2_load" 2559 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2560 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))] 2561 "TARGET_POWERPC64 && TARGET_LDBRX" 2562 "ldbrx %0,%y1" 2563 [(set_attr "type" "load")]) 2564 2565(define_insn "bswapdi2_store" 2566 [(set (match_operand:DI 0 "memory_operand" "=Z") 2567 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] 2568 "TARGET_POWERPC64 && TARGET_LDBRX" 2569 "stdbrx %1,%y0" 2570 [(set_attr "type" "store")]) 2571 2572(define_insn "bswapdi2_xxbrd" 2573 [(set (match_operand:DI 0 "gpc_reg_operand" "=wo") 2574 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))] 2575 "TARGET_P9_VECTOR" 2576 "xxbrd %x0,%x1" 2577 [(set_attr "type" "vecperm")]) 2578 2579(define_insn "bswapdi2_reg" 2580 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") 2581 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) 2582 (clobber (match_scratch:DI 2 "=&r")) 2583 (clobber (match_scratch:DI 3 "=&r"))] 2584 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR" 2585 "#" 2586 [(set_attr "length" "36")]) 2587 2588;; Non-power7/cell, fall back to use lwbrx/stwbrx 2589(define_insn "*bswapdi2_64bit" 2590 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r") 2591 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) 2592 (clobber (match_scratch:DI 2 "=&b,&b,&r")) 2593 (clobber (match_scratch:DI 3 "=&r,&r,&r"))] 2594 "TARGET_POWERPC64 && !TARGET_LDBRX 2595 && (REG_P (operands[0]) || REG_P (operands[1])) 2596 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) 2597 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))" 2598 "#" 2599 [(set_attr "length" "16,12,36")]) 2600 2601(define_split 2602 [(set (match_operand:DI 0 "gpc_reg_operand") 2603 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand"))) 2604 (clobber (match_operand:DI 2 "gpc_reg_operand")) 2605 (clobber (match_operand:DI 3 "gpc_reg_operand"))] 2606 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" 2607 [(const_int 0)] 2608{ 2609 rtx dest = operands[0]; 2610 rtx src = operands[1]; 2611 rtx op2 = operands[2]; 2612 rtx op3 = operands[3]; 2613 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, 2614 BYTES_BIG_ENDIAN ? 4 : 0); 2615 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode, 2616 BYTES_BIG_ENDIAN ? 4 : 0); 2617 rtx addr1; 2618 rtx addr2; 2619 rtx word1; 2620 rtx word2; 2621 2622 addr1 = XEXP (src, 0); 2623 if (GET_CODE (addr1) == PLUS) 2624 { 2625 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2626 if (TARGET_AVOID_XFORM) 2627 { 2628 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2629 addr2 = op2; 2630 } 2631 else 2632 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); 2633 } 2634 else if (TARGET_AVOID_XFORM) 2635 { 2636 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2637 addr2 = op2; 2638 } 2639 else 2640 { 2641 emit_move_insn (op2, GEN_INT (4)); 2642 addr2 = gen_rtx_PLUS (Pmode, op2, addr1); 2643 } 2644 2645 word1 = change_address (src, SImode, addr1); 2646 word2 = change_address (src, SImode, addr2); 2647 2648 if (BYTES_BIG_ENDIAN) 2649 { 2650 emit_insn (gen_bswapsi2 (op3_32, word2)); 2651 emit_insn (gen_bswapsi2 (dest_32, word1)); 2652 } 2653 else 2654 { 2655 emit_insn (gen_bswapsi2 (op3_32, word1)); 2656 emit_insn (gen_bswapsi2 (dest_32, word2)); 2657 } 2658 2659 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32))); 2660 emit_insn (gen_iordi3 (dest, dest, op3)); 2661 DONE; 2662}) 2663 2664(define_split 2665 [(set (match_operand:DI 0 "indexed_or_indirect_operand") 2666 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 2667 (clobber (match_operand:DI 2 "gpc_reg_operand")) 2668 (clobber (match_operand:DI 3 "gpc_reg_operand"))] 2669 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" 2670 [(const_int 0)] 2671{ 2672 rtx dest = operands[0]; 2673 rtx src = operands[1]; 2674 rtx op2 = operands[2]; 2675 rtx op3 = operands[3]; 2676 rtx src_si = simplify_gen_subreg (SImode, src, DImode, 2677 BYTES_BIG_ENDIAN ? 4 : 0); 2678 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 2679 BYTES_BIG_ENDIAN ? 4 : 0); 2680 rtx addr1; 2681 rtx addr2; 2682 rtx word1; 2683 rtx word2; 2684 2685 addr1 = XEXP (dest, 0); 2686 if (GET_CODE (addr1) == PLUS) 2687 { 2688 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2689 if (TARGET_AVOID_XFORM) 2690 { 2691 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2692 addr2 = op2; 2693 } 2694 else 2695 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); 2696 } 2697 else if (TARGET_AVOID_XFORM) 2698 { 2699 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2700 addr2 = op2; 2701 } 2702 else 2703 { 2704 emit_move_insn (op2, GEN_INT (4)); 2705 addr2 = gen_rtx_PLUS (Pmode, op2, addr1); 2706 } 2707 2708 word1 = change_address (dest, SImode, addr1); 2709 word2 = change_address (dest, SImode, addr2); 2710 2711 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32))); 2712 2713 if (BYTES_BIG_ENDIAN) 2714 { 2715 emit_insn (gen_bswapsi2 (word1, src_si)); 2716 emit_insn (gen_bswapsi2 (word2, op3_si)); 2717 } 2718 else 2719 { 2720 emit_insn (gen_bswapsi2 (word2, src_si)); 2721 emit_insn (gen_bswapsi2 (word1, op3_si)); 2722 } 2723 DONE; 2724}) 2725 2726(define_split 2727 [(set (match_operand:DI 0 "gpc_reg_operand") 2728 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 2729 (clobber (match_operand:DI 2 "gpc_reg_operand")) 2730 (clobber (match_operand:DI 3 "gpc_reg_operand"))] 2731 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed" 2732 [(const_int 0)] 2733{ 2734 rtx dest = operands[0]; 2735 rtx src = operands[1]; 2736 rtx op2 = operands[2]; 2737 rtx op3 = operands[3]; 2738 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0; 2739 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off); 2740 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off); 2741 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off); 2742 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off); 2743 2744 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32))); 2745 emit_insn (gen_bswapsi2 (dest_si, src_si)); 2746 emit_insn (gen_bswapsi2 (op3_si, op2_si)); 2747 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32))); 2748 emit_insn (gen_iordi3 (dest, dest, op3)); 2749 DONE; 2750}) 2751 2752(define_insn "bswapdi2_32bit" 2753 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r") 2754 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) 2755 (clobber (match_scratch:SI 2 "=&b,&b,X"))] 2756 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))" 2757 "#" 2758 [(set_attr "length" "16,12,36")]) 2759 2760(define_split 2761 [(set (match_operand:DI 0 "gpc_reg_operand") 2762 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand"))) 2763 (clobber (match_operand:SI 2 "gpc_reg_operand"))] 2764 "!TARGET_POWERPC64 && reload_completed" 2765 [(const_int 0)] 2766{ 2767 rtx dest = operands[0]; 2768 rtx src = operands[1]; 2769 rtx op2 = operands[2]; 2770 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); 2771 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); 2772 rtx addr1; 2773 rtx addr2; 2774 rtx word1; 2775 rtx word2; 2776 2777 addr1 = XEXP (src, 0); 2778 if (GET_CODE (addr1) == PLUS) 2779 { 2780 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2781 if (TARGET_AVOID_XFORM 2782 || REGNO (XEXP (addr1, 1)) == REGNO (dest2)) 2783 { 2784 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2785 addr2 = op2; 2786 } 2787 else 2788 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); 2789 } 2790 else if (TARGET_AVOID_XFORM 2791 || REGNO (addr1) == REGNO (dest2)) 2792 { 2793 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2794 addr2 = op2; 2795 } 2796 else 2797 { 2798 emit_move_insn (op2, GEN_INT (4)); 2799 addr2 = gen_rtx_PLUS (SImode, op2, addr1); 2800 } 2801 2802 word1 = change_address (src, SImode, addr1); 2803 word2 = change_address (src, SImode, addr2); 2804 2805 emit_insn (gen_bswapsi2 (dest2, word1)); 2806 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed, 2807 thus allowing us to omit an early clobber on the output. */ 2808 emit_insn (gen_bswapsi2 (dest1, word2)); 2809 DONE; 2810}) 2811 2812(define_split 2813 [(set (match_operand:DI 0 "indexed_or_indirect_operand") 2814 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 2815 (clobber (match_operand:SI 2 "gpc_reg_operand"))] 2816 "!TARGET_POWERPC64 && reload_completed" 2817 [(const_int 0)] 2818{ 2819 rtx dest = operands[0]; 2820 rtx src = operands[1]; 2821 rtx op2 = operands[2]; 2822 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); 2823 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); 2824 rtx addr1; 2825 rtx addr2; 2826 rtx word1; 2827 rtx word2; 2828 2829 addr1 = XEXP (dest, 0); 2830 if (GET_CODE (addr1) == PLUS) 2831 { 2832 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2833 if (TARGET_AVOID_XFORM) 2834 { 2835 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2836 addr2 = op2; 2837 } 2838 else 2839 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); 2840 } 2841 else if (TARGET_AVOID_XFORM) 2842 { 2843 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2844 addr2 = op2; 2845 } 2846 else 2847 { 2848 emit_move_insn (op2, GEN_INT (4)); 2849 addr2 = gen_rtx_PLUS (SImode, op2, addr1); 2850 } 2851 2852 word1 = change_address (dest, SImode, addr1); 2853 word2 = change_address (dest, SImode, addr2); 2854 2855 emit_insn (gen_bswapsi2 (word2, src1)); 2856 emit_insn (gen_bswapsi2 (word1, src2)); 2857 DONE; 2858}) 2859 2860(define_split 2861 [(set (match_operand:DI 0 "gpc_reg_operand") 2862 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 2863 (clobber (match_operand:SI 2 ""))] 2864 "!TARGET_POWERPC64 && reload_completed" 2865 [(const_int 0)] 2866{ 2867 rtx dest = operands[0]; 2868 rtx src = operands[1]; 2869 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); 2870 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); 2871 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); 2872 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); 2873 2874 emit_insn (gen_bswapsi2 (dest1, src2)); 2875 emit_insn (gen_bswapsi2 (dest2, src1)); 2876 DONE; 2877}) 2878 2879 2880(define_insn "mul<mode>3" 2881 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2882 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 2883 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))] 2884 "" 2885 "@ 2886 mull<wd> %0,%1,%2 2887 mulli %0,%1,%2" 2888 [(set_attr "type" "mul") 2889 (set (attr "size") 2890 (cond [(match_operand:GPR 2 "s8bit_cint_operand") 2891 (const_string "8") 2892 (match_operand:GPR 2 "short_cint_operand") 2893 (const_string "16")] 2894 (const_string "<bits>")))]) 2895 2896(define_insn_and_split "*mul<mode>3_dot" 2897 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2898 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 2899 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 2900 (const_int 0))) 2901 (clobber (match_scratch:GPR 0 "=r,r"))] 2902 "<MODE>mode == Pmode" 2903 "@ 2904 mull<wd>. %0,%1,%2 2905 #" 2906 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2907 [(set (match_dup 0) 2908 (mult:GPR (match_dup 1) 2909 (match_dup 2))) 2910 (set (match_dup 3) 2911 (compare:CC (match_dup 0) 2912 (const_int 0)))] 2913 "" 2914 [(set_attr "type" "mul") 2915 (set_attr "size" "<bits>") 2916 (set_attr "dot" "yes") 2917 (set_attr "length" "4,8")]) 2918 2919(define_insn_and_split "*mul<mode>3_dot2" 2920 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2921 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 2922 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 2923 (const_int 0))) 2924 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2925 (mult:GPR (match_dup 1) 2926 (match_dup 2)))] 2927 "<MODE>mode == Pmode" 2928 "@ 2929 mull<wd>. %0,%1,%2 2930 #" 2931 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2932 [(set (match_dup 0) 2933 (mult:GPR (match_dup 1) 2934 (match_dup 2))) 2935 (set (match_dup 3) 2936 (compare:CC (match_dup 0) 2937 (const_int 0)))] 2938 "" 2939 [(set_attr "type" "mul") 2940 (set_attr "size" "<bits>") 2941 (set_attr "dot" "yes") 2942 (set_attr "length" "4,8")]) 2943 2944 2945(define_expand "<su>mul<mode>3_highpart" 2946 [(set (match_operand:GPR 0 "gpc_reg_operand") 2947 (subreg:GPR 2948 (mult:<DMODE> (any_extend:<DMODE> 2949 (match_operand:GPR 1 "gpc_reg_operand")) 2950 (any_extend:<DMODE> 2951 (match_operand:GPR 2 "gpc_reg_operand"))) 2952 0))] 2953 "" 2954{ 2955 if (<MODE>mode == SImode && TARGET_POWERPC64) 2956 { 2957 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1], 2958 operands[2])); 2959 DONE; 2960 } 2961 2962 if (!WORDS_BIG_ENDIAN) 2963 { 2964 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1], 2965 operands[2])); 2966 DONE; 2967 } 2968}) 2969 2970(define_insn "*<su>mul<mode>3_highpart" 2971 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2972 (subreg:GPR 2973 (mult:<DMODE> (any_extend:<DMODE> 2974 (match_operand:GPR 1 "gpc_reg_operand" "r")) 2975 (any_extend:<DMODE> 2976 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 2977 0))] 2978 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)" 2979 "mulh<wd><u> %0,%1,%2" 2980 [(set_attr "type" "mul") 2981 (set_attr "size" "<bits>")]) 2982 2983(define_insn "<su>mulsi3_highpart_le" 2984 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2985 (subreg:SI 2986 (mult:DI (any_extend:DI 2987 (match_operand:SI 1 "gpc_reg_operand" "r")) 2988 (any_extend:DI 2989 (match_operand:SI 2 "gpc_reg_operand" "r"))) 2990 4))] 2991 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64" 2992 "mulhw<u> %0,%1,%2" 2993 [(set_attr "type" "mul")]) 2994 2995(define_insn "<su>muldi3_highpart_le" 2996 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2997 (subreg:DI 2998 (mult:TI (any_extend:TI 2999 (match_operand:DI 1 "gpc_reg_operand" "r")) 3000 (any_extend:TI 3001 (match_operand:DI 2 "gpc_reg_operand" "r"))) 3002 8))] 3003 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64" 3004 "mulhd<u> %0,%1,%2" 3005 [(set_attr "type" "mul") 3006 (set_attr "size" "64")]) 3007 3008(define_insn "<su>mulsi3_highpart_64" 3009 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 3010 (truncate:SI 3011 (lshiftrt:DI 3012 (mult:DI (any_extend:DI 3013 (match_operand:SI 1 "gpc_reg_operand" "r")) 3014 (any_extend:DI 3015 (match_operand:SI 2 "gpc_reg_operand" "r"))) 3016 (const_int 32))))] 3017 "TARGET_POWERPC64" 3018 "mulhw<u> %0,%1,%2" 3019 [(set_attr "type" "mul")]) 3020 3021(define_expand "<u>mul<mode><dmode>3" 3022 [(set (match_operand:<DMODE> 0 "gpc_reg_operand") 3023 (mult:<DMODE> (any_extend:<DMODE> 3024 (match_operand:GPR 1 "gpc_reg_operand")) 3025 (any_extend:<DMODE> 3026 (match_operand:GPR 2 "gpc_reg_operand"))))] 3027 "!(<MODE>mode == SImode && TARGET_POWERPC64)" 3028{ 3029 rtx l = gen_reg_rtx (<MODE>mode); 3030 rtx h = gen_reg_rtx (<MODE>mode); 3031 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2])); 3032 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2])); 3033 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l); 3034 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h); 3035 DONE; 3036}) 3037 3038(define_insn "*maddld4" 3039 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3040 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r") 3041 (match_operand:DI 2 "gpc_reg_operand" "r")) 3042 (match_operand:DI 3 "gpc_reg_operand" "r")))] 3043 "TARGET_MADDLD" 3044 "maddld %0,%1,%2,%3" 3045 [(set_attr "type" "mul")]) 3046 3047(define_insn "udiv<mode>3" 3048 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3049 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3050 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3051 "" 3052 "div<wd>u %0,%1,%2" 3053 [(set_attr "type" "div") 3054 (set_attr "size" "<bits>")]) 3055 3056 3057;; For powers of two we can do sra[wd]i/addze for divide and then adjust for 3058;; modulus. If it isn't a power of two, force operands into register and do 3059;; a normal divide. 3060(define_expand "div<mode>3" 3061 [(set (match_operand:GPR 0 "gpc_reg_operand") 3062 (div:GPR (match_operand:GPR 1 "gpc_reg_operand") 3063 (match_operand:GPR 2 "reg_or_cint_operand")))] 3064 "" 3065{ 3066 if (CONST_INT_P (operands[2]) 3067 && INTVAL (operands[2]) > 0 3068 && exact_log2 (INTVAL (operands[2])) >= 0) 3069 { 3070 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2])); 3071 DONE; 3072 } 3073 3074 operands[2] = force_reg (<MODE>mode, operands[2]); 3075}) 3076 3077(define_insn "*div<mode>3" 3078 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3079 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3080 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3081 "" 3082 "div<wd> %0,%1,%2" 3083 [(set_attr "type" "div") 3084 (set_attr "size" "<bits>")]) 3085 3086(define_insn "div<mode>3_sra" 3087 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3088 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3089 (match_operand:GPR 2 "exact_log2_cint_operand" "N"))) 3090 (clobber (reg:GPR CA_REGNO))] 3091 "" 3092 "sra<wd>i %0,%1,%p2\;addze %0,%0" 3093 [(set_attr "type" "two") 3094 (set_attr "length" "8")]) 3095 3096(define_insn_and_split "*div<mode>3_sra_dot" 3097 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3098 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3099 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")) 3100 (const_int 0))) 3101 (clobber (match_scratch:GPR 0 "=r,r")) 3102 (clobber (reg:GPR CA_REGNO))] 3103 "<MODE>mode == Pmode" 3104 "@ 3105 sra<wd>i %0,%1,%p2\;addze. %0,%0 3106 #" 3107 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3108 [(parallel [(set (match_dup 0) 3109 (div:GPR (match_dup 1) 3110 (match_dup 2))) 3111 (clobber (reg:GPR CA_REGNO))]) 3112 (set (match_dup 3) 3113 (compare:CC (match_dup 0) 3114 (const_int 0)))] 3115 "" 3116 [(set_attr "type" "two") 3117 (set_attr "length" "8,12") 3118 (set_attr "cell_micro" "not")]) 3119 3120(define_insn_and_split "*div<mode>3_sra_dot2" 3121 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3122 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3123 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")) 3124 (const_int 0))) 3125 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3126 (div:GPR (match_dup 1) 3127 (match_dup 2))) 3128 (clobber (reg:GPR CA_REGNO))] 3129 "<MODE>mode == Pmode" 3130 "@ 3131 sra<wd>i %0,%1,%p2\;addze. %0,%0 3132 #" 3133 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3134 [(parallel [(set (match_dup 0) 3135 (div:GPR (match_dup 1) 3136 (match_dup 2))) 3137 (clobber (reg:GPR CA_REGNO))]) 3138 (set (match_dup 3) 3139 (compare:CC (match_dup 0) 3140 (const_int 0)))] 3141 "" 3142 [(set_attr "type" "two") 3143 (set_attr "length" "8,12") 3144 (set_attr "cell_micro" "not")]) 3145 3146(define_expand "mod<mode>3" 3147 [(set (match_operand:GPR 0 "gpc_reg_operand") 3148 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand") 3149 (match_operand:GPR 2 "reg_or_cint_operand")))] 3150 "" 3151{ 3152 int i; 3153 rtx temp1; 3154 rtx temp2; 3155 3156 if (GET_CODE (operands[2]) != CONST_INT 3157 || INTVAL (operands[2]) <= 0 3158 || (i = exact_log2 (INTVAL (operands[2]))) < 0) 3159 { 3160 if (!TARGET_MODULO) 3161 FAIL; 3162 3163 operands[2] = force_reg (<MODE>mode, operands[2]); 3164 } 3165 else 3166 { 3167 temp1 = gen_reg_rtx (<MODE>mode); 3168 temp2 = gen_reg_rtx (<MODE>mode); 3169 3170 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2])); 3171 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i))); 3172 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2)); 3173 DONE; 3174 } 3175}) 3176 3177;; In order to enable using a peephole2 for combining div/mod to eliminate the 3178;; mod, prefer putting the result of mod into a different register 3179(define_insn "*mod<mode>3" 3180 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 3181 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3182 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3183 "TARGET_MODULO" 3184 "mods<wd> %0,%1,%2" 3185 [(set_attr "type" "div") 3186 (set_attr "size" "<bits>")]) 3187 3188 3189(define_insn "umod<mode>3" 3190 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 3191 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3192 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3193 "TARGET_MODULO" 3194 "modu<wd> %0,%1,%2" 3195 [(set_attr "type" "div") 3196 (set_attr "size" "<bits>")]) 3197 3198;; On machines with modulo support, do a combined div/mod the old fashioned 3199;; method, since the multiply/subtract is faster than doing the mod instruction 3200;; after a divide. 3201 3202(define_peephole2 3203 [(set (match_operand:GPR 0 "gpc_reg_operand") 3204 (div:GPR (match_operand:GPR 1 "gpc_reg_operand") 3205 (match_operand:GPR 2 "gpc_reg_operand"))) 3206 (set (match_operand:GPR 3 "gpc_reg_operand") 3207 (mod:GPR (match_dup 1) 3208 (match_dup 2)))] 3209 "TARGET_MODULO 3210 && ! reg_mentioned_p (operands[0], operands[1]) 3211 && ! reg_mentioned_p (operands[0], operands[2]) 3212 && ! reg_mentioned_p (operands[3], operands[1]) 3213 && ! reg_mentioned_p (operands[3], operands[2])" 3214 [(set (match_dup 0) 3215 (div:GPR (match_dup 1) 3216 (match_dup 2))) 3217 (set (match_dup 3) 3218 (mult:GPR (match_dup 0) 3219 (match_dup 2))) 3220 (set (match_dup 3) 3221 (minus:GPR (match_dup 1) 3222 (match_dup 3)))]) 3223 3224(define_peephole2 3225 [(set (match_operand:GPR 0 "gpc_reg_operand") 3226 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand") 3227 (match_operand:GPR 2 "gpc_reg_operand"))) 3228 (set (match_operand:GPR 3 "gpc_reg_operand") 3229 (umod:GPR (match_dup 1) 3230 (match_dup 2)))] 3231 "TARGET_MODULO 3232 && ! reg_mentioned_p (operands[0], operands[1]) 3233 && ! reg_mentioned_p (operands[0], operands[2]) 3234 && ! reg_mentioned_p (operands[3], operands[1]) 3235 && ! reg_mentioned_p (operands[3], operands[2])" 3236 [(set (match_dup 0) 3237 (udiv:GPR (match_dup 1) 3238 (match_dup 2))) 3239 (set (match_dup 3) 3240 (mult:GPR (match_dup 0) 3241 (match_dup 2))) 3242 (set (match_dup 3) 3243 (minus:GPR (match_dup 1) 3244 (match_dup 3)))]) 3245 3246 3247;; Logical instructions 3248;; The logical instructions are mostly combined by using match_operator, 3249;; but the plain AND insns are somewhat different because there is no 3250;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all 3251;; those rotate-and-mask operations. Thus, the AND insns come first. 3252 3253(define_expand "and<mode>3" 3254 [(set (match_operand:SDI 0 "gpc_reg_operand") 3255 (and:SDI (match_operand:SDI 1 "gpc_reg_operand") 3256 (match_operand:SDI 2 "reg_or_cint_operand")))] 3257 "" 3258{ 3259 if (<MODE>mode == DImode && !TARGET_POWERPC64) 3260 { 3261 rs6000_split_logical (operands, AND, false, false, false); 3262 DONE; 3263 } 3264 3265 if (CONST_INT_P (operands[2])) 3266 { 3267 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode)) 3268 { 3269 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2])); 3270 DONE; 3271 } 3272 3273 if (logical_const_operand (operands[2], <MODE>mode)) 3274 { 3275 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2])); 3276 DONE; 3277 } 3278 3279 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode)) 3280 { 3281 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0); 3282 DONE; 3283 } 3284 3285 operands[2] = force_reg (<MODE>mode, operands[2]); 3286 } 3287}) 3288 3289 3290(define_insn "and<mode>3_imm" 3291 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3292 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3293 (match_operand:GPR 2 "logical_const_operand" "n"))) 3294 (clobber (match_scratch:CC 3 "=x"))] 3295 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3296 "andi%e2. %0,%1,%u2" 3297 [(set_attr "type" "logical") 3298 (set_attr "dot" "yes")]) 3299 3300(define_insn_and_split "*and<mode>3_imm_dot" 3301 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3302 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3303 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3304 (const_int 0))) 3305 (clobber (match_scratch:GPR 0 "=r,r")) 3306 (clobber (match_scratch:CC 4 "=X,x"))] 3307 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3308 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3309 "@ 3310 andi%e2. %0,%1,%u2 3311 #" 3312 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3313 [(parallel [(set (match_dup 0) 3314 (and:GPR (match_dup 1) 3315 (match_dup 2))) 3316 (clobber (match_dup 4))]) 3317 (set (match_dup 3) 3318 (compare:CC (match_dup 0) 3319 (const_int 0)))] 3320 "" 3321 [(set_attr "type" "logical") 3322 (set_attr "dot" "yes") 3323 (set_attr "length" "4,8")]) 3324 3325(define_insn_and_split "*and<mode>3_imm_dot2" 3326 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3327 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3328 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3329 (const_int 0))) 3330 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3331 (and:GPR (match_dup 1) 3332 (match_dup 2))) 3333 (clobber (match_scratch:CC 4 "=X,x"))] 3334 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3335 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3336 "@ 3337 andi%e2. %0,%1,%u2 3338 #" 3339 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3340 [(parallel [(set (match_dup 0) 3341 (and:GPR (match_dup 1) 3342 (match_dup 2))) 3343 (clobber (match_dup 4))]) 3344 (set (match_dup 3) 3345 (compare:CC (match_dup 0) 3346 (const_int 0)))] 3347 "" 3348 [(set_attr "type" "logical") 3349 (set_attr "dot" "yes") 3350 (set_attr "length" "4,8")]) 3351 3352(define_insn_and_split "*and<mode>3_imm_mask_dot" 3353 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3354 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3355 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3356 (const_int 0))) 3357 (clobber (match_scratch:GPR 0 "=r,r"))] 3358 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3359 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3360 "@ 3361 andi%e2. %0,%1,%u2 3362 #" 3363 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3364 [(set (match_dup 0) 3365 (and:GPR (match_dup 1) 3366 (match_dup 2))) 3367 (set (match_dup 3) 3368 (compare:CC (match_dup 0) 3369 (const_int 0)))] 3370 "" 3371 [(set_attr "type" "logical") 3372 (set_attr "dot" "yes") 3373 (set_attr "length" "4,8")]) 3374 3375(define_insn_and_split "*and<mode>3_imm_mask_dot2" 3376 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3377 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3378 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3379 (const_int 0))) 3380 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3381 (and:GPR (match_dup 1) 3382 (match_dup 2)))] 3383 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3384 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3385 "@ 3386 andi%e2. %0,%1,%u2 3387 #" 3388 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3389 [(set (match_dup 0) 3390 (and:GPR (match_dup 1) 3391 (match_dup 2))) 3392 (set (match_dup 3) 3393 (compare:CC (match_dup 0) 3394 (const_int 0)))] 3395 "" 3396 [(set_attr "type" "logical") 3397 (set_attr "dot" "yes") 3398 (set_attr "length" "4,8")]) 3399 3400(define_insn "*and<mode>3_imm_dot_shifted" 3401 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 3402 (compare:CC 3403 (and:GPR 3404 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3405 (match_operand:SI 4 "const_int_operand" "n")) 3406 (match_operand:GPR 2 "const_int_operand" "n")) 3407 (const_int 0))) 3408 (clobber (match_scratch:GPR 0 "=r"))] 3409 "logical_const_operand (GEN_INT (UINTVAL (operands[2]) 3410 << INTVAL (operands[4])), 3411 DImode) 3412 && (<MODE>mode == Pmode 3413 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)" 3414{ 3415 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4])); 3416 return "andi%e2. %0,%1,%u2"; 3417} 3418 [(set_attr "type" "logical") 3419 (set_attr "dot" "yes")]) 3420 3421 3422(define_insn "and<mode>3_mask" 3423 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3424 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3425 (match_operand:GPR 2 "const_int_operand" "n")))] 3426 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3427{ 3428 return rs6000_insn_for_and_mask (<MODE>mode, operands, false); 3429} 3430 [(set_attr "type" "shift")]) 3431 3432(define_insn_and_split "*and<mode>3_mask_dot" 3433 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3434 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3435 (match_operand:GPR 2 "const_int_operand" "n,n")) 3436 (const_int 0))) 3437 (clobber (match_scratch:GPR 0 "=r,r"))] 3438 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3439 && !logical_const_operand (operands[2], <MODE>mode) 3440 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3441{ 3442 if (which_alternative == 0) 3443 return rs6000_insn_for_and_mask (<MODE>mode, operands, true); 3444 else 3445 return "#"; 3446} 3447 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3448 [(set (match_dup 0) 3449 (and:GPR (match_dup 1) 3450 (match_dup 2))) 3451 (set (match_dup 3) 3452 (compare:CC (match_dup 0) 3453 (const_int 0)))] 3454 "" 3455 [(set_attr "type" "shift") 3456 (set_attr "dot" "yes") 3457 (set_attr "length" "4,8")]) 3458 3459(define_insn_and_split "*and<mode>3_mask_dot2" 3460 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3461 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3462 (match_operand:GPR 2 "const_int_operand" "n,n")) 3463 (const_int 0))) 3464 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3465 (and:GPR (match_dup 1) 3466 (match_dup 2)))] 3467 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3468 && !logical_const_operand (operands[2], <MODE>mode) 3469 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3470{ 3471 if (which_alternative == 0) 3472 return rs6000_insn_for_and_mask (<MODE>mode, operands, true); 3473 else 3474 return "#"; 3475} 3476 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3477 [(set (match_dup 0) 3478 (and:GPR (match_dup 1) 3479 (match_dup 2))) 3480 (set (match_dup 3) 3481 (compare:CC (match_dup 0) 3482 (const_int 0)))] 3483 "" 3484 [(set_attr "type" "shift") 3485 (set_attr "dot" "yes") 3486 (set_attr "length" "4,8")]) 3487 3488 3489(define_insn_and_split "*and<mode>3_2insn" 3490 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3491 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3492 (match_operand:GPR 2 "const_int_operand" "n")))] 3493 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3494 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3495 || logical_const_operand (operands[2], <MODE>mode))" 3496 "#" 3497 "&& 1" 3498 [(pc)] 3499{ 3500 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0); 3501 DONE; 3502} 3503 [(set_attr "type" "shift") 3504 (set_attr "length" "8")]) 3505 3506(define_insn_and_split "*and<mode>3_2insn_dot" 3507 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3508 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3509 (match_operand:GPR 2 "const_int_operand" "n,n")) 3510 (const_int 0))) 3511 (clobber (match_scratch:GPR 0 "=r,r"))] 3512 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3513 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3514 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3515 || logical_const_operand (operands[2], <MODE>mode))" 3516 "#" 3517 "&& reload_completed" 3518 [(pc)] 3519{ 3520 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1); 3521 DONE; 3522} 3523 [(set_attr "type" "shift") 3524 (set_attr "dot" "yes") 3525 (set_attr "length" "8,12")]) 3526 3527(define_insn_and_split "*and<mode>3_2insn_dot2" 3528 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3529 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3530 (match_operand:GPR 2 "const_int_operand" "n,n")) 3531 (const_int 0))) 3532 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3533 (and:GPR (match_dup 1) 3534 (match_dup 2)))] 3535 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3536 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3537 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3538 || logical_const_operand (operands[2], <MODE>mode))" 3539 "#" 3540 "&& reload_completed" 3541 [(pc)] 3542{ 3543 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2); 3544 DONE; 3545} 3546 [(set_attr "type" "shift") 3547 (set_attr "dot" "yes") 3548 (set_attr "length" "8,12")]) 3549 3550 3551(define_expand "<code><mode>3" 3552 [(set (match_operand:SDI 0 "gpc_reg_operand") 3553 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand") 3554 (match_operand:SDI 2 "reg_or_cint_operand")))] 3555 "" 3556{ 3557 if (<MODE>mode == DImode && !TARGET_POWERPC64) 3558 { 3559 rs6000_split_logical (operands, <CODE>, false, false, false); 3560 DONE; 3561 } 3562 3563 if (non_logical_cint_operand (operands[2], <MODE>mode)) 3564 { 3565 rtx tmp = ((!can_create_pseudo_p () 3566 || rtx_equal_p (operands[0], operands[1])) 3567 ? operands[0] : gen_reg_rtx (<MODE>mode)); 3568 3569 HOST_WIDE_INT value = INTVAL (operands[2]); 3570 HOST_WIDE_INT lo = value & 0xffff; 3571 HOST_WIDE_INT hi = value - lo; 3572 3573 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi))); 3574 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo))); 3575 DONE; 3576 } 3577 3578 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode)) 3579 operands[2] = force_reg (<MODE>mode, operands[2]); 3580}) 3581 3582(define_split 3583 [(set (match_operand:GPR 0 "gpc_reg_operand") 3584 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand") 3585 (match_operand:GPR 2 "non_logical_cint_operand")))] 3586 "" 3587 [(set (match_dup 3) 3588 (iorxor:GPR (match_dup 1) 3589 (match_dup 4))) 3590 (set (match_dup 0) 3591 (iorxor:GPR (match_dup 3) 3592 (match_dup 5)))] 3593{ 3594 operands[3] = ((!can_create_pseudo_p () 3595 || rtx_equal_p (operands[0], operands[1])) 3596 ? operands[0] : gen_reg_rtx (<MODE>mode)); 3597 3598 HOST_WIDE_INT value = INTVAL (operands[2]); 3599 HOST_WIDE_INT lo = value & 0xffff; 3600 HOST_WIDE_INT hi = value - lo; 3601 3602 operands[4] = GEN_INT (hi); 3603 operands[5] = GEN_INT (lo); 3604}) 3605 3606(define_insn "*bool<mode>3_imm" 3607 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3608 (match_operator:GPR 3 "boolean_or_operator" 3609 [(match_operand:GPR 1 "gpc_reg_operand" "%r") 3610 (match_operand:GPR 2 "logical_const_operand" "n")]))] 3611 "" 3612 "%q3i%e2 %0,%1,%u2" 3613 [(set_attr "type" "logical")]) 3614 3615(define_insn "*bool<mode>3" 3616 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3617 (match_operator:GPR 3 "boolean_operator" 3618 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3619 (match_operand:GPR 2 "gpc_reg_operand" "r")]))] 3620 "" 3621 "%q3 %0,%1,%2" 3622 [(set_attr "type" "logical")]) 3623 3624(define_insn_and_split "*bool<mode>3_dot" 3625 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3626 (compare:CC (match_operator:GPR 3 "boolean_operator" 3627 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3628 (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) 3629 (const_int 0))) 3630 (clobber (match_scratch:GPR 0 "=r,r"))] 3631 "<MODE>mode == Pmode" 3632 "@ 3633 %q3. %0,%1,%2 3634 #" 3635 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3636 [(set (match_dup 0) 3637 (match_dup 3)) 3638 (set (match_dup 4) 3639 (compare:CC (match_dup 0) 3640 (const_int 0)))] 3641 "" 3642 [(set_attr "type" "logical") 3643 (set_attr "dot" "yes") 3644 (set_attr "length" "4,8")]) 3645 3646(define_insn_and_split "*bool<mode>3_dot2" 3647 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3648 (compare:CC (match_operator:GPR 3 "boolean_operator" 3649 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3650 (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) 3651 (const_int 0))) 3652 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3653 (match_dup 3))] 3654 "<MODE>mode == Pmode" 3655 "@ 3656 %q3. %0,%1,%2 3657 #" 3658 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3659 [(set (match_dup 0) 3660 (match_dup 3)) 3661 (set (match_dup 4) 3662 (compare:CC (match_dup 0) 3663 (const_int 0)))] 3664 "" 3665 [(set_attr "type" "logical") 3666 (set_attr "dot" "yes") 3667 (set_attr "length" "4,8")]) 3668 3669 3670(define_insn "*boolc<mode>3" 3671 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3672 (match_operator:GPR 3 "boolean_operator" 3673 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")) 3674 (match_operand:GPR 1 "gpc_reg_operand" "r")]))] 3675 "" 3676 "%q3 %0,%1,%2" 3677 [(set_attr "type" "logical")]) 3678 3679(define_insn_and_split "*boolc<mode>3_dot" 3680 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3681 (compare:CC (match_operator:GPR 3 "boolean_operator" 3682 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3683 (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) 3684 (const_int 0))) 3685 (clobber (match_scratch:GPR 0 "=r,r"))] 3686 "<MODE>mode == Pmode" 3687 "@ 3688 %q3. %0,%1,%2 3689 #" 3690 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3691 [(set (match_dup 0) 3692 (match_dup 3)) 3693 (set (match_dup 4) 3694 (compare:CC (match_dup 0) 3695 (const_int 0)))] 3696 "" 3697 [(set_attr "type" "logical") 3698 (set_attr "dot" "yes") 3699 (set_attr "length" "4,8")]) 3700 3701(define_insn_and_split "*boolc<mode>3_dot2" 3702 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3703 (compare:CC (match_operator:GPR 3 "boolean_operator" 3704 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3705 (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) 3706 (const_int 0))) 3707 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3708 (match_dup 3))] 3709 "<MODE>mode == Pmode" 3710 "@ 3711 %q3. %0,%1,%2 3712 #" 3713 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3714 [(set (match_dup 0) 3715 (match_dup 3)) 3716 (set (match_dup 4) 3717 (compare:CC (match_dup 0) 3718 (const_int 0)))] 3719 "" 3720 [(set_attr "type" "logical") 3721 (set_attr "dot" "yes") 3722 (set_attr "length" "4,8")]) 3723 3724 3725(define_insn "*boolcc<mode>3" 3726 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3727 (match_operator:GPR 3 "boolean_operator" 3728 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 3729 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))] 3730 "" 3731 "%q3 %0,%1,%2" 3732 [(set_attr "type" "logical")]) 3733 3734(define_insn_and_split "*boolcc<mode>3_dot" 3735 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3736 (compare:CC (match_operator:GPR 3 "boolean_operator" 3737 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 3738 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) 3739 (const_int 0))) 3740 (clobber (match_scratch:GPR 0 "=r,r"))] 3741 "<MODE>mode == Pmode" 3742 "@ 3743 %q3. %0,%1,%2 3744 #" 3745 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3746 [(set (match_dup 0) 3747 (match_dup 3)) 3748 (set (match_dup 4) 3749 (compare:CC (match_dup 0) 3750 (const_int 0)))] 3751 "" 3752 [(set_attr "type" "logical") 3753 (set_attr "dot" "yes") 3754 (set_attr "length" "4,8")]) 3755 3756(define_insn_and_split "*boolcc<mode>3_dot2" 3757 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3758 (compare:CC (match_operator:GPR 3 "boolean_operator" 3759 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 3760 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) 3761 (const_int 0))) 3762 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3763 (match_dup 3))] 3764 "<MODE>mode == Pmode" 3765 "@ 3766 %q3. %0,%1,%2 3767 #" 3768 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3769 [(set (match_dup 0) 3770 (match_dup 3)) 3771 (set (match_dup 4) 3772 (compare:CC (match_dup 0) 3773 (const_int 0)))] 3774 "" 3775 [(set_attr "type" "logical") 3776 (set_attr "dot" "yes") 3777 (set_attr "length" "4,8")]) 3778 3779 3780;; TODO: Should have dots of this as well. 3781(define_insn "*eqv<mode>3" 3782 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3783 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3784 (match_operand:GPR 2 "gpc_reg_operand" "r"))))] 3785 "" 3786 "eqv %0,%1,%2" 3787 [(set_attr "type" "logical")]) 3788 3789;; Rotate-and-mask and insert. 3790 3791(define_insn "*rotl<mode>3_mask" 3792 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3793 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3794 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3795 (match_operand:SI 2 "reg_or_cint_operand" "rn")]) 3796 (match_operand:GPR 3 "const_int_operand" "n")))] 3797 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3798{ 3799 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false); 3800} 3801 [(set_attr "type" "shift") 3802 (set_attr "maybe_var_shift" "yes")]) 3803 3804(define_insn_and_split "*rotl<mode>3_mask_dot" 3805 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") 3806 (compare:CC 3807 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3808 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3809 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")]) 3810 (match_operand:GPR 3 "const_int_operand" "n,n")) 3811 (const_int 0))) 3812 (clobber (match_scratch:GPR 0 "=r,r"))] 3813 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff) 3814 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3815{ 3816 if (which_alternative == 0) 3817 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true); 3818 else 3819 return "#"; 3820} 3821 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)" 3822 [(set (match_dup 0) 3823 (and:GPR (match_dup 4) 3824 (match_dup 3))) 3825 (set (match_dup 5) 3826 (compare:CC (match_dup 0) 3827 (const_int 0)))] 3828 "" 3829 [(set_attr "type" "shift") 3830 (set_attr "maybe_var_shift" "yes") 3831 (set_attr "dot" "yes") 3832 (set_attr "length" "4,8")]) 3833 3834(define_insn_and_split "*rotl<mode>3_mask_dot2" 3835 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") 3836 (compare:CC 3837 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3838 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3839 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")]) 3840 (match_operand:GPR 3 "const_int_operand" "n,n")) 3841 (const_int 0))) 3842 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3843 (and:GPR (match_dup 4) 3844 (match_dup 3)))] 3845 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff) 3846 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3847{ 3848 if (which_alternative == 0) 3849 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true); 3850 else 3851 return "#"; 3852} 3853 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)" 3854 [(set (match_dup 0) 3855 (and:GPR (match_dup 4) 3856 (match_dup 3))) 3857 (set (match_dup 5) 3858 (compare:CC (match_dup 0) 3859 (const_int 0)))] 3860 "" 3861 [(set_attr "type" "shift") 3862 (set_attr "maybe_var_shift" "yes") 3863 (set_attr "dot" "yes") 3864 (set_attr "length" "4,8")]) 3865 3866; Special case for less-than-0. We can do it with just one machine 3867; instruction, but the generic optimizers do not realise it is cheap. 3868(define_insn "*lt0_<mode>di" 3869 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3870 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r") 3871 (const_int 0)))] 3872 "TARGET_POWERPC64" 3873 "srdi %0,%1,63" 3874 [(set_attr "type" "shift")]) 3875 3876(define_insn "*lt0_<mode>si" 3877 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3878 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r") 3879 (const_int 0)))] 3880 "" 3881 "rlwinm %0,%1,1,31,31" 3882 [(set_attr "type" "shift")]) 3883 3884 3885 3886; Two forms for insert (the two arms of the IOR are not canonicalized, 3887; both are an AND so are the same precedence). 3888(define_insn "*rotl<mode>3_insert" 3889 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3890 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3891 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3892 (match_operand:SI 2 "const_int_operand" "n")]) 3893 (match_operand:GPR 3 "const_int_operand" "n")) 3894 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0") 3895 (match_operand:GPR 6 "const_int_operand" "n"))))] 3896 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode) 3897 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0" 3898{ 3899 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false); 3900} 3901 [(set_attr "type" "insert")]) 3902; FIXME: this needs an attr "size", so that the scheduler can see the 3903; difference between rlwimi and rldimi. We also might want dot forms, 3904; but not for rlwimi on POWER4 and similar processors. 3905 3906(define_insn "*rotl<mode>3_insert_2" 3907 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3908 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0") 3909 (match_operand:GPR 6 "const_int_operand" "n")) 3910 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3911 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3912 (match_operand:SI 2 "const_int_operand" "n")]) 3913 (match_operand:GPR 3 "const_int_operand" "n"))))] 3914 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode) 3915 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0" 3916{ 3917 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false); 3918} 3919 [(set_attr "type" "insert")]) 3920 3921; There are also some forms without one of the ANDs. 3922(define_insn "*rotl<mode>3_insert_3" 3923 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3924 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 3925 (match_operand:GPR 4 "const_int_operand" "n")) 3926 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3927 (match_operand:SI 2 "const_int_operand" "n"))))] 3928 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)" 3929{ 3930 if (<MODE>mode == SImode) 3931 return "rlwimi %0,%1,%h2,0,31-%h2"; 3932 else 3933 return "rldimi %0,%1,%H2,0"; 3934} 3935 [(set_attr "type" "insert")]) 3936 3937(define_insn "*rotl<mode>3_insert_4" 3938 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3939 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 3940 (match_operand:GPR 4 "const_int_operand" "n")) 3941 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3942 (match_operand:SI 2 "const_int_operand" "n"))))] 3943 "<MODE>mode == SImode && 3944 GET_MODE_PRECISION (<MODE>mode) 3945 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))" 3946{ 3947 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode) 3948 - INTVAL (operands[2])); 3949 if (<MODE>mode == SImode) 3950 return "rlwimi %0,%1,%h2,32-%h2,31"; 3951 else 3952 return "rldimi %0,%1,%H2,64-%H2"; 3953} 3954 [(set_attr "type" "insert")]) 3955 3956(define_insn "*rotlsi3_insert_5" 3957 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 3958 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r") 3959 (match_operand:SI 2 "const_int_operand" "n,n")) 3960 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0") 3961 (match_operand:SI 4 "const_int_operand" "n,n"))))] 3962 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode) 3963 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0 3964 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 3965 "@ 3966 rlwimi %0,%3,0,%4 3967 rlwimi %0,%1,0,%2" 3968 [(set_attr "type" "insert")]) 3969 3970(define_insn "*rotldi3_insert_6" 3971 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3972 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0") 3973 (match_operand:DI 2 "const_int_operand" "n")) 3974 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r") 3975 (match_operand:DI 4 "const_int_operand" "n"))))] 3976 "exact_log2 (-UINTVAL (operands[2])) > 0 3977 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 3978{ 3979 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2]))); 3980 return "rldimi %0,%3,0,%5"; 3981} 3982 [(set_attr "type" "insert") 3983 (set_attr "size" "64")]) 3984 3985(define_insn "*rotldi3_insert_7" 3986 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3987 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r") 3988 (match_operand:DI 4 "const_int_operand" "n")) 3989 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0") 3990 (match_operand:DI 2 "const_int_operand" "n"))))] 3991 "exact_log2 (-UINTVAL (operands[2])) > 0 3992 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 3993{ 3994 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2]))); 3995 return "rldimi %0,%3,0,%5"; 3996} 3997 [(set_attr "type" "insert") 3998 (set_attr "size" "64")]) 3999 4000 4001; This handles the important case of multiple-precision shifts. There is 4002; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns. 4003(define_split 4004 [(set (match_operand:GPR 0 "gpc_reg_operand") 4005 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 4006 (match_operand:SI 3 "const_int_operand")) 4007 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand") 4008 (match_operand:SI 4 "const_int_operand"))))] 4009 "can_create_pseudo_p () 4010 && INTVAL (operands[3]) + INTVAL (operands[4]) 4011 >= GET_MODE_PRECISION (<MODE>mode)" 4012 [(set (match_dup 5) 4013 (lshiftrt:GPR (match_dup 2) 4014 (match_dup 4))) 4015 (set (match_dup 0) 4016 (ior:GPR (and:GPR (match_dup 5) 4017 (match_dup 6)) 4018 (ashift:GPR (match_dup 1) 4019 (match_dup 3))))] 4020{ 4021 unsigned HOST_WIDE_INT mask = 1; 4022 mask = (mask << INTVAL (operands[3])) - 1; 4023 operands[5] = gen_reg_rtx (<MODE>mode); 4024 operands[6] = GEN_INT (mask); 4025}) 4026 4027(define_split 4028 [(set (match_operand:GPR 0 "gpc_reg_operand") 4029 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand") 4030 (match_operand:SI 4 "const_int_operand")) 4031 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 4032 (match_operand:SI 3 "const_int_operand"))))] 4033 "can_create_pseudo_p () 4034 && INTVAL (operands[3]) + INTVAL (operands[4]) 4035 >= GET_MODE_PRECISION (<MODE>mode)" 4036 [(set (match_dup 5) 4037 (lshiftrt:GPR (match_dup 2) 4038 (match_dup 4))) 4039 (set (match_dup 0) 4040 (ior:GPR (and:GPR (match_dup 5) 4041 (match_dup 6)) 4042 (ashift:GPR (match_dup 1) 4043 (match_dup 3))))] 4044{ 4045 unsigned HOST_WIDE_INT mask = 1; 4046 mask = (mask << INTVAL (operands[3])) - 1; 4047 operands[5] = gen_reg_rtx (<MODE>mode); 4048 operands[6] = GEN_INT (mask); 4049}) 4050 4051 4052; Another important case is setting some bits to 1; we can do that with 4053; an insert instruction, in many cases. 4054(define_insn_and_split "*ior<mode>_mask" 4055 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4056 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0") 4057 (match_operand:GPR 2 "const_int_operand" "n"))) 4058 (clobber (match_scratch:GPR 3 "=r"))] 4059 "!logical_const_operand (operands[2], <MODE>mode) 4060 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)" 4061 "#" 4062 "&& 1" 4063 [(set (match_dup 3) 4064 (const_int -1)) 4065 (set (match_dup 0) 4066 (ior:GPR (and:GPR (rotate:GPR (match_dup 3) 4067 (match_dup 4)) 4068 (match_dup 2)) 4069 (and:GPR (match_dup 1) 4070 (match_dup 5))))] 4071{ 4072 int nb, ne; 4073 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode); 4074 if (GET_CODE (operands[3]) == SCRATCH) 4075 operands[3] = gen_reg_rtx (<MODE>mode); 4076 operands[4] = GEN_INT (ne); 4077 operands[5] = GEN_INT (~UINTVAL (operands[2])); 4078} 4079 [(set_attr "type" "two") 4080 (set_attr "length" "8")]) 4081 4082 4083;; Now the simple shifts. 4084 4085(define_insn "rotl<mode>3" 4086 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4087 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4088 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4089 "" 4090 "rotl<wd>%I2 %0,%1,%<hH>2" 4091 [(set_attr "type" "shift") 4092 (set_attr "maybe_var_shift" "yes")]) 4093 4094(define_insn "*rotlsi3_64" 4095 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4096 (zero_extend:DI 4097 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4098 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4099 "TARGET_POWERPC64" 4100 "rotlw%I2 %0,%1,%h2" 4101 [(set_attr "type" "shift") 4102 (set_attr "maybe_var_shift" "yes")]) 4103 4104(define_insn_and_split "*rotl<mode>3_dot" 4105 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4106 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4107 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4108 (const_int 0))) 4109 (clobber (match_scratch:GPR 0 "=r,r"))] 4110 "<MODE>mode == Pmode" 4111 "@ 4112 rotl<wd>%I2. %0,%1,%<hH>2 4113 #" 4114 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4115 [(set (match_dup 0) 4116 (rotate:GPR (match_dup 1) 4117 (match_dup 2))) 4118 (set (match_dup 3) 4119 (compare:CC (match_dup 0) 4120 (const_int 0)))] 4121 "" 4122 [(set_attr "type" "shift") 4123 (set_attr "maybe_var_shift" "yes") 4124 (set_attr "dot" "yes") 4125 (set_attr "length" "4,8")]) 4126 4127(define_insn_and_split "*rotl<mode>3_dot2" 4128 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4129 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4130 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4131 (const_int 0))) 4132 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4133 (rotate:GPR (match_dup 1) 4134 (match_dup 2)))] 4135 "<MODE>mode == Pmode" 4136 "@ 4137 rotl<wd>%I2. %0,%1,%<hH>2 4138 #" 4139 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4140 [(set (match_dup 0) 4141 (rotate:GPR (match_dup 1) 4142 (match_dup 2))) 4143 (set (match_dup 3) 4144 (compare:CC (match_dup 0) 4145 (const_int 0)))] 4146 "" 4147 [(set_attr "type" "shift") 4148 (set_attr "maybe_var_shift" "yes") 4149 (set_attr "dot" "yes") 4150 (set_attr "length" "4,8")]) 4151 4152 4153(define_insn "ashl<mode>3" 4154 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4155 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4156 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4157 "" 4158 "sl<wd>%I2 %0,%1,%<hH>2" 4159 [(set_attr "type" "shift") 4160 (set_attr "maybe_var_shift" "yes")]) 4161 4162(define_insn "*ashlsi3_64" 4163 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4164 (zero_extend:DI 4165 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4166 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4167 "TARGET_POWERPC64" 4168 "slw%I2 %0,%1,%h2" 4169 [(set_attr "type" "shift") 4170 (set_attr "maybe_var_shift" "yes")]) 4171 4172(define_insn_and_split "*ashl<mode>3_dot" 4173 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4174 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4175 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4176 (const_int 0))) 4177 (clobber (match_scratch:GPR 0 "=r,r"))] 4178 "<MODE>mode == Pmode" 4179 "@ 4180 sl<wd>%I2. %0,%1,%<hH>2 4181 #" 4182 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4183 [(set (match_dup 0) 4184 (ashift:GPR (match_dup 1) 4185 (match_dup 2))) 4186 (set (match_dup 3) 4187 (compare:CC (match_dup 0) 4188 (const_int 0)))] 4189 "" 4190 [(set_attr "type" "shift") 4191 (set_attr "maybe_var_shift" "yes") 4192 (set_attr "dot" "yes") 4193 (set_attr "length" "4,8")]) 4194 4195(define_insn_and_split "*ashl<mode>3_dot2" 4196 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4197 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4198 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4199 (const_int 0))) 4200 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4201 (ashift:GPR (match_dup 1) 4202 (match_dup 2)))] 4203 "<MODE>mode == Pmode" 4204 "@ 4205 sl<wd>%I2. %0,%1,%<hH>2 4206 #" 4207 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4208 [(set (match_dup 0) 4209 (ashift:GPR (match_dup 1) 4210 (match_dup 2))) 4211 (set (match_dup 3) 4212 (compare:CC (match_dup 0) 4213 (const_int 0)))] 4214 "" 4215 [(set_attr "type" "shift") 4216 (set_attr "maybe_var_shift" "yes") 4217 (set_attr "dot" "yes") 4218 (set_attr "length" "4,8")]) 4219 4220;; Pretend we have a memory form of extswsli until register allocation is done 4221;; so that we use LWZ to load the value from memory, instead of LWA. 4222(define_insn_and_split "ashdi3_extswsli" 4223 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 4224 (ashift:DI 4225 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m")) 4226 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))] 4227 "TARGET_EXTSWSLI" 4228 "@ 4229 extswsli %0,%1,%2 4230 #" 4231 "&& reload_completed && MEM_P (operands[1])" 4232 [(set (match_dup 3) 4233 (match_dup 1)) 4234 (set (match_dup 0) 4235 (ashift:DI (sign_extend:DI (match_dup 3)) 4236 (match_dup 2)))] 4237{ 4238 operands[3] = gen_lowpart (SImode, operands[0]); 4239} 4240 [(set_attr "type" "shift") 4241 (set_attr "maybe_var_shift" "no")]) 4242 4243 4244(define_insn_and_split "ashdi3_extswsli_dot" 4245 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y") 4246 (compare:CC 4247 (ashift:DI 4248 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m")) 4249 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n")) 4250 (const_int 0))) 4251 (clobber (match_scratch:DI 0 "=r,r,r,r"))] 4252 "TARGET_EXTSWSLI" 4253 "@ 4254 extswsli. %0,%1,%2 4255 # 4256 # 4257 #" 4258 "&& reload_completed 4259 && (cc_reg_not_cr0_operand (operands[3], CCmode) 4260 || memory_operand (operands[1], SImode))" 4261 [(pc)] 4262{ 4263 rtx dest = operands[0]; 4264 rtx src = operands[1]; 4265 rtx shift = operands[2]; 4266 rtx cr = operands[3]; 4267 rtx src2; 4268 4269 if (!MEM_P (src)) 4270 src2 = src; 4271 else 4272 { 4273 src2 = gen_lowpart (SImode, dest); 4274 emit_move_insn (src2, src); 4275 } 4276 4277 if (REGNO (cr) == CR0_REGNO) 4278 { 4279 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr)); 4280 DONE; 4281 } 4282 4283 emit_insn (gen_ashdi3_extswsli (dest, src2, shift)); 4284 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx))); 4285 DONE; 4286} 4287 [(set_attr "type" "shift") 4288 (set_attr "maybe_var_shift" "no") 4289 (set_attr "dot" "yes") 4290 (set_attr "length" "4,8,8,12")]) 4291 4292(define_insn_and_split "ashdi3_extswsli_dot2" 4293 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y") 4294 (compare:CC 4295 (ashift:DI 4296 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m")) 4297 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n")) 4298 (const_int 0))) 4299 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") 4300 (ashift:DI (sign_extend:DI (match_dup 1)) 4301 (match_dup 2)))] 4302 "TARGET_EXTSWSLI" 4303 "@ 4304 extswsli. %0,%1,%2 4305 # 4306 # 4307 #" 4308 "&& reload_completed 4309 && (cc_reg_not_cr0_operand (operands[3], CCmode) 4310 || memory_operand (operands[1], SImode))" 4311 [(pc)] 4312{ 4313 rtx dest = operands[0]; 4314 rtx src = operands[1]; 4315 rtx shift = operands[2]; 4316 rtx cr = operands[3]; 4317 rtx src2; 4318 4319 if (!MEM_P (src)) 4320 src2 = src; 4321 else 4322 { 4323 src2 = gen_lowpart (SImode, dest); 4324 emit_move_insn (src2, src); 4325 } 4326 4327 if (REGNO (cr) == CR0_REGNO) 4328 { 4329 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr)); 4330 DONE; 4331 } 4332 4333 emit_insn (gen_ashdi3_extswsli (dest, src2, shift)); 4334 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx))); 4335 DONE; 4336} 4337 [(set_attr "type" "shift") 4338 (set_attr "maybe_var_shift" "no") 4339 (set_attr "dot" "yes") 4340 (set_attr "length" "4,8,8,12")]) 4341 4342(define_insn "lshr<mode>3" 4343 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4344 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4345 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4346 "" 4347 "sr<wd>%I2 %0,%1,%<hH>2" 4348 [(set_attr "type" "shift") 4349 (set_attr "maybe_var_shift" "yes")]) 4350 4351(define_insn "*lshrsi3_64" 4352 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4353 (zero_extend:DI 4354 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4355 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4356 "TARGET_POWERPC64" 4357 "srw%I2 %0,%1,%h2" 4358 [(set_attr "type" "shift") 4359 (set_attr "maybe_var_shift" "yes")]) 4360 4361(define_insn_and_split "*lshr<mode>3_dot" 4362 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4363 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4364 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4365 (const_int 0))) 4366 (clobber (match_scratch:GPR 0 "=r,r"))] 4367 "<MODE>mode == Pmode" 4368 "@ 4369 sr<wd>%I2. %0,%1,%<hH>2 4370 #" 4371 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4372 [(set (match_dup 0) 4373 (lshiftrt:GPR (match_dup 1) 4374 (match_dup 2))) 4375 (set (match_dup 3) 4376 (compare:CC (match_dup 0) 4377 (const_int 0)))] 4378 "" 4379 [(set_attr "type" "shift") 4380 (set_attr "maybe_var_shift" "yes") 4381 (set_attr "dot" "yes") 4382 (set_attr "length" "4,8")]) 4383 4384(define_insn_and_split "*lshr<mode>3_dot2" 4385 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4386 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4387 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4388 (const_int 0))) 4389 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4390 (lshiftrt:GPR (match_dup 1) 4391 (match_dup 2)))] 4392 "<MODE>mode == Pmode" 4393 "@ 4394 sr<wd>%I2. %0,%1,%<hH>2 4395 #" 4396 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4397 [(set (match_dup 0) 4398 (lshiftrt:GPR (match_dup 1) 4399 (match_dup 2))) 4400 (set (match_dup 3) 4401 (compare:CC (match_dup 0) 4402 (const_int 0)))] 4403 "" 4404 [(set_attr "type" "shift") 4405 (set_attr "maybe_var_shift" "yes") 4406 (set_attr "dot" "yes") 4407 (set_attr "length" "4,8")]) 4408 4409 4410(define_insn "ashr<mode>3" 4411 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4412 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4413 (match_operand:SI 2 "reg_or_cint_operand" "rn"))) 4414 (clobber (reg:GPR CA_REGNO))] 4415 "" 4416 "sra<wd>%I2 %0,%1,%<hH>2" 4417 [(set_attr "type" "shift") 4418 (set_attr "maybe_var_shift" "yes")]) 4419 4420(define_insn "*ashrsi3_64" 4421 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4422 (sign_extend:DI 4423 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4424 (match_operand:SI 2 "reg_or_cint_operand" "rn")))) 4425 (clobber (reg:SI CA_REGNO))] 4426 "TARGET_POWERPC64" 4427 "sraw%I2 %0,%1,%h2" 4428 [(set_attr "type" "shift") 4429 (set_attr "maybe_var_shift" "yes")]) 4430 4431(define_insn_and_split "*ashr<mode>3_dot" 4432 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4433 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4434 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4435 (const_int 0))) 4436 (clobber (match_scratch:GPR 0 "=r,r")) 4437 (clobber (reg:GPR CA_REGNO))] 4438 "<MODE>mode == Pmode" 4439 "@ 4440 sra<wd>%I2. %0,%1,%<hH>2 4441 #" 4442 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4443 [(parallel [(set (match_dup 0) 4444 (ashiftrt:GPR (match_dup 1) 4445 (match_dup 2))) 4446 (clobber (reg:GPR CA_REGNO))]) 4447 (set (match_dup 3) 4448 (compare:CC (match_dup 0) 4449 (const_int 0)))] 4450 "" 4451 [(set_attr "type" "shift") 4452 (set_attr "maybe_var_shift" "yes") 4453 (set_attr "dot" "yes") 4454 (set_attr "length" "4,8")]) 4455 4456(define_insn_and_split "*ashr<mode>3_dot2" 4457 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4458 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4459 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4460 (const_int 0))) 4461 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4462 (ashiftrt:GPR (match_dup 1) 4463 (match_dup 2))) 4464 (clobber (reg:GPR CA_REGNO))] 4465 "<MODE>mode == Pmode" 4466 "@ 4467 sra<wd>%I2. %0,%1,%<hH>2 4468 #" 4469 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4470 [(parallel [(set (match_dup 0) 4471 (ashiftrt:GPR (match_dup 1) 4472 (match_dup 2))) 4473 (clobber (reg:GPR CA_REGNO))]) 4474 (set (match_dup 3) 4475 (compare:CC (match_dup 0) 4476 (const_int 0)))] 4477 "" 4478 [(set_attr "type" "shift") 4479 (set_attr "maybe_var_shift" "yes") 4480 (set_attr "dot" "yes") 4481 (set_attr "length" "4,8")]) 4482 4483;; Builtins to replace a division to generate FRE reciprocal estimate 4484;; instructions and the necessary fixup instructions 4485(define_expand "recip<mode>3" 4486 [(match_operand:RECIPF 0 "gpc_reg_operand") 4487 (match_operand:RECIPF 1 "gpc_reg_operand") 4488 (match_operand:RECIPF 2 "gpc_reg_operand")] 4489 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)" 4490{ 4491 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false); 4492 DONE; 4493}) 4494 4495;; Split to create division from FRE/FRES/etc. and fixup instead of the normal 4496;; hardware division. This is only done before register allocation and with 4497;; -ffast-math. This must appear before the divsf3/divdf3 insns. 4498;; We used to also check optimize_insn_for_speed_p () but problems with guessed 4499;; frequencies (pr68212/pr77536) yields that unreliable so it was removed. 4500(define_split 4501 [(set (match_operand:RECIPF 0 "gpc_reg_operand") 4502 (div:RECIPF (match_operand 1 "gpc_reg_operand") 4503 (match_operand 2 "gpc_reg_operand")))] 4504 "RS6000_RECIP_AUTO_RE_P (<MODE>mode) 4505 && can_create_pseudo_p () && flag_finite_math_only 4506 && !flag_trapping_math && flag_reciprocal_math" 4507 [(const_int 0)] 4508{ 4509 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); 4510 DONE; 4511}) 4512 4513;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the 4514;; appropriate fixup. 4515(define_expand "rsqrt<mode>2" 4516 [(match_operand:RECIPF 0 "gpc_reg_operand") 4517 (match_operand:RECIPF 1 "gpc_reg_operand")] 4518 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 4519{ 4520 rs6000_emit_swsqrt (operands[0], operands[1], 1); 4521 DONE; 4522}) 4523 4524;; Floating-point insns, excluding normal data motion. We combine the SF/DF 4525;; modes here, and also add in conditional vsx/power8-vector support to access 4526;; values in the traditional Altivec registers if the appropriate 4527;; -mupper-regs-{df,sf} option is enabled. 4528 4529(define_expand "abs<mode>2" 4530 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4531 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] 4532 "TARGET_<MODE>_INSN" 4533 "") 4534 4535(define_insn "*abs<mode>2_fpr" 4536 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4537 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 4538 "TARGET_<MODE>_FPR" 4539 "@ 4540 fabs %0,%1 4541 xsabsdp %x0,%x1" 4542 [(set_attr "type" "fpsimple") 4543 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4544 4545(define_insn "*nabs<mode>2_fpr" 4546 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4547 (neg:SFDF 4548 (abs:SFDF 4549 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))] 4550 "TARGET_<MODE>_FPR" 4551 "@ 4552 fnabs %0,%1 4553 xsnabsdp %x0,%x1" 4554 [(set_attr "type" "fpsimple") 4555 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4556 4557(define_expand "neg<mode>2" 4558 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4559 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] 4560 "TARGET_<MODE>_INSN" 4561 "") 4562 4563(define_insn "*neg<mode>2_fpr" 4564 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4565 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 4566 "TARGET_<MODE>_FPR" 4567 "@ 4568 fneg %0,%1 4569 xsnegdp %x0,%x1" 4570 [(set_attr "type" "fpsimple") 4571 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4572 4573(define_expand "add<mode>3" 4574 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4575 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4576 (match_operand:SFDF 2 "gpc_reg_operand")))] 4577 "TARGET_<MODE>_INSN" 4578 "") 4579 4580(define_insn "*add<mode>3_fpr" 4581 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4582 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") 4583 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4584 "TARGET_<MODE>_FPR" 4585 "@ 4586 fadd<Ftrad> %0,%1,%2 4587 xsadd<Fvsx> %x0,%x1,%x2" 4588 [(set_attr "type" "fp") 4589 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4590 4591(define_expand "sub<mode>3" 4592 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4593 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4594 (match_operand:SFDF 2 "gpc_reg_operand")))] 4595 "TARGET_<MODE>_INSN" 4596 "") 4597 4598(define_insn "*sub<mode>3_fpr" 4599 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4600 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") 4601 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4602 "TARGET_<MODE>_FPR" 4603 "@ 4604 fsub<Ftrad> %0,%1,%2 4605 xssub<Fvsx> %x0,%x1,%x2" 4606 [(set_attr "type" "fp") 4607 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4608 4609(define_expand "mul<mode>3" 4610 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4611 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4612 (match_operand:SFDF 2 "gpc_reg_operand")))] 4613 "TARGET_<MODE>_INSN" 4614 "") 4615 4616(define_insn "*mul<mode>3_fpr" 4617 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4618 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") 4619 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4620 "TARGET_<MODE>_FPR" 4621 "@ 4622 fmul<Ftrad> %0,%1,%2 4623 xsmul<Fvsx> %x0,%x1,%x2" 4624 [(set_attr "type" "dmul") 4625 (set_attr "fp_type" "fp_mul_<Fs>")]) 4626 4627(define_expand "div<mode>3" 4628 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4629 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4630 (match_operand:SFDF 2 "gpc_reg_operand")))] 4631 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU" 4632{ 4633 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode) 4634 && can_create_pseudo_p () && flag_finite_math_only 4635 && !flag_trapping_math && flag_reciprocal_math) 4636 { 4637 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); 4638 DONE; 4639 } 4640}) 4641 4642(define_insn "*div<mode>3_fpr" 4643 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4644 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") 4645 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4646 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU" 4647 "@ 4648 fdiv<Ftrad> %0,%1,%2 4649 xsdiv<Fvsx> %x0,%x1,%x2" 4650 [(set_attr "type" "<Fs>div") 4651 (set_attr "fp_type" "fp_div_<Fs>")]) 4652 4653(define_insn "*sqrt<mode>2_internal" 4654 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4655 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4656 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU 4657 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))" 4658 "@ 4659 fsqrt<Ftrad> %0,%1 4660 xssqrt<Fvsx> %x0,%x1" 4661 [(set_attr "type" "<Fs>sqrt") 4662 (set_attr "fp_type" "fp_sqrt_<Fs>")]) 4663 4664(define_expand "sqrt<mode>2" 4665 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4666 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] 4667 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU 4668 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))" 4669{ 4670 if (<MODE>mode == SFmode 4671 && TARGET_RECIP_PRECISION 4672 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode) 4673 && !optimize_function_for_size_p (cfun) 4674 && flag_finite_math_only && !flag_trapping_math 4675 && flag_unsafe_math_optimizations) 4676 { 4677 rs6000_emit_swsqrt (operands[0], operands[1], 0); 4678 DONE; 4679 } 4680}) 4681 4682;; Floating point reciprocal approximation 4683(define_insn "fre<Fs>" 4684 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4685 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")] 4686 UNSPEC_FRES))] 4687 "TARGET_<FFRE>" 4688 "@ 4689 fre<Ftrad> %0,%1 4690 xsre<Fvsx> %x0,%x1" 4691 [(set_attr "type" "fp")]) 4692 4693(define_insn "*rsqrt<mode>2" 4694 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4695 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")] 4696 UNSPEC_RSQRT))] 4697 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 4698 "@ 4699 frsqrte<Ftrad> %0,%1 4700 xsrsqrte<Fvsx> %x0,%x1" 4701 [(set_attr "type" "fp")]) 4702 4703;; Floating point comparisons 4704(define_insn "*cmp<mode>_fpr" 4705 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y") 4706 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") 4707 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4708 "TARGET_<MODE>_FPR" 4709 "@ 4710 fcmpu %0,%1,%2 4711 xscmpudp %0,%x1,%x2" 4712 [(set_attr "type" "fpcompare")]) 4713 4714;; Floating point conversions 4715(define_expand "extendsfdf2" 4716 [(set (match_operand:DF 0 "gpc_reg_operand") 4717 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))] 4718 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 4719{ 4720 if (HONOR_SNANS (SFmode)) 4721 operands[1] = force_reg (SFmode, operands[1]); 4722}) 4723 4724(define_insn_and_split "*extendsfdf2_fpr" 4725 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb") 4726 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))] 4727 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)" 4728 "@ 4729 # 4730 fmr %0,%1 4731 lfs%U1%X1 %0,%1 4732 # 4733 xscpsgndp %x0,%x1,%x1 4734 lxsspx %x0,%y1 4735 lxssp %0,%1" 4736 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])" 4737 [(const_int 0)] 4738{ 4739 emit_note (NOTE_INSN_DELETED); 4740 DONE; 4741} 4742 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")]) 4743 4744(define_insn "*extendsfdf2_snan" 4745 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 4746 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))] 4747 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)" 4748 "@ 4749 frsp %0,%1 4750 xsrsp %x0,%x1" 4751 [(set_attr "type" "fp")]) 4752 4753(define_expand "truncdfsf2" 4754 [(set (match_operand:SF 0 "gpc_reg_operand") 4755 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))] 4756 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 4757 "") 4758 4759(define_insn "*truncdfsf2_fpr" 4760 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy") 4761 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))] 4762 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 4763 "@ 4764 frsp %0,%1 4765 xsrsp %x0,%x1" 4766 [(set_attr "type" "fp")]) 4767 4768;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in 4769;; builtins.c and optabs.c that are not correct for IBM long double 4770;; when little-endian. 4771(define_expand "signbit<mode>2" 4772 [(set (match_dup 2) 4773 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand"))) 4774 (set (match_dup 3) 4775 (subreg:DI (match_dup 2) 0)) 4776 (set (match_dup 4) 4777 (match_dup 5)) 4778 (set (match_operand:SI 0 "gpc_reg_operand") 4779 (match_dup 6))] 4780 "TARGET_HARD_FLOAT 4781 && (!FLOAT128_IEEE_P (<MODE>mode) 4782 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))" 4783{ 4784 if (FLOAT128_IEEE_P (<MODE>mode)) 4785 { 4786 rtx dest = operands[0]; 4787 rtx src = operands[1]; 4788 rtx tmp = gen_reg_rtx (DImode); 4789 rtx dest_di = gen_lowpart (DImode, dest); 4790 4791 if (<MODE>mode == KFmode) 4792 emit_insn (gen_signbitkf2_dm (tmp, src)); 4793 else if (<MODE>mode == TFmode) 4794 emit_insn (gen_signbittf2_dm (tmp, src)); 4795 else 4796 gcc_unreachable (); 4797 4798 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63))); 4799 DONE; 4800 } 4801 operands[2] = gen_reg_rtx (DFmode); 4802 operands[3] = gen_reg_rtx (DImode); 4803 if (TARGET_POWERPC64) 4804 { 4805 operands[4] = gen_reg_rtx (DImode); 4806 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63)); 4807 operands[6] = gen_rtx_SUBREG (SImode, operands[4], 4808 WORDS_BIG_ENDIAN ? 4 : 0); 4809 } 4810 else 4811 { 4812 operands[4] = gen_reg_rtx (SImode); 4813 operands[5] = gen_rtx_SUBREG (SImode, operands[3], 4814 WORDS_BIG_ENDIAN ? 0 : 4); 4815 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31)); 4816 } 4817}) 4818 4819;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid 4820;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the 4821;; register allocator would typically move the entire _Float128 item to GPRs (2 4822;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07). 4823;; 4824;; After register allocation, if the _Float128 had originally been in GPRs, the 4825;; split allows the post reload phases to eliminate the move, and do the shift 4826;; directly with the register that contains the signbit. 4827(define_insn_and_split "signbit<mode>2_dm" 4828 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 4829 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")] 4830 UNSPEC_SIGNBIT))] 4831 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 4832 "@ 4833 mfvsrd %0,%x1 4834 #" 4835 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)" 4836 [(set (match_dup 0) 4837 (match_dup 2))] 4838{ 4839 operands[2] = gen_highpart (DImode, operands[1]); 4840} 4841 [(set_attr "type" "mftgpr,*")]) 4842 4843;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector 4844;; register and then doing a direct move if the value comes from memory. On 4845;; little endian, we have to load the 2nd double-word to get the sign bit. 4846(define_insn_and_split "*signbit<mode>2_dm_mem" 4847 [(set (match_operand:DI 0 "gpc_reg_operand" "=b") 4848 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")] 4849 UNSPEC_SIGNBIT))] 4850 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 4851 "#" 4852 "&& 1" 4853 [(set (match_dup 0) 4854 (match_dup 2))] 4855{ 4856 rtx dest = operands[0]; 4857 rtx src = operands[1]; 4858 rtx addr = XEXP (src, 0); 4859 4860 if (WORDS_BIG_ENDIAN) 4861 operands[2] = adjust_address (src, DImode, 0); 4862 4863 else if (REG_P (addr) || SUBREG_P (addr)) 4864 operands[2] = adjust_address (src, DImode, 8); 4865 4866 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0)) 4867 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode)) 4868 operands[2] = adjust_address (src, DImode, 8); 4869 4870 else 4871 { 4872 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest; 4873 emit_insn (gen_rtx_SET (tmp, addr)); 4874 operands[2] = change_address (src, DImode, 4875 gen_rtx_PLUS (DImode, tmp, GEN_INT (8))); 4876 } 4877}) 4878 4879(define_expand "copysign<mode>3" 4880 [(set (match_dup 3) 4881 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand"))) 4882 (set (match_dup 4) 4883 (neg:SFDF (abs:SFDF (match_dup 1)))) 4884 (set (match_operand:SFDF 0 "gpc_reg_operand") 4885 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand") 4886 (match_dup 5)) 4887 (match_dup 3) 4888 (match_dup 4)))] 4889 "TARGET_HARD_FLOAT && <TARGET_FLOAT> 4890 && ((TARGET_PPC_GFXOPT 4891 && !HONOR_NANS (<MODE>mode) 4892 && !HONOR_SIGNED_ZEROS (<MODE>mode)) 4893 || TARGET_CMPB 4894 || VECTOR_UNIT_VSX_P (<MODE>mode))" 4895{ 4896 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode)) 4897 { 4898 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1], 4899 operands[2])); 4900 DONE; 4901 } 4902 4903 operands[3] = gen_reg_rtx (<MODE>mode); 4904 operands[4] = gen_reg_rtx (<MODE>mode); 4905 operands[5] = CONST0_RTX (<MODE>mode); 4906 }) 4907 4908;; Use an unspec rather providing an if-then-else in RTL, to prevent the 4909;; compiler from optimizing -0.0 4910(define_insn "copysign<mode>3_fcpsgn" 4911 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4912 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") 4913 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")] 4914 UNSPEC_COPYSIGN))] 4915 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))" 4916 "@ 4917 fcpsgn %0,%2,%1 4918 xscpsgndp %x0,%x2,%x1" 4919 [(set_attr "type" "fpsimple")]) 4920 4921;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a 4922;; fsel instruction and some auxiliary computations. Then we just have a 4923;; single DEFINE_INSN for fsel and the define_splits to make them if made by 4924;; combine. 4925;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we 4926;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary 4927;; computations. Then we just have a single DEFINE_INSN for fsel and the 4928;; define_splits to make them if made by combine. On VSX machines we have the 4929;; min/max instructions. 4930;; 4931;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector 4932;; to allow either DF/SF to use only traditional registers. 4933 4934(define_expand "s<minmax><mode>3" 4935 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4936 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4937 (match_operand:SFDF 2 "gpc_reg_operand")))] 4938 "TARGET_MINMAX_<MODE>" 4939{ 4940 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 4941 DONE; 4942}) 4943 4944(define_insn "*s<minmax><mode>3_vsx" 4945 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 4946 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>") 4947 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))] 4948 "TARGET_VSX && TARGET_<MODE>_FPR" 4949{ 4950 return (TARGET_P9_MINMAX 4951 ? "xs<minmax>cdp %x0,%x1,%x2" 4952 : "xs<minmax>dp %x0,%x1,%x2"); 4953} 4954 [(set_attr "type" "fp")]) 4955 4956;; The conditional move instructions allow us to perform max and min operations 4957;; even when we don't have the appropriate max/min instruction using the FSEL 4958;; instruction. 4959 4960(define_insn_and_split "*s<minmax><mode>3_fpr" 4961 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4962 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4963 (match_operand:SFDF 2 "gpc_reg_operand")))] 4964 "!TARGET_VSX && TARGET_MINMAX_<MODE>" 4965 "#" 4966 "&& 1" 4967 [(const_int 0)] 4968{ 4969 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 4970 DONE; 4971}) 4972 4973(define_expand "mov<mode>cc" 4974 [(set (match_operand:GPR 0 "gpc_reg_operand") 4975 (if_then_else:GPR (match_operand 1 "comparison_operator") 4976 (match_operand:GPR 2 "gpc_reg_operand") 4977 (match_operand:GPR 3 "gpc_reg_operand")))] 4978 "TARGET_ISEL" 4979{ 4980 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 4981 DONE; 4982 else 4983 FAIL; 4984}) 4985 4986;; We use the BASE_REGS for the isel input operands because, if rA is 4987;; 0, the value of 0 is placed in rD upon truth. Similarly for rB 4988;; because we may switch the operands and rB may end up being rA. 4989;; 4990;; We need 2 patterns: an unsigned and a signed pattern. We could 4991;; leave out the mode in operand 4 and use one pattern, but reload can 4992;; change the mode underneath our feet and then gets confused trying 4993;; to reload the value. 4994(define_insn "isel_signed_<mode>" 4995 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4996 (if_then_else:GPR 4997 (match_operator 1 "scc_comparison_operator" 4998 [(match_operand:CC 4 "cc_reg_operand" "y,y") 4999 (const_int 0)]) 5000 (match_operand:GPR 2 "reg_or_zero_operand" "O,b") 5001 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] 5002 "TARGET_ISEL" 5003 "isel %0,%2,%3,%j1" 5004 [(set_attr "type" "isel")]) 5005 5006(define_insn "isel_unsigned_<mode>" 5007 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 5008 (if_then_else:GPR 5009 (match_operator 1 "scc_comparison_operator" 5010 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y") 5011 (const_int 0)]) 5012 (match_operand:GPR 2 "reg_or_zero_operand" "O,b") 5013 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] 5014 "TARGET_ISEL" 5015 "isel %0,%2,%3,%j1" 5016 [(set_attr "type" "isel")]) 5017 5018;; These patterns can be useful for combine; they let combine know that 5019;; isel can handle reversed comparisons so long as the operands are 5020;; registers. 5021 5022(define_insn "*isel_reversed_signed_<mode>" 5023 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 5024 (if_then_else:GPR 5025 (match_operator 1 "scc_rev_comparison_operator" 5026 [(match_operand:CC 4 "cc_reg_operand" "y,y") 5027 (const_int 0)]) 5028 (match_operand:GPR 2 "gpc_reg_operand" "r,r") 5029 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))] 5030 "TARGET_ISEL" 5031{ 5032 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1]))); 5033 return "isel %0,%3,%2,%j1"; 5034} 5035 [(set_attr "type" "isel")]) 5036 5037(define_insn "*isel_reversed_unsigned_<mode>" 5038 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 5039 (if_then_else:GPR 5040 (match_operator 1 "scc_rev_comparison_operator" 5041 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y") 5042 (const_int 0)]) 5043 (match_operand:GPR 2 "gpc_reg_operand" "r,r") 5044 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))] 5045 "TARGET_ISEL" 5046{ 5047 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1]))); 5048 return "isel %0,%3,%2,%j1"; 5049} 5050 [(set_attr "type" "isel")]) 5051 5052;; Floating point conditional move 5053(define_expand "mov<mode>cc" 5054 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5055 (if_then_else:SFDF (match_operand 1 "comparison_operator") 5056 (match_operand:SFDF 2 "gpc_reg_operand") 5057 (match_operand:SFDF 3 "gpc_reg_operand")))] 5058 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT" 5059{ 5060 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 5061 DONE; 5062 else 5063 FAIL; 5064}) 5065 5066(define_insn "*fsel<SFDF:mode><SFDF2:mode>4" 5067 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>") 5068 (if_then_else:SFDF 5069 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>") 5070 (match_operand:SFDF2 4 "zero_fp_constant" "F")) 5071 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>") 5072 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))] 5073 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT" 5074 "fsel %0,%1,%2,%3" 5075 [(set_attr "type" "fp")]) 5076 5077(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9" 5078 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 5079 (if_then_else:SFDF 5080 (match_operator:CCFP 1 "fpmask_comparison_operator" 5081 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 5082 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 5083 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 5084 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5085 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 5086 "TARGET_P9_MINMAX" 5087 "#" 5088 "" 5089 [(set (match_dup 6) 5090 (if_then_else:V2DI (match_dup 1) 5091 (match_dup 7) 5092 (match_dup 8))) 5093 (set (match_dup 0) 5094 (if_then_else:SFDF (ne (match_dup 6) 5095 (match_dup 8)) 5096 (match_dup 4) 5097 (match_dup 5)))] 5098{ 5099 if (GET_CODE (operands[6]) == SCRATCH) 5100 operands[6] = gen_reg_rtx (V2DImode); 5101 5102 operands[7] = CONSTM1_RTX (V2DImode); 5103 operands[8] = CONST0_RTX (V2DImode); 5104} 5105 [(set_attr "length" "8") 5106 (set_attr "type" "vecperm")]) 5107 5108;; Handle inverting the fpmask comparisons. 5109(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9" 5110 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 5111 (if_then_else:SFDF 5112 (match_operator:CCFP 1 "invert_fpmask_comparison_operator" 5113 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 5114 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 5115 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 5116 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5117 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 5118 "TARGET_P9_MINMAX" 5119 "#" 5120 "&& 1" 5121 [(set (match_dup 6) 5122 (if_then_else:V2DI (match_dup 9) 5123 (match_dup 7) 5124 (match_dup 8))) 5125 (set (match_dup 0) 5126 (if_then_else:SFDF (ne (match_dup 6) 5127 (match_dup 8)) 5128 (match_dup 5) 5129 (match_dup 4)))] 5130{ 5131 rtx op1 = operands[1]; 5132 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1)); 5133 5134 if (GET_CODE (operands[6]) == SCRATCH) 5135 operands[6] = gen_reg_rtx (V2DImode); 5136 5137 operands[7] = CONSTM1_RTX (V2DImode); 5138 operands[8] = CONST0_RTX (V2DImode); 5139 5140 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]); 5141} 5142 [(set_attr "length" "8") 5143 (set_attr "type" "vecperm")]) 5144 5145(define_insn "*fpmask<mode>" 5146 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa") 5147 (if_then_else:V2DI 5148 (match_operator:CCFP 1 "fpmask_comparison_operator" 5149 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>") 5150 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")]) 5151 (match_operand:V2DI 4 "all_ones_constant" "") 5152 (match_operand:V2DI 5 "zero_constant" "")))] 5153 "TARGET_P9_MINMAX" 5154 "xscmp%V1dp %x0,%x2,%x3" 5155 [(set_attr "type" "fpcompare")]) 5156 5157(define_insn "*xxsel<mode>" 5158 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 5159 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa") 5160 (match_operand:V2DI 2 "zero_constant" "")) 5161 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>") 5162 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))] 5163 "TARGET_P9_MINMAX" 5164 "xxsel %x0,%x4,%x3,%x1" 5165 [(set_attr "type" "vecmove")]) 5166 5167 5168;; Conversions to and from floating-point. 5169 5170; We don't define lfiwax/lfiwzx with the normal definition, because we 5171; don't want to support putting SImode in FPR registers. 5172(define_insn "lfiwax" 5173 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK") 5174 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")] 5175 UNSPEC_LFIWAX))] 5176 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX" 5177 "@ 5178 lfiwax %0,%y1 5179 lxsiwax %x0,%y1 5180 mtvsrwa %x0,%1 5181 vextsw2d %0,%1" 5182 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")]) 5183 5184; This split must be run before register allocation because it allocates the 5185; memory slot that is needed to move values to/from the FPR. We don't allocate 5186; it earlier to allow for the combiner to merge insns together where it might 5187; not be needed and also in case the insns are deleted as dead code. 5188 5189(define_insn_and_split "floatsi<mode>2_lfiwax" 5190 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5191 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) 5192 (clobber (match_scratch:DI 2 "=wi"))] 5193 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX 5194 && <SI_CONVERT_FP> && can_create_pseudo_p ()" 5195 "#" 5196 "" 5197 [(pc)] 5198{ 5199 rtx dest = operands[0]; 5200 rtx src = operands[1]; 5201 rtx tmp; 5202 5203 if (!MEM_P (src) && TARGET_POWERPC64 5204 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5205 tmp = convert_to_mode (DImode, src, false); 5206 else 5207 { 5208 tmp = operands[2]; 5209 if (GET_CODE (tmp) == SCRATCH) 5210 tmp = gen_reg_rtx (DImode); 5211 if (MEM_P (src)) 5212 { 5213 src = rs6000_address_for_fpconvert (src); 5214 emit_insn (gen_lfiwax (tmp, src)); 5215 } 5216 else 5217 { 5218 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5219 emit_move_insn (stack, src); 5220 emit_insn (gen_lfiwax (tmp, stack)); 5221 } 5222 } 5223 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5224 DONE; 5225} 5226 [(set_attr "length" "12") 5227 (set_attr "type" "fpload")]) 5228 5229(define_insn_and_split "floatsi<mode>2_lfiwax_mem" 5230 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5231 (float:SFDF 5232 (sign_extend:DI 5233 (match_operand:SI 1 "indexed_or_indirect_operand" "Z")))) 5234 (clobber (match_scratch:DI 2 "=wi"))] 5235 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>" 5236 "#" 5237 "" 5238 [(pc)] 5239{ 5240 operands[1] = rs6000_address_for_fpconvert (operands[1]); 5241 if (GET_CODE (operands[2]) == SCRATCH) 5242 operands[2] = gen_reg_rtx (DImode); 5243 if (TARGET_P8_VECTOR) 5244 emit_insn (gen_extendsidi2 (operands[2], operands[1])); 5245 else 5246 emit_insn (gen_lfiwax (operands[2], operands[1])); 5247 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5248 DONE; 5249} 5250 [(set_attr "length" "8") 5251 (set_attr "type" "fpload")]) 5252 5253(define_insn "lfiwzx" 5254 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK") 5255 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")] 5256 UNSPEC_LFIWZX))] 5257 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX" 5258 "@ 5259 lfiwzx %0,%y1 5260 lxsiwzx %x0,%y1 5261 mtvsrwz %x0,%1 5262 xxextractuw %x0,%x1,4" 5263 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")]) 5264 5265(define_insn_and_split "floatunssi<mode>2_lfiwzx" 5266 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5267 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) 5268 (clobber (match_scratch:DI 2 "=wi"))] 5269 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" 5270 "#" 5271 "" 5272 [(pc)] 5273{ 5274 rtx dest = operands[0]; 5275 rtx src = operands[1]; 5276 rtx tmp; 5277 5278 if (!MEM_P (src) && TARGET_POWERPC64 5279 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5280 tmp = convert_to_mode (DImode, src, true); 5281 else 5282 { 5283 tmp = operands[2]; 5284 if (GET_CODE (tmp) == SCRATCH) 5285 tmp = gen_reg_rtx (DImode); 5286 if (MEM_P (src)) 5287 { 5288 src = rs6000_address_for_fpconvert (src); 5289 emit_insn (gen_lfiwzx (tmp, src)); 5290 } 5291 else 5292 { 5293 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5294 emit_move_insn (stack, src); 5295 emit_insn (gen_lfiwzx (tmp, stack)); 5296 } 5297 } 5298 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5299 DONE; 5300} 5301 [(set_attr "length" "12") 5302 (set_attr "type" "fpload")]) 5303 5304(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem" 5305 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5306 (unsigned_float:SFDF 5307 (zero_extend:DI 5308 (match_operand:SI 1 "indexed_or_indirect_operand" "Z")))) 5309 (clobber (match_scratch:DI 2 "=wi"))] 5310 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" 5311 "#" 5312 "" 5313 [(pc)] 5314{ 5315 operands[1] = rs6000_address_for_fpconvert (operands[1]); 5316 if (GET_CODE (operands[2]) == SCRATCH) 5317 operands[2] = gen_reg_rtx (DImode); 5318 if (TARGET_P8_VECTOR) 5319 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1])); 5320 else 5321 emit_insn (gen_lfiwzx (operands[2], operands[1])); 5322 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5323 DONE; 5324} 5325 [(set_attr "length" "8") 5326 (set_attr "type" "fpload")]) 5327 5328; For each of these conversions, there is a define_expand, a define_insn 5329; with a '#' template, and a define_split (with C code). The idea is 5330; to allow constant folding with the template of the define_insn, 5331; then to have the insns split later (between sched1 and final). 5332 5333(define_expand "floatsidf2" 5334 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand") 5335 (float:DF (match_operand:SI 1 "nonimmediate_operand"))) 5336 (use (match_dup 2)) 5337 (use (match_dup 3)) 5338 (clobber (match_dup 4)) 5339 (clobber (match_dup 5)) 5340 (clobber (match_dup 6))])] 5341 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 5342{ 5343 if (TARGET_LFIWAX && TARGET_FCFID) 5344 { 5345 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1])); 5346 DONE; 5347 } 5348 else if (TARGET_FCFID) 5349 { 5350 rtx dreg = operands[1]; 5351 if (!REG_P (dreg)) 5352 dreg = force_reg (SImode, dreg); 5353 dreg = convert_to_mode (DImode, dreg, false); 5354 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5355 DONE; 5356 } 5357 5358 if (!REG_P (operands[1])) 5359 operands[1] = force_reg (SImode, operands[1]); 5360 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5361 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); 5362 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5363 operands[5] = gen_reg_rtx (DFmode); 5364 operands[6] = gen_reg_rtx (SImode); 5365}) 5366 5367(define_insn_and_split "*floatsidf2_internal" 5368 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5369 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5370 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5371 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5372 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5373 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) 5374 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] 5375 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 5376 "#" 5377 "" 5378 [(pc)] 5379{ 5380 rtx lowword, highword; 5381 gcc_assert (MEM_P (operands[4])); 5382 highword = adjust_address (operands[4], SImode, 0); 5383 lowword = adjust_address (operands[4], SImode, 4); 5384 if (! WORDS_BIG_ENDIAN) 5385 std::swap (lowword, highword); 5386 5387 emit_insn (gen_xorsi3 (operands[6], operands[1], 5388 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff))); 5389 emit_move_insn (lowword, operands[6]); 5390 emit_move_insn (highword, operands[2]); 5391 emit_move_insn (operands[5], operands[4]); 5392 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5393 DONE; 5394} 5395 [(set_attr "length" "24") 5396 (set_attr "type" "fp")]) 5397 5398;; If we don't have a direct conversion to single precision, don't enable this 5399;; conversion for 32-bit without fast math, because we don't have the insn to 5400;; generate the fixup swizzle to avoid double rounding problems. 5401(define_expand "floatunssisf2" 5402 [(set (match_operand:SF 0 "gpc_reg_operand") 5403 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))] 5404 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 5405 && ((TARGET_FCFIDUS && TARGET_LFIWZX) 5406 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID 5407 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" 5408{ 5409 if (TARGET_LFIWZX && TARGET_FCFIDUS) 5410 { 5411 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1])); 5412 DONE; 5413 } 5414 else 5415 { 5416 rtx dreg = operands[1]; 5417 if (!REG_P (dreg)) 5418 dreg = force_reg (SImode, dreg); 5419 dreg = convert_to_mode (DImode, dreg, true); 5420 emit_insn (gen_floatdisf2 (operands[0], dreg)); 5421 DONE; 5422 } 5423}) 5424 5425(define_expand "floatunssidf2" 5426 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand") 5427 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand"))) 5428 (use (match_dup 2)) 5429 (use (match_dup 3)) 5430 (clobber (match_dup 4)) 5431 (clobber (match_dup 5))])] 5432 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 5433{ 5434 if (TARGET_LFIWZX && TARGET_FCFID) 5435 { 5436 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1])); 5437 DONE; 5438 } 5439 else if (TARGET_FCFID) 5440 { 5441 rtx dreg = operands[1]; 5442 if (!REG_P (dreg)) 5443 dreg = force_reg (SImode, dreg); 5444 dreg = convert_to_mode (DImode, dreg, true); 5445 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5446 DONE; 5447 } 5448 5449 if (!REG_P (operands[1])) 5450 operands[1] = force_reg (SImode, operands[1]); 5451 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5452 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); 5453 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5454 operands[5] = gen_reg_rtx (DFmode); 5455}) 5456 5457(define_insn_and_split "*floatunssidf2_internal" 5458 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5459 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5460 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5461 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5462 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5463 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] 5464 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 5465 && !(TARGET_FCFID && TARGET_POWERPC64)" 5466 "#" 5467 "" 5468 [(pc)] 5469{ 5470 rtx lowword, highword; 5471 gcc_assert (MEM_P (operands[4])); 5472 highword = adjust_address (operands[4], SImode, 0); 5473 lowword = adjust_address (operands[4], SImode, 4); 5474 if (! WORDS_BIG_ENDIAN) 5475 std::swap (lowword, highword); 5476 5477 emit_move_insn (lowword, operands[1]); 5478 emit_move_insn (highword, operands[2]); 5479 emit_move_insn (operands[5], operands[4]); 5480 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5481 DONE; 5482} 5483 [(set_attr "length" "20") 5484 (set_attr "type" "fp")]) 5485 5486;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to 5487;; vector registers. These insns favor doing the sign/zero extension in 5488;; the vector registers, rather then loading up a GPR, doing a sign/zero 5489;; extension and then a direct move. 5490 5491(define_expand "float<QHI:mode><FP_ISA3:mode>2" 5492 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") 5493 (float:FP_ISA3 5494 (match_operand:QHI 1 "input_operand"))) 5495 (clobber (match_scratch:DI 2)) 5496 (clobber (match_scratch:DI 3)) 5497 (clobber (match_scratch:<QHI:MODE> 4))])] 5498 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5499{ 5500 if (MEM_P (operands[1])) 5501 operands[1] = rs6000_address_for_fpconvert (operands[1]); 5502}) 5503 5504(define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal" 5505 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>") 5506 (float:FP_ISA3 5507 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z"))) 5508 (clobber (match_scratch:DI 2 "=wK,wi,wK")) 5509 (clobber (match_scratch:DI 3 "=X,r,X")) 5510 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))] 5511 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5512 "#" 5513 "&& reload_completed" 5514 [(const_int 0)] 5515{ 5516 rtx result = operands[0]; 5517 rtx input = operands[1]; 5518 rtx di = operands[2]; 5519 5520 if (!MEM_P (input)) 5521 { 5522 rtx tmp = operands[3]; 5523 if (altivec_register_operand (input, <QHI:MODE>mode)) 5524 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5525 else if (GET_CODE (tmp) == SCRATCH) 5526 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5527 else 5528 { 5529 emit_insn (gen_extend<QHI:mode>di2 (tmp, input)); 5530 emit_move_insn (di, tmp); 5531 } 5532 } 5533 else 5534 { 5535 rtx tmp = operands[4]; 5536 emit_move_insn (tmp, input); 5537 emit_insn (gen_extend<QHI:mode>di2 (di, tmp)); 5538 } 5539 5540 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); 5541 DONE; 5542}) 5543 5544(define_expand "floatuns<QHI:mode><FP_ISA3:mode>2" 5545 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") 5546 (unsigned_float:FP_ISA3 5547 (match_operand:QHI 1 "input_operand"))) 5548 (clobber (match_scratch:DI 2)) 5549 (clobber (match_scratch:DI 3))])] 5550 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5551{ 5552 if (MEM_P (operands[1])) 5553 operands[1] = rs6000_address_for_fpconvert (operands[1]); 5554}) 5555 5556(define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal" 5557 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>") 5558 (unsigned_float:FP_ISA3 5559 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z"))) 5560 (clobber (match_scratch:DI 2 "=wK,wi,wJwK")) 5561 (clobber (match_scratch:DI 3 "=X,r,X"))] 5562 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5563 "#" 5564 "&& reload_completed" 5565 [(const_int 0)] 5566{ 5567 rtx result = operands[0]; 5568 rtx input = operands[1]; 5569 rtx di = operands[2]; 5570 5571 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode)) 5572 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input)); 5573 else 5574 { 5575 rtx tmp = operands[3]; 5576 if (GET_CODE (tmp) == SCRATCH) 5577 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5578 else 5579 { 5580 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input)); 5581 emit_move_insn (di, tmp); 5582 } 5583 } 5584 5585 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); 5586 DONE; 5587}) 5588 5589(define_expand "fix_trunc<mode>si2" 5590 [(set (match_operand:SI 0 "gpc_reg_operand") 5591 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))] 5592 "TARGET_HARD_FLOAT && <TARGET_FLOAT>" 5593{ 5594 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)) 5595 { 5596 rtx src = force_reg (<MODE>mode, operands[1]); 5597 5598 if (TARGET_STFIWX) 5599 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src)); 5600 else 5601 { 5602 rtx tmp = gen_reg_rtx (DImode); 5603 rtx stack = rs6000_allocate_stack_temp (DImode, true, false); 5604 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src, 5605 tmp, stack)); 5606 } 5607 DONE; 5608 } 5609}) 5610 5611; Like the convert to float patterns, this insn must be split before 5612; register allocation so that it can allocate the memory slot if it 5613; needed 5614(define_insn_and_split "fix_trunc<mode>si2_stfiwx" 5615 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5616 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 5617 (clobber (match_scratch:DI 2 "=d"))] 5618 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 5619 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT) 5620 && TARGET_STFIWX && can_create_pseudo_p () 5621 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" 5622 "#" 5623 "" 5624 [(pc)] 5625{ 5626 rtx dest = operands[0]; 5627 rtx src = operands[1]; 5628 rtx tmp = operands[2]; 5629 5630 if (GET_CODE (tmp) == SCRATCH) 5631 tmp = gen_reg_rtx (DImode); 5632 5633 emit_insn (gen_fctiwz_<mode> (tmp, src)); 5634 if (MEM_P (dest)) 5635 { 5636 dest = rs6000_address_for_fpconvert (dest); 5637 emit_insn (gen_stfiwx (dest, tmp)); 5638 DONE; 5639 } 5640 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5641 { 5642 dest = gen_lowpart (DImode, dest); 5643 emit_move_insn (dest, tmp); 5644 DONE; 5645 } 5646 else 5647 { 5648 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5649 emit_insn (gen_stfiwx (stack, tmp)); 5650 emit_move_insn (dest, stack); 5651 DONE; 5652 } 5653} 5654 [(set_attr "length" "12") 5655 (set_attr "type" "fp")]) 5656 5657(define_insn_and_split "fix_trunc<mode>si2_internal" 5658 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r") 5659 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>"))) 5660 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d")) 5661 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))] 5662 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 5663 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" 5664 "#" 5665 "" 5666 [(pc)] 5667{ 5668 rtx lowword; 5669 gcc_assert (MEM_P (operands[3])); 5670 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 5671 5672 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1])); 5673 emit_move_insn (operands[3], operands[2]); 5674 emit_move_insn (operands[0], lowword); 5675 DONE; 5676} 5677 [(set_attr "length" "16") 5678 (set_attr "type" "fp")]) 5679 5680(define_expand "fix_trunc<mode>di2" 5681 [(set (match_operand:DI 0 "gpc_reg_operand") 5682 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))] 5683 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID" 5684 "") 5685 5686(define_insn "*fix_trunc<mode>di2_fctidz" 5687 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5688 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 5689 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID" 5690 "@ 5691 fctidz %0,%1 5692 xscvdpsxds %x0,%x1" 5693 [(set_attr "type" "fp")]) 5694 5695;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR 5696;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the 5697;; vector registers, so we need to do direct moves to the GPRs, but SImode 5698;; values can go in VSX registers. Keeping the direct move part through 5699;; register allocation prevents the register allocator from doing a direct move 5700;; of the SImode value to a GPR, and then a store/load. 5701(define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2" 5702 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r") 5703 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa"))) 5704 (clobber (match_scratch:SI 2 "=X,X,wi"))] 5705 "TARGET_DIRECT_MOVE" 5706 "@ 5707 fctiw<u>z %0,%1 5708 xscvdp<su>xws %x0,%x1 5709 #" 5710 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)" 5711 [(set (match_dup 2) 5712 (any_fix:SI (match_dup 1))) 5713 (set (match_dup 3) 5714 (match_dup 2))] 5715{ 5716 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0])); 5717} 5718 [(set_attr "length" "4,4,8") 5719 (set_attr "type" "fp")]) 5720 5721(define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8" 5722 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa") 5723 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))] 5724 "TARGET_DIRECT_MOVE" 5725 "@ 5726 fctiw<u>z %0,%1 5727 xscvdp<su>xws %x0,%x1" 5728 [(set_attr "type" "fp")]) 5729 5730;; Keep the convert and store together through register allocation to prevent 5731;; the register allocator from getting clever and doing a direct move to a GPR 5732;; and then store for reg+offset stores. 5733(define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem" 5734 [(set (match_operand:QHSI 0 "memory_operand" "=Z") 5735 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa"))) 5736 (clobber (match_scratch:SI 2 "=wa"))] 5737 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR" 5738 "#" 5739 "&& reload_completed" 5740 [(set (match_dup 2) 5741 (any_fix:SI (match_dup 1))) 5742 (set (match_dup 0) 5743 (match_dup 3))] 5744{ 5745 operands[3] = (<QHSI:MODE>mode == SImode 5746 ? operands[2] 5747 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2]))); 5748}) 5749 5750(define_expand "fixuns_trunc<mode>si2" 5751 [(set (match_operand:SI 0 "gpc_reg_operand") 5752 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))] 5753 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX" 5754{ 5755 if (!TARGET_P8_VECTOR) 5756 { 5757 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1])); 5758 DONE; 5759 } 5760}) 5761 5762(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx" 5763 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5764 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 5765 (clobber (match_scratch:DI 2 "=d"))] 5766 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ 5767 && TARGET_STFIWX && can_create_pseudo_p () 5768 && !TARGET_P8_VECTOR" 5769 "#" 5770 "" 5771 [(pc)] 5772{ 5773 rtx dest = operands[0]; 5774 rtx src = operands[1]; 5775 rtx tmp = operands[2]; 5776 5777 if (GET_CODE (tmp) == SCRATCH) 5778 tmp = gen_reg_rtx (DImode); 5779 5780 emit_insn (gen_fctiwuz_<mode> (tmp, src)); 5781 if (MEM_P (dest)) 5782 { 5783 dest = rs6000_address_for_fpconvert (dest); 5784 emit_insn (gen_stfiwx (dest, tmp)); 5785 DONE; 5786 } 5787 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5788 { 5789 dest = gen_lowpart (DImode, dest); 5790 emit_move_insn (dest, tmp); 5791 DONE; 5792 } 5793 else 5794 { 5795 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5796 emit_insn (gen_stfiwx (stack, tmp)); 5797 emit_move_insn (dest, stack); 5798 DONE; 5799 } 5800} 5801 [(set_attr "length" "12") 5802 (set_attr "type" "fp")]) 5803 5804(define_insn "fixuns_trunc<mode>di2" 5805 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5806 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 5807 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ" 5808 "@ 5809 fctiduz %0,%1 5810 xscvdpuxds %x0,%x1" 5811 [(set_attr "type" "fp")]) 5812 5813;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) 5814;; rather than (set (subreg:SI (reg)) (fix:SI ...)) 5815;; because the first makes it clear that operand 0 is not live 5816;; before the instruction. 5817(define_insn "fctiwz_<mode>" 5818 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5819 (unspec:DI [(fix:SI 5820 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 5821 UNSPEC_FCTIWZ))] 5822 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 5823 "@ 5824 fctiwz %0,%1 5825 xscvdpsxws %x0,%x1" 5826 [(set_attr "type" "fp")]) 5827 5828(define_insn "fctiwuz_<mode>" 5829 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5830 (unspec:DI [(unsigned_fix:SI 5831 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 5832 UNSPEC_FCTIWUZ))] 5833 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ" 5834 "@ 5835 fctiwuz %0,%1 5836 xscvdpuxws %x0,%x1" 5837 [(set_attr "type" "fp")]) 5838 5839;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since 5840;; since the friz instruction does not truncate the value if the floating 5841;; point value is < LONG_MIN or > LONG_MAX. 5842(define_insn "*friz" 5843 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 5844 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))] 5845 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND 5846 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ" 5847 "@ 5848 friz %0,%1 5849 xsrdpiz %x0,%x1" 5850 [(set_attr "type" "fp")]) 5851 5852;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This 5853;; optimization prevents on ISA 2.06 systems and earlier having to store the 5854;; value from the FPR/vector unit to the stack, load the value into a GPR, sign 5855;; extend it, store it back on the stack from the GPR, load it back into the 5856;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07), 5857;; disable using store and load to sign/zero extend the value. 5858(define_insn_and_split "*round32<mode>2_fprs" 5859 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 5860 (float:SFDF 5861 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 5862 (clobber (match_scratch:DI 2 "=d")) 5863 (clobber (match_scratch:DI 3 "=d"))] 5864 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 5865 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID 5866 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()" 5867 "#" 5868 "" 5869 [(pc)] 5870{ 5871 rtx dest = operands[0]; 5872 rtx src = operands[1]; 5873 rtx tmp1 = operands[2]; 5874 rtx tmp2 = operands[3]; 5875 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5876 5877 if (GET_CODE (tmp1) == SCRATCH) 5878 tmp1 = gen_reg_rtx (DImode); 5879 if (GET_CODE (tmp2) == SCRATCH) 5880 tmp2 = gen_reg_rtx (DImode); 5881 5882 emit_insn (gen_fctiwz_<mode> (tmp1, src)); 5883 emit_insn (gen_stfiwx (stack, tmp1)); 5884 emit_insn (gen_lfiwax (tmp2, stack)); 5885 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 5886 DONE; 5887} 5888 [(set_attr "type" "fpload") 5889 (set_attr "length" "16")]) 5890 5891(define_insn_and_split "*roundu32<mode>2_fprs" 5892 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 5893 (unsigned_float:SFDF 5894 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 5895 (clobber (match_scratch:DI 2 "=d")) 5896 (clobber (match_scratch:DI 3 "=d"))] 5897 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 5898 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE 5899 && can_create_pseudo_p ()" 5900 "#" 5901 "" 5902 [(pc)] 5903{ 5904 rtx dest = operands[0]; 5905 rtx src = operands[1]; 5906 rtx tmp1 = operands[2]; 5907 rtx tmp2 = operands[3]; 5908 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5909 5910 if (GET_CODE (tmp1) == SCRATCH) 5911 tmp1 = gen_reg_rtx (DImode); 5912 if (GET_CODE (tmp2) == SCRATCH) 5913 tmp2 = gen_reg_rtx (DImode); 5914 5915 emit_insn (gen_fctiwuz_<mode> (tmp1, src)); 5916 emit_insn (gen_stfiwx (stack, tmp1)); 5917 emit_insn (gen_lfiwzx (tmp2, stack)); 5918 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 5919 DONE; 5920} 5921 [(set_attr "type" "fpload") 5922 (set_attr "length" "16")]) 5923 5924;; No VSX equivalent to fctid 5925(define_insn "lrint<mode>di2" 5926 [(set (match_operand:DI 0 "gpc_reg_operand" "=d") 5927 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 5928 UNSPEC_FCTID))] 5929 "TARGET_<MODE>_FPR && TARGET_FPRND" 5930 "fctid %0,%1" 5931 [(set_attr "type" "fp")]) 5932 5933(define_insn "btrunc<mode>2" 5934 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5935 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 5936 UNSPEC_FRIZ))] 5937 "TARGET_<MODE>_FPR && TARGET_FPRND" 5938 "@ 5939 friz %0,%1 5940 xsrdpiz %x0,%x1" 5941 [(set_attr "type" "fp") 5942 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5943 5944(define_insn "ceil<mode>2" 5945 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5946 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 5947 UNSPEC_FRIP))] 5948 "TARGET_<MODE>_FPR && TARGET_FPRND" 5949 "@ 5950 frip %0,%1 5951 xsrdpip %x0,%x1" 5952 [(set_attr "type" "fp") 5953 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5954 5955(define_insn "floor<mode>2" 5956 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5957 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 5958 UNSPEC_FRIM))] 5959 "TARGET_<MODE>_FPR && TARGET_FPRND" 5960 "@ 5961 frim %0,%1 5962 xsrdpim %x0,%x1" 5963 [(set_attr "type" "fp") 5964 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5965 5966;; No VSX equivalent to frin 5967(define_insn "round<mode>2" 5968 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") 5969 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 5970 UNSPEC_FRIN))] 5971 "TARGET_<MODE>_FPR && TARGET_FPRND" 5972 "frin %0,%1" 5973 [(set_attr "type" "fp") 5974 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5975 5976(define_insn "*xsrdpi<mode>2" 5977 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5978 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")] 5979 UNSPEC_XSRDPI))] 5980 "TARGET_<MODE>_FPR && TARGET_VSX" 5981 "xsrdpi %x0,%x1" 5982 [(set_attr "type" "fp") 5983 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5984 5985(define_expand "lround<mode>di2" 5986 [(set (match_dup 2) 5987 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")] 5988 UNSPEC_XSRDPI)) 5989 (set (match_operand:DI 0 "gpc_reg_operand") 5990 (unspec:DI [(match_dup 2)] 5991 UNSPEC_FCTID))] 5992 "TARGET_<MODE>_FPR && TARGET_VSX && TARGET_FPRND" 5993{ 5994 operands[2] = gen_reg_rtx (<MODE>mode); 5995}) 5996 5997; An UNSPEC is used so we don't have to support SImode in FP registers. 5998; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx 5999; is only generated for Power8 or later. 6000(define_insn "stfiwx" 6001 [(set (match_operand:SI 0 "memory_operand" "=Z,Z") 6002 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")] 6003 UNSPEC_STFIWX))] 6004 "TARGET_PPC_GFXOPT" 6005 "@ 6006 stfiwx %1,%y0 6007 stxsiwx %x1,%y0" 6008 [(set_attr "type" "fpstore")]) 6009 6010;; If we don't have a direct conversion to single precision, don't enable this 6011;; conversion for 32-bit without fast math, because we don't have the insn to 6012;; generate the fixup swizzle to avoid double rounding problems. 6013(define_expand "floatsisf2" 6014 [(set (match_operand:SF 0 "gpc_reg_operand") 6015 (float:SF (match_operand:SI 1 "nonimmediate_operand")))] 6016 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 6017 && ((TARGET_FCFIDS && TARGET_LFIWAX) 6018 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID 6019 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" 6020{ 6021 if (TARGET_FCFIDS && TARGET_LFIWAX) 6022 { 6023 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1])); 6024 DONE; 6025 } 6026 else if (TARGET_FCFID && TARGET_LFIWAX) 6027 { 6028 rtx dfreg = gen_reg_rtx (DFmode); 6029 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1])); 6030 emit_insn (gen_truncdfsf2 (operands[0], dfreg)); 6031 DONE; 6032 } 6033 else 6034 { 6035 rtx dreg = operands[1]; 6036 if (!REG_P (dreg)) 6037 dreg = force_reg (SImode, dreg); 6038 dreg = convert_to_mode (DImode, dreg, false); 6039 emit_insn (gen_floatdisf2 (operands[0], dreg)); 6040 DONE; 6041 } 6042}) 6043 6044(define_insn "floatdidf2" 6045 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 6046 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 6047 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT" 6048 "@ 6049 fcfid %0,%1 6050 xscvsxddp %x0,%x1" 6051 [(set_attr "type" "fp")]) 6052 6053; Allow the combiner to merge source memory operands to the conversion so that 6054; the optimizer/register allocator doesn't try to load the value too early in a 6055; GPR and then use store/load to move it to a FPR and suffer from a store-load 6056; hit. We will split after reload to avoid the trip through the GPRs 6057 6058(define_insn_and_split "*floatdidf2_mem" 6059 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 6060 (float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 6061 (clobber (match_scratch:DI 2 "=d,wi"))] 6062 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID" 6063 "#" 6064 "&& reload_completed" 6065 [(set (match_dup 2) (match_dup 1)) 6066 (set (match_dup 0) (float:DF (match_dup 2)))] 6067 "" 6068 [(set_attr "length" "8") 6069 (set_attr "type" "fpload")]) 6070 6071(define_expand "floatunsdidf2" 6072 [(set (match_operand:DF 0 "gpc_reg_operand") 6073 (unsigned_float:DF 6074 (match_operand:DI 1 "gpc_reg_operand")))] 6075 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 6076 "") 6077 6078(define_insn "*floatunsdidf2_fcfidu" 6079 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 6080 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 6081 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 6082 "@ 6083 fcfidu %0,%1 6084 xscvuxddp %x0,%x1" 6085 [(set_attr "type" "fp") 6086 (set_attr "length" "4")]) 6087 6088(define_insn_and_split "*floatunsdidf2_mem" 6089 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 6090 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 6091 (clobber (match_scratch:DI 2 "=d,wi"))] 6092 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))" 6093 "#" 6094 "&& reload_completed" 6095 [(set (match_dup 2) (match_dup 1)) 6096 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))] 6097 "" 6098 [(set_attr "length" "8") 6099 (set_attr "type" "fpload")]) 6100 6101(define_expand "floatdisf2" 6102 [(set (match_operand:SF 0 "gpc_reg_operand") 6103 (float:SF (match_operand:DI 1 "gpc_reg_operand")))] 6104 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 6105 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)" 6106{ 6107 if (!TARGET_FCFIDS) 6108 { 6109 rtx val = operands[1]; 6110 if (!flag_unsafe_math_optimizations) 6111 { 6112 rtx label = gen_label_rtx (); 6113 val = gen_reg_rtx (DImode); 6114 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label)); 6115 emit_label (label); 6116 } 6117 emit_insn (gen_floatdisf2_internal1 (operands[0], val)); 6118 DONE; 6119 } 6120}) 6121 6122(define_insn "floatdisf2_fcfids" 6123 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy") 6124 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 6125 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 6126 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS" 6127 "@ 6128 fcfids %0,%1 6129 xscvsxdsp %x0,%x1" 6130 [(set_attr "type" "fp")]) 6131 6132(define_insn_and_split "*floatdisf2_mem" 6133 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy") 6134 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 6135 (clobber (match_scratch:DI 2 "=d,d,wi"))] 6136 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 6137 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS" 6138 "#" 6139 "&& reload_completed" 6140 [(pc)] 6141{ 6142 emit_move_insn (operands[2], operands[1]); 6143 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2])); 6144 DONE; 6145} 6146 [(set_attr "length" "8")]) 6147 6148;; This is not IEEE compliant if rounding mode is "round to nearest". 6149;; If the DI->DF conversion is inexact, then it's possible to suffer 6150;; from double rounding. 6151;; Instead of creating a new cpu type for two FP operations, just use fp 6152(define_insn_and_split "floatdisf2_internal1" 6153 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 6154 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d"))) 6155 (clobber (match_scratch:DF 2 "=d"))] 6156 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS" 6157 "#" 6158 "&& reload_completed" 6159 [(set (match_dup 2) 6160 (float:DF (match_dup 1))) 6161 (set (match_dup 0) 6162 (float_truncate:SF (match_dup 2)))] 6163 "" 6164 [(set_attr "length" "8") 6165 (set_attr "type" "fp")]) 6166 6167;; Twiddles bits to avoid double rounding. 6168;; Bits that might be truncated when converting to DFmode are replaced 6169;; by a bit that won't be lost at that stage, but is below the SFmode 6170;; rounding position. 6171(define_expand "floatdisf2_internal2" 6172 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "") 6173 (const_int 53))) 6174 (clobber (reg:DI CA_REGNO))]) 6175 (set (match_operand:DI 0 "") (and:DI (match_dup 1) 6176 (const_int 2047))) 6177 (set (match_dup 3) (plus:DI (match_dup 3) 6178 (const_int 1))) 6179 (set (match_dup 0) (plus:DI (match_dup 0) 6180 (const_int 2047))) 6181 (set (match_dup 4) (compare:CCUNS (match_dup 3) 6182 (const_int 2))) 6183 (set (match_dup 0) (ior:DI (match_dup 0) 6184 (match_dup 1))) 6185 (set (match_dup 0) (and:DI (match_dup 0) 6186 (const_int -2048))) 6187 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) 6188 (label_ref (match_operand:DI 2 "")) 6189 (pc))) 6190 (set (match_dup 0) (match_dup 1))] 6191 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 6192 && !TARGET_FCFIDS" 6193{ 6194 operands[3] = gen_reg_rtx (DImode); 6195 operands[4] = gen_reg_rtx (CCUNSmode); 6196}) 6197 6198(define_expand "floatunsdisf2" 6199 [(set (match_operand:SF 0 "gpc_reg_operand") 6200 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))] 6201 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 6202 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" 6203 "") 6204 6205(define_insn "floatunsdisf2_fcfidus" 6206 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu") 6207 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 6208 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 6209 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" 6210 "@ 6211 fcfidus %0,%1 6212 xscvuxdsp %x0,%x1" 6213 [(set_attr "type" "fp")]) 6214 6215(define_insn_and_split "*floatunsdisf2_mem" 6216 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy") 6217 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 6218 (clobber (match_scratch:DI 2 "=d,d,wi"))] 6219 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 6220 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" 6221 "#" 6222 "&& reload_completed" 6223 [(pc)] 6224{ 6225 emit_move_insn (operands[2], operands[1]); 6226 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2])); 6227 DONE; 6228} 6229 [(set_attr "length" "8") 6230 (set_attr "type" "fpload")]) 6231 6232;; Define the TImode operations that can be done in a small number 6233;; of instructions. The & constraints are to prevent the register 6234;; allocator from allocating registers that overlap with the inputs 6235;; (for example, having an input in 7,8 and an output in 6,7). We 6236;; also allow for the output being the same as one of the inputs. 6237 6238(define_expand "addti3" 6239 [(set (match_operand:TI 0 "gpc_reg_operand") 6240 (plus:TI (match_operand:TI 1 "gpc_reg_operand") 6241 (match_operand:TI 2 "reg_or_short_operand")))] 6242 "TARGET_64BIT" 6243{ 6244 rtx lo0 = gen_lowpart (DImode, operands[0]); 6245 rtx lo1 = gen_lowpart (DImode, operands[1]); 6246 rtx lo2 = gen_lowpart (DImode, operands[2]); 6247 rtx hi0 = gen_highpart (DImode, operands[0]); 6248 rtx hi1 = gen_highpart (DImode, operands[1]); 6249 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]); 6250 6251 if (!reg_or_short_operand (lo2, DImode)) 6252 lo2 = force_reg (DImode, lo2); 6253 if (!adde_operand (hi2, DImode)) 6254 hi2 = force_reg (DImode, hi2); 6255 6256 emit_insn (gen_adddi3_carry (lo0, lo1, lo2)); 6257 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2)); 6258 DONE; 6259}) 6260 6261(define_expand "subti3" 6262 [(set (match_operand:TI 0 "gpc_reg_operand") 6263 (minus:TI (match_operand:TI 1 "reg_or_short_operand") 6264 (match_operand:TI 2 "gpc_reg_operand")))] 6265 "TARGET_64BIT" 6266{ 6267 rtx lo0 = gen_lowpart (DImode, operands[0]); 6268 rtx lo1 = gen_lowpart (DImode, operands[1]); 6269 rtx lo2 = gen_lowpart (DImode, operands[2]); 6270 rtx hi0 = gen_highpart (DImode, operands[0]); 6271 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]); 6272 rtx hi2 = gen_highpart (DImode, operands[2]); 6273 6274 if (!reg_or_short_operand (lo1, DImode)) 6275 lo1 = force_reg (DImode, lo1); 6276 if (!adde_operand (hi1, DImode)) 6277 hi1 = force_reg (DImode, hi1); 6278 6279 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1)); 6280 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1)); 6281 DONE; 6282}) 6283 6284;; 128-bit logical operations expanders 6285 6286(define_expand "and<mode>3" 6287 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6288 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6289 (match_operand:BOOL_128 2 "vlogical_operand")))] 6290 "" 6291 "") 6292 6293(define_expand "ior<mode>3" 6294 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6295 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6296 (match_operand:BOOL_128 2 "vlogical_operand")))] 6297 "" 6298 "") 6299 6300(define_expand "xor<mode>3" 6301 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6302 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6303 (match_operand:BOOL_128 2 "vlogical_operand")))] 6304 "" 6305 "") 6306 6307(define_expand "one_cmpl<mode>2" 6308 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6309 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))] 6310 "" 6311 "") 6312 6313(define_expand "nor<mode>3" 6314 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6315 (and:BOOL_128 6316 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")) 6317 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))] 6318 "" 6319 "") 6320 6321(define_expand "andc<mode>3" 6322 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6323 (and:BOOL_128 6324 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand")) 6325 (match_operand:BOOL_128 1 "vlogical_operand")))] 6326 "" 6327 "") 6328 6329;; Power8 vector logical instructions. 6330(define_expand "eqv<mode>3" 6331 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6332 (not:BOOL_128 6333 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6334 (match_operand:BOOL_128 2 "vlogical_operand"))))] 6335 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6336 "") 6337 6338;; Rewrite nand into canonical form 6339(define_expand "nand<mode>3" 6340 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6341 (ior:BOOL_128 6342 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")) 6343 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))] 6344 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6345 "") 6346 6347;; The canonical form is to have the negated element first, so we need to 6348;; reverse arguments. 6349(define_expand "orc<mode>3" 6350 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6351 (ior:BOOL_128 6352 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand")) 6353 (match_operand:BOOL_128 1 "vlogical_operand")))] 6354 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6355 "") 6356 6357;; 128-bit logical operations insns and split operations 6358(define_insn_and_split "*and<mode>3_internal" 6359 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6360 (and:BOOL_128 6361 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 6362 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))] 6363 "" 6364{ 6365 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6366 return "xxland %x0,%x1,%x2"; 6367 6368 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6369 return "vand %0,%1,%2"; 6370 6371 return "#"; 6372} 6373 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6374 [(const_int 0)] 6375{ 6376 rs6000_split_logical (operands, AND, false, false, false); 6377 DONE; 6378} 6379 [(set (attr "type") 6380 (if_then_else 6381 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6382 (const_string "veclogical") 6383 (const_string "integer"))) 6384 (set (attr "length") 6385 (if_then_else 6386 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6387 (const_string "4") 6388 (if_then_else 6389 (match_test "TARGET_POWERPC64") 6390 (const_string "8") 6391 (const_string "16"))))]) 6392 6393;; 128-bit IOR/XOR 6394(define_insn_and_split "*bool<mode>3_internal" 6395 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6396 (match_operator:BOOL_128 3 "boolean_or_operator" 6397 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 6398 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))] 6399 "" 6400{ 6401 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6402 return "xxl%q3 %x0,%x1,%x2"; 6403 6404 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6405 return "v%q3 %0,%1,%2"; 6406 6407 return "#"; 6408} 6409 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6410 [(const_int 0)] 6411{ 6412 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false); 6413 DONE; 6414} 6415 [(set (attr "type") 6416 (if_then_else 6417 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6418 (const_string "veclogical") 6419 (const_string "integer"))) 6420 (set (attr "length") 6421 (if_then_else 6422 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6423 (const_string "4") 6424 (if_then_else 6425 (match_test "TARGET_POWERPC64") 6426 (const_string "8") 6427 (const_string "16"))))]) 6428 6429;; 128-bit ANDC/ORC 6430(define_insn_and_split "*boolc<mode>3_internal1" 6431 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6432 (match_operator:BOOL_128 3 "boolean_operator" 6433 [(not:BOOL_128 6434 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")) 6435 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))] 6436 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 6437{ 6438 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6439 return "xxl%q3 %x0,%x1,%x2"; 6440 6441 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6442 return "v%q3 %0,%1,%2"; 6443 6444 return "#"; 6445} 6446 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 6447 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6448 [(const_int 0)] 6449{ 6450 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 6451 DONE; 6452} 6453 [(set (attr "type") 6454 (if_then_else 6455 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6456 (const_string "veclogical") 6457 (const_string "integer"))) 6458 (set (attr "length") 6459 (if_then_else 6460 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6461 (const_string "4") 6462 (if_then_else 6463 (match_test "TARGET_POWERPC64") 6464 (const_string "8") 6465 (const_string "16"))))]) 6466 6467(define_insn_and_split "*boolc<mode>3_internal2" 6468 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6469 (match_operator:TI2 3 "boolean_operator" 6470 [(not:TI2 6471 (match_operand:TI2 2 "int_reg_operand" "r,0,r")) 6472 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))] 6473 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6474 "#" 6475 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6476 [(const_int 0)] 6477{ 6478 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 6479 DONE; 6480} 6481 [(set_attr "type" "integer") 6482 (set (attr "length") 6483 (if_then_else 6484 (match_test "TARGET_POWERPC64") 6485 (const_string "8") 6486 (const_string "16")))]) 6487 6488;; 128-bit NAND/NOR 6489(define_insn_and_split "*boolcc<mode>3_internal1" 6490 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6491 (match_operator:BOOL_128 3 "boolean_operator" 6492 [(not:BOOL_128 6493 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")) 6494 (not:BOOL_128 6495 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))] 6496 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 6497{ 6498 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6499 return "xxl%q3 %x0,%x1,%x2"; 6500 6501 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6502 return "v%q3 %0,%1,%2"; 6503 6504 return "#"; 6505} 6506 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 6507 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6508 [(const_int 0)] 6509{ 6510 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 6511 DONE; 6512} 6513 [(set (attr "type") 6514 (if_then_else 6515 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6516 (const_string "veclogical") 6517 (const_string "integer"))) 6518 (set (attr "length") 6519 (if_then_else 6520 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6521 (const_string "4") 6522 (if_then_else 6523 (match_test "TARGET_POWERPC64") 6524 (const_string "8") 6525 (const_string "16"))))]) 6526 6527(define_insn_and_split "*boolcc<mode>3_internal2" 6528 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6529 (match_operator:TI2 3 "boolean_operator" 6530 [(not:TI2 6531 (match_operand:TI2 1 "int_reg_operand" "r,0,r")) 6532 (not:TI2 6533 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))] 6534 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6535 "#" 6536 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6537 [(const_int 0)] 6538{ 6539 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 6540 DONE; 6541} 6542 [(set_attr "type" "integer") 6543 (set (attr "length") 6544 (if_then_else 6545 (match_test "TARGET_POWERPC64") 6546 (const_string "8") 6547 (const_string "16")))]) 6548 6549 6550;; 128-bit EQV 6551(define_insn_and_split "*eqv<mode>3_internal1" 6552 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6553 (not:BOOL_128 6554 (xor:BOOL_128 6555 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>") 6556 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))] 6557 "TARGET_P8_VECTOR" 6558{ 6559 if (vsx_register_operand (operands[0], <MODE>mode)) 6560 return "xxleqv %x0,%x1,%x2"; 6561 6562 return "#"; 6563} 6564 "TARGET_P8_VECTOR && reload_completed 6565 && int_reg_operand (operands[0], <MODE>mode)" 6566 [(const_int 0)] 6567{ 6568 rs6000_split_logical (operands, XOR, true, false, false); 6569 DONE; 6570} 6571 [(set (attr "type") 6572 (if_then_else 6573 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6574 (const_string "veclogical") 6575 (const_string "integer"))) 6576 (set (attr "length") 6577 (if_then_else 6578 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6579 (const_string "4") 6580 (if_then_else 6581 (match_test "TARGET_POWERPC64") 6582 (const_string "8") 6583 (const_string "16"))))]) 6584 6585(define_insn_and_split "*eqv<mode>3_internal2" 6586 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6587 (not:TI2 6588 (xor:TI2 6589 (match_operand:TI2 1 "int_reg_operand" "r,0,r") 6590 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))] 6591 "!TARGET_P8_VECTOR" 6592 "#" 6593 "reload_completed && !TARGET_P8_VECTOR" 6594 [(const_int 0)] 6595{ 6596 rs6000_split_logical (operands, XOR, true, false, false); 6597 DONE; 6598} 6599 [(set_attr "type" "integer") 6600 (set (attr "length") 6601 (if_then_else 6602 (match_test "TARGET_POWERPC64") 6603 (const_string "8") 6604 (const_string "16")))]) 6605 6606;; 128-bit one's complement 6607(define_insn_and_split "*one_cmpl<mode>3_internal" 6608 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6609 (not:BOOL_128 6610 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))] 6611 "" 6612{ 6613 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6614 return "xxlnor %x0,%x1,%x1"; 6615 6616 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6617 return "vnor %0,%1,%1"; 6618 6619 return "#"; 6620} 6621 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6622 [(const_int 0)] 6623{ 6624 rs6000_split_logical (operands, NOT, false, false, false); 6625 DONE; 6626} 6627 [(set (attr "type") 6628 (if_then_else 6629 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6630 (const_string "veclogical") 6631 (const_string "integer"))) 6632 (set (attr "length") 6633 (if_then_else 6634 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6635 (const_string "4") 6636 (if_then_else 6637 (match_test "TARGET_POWERPC64") 6638 (const_string "8") 6639 (const_string "16"))))]) 6640 6641 6642;; Now define ways of moving data around. 6643 6644;; Set up a register with a value from the GOT table 6645 6646(define_expand "movsi_got" 6647 [(set (match_operand:SI 0 "gpc_reg_operand") 6648 (unspec:SI [(match_operand:SI 1 "got_operand") 6649 (match_dup 2)] UNSPEC_MOVSI_GOT))] 6650 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 6651{ 6652 if (GET_CODE (operands[1]) == CONST) 6653 { 6654 rtx offset = const0_rtx; 6655 HOST_WIDE_INT value; 6656 6657 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset); 6658 value = INTVAL (offset); 6659 if (value != 0) 6660 { 6661 rtx tmp = (!can_create_pseudo_p () 6662 ? operands[0] 6663 : gen_reg_rtx (Pmode)); 6664 emit_insn (gen_movsi_got (tmp, operands[1])); 6665 emit_insn (gen_addsi3 (operands[0], tmp, offset)); 6666 DONE; 6667 } 6668 } 6669 6670 operands[2] = rs6000_got_register (operands[1]); 6671}) 6672 6673(define_insn "*movsi_got_internal" 6674 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 6675 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") 6676 (match_operand:SI 2 "gpc_reg_operand" "b")] 6677 UNSPEC_MOVSI_GOT))] 6678 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 6679 "lwz %0,%a1@got(%2)" 6680 [(set_attr "type" "load")]) 6681 6682;; Used by sched, shorten_branches and final when the GOT pseudo reg 6683;; didn't get allocated to a hard register. 6684(define_split 6685 [(set (match_operand:SI 0 "gpc_reg_operand") 6686 (unspec:SI [(match_operand:SI 1 "got_no_const_operand") 6687 (match_operand:SI 2 "memory_operand")] 6688 UNSPEC_MOVSI_GOT))] 6689 "DEFAULT_ABI == ABI_V4 6690 && flag_pic == 1 6691 && reload_completed" 6692 [(set (match_dup 0) (match_dup 2)) 6693 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 6694 UNSPEC_MOVSI_GOT))] 6695 "") 6696 6697;; For SI, we special-case integers that can't be loaded in one insn. We 6698;; do the load 16-bits at a time. We could do this by loading from memory, 6699;; and this is even supposed to be faster, but it is simpler not to get 6700;; integers in the TOC. 6701 6702;; MR LA LWZ LFIWZX LXSIWZX 6703;; STW STFIWX STXSIWX LI LIS 6704;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW 6705;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ 6706;; MF%1 MT%0 MT%0 NOP 6707(define_insn "*movsi_internal1" 6708 [(set (match_operand:SI 0 "nonimmediate_operand" 6709 "=r, r, r, ?*wI, ?*wH, 6710 m, ?Z, ?Z, r, r, 6711 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu, 6712 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r, 6713 r, *c*l, *h, *h") 6714 6715 (match_operand:SI 1 "input_operand" 6716 "r, U, m, Z, Z, 6717 r, wI, wH, I, L, 6718 n, wIwH, O, wM, wB, 6719 O, wM, wS, r, wIwH, 6720 *h, r, r, 0"))] 6721 6722 "!TARGET_SINGLE_FPU && 6723 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" 6724 "@ 6725 mr %0,%1 6726 la %0,%a1 6727 lwz%U1%X1 %0,%1 6728 lfiwzx %0,%y1 6729 lxsiwzx %x0,%y1 6730 stw%U0%X0 %1,%0 6731 stfiwx %1,%y0 6732 stxsiwx %x1,%y0 6733 li %0,%1 6734 lis %0,%v1 6735 # 6736 xxlor %x0,%x1,%x1 6737 xxspltib %x0,0 6738 xxspltib %x0,255 6739 vspltisw %0,%1 6740 xxlxor %x0,%x0,%x0 6741 xxlorc %x0,%x0,%x0 6742 # 6743 mtvsrwz %x0,%1 6744 mfvsrwz %0,%x1 6745 mf%1 %0 6746 mt%0 %1 6747 mt%0 %1 6748 nop" 6749 [(set_attr "type" 6750 "*, *, load, fpload, fpload, 6751 store, fpstore, fpstore, *, *, 6752 *, veclogical, vecsimple, vecsimple, vecsimple, 6753 veclogical, veclogical, vecsimple, mffgpr, mftgpr, 6754 *, *, *, *") 6755 6756 (set_attr "length" 6757 "4, 4, 4, 4, 4, 6758 4, 4, 4, 4, 4, 6759 8, 4, 4, 4, 4, 6760 4, 4, 8, 4, 4, 6761 4, 4, 4, 4")]) 6762 6763(define_insn "*movsi_internal1_single" 6764 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f") 6765 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))] 6766 "TARGET_SINGLE_FPU && 6767 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" 6768 "@ 6769 mr %0,%1 6770 la %0,%a1 6771 lwz%U1%X1 %0,%1 6772 stw%U0%X0 %1,%0 6773 li %0,%1 6774 lis %0,%v1 6775 # 6776 mf%1 %0 6777 mt%0 %1 6778 mt%0 %1 6779 nop 6780 stfs%U0%X0 %1,%0 6781 lfs%U1%X1 %0,%1" 6782 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload") 6783 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")]) 6784 6785;; Like movsi, but adjust a SF value to be used in a SI context, i.e. 6786;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0)) 6787;; 6788;; Because SF values are actually stored as DF values within the vector 6789;; registers, we need to convert the value to the vector SF format when 6790;; we need to use the bits in a union or similar cases. We only need 6791;; to do this transformation when the value is a vector register. Loads, 6792;; stores, and transfers within GPRs are assumed to be safe. 6793;; 6794;; This is a more general case of reload_gpr_from_vsxsf. That insn must have 6795;; no alternatives, because the call is created as part of secondary_reload, 6796;; and operand #2's register class is used to allocate the temporary register. 6797;; This function is called before reload, and it creates the temporary as 6798;; needed. 6799 6800;; MR LWZ LFIWZX LXSIWZX STW 6801;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX 6802;; MTVSRWZ 6803 6804(define_insn_and_split "movsi_from_sf" 6805 [(set (match_operand:SI 0 "nonimmediate_operand" 6806 "=r, r, ?*wI, ?*wH, m, 6807 m, wY, Z, r, ?*wIwH, 6808 wIwH") 6809 6810 (unspec:SI [(match_operand:SF 1 "input_operand" 6811 "r, m, Z, Z, r, 6812 f, wb, wu, wIwH, wIwH, 6813 r")] 6814 UNSPEC_SI_FROM_SF)) 6815 6816 (clobber (match_scratch:V4SF 2 6817 "=X, X, X, X, X, 6818 X, X, X, wIwH, X, 6819 X"))] 6820 6821 "TARGET_NO_SF_SUBREG 6822 && (register_operand (operands[0], SImode) 6823 || register_operand (operands[1], SFmode))" 6824 "@ 6825 mr %0,%1 6826 lwz%U1%X1 %0,%1 6827 lfiwzx %0,%y1 6828 lxsiwzx %x0,%y1 6829 stw%U0%X0 %1,%0 6830 stfs%U0%X0 %1,%0 6831 stxssp %1,%0 6832 stxsspx %x1,%y0 6833 # 6834 xscvdpspn %x0,%x1 6835 mtvsrwz %x0,%1" 6836 "&& reload_completed 6837 && int_reg_operand (operands[0], SImode) 6838 && vsx_reg_sfsubreg_ok (operands[1], SFmode)" 6839 [(const_int 0)] 6840{ 6841 rtx op0 = operands[0]; 6842 rtx op1 = operands[1]; 6843 rtx op2 = operands[2]; 6844 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0)); 6845 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 6846 6847 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 6848 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si)); 6849 DONE; 6850} 6851 [(set_attr "type" 6852 "*, load, fpload, fpload, store, 6853 fpstore, fpstore, fpstore, mftgpr, fp, 6854 mffgpr") 6855 6856 (set_attr "length" 6857 "4, 4, 4, 4, 4, 6858 4, 4, 4, 8, 4, 6859 4")]) 6860 6861;; movsi_from_sf with zero extension 6862;; 6863;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR 6864;; VSX->VSX MTVSRWZ 6865 6866(define_insn_and_split "*movdi_from_sf_zero_ext" 6867 [(set (match_operand:DI 0 "gpc_reg_operand" 6868 "=r, r, ?*wI, ?*wH, r, 6869 ?wK, wIwH") 6870 6871 (zero_extend:DI 6872 (unspec:SI [(match_operand:SF 1 "input_operand" 6873 "r, m, Z, Z, wIwH, 6874 wIwH, r")] 6875 UNSPEC_SI_FROM_SF))) 6876 6877 (clobber (match_scratch:V4SF 2 6878 "=X, X, X, X, wa, 6879 wIwH, X"))] 6880 6881 "TARGET_DIRECT_MOVE_64BIT 6882 && (register_operand (operands[0], DImode) 6883 || register_operand (operands[1], SImode))" 6884 "@ 6885 rldicl %0,%1,0,32 6886 lwz%U1%X1 %0,%1 6887 lfiwzx %0,%y1 6888 lxsiwzx %x0,%y1 6889 # 6890 # 6891 mtvsrwz %x0,%1" 6892 "&& reload_completed 6893 && register_operand (operands[0], DImode) 6894 && vsx_reg_sfsubreg_ok (operands[1], SFmode)" 6895 [(const_int 0)] 6896{ 6897 rtx op0 = operands[0]; 6898 rtx op1 = operands[1]; 6899 rtx op2 = operands[2]; 6900 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 6901 6902 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 6903 emit_insn (gen_zero_extendsidi2 (op0, op2_si)); 6904 DONE; 6905} 6906 [(set_attr "type" 6907 "*, load, fpload, fpload, two, 6908 two, mffgpr") 6909 6910 (set_attr "length" 6911 "4, 4, 4, 4, 8, 6912 8, 4")]) 6913 6914;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before 6915;; moving it to SImode. We cannot do a SFmode store without having to do the 6916;; conversion explicitly since that doesn't work in most cases if the input 6917;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the 6918;; former handles cases where the input will not fit in a SFmode, and the 6919;; latter assumes the value has already been rounded. 6920(define_insn "*movsi_from_df" 6921 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa") 6922 (unspec:SI [(float_truncate:SF 6923 (match_operand:DF 1 "gpc_reg_operand" "wa"))] 6924 UNSPEC_SI_FROM_SF))] 6925 "TARGET_NO_SF_SUBREG" 6926 "xscvdpsp %x0,%x1" 6927 [(set_attr "type" "fp")]) 6928 6929;; Split a load of a large constant into the appropriate two-insn 6930;; sequence. 6931 6932(define_split 6933 [(set (match_operand:SI 0 "gpc_reg_operand") 6934 (match_operand:SI 1 "const_int_operand"))] 6935 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000 6936 && (INTVAL (operands[1]) & 0xffff) != 0" 6937 [(set (match_dup 0) 6938 (match_dup 2)) 6939 (set (match_dup 0) 6940 (ior:SI (match_dup 0) 6941 (match_dup 3)))] 6942{ 6943 if (rs6000_emit_set_const (operands[0], operands[1])) 6944 DONE; 6945 else 6946 FAIL; 6947}) 6948 6949;; Split loading -128..127 to use XXSPLITB and VEXTSW2D 6950(define_split 6951 [(set (match_operand:DI 0 "altivec_register_operand") 6952 (match_operand:DI 1 "xxspltib_constant_split"))] 6953 "TARGET_P9_VECTOR && reload_completed" 6954 [(const_int 0)] 6955{ 6956 rtx op0 = operands[0]; 6957 rtx op1 = operands[1]; 6958 int r = REGNO (op0); 6959 rtx op0_v16qi = gen_rtx_REG (V16QImode, r); 6960 6961 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1)); 6962 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi)); 6963 DONE; 6964}) 6965 6966(define_insn "*mov<mode>_internal2" 6967 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y") 6968 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r") 6969 (const_int 0))) 6970 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))] 6971 "" 6972 "@ 6973 cmp<wd>i %2,%0,0 6974 mr. %0,%1 6975 #" 6976 [(set_attr "type" "cmp,logical,cmp") 6977 (set_attr "dot" "yes") 6978 (set_attr "length" "4,4,8")]) 6979 6980(define_split 6981 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand") 6982 (compare:CC (match_operand:P 1 "gpc_reg_operand") 6983 (const_int 0))) 6984 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))] 6985 "reload_completed" 6986 [(set (match_dup 0) (match_dup 1)) 6987 (set (match_dup 2) 6988 (compare:CC (match_dup 0) 6989 (const_int 0)))] 6990 "") 6991 6992(define_expand "mov<mode>" 6993 [(set (match_operand:INT 0 "general_operand") 6994 (match_operand:INT 1 "any_operand"))] 6995 "" 6996{ 6997 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 6998 DONE; 6999}) 7000 7001;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI 7002;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ 7003;; MTVSRWZ MF%1 MT%1 NOP 7004(define_insn "*mov<mode>_internal" 7005 [(set (match_operand:QHI 0 "nonimmediate_operand" 7006 "=r, r, ?*wJwK, m, Z, r, 7007 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r, 7008 ?*wJwK, r, *c*l, *h") 7009 7010 (match_operand:QHI 1 "input_operand" 7011 "r, m, Z, r, wJwK, i, 7012 wJwK, O, wM, wB, wS, ?*wJwK, 7013 r, *h, r, 0"))] 7014 7015 "gpc_reg_operand (operands[0], <MODE>mode) 7016 || gpc_reg_operand (operands[1], <MODE>mode)" 7017 "@ 7018 mr %0,%1 7019 l<wd>z%U1%X1 %0,%1 7020 lxsi<wd>zx %x0,%y1 7021 st<wd>%U0%X0 %1,%0 7022 stxsi<wd>x %x1,%y0 7023 li %0,%1 7024 xxlor %x0,%x1,%x1 7025 xxspltib %x0,0 7026 xxspltib %x0,255 7027 vspltis<wd> %0,%1 7028 # 7029 mfvsrwz %0,%x1 7030 mtvsrwz %x0,%1 7031 mf%1 %0 7032 mt%0 %1 7033 nop" 7034 [(set_attr "type" 7035 "*, load, fpload, store, fpstore, *, 7036 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr, 7037 mffgpr, mfjmpr, mtjmpr, *") 7038 7039 (set_attr "length" 7040 "4, 4, 4, 4, 4, 4, 7041 4, 4, 4, 4, 8, 4, 7042 4, 4, 4, 4")]) 7043 7044 7045;; Here is how to move condition codes around. When we store CC data in 7046;; an integer register or memory, we store just the high-order 4 bits. 7047;; This lets us not shift in the most common case of CR0. 7048(define_expand "movcc" 7049 [(set (match_operand:CC 0 "nonimmediate_operand") 7050 (match_operand:CC 1 "nonimmediate_operand"))] 7051 "" 7052 "") 7053 7054(define_insn "*movcc_internal1" 7055 [(set (match_operand:CC 0 "nonimmediate_operand" 7056 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m") 7057 (match_operand:CC 1 "general_operand" 7058 " y,r, r,O,x,y,r,I,h, r,m,r"))] 7059 "register_operand (operands[0], CCmode) 7060 || register_operand (operands[1], CCmode)" 7061 "@ 7062 mcrf %0,%1 7063 mtcrf 128,%1 7064 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff 7065 crxor %0,%0,%0 7066 mfcr %0%Q1 7067 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000 7068 mr %0,%1 7069 li %0,%1 7070 mf%1 %0 7071 mt%0 %1 7072 lwz%U1%X1 %0,%1 7073 stw%U0%X0 %1,%0" 7074 [(set (attr "type") 7075 (cond [(eq_attr "alternative" "0,3") 7076 (const_string "cr_logical") 7077 (eq_attr "alternative" "1,2") 7078 (const_string "mtcr") 7079 (eq_attr "alternative" "6,7") 7080 (const_string "integer") 7081 (eq_attr "alternative" "8") 7082 (const_string "mfjmpr") 7083 (eq_attr "alternative" "9") 7084 (const_string "mtjmpr") 7085 (eq_attr "alternative" "10") 7086 (const_string "load") 7087 (eq_attr "alternative" "11") 7088 (const_string "store") 7089 (match_test "TARGET_MFCRF") 7090 (const_string "mfcrf") 7091 ] 7092 (const_string "mfcr"))) 7093 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")]) 7094 7095;; For floating-point, we normally deal with the floating-point registers 7096;; unless -msoft-float is used. The sole exception is that parameter passing 7097;; can produce floating-point values in fixed-point registers. Unless the 7098;; value is a simple constant or already in memory, we deal with this by 7099;; allocating memory and copying the value explicitly via that memory location. 7100 7101;; Move 32-bit binary/decimal floating point 7102(define_expand "mov<mode>" 7103 [(set (match_operand:FMOVE32 0 "nonimmediate_operand") 7104 (match_operand:FMOVE32 1 "any_operand"))] 7105 "<fmove_ok>" 7106{ 7107 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7108 DONE; 7109}) 7110 7111(define_split 7112 [(set (match_operand:FMOVE32 0 "gpc_reg_operand") 7113 (match_operand:FMOVE32 1 "const_double_operand"))] 7114 "reload_completed 7115 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 7116 || (GET_CODE (operands[0]) == SUBREG 7117 && GET_CODE (SUBREG_REG (operands[0])) == REG 7118 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7119 [(set (match_dup 2) (match_dup 3))] 7120{ 7121 long l; 7122 7123 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7124 7125 if (! TARGET_POWERPC64) 7126 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); 7127 else 7128 operands[2] = gen_lowpart (SImode, operands[0]); 7129 7130 operands[3] = gen_int_mode (l, SImode); 7131}) 7132 7133;; Originally, we tried to keep movsf and movsd common, but the differences 7134;; addressing was making it rather difficult to hide with mode attributes. In 7135;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store 7136;; before the VSX stores meant that the register allocator would tend to do a 7137;; direct move to the GPR (which involves conversion from scalar to 7138;; vector/memory formats) to save values in the traditional Altivec registers, 7139;; while SDmode had problems on power6 if the GPR store was not first due to 7140;; the power6 not having an integer store operation. 7141;; 7142;; LWZ LFS LXSSP LXSSPX STFS STXSSP 7143;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP 7144;; MR MT<x> MF<x> NOP 7145 7146(define_insn "movsf_hardfloat" 7147 [(set (match_operand:SF 0 "nonimmediate_operand" 7148 "=!r, f, wb, wu, m, wY, 7149 Z, m, ww, !r, f, ww, 7150 !r, *c*l, !r, *h") 7151 (match_operand:SF 1 "input_operand" 7152 "m, m, wY, Z, f, wb, 7153 wu, r, j, j, f, ww, 7154 r, r, *h, 0"))] 7155 "(register_operand (operands[0], SFmode) 7156 || register_operand (operands[1], SFmode)) 7157 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 7158 && (TARGET_ALLOW_SF_SUBREG 7159 || valid_sf_si_move (operands[0], operands[1], SFmode))" 7160 "@ 7161 lwz%U1%X1 %0,%1 7162 lfs%U1%X1 %0,%1 7163 lxssp %0,%1 7164 lxsspx %x0,%y1 7165 stfs%U0%X0 %1,%0 7166 stxssp %1,%0 7167 stxsspx %x1,%y0 7168 stw%U0%X0 %1,%0 7169 xxlxor %x0,%x0,%x0 7170 li %0,0 7171 fmr %0,%1 7172 xscpsgndp %x0,%x1,%x1 7173 mr %0,%1 7174 mt%0 %1 7175 mf%1 %0 7176 nop" 7177 [(set_attr "type" 7178 "load, fpload, fpload, fpload, fpstore, fpstore, 7179 fpstore, store, veclogical, integer, fpsimple, fpsimple, 7180 *, mtjmpr, mfjmpr, *")]) 7181 7182;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ 7183;; FMR MR MT%0 MF%1 NOP 7184(define_insn "movsd_hardfloat" 7185 [(set (match_operand:SD 0 "nonimmediate_operand" 7186 "=!r, wz, m, Z, ?wh, ?r, 7187 f, !r, *c*l, !r, *h") 7188 (match_operand:SD 1 "input_operand" 7189 "m, Z, r, wx, r, wh, 7190 f, r, r, *h, 0"))] 7191 "(register_operand (operands[0], SDmode) 7192 || register_operand (operands[1], SDmode)) 7193 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT" 7194 "@ 7195 lwz%U1%X1 %0,%1 7196 lfiwzx %0,%y1 7197 stw%U0%X0 %1,%0 7198 stfiwx %1,%y0 7199 mtvsrwz %x0,%1 7200 mfvsrwz %0,%x1 7201 fmr %0,%1 7202 mr %0,%1 7203 mt%0 %1 7204 mf%1 %0 7205 nop" 7206 [(set_attr "type" 7207 "load, fpload, store, fpstore, mffgpr, mftgpr, 7208 fpsimple, *, mtjmpr, mfjmpr, *")]) 7209 7210(define_insn "*mov<mode>_softfloat" 7211 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h") 7212 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))] 7213 "(gpc_reg_operand (operands[0], <MODE>mode) 7214 || gpc_reg_operand (operands[1], <MODE>mode)) 7215 && TARGET_SOFT_FLOAT" 7216 "@ 7217 mr %0,%1 7218 mt%0 %1 7219 mf%1 %0 7220 lwz%U1%X1 %0,%1 7221 stw%U0%X0 %1,%0 7222 li %0,%1 7223 lis %0,%v1 7224 # 7225 # 7226 nop" 7227 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*") 7228 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")]) 7229 7230;; Like movsf, but adjust a SI value to be used in a SF context, i.e. 7231;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0)) 7232;; 7233;; Because SF values are actually stored as DF values within the vector 7234;; registers, we need to convert the value to the vector SF format when 7235;; we need to use the bits in a union or similar cases. We only need 7236;; to do this transformation when the value is a vector register. Loads, 7237;; stores, and transfers within GPRs are assumed to be safe. 7238;; 7239;; This is a more general case of reload_vsx_from_gprsf. That insn must have 7240;; no alternatives, because the call is created as part of secondary_reload, 7241;; and operand #2's register class is used to allocate the temporary register. 7242;; This function is called before reload, and it creates the temporary as 7243;; needed. 7244 7245;; LWZ LFS LXSSP LXSSPX STW STFIWX 7246;; STXSIWX GPR->VSX VSX->GPR GPR->GPR 7247(define_insn_and_split "movsf_from_si" 7248 [(set (match_operand:SF 0 "nonimmediate_operand" 7249 "=!r, f, wb, wu, m, Z, 7250 Z, wy, ?r, !r") 7251 7252 (unspec:SF [(match_operand:SI 1 "input_operand" 7253 "m, m, wY, Z, r, f, 7254 wu, r, wy, r")] 7255 UNSPEC_SF_FROM_SI)) 7256 7257 (clobber (match_scratch:DI 2 7258 "=X, X, X, X, X, X, 7259 X, r, X, X"))] 7260 7261 "TARGET_NO_SF_SUBREG 7262 && (register_operand (operands[0], SFmode) 7263 || register_operand (operands[1], SImode))" 7264 "@ 7265 lwz%U1%X1 %0,%1 7266 lfs%U1%X1 %0,%1 7267 lxssp %0,%1 7268 lxsspx %x0,%y1 7269 stw%U0%X0 %1,%0 7270 stfiwx %1,%y0 7271 stxsiwx %x1,%y0 7272 # 7273 mfvsrwz %0,%x1 7274 mr %0,%1" 7275 7276 "&& reload_completed 7277 && vsx_reg_sfsubreg_ok (operands[0], SFmode) 7278 && int_reg_operand_not_pseudo (operands[1], SImode)" 7279 [(const_int 0)] 7280{ 7281 rtx op0 = operands[0]; 7282 rtx op1 = operands[1]; 7283 rtx op2 = operands[2]; 7284 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1)); 7285 7286 /* Move SF value to upper 32-bits for xscvspdpn. */ 7287 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 7288 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 7289 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 7290 DONE; 7291} 7292 [(set_attr "length" 7293 "4, 4, 4, 4, 4, 4, 7294 4, 12, 4, 4") 7295 (set_attr "type" 7296 "load, fpload, fpload, fpload, store, fpstore, 7297 fpstore, vecfloat, mffgpr, *")]) 7298 7299 7300;; Move 64-bit binary/decimal floating point 7301(define_expand "mov<mode>" 7302 [(set (match_operand:FMOVE64 0 "nonimmediate_operand") 7303 (match_operand:FMOVE64 1 "any_operand"))] 7304 "" 7305{ 7306 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7307 DONE; 7308}) 7309 7310(define_split 7311 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 7312 (match_operand:FMOVE64 1 "const_int_operand"))] 7313 "! TARGET_POWERPC64 && reload_completed 7314 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 7315 || (GET_CODE (operands[0]) == SUBREG 7316 && GET_CODE (SUBREG_REG (operands[0])) == REG 7317 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7318 [(set (match_dup 2) (match_dup 4)) 7319 (set (match_dup 3) (match_dup 1))] 7320{ 7321 int endian = (WORDS_BIG_ENDIAN == 0); 7322 HOST_WIDE_INT value = INTVAL (operands[1]); 7323 7324 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 7325 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 7326 operands[4] = GEN_INT (value >> 32); 7327 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 7328}) 7329 7330(define_split 7331 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 7332 (match_operand:FMOVE64 1 "const_double_operand"))] 7333 "! TARGET_POWERPC64 && reload_completed 7334 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 7335 || (GET_CODE (operands[0]) == SUBREG 7336 && GET_CODE (SUBREG_REG (operands[0])) == REG 7337 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7338 [(set (match_dup 2) (match_dup 4)) 7339 (set (match_dup 3) (match_dup 5))] 7340{ 7341 int endian = (WORDS_BIG_ENDIAN == 0); 7342 long l[2]; 7343 7344 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7345 7346 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 7347 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 7348 operands[4] = gen_int_mode (l[endian], SImode); 7349 operands[5] = gen_int_mode (l[1 - endian], SImode); 7350}) 7351 7352(define_split 7353 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 7354 (match_operand:FMOVE64 1 "const_double_operand"))] 7355 "TARGET_POWERPC64 && reload_completed 7356 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 7357 || (GET_CODE (operands[0]) == SUBREG 7358 && GET_CODE (SUBREG_REG (operands[0])) == REG 7359 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7360 [(set (match_dup 2) (match_dup 3))] 7361{ 7362 int endian = (WORDS_BIG_ENDIAN == 0); 7363 long l[2]; 7364 HOST_WIDE_INT val; 7365 7366 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7367 7368 operands[2] = gen_lowpart (DImode, operands[0]); 7369 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ 7370 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 7371 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); 7372 7373 operands[3] = gen_int_mode (val, DImode); 7374}) 7375 7376;; Don't have reload use general registers to load a constant. It is 7377;; less efficient than loading the constant into an FP register, since 7378;; it will probably be used there. 7379 7380;; The move constraints are ordered to prefer floating point registers before 7381;; general purpose registers to avoid doing a store and a load to get the value 7382;; into a floating point register when it is needed for a floating point 7383;; operation. Prefer traditional floating point registers over VSX registers, 7384;; since the D-form version of the memory instructions does not need a GPR for 7385;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec 7386;; registers. 7387 7388;; If we have FPR registers, rs6000_emit_move has moved all constants to memory, 7389;; except for 0.0 which can be created on VSX with an xor instruction. 7390 7391(define_insn "*mov<mode>_hardfloat32" 7392 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r") 7393 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))] 7394 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 7395 && (gpc_reg_operand (operands[0], <MODE>mode) 7396 || gpc_reg_operand (operands[1], <MODE>mode))" 7397 "@ 7398 stfd%U0%X0 %1,%0 7399 lfd%U1%X1 %0,%1 7400 fmr %0,%1 7401 lxsd %0,%1 7402 stxsd %1,%0 7403 lxsd%U1x %x0,%y1 7404 stxsd%U0x %x1,%y0 7405 xxlor %x0,%x1,%x1 7406 xxlxor %x0,%x0,%x0 7407 # 7408 # 7409 # 7410 #" 7411 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two") 7412 (set_attr "size" "64") 7413 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")]) 7414 7415(define_insn "*mov<mode>_softfloat32" 7416 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r") 7417 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))] 7418 "! TARGET_POWERPC64 7419 && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT) 7420 && (gpc_reg_operand (operands[0], <MODE>mode) 7421 || gpc_reg_operand (operands[1], <MODE>mode))" 7422 "#" 7423 [(set_attr "type" "store,load,two,*,*,*") 7424 (set_attr "length" "8,8,8,8,12,16")]) 7425 7426; ld/std require word-aligned displacements -> 'Y' constraint. 7427; List Y->r and r->Y before r->r for reload. 7428(define_insn "*mov<mode>_hardfloat64" 7429 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,YZ,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>") 7430 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,YZ,r,r,h,0,wg,r,<f64_dm>,r"))] 7431 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 7432 && (gpc_reg_operand (operands[0], <MODE>mode) 7433 || gpc_reg_operand (operands[1], <MODE>mode))" 7434 "@ 7435 stfd%U0%X0 %1,%0 7436 lfd%U1%X1 %0,%1 7437 fmr %0,%1 7438 lxsd %0,%1 7439 stxsd %1,%0 7440 lxsd%U1x %x0,%y1 7441 stxsd%U0x %x1,%y0 7442 xxlor %x0,%x1,%x1 7443 xxlxor %x0,%x0,%x0 7444 li %0,0 7445 std%U0%X0 %1,%0 7446 ld%U1%X1 %0,%1 7447 mr %0,%1 7448 mt%0 %1 7449 mf%1 %0 7450 nop 7451 mftgpr %0,%1 7452 mffgpr %0,%1 7453 mfvsrd %0,%x1 7454 mtvsrd %x0,%1" 7455 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr") 7456 (set_attr "size" "64") 7457 (set_attr "length" "4")]) 7458 7459(define_insn "*mov<mode>_softfloat64" 7460 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h") 7461 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))] 7462 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT 7463 && (gpc_reg_operand (operands[0], <MODE>mode) 7464 || gpc_reg_operand (operands[1], <MODE>mode))" 7465 "@ 7466 std%U0%X0 %1,%0 7467 ld%U1%X1 %0,%1 7468 mr %0,%1 7469 mt%0 %1 7470 mf%1 %0 7471 # 7472 # 7473 # 7474 nop" 7475 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*") 7476 (set_attr "length" "4,4,4,4,4,8,12,16,4")]) 7477 7478(define_expand "mov<mode>" 7479 [(set (match_operand:FMOVE128 0 "general_operand") 7480 (match_operand:FMOVE128 1 "any_operand"))] 7481 "" 7482{ 7483 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7484 DONE; 7485}) 7486 7487;; It's important to list Y->r and r->Y before r->r because otherwise 7488;; reload, given m->r, will try to pick r->r and reload it, which 7489;; doesn't make progress. 7490 7491;; We can't split little endian direct moves of TDmode, because the words are 7492;; not swapped like they are for TImode or TFmode. Subregs therefore are 7493;; problematical. Don't allow direct move for this case. 7494 7495(define_insn_and_split "*mov<mode>_64bit_dm" 7496 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh") 7497 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))] 7498 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode) 7499 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN) 7500 && (gpc_reg_operand (operands[0], <MODE>mode) 7501 || gpc_reg_operand (operands[1], <MODE>mode))" 7502 "#" 7503 "&& reload_completed" 7504 [(pc)] 7505{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 7506 [(set_attr "length" "8,8,8,8,12,12,8,8,8")]) 7507 7508(define_insn_and_split "*movtd_64bit_nodm" 7509 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r") 7510 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))] 7511 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN 7512 && (gpc_reg_operand (operands[0], TDmode) 7513 || gpc_reg_operand (operands[1], TDmode))" 7514 "#" 7515 "&& reload_completed" 7516 [(pc)] 7517{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 7518 [(set_attr "length" "8,8,8,12,12,8")]) 7519 7520(define_insn_and_split "*mov<mode>_32bit" 7521 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r") 7522 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))] 7523 "TARGET_HARD_FLOAT && !TARGET_POWERPC64 7524 && (FLOAT128_2REG_P (<MODE>mode) 7525 || int_reg_operand_not_pseudo (operands[0], <MODE>mode) 7526 || int_reg_operand_not_pseudo (operands[1], <MODE>mode)) 7527 && (gpc_reg_operand (operands[0], <MODE>mode) 7528 || gpc_reg_operand (operands[1], <MODE>mode))" 7529 "#" 7530 "&& reload_completed" 7531 [(pc)] 7532{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 7533 [(set_attr "length" "8,8,8,8,20,20,16")]) 7534 7535(define_insn_and_split "*mov<mode>_softfloat" 7536 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r") 7537 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))] 7538 "TARGET_SOFT_FLOAT 7539 && (gpc_reg_operand (operands[0], <MODE>mode) 7540 || gpc_reg_operand (operands[1], <MODE>mode))" 7541 "#" 7542 "&& reload_completed" 7543 [(pc)] 7544{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 7545 [(set_attr "length" "20,20,16")]) 7546 7547(define_expand "extenddf<mode>2" 7548 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7549 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))] 7550 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7551{ 7552 if (FLOAT128_IEEE_P (<MODE>mode)) 7553 rs6000_expand_float128_convert (operands[0], operands[1], false); 7554 else if (TARGET_VSX) 7555 { 7556 if (<MODE>mode == TFmode) 7557 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1])); 7558 else if (<MODE>mode == IFmode) 7559 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1])); 7560 else 7561 gcc_unreachable (); 7562 } 7563 else 7564 { 7565 rtx zero = gen_reg_rtx (DFmode); 7566 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode); 7567 7568 if (<MODE>mode == TFmode) 7569 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero)); 7570 else if (<MODE>mode == IFmode) 7571 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero)); 7572 else 7573 gcc_unreachable (); 7574 } 7575 DONE; 7576}) 7577 7578;; Allow memory operands for the source to be created by the combiner. 7579(define_insn_and_split "extenddf<mode>2_fprs" 7580 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d") 7581 (float_extend:IBM128 7582 (match_operand:DF 1 "nonimmediate_operand" "d,m,d"))) 7583 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))] 7584 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT 7585 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" 7586 "#" 7587 "&& reload_completed" 7588 [(set (match_dup 3) (match_dup 1)) 7589 (set (match_dup 4) (match_dup 2))] 7590{ 7591 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 7592 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 7593 7594 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 7595 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 7596}) 7597 7598(define_insn_and_split "extenddf<mode>2_vsx" 7599 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d") 7600 (float_extend:IBM128 7601 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))] 7602 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)" 7603 "#" 7604 "&& reload_completed" 7605 [(set (match_dup 2) (match_dup 1)) 7606 (set (match_dup 3) (match_dup 4))] 7607{ 7608 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 7609 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 7610 7611 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 7612 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 7613 operands[4] = CONST0_RTX (DFmode); 7614}) 7615 7616(define_expand "extendsf<mode>2" 7617 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7618 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))] 7619 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7620{ 7621 if (FLOAT128_IEEE_P (<MODE>mode)) 7622 rs6000_expand_float128_convert (operands[0], operands[1], false); 7623 else 7624 { 7625 rtx tmp = gen_reg_rtx (DFmode); 7626 emit_insn (gen_extendsfdf2 (tmp, operands[1])); 7627 emit_insn (gen_extenddf<mode>2 (operands[0], tmp)); 7628 } 7629 DONE; 7630}) 7631 7632(define_expand "trunc<mode>df2" 7633 [(set (match_operand:DF 0 "gpc_reg_operand") 7634 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))] 7635 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7636{ 7637 if (FLOAT128_IEEE_P (<MODE>mode)) 7638 { 7639 rs6000_expand_float128_convert (operands[0], operands[1], false); 7640 DONE; 7641 } 7642}) 7643 7644(define_insn_and_split "trunc<mode>df2_internal1" 7645 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d") 7646 (float_truncate:DF 7647 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))] 7648 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT 7649 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7650 "@ 7651 # 7652 fmr %0,%1" 7653 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 7654 [(const_int 0)] 7655{ 7656 emit_note (NOTE_INSN_DELETED); 7657 DONE; 7658} 7659 [(set_attr "type" "fpsimple")]) 7660 7661(define_insn "trunc<mode>df2_internal2" 7662 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7663 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 7664 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT 7665 && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 7666 "fadd %0,%1,%L1" 7667 [(set_attr "type" "fp") 7668 (set_attr "fp_type" "fp_addsub_d")]) 7669 7670(define_expand "trunc<mode>sf2" 7671 [(set (match_operand:SF 0 "gpc_reg_operand") 7672 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))] 7673 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7674{ 7675 if (FLOAT128_IEEE_P (<MODE>mode)) 7676 rs6000_expand_float128_convert (operands[0], operands[1], false); 7677 else if (<MODE>mode == TFmode) 7678 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1])); 7679 else if (<MODE>mode == IFmode) 7680 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1])); 7681 else 7682 gcc_unreachable (); 7683 DONE; 7684}) 7685 7686(define_insn_and_split "trunc<mode>sf2_fprs" 7687 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 7688 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d"))) 7689 (clobber (match_scratch:DF 2 "=d"))] 7690 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 7691 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" 7692 "#" 7693 "&& reload_completed" 7694 [(set (match_dup 2) 7695 (float_truncate:DF (match_dup 1))) 7696 (set (match_dup 0) 7697 (float_truncate:SF (match_dup 2)))] 7698 "") 7699 7700(define_expand "floatsi<mode>2" 7701 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7702 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand"))) 7703 (clobber (match_scratch:DI 2))])] 7704 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7705{ 7706 rtx op0 = operands[0]; 7707 rtx op1 = operands[1]; 7708 7709 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)) 7710 ; 7711 else if (FLOAT128_IEEE_P (<MODE>mode)) 7712 { 7713 rs6000_expand_float128_convert (op0, op1, false); 7714 DONE; 7715 } 7716 else 7717 { 7718 rtx tmp = gen_reg_rtx (DFmode); 7719 expand_float (tmp, op1, false); 7720 if (<MODE>mode == TFmode) 7721 emit_insn (gen_extenddftf2 (op0, tmp)); 7722 else if (<MODE>mode == IFmode) 7723 emit_insn (gen_extenddfif2 (op0, tmp)); 7724 else 7725 gcc_unreachable (); 7726 DONE; 7727 } 7728}) 7729 7730; fadd, but rounding towards zero. 7731; This is probably not the optimal code sequence. 7732(define_insn "fix_trunc_helper<mode>" 7733 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7734 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")] 7735 UNSPEC_FIX_TRUNC_TF)) 7736 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))] 7737 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)" 7738 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" 7739 [(set_attr "type" "fp") 7740 (set_attr "length" "20")]) 7741 7742(define_expand "fix_trunc<mode>si2" 7743 [(set (match_operand:SI 0 "gpc_reg_operand") 7744 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))] 7745 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7746{ 7747 rtx op0 = operands[0]; 7748 rtx op1 = operands[1]; 7749 7750 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)) 7751 ; 7752 else 7753 { 7754 if (FLOAT128_IEEE_P (<MODE>mode)) 7755 rs6000_expand_float128_convert (op0, op1, false); 7756 else if (<MODE>mode == TFmode) 7757 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1)); 7758 else if (<MODE>mode == IFmode) 7759 emit_insn (gen_fix_truncifsi2_fprs (op0, op1)); 7760 else 7761 gcc_unreachable (); 7762 DONE; 7763 } 7764}) 7765 7766(define_expand "fix_trunc<mode>si2_fprs" 7767 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand") 7768 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand"))) 7769 (clobber (match_dup 2)) 7770 (clobber (match_dup 3)) 7771 (clobber (match_dup 4)) 7772 (clobber (match_dup 5))])] 7773 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7774{ 7775 operands[2] = gen_reg_rtx (DFmode); 7776 operands[3] = gen_reg_rtx (DFmode); 7777 operands[4] = gen_reg_rtx (DImode); 7778 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode)); 7779}) 7780 7781(define_insn_and_split "*fix_trunc<mode>si2_internal" 7782 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 7783 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d"))) 7784 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d")) 7785 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d")) 7786 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d")) 7787 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))] 7788 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7789 "#" 7790 "" 7791 [(pc)] 7792{ 7793 rtx lowword; 7794 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1], 7795 operands[3])); 7796 7797 gcc_assert (MEM_P (operands[5])); 7798 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 7799 7800 emit_insn (gen_fctiwz_df (operands[4], operands[2])); 7801 emit_move_insn (operands[5], operands[4]); 7802 emit_move_insn (operands[0], lowword); 7803 DONE; 7804}) 7805 7806(define_expand "fix_trunc<mode>di2" 7807 [(set (match_operand:DI 0 "gpc_reg_operand") 7808 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))] 7809 "TARGET_FLOAT128_TYPE" 7810{ 7811 if (!TARGET_FLOAT128_HW) 7812 { 7813 rs6000_expand_float128_convert (operands[0], operands[1], false); 7814 DONE; 7815 } 7816}) 7817 7818(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2" 7819 [(set (match_operand:SDI 0 "gpc_reg_operand") 7820 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))] 7821 "TARGET_FLOAT128_TYPE" 7822{ 7823 rs6000_expand_float128_convert (operands[0], operands[1], true); 7824 DONE; 7825}) 7826 7827(define_expand "floatdi<mode>2" 7828 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 7829 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))] 7830 "TARGET_FLOAT128_TYPE" 7831{ 7832 if (!TARGET_FLOAT128_HW) 7833 { 7834 rs6000_expand_float128_convert (operands[0], operands[1], false); 7835 DONE; 7836 } 7837}) 7838 7839(define_expand "floatunsdi<IEEE128:mode>2" 7840 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 7841 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))] 7842 "TARGET_FLOAT128_TYPE" 7843{ 7844 if (!TARGET_FLOAT128_HW) 7845 { 7846 rs6000_expand_float128_convert (operands[0], operands[1], true); 7847 DONE; 7848 } 7849}) 7850 7851(define_expand "floatuns<IEEE128:mode>2" 7852 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 7853 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))] 7854 "TARGET_FLOAT128_TYPE" 7855{ 7856 rtx op0 = operands[0]; 7857 rtx op1 = operands[1]; 7858 7859 if (TARGET_FLOAT128_HW) 7860 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1)); 7861 else 7862 rs6000_expand_float128_convert (op0, op1, true); 7863 DONE; 7864}) 7865 7866(define_expand "neg<mode>2" 7867 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7868 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))] 7869 "FLOAT128_IEEE_P (<MODE>mode) 7870 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" 7871{ 7872 if (FLOAT128_IEEE_P (<MODE>mode)) 7873 { 7874 if (TARGET_FLOAT128_HW) 7875 { 7876 if (<MODE>mode == TFmode) 7877 emit_insn (gen_negtf2_hw (operands[0], operands[1])); 7878 else if (<MODE>mode == KFmode) 7879 emit_insn (gen_negkf2_hw (operands[0], operands[1])); 7880 else 7881 gcc_unreachable (); 7882 } 7883 else if (TARGET_FLOAT128_TYPE) 7884 { 7885 if (<MODE>mode == TFmode) 7886 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1])); 7887 else if (<MODE>mode == KFmode) 7888 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1])); 7889 else 7890 gcc_unreachable (); 7891 } 7892 else 7893 { 7894 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode); 7895 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST, 7896 <MODE>mode, 7897 operands[1], <MODE>mode); 7898 7899 if (target && !rtx_equal_p (target, operands[0])) 7900 emit_move_insn (operands[0], target); 7901 } 7902 DONE; 7903 } 7904}) 7905 7906(define_insn "neg<mode>2_internal" 7907 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d") 7908 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 7909 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)" 7910{ 7911 if (REGNO (operands[0]) == REGNO (operands[1]) + 1) 7912 return "fneg %L0,%L1\;fneg %0,%1"; 7913 else 7914 return "fneg %0,%1\;fneg %L0,%L1"; 7915} 7916 [(set_attr "type" "fpsimple") 7917 (set_attr "length" "8")]) 7918 7919(define_expand "abs<mode>2" 7920 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7921 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))] 7922 "FLOAT128_IEEE_P (<MODE>mode) 7923 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" 7924{ 7925 rtx label; 7926 7927 if (FLOAT128_IEEE_P (<MODE>mode)) 7928 { 7929 if (TARGET_FLOAT128_HW) 7930 { 7931 if (<MODE>mode == TFmode) 7932 emit_insn (gen_abstf2_hw (operands[0], operands[1])); 7933 else if (<MODE>mode == KFmode) 7934 emit_insn (gen_abskf2_hw (operands[0], operands[1])); 7935 else 7936 FAIL; 7937 DONE; 7938 } 7939 else if (TARGET_FLOAT128_TYPE) 7940 { 7941 if (<MODE>mode == TFmode) 7942 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1])); 7943 else if (<MODE>mode == KFmode) 7944 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1])); 7945 else 7946 FAIL; 7947 DONE; 7948 } 7949 else 7950 FAIL; 7951 } 7952 7953 label = gen_label_rtx (); 7954 if (<MODE>mode == TFmode) 7955 emit_insn (gen_abstf2_internal (operands[0], operands[1], label)); 7956 else if (<MODE>mode == IFmode) 7957 emit_insn (gen_absif2_internal (operands[0], operands[1], label)); 7958 else 7959 FAIL; 7960 emit_label (label); 7961 DONE; 7962}) 7963 7964(define_expand "abs<mode>2_internal" 7965 [(set (match_operand:IBM128 0 "gpc_reg_operand") 7966 (match_operand:IBM128 1 "gpc_reg_operand")) 7967 (set (match_dup 3) (match_dup 5)) 7968 (set (match_dup 5) (abs:DF (match_dup 5))) 7969 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5))) 7970 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0)) 7971 (label_ref (match_operand 2 "")) 7972 (pc))) 7973 (set (match_dup 6) (neg:DF (match_dup 6)))] 7974 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 7975{ 7976 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 7977 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 7978 operands[3] = gen_reg_rtx (DFmode); 7979 operands[4] = gen_reg_rtx (CCFPmode); 7980 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 7981 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 7982}) 7983 7984 7985;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector 7986;; register 7987 7988(define_expand "ieee_128bit_negative_zero" 7989 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))] 7990 "TARGET_FLOAT128_TYPE" 7991{ 7992 rtvec v = rtvec_alloc (16); 7993 int i, high; 7994 7995 for (i = 0; i < 16; i++) 7996 RTVEC_ELT (v, i) = const0_rtx; 7997 7998 high = (BYTES_BIG_ENDIAN) ? 0 : 15; 7999 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode); 8000 8001 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v)); 8002 DONE; 8003}) 8004 8005;; IEEE 128-bit negate 8006 8007;; We have 2 insns here for negate and absolute value. The first uses 8008;; match_scratch so that phases like combine can recognize neg/abs as generic 8009;; insns, and second insn after the first split pass loads up the bit to 8010;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of 8011;; neg/abs to create the constant just once. 8012 8013(define_insn_and_split "ieee_128bit_vsx_neg<mode>2" 8014 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8015 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8016 (clobber (match_scratch:V16QI 2 "=v"))] 8017 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8018 "#" 8019 "&& 1" 8020 [(parallel [(set (match_dup 0) 8021 (neg:IEEE128 (match_dup 1))) 8022 (use (match_dup 2))])] 8023{ 8024 if (GET_CODE (operands[2]) == SCRATCH) 8025 operands[2] = gen_reg_rtx (V16QImode); 8026 8027 operands[3] = gen_reg_rtx (V16QImode); 8028 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8029} 8030 [(set_attr "length" "8") 8031 (set_attr "type" "vecsimple")]) 8032 8033(define_insn "*ieee_128bit_vsx_neg<mode>2_internal" 8034 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8035 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8036 (use (match_operand:V16QI 2 "register_operand" "v"))] 8037 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8038 "xxlxor %x0,%x1,%x2" 8039 [(set_attr "type" "veclogical")]) 8040 8041;; IEEE 128-bit absolute value 8042(define_insn_and_split "ieee_128bit_vsx_abs<mode>2" 8043 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8044 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8045 (clobber (match_scratch:V16QI 2 "=v"))] 8046 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 8047 "#" 8048 "&& 1" 8049 [(parallel [(set (match_dup 0) 8050 (abs:IEEE128 (match_dup 1))) 8051 (use (match_dup 2))])] 8052{ 8053 if (GET_CODE (operands[2]) == SCRATCH) 8054 operands[2] = gen_reg_rtx (V16QImode); 8055 8056 operands[3] = gen_reg_rtx (V16QImode); 8057 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8058} 8059 [(set_attr "length" "8") 8060 (set_attr "type" "vecsimple")]) 8061 8062(define_insn "*ieee_128bit_vsx_abs<mode>2_internal" 8063 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8064 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8065 (use (match_operand:V16QI 2 "register_operand" "v"))] 8066 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8067 "xxlandc %x0,%x1,%x2" 8068 [(set_attr "type" "veclogical")]) 8069 8070;; IEEE 128-bit negative absolute value 8071(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2" 8072 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8073 (neg:IEEE128 8074 (abs:IEEE128 8075 (match_operand:IEEE128 1 "register_operand" "wa")))) 8076 (clobber (match_scratch:V16QI 2 "=v"))] 8077 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW 8078 && FLOAT128_IEEE_P (<MODE>mode)" 8079 "#" 8080 "&& 1" 8081 [(parallel [(set (match_dup 0) 8082 (neg:IEEE128 (abs:IEEE128 (match_dup 1)))) 8083 (use (match_dup 2))])] 8084{ 8085 if (GET_CODE (operands[2]) == SCRATCH) 8086 operands[2] = gen_reg_rtx (V16QImode); 8087 8088 operands[3] = gen_reg_rtx (V16QImode); 8089 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8090} 8091 [(set_attr "length" "8") 8092 (set_attr "type" "vecsimple")]) 8093 8094(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal" 8095 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8096 (neg:IEEE128 8097 (abs:IEEE128 8098 (match_operand:IEEE128 1 "register_operand" "wa")))) 8099 (use (match_operand:V16QI 2 "register_operand" "v"))] 8100 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8101 "xxlor %x0,%x1,%x2" 8102 [(set_attr "type" "veclogical")]) 8103 8104;; Float128 conversion functions. These expand to library function calls. 8105;; We use expand to convert from IBM double double to IEEE 128-bit 8106;; and trunc for the opposite. 8107(define_expand "extendiftf2" 8108 [(set (match_operand:TF 0 "gpc_reg_operand") 8109 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))] 8110 "TARGET_FLOAT128_TYPE" 8111{ 8112 rs6000_expand_float128_convert (operands[0], operands[1], false); 8113 DONE; 8114}) 8115 8116(define_expand "extendifkf2" 8117 [(set (match_operand:KF 0 "gpc_reg_operand") 8118 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))] 8119 "TARGET_FLOAT128_TYPE" 8120{ 8121 rs6000_expand_float128_convert (operands[0], operands[1], false); 8122 DONE; 8123}) 8124 8125(define_expand "extendtfkf2" 8126 [(set (match_operand:KF 0 "gpc_reg_operand") 8127 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))] 8128 "TARGET_FLOAT128_TYPE" 8129{ 8130 rs6000_expand_float128_convert (operands[0], operands[1], false); 8131 DONE; 8132}) 8133 8134(define_expand "extendtfif2" 8135 [(set (match_operand:IF 0 "gpc_reg_operand") 8136 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))] 8137 "TARGET_FLOAT128_TYPE" 8138{ 8139 rs6000_expand_float128_convert (operands[0], operands[1], false); 8140 DONE; 8141}) 8142 8143(define_expand "trunciftf2" 8144 [(set (match_operand:TF 0 "gpc_reg_operand") 8145 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))] 8146 "TARGET_FLOAT128_TYPE" 8147{ 8148 rs6000_expand_float128_convert (operands[0], operands[1], false); 8149 DONE; 8150}) 8151 8152(define_expand "truncifkf2" 8153 [(set (match_operand:KF 0 "gpc_reg_operand") 8154 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))] 8155 "TARGET_FLOAT128_TYPE" 8156{ 8157 rs6000_expand_float128_convert (operands[0], operands[1], false); 8158 DONE; 8159}) 8160 8161(define_expand "trunckftf2" 8162 [(set (match_operand:TF 0 "gpc_reg_operand") 8163 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))] 8164 "TARGET_FLOAT128_TYPE" 8165{ 8166 rs6000_expand_float128_convert (operands[0], operands[1], false); 8167 DONE; 8168}) 8169 8170(define_expand "trunctfif2" 8171 [(set (match_operand:IF 0 "gpc_reg_operand") 8172 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))] 8173 "TARGET_FLOAT128_TYPE" 8174{ 8175 rs6000_expand_float128_convert (operands[0], operands[1], false); 8176 DONE; 8177}) 8178 8179(define_insn_and_split "*extend<mode>tf2_internal" 8180 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>") 8181 (float_extend:TF 8182 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))] 8183 "TARGET_FLOAT128_TYPE 8184 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)" 8185 "#" 8186 "&& reload_completed" 8187 [(set (match_dup 0) (match_dup 2))] 8188{ 8189 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1])); 8190}) 8191 8192(define_insn_and_split "*extendtf<mode>2_internal" 8193 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>") 8194 (float_extend:IFKF 8195 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))] 8196 "TARGET_FLOAT128_TYPE 8197 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)" 8198 "#" 8199 "&& reload_completed" 8200 [(set (match_dup 0) (match_dup 2))] 8201{ 8202 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1])); 8203}) 8204 8205 8206;; Reload helper functions used by rs6000_secondary_reload. The patterns all 8207;; must have 3 arguments, and scratch register constraint must be a single 8208;; constraint. 8209 8210;; Reload patterns to support gpr load/store with misaligned mem. 8211;; and multiple gpr load/store at offset >= 0xfffc 8212(define_expand "reload_<mode>_store" 8213 [(parallel [(match_operand 0 "memory_operand" "=m") 8214 (match_operand 1 "gpc_reg_operand" "r") 8215 (match_operand:GPR 2 "register_operand" "=&b")])] 8216 "" 8217{ 8218 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true); 8219 DONE; 8220}) 8221 8222(define_expand "reload_<mode>_load" 8223 [(parallel [(match_operand 0 "gpc_reg_operand" "=r") 8224 (match_operand 1 "memory_operand" "m") 8225 (match_operand:GPR 2 "register_operand" "=b")])] 8226 "" 8227{ 8228 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false); 8229 DONE; 8230}) 8231 8232 8233;; Reload patterns for various types using the vector registers. We may need 8234;; an additional base register to convert the reg+offset addressing to reg+reg 8235;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an 8236;; index register for gpr registers. 8237(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store" 8238 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m") 8239 (match_operand:RELOAD 1 "gpc_reg_operand" "wa") 8240 (match_operand:P 2 "register_operand" "=b")])] 8241 "<P:tptrsize>" 8242{ 8243 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true); 8244 DONE; 8245}) 8246 8247(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load" 8248 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa") 8249 (match_operand:RELOAD 1 "memory_operand" "m") 8250 (match_operand:P 2 "register_operand" "=b")])] 8251 "<P:tptrsize>" 8252{ 8253 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false); 8254 DONE; 8255}) 8256 8257 8258;; Reload sometimes tries to move the address to a GPR, and can generate 8259;; invalid RTL for addresses involving AND -16. Allow addresses involving 8260;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16. 8261 8262(define_insn_and_split "*vec_reload_and_plus_<mptrsize>" 8263 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 8264 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 8265 (match_operand:P 2 "reg_or_cint_operand" "rI")) 8266 (const_int -16)))] 8267 "TARGET_ALTIVEC && reload_completed" 8268 "#" 8269 "&& reload_completed" 8270 [(set (match_dup 0) 8271 (plus:P (match_dup 1) 8272 (match_dup 2))) 8273 (set (match_dup 0) 8274 (and:P (match_dup 0) 8275 (const_int -16)))]) 8276 8277;; Power8 merge instructions to allow direct move to/from floating point 8278;; registers in 32-bit mode. We use TF mode to get two registers to move the 8279;; individual 32-bit parts across. Subreg doesn't work too well on the TF 8280;; value, since it is allocated in reload and not all of the flow information 8281;; is setup for it. We have two patterns to do the two moves between gprs and 8282;; fprs. There isn't a dependancy between the two, but we could potentially 8283;; schedule other instructions between the two instructions. 8284 8285(define_insn "p8_fmrgow_<mode>" 8286 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 8287 (unspec:FMOVE64X [ 8288 (match_operand:DF 1 "register_operand" "d") 8289 (match_operand:DF 2 "register_operand" "d")] 8290 UNSPEC_P8V_FMRGOW))] 8291 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8292 "fmrgow %0,%1,%2" 8293 [(set_attr "type" "fpsimple")]) 8294 8295(define_insn "p8_mtvsrwz" 8296 [(set (match_operand:DF 0 "register_operand" "=d") 8297 (unspec:DF [(match_operand:SI 1 "register_operand" "r")] 8298 UNSPEC_P8V_MTVSRWZ))] 8299 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8300 "mtvsrwz %x0,%1" 8301 [(set_attr "type" "mftgpr")]) 8302 8303(define_insn_and_split "reload_fpr_from_gpr<mode>" 8304 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 8305 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")] 8306 UNSPEC_P8V_RELOAD_FROM_GPR)) 8307 (clobber (match_operand:IF 2 "register_operand" "=d"))] 8308 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8309 "#" 8310 "&& reload_completed" 8311 [(const_int 0)] 8312{ 8313 rtx dest = operands[0]; 8314 rtx src = operands[1]; 8315 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 8316 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 8317 rtx gpr_hi_reg = gen_highpart (SImode, src); 8318 rtx gpr_lo_reg = gen_lowpart (SImode, src); 8319 8320 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg)); 8321 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg)); 8322 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo)); 8323 DONE; 8324} 8325 [(set_attr "length" "12") 8326 (set_attr "type" "three")]) 8327 8328;; Move 128 bit values from GPRs to VSX registers in 64-bit mode 8329(define_insn "p8_mtvsrd_df" 8330 [(set (match_operand:DF 0 "register_operand" "=wa") 8331 (unspec:DF [(match_operand:DI 1 "register_operand" "r")] 8332 UNSPEC_P8V_MTVSRD))] 8333 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8334 "mtvsrd %x0,%1" 8335 [(set_attr "type" "mftgpr")]) 8336 8337(define_insn "p8_xxpermdi_<mode>" 8338 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 8339 (unspec:FMOVE128_GPR [ 8340 (match_operand:DF 1 "register_operand" "wa") 8341 (match_operand:DF 2 "register_operand" "wa")] 8342 UNSPEC_P8V_XXPERMDI))] 8343 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8344 "xxpermdi %x0,%x1,%x2,0" 8345 [(set_attr "type" "vecperm")]) 8346 8347(define_insn_and_split "reload_vsx_from_gpr<mode>" 8348 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 8349 (unspec:FMOVE128_GPR 8350 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")] 8351 UNSPEC_P8V_RELOAD_FROM_GPR)) 8352 (clobber (match_operand:IF 2 "register_operand" "=wa"))] 8353 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8354 "#" 8355 "&& reload_completed" 8356 [(const_int 0)] 8357{ 8358 rtx dest = operands[0]; 8359 rtx src = operands[1]; 8360 /* You might think that we could use op0 as one temp and a DF clobber 8361 as op2, but you'd be wrong. Secondary reload move patterns don't 8362 check for overlap of the clobber and the destination. */ 8363 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 8364 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 8365 rtx gpr_hi_reg = gen_highpart (DImode, src); 8366 rtx gpr_lo_reg = gen_lowpart (DImode, src); 8367 8368 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg)); 8369 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg)); 8370 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo)); 8371 DONE; 8372} 8373 [(set_attr "length" "12") 8374 (set_attr "type" "three")]) 8375 8376(define_split 8377 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand") 8378 (match_operand:FMOVE128_GPR 1 "input_operand"))] 8379 "reload_completed 8380 && (int_reg_operand (operands[0], <MODE>mode) 8381 || int_reg_operand (operands[1], <MODE>mode)) 8382 && (!TARGET_DIRECT_MOVE_128 8383 || (!vsx_register_operand (operands[0], <MODE>mode) 8384 && !vsx_register_operand (operands[1], <MODE>mode)))" 8385 [(pc)] 8386{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) 8387 8388;; Move SFmode to a VSX from a GPR register. Because scalar floating point 8389;; type is stored internally as double precision in the VSX registers, we have 8390;; to convert it from the vector format. 8391(define_insn "p8_mtvsrd_sf" 8392 [(set (match_operand:SF 0 "register_operand" "=wa") 8393 (unspec:SF [(match_operand:DI 1 "register_operand" "r")] 8394 UNSPEC_P8V_MTVSRD))] 8395 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8396 "mtvsrd %x0,%1" 8397 [(set_attr "type" "mftgpr")]) 8398 8399(define_insn_and_split "reload_vsx_from_gprsf" 8400 [(set (match_operand:SF 0 "register_operand" "=wa") 8401 (unspec:SF [(match_operand:SF 1 "register_operand" "r")] 8402 UNSPEC_P8V_RELOAD_FROM_GPR)) 8403 (clobber (match_operand:DI 2 "register_operand" "=r"))] 8404 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8405 "#" 8406 "&& reload_completed" 8407 [(const_int 0)] 8408{ 8409 rtx op0 = operands[0]; 8410 rtx op1 = operands[1]; 8411 rtx op2 = operands[2]; 8412 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0); 8413 8414 /* Move SF value to upper 32-bits for xscvspdpn. */ 8415 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 8416 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 8417 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 8418 DONE; 8419} 8420 [(set_attr "length" "8") 8421 (set_attr "type" "two")]) 8422 8423;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a 8424;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value, 8425;; and then doing a move of that. 8426(define_insn "p8_mfvsrd_3_<mode>" 8427 [(set (match_operand:DF 0 "register_operand" "=r") 8428 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 8429 UNSPEC_P8V_RELOAD_FROM_VSX))] 8430 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8431 "mfvsrd %0,%x1" 8432 [(set_attr "type" "mftgpr")]) 8433 8434(define_insn_and_split "reload_gpr_from_vsx<mode>" 8435 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r") 8436 (unspec:FMOVE128_GPR 8437 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 8438 UNSPEC_P8V_RELOAD_FROM_VSX)) 8439 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))] 8440 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8441 "#" 8442 "&& reload_completed" 8443 [(const_int 0)] 8444{ 8445 rtx dest = operands[0]; 8446 rtx src = operands[1]; 8447 rtx tmp = operands[2]; 8448 rtx gpr_hi_reg = gen_highpart (DFmode, dest); 8449 rtx gpr_lo_reg = gen_lowpart (DFmode, dest); 8450 8451 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src)); 8452 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3))); 8453 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp)); 8454 DONE; 8455} 8456 [(set_attr "length" "12") 8457 (set_attr "type" "three")]) 8458 8459;; Move SFmode to a GPR from a VSX register. Because scalar floating point 8460;; type is stored internally as double precision, we have to convert it to the 8461;; vector format. 8462 8463(define_insn_and_split "reload_gpr_from_vsxsf" 8464 [(set (match_operand:SF 0 "register_operand" "=r") 8465 (unspec:SF [(match_operand:SF 1 "register_operand" "ww")] 8466 UNSPEC_P8V_RELOAD_FROM_VSX)) 8467 (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))] 8468 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8469 "#" 8470 "&& reload_completed" 8471 [(const_int 0)] 8472{ 8473 rtx op0 = operands[0]; 8474 rtx op1 = operands[1]; 8475 rtx op2 = operands[2]; 8476 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0)); 8477 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 8478 8479 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 8480 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si)); 8481 DONE; 8482} 8483 [(set_attr "length" "8") 8484 (set_attr "type" "two")]) 8485 8486 8487;; Next come the multi-word integer load and store and the load and store 8488;; multiple insns. 8489 8490;; List r->r after r->Y, otherwise reload will try to reload a 8491;; non-offsettable address by using r->r which won't make progress. 8492;; Use of fprs is disparaged slightly otherwise reload prefers to reload 8493;; a gpr into a fpr instead of reloading an invalid 'Y' address 8494 8495;; GPR store GPR load GPR move FPR store FPR load FPR move 8496;; GPR const AVX store AVX store AVX load AVX load VSX move 8497;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const 8498;; AVX const 8499 8500(define_insn "*movdi_internal32" 8501 [(set (match_operand:DI 0 "nonimmediate_operand" 8502 "=Y, r, r, m, ^d, ^d, 8503 r, wY, Z, ^wb, $wv, ^wi, 8504 *wo, *wo, *wv, *wi, *wi, *wv, 8505 *wv") 8506 8507 (match_operand:DI 1 "input_operand" 8508 "r, Y, r, ^d, m, ^d, 8509 IJKnGHF, ^wb, $wv, wY, Z, ^wi, 8510 Oj, wM, OjwM, Oj, wM, wS, 8511 wB"))] 8512 8513 "! TARGET_POWERPC64 8514 && (gpc_reg_operand (operands[0], DImode) 8515 || gpc_reg_operand (operands[1], DImode))" 8516 "@ 8517 # 8518 # 8519 # 8520 stfd%U0%X0 %1,%0 8521 lfd%U1%X1 %0,%1 8522 fmr %0,%1 8523 # 8524 stxsd %1,%0 8525 stxsdx %x1,%y0 8526 lxsd %0,%1 8527 lxsdx %x0,%y1 8528 xxlor %x0,%x1,%x1 8529 xxspltib %x0,0 8530 xxspltib %x0,255 8531 vspltisw %0,%1 8532 xxlxor %x0,%x0,%x0 8533 xxlorc %x0,%x0,%x0 8534 # 8535 #" 8536 [(set_attr "type" 8537 "store, load, *, fpstore, fpload, fpsimple, 8538 *, fpstore, fpstore, fpload, fpload, veclogical, 8539 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple, 8540 vecsimple") 8541 (set_attr "size" "64")]) 8542 8543(define_split 8544 [(set (match_operand:DI 0 "gpc_reg_operand") 8545 (match_operand:DI 1 "const_int_operand"))] 8546 "! TARGET_POWERPC64 && reload_completed 8547 && gpr_or_gpr_p (operands[0], operands[1]) 8548 && !direct_move_p (operands[0], operands[1])" 8549 [(set (match_dup 2) (match_dup 4)) 8550 (set (match_dup 3) (match_dup 1))] 8551{ 8552 HOST_WIDE_INT value = INTVAL (operands[1]); 8553 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 8554 DImode); 8555 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 8556 DImode); 8557 operands[4] = GEN_INT (value >> 32); 8558 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 8559}) 8560 8561(define_split 8562 [(set (match_operand:DIFD 0 "nonimmediate_operand") 8563 (match_operand:DIFD 1 "input_operand"))] 8564 "reload_completed && !TARGET_POWERPC64 8565 && gpr_or_gpr_p (operands[0], operands[1]) 8566 && !direct_move_p (operands[0], operands[1])" 8567 [(pc)] 8568{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) 8569 8570;; GPR store GPR load GPR move GPR li GPR lis GPR # 8571;; FPR store FPR load FPR move AVX store AVX store AVX load 8572;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0 8573;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR 8574;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX 8575(define_insn "*movdi_internal64" 8576 [(set (match_operand:DI 0 "nonimmediate_operand" 8577 "=YZ, r, r, r, r, r, 8578 m, ^d, ^d, wY, Z, $wb, 8579 $wv, ^wi, *wo, *wo, *wv, *wi, 8580 *wi, *wv, *wv, r, *h, *h, 8581 ?*r, ?*wg, ?*r, ?*wj") 8582 8583 (match_operand:DI 1 "input_operand" 8584 "r, YZ, r, I, L, nF, 8585 ^d, m, ^d, ^wb, $wv, wY, 8586 Z, ^wi, Oj, wM, OjwM, Oj, 8587 wM, wS, wB, *h, r, 0, 8588 wg, r, wj, r"))] 8589 8590 "TARGET_POWERPC64 8591 && (gpc_reg_operand (operands[0], DImode) 8592 || gpc_reg_operand (operands[1], DImode))" 8593 "@ 8594 std%U0%X0 %1,%0 8595 ld%U1%X1 %0,%1 8596 mr %0,%1 8597 li %0,%1 8598 lis %0,%v1 8599 # 8600 stfd%U0%X0 %1,%0 8601 lfd%U1%X1 %0,%1 8602 fmr %0,%1 8603 stxsd %1,%0 8604 stxsdx %x1,%y0 8605 lxsd %0,%1 8606 lxsdx %x0,%y1 8607 xxlor %x0,%x1,%x1 8608 xxspltib %x0,0 8609 xxspltib %x0,255 8610 # 8611 xxlxor %x0,%x0,%x0 8612 xxlorc %x0,%x0,%x0 8613 # 8614 # 8615 mf%1 %0 8616 mt%0 %1 8617 nop 8618 mftgpr %0,%1 8619 mffgpr %0,%1 8620 mfvsrd %0,%x1 8621 mtvsrd %x0,%1" 8622 [(set_attr "type" 8623 "store, load, *, *, *, *, 8624 fpstore, fpload, fpsimple, fpstore, fpstore, fpload, 8625 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical, 8626 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *, 8627 mftgpr, mffgpr, mftgpr, mffgpr") 8628 8629 (set_attr "size" "64") 8630 (set_attr "length" 8631 "4, 4, 4, 4, 4, 20, 8632 4, 4, 4, 4, 4, 4, 8633 4, 4, 4, 4, 4, 8, 8634 8, 4, 4, 4, 4, 4, 8635 4, 4, 4, 4")]) 8636 8637; Some DImode loads are best done as a load of -1 followed by a mask 8638; instruction. 8639(define_split 8640 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 8641 (match_operand:DI 1 "const_int_operand"))] 8642 "TARGET_POWERPC64 8643 && num_insns_constant (operands[1], DImode) > 1 8644 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff) 8645 && rs6000_is_valid_and_mask (operands[1], DImode)" 8646 [(set (match_dup 0) 8647 (const_int -1)) 8648 (set (match_dup 0) 8649 (and:DI (match_dup 0) 8650 (match_dup 1)))] 8651 "") 8652 8653;; Split a load of a large constant into the appropriate five-instruction 8654;; sequence. Handle anything in a constant number of insns. 8655;; When non-easy constants can go in the TOC, this should use 8656;; easy_fp_constant predicate. 8657(define_split 8658 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 8659 (match_operand:DI 1 "const_int_operand"))] 8660 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 8661 [(set (match_dup 0) (match_dup 2)) 8662 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 8663{ 8664 if (rs6000_emit_set_const (operands[0], operands[1])) 8665 DONE; 8666 else 8667 FAIL; 8668}) 8669 8670(define_split 8671 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 8672 (match_operand:DI 1 "const_scalar_int_operand"))] 8673 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 8674 [(set (match_dup 0) (match_dup 2)) 8675 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 8676{ 8677 if (rs6000_emit_set_const (operands[0], operands[1])) 8678 DONE; 8679 else 8680 FAIL; 8681}) 8682 8683(define_split 8684 [(set (match_operand:DI 0 "altivec_register_operand") 8685 (match_operand:DI 1 "s5bit_cint_operand"))] 8686 "TARGET_VSX && reload_completed" 8687 [(const_int 0)] 8688{ 8689 rtx op0 = operands[0]; 8690 rtx op1 = operands[1]; 8691 int r = REGNO (op0); 8692 rtx op0_v4si = gen_rtx_REG (V4SImode, r); 8693 8694 emit_insn (gen_altivec_vspltisw (op0_v4si, op1)); 8695 if (op1 != const0_rtx && op1 != constm1_rtx) 8696 { 8697 rtx op0_v2di = gen_rtx_REG (V2DImode, r); 8698 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si)); 8699 } 8700 DONE; 8701}) 8702 8703;; Split integer constants that can be loaded with XXSPLTIB and a 8704;; sign extend operation. 8705(define_split 8706 [(set (match_operand:INT_ISA3 0 "altivec_register_operand") 8707 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))] 8708 "TARGET_P9_VECTOR && reload_completed" 8709 [(const_int 0)] 8710{ 8711 rtx op0 = operands[0]; 8712 rtx op1 = operands[1]; 8713 int r = REGNO (op0); 8714 rtx op0_v16qi = gen_rtx_REG (V16QImode, r); 8715 8716 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1)); 8717 if (<MODE>mode == DImode) 8718 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi)); 8719 else if (<MODE>mode == SImode) 8720 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi)); 8721 else if (<MODE>mode == HImode) 8722 { 8723 rtx op0_v8hi = gen_rtx_REG (V8HImode, r); 8724 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi)); 8725 } 8726 DONE; 8727}) 8728 8729 8730;; TImode/PTImode is similar, except that we usually want to compute the 8731;; address into a register and use lsi/stsi (the exception is during reload). 8732 8733(define_insn "*mov<mode>_string" 8734 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r") 8735 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))] 8736 "! TARGET_POWERPC64 8737 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode)) 8738 && (gpc_reg_operand (operands[0], <MODE>mode) 8739 || gpc_reg_operand (operands[1], <MODE>mode))" 8740 "#" 8741 [(set_attr "type" "store,store,load,load,*,*") 8742 (set_attr "update" "yes") 8743 (set_attr "indexed" "yes") 8744 (set_attr "cell_micro" "conditional")]) 8745 8746(define_insn "*mov<mode>_ppc64" 8747 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r") 8748 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))] 8749 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode) 8750 && (gpc_reg_operand (operands[0], <MODE>mode) 8751 || gpc_reg_operand (operands[1], <MODE>mode)))" 8752{ 8753 return rs6000_output_move_128bit (operands); 8754} 8755 [(set_attr "type" "store,store,load,load,*,*") 8756 (set_attr "length" "8")]) 8757 8758(define_split 8759 [(set (match_operand:TI2 0 "int_reg_operand") 8760 (match_operand:TI2 1 "const_scalar_int_operand"))] 8761 "TARGET_POWERPC64 8762 && (VECTOR_MEM_NONE_P (<MODE>mode) 8763 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))" 8764 [(set (match_dup 2) (match_dup 4)) 8765 (set (match_dup 3) (match_dup 5))] 8766{ 8767 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 8768 <MODE>mode); 8769 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 8770 <MODE>mode); 8771 if (CONST_WIDE_INT_P (operands[1])) 8772 { 8773 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1)); 8774 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0)); 8775 } 8776 else if (CONST_INT_P (operands[1])) 8777 { 8778 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); 8779 operands[5] = operands[1]; 8780 } 8781 else 8782 FAIL; 8783}) 8784 8785(define_split 8786 [(set (match_operand:TI2 0 "nonimmediate_operand") 8787 (match_operand:TI2 1 "input_operand"))] 8788 "reload_completed 8789 && gpr_or_gpr_p (operands[0], operands[1]) 8790 && !direct_move_p (operands[0], operands[1]) 8791 && !quad_load_store_p (operands[0], operands[1])" 8792 [(pc)] 8793{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) 8794 8795(define_expand "setmemsi" 8796 [(parallel [(set (match_operand:BLK 0 "") 8797 (match_operand 2 "const_int_operand")) 8798 (use (match_operand:SI 1 "")) 8799 (use (match_operand:SI 3 ""))])] 8800 "" 8801{ 8802 /* If value to set is not zero, use the library routine. */ 8803 if (operands[2] != const0_rtx) 8804 FAIL; 8805 8806 if (expand_block_clear (operands)) 8807 DONE; 8808 else 8809 FAIL; 8810}) 8811 8812;; String compare N insn. 8813;; Argument 0 is the target (result) 8814;; Argument 1 is the destination 8815;; Argument 2 is the source 8816;; Argument 3 is the length 8817;; Argument 4 is the alignment 8818 8819(define_expand "cmpstrnsi" 8820 [(parallel [(set (match_operand:SI 0) 8821 (compare:SI (match_operand:BLK 1) 8822 (match_operand:BLK 2))) 8823 (use (match_operand:SI 3)) 8824 (use (match_operand:SI 4))])] 8825 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)" 8826{ 8827 if (optimize_insn_for_size_p ()) 8828 FAIL; 8829 8830 if (expand_strn_compare (operands, 0)) 8831 DONE; 8832 else 8833 FAIL; 8834}) 8835 8836;; String compare insn. 8837;; Argument 0 is the target (result) 8838;; Argument 1 is the destination 8839;; Argument 2 is the source 8840;; Argument 3 is the alignment 8841 8842(define_expand "cmpstrsi" 8843 [(parallel [(set (match_operand:SI 0) 8844 (compare:SI (match_operand:BLK 1) 8845 (match_operand:BLK 2))) 8846 (use (match_operand:SI 3))])] 8847 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)" 8848{ 8849 if (optimize_insn_for_size_p ()) 8850 FAIL; 8851 8852 if (expand_strn_compare (operands, 1)) 8853 DONE; 8854 else 8855 FAIL; 8856}) 8857 8858;; Block compare insn. 8859;; Argument 0 is the target (result) 8860;; Argument 1 is the destination 8861;; Argument 2 is the source 8862;; Argument 3 is the length 8863;; Argument 4 is the alignment 8864 8865(define_expand "cmpmemsi" 8866 [(parallel [(set (match_operand:SI 0) 8867 (compare:SI (match_operand:BLK 1) 8868 (match_operand:BLK 2))) 8869 (use (match_operand:SI 3)) 8870 (use (match_operand:SI 4))])] 8871 "TARGET_POPCNTD" 8872{ 8873 if (expand_block_compare (operands)) 8874 DONE; 8875 else 8876 FAIL; 8877}) 8878 8879;; String/block move insn. 8880;; Argument 0 is the destination 8881;; Argument 1 is the source 8882;; Argument 2 is the length 8883;; Argument 3 is the alignment 8884 8885(define_expand "movmemsi" 8886 [(parallel [(set (match_operand:BLK 0 "") 8887 (match_operand:BLK 1 "")) 8888 (use (match_operand:SI 2 "")) 8889 (use (match_operand:SI 3 ""))])] 8890 "" 8891{ 8892 if (expand_block_move (operands)) 8893 DONE; 8894 else 8895 FAIL; 8896}) 8897 8898;; Define insns that do load or store with update. Some of these we can 8899;; get by using pre-decrement or pre-increment, but the hardware can also 8900;; do cases where the increment is not the size of the object. 8901;; 8902;; In all these cases, we use operands 0 and 1 for the register being 8903;; incremented because those are the operands that local-alloc will 8904;; tie and these are the pair most likely to be tieable (and the ones 8905;; that will benefit the most). 8906 8907(define_insn "*movdi_update1" 8908 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r") 8909 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") 8910 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))) 8911 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") 8912 (plus:DI (match_dup 1) (match_dup 2)))] 8913 "TARGET_POWERPC64 && TARGET_UPDATE 8914 && (!avoiding_indexed_address_p (DImode) 8915 || !gpc_reg_operand (operands[2], DImode))" 8916 "@ 8917 ldux %3,%0,%2 8918 ldu %3,%2(%0)" 8919 [(set_attr "type" "load") 8920 (set_attr "update" "yes") 8921 (set_attr "indexed" "yes,no")]) 8922 8923(define_insn "movdi_<mode>_update" 8924 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 8925 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) 8926 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 8927 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 8928 (plus:P (match_dup 1) (match_dup 2)))] 8929 "TARGET_POWERPC64 && TARGET_UPDATE 8930 && (!avoiding_indexed_address_p (Pmode) 8931 || !gpc_reg_operand (operands[2], Pmode) 8932 || (REG_P (operands[0]) 8933 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 8934 "@ 8935 stdux %3,%0,%2 8936 stdu %3,%2(%0)" 8937 [(set_attr "type" "store") 8938 (set_attr "update" "yes") 8939 (set_attr "indexed" "yes,no")]) 8940 8941;; This pattern is only conditional on TARGET_POWERPC64, as it is 8942;; needed for stack allocation, even if the user passes -mno-update. 8943(define_insn "movdi_<mode>_update_stack" 8944 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 8945 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) 8946 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 8947 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 8948 (plus:P (match_dup 1) (match_dup 2)))] 8949 "TARGET_POWERPC64" 8950 "@ 8951 stdux %3,%0,%2 8952 stdu %3,%2(%0)" 8953 [(set_attr "type" "store") 8954 (set_attr "update" "yes") 8955 (set_attr "indexed" "yes,no")]) 8956 8957(define_insn "*movsi_update1" 8958 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 8959 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8960 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 8961 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8962 (plus:SI (match_dup 1) (match_dup 2)))] 8963 "TARGET_UPDATE 8964 && (!avoiding_indexed_address_p (SImode) 8965 || !gpc_reg_operand (operands[2], SImode))" 8966 "@ 8967 lwzux %3,%0,%2 8968 lwzu %3,%2(%0)" 8969 [(set_attr "type" "load") 8970 (set_attr "update" "yes") 8971 (set_attr "indexed" "yes,no")]) 8972 8973(define_insn "*movsi_update2" 8974 [(set (match_operand:DI 3 "gpc_reg_operand" "=r") 8975 (sign_extend:DI 8976 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0") 8977 (match_operand:DI 2 "gpc_reg_operand" "r"))))) 8978 (set (match_operand:DI 0 "gpc_reg_operand" "=b") 8979 (plus:DI (match_dup 1) (match_dup 2)))] 8980 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)" 8981 "lwaux %3,%0,%2" 8982 [(set_attr "type" "load") 8983 (set_attr "sign_extend" "yes") 8984 (set_attr "update" "yes") 8985 (set_attr "indexed" "yes")]) 8986 8987(define_insn "movsi_update" 8988 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 8989 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 8990 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 8991 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 8992 (plus:SI (match_dup 1) (match_dup 2)))] 8993 "TARGET_UPDATE 8994 && (!avoiding_indexed_address_p (SImode) 8995 || !gpc_reg_operand (operands[2], SImode) 8996 || (REG_P (operands[0]) 8997 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 8998 "@ 8999 stwux %3,%0,%2 9000 stwu %3,%2(%0)" 9001 [(set_attr "type" "store") 9002 (set_attr "update" "yes") 9003 (set_attr "indexed" "yes,no")]) 9004 9005;; This is an unconditional pattern; needed for stack allocation, even 9006;; if the user passes -mno-update. 9007(define_insn "movsi_update_stack" 9008 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9009 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9010 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 9011 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9012 (plus:SI (match_dup 1) (match_dup 2)))] 9013 "" 9014 "@ 9015 stwux %3,%0,%2 9016 stwu %3,%2(%0)" 9017 [(set_attr "type" "store") 9018 (set_attr "update" "yes") 9019 (set_attr "indexed" "yes,no")]) 9020 9021(define_insn "*movhi_update1" 9022 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r") 9023 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9024 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9025 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9026 (plus:SI (match_dup 1) (match_dup 2)))] 9027 "TARGET_UPDATE 9028 && (!avoiding_indexed_address_p (SImode) 9029 || !gpc_reg_operand (operands[2], SImode))" 9030 "@ 9031 lhzux %3,%0,%2 9032 lhzu %3,%2(%0)" 9033 [(set_attr "type" "load") 9034 (set_attr "update" "yes") 9035 (set_attr "indexed" "yes,no")]) 9036 9037(define_insn "*movhi_update2" 9038 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 9039 (zero_extend:SI 9040 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9041 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) 9042 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9043 (plus:SI (match_dup 1) (match_dup 2)))] 9044 "TARGET_UPDATE 9045 && (!avoiding_indexed_address_p (SImode) 9046 || !gpc_reg_operand (operands[2], SImode))" 9047 "@ 9048 lhzux %3,%0,%2 9049 lhzu %3,%2(%0)" 9050 [(set_attr "type" "load") 9051 (set_attr "update" "yes") 9052 (set_attr "indexed" "yes,no")]) 9053 9054(define_insn "*movhi_update3" 9055 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 9056 (sign_extend:SI 9057 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9058 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) 9059 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9060 (plus:SI (match_dup 1) (match_dup 2)))] 9061 "TARGET_UPDATE 9062 && !(avoiding_indexed_address_p (SImode) 9063 && gpc_reg_operand (operands[2], SImode))" 9064 "@ 9065 lhaux %3,%0,%2 9066 lhau %3,%2(%0)" 9067 [(set_attr "type" "load") 9068 (set_attr "sign_extend" "yes") 9069 (set_attr "update" "yes") 9070 (set_attr "indexed" "yes,no")]) 9071 9072(define_insn "*movhi_update4" 9073 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9074 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9075 (match_operand:HI 3 "gpc_reg_operand" "r,r")) 9076 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9077 (plus:SI (match_dup 1) (match_dup 2)))] 9078 "TARGET_UPDATE 9079 && (!avoiding_indexed_address_p (SImode) 9080 || !gpc_reg_operand (operands[2], SImode))" 9081 "@ 9082 sthux %3,%0,%2 9083 sthu %3,%2(%0)" 9084 [(set_attr "type" "store") 9085 (set_attr "update" "yes") 9086 (set_attr "indexed" "yes,no")]) 9087 9088(define_insn "*movqi_update1" 9089 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r") 9090 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9091 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9092 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9093 (plus:SI (match_dup 1) (match_dup 2)))] 9094 "TARGET_UPDATE 9095 && (!avoiding_indexed_address_p (SImode) 9096 || !gpc_reg_operand (operands[2], SImode))" 9097 "@ 9098 lbzux %3,%0,%2 9099 lbzu %3,%2(%0)" 9100 [(set_attr "type" "load") 9101 (set_attr "update" "yes") 9102 (set_attr "indexed" "yes,no")]) 9103 9104(define_insn "*movqi_update2" 9105 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 9106 (zero_extend:SI 9107 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9108 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) 9109 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9110 (plus:SI (match_dup 1) (match_dup 2)))] 9111 "TARGET_UPDATE 9112 && (!avoiding_indexed_address_p (SImode) 9113 || !gpc_reg_operand (operands[2], SImode))" 9114 "@ 9115 lbzux %3,%0,%2 9116 lbzu %3,%2(%0)" 9117 [(set_attr "type" "load") 9118 (set_attr "update" "yes") 9119 (set_attr "indexed" "yes,no")]) 9120 9121(define_insn "*movqi_update3" 9122 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9123 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9124 (match_operand:QI 3 "gpc_reg_operand" "r,r")) 9125 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9126 (plus:SI (match_dup 1) (match_dup 2)))] 9127 "TARGET_UPDATE 9128 && (!avoiding_indexed_address_p (SImode) 9129 || !gpc_reg_operand (operands[2], SImode))" 9130 "@ 9131 stbux %3,%0,%2 9132 stbu %3,%2(%0)" 9133 [(set_attr "type" "store") 9134 (set_attr "update" "yes") 9135 (set_attr "indexed" "yes,no")]) 9136 9137(define_insn "*movsf_update1" 9138 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f") 9139 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9140 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9141 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9142 (plus:SI (match_dup 1) (match_dup 2)))] 9143 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE 9144 && (!avoiding_indexed_address_p (SImode) 9145 || !gpc_reg_operand (operands[2], SImode))" 9146 "@ 9147 lfsux %3,%0,%2 9148 lfsu %3,%2(%0)" 9149 [(set_attr "type" "fpload") 9150 (set_attr "update" "yes") 9151 (set_attr "indexed" "yes,no")]) 9152 9153(define_insn "*movsf_update2" 9154 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9155 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9156 (match_operand:SF 3 "gpc_reg_operand" "f,f")) 9157 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9158 (plus:SI (match_dup 1) (match_dup 2)))] 9159 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE 9160 && (!avoiding_indexed_address_p (SImode) 9161 || !gpc_reg_operand (operands[2], SImode))" 9162 "@ 9163 stfsux %3,%0,%2 9164 stfsu %3,%2(%0)" 9165 [(set_attr "type" "fpstore") 9166 (set_attr "update" "yes") 9167 (set_attr "indexed" "yes,no")]) 9168 9169(define_insn "*movsf_update3" 9170 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r") 9171 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9172 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9173 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9174 (plus:SI (match_dup 1) (match_dup 2)))] 9175 "TARGET_SOFT_FLOAT && TARGET_UPDATE 9176 && (!avoiding_indexed_address_p (SImode) 9177 || !gpc_reg_operand (operands[2], SImode))" 9178 "@ 9179 lwzux %3,%0,%2 9180 lwzu %3,%2(%0)" 9181 [(set_attr "type" "load") 9182 (set_attr "update" "yes") 9183 (set_attr "indexed" "yes,no")]) 9184 9185(define_insn "*movsf_update4" 9186 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9187 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9188 (match_operand:SF 3 "gpc_reg_operand" "r,r")) 9189 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9190 (plus:SI (match_dup 1) (match_dup 2)))] 9191 "TARGET_SOFT_FLOAT && TARGET_UPDATE 9192 && (!avoiding_indexed_address_p (SImode) 9193 || !gpc_reg_operand (operands[2], SImode))" 9194 "@ 9195 stwux %3,%0,%2 9196 stwu %3,%2(%0)" 9197 [(set_attr "type" "store") 9198 (set_attr "update" "yes") 9199 (set_attr "indexed" "yes,no")]) 9200 9201(define_insn "*movdf_update1" 9202 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d") 9203 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9204 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9205 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9206 (plus:SI (match_dup 1) (match_dup 2)))] 9207 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE 9208 && (!avoiding_indexed_address_p (SImode) 9209 || !gpc_reg_operand (operands[2], SImode))" 9210 "@ 9211 lfdux %3,%0,%2 9212 lfdu %3,%2(%0)" 9213 [(set_attr "type" "fpload") 9214 (set_attr "update" "yes") 9215 (set_attr "indexed" "yes,no") 9216 (set_attr "size" "64")]) 9217 9218(define_insn "*movdf_update2" 9219 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9220 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9221 (match_operand:DF 3 "gpc_reg_operand" "d,d")) 9222 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9223 (plus:SI (match_dup 1) (match_dup 2)))] 9224 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE 9225 && (!avoiding_indexed_address_p (SImode) 9226 || !gpc_reg_operand (operands[2], SImode))" 9227 "@ 9228 stfdux %3,%0,%2 9229 stfdu %3,%2(%0)" 9230 [(set_attr "type" "fpstore") 9231 (set_attr "update" "yes") 9232 (set_attr "indexed" "yes,no")]) 9233 9234 9235;; After inserting conditional returns we can sometimes have 9236;; unnecessary register moves. Unfortunately we cannot have a 9237;; modeless peephole here, because some single SImode sets have early 9238;; clobber outputs. Although those sets expand to multi-ppc-insn 9239;; sequences, using get_attr_length here will smash the operands 9240;; array. Neither is there an early_cobbler_p predicate. 9241;; Also this optimization interferes with scalars going into 9242;; altivec registers (the code does reloading through the FPRs). 9243(define_peephole2 9244 [(set (match_operand:DF 0 "gpc_reg_operand") 9245 (match_operand:DF 1 "any_operand")) 9246 (set (match_operand:DF 2 "gpc_reg_operand") 9247 (match_dup 0))] 9248 "!TARGET_VSX 9249 && peep2_reg_dead_p (2, operands[0])" 9250 [(set (match_dup 2) (match_dup 1))]) 9251 9252(define_peephole2 9253 [(set (match_operand:SF 0 "gpc_reg_operand") 9254 (match_operand:SF 1 "any_operand")) 9255 (set (match_operand:SF 2 "gpc_reg_operand") 9256 (match_dup 0))] 9257 "!TARGET_P8_VECTOR 9258 && peep2_reg_dead_p (2, operands[0])" 9259 [(set (match_dup 2) (match_dup 1))]) 9260 9261 9262;; TLS support. 9263 9264;; Mode attributes for different ABIs. 9265(define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")]) 9266(define_mode_attr tls_abi_suffix [(SI "32") (DI "64")]) 9267(define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")]) 9268(define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")]) 9269 9270(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>" 9271 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9272 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) 9273 (match_operand 4 "" "g"))) 9274 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9275 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9276 UNSPEC_TLSGD) 9277 (clobber (reg:SI LR_REGNO))] 9278 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 9279{ 9280 if (TARGET_CMODEL != CMODEL_SMALL) 9281 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;" 9282 "bl %z3\;nop"; 9283 else 9284 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop"; 9285} 9286 "&& TARGET_TLS_MARKERS" 9287 [(set (match_dup 0) 9288 (unspec:TLSmode [(match_dup 1) 9289 (match_dup 2)] 9290 UNSPEC_TLSGD)) 9291 (parallel [(set (match_dup 0) 9292 (call (mem:TLSmode (match_dup 3)) 9293 (match_dup 4))) 9294 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) 9295 (clobber (reg:SI LR_REGNO))])] 9296 "" 9297 [(set_attr "type" "two") 9298 (set (attr "length") 9299 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9300 (const_int 16) 9301 (const_int 12)))]) 9302 9303(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>" 9304 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9305 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) 9306 (match_operand 4 "" "g"))) 9307 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9308 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9309 UNSPEC_TLSGD) 9310 (clobber (reg:SI LR_REGNO))] 9311 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" 9312{ 9313 if (flag_pic) 9314 { 9315 if (TARGET_SECURE_PLT && flag_pic == 2) 9316 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt"; 9317 else 9318 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt"; 9319 } 9320 else 9321 return "addi %0,%1,%2@got@tlsgd\;bl %z3"; 9322} 9323 "&& TARGET_TLS_MARKERS" 9324 [(set (match_dup 0) 9325 (unspec:TLSmode [(match_dup 1) 9326 (match_dup 2)] 9327 UNSPEC_TLSGD)) 9328 (parallel [(set (match_dup 0) 9329 (call (mem:TLSmode (match_dup 3)) 9330 (match_dup 4))) 9331 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) 9332 (clobber (reg:SI LR_REGNO))])] 9333 "" 9334 [(set_attr "type" "two") 9335 (set_attr "length" "8")]) 9336 9337(define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>" 9338 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9339 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9340 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9341 UNSPEC_TLSGD))] 9342 "HAVE_AS_TLS && TARGET_TLS_MARKERS" 9343 "addi %0,%1,%2@got@tlsgd" 9344 "&& TARGET_CMODEL != CMODEL_SMALL" 9345 [(set (match_dup 3) 9346 (high:TLSmode 9347 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) 9348 (set (match_dup 0) 9349 (lo_sum:TLSmode (match_dup 3) 9350 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))] 9351{ 9352 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9353} 9354 [(set (attr "length") 9355 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9356 (const_int 8) 9357 (const_int 4)))]) 9358 9359(define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>" 9360 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9361 (high:TLSmode 9362 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9363 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9364 UNSPEC_TLSGD)))] 9365 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 9366 "addis %0,%1,%2@got@tlsgd@ha" 9367 [(set_attr "length" "4")]) 9368 9369(define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>" 9370 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9371 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 9372 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") 9373 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9374 UNSPEC_TLSGD)))] 9375 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 9376 "addi %0,%1,%2@got@tlsgd@l" 9377 [(set_attr "length" "4")]) 9378 9379(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>" 9380 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9381 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 9382 (match_operand 2 "" "g"))) 9383 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] 9384 UNSPEC_TLSGD) 9385 (clobber (reg:SI LR_REGNO))] 9386 "HAVE_AS_TLS && TARGET_TLS_MARKERS 9387 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 9388 "bl %z1(%3@tlsgd)\;nop" 9389 [(set_attr "type" "branch") 9390 (set_attr "length" "8")]) 9391 9392(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>" 9393 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9394 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 9395 (match_operand 2 "" "g"))) 9396 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] 9397 UNSPEC_TLSGD) 9398 (clobber (reg:SI LR_REGNO))] 9399 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" 9400{ 9401 if (flag_pic) 9402 { 9403 if (TARGET_SECURE_PLT && flag_pic == 2) 9404 return "bl %z1+32768(%3@tlsgd)@plt"; 9405 return "bl %z1(%3@tlsgd)@plt"; 9406 } 9407 return "bl %z1(%3@tlsgd)"; 9408} 9409 [(set_attr "type" "branch") 9410 (set_attr "length" "4")]) 9411 9412(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>" 9413 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9414 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) 9415 (match_operand 3 "" "g"))) 9416 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 9417 UNSPEC_TLSLD) 9418 (clobber (reg:SI LR_REGNO))] 9419 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 9420{ 9421 if (TARGET_CMODEL != CMODEL_SMALL) 9422 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;" 9423 "bl %z2\;nop"; 9424 else 9425 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop"; 9426} 9427 "&& TARGET_TLS_MARKERS" 9428 [(set (match_dup 0) 9429 (unspec:TLSmode [(match_dup 1)] 9430 UNSPEC_TLSLD)) 9431 (parallel [(set (match_dup 0) 9432 (call (mem:TLSmode (match_dup 2)) 9433 (match_dup 3))) 9434 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 9435 (clobber (reg:SI LR_REGNO))])] 9436 "" 9437 [(set_attr "type" "two") 9438 (set (attr "length") 9439 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9440 (const_int 16) 9441 (const_int 12)))]) 9442 9443(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>" 9444 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9445 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) 9446 (match_operand 3 "" "g"))) 9447 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 9448 UNSPEC_TLSLD) 9449 (clobber (reg:SI LR_REGNO))] 9450 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" 9451{ 9452 if (flag_pic) 9453 { 9454 if (TARGET_SECURE_PLT && flag_pic == 2) 9455 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt"; 9456 else 9457 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt"; 9458 } 9459 else 9460 return "addi %0,%1,%&@got@tlsld\;bl %z2"; 9461} 9462 "&& TARGET_TLS_MARKERS" 9463 [(set (match_dup 0) 9464 (unspec:TLSmode [(match_dup 1)] 9465 UNSPEC_TLSLD)) 9466 (parallel [(set (match_dup 0) 9467 (call (mem:TLSmode (match_dup 2)) 9468 (match_dup 3))) 9469 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 9470 (clobber (reg:SI LR_REGNO))])] 9471 "" 9472 [(set_attr "length" "8")]) 9473 9474(define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>" 9475 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9476 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 9477 UNSPEC_TLSLD))] 9478 "HAVE_AS_TLS && TARGET_TLS_MARKERS" 9479 "addi %0,%1,%&@got@tlsld" 9480 "&& TARGET_CMODEL != CMODEL_SMALL" 9481 [(set (match_dup 2) 9482 (high:TLSmode 9483 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD))) 9484 (set (match_dup 0) 9485 (lo_sum:TLSmode (match_dup 2) 9486 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))] 9487{ 9488 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9489} 9490 [(set (attr "length") 9491 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9492 (const_int 8) 9493 (const_int 4)))]) 9494 9495(define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>" 9496 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9497 (high:TLSmode 9498 (unspec:TLSmode [(const_int 0) 9499 (match_operand:TLSmode 1 "gpc_reg_operand" "b")] 9500 UNSPEC_TLSLD)))] 9501 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 9502 "addis %0,%1,%&@got@tlsld@ha" 9503 [(set_attr "length" "4")]) 9504 9505(define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>" 9506 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9507 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 9508 (unspec:TLSmode [(const_int 0) 9509 (match_operand:TLSmode 2 "gpc_reg_operand" "b")] 9510 UNSPEC_TLSLD)))] 9511 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 9512 "addi %0,%1,%&@got@tlsld@l" 9513 [(set_attr "length" "4")]) 9514 9515(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>" 9516 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9517 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 9518 (match_operand 2 "" "g"))) 9519 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 9520 (clobber (reg:SI LR_REGNO))] 9521 "HAVE_AS_TLS && TARGET_TLS_MARKERS 9522 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 9523 "bl %z1(%&@tlsld)\;nop" 9524 [(set_attr "type" "branch") 9525 (set_attr "length" "8")]) 9526 9527(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>" 9528 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9529 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 9530 (match_operand 2 "" "g"))) 9531 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 9532 (clobber (reg:SI LR_REGNO))] 9533 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" 9534{ 9535 if (flag_pic) 9536 { 9537 if (TARGET_SECURE_PLT && flag_pic == 2) 9538 return "bl %z1+32768(%&@tlsld)@plt"; 9539 return "bl %z1(%&@tlsld)@plt"; 9540 } 9541 return "bl %z1(%&@tlsld)"; 9542} 9543 [(set_attr "type" "branch") 9544 (set_attr "length" "4")]) 9545 9546(define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>" 9547 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9548 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9549 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9550 UNSPEC_TLSDTPREL))] 9551 "HAVE_AS_TLS" 9552 "addi %0,%1,%2@dtprel") 9553 9554(define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>" 9555 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9556 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9557 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9558 UNSPEC_TLSDTPRELHA))] 9559 "HAVE_AS_TLS" 9560 "addis %0,%1,%2@dtprel@ha") 9561 9562(define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>" 9563 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9564 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9565 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9566 UNSPEC_TLSDTPRELLO))] 9567 "HAVE_AS_TLS" 9568 "addi %0,%1,%2@dtprel@l") 9569 9570(define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>" 9571 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9572 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9573 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9574 UNSPEC_TLSGOTDTPREL))] 9575 "HAVE_AS_TLS" 9576 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)" 9577 "&& TARGET_CMODEL != CMODEL_SMALL" 9578 [(set (match_dup 3) 9579 (high:TLSmode 9580 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) 9581 (set (match_dup 0) 9582 (lo_sum:TLSmode (match_dup 3) 9583 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))] 9584{ 9585 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9586} 9587 [(set (attr "length") 9588 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9589 (const_int 8) 9590 (const_int 4)))]) 9591 9592(define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>" 9593 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9594 (high:TLSmode 9595 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9596 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9597 UNSPEC_TLSGOTDTPREL)))] 9598 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9599 "addis %0,%1,%2@got@dtprel@ha" 9600 [(set_attr "length" "4")]) 9601 9602(define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>" 9603 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9604 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 9605 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") 9606 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9607 UNSPEC_TLSGOTDTPREL)))] 9608 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9609 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)" 9610 [(set_attr "length" "4")]) 9611 9612(define_insn "tls_tprel_<TLSmode:tls_abi_suffix>" 9613 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9614 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9615 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9616 UNSPEC_TLSTPREL))] 9617 "HAVE_AS_TLS" 9618 "addi %0,%1,%2@tprel") 9619 9620(define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>" 9621 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9622 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9623 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9624 UNSPEC_TLSTPRELHA))] 9625 "HAVE_AS_TLS" 9626 "addis %0,%1,%2@tprel@ha") 9627 9628(define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>" 9629 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9630 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9631 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9632 UNSPEC_TLSTPRELLO))] 9633 "HAVE_AS_TLS" 9634 "addi %0,%1,%2@tprel@l") 9635 9636;; "b" output constraint here and on tls_tls input to support linker tls 9637;; optimization. The linker may edit the instructions emitted by a 9638;; tls_got_tprel/tls_tls pair to addis,addi. 9639(define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>" 9640 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9641 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9642 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9643 UNSPEC_TLSGOTTPREL))] 9644 "HAVE_AS_TLS" 9645 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)" 9646 "&& TARGET_CMODEL != CMODEL_SMALL" 9647 [(set (match_dup 3) 9648 (high:TLSmode 9649 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) 9650 (set (match_dup 0) 9651 (lo_sum:TLSmode (match_dup 3) 9652 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))] 9653{ 9654 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9655} 9656 [(set (attr "length") 9657 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9658 (const_int 8) 9659 (const_int 4)))]) 9660 9661(define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>" 9662 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9663 (high:TLSmode 9664 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9665 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9666 UNSPEC_TLSGOTTPREL)))] 9667 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9668 "addis %0,%1,%2@got@tprel@ha" 9669 [(set_attr "length" "4")]) 9670 9671(define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>" 9672 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9673 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 9674 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") 9675 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9676 UNSPEC_TLSGOTTPREL)))] 9677 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9678 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)" 9679 [(set_attr "length" "4")]) 9680 9681(define_insn "tls_tls_<TLSmode:tls_abi_suffix>" 9682 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 9683 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9684 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9685 UNSPEC_TLSTLS))] 9686 "TARGET_ELF && HAVE_AS_TLS" 9687 "add %0,%1,%2@tls") 9688 9689(define_expand "tls_get_tpointer" 9690 [(set (match_operand:SI 0 "gpc_reg_operand") 9691 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))] 9692 "TARGET_XCOFF && HAVE_AS_TLS" 9693{ 9694 emit_insn (gen_tls_get_tpointer_internal ()); 9695 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); 9696 DONE; 9697}) 9698 9699(define_insn "tls_get_tpointer_internal" 9700 [(set (reg:SI 3) 9701 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS)) 9702 (clobber (reg:SI LR_REGNO))] 9703 "TARGET_XCOFF && HAVE_AS_TLS" 9704 "bla __get_tpointer") 9705 9706(define_expand "tls_get_addr<mode>" 9707 [(set (match_operand:P 0 "gpc_reg_operand") 9708 (unspec:P [(match_operand:P 1 "gpc_reg_operand") 9709 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))] 9710 "TARGET_XCOFF && HAVE_AS_TLS" 9711{ 9712 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]); 9713 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]); 9714 emit_insn (gen_tls_get_addr_internal<mode> ()); 9715 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3)); 9716 DONE; 9717}) 9718 9719(define_insn "tls_get_addr_internal<mode>" 9720 [(set (reg:P 3) 9721 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS)) 9722 (clobber (reg:P 0)) 9723 (clobber (reg:P 4)) 9724 (clobber (reg:P 5)) 9725 (clobber (reg:P 11)) 9726 (clobber (reg:CC CR0_REGNO)) 9727 (clobber (reg:P LR_REGNO))] 9728 "TARGET_XCOFF && HAVE_AS_TLS" 9729 "bla __tls_get_addr") 9730 9731;; Next come insns related to the calling sequence. 9732;; 9733;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). 9734;; We move the back-chain and decrement the stack pointer. 9735;; 9736;; Operand1 is more naturally reg_or_short_operand. However, for a large 9737;; constant alloca, using that predicate will force the generic code to put 9738;; the constant size into a register before calling the expander. 9739;; 9740;; As a result the expander would not have the constant size information 9741;; in those cases and would have to generate less efficient code. 9742;; 9743;; Thus we allow reg_or_cint_operand instead so that the expander can see 9744;; the constant size. The value is forced into a register if necessary. 9745;; 9746(define_expand "allocate_stack" 9747 [(set (match_operand 0 "gpc_reg_operand") 9748 (minus (reg 1) (match_operand 1 "reg_or_cint_operand"))) 9749 (set (reg 1) 9750 (minus (reg 1) (match_dup 1)))] 9751 "" 9752{ 9753 rtx chain = gen_reg_rtx (Pmode); 9754 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); 9755 rtx neg_op0; 9756 rtx insn, par, set, mem; 9757 9758 /* By allowing reg_or_cint_operand as the predicate we can get 9759 better code for stack-clash-protection because we do not lose 9760 size information. But the rest of the code expects the operand 9761 to be reg_or_short_operand. If it isn't, then force it into 9762 a register. */ 9763 rtx orig_op1 = operands[1]; 9764 if (!reg_or_short_operand (operands[1], Pmode)) 9765 operands[1] = force_reg (Pmode, operands[1]); 9766 9767 emit_move_insn (chain, stack_bot); 9768 9769 /* Check stack bounds if necessary. */ 9770 if (crtl->limit_stack) 9771 { 9772 rtx available; 9773 available = expand_binop (Pmode, sub_optab, 9774 stack_pointer_rtx, stack_limit_rtx, 9775 NULL_RTX, 1, OPTAB_WIDEN); 9776 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx)); 9777 } 9778 9779 /* Allocate and probe if requested. 9780 This may look similar to the loop we use for prologue allocations, 9781 but it is critically different. For the former we know the loop 9782 will iterate, but do not know that generally here. The former 9783 uses that knowledge to rotate the loop. Combining them would be 9784 possible with some performance cost. */ 9785 if (flag_stack_clash_protection) 9786 { 9787 rtx rounded_size, last_addr, residual; 9788 HOST_WIDE_INT probe_interval; 9789 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr, 9790 &residual, &probe_interval, 9791 orig_op1); 9792 9793 /* We do occasionally get in here with constant sizes, we might 9794 as well do a reasonable job when we obviously can. */ 9795 if (rounded_size != const0_rtx) 9796 { 9797 rtx loop_lab, end_loop; 9798 bool rotated = CONST_INT_P (rounded_size); 9799 rtx update = GEN_INT (-probe_interval); 9800 if (probe_interval > 32768) 9801 update = force_reg (Pmode, update); 9802 9803 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop, 9804 last_addr, rotated); 9805 9806 if (Pmode == SImode) 9807 emit_insn (gen_movsi_update_stack (stack_pointer_rtx, 9808 stack_pointer_rtx, 9809 update, chain)); 9810 else 9811 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx, 9812 stack_pointer_rtx, 9813 update, chain)); 9814 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop, 9815 last_addr, rotated); 9816 } 9817 9818 /* Now handle residuals. We just have to set operands[1] correctly 9819 and let the rest of the expander run. */ 9820 operands[1] = residual; 9821 } 9822 9823 if (!(CONST_INT_P (operands[1]) 9824 && IN_RANGE (INTVAL (operands[1]), -32767, 32768))) 9825 { 9826 operands[1] = force_reg (Pmode, operands[1]); 9827 neg_op0 = gen_reg_rtx (Pmode); 9828 if (TARGET_32BIT) 9829 emit_insn (gen_negsi2 (neg_op0, operands[1])); 9830 else 9831 emit_insn (gen_negdi2 (neg_op0, operands[1])); 9832 } 9833 else 9834 neg_op0 = GEN_INT (-INTVAL (operands[1])); 9835 9836 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack 9837 : gen_movdi_di_update_stack)) 9838 (stack_pointer_rtx, stack_pointer_rtx, neg_op0, 9839 chain)); 9840 /* Since we didn't use gen_frame_mem to generate the MEM, grab 9841 it now and set the alias set/attributes. The above gen_*_update 9842 calls will generate a PARALLEL with the MEM set being the first 9843 operation. */ 9844 par = PATTERN (insn); 9845 gcc_assert (GET_CODE (par) == PARALLEL); 9846 set = XVECEXP (par, 0, 0); 9847 gcc_assert (GET_CODE (set) == SET); 9848 mem = SET_DEST (set); 9849 gcc_assert (MEM_P (mem)); 9850 MEM_NOTRAP_P (mem) = 1; 9851 set_mem_alias_set (mem, get_frame_alias_set ()); 9852 9853 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 9854 DONE; 9855}) 9856 9857;; These patterns say how to save and restore the stack pointer. We need not 9858;; save the stack pointer at function level since we are careful to 9859;; preserve the backchain. At block level, we have to restore the backchain 9860;; when we restore the stack pointer. 9861;; 9862;; For nonlocal gotos, we must save both the stack pointer and its 9863;; backchain and restore both. Note that in the nonlocal case, the 9864;; save area is a memory location. 9865 9866(define_expand "save_stack_function" 9867 [(match_operand 0 "any_operand") 9868 (match_operand 1 "any_operand")] 9869 "" 9870 "DONE;") 9871 9872(define_expand "restore_stack_function" 9873 [(match_operand 0 "any_operand") 9874 (match_operand 1 "any_operand")] 9875 "" 9876 "DONE;") 9877 9878;; Adjust stack pointer (op0) to a new value (op1). 9879;; First copy old stack backchain to new location, and ensure that the 9880;; scheduler won't reorder the sp assignment before the backchain write. 9881(define_expand "restore_stack_block" 9882 [(set (match_dup 2) (match_dup 3)) 9883 (set (match_dup 4) (match_dup 2)) 9884 (match_dup 5) 9885 (set (match_operand 0 "register_operand") 9886 (match_operand 1 "register_operand"))] 9887 "" 9888{ 9889 rtvec p; 9890 9891 operands[1] = force_reg (Pmode, operands[1]); 9892 operands[2] = gen_reg_rtx (Pmode); 9893 operands[3] = gen_frame_mem (Pmode, operands[0]); 9894 operands[4] = gen_frame_mem (Pmode, operands[1]); 9895 p = rtvec_alloc (1); 9896 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 9897 const0_rtx); 9898 operands[5] = gen_rtx_PARALLEL (VOIDmode, p); 9899}) 9900 9901(define_expand "save_stack_nonlocal" 9902 [(set (match_dup 3) (match_dup 4)) 9903 (set (match_operand 0 "memory_operand") (match_dup 3)) 9904 (set (match_dup 2) (match_operand 1 "register_operand"))] 9905 "" 9906{ 9907 int units_per_word = (TARGET_32BIT) ? 4 : 8; 9908 9909 /* Copy the backchain to the first word, sp to the second. */ 9910 operands[0] = adjust_address_nv (operands[0], Pmode, 0); 9911 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word); 9912 operands[3] = gen_reg_rtx (Pmode); 9913 operands[4] = gen_frame_mem (Pmode, operands[1]); 9914}) 9915 9916(define_expand "restore_stack_nonlocal" 9917 [(set (match_dup 2) (match_operand 1 "memory_operand")) 9918 (set (match_dup 3) (match_dup 4)) 9919 (set (match_dup 5) (match_dup 2)) 9920 (match_dup 6) 9921 (set (match_operand 0 "register_operand") (match_dup 3))] 9922 "" 9923{ 9924 int units_per_word = (TARGET_32BIT) ? 4 : 8; 9925 rtvec p; 9926 9927 /* Restore the backchain from the first word, sp from the second. */ 9928 operands[2] = gen_reg_rtx (Pmode); 9929 operands[3] = gen_reg_rtx (Pmode); 9930 operands[1] = adjust_address_nv (operands[1], Pmode, 0); 9931 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word); 9932 operands[5] = gen_frame_mem (Pmode, operands[3]); 9933 p = rtvec_alloc (1); 9934 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 9935 const0_rtx); 9936 operands[6] = gen_rtx_PARALLEL (VOIDmode, p); 9937}) 9938 9939;; TOC register handling. 9940 9941;; Code to initialize the TOC register... 9942 9943(define_insn "load_toc_aix_si" 9944 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 9945 (unspec:SI [(const_int 0)] UNSPEC_TOC)) 9946 (use (reg:SI 2))])] 9947 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT" 9948{ 9949 char buf[30]; 9950 extern int need_toc_init; 9951 need_toc_init = 1; 9952 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); 9953 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 9954 operands[2] = gen_rtx_REG (Pmode, 2); 9955 return "lwz %0,%1(%2)"; 9956} 9957 [(set_attr "type" "load") 9958 (set_attr "update" "no") 9959 (set_attr "indexed" "no")]) 9960 9961(define_insn "load_toc_aix_di" 9962 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 9963 (unspec:DI [(const_int 0)] UNSPEC_TOC)) 9964 (use (reg:DI 2))])] 9965 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT" 9966{ 9967 char buf[30]; 9968 extern int need_toc_init; 9969 need_toc_init = 1; 9970 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 9971 !TARGET_ELF || !TARGET_MINIMAL_TOC); 9972 if (TARGET_ELF) 9973 strcat (buf, "@toc"); 9974 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 9975 operands[2] = gen_rtx_REG (Pmode, 2); 9976 return "ld %0,%1(%2)"; 9977} 9978 [(set_attr "type" "load") 9979 (set_attr "update" "no") 9980 (set_attr "indexed" "no")]) 9981 9982(define_insn "load_toc_v4_pic_si" 9983 [(set (reg:SI LR_REGNO) 9984 (unspec:SI [(const_int 0)] UNSPEC_TOC))] 9985 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT" 9986 "bl _GLOBAL_OFFSET_TABLE_@local-4" 9987 [(set_attr "type" "branch") 9988 (set_attr "length" "4")]) 9989 9990(define_expand "load_toc_v4_PIC_1" 9991 [(parallel [(set (reg:SI LR_REGNO) 9992 (match_operand:SI 0 "immediate_operand" "s")) 9993 (use (unspec [(match_dup 0)] UNSPEC_TOC))])] 9994 "TARGET_ELF && DEFAULT_ABI == ABI_V4 9995 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 9996 "") 9997 9998(define_insn "load_toc_v4_PIC_1_normal" 9999 [(set (reg:SI LR_REGNO) 10000 (match_operand:SI 0 "immediate_operand" "s")) 10001 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 10002 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 10003 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10004 "bcl 20,31,%0\n%0:" 10005 [(set_attr "type" "branch") 10006 (set_attr "length" "4") 10007 (set_attr "cannot_copy" "yes")]) 10008 10009(define_insn "load_toc_v4_PIC_1_476" 10010 [(set (reg:SI LR_REGNO) 10011 (match_operand:SI 0 "immediate_operand" "s")) 10012 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 10013 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 10014 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10015{ 10016 char name[32]; 10017 static char templ[32]; 10018 10019 get_ppc476_thunk_name (name); 10020 sprintf (templ, "bl %s\n%%0:", name); 10021 return templ; 10022} 10023 [(set_attr "type" "branch") 10024 (set_attr "length" "4") 10025 (set_attr "cannot_copy" "yes")]) 10026 10027(define_expand "load_toc_v4_PIC_1b" 10028 [(parallel [(set (reg:SI LR_REGNO) 10029 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10030 (label_ref (match_operand 1 ""))] 10031 UNSPEC_TOCPTR)) 10032 (match_dup 1)])] 10033 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10034 "") 10035 10036(define_insn "load_toc_v4_PIC_1b_normal" 10037 [(set (reg:SI LR_REGNO) 10038 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10039 (label_ref (match_operand 1 "" ""))] 10040 UNSPEC_TOCPTR)) 10041 (match_dup 1)] 10042 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10043 "bcl 20,31,$+8\;.long %0-$" 10044 [(set_attr "type" "branch") 10045 (set_attr "length" "8")]) 10046 10047(define_insn "load_toc_v4_PIC_1b_476" 10048 [(set (reg:SI LR_REGNO) 10049 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10050 (label_ref (match_operand 1 "" ""))] 10051 UNSPEC_TOCPTR)) 10052 (match_dup 1)] 10053 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10054{ 10055 char name[32]; 10056 static char templ[32]; 10057 10058 get_ppc476_thunk_name (name); 10059 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name); 10060 return templ; 10061} 10062 [(set_attr "type" "branch") 10063 (set_attr "length" "16")]) 10064 10065(define_insn "load_toc_v4_PIC_2" 10066 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10067 (mem:SI (plus:SI 10068 (match_operand:SI 1 "gpc_reg_operand" "b") 10069 (const 10070 (minus:SI (match_operand:SI 2 "immediate_operand" "s") 10071 (match_operand:SI 3 "immediate_operand" "s"))))))] 10072 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10073 "lwz %0,%2-%3(%1)" 10074 [(set_attr "type" "load")]) 10075 10076(define_insn "load_toc_v4_PIC_3b" 10077 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10078 (plus:SI 10079 (match_operand:SI 1 "gpc_reg_operand" "b") 10080 (high:SI 10081 (const 10082 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 10083 (match_operand:SI 3 "symbol_ref_operand" "s"))))))] 10084 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 10085 "addis %0,%1,%2-%3@ha") 10086 10087(define_insn "load_toc_v4_PIC_3c" 10088 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10089 (lo_sum:SI 10090 (match_operand:SI 1 "gpc_reg_operand" "b") 10091 (const 10092 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 10093 (match_operand:SI 3 "symbol_ref_operand" "s")))))] 10094 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 10095 "addi %0,%1,%2-%3@l") 10096 10097;; If the TOC is shared over a translation unit, as happens with all 10098;; the kinds of PIC that we support, we need to restore the TOC 10099;; pointer only when jumping over units of translation. 10100;; On Darwin, we need to reload the picbase. 10101 10102(define_expand "builtin_setjmp_receiver" 10103 [(use (label_ref (match_operand 0 "")))] 10104 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1) 10105 || (TARGET_TOC && TARGET_MINIMAL_TOC) 10106 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)" 10107{ 10108#if TARGET_MACHO 10109 if (DEFAULT_ABI == ABI_DARWIN) 10110 { 10111 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); 10112 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 10113 rtx tmplabrtx; 10114 char tmplab[20]; 10115 10116 crtl->uses_pic_offset_table = 1; 10117 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR", 10118 CODE_LABEL_NUMBER (operands[0])); 10119 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); 10120 10121 emit_insn (gen_load_macho_picbase (tmplabrtx)); 10122 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); 10123 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx)); 10124 } 10125 else 10126#endif 10127 rs6000_emit_load_toc_table (FALSE); 10128 DONE; 10129}) 10130 10131;; Largetoc support 10132(define_insn "*largetoc_high" 10133 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 10134 (high:DI 10135 (unspec [(match_operand:DI 1 "" "") 10136 (match_operand:DI 2 "gpc_reg_operand" "b")] 10137 UNSPEC_TOCREL)))] 10138 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10139 "addis %0,%2,%1@toc@ha") 10140 10141(define_insn "*largetoc_high_aix<mode>" 10142 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 10143 (high:P 10144 (unspec [(match_operand:P 1 "" "") 10145 (match_operand:P 2 "gpc_reg_operand" "b")] 10146 UNSPEC_TOCREL)))] 10147 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10148 "addis %0,%1@u(%2)") 10149 10150(define_insn "*largetoc_high_plus" 10151 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 10152 (high:DI 10153 (plus:DI 10154 (unspec [(match_operand:DI 1 "" "") 10155 (match_operand:DI 2 "gpc_reg_operand" "b")] 10156 UNSPEC_TOCREL) 10157 (match_operand:DI 3 "add_cint_operand" "n"))))] 10158 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10159 "addis %0,%2,%1+%3@toc@ha") 10160 10161(define_insn "*largetoc_high_plus_aix<mode>" 10162 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 10163 (high:P 10164 (plus:P 10165 (unspec [(match_operand:P 1 "" "") 10166 (match_operand:P 2 "gpc_reg_operand" "b")] 10167 UNSPEC_TOCREL) 10168 (match_operand:P 3 "add_cint_operand" "n"))))] 10169 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10170 "addis %0,%1+%3@u(%2)") 10171 10172(define_insn "*largetoc_low" 10173 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10174 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 10175 (match_operand:DI 2 "" "")))] 10176 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10177 "addi %0,%1,%2@l") 10178 10179(define_insn "*largetoc_low_aix<mode>" 10180 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10181 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 10182 (match_operand:P 2 "" "")))] 10183 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10184 "la %0,%2@l(%1)") 10185 10186(define_insn_and_split "*tocref<mode>" 10187 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10188 (match_operand:P 1 "small_toc_ref" "R"))] 10189 "TARGET_TOC" 10190 "la %0,%a1" 10191 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed" 10192 [(set (match_dup 0) (high:P (match_dup 1))) 10193 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))]) 10194 10195;; Elf specific ways of loading addresses for non-PIC code. 10196;; The output of this could be r0, but we make a very strong 10197;; preference for a base register because it will usually 10198;; be needed there. 10199(define_insn "elf_high" 10200 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") 10201 (high:SI (match_operand 1 "" "")))] 10202 "TARGET_ELF && !TARGET_64BIT && !flag_pic" 10203 "lis %0,%1@ha") 10204 10205(define_insn "elf_low" 10206 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10207 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 10208 (match_operand 2 "" "")))] 10209 "TARGET_ELF && !TARGET_64BIT && !flag_pic" 10210 "la %0,%2@l(%1)") 10211 10212;; Call and call_value insns 10213(define_expand "call" 10214 [(parallel [(call (mem:SI (match_operand 0 "address_operand")) 10215 (match_operand 1 "")) 10216 (use (match_operand 2 "")) 10217 (clobber (reg:SI LR_REGNO))])] 10218 "" 10219{ 10220#if TARGET_MACHO 10221 if (MACHOPIC_INDIRECT) 10222 operands[0] = machopic_indirect_call_target (operands[0]); 10223#endif 10224 10225 gcc_assert (GET_CODE (operands[0]) == MEM); 10226 gcc_assert (GET_CODE (operands[1]) == CONST_INT); 10227 10228 operands[0] = XEXP (operands[0], 0); 10229 10230 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10231 { 10232 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]); 10233 DONE; 10234 } 10235 10236 if (GET_CODE (operands[0]) != SYMBOL_REF 10237 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0)) 10238 { 10239 if (INTVAL (operands[2]) & CALL_LONG) 10240 operands[0] = rs6000_longcall_ref (operands[0]); 10241 10242 switch (DEFAULT_ABI) 10243 { 10244 case ABI_V4: 10245 case ABI_DARWIN: 10246 operands[0] = force_reg (Pmode, operands[0]); 10247 break; 10248 10249 default: 10250 gcc_unreachable (); 10251 } 10252 } 10253}) 10254 10255(define_expand "call_value" 10256 [(parallel [(set (match_operand 0 "") 10257 (call (mem:SI (match_operand 1 "address_operand")) 10258 (match_operand 2 ""))) 10259 (use (match_operand 3 "")) 10260 (clobber (reg:SI LR_REGNO))])] 10261 "" 10262{ 10263#if TARGET_MACHO 10264 if (MACHOPIC_INDIRECT) 10265 operands[1] = machopic_indirect_call_target (operands[1]); 10266#endif 10267 10268 gcc_assert (GET_CODE (operands[1]) == MEM); 10269 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 10270 10271 operands[1] = XEXP (operands[1], 0); 10272 10273 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10274 { 10275 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]); 10276 DONE; 10277 } 10278 10279 if (GET_CODE (operands[1]) != SYMBOL_REF 10280 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0)) 10281 { 10282 if (INTVAL (operands[3]) & CALL_LONG) 10283 operands[1] = rs6000_longcall_ref (operands[1]); 10284 10285 switch (DEFAULT_ABI) 10286 { 10287 case ABI_V4: 10288 case ABI_DARWIN: 10289 operands[1] = force_reg (Pmode, operands[1]); 10290 break; 10291 10292 default: 10293 gcc_unreachable (); 10294 } 10295 } 10296}) 10297 10298;; Call to function in current module. No TOC pointer reload needed. 10299;; Operand2 is nonzero if we are using the V.4 calling sequence and 10300;; either the function was not prototyped, or it was prototyped as a 10301;; variable argument function. It is > 0 if FP registers were passed 10302;; and < 0 if they were not. 10303 10304(define_insn "*call_local32" 10305 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) 10306 (match_operand 1 "" "g,g")) 10307 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10308 (clobber (reg:SI LR_REGNO))] 10309 "(INTVAL (operands[2]) & CALL_LONG) == 0" 10310{ 10311 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10312 output_asm_insn ("crxor 6,6,6", operands); 10313 10314 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10315 output_asm_insn ("creqv 6,6,6", operands); 10316 10317 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0"; 10318} 10319 [(set_attr "type" "branch") 10320 (set_attr "length" "4,8")]) 10321 10322(define_insn "*call_local64" 10323 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) 10324 (match_operand 1 "" "g,g")) 10325 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10326 (clobber (reg:SI LR_REGNO))] 10327 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" 10328{ 10329 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10330 output_asm_insn ("crxor 6,6,6", operands); 10331 10332 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10333 output_asm_insn ("creqv 6,6,6", operands); 10334 10335 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0"; 10336} 10337 [(set_attr "type" "branch") 10338 (set_attr "length" "4,8")]) 10339 10340(define_insn "*call_value_local32" 10341 [(set (match_operand 0 "" "") 10342 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) 10343 (match_operand 2 "" "g,g"))) 10344 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10345 (clobber (reg:SI LR_REGNO))] 10346 "(INTVAL (operands[3]) & CALL_LONG) == 0" 10347{ 10348 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10349 output_asm_insn ("crxor 6,6,6", operands); 10350 10351 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10352 output_asm_insn ("creqv 6,6,6", operands); 10353 10354 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1"; 10355} 10356 [(set_attr "type" "branch") 10357 (set_attr "length" "4,8")]) 10358 10359 10360(define_insn "*call_value_local64" 10361 [(set (match_operand 0 "" "") 10362 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) 10363 (match_operand 2 "" "g,g"))) 10364 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10365 (clobber (reg:SI LR_REGNO))] 10366 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" 10367{ 10368 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10369 output_asm_insn ("crxor 6,6,6", operands); 10370 10371 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10372 output_asm_insn ("creqv 6,6,6", operands); 10373 10374 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1"; 10375} 10376 [(set_attr "type" "branch") 10377 (set_attr "length" "4,8")]) 10378 10379 10380;; A function pointer under System V is just a normal pointer 10381;; operands[0] is the function pointer 10382;; operands[1] is the stack size to clean up 10383;; operands[2] is the value FUNCTION_ARG returns for the VOID argument 10384;; which indicates how to set cr1 10385 10386(define_insn "*call_indirect_nonlocal_sysv<mode>" 10387 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l")) 10388 (match_operand 1 "" "g,g,g,g")) 10389 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) 10390 (clobber (reg:SI LR_REGNO))] 10391 "DEFAULT_ABI == ABI_V4 10392 || DEFAULT_ABI == ABI_DARWIN" 10393{ 10394 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10395 output_asm_insn ("crxor 6,6,6", operands); 10396 10397 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10398 output_asm_insn ("creqv 6,6,6", operands); 10399 10400 if (rs6000_speculate_indirect_jumps 10401 || which_alternative == 1 || which_alternative == 3) 10402 return "b%T0l"; 10403 else 10404 return "crset 2\;beq%T0l-"; 10405} 10406 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") 10407 (set (attr "length") 10408 (cond [(and (eq (symbol_ref "which_alternative") (const_int 0)) 10409 (eq (symbol_ref "rs6000_speculate_indirect_jumps") 10410 (const_int 0))) 10411 (const_string "8") 10412 (and (eq (symbol_ref "which_alternative") (const_int 2)) 10413 (ne (symbol_ref "rs6000_speculate_indirect_jumps") 10414 (const_int 0))) 10415 (const_string "8") 10416 (and (eq (symbol_ref "which_alternative") (const_int 2)) 10417 (eq (symbol_ref "rs6000_speculate_indirect_jumps") 10418 (const_int 0))) 10419 (const_string "12") 10420 (eq (symbol_ref "which_alternative") (const_int 3)) 10421 (const_string "8")] 10422 (const_string "4")))]) 10423 10424(define_insn_and_split "*call_nonlocal_sysv<mode>" 10425 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 10426 (match_operand 1 "" "g,g")) 10427 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10428 (clobber (reg:SI LR_REGNO))] 10429 "(DEFAULT_ABI == ABI_DARWIN 10430 || (DEFAULT_ABI == ABI_V4 10431 && (INTVAL (operands[2]) & CALL_LONG) == 0))" 10432{ 10433 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10434 output_asm_insn ("crxor 6,6,6", operands); 10435 10436 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10437 output_asm_insn ("creqv 6,6,6", operands); 10438 10439#if TARGET_MACHO 10440 return output_call(insn, operands, 0, 2); 10441#else 10442 if (DEFAULT_ABI == ABI_V4 && flag_pic) 10443 { 10444 gcc_assert (!TARGET_SECURE_PLT); 10445 return "bl %z0@plt"; 10446 } 10447 else 10448 return "bl %z0"; 10449#endif 10450} 10451 "DEFAULT_ABI == ABI_V4 10452 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) 10453 && (INTVAL (operands[2]) & CALL_LONG) == 0" 10454 [(parallel [(call (mem:SI (match_dup 0)) 10455 (match_dup 1)) 10456 (use (match_dup 2)) 10457 (use (match_dup 3)) 10458 (clobber (reg:SI LR_REGNO))])] 10459{ 10460 operands[3] = pic_offset_table_rtx; 10461} 10462 [(set_attr "type" "branch,branch") 10463 (set_attr "length" "4,8")]) 10464 10465(define_insn "*call_nonlocal_sysv_secure<mode>" 10466 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 10467 (match_operand 1 "" "g,g")) 10468 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10469 (use (match_operand:SI 3 "register_operand" "r,r")) 10470 (clobber (reg:SI LR_REGNO))] 10471 "(DEFAULT_ABI == ABI_V4 10472 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) 10473 && (INTVAL (operands[2]) & CALL_LONG) == 0)" 10474{ 10475 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10476 output_asm_insn ("crxor 6,6,6", operands); 10477 10478 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10479 output_asm_insn ("creqv 6,6,6", operands); 10480 10481 if (flag_pic == 2) 10482 /* The magic 32768 offset here and in the other sysv call insns 10483 corresponds to the offset of r30 in .got2, as given by LCTOC1. 10484 See sysv4.h:toc_section. */ 10485 return "bl %z0+32768@plt"; 10486 else 10487 return "bl %z0@plt"; 10488} 10489 [(set_attr "type" "branch,branch") 10490 (set_attr "length" "4,8")]) 10491 10492(define_insn "*call_value_indirect_nonlocal_sysv<mode>" 10493 [(set (match_operand 0 "" "") 10494 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l")) 10495 (match_operand 2 "" "g,g,g,g"))) 10496 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) 10497 (clobber (reg:SI LR_REGNO))] 10498 "DEFAULT_ABI == ABI_V4 10499 || DEFAULT_ABI == ABI_DARWIN" 10500{ 10501 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10502 output_asm_insn ("crxor 6,6,6", operands); 10503 10504 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10505 output_asm_insn ("creqv 6,6,6", operands); 10506 10507 if (rs6000_speculate_indirect_jumps 10508 || which_alternative == 1 || which_alternative == 3) 10509 return "b%T1l"; 10510 else 10511 return "crset 2\;beq%T1l-"; 10512} 10513 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") 10514 (set (attr "length") 10515 (cond [(and (eq (symbol_ref "which_alternative") (const_int 0)) 10516 (eq (symbol_ref "rs6000_speculate_indirect_jumps") 10517 (const_int 0))) 10518 (const_string "8") 10519 (and (eq (symbol_ref "which_alternative") (const_int 2)) 10520 (ne (symbol_ref "rs6000_speculate_indirect_jumps") 10521 (const_int 0))) 10522 (const_string "8") 10523 (and (eq (symbol_ref "which_alternative") (const_int 2)) 10524 (eq (symbol_ref "rs6000_speculate_indirect_jumps") 10525 (const_int 0))) 10526 (const_string "12") 10527 (eq (symbol_ref "which_alternative") (const_int 3)) 10528 (const_string "8")] 10529 (const_string "4")))]) 10530 10531(define_insn_and_split "*call_value_nonlocal_sysv<mode>" 10532 [(set (match_operand 0 "" "") 10533 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) 10534 (match_operand 2 "" "g,g"))) 10535 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10536 (clobber (reg:SI LR_REGNO))] 10537 "(DEFAULT_ABI == ABI_DARWIN 10538 || (DEFAULT_ABI == ABI_V4 10539 && (INTVAL (operands[3]) & CALL_LONG) == 0))" 10540{ 10541 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10542 output_asm_insn ("crxor 6,6,6", operands); 10543 10544 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10545 output_asm_insn ("creqv 6,6,6", operands); 10546 10547#if TARGET_MACHO 10548 return output_call(insn, operands, 1, 3); 10549#else 10550 if (DEFAULT_ABI == ABI_V4 && flag_pic) 10551 { 10552 gcc_assert (!TARGET_SECURE_PLT); 10553 return "bl %z1@plt"; 10554 } 10555 else 10556 return "bl %z1"; 10557#endif 10558} 10559 "DEFAULT_ABI == ABI_V4 10560 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) 10561 && (INTVAL (operands[3]) & CALL_LONG) == 0" 10562 [(parallel [(set (match_dup 0) 10563 (call (mem:SI (match_dup 1)) 10564 (match_dup 2))) 10565 (use (match_dup 3)) 10566 (use (match_dup 4)) 10567 (clobber (reg:SI LR_REGNO))])] 10568{ 10569 operands[4] = pic_offset_table_rtx; 10570} 10571 [(set_attr "type" "branch,branch") 10572 (set_attr "length" "4,8")]) 10573 10574(define_insn "*call_value_nonlocal_sysv_secure<mode>" 10575 [(set (match_operand 0 "" "") 10576 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) 10577 (match_operand 2 "" "g,g"))) 10578 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10579 (use (match_operand:SI 4 "register_operand" "r,r")) 10580 (clobber (reg:SI LR_REGNO))] 10581 "(DEFAULT_ABI == ABI_V4 10582 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) 10583 && (INTVAL (operands[3]) & CALL_LONG) == 0)" 10584{ 10585 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10586 output_asm_insn ("crxor 6,6,6", operands); 10587 10588 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10589 output_asm_insn ("creqv 6,6,6", operands); 10590 10591 if (flag_pic == 2) 10592 return "bl %z1+32768@plt"; 10593 else 10594 return "bl %z1@plt"; 10595} 10596 [(set_attr "type" "branch,branch") 10597 (set_attr "length" "4,8")]) 10598 10599 10600;; Call to AIX abi function in the same module. 10601 10602(define_insn "*call_local_aix<mode>" 10603 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s")) 10604 (match_operand 1 "" "g")) 10605 (clobber (reg:P LR_REGNO))] 10606 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10607 "bl %z0" 10608 [(set_attr "type" "branch") 10609 (set_attr "length" "4")]) 10610 10611(define_insn "*call_value_local_aix<mode>" 10612 [(set (match_operand 0 "" "") 10613 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s")) 10614 (match_operand 2 "" "g"))) 10615 (clobber (reg:P LR_REGNO))] 10616 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10617 "bl %z1" 10618 [(set_attr "type" "branch") 10619 (set_attr "length" "4")]) 10620 10621;; Call to AIX abi function which may be in another module. 10622;; Restore the TOC pointer (r2) after the call. 10623 10624(define_insn "*call_nonlocal_aix<mode>" 10625 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s")) 10626 (match_operand 1 "" "g")) 10627 (clobber (reg:P LR_REGNO))] 10628 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10629 "bl %z0\;nop" 10630 [(set_attr "type" "branch") 10631 (set_attr "length" "8")]) 10632 10633(define_insn "*call_value_nonlocal_aix<mode>" 10634 [(set (match_operand 0 "" "") 10635 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 10636 (match_operand 2 "" "g"))) 10637 (clobber (reg:P LR_REGNO))] 10638 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10639 "bl %z1\;nop" 10640 [(set_attr "type" "branch") 10641 (set_attr "length" "8")]) 10642 10643;; Call to indirect functions with the AIX abi using a 3 word descriptor. 10644;; Operand0 is the addresss of the function to call 10645;; Operand2 is the location in the function descriptor to load r2 from 10646;; Operand3 is the offset of the stack location holding the current TOC pointer 10647 10648(define_insn "*call_indirect_aix<mode>" 10649 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) 10650 (match_operand 1 "" "g,g")) 10651 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>")) 10652 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10653 (clobber (reg:P LR_REGNO))] 10654 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps" 10655 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)" 10656 [(set_attr "type" "jmpreg") 10657 (set_attr "length" "12")]) 10658 10659(define_insn "*call_indirect_aix<mode>_nospec" 10660 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) 10661 (match_operand 1 "" "g,g")) 10662 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>")) 10663 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10664 (clobber (reg:P LR_REGNO))] 10665 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps" 10666 "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)" 10667 [(set_attr "type" "jmpreg") 10668 (set_attr "length" "16")]) 10669 10670(define_insn "*call_value_indirect_aix<mode>" 10671 [(set (match_operand 0 "" "") 10672 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) 10673 (match_operand 2 "" "g,g"))) 10674 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) 10675 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10676 (clobber (reg:P LR_REGNO))] 10677 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps" 10678 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)" 10679 [(set_attr "type" "jmpreg") 10680 (set_attr "length" "12")]) 10681 10682(define_insn "*call_value_indirect_aix<mode>_nospec" 10683 [(set (match_operand 0 "" "") 10684 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) 10685 (match_operand 2 "" "g,g"))) 10686 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) 10687 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10688 (clobber (reg:P LR_REGNO))] 10689 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps" 10690 "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)" 10691 [(set_attr "type" "jmpreg") 10692 (set_attr "length" "16")]) 10693 10694;; Call to indirect functions with the ELFv2 ABI. 10695;; Operand0 is the addresss of the function to call 10696;; Operand2 is the offset of the stack location holding the current TOC pointer 10697 10698(define_insn "*call_indirect_elfv2<mode>" 10699 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) 10700 (match_operand 1 "" "g,g")) 10701 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10702 (clobber (reg:P LR_REGNO))] 10703 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps" 10704 "b%T0l\;<ptrload> 2,%2(1)" 10705 [(set_attr "type" "jmpreg") 10706 (set_attr "length" "8")]) 10707 10708;; Variant with deliberate misprediction. 10709(define_insn "*call_indirect_elfv2<mode>_nospec" 10710 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) 10711 (match_operand 1 "" "g,g")) 10712 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10713 (clobber (reg:P LR_REGNO))] 10714 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps" 10715 "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)" 10716 [(set_attr "type" "jmpreg") 10717 (set_attr "length" "12")]) 10718 10719(define_insn "*call_value_indirect_elfv2<mode>" 10720 [(set (match_operand 0 "" "") 10721 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) 10722 (match_operand 2 "" "g,g"))) 10723 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10724 (clobber (reg:P LR_REGNO))] 10725 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps" 10726 "b%T1l\;<ptrload> 2,%3(1)" 10727 [(set_attr "type" "jmpreg") 10728 (set_attr "length" "8")]) 10729 10730; Variant with deliberate misprediction. 10731(define_insn "*call_value_indirect_elfv2<mode>_nospec" 10732 [(set (match_operand 0 "" "") 10733 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) 10734 (match_operand 2 "" "g,g"))) 10735 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 10736 (clobber (reg:P LR_REGNO))] 10737 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps" 10738 "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)" 10739 [(set_attr "type" "jmpreg") 10740 (set_attr "length" "12")]) 10741 10742;; Call subroutine returning any type. 10743(define_expand "untyped_call" 10744 [(parallel [(call (match_operand 0 "") 10745 (const_int 0)) 10746 (match_operand 1 "") 10747 (match_operand 2 "")])] 10748 "" 10749{ 10750 int i; 10751 10752 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); 10753 10754 for (i = 0; i < XVECLEN (operands[2], 0); i++) 10755 { 10756 rtx set = XVECEXP (operands[2], 0, i); 10757 emit_move_insn (SET_DEST (set), SET_SRC (set)); 10758 } 10759 10760 /* The optimizer does not know that the call sets the function value 10761 registers we stored in the result block. We avoid problems by 10762 claiming that all hard registers are used and clobbered at this 10763 point. */ 10764 emit_insn (gen_blockage ()); 10765 10766 DONE; 10767}) 10768 10769;; sibling call patterns 10770(define_expand "sibcall" 10771 [(parallel [(call (mem:SI (match_operand 0 "address_operand")) 10772 (match_operand 1 "")) 10773 (use (match_operand 2 "")) 10774 (simple_return)])] 10775 "" 10776{ 10777#if TARGET_MACHO 10778 if (MACHOPIC_INDIRECT) 10779 operands[0] = machopic_indirect_call_target (operands[0]); 10780#endif 10781 10782 gcc_assert (GET_CODE (operands[0]) == MEM); 10783 gcc_assert (GET_CODE (operands[1]) == CONST_INT); 10784 10785 operands[0] = XEXP (operands[0], 0); 10786 10787 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10788 { 10789 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); 10790 DONE; 10791 } 10792}) 10793 10794(define_expand "sibcall_value" 10795 [(parallel [(set (match_operand 0 "register_operand") 10796 (call (mem:SI (match_operand 1 "address_operand")) 10797 (match_operand 2 ""))) 10798 (use (match_operand 3 "")) 10799 (simple_return)])] 10800 "" 10801{ 10802#if TARGET_MACHO 10803 if (MACHOPIC_INDIRECT) 10804 operands[1] = machopic_indirect_call_target (operands[1]); 10805#endif 10806 10807 gcc_assert (GET_CODE (operands[1]) == MEM); 10808 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 10809 10810 operands[1] = XEXP (operands[1], 0); 10811 10812 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10813 { 10814 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]); 10815 DONE; 10816 } 10817}) 10818 10819(define_insn "*sibcall_local32" 10820 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) 10821 (match_operand 1 "" "g,g")) 10822 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10823 (simple_return)] 10824 "(INTVAL (operands[2]) & CALL_LONG) == 0" 10825{ 10826 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10827 output_asm_insn ("crxor 6,6,6", operands); 10828 10829 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10830 output_asm_insn ("creqv 6,6,6", operands); 10831 10832 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0"; 10833} 10834 [(set_attr "type" "branch") 10835 (set_attr "length" "4,8")]) 10836 10837(define_insn "*sibcall_local64" 10838 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) 10839 (match_operand 1 "" "g,g")) 10840 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10841 (simple_return)] 10842 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" 10843{ 10844 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10845 output_asm_insn ("crxor 6,6,6", operands); 10846 10847 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10848 output_asm_insn ("creqv 6,6,6", operands); 10849 10850 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0"; 10851} 10852 [(set_attr "type" "branch") 10853 (set_attr "length" "4,8")]) 10854 10855(define_insn "*sibcall_value_local32" 10856 [(set (match_operand 0 "" "") 10857 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) 10858 (match_operand 2 "" "g,g"))) 10859 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10860 (simple_return)] 10861 "(INTVAL (operands[3]) & CALL_LONG) == 0" 10862{ 10863 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10864 output_asm_insn ("crxor 6,6,6", operands); 10865 10866 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10867 output_asm_insn ("creqv 6,6,6", operands); 10868 10869 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1"; 10870} 10871 [(set_attr "type" "branch") 10872 (set_attr "length" "4,8")]) 10873 10874(define_insn "*sibcall_value_local64" 10875 [(set (match_operand 0 "" "") 10876 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) 10877 (match_operand 2 "" "g,g"))) 10878 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10879 (simple_return)] 10880 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" 10881{ 10882 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10883 output_asm_insn ("crxor 6,6,6", operands); 10884 10885 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10886 output_asm_insn ("creqv 6,6,6", operands); 10887 10888 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1"; 10889} 10890 [(set_attr "type" "branch") 10891 (set_attr "length" "4,8")]) 10892 10893(define_insn "*sibcall_nonlocal_sysv<mode>" 10894 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c")) 10895 (match_operand 1 "" "")) 10896 (use (match_operand 2 "immediate_operand" "O,n,O,n")) 10897 (simple_return)] 10898 "(DEFAULT_ABI == ABI_DARWIN 10899 || DEFAULT_ABI == ABI_V4) 10900 && (INTVAL (operands[2]) & CALL_LONG) == 0" 10901{ 10902 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10903 output_asm_insn ("crxor 6,6,6", operands); 10904 10905 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10906 output_asm_insn ("creqv 6,6,6", operands); 10907 10908 if (which_alternative >= 2) 10909 { 10910 if (rs6000_speculate_indirect_jumps) 10911 return "b%T0"; 10912 else 10913 /* Can use CR0 since it is volatile across sibcalls. */ 10914 return "crset 2\;beq%T0-\;b $"; 10915 } 10916 else if (DEFAULT_ABI == ABI_V4 && flag_pic) 10917 { 10918 gcc_assert (!TARGET_SECURE_PLT); 10919 return "b %z0@plt"; 10920 } 10921 else 10922 return "b %z0"; 10923} 10924 [(set_attr "type" "branch") 10925 (set (attr "length") 10926 (cond [(eq (symbol_ref "which_alternative") (const_int 1)) 10927 (const_string "8") 10928 (and (eq (symbol_ref "which_alternative") (const_int 2)) 10929 (eq (symbol_ref "rs6000_speculate_indirect_jumps") 10930 (const_int 0))) 10931 (const_string "12") 10932 (and (eq (symbol_ref "which_alternative") (const_int 3)) 10933 (ne (symbol_ref "rs6000_speculate_indirect_jumps") 10934 (const_int 0))) 10935 (const_string "8") 10936 (and (eq (symbol_ref "which_alternative") (const_int 3)) 10937 (eq (symbol_ref "rs6000_speculate_indirect_jumps") 10938 (const_int 0))) 10939 (const_string "16")] 10940 (const_string "4")))]) 10941 10942(define_insn "*sibcall_value_nonlocal_sysv<mode>" 10943 [(set (match_operand 0 "" "") 10944 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c")) 10945 (match_operand 2 "" ""))) 10946 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) 10947 (simple_return)] 10948 "(DEFAULT_ABI == ABI_DARWIN 10949 || DEFAULT_ABI == ABI_V4) 10950 && (INTVAL (operands[3]) & CALL_LONG) == 0" 10951{ 10952 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10953 output_asm_insn ("crxor 6,6,6", operands); 10954 10955 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10956 output_asm_insn ("creqv 6,6,6", operands); 10957 10958 if (which_alternative >= 2) 10959 { 10960 if (rs6000_speculate_indirect_jumps) 10961 return "b%T1"; 10962 else 10963 /* Can use CR0 since it is volatile across sibcalls. */ 10964 return "crset 2\;beq%T1-\;b $"; 10965 } 10966 else if (DEFAULT_ABI == ABI_V4 && flag_pic) 10967 { 10968 gcc_assert (!TARGET_SECURE_PLT); 10969 return "b %z1@plt"; 10970 } 10971 else 10972 return "b %z1"; 10973} 10974 [(set_attr "type" "branch") 10975 (set (attr "length") 10976 (cond [(eq (symbol_ref "which_alternative") (const_int 1)) 10977 (const_string "8") 10978 (and (eq (symbol_ref "which_alternative") (const_int 2)) 10979 (eq (symbol_ref "rs6000_speculate_indirect_jumps") 10980 (const_int 0))) 10981 (const_string "12") 10982 (and (eq (symbol_ref "which_alternative") (const_int 3)) 10983 (ne (symbol_ref "rs6000_speculate_indirect_jumps") 10984 (const_int 0))) 10985 (const_string "8") 10986 (and (eq (symbol_ref "which_alternative") (const_int 3)) 10987 (eq (symbol_ref "rs6000_speculate_indirect_jumps") 10988 (const_int 0))) 10989 (const_string "16")] 10990 (const_string "4")))]) 10991 10992;; AIX ABI sibling call patterns. 10993 10994(define_insn "*sibcall_aix<mode>" 10995 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) 10996 (match_operand 1 "" "g,g")) 10997 (simple_return)] 10998 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 10999 "@ 11000 b %z0 11001 b%T0" 11002 [(set_attr "type" "branch") 11003 (set_attr "length" "4")]) 11004 11005(define_insn "*sibcall_value_aix<mode>" 11006 [(set (match_operand 0 "" "") 11007 (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) 11008 (match_operand 2 "" "g,g"))) 11009 (simple_return)] 11010 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11011 "@ 11012 b %z1 11013 b%T1" 11014 [(set_attr "type" "branch") 11015 (set_attr "length" "4")]) 11016 11017(define_expand "sibcall_epilogue" 11018 [(use (const_int 0))] 11019 "" 11020{ 11021 if (!TARGET_SCHED_PROLOG) 11022 emit_insn (gen_blockage ()); 11023 rs6000_emit_epilogue (TRUE); 11024 DONE; 11025}) 11026 11027;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 11028;; all of memory. This blocks insns from being moved across this point. 11029 11030(define_insn "blockage" 11031 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] 11032 "" 11033 "" 11034 [(set_attr "length" "0")]) 11035 11036(define_expand "probe_stack_address" 11037 [(use (match_operand 0 "address_operand"))] 11038 "" 11039{ 11040 operands[0] = gen_rtx_MEM (Pmode, operands[0]); 11041 MEM_VOLATILE_P (operands[0]) = 1; 11042 11043 if (TARGET_64BIT) 11044 emit_insn (gen_probe_stack_di (operands[0])); 11045 else 11046 emit_insn (gen_probe_stack_si (operands[0])); 11047 DONE; 11048}) 11049 11050(define_insn "probe_stack_<mode>" 11051 [(set (match_operand:P 0 "memory_operand" "=m") 11052 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))] 11053 "" 11054{ 11055 operands[1] = gen_rtx_REG (Pmode, 0); 11056 return "st<wd>%U0%X0 %1,%0"; 11057} 11058 [(set_attr "type" "store") 11059 (set (attr "update") 11060 (if_then_else (match_operand 0 "update_address_mem") 11061 (const_string "yes") 11062 (const_string "no"))) 11063 (set (attr "indexed") 11064 (if_then_else (match_operand 0 "indexed_address_mem") 11065 (const_string "yes") 11066 (const_string "no"))) 11067 (set_attr "length" "4")]) 11068 11069(define_insn "probe_stack_range<P:mode>" 11070 [(set (match_operand:P 0 "register_operand" "=&r") 11071 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 11072 (match_operand:P 2 "register_operand" "r") 11073 (match_operand:P 3 "register_operand" "r")] 11074 UNSPECV_PROBE_STACK_RANGE))] 11075 "" 11076 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);" 11077 [(set_attr "type" "three")]) 11078 11079;; Compare insns are next. Note that the RS/6000 has two types of compares, 11080;; signed & unsigned, and one type of branch. 11081;; 11082;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc 11083;; insns, and branches. 11084 11085(define_expand "cbranch<mode>4" 11086 [(use (match_operator 0 "comparison_operator" 11087 [(match_operand:GPR 1 "gpc_reg_operand") 11088 (match_operand:GPR 2 "reg_or_short_operand")])) 11089 (use (match_operand 3))] 11090 "" 11091{ 11092 /* Take care of the possibility that operands[2] might be negative but 11093 this might be a logical operation. That insn doesn't exist. */ 11094 if (GET_CODE (operands[2]) == CONST_INT 11095 && INTVAL (operands[2]) < 0) 11096 { 11097 operands[2] = force_reg (<MODE>mode, operands[2]); 11098 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]), 11099 GET_MODE (operands[0]), 11100 operands[1], operands[2]); 11101 } 11102 11103 rs6000_emit_cbranch (<MODE>mode, operands); 11104 DONE; 11105}) 11106 11107(define_expand "cbranch<mode>4" 11108 [(use (match_operator 0 "comparison_operator" 11109 [(match_operand:FP 1 "gpc_reg_operand") 11110 (match_operand:FP 2 "gpc_reg_operand")])) 11111 (use (match_operand 3))] 11112 "" 11113{ 11114 rs6000_emit_cbranch (<MODE>mode, operands); 11115 DONE; 11116}) 11117 11118(define_expand "cstore<mode>4_signed" 11119 [(use (match_operator 1 "signed_comparison_operator" 11120 [(match_operand:P 2 "gpc_reg_operand") 11121 (match_operand:P 3 "gpc_reg_operand")])) 11122 (clobber (match_operand:P 0 "gpc_reg_operand"))] 11123 "" 11124{ 11125 enum rtx_code cond_code = GET_CODE (operands[1]); 11126 11127 rtx op0 = operands[0]; 11128 rtx op1 = operands[2]; 11129 rtx op2 = operands[3]; 11130 11131 if (cond_code == GE || cond_code == LT) 11132 { 11133 cond_code = swap_condition (cond_code); 11134 std::swap (op1, op2); 11135 } 11136 11137 rtx tmp1 = gen_reg_rtx (<MODE>mode); 11138 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11139 rtx tmp3 = gen_reg_rtx (<MODE>mode); 11140 11141 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11142 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh))); 11143 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh))); 11144 11145 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2)); 11146 11147 if (cond_code == LE) 11148 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2)); 11149 else 11150 { 11151 rtx tmp4 = gen_reg_rtx (<MODE>mode); 11152 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2)); 11153 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx)); 11154 } 11155 11156 DONE; 11157}) 11158 11159(define_expand "cstore<mode>4_unsigned" 11160 [(use (match_operator 1 "unsigned_comparison_operator" 11161 [(match_operand:P 2 "gpc_reg_operand") 11162 (match_operand:P 3 "reg_or_short_operand")])) 11163 (clobber (match_operand:P 0 "gpc_reg_operand"))] 11164 "" 11165{ 11166 enum rtx_code cond_code = GET_CODE (operands[1]); 11167 11168 rtx op0 = operands[0]; 11169 rtx op1 = operands[2]; 11170 rtx op2 = operands[3]; 11171 11172 if (cond_code == GEU || cond_code == LTU) 11173 { 11174 cond_code = swap_condition (cond_code); 11175 std::swap (op1, op2); 11176 } 11177 11178 if (!gpc_reg_operand (op1, <MODE>mode)) 11179 op1 = force_reg (<MODE>mode, op1); 11180 if (!reg_or_short_operand (op2, <MODE>mode)) 11181 op2 = force_reg (<MODE>mode, op2); 11182 11183 rtx tmp = gen_reg_rtx (<MODE>mode); 11184 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11185 11186 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2)); 11187 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2)); 11188 11189 if (cond_code == LEU) 11190 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx)); 11191 else 11192 emit_insn (gen_neg<mode>2 (op0, tmp2)); 11193 11194 DONE; 11195}) 11196 11197(define_expand "cstore_si_as_di" 11198 [(use (match_operator 1 "unsigned_comparison_operator" 11199 [(match_operand:SI 2 "gpc_reg_operand") 11200 (match_operand:SI 3 "reg_or_short_operand")])) 11201 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 11202 "" 11203{ 11204 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0; 11205 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1])); 11206 11207 operands[2] = force_reg (SImode, operands[2]); 11208 operands[3] = force_reg (SImode, operands[3]); 11209 rtx op1 = gen_reg_rtx (DImode); 11210 rtx op2 = gen_reg_rtx (DImode); 11211 convert_move (op1, operands[2], uns_flag); 11212 convert_move (op2, operands[3], uns_flag); 11213 11214 if (cond_code == GT || cond_code == LE) 11215 { 11216 cond_code = swap_condition (cond_code); 11217 std::swap (op1, op2); 11218 } 11219 11220 rtx tmp = gen_reg_rtx (DImode); 11221 rtx tmp2 = gen_reg_rtx (DImode); 11222 emit_insn (gen_subdi3 (tmp, op1, op2)); 11223 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63))); 11224 11225 rtx tmp3; 11226 switch (cond_code) 11227 { 11228 default: 11229 gcc_unreachable (); 11230 case LT: 11231 tmp3 = tmp2; 11232 break; 11233 case GE: 11234 tmp3 = gen_reg_rtx (DImode); 11235 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx)); 11236 break; 11237 } 11238 11239 convert_move (operands[0], tmp3, 1); 11240 11241 DONE; 11242}) 11243 11244(define_expand "cstore<mode>4_signed_imm" 11245 [(use (match_operator 1 "signed_comparison_operator" 11246 [(match_operand:GPR 2 "gpc_reg_operand") 11247 (match_operand:GPR 3 "immediate_operand")])) 11248 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11249 "" 11250{ 11251 bool invert = false; 11252 11253 enum rtx_code cond_code = GET_CODE (operands[1]); 11254 11255 rtx op0 = operands[0]; 11256 rtx op1 = operands[2]; 11257 HOST_WIDE_INT val = INTVAL (operands[3]); 11258 11259 if (cond_code == GE || cond_code == GT) 11260 { 11261 cond_code = reverse_condition (cond_code); 11262 invert = true; 11263 } 11264 11265 if (cond_code == LE) 11266 val++; 11267 11268 rtx tmp = gen_reg_rtx (<MODE>mode); 11269 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 11270 rtx x = gen_reg_rtx (<MODE>mode); 11271 if (val < 0) 11272 emit_insn (gen_and<mode>3 (x, op1, tmp)); 11273 else 11274 emit_insn (gen_ior<mode>3 (x, op1, tmp)); 11275 11276 if (invert) 11277 { 11278 rtx tmp = gen_reg_rtx (<MODE>mode); 11279 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 11280 x = tmp; 11281 } 11282 11283 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11284 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 11285 11286 DONE; 11287}) 11288 11289(define_expand "cstore<mode>4_unsigned_imm" 11290 [(use (match_operator 1 "unsigned_comparison_operator" 11291 [(match_operand:GPR 2 "gpc_reg_operand") 11292 (match_operand:GPR 3 "immediate_operand")])) 11293 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11294 "" 11295{ 11296 bool invert = false; 11297 11298 enum rtx_code cond_code = GET_CODE (operands[1]); 11299 11300 rtx op0 = operands[0]; 11301 rtx op1 = operands[2]; 11302 HOST_WIDE_INT val = INTVAL (operands[3]); 11303 11304 if (cond_code == GEU || cond_code == GTU) 11305 { 11306 cond_code = reverse_condition (cond_code); 11307 invert = true; 11308 } 11309 11310 if (cond_code == LEU) 11311 val++; 11312 11313 rtx tmp = gen_reg_rtx (<MODE>mode); 11314 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11315 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 11316 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1)); 11317 rtx x = gen_reg_rtx (<MODE>mode); 11318 if (val < 0) 11319 emit_insn (gen_ior<mode>3 (x, tmp, tmp2)); 11320 else 11321 emit_insn (gen_and<mode>3 (x, tmp, tmp2)); 11322 11323 if (invert) 11324 { 11325 rtx tmp = gen_reg_rtx (<MODE>mode); 11326 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 11327 x = tmp; 11328 } 11329 11330 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11331 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 11332 11333 DONE; 11334}) 11335 11336(define_expand "cstore<mode>4" 11337 [(use (match_operator 1 "comparison_operator" 11338 [(match_operand:GPR 2 "gpc_reg_operand") 11339 (match_operand:GPR 3 "reg_or_short_operand")])) 11340 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11341 "" 11342{ 11343 /* Expanding EQ and NE directly to some machine instructions does not help 11344 but does hurt combine. So don't. */ 11345 if (GET_CODE (operands[1]) == EQ) 11346 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3])); 11347 else if (<MODE>mode == Pmode 11348 && GET_CODE (operands[1]) == NE) 11349 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3])); 11350 else if (GET_CODE (operands[1]) == NE) 11351 { 11352 rtx tmp = gen_reg_rtx (<MODE>mode); 11353 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3])); 11354 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); 11355 } 11356 11357 /* If ISEL is fast, expand to it. */ 11358 else if (TARGET_ISEL) 11359 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx); 11360 11361 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu 11362 etc. combinations magically work out just right. */ 11363 else if (<MODE>mode == Pmode 11364 && unsigned_comparison_operator (operands[1], VOIDmode)) 11365 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1], 11366 operands[2], operands[3])); 11367 11368 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */ 11369 else if (<MODE>mode == SImode && Pmode == DImode) 11370 emit_insn (gen_cstore_si_as_di (operands[0], operands[1], 11371 operands[2], operands[3])); 11372 11373 /* For signed comparisons against a constant, we can do some simple 11374 bit-twiddling. */ 11375 else if (signed_comparison_operator (operands[1], VOIDmode) 11376 && CONST_INT_P (operands[3])) 11377 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1], 11378 operands[2], operands[3])); 11379 11380 /* And similarly for unsigned comparisons. */ 11381 else if (unsigned_comparison_operator (operands[1], VOIDmode) 11382 && CONST_INT_P (operands[3])) 11383 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1], 11384 operands[2], operands[3])); 11385 11386 /* We also do not want to use mfcr for signed comparisons. */ 11387 else if (<MODE>mode == Pmode 11388 && signed_comparison_operator (operands[1], VOIDmode)) 11389 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1], 11390 operands[2], operands[3])); 11391 11392 /* Everything else, use the mfcr brute force. */ 11393 else 11394 rs6000_emit_sCOND (<MODE>mode, operands); 11395 11396 DONE; 11397}) 11398 11399(define_expand "cstore<mode>4" 11400 [(use (match_operator 1 "comparison_operator" 11401 [(match_operand:FP 2 "gpc_reg_operand") 11402 (match_operand:FP 3 "gpc_reg_operand")])) 11403 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 11404 "" 11405{ 11406 rs6000_emit_sCOND (<MODE>mode, operands); 11407 DONE; 11408}) 11409 11410 11411(define_expand "stack_protect_set" 11412 [(match_operand 0 "memory_operand") 11413 (match_operand 1 "memory_operand")] 11414 "" 11415{ 11416 if (rs6000_stack_protector_guard == SSP_TLS) 11417 { 11418 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg); 11419 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset); 11420 rtx addr = gen_rtx_PLUS (Pmode, reg, offset); 11421 operands[1] = gen_rtx_MEM (Pmode, addr); 11422 } 11423 11424 if (TARGET_64BIT) 11425 emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); 11426 else 11427 emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); 11428 11429 DONE; 11430}) 11431 11432(define_insn "stack_protect_setsi" 11433 [(set (match_operand:SI 0 "memory_operand" "=m") 11434 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 11435 (set (match_scratch:SI 2 "=&r") (const_int 0))] 11436 "TARGET_32BIT" 11437 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0" 11438 [(set_attr "type" "three") 11439 (set_attr "length" "12")]) 11440 11441(define_insn "stack_protect_setdi" 11442 [(set (match_operand:DI 0 "memory_operand" "=Y") 11443 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET)) 11444 (set (match_scratch:DI 2 "=&r") (const_int 0))] 11445 "TARGET_64BIT" 11446 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0" 11447 [(set_attr "type" "three") 11448 (set_attr "length" "12")]) 11449 11450(define_expand "stack_protect_test" 11451 [(match_operand 0 "memory_operand") 11452 (match_operand 1 "memory_operand") 11453 (match_operand 2 "")] 11454 "" 11455{ 11456 rtx guard = operands[1]; 11457 11458 if (rs6000_stack_protector_guard == SSP_TLS) 11459 { 11460 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg); 11461 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset); 11462 rtx addr = gen_rtx_PLUS (Pmode, reg, offset); 11463 guard = gen_rtx_MEM (Pmode, addr); 11464 } 11465 11466 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST); 11467 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]); 11468 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]); 11469 emit_jump_insn (jump); 11470 11471 DONE; 11472}) 11473 11474(define_insn "stack_protect_testsi" 11475 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 11476 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m") 11477 (match_operand:SI 2 "memory_operand" "m,m")] 11478 UNSPEC_SP_TEST)) 11479 (set (match_scratch:SI 4 "=r,r") (const_int 0)) 11480 (clobber (match_scratch:SI 3 "=&r,&r"))] 11481 "TARGET_32BIT" 11482 "@ 11483 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 11484 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0" 11485 [(set_attr "length" "16,20")]) 11486 11487(define_insn "stack_protect_testdi" 11488 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 11489 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y") 11490 (match_operand:DI 2 "memory_operand" "Y,Y")] 11491 UNSPEC_SP_TEST)) 11492 (set (match_scratch:DI 4 "=r,r") (const_int 0)) 11493 (clobber (match_scratch:DI 3 "=&r,&r"))] 11494 "TARGET_64BIT" 11495 "@ 11496 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 11497 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0" 11498 [(set_attr "length" "16,20")]) 11499 11500 11501;; Here are the actual compare insns. 11502(define_insn "*cmp<mode>_signed" 11503 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 11504 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r") 11505 (match_operand:GPR 2 "reg_or_short_operand" "rI")))] 11506 "" 11507 "cmp<wd>%I2 %0,%1,%2" 11508 [(set_attr "type" "cmp")]) 11509 11510(define_insn "*cmp<mode>_unsigned" 11511 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") 11512 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r") 11513 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))] 11514 "" 11515 "cmpl<wd>%I2 %0,%1,%2" 11516 [(set_attr "type" "cmp")]) 11517 11518;; If we are comparing a register for equality with a large constant, 11519;; we can do this with an XOR followed by a compare. But this is profitable 11520;; only if the large constant is only used for the comparison (and in this 11521;; case we already have a register to reuse as scratch). 11522;; 11523;; For 64-bit registers, we could only do so if the constant's bit 15 is clear: 11524;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available. 11525 11526(define_peephole2 11527 [(set (match_operand:SI 0 "register_operand") 11528 (match_operand:SI 1 "logical_const_operand")) 11529 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator" 11530 [(match_dup 0) 11531 (match_operand:SI 2 "logical_const_operand")])) 11532 (set (match_operand:CC 4 "cc_reg_operand") 11533 (compare:CC (match_operand:SI 5 "gpc_reg_operand") 11534 (match_dup 0))) 11535 (set (pc) 11536 (if_then_else (match_operator 6 "equality_operator" 11537 [(match_dup 4) (const_int 0)]) 11538 (match_operand 7 "") 11539 (match_operand 8 "")))] 11540 "peep2_reg_dead_p (3, operands[0]) 11541 && peep2_reg_dead_p (4, operands[4]) 11542 && REGNO (operands[0]) != REGNO (operands[5])" 11543 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9))) 11544 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10))) 11545 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))] 11546 11547{ 11548 /* Get the constant we are comparing against, and see what it looks like 11549 when sign-extended from 16 to 32 bits. Then see what constant we could 11550 XOR with SEXTC to get the sign-extended value. */ 11551 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]), 11552 SImode, 11553 operands[1], operands[2]); 11554 HOST_WIDE_INT c = INTVAL (cnst); 11555 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000; 11556 HOST_WIDE_INT xorv = c ^ sextc; 11557 11558 operands[9] = GEN_INT (xorv); 11559 operands[10] = GEN_INT (sextc); 11560}) 11561 11562;; The following two insns don't exist as single insns, but if we provide 11563;; them, we can swap an add and compare, which will enable us to overlap more 11564;; of the required delay between a compare and branch. We generate code for 11565;; them by splitting. 11566 11567(define_insn "" 11568 [(set (match_operand:CC 3 "cc_reg_operand" "=y") 11569 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r") 11570 (match_operand:SI 2 "short_cint_operand" "i"))) 11571 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 11572 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] 11573 "" 11574 "#" 11575 [(set_attr "length" "8")]) 11576 11577(define_insn "" 11578 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y") 11579 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") 11580 (match_operand:SI 2 "u_short_cint_operand" "i"))) 11581 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 11582 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] 11583 "" 11584 "#" 11585 [(set_attr "length" "8")]) 11586 11587(define_split 11588 [(set (match_operand:CC 3 "cc_reg_operand") 11589 (compare:CC (match_operand:SI 1 "gpc_reg_operand") 11590 (match_operand:SI 2 "short_cint_operand"))) 11591 (set (match_operand:SI 0 "gpc_reg_operand") 11592 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))] 11593 "" 11594 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2))) 11595 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) 11596 11597(define_split 11598 [(set (match_operand:CCUNS 3 "cc_reg_operand") 11599 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand") 11600 (match_operand:SI 2 "u_short_cint_operand"))) 11601 (set (match_operand:SI 0 "gpc_reg_operand") 11602 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))] 11603 "" 11604 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2))) 11605 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) 11606 11607;; Only need to compare second words if first words equal 11608(define_insn "*cmp<mode>_internal1" 11609 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 11610 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 11611 (match_operand:IBM128 2 "gpc_reg_operand" "d")))] 11612 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) 11613 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 11614 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" 11615 [(set_attr "type" "fpcompare") 11616 (set_attr "length" "12")]) 11617 11618(define_insn_and_split "*cmp<mode>_internal2" 11619 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 11620 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 11621 (match_operand:IBM128 2 "gpc_reg_operand" "d"))) 11622 (clobber (match_scratch:DF 3 "=d")) 11623 (clobber (match_scratch:DF 4 "=d")) 11624 (clobber (match_scratch:DF 5 "=d")) 11625 (clobber (match_scratch:DF 6 "=d")) 11626 (clobber (match_scratch:DF 7 "=d")) 11627 (clobber (match_scratch:DF 8 "=d")) 11628 (clobber (match_scratch:DF 9 "=d")) 11629 (clobber (match_scratch:DF 10 "=d")) 11630 (clobber (match_scratch:GPR 11 "=b"))] 11631 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) 11632 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 11633 "#" 11634 "&& reload_completed" 11635 [(set (match_dup 3) (match_dup 14)) 11636 (set (match_dup 4) (match_dup 15)) 11637 (set (match_dup 9) (abs:DF (match_dup 5))) 11638 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) 11639 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) 11640 (label_ref (match_dup 12)) 11641 (pc))) 11642 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) 11643 (set (pc) (label_ref (match_dup 13))) 11644 (match_dup 12) 11645 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) 11646 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) 11647 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) 11648 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4))) 11649 (match_dup 13)] 11650{ 11651 REAL_VALUE_TYPE rv; 11652 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 11653 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 11654 11655 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word); 11656 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word); 11657 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word); 11658 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word); 11659 operands[12] = gen_label_rtx (); 11660 operands[13] = gen_label_rtx (); 11661 real_inf (&rv); 11662 operands[14] = force_const_mem (DFmode, 11663 const_double_from_real_value (rv, DFmode)); 11664 operands[15] = force_const_mem (DFmode, 11665 const_double_from_real_value (dconst0, 11666 DFmode)); 11667 if (TARGET_TOC) 11668 { 11669 rtx tocref; 11670 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]); 11671 operands[14] = gen_const_mem (DFmode, tocref); 11672 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]); 11673 operands[15] = gen_const_mem (DFmode, tocref); 11674 set_mem_alias_set (operands[14], get_TOC_alias_set ()); 11675 set_mem_alias_set (operands[15], get_TOC_alias_set ()); 11676 } 11677}) 11678 11679;; Now we have the scc insns. We can do some combinations because of the 11680;; way the machine works. 11681;; 11682;; Note that this is probably faster if we can put an insn between the 11683;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most 11684;; cases the insns below which don't use an intermediate CR field will 11685;; be used instead. 11686(define_insn "" 11687 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 11688 (match_operator:SI 1 "scc_comparison_operator" 11689 [(match_operand 2 "cc_reg_operand" "y") 11690 (const_int 0)]))] 11691 "" 11692 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" 11693 [(set (attr "type") 11694 (cond [(match_test "TARGET_MFCRF") 11695 (const_string "mfcrf") 11696 ] 11697 (const_string "mfcr"))) 11698 (set_attr "length" "8")]) 11699 11700;; Same as above, but get the OV/ORDERED bit. 11701(define_insn "move_from_CR_ov_bit" 11702 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 11703 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")] 11704 UNSPEC_MV_CR_OV))] 11705 "TARGET_PAIRED_FLOAT" 11706 "mfcr %0\;rlwinm %0,%0,%t1,1" 11707 [(set_attr "type" "mfcr") 11708 (set_attr "length" "8")]) 11709 11710(define_insn "" 11711 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 11712 (match_operator:DI 1 "scc_comparison_operator" 11713 [(match_operand 2 "cc_reg_operand" "y") 11714 (const_int 0)]))] 11715 "TARGET_POWERPC64" 11716 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" 11717 [(set (attr "type") 11718 (cond [(match_test "TARGET_MFCRF") 11719 (const_string "mfcrf") 11720 ] 11721 (const_string "mfcr"))) 11722 (set_attr "length" "8")]) 11723 11724(define_insn "" 11725 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") 11726 (compare:CC (match_operator:SI 1 "scc_comparison_operator" 11727 [(match_operand 2 "cc_reg_operand" "y,y") 11728 (const_int 0)]) 11729 (const_int 0))) 11730 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 11731 (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 11732 "TARGET_32BIT" 11733 "@ 11734 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1 11735 #" 11736 [(set_attr "type" "shift") 11737 (set_attr "dot" "yes") 11738 (set_attr "length" "8,16")]) 11739 11740(define_split 11741 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand") 11742 (compare:CC (match_operator:SI 1 "scc_comparison_operator" 11743 [(match_operand 2 "cc_reg_operand") 11744 (const_int 0)]) 11745 (const_int 0))) 11746 (set (match_operand:SI 3 "gpc_reg_operand") 11747 (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 11748 "TARGET_32BIT && reload_completed" 11749 [(set (match_dup 3) 11750 (match_op_dup 1 [(match_dup 2) (const_int 0)])) 11751 (set (match_dup 0) 11752 (compare:CC (match_dup 3) 11753 (const_int 0)))] 11754 "") 11755 11756(define_insn "" 11757 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 11758 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" 11759 [(match_operand 2 "cc_reg_operand" "y") 11760 (const_int 0)]) 11761 (match_operand:SI 3 "const_int_operand" "n")))] 11762 "" 11763{ 11764 int is_bit = ccr_bit (operands[1], 1); 11765 int put_bit = 31 - (INTVAL (operands[3]) & 31); 11766 int count; 11767 11768 if (is_bit >= put_bit) 11769 count = is_bit - put_bit; 11770 else 11771 count = 32 - (put_bit - is_bit); 11772 11773 operands[4] = GEN_INT (count); 11774 operands[5] = GEN_INT (put_bit); 11775 11776 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5"; 11777} 11778 [(set (attr "type") 11779 (cond [(match_test "TARGET_MFCRF") 11780 (const_string "mfcrf") 11781 ] 11782 (const_string "mfcr"))) 11783 (set_attr "length" "8")]) 11784 11785(define_insn "" 11786 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") 11787 (compare:CC 11788 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" 11789 [(match_operand 2 "cc_reg_operand" "y,y") 11790 (const_int 0)]) 11791 (match_operand:SI 3 "const_int_operand" "n,n")) 11792 (const_int 0))) 11793 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r") 11794 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) 11795 (match_dup 3)))] 11796 "" 11797{ 11798 int is_bit = ccr_bit (operands[1], 1); 11799 int put_bit = 31 - (INTVAL (operands[3]) & 31); 11800 int count; 11801 11802 /* Force split for non-cc0 compare. */ 11803 if (which_alternative == 1) 11804 return "#"; 11805 11806 if (is_bit >= put_bit) 11807 count = is_bit - put_bit; 11808 else 11809 count = 32 - (put_bit - is_bit); 11810 11811 operands[5] = GEN_INT (count); 11812 operands[6] = GEN_INT (put_bit); 11813 11814 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6"; 11815} 11816 [(set_attr "type" "shift") 11817 (set_attr "dot" "yes") 11818 (set_attr "length" "8,16")]) 11819 11820(define_split 11821 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand") 11822 (compare:CC 11823 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" 11824 [(match_operand 2 "cc_reg_operand") 11825 (const_int 0)]) 11826 (match_operand:SI 3 "const_int_operand")) 11827 (const_int 0))) 11828 (set (match_operand:SI 4 "gpc_reg_operand") 11829 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) 11830 (match_dup 3)))] 11831 "reload_completed" 11832 [(set (match_dup 4) 11833 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) 11834 (match_dup 3))) 11835 (set (match_dup 0) 11836 (compare:CC (match_dup 4) 11837 (const_int 0)))] 11838 "") 11839 11840 11841(define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu]) 11842(define_code_attr UNS [(eq "CC") 11843 (ne "CC") 11844 (lt "CC") (ltu "CCUNS") 11845 (gt "CC") (gtu "CCUNS") 11846 (le "CC") (leu "CCUNS") 11847 (ge "CC") (geu "CCUNS")]) 11848(define_code_attr UNSu_ [(eq "") 11849 (ne "") 11850 (lt "") (ltu "u_") 11851 (gt "") (gtu "u_") 11852 (le "") (leu "u_") 11853 (ge "") (geu "u_")]) 11854(define_code_attr UNSIK [(eq "I") 11855 (ne "I") 11856 (lt "I") (ltu "K") 11857 (gt "I") (gtu "K") 11858 (le "I") (leu "K") 11859 (ge "I") (geu "K")]) 11860 11861(define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel" 11862 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11863 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r") 11864 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>"))) 11865 (clobber (match_scratch:GPR 3 "=r")) 11866 (clobber (match_scratch:GPR 4 "=r")) 11867 (clobber (match_scratch:<UNS> 5 "=y"))] 11868 "TARGET_ISEL 11869 && !(<CODE> == EQ && operands[2] == const0_rtx) 11870 && !(<CODE> == NE && operands[2] == const0_rtx 11871 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)" 11872 "#" 11873 "&& 1" 11874 [(pc)] 11875{ 11876 rtx_code code = <CODE>; 11877 if (CONST_INT_P (operands[2]) && code != EQ && code != NE) 11878 { 11879 HOST_WIDE_INT val = INTVAL (operands[2]); 11880 if (code == LT && val != -0x8000) 11881 { 11882 code = LE; 11883 val--; 11884 } 11885 if (code == GT && val != 0x7fff) 11886 { 11887 code = GE; 11888 val++; 11889 } 11890 if (code == LTU && val != 0) 11891 { 11892 code = LEU; 11893 val--; 11894 } 11895 if (code == GTU && val != 0xffff) 11896 { 11897 code = GEU; 11898 val++; 11899 } 11900 operands[2] = GEN_INT (val); 11901 } 11902 11903 if (code == NE || code == LE || code == GE || code == LEU || code == GEU) 11904 operands[3] = const0_rtx; 11905 else 11906 { 11907 if (GET_CODE (operands[3]) == SCRATCH) 11908 operands[3] = gen_reg_rtx (<GPR:MODE>mode); 11909 emit_move_insn (operands[3], const0_rtx); 11910 } 11911 11912 if (GET_CODE (operands[4]) == SCRATCH) 11913 operands[4] = gen_reg_rtx (<GPR:MODE>mode); 11914 emit_move_insn (operands[4], const1_rtx); 11915 11916 if (GET_CODE (operands[5]) == SCRATCH) 11917 operands[5] = gen_reg_rtx (<UNS>mode); 11918 11919 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]); 11920 emit_insn (gen_rtx_SET (operands[5], c1)); 11921 11922 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx); 11923 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]); 11924 emit_move_insn (operands[0], x); 11925 11926 DONE; 11927} 11928 [(set (attr "cost") 11929 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ) 11930 || <CODE> == NE 11931 || <CODE> == LE || <CODE> == GE 11932 || <CODE> == LEU || <CODE> == GEU") 11933 (const_string "9") 11934 (const_string "10")))]) 11935 11936(define_mode_attr scc_eq_op2 [(SI "rKLI") 11937 (DI "rKJI")]) 11938 11939(define_expand "eq<mode>3" 11940 [(parallel [ 11941 (set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11942 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 11943 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 11944 (clobber (match_scratch:GPR 3 "=r")) 11945 (clobber (match_scratch:GPR 4 "=r"))])] 11946 "" 11947{ 11948 if (TARGET_ISEL && operands[2] != const0_rtx) 11949 { 11950 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1], 11951 operands[2])); 11952 DONE; 11953 } 11954}) 11955 11956(define_insn_and_split "*eq<mode>3" 11957 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11958 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 11959 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 11960 (clobber (match_scratch:GPR 3 "=r")) 11961 (clobber (match_scratch:GPR 4 "=r"))] 11962 "!(TARGET_ISEL && operands[2] != const0_rtx)" 11963 "#" 11964 "&& 1" 11965 [(set (match_dup 4) 11966 (clz:GPR (match_dup 3))) 11967 (set (match_dup 0) 11968 (lshiftrt:GPR (match_dup 4) 11969 (match_dup 5)))] 11970{ 11971 operands[3] = rs6000_emit_eqne (<MODE>mode, 11972 operands[1], operands[2], operands[3]); 11973 11974 if (GET_CODE (operands[4]) == SCRATCH) 11975 operands[4] = gen_reg_rtx (<MODE>mode); 11976 11977 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode))); 11978} 11979 [(set (attr "length") 11980 (if_then_else (match_test "operands[2] == const0_rtx") 11981 (const_string "8") 11982 (const_string "12")))]) 11983 11984(define_expand "ne<mode>3" 11985 [(parallel [ 11986 (set (match_operand:P 0 "gpc_reg_operand" "=r") 11987 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 11988 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) 11989 (clobber (match_scratch:P 3 "=r")) 11990 (clobber (match_scratch:P 4 "=r")) 11991 (clobber (reg:P CA_REGNO))])] 11992 "" 11993{ 11994 if (TARGET_ISEL && operands[2] != const0_rtx) 11995 { 11996 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1], 11997 operands[2])); 11998 DONE; 11999 } 12000}) 12001 12002(define_insn_and_split "*ne<mode>3" 12003 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12004 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12005 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) 12006 (clobber (match_scratch:P 3 "=r")) 12007 (clobber (match_scratch:P 4 "=r")) 12008 (clobber (reg:P CA_REGNO))] 12009 "!(TARGET_ISEL && operands[2] != const0_rtx)" 12010 "#" 12011 "&& 1" 12012 [(parallel [(set (match_dup 4) 12013 (plus:P (match_dup 3) 12014 (const_int -1))) 12015 (set (reg:P CA_REGNO) 12016 (ne:P (match_dup 3) 12017 (const_int 0)))]) 12018 (parallel [(set (match_dup 0) 12019 (plus:P (plus:P (not:P (match_dup 4)) 12020 (reg:P CA_REGNO)) 12021 (match_dup 3))) 12022 (clobber (reg:P CA_REGNO))])] 12023{ 12024 operands[3] = rs6000_emit_eqne (<MODE>mode, 12025 operands[1], operands[2], operands[3]); 12026 12027 if (GET_CODE (operands[4]) == SCRATCH) 12028 operands[4] = gen_reg_rtx (<MODE>mode); 12029} 12030 [(set (attr "length") 12031 (if_then_else (match_test "operands[2] == const0_rtx") 12032 (const_string "8") 12033 (const_string "12")))]) 12034 12035(define_insn_and_split "*neg_eq_<mode>" 12036 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12037 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12038 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12039 (clobber (match_scratch:P 3 "=r")) 12040 (clobber (match_scratch:P 4 "=r")) 12041 (clobber (reg:P CA_REGNO))] 12042 "" 12043 "#" 12044 "" 12045 [(parallel [(set (match_dup 4) 12046 (plus:P (match_dup 3) 12047 (const_int -1))) 12048 (set (reg:P CA_REGNO) 12049 (ne:P (match_dup 3) 12050 (const_int 0)))]) 12051 (parallel [(set (match_dup 0) 12052 (plus:P (reg:P CA_REGNO) 12053 (const_int -1))) 12054 (clobber (reg:P CA_REGNO))])] 12055{ 12056 operands[3] = rs6000_emit_eqne (<MODE>mode, 12057 operands[1], operands[2], operands[3]); 12058 12059 if (GET_CODE (operands[4]) == SCRATCH) 12060 operands[4] = gen_reg_rtx (<MODE>mode); 12061} 12062 [(set (attr "length") 12063 (if_then_else (match_test "operands[2] == const0_rtx") 12064 (const_string "8") 12065 (const_string "12")))]) 12066 12067(define_insn_and_split "*neg_ne_<mode>" 12068 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12069 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12070 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12071 (clobber (match_scratch:P 3 "=r")) 12072 (clobber (match_scratch:P 4 "=r")) 12073 (clobber (reg:P CA_REGNO))] 12074 "" 12075 "#" 12076 "" 12077 [(parallel [(set (match_dup 4) 12078 (neg:P (match_dup 3))) 12079 (set (reg:P CA_REGNO) 12080 (eq:P (match_dup 3) 12081 (const_int 0)))]) 12082 (parallel [(set (match_dup 0) 12083 (plus:P (reg:P CA_REGNO) 12084 (const_int -1))) 12085 (clobber (reg:P CA_REGNO))])] 12086{ 12087 operands[3] = rs6000_emit_eqne (<MODE>mode, 12088 operands[1], operands[2], operands[3]); 12089 12090 if (GET_CODE (operands[4]) == SCRATCH) 12091 operands[4] = gen_reg_rtx (<MODE>mode); 12092} 12093 [(set (attr "length") 12094 (if_then_else (match_test "operands[2] == const0_rtx") 12095 (const_string "8") 12096 (const_string "12")))]) 12097 12098(define_insn_and_split "*plus_eq_<mode>" 12099 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12100 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12101 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 12102 (match_operand:P 3 "gpc_reg_operand" "r"))) 12103 (clobber (match_scratch:P 4 "=r")) 12104 (clobber (match_scratch:P 5 "=r")) 12105 (clobber (reg:P CA_REGNO))] 12106 "" 12107 "#" 12108 "" 12109 [(parallel [(set (match_dup 5) 12110 (neg:P (match_dup 4))) 12111 (set (reg:P CA_REGNO) 12112 (eq:P (match_dup 4) 12113 (const_int 0)))]) 12114 (parallel [(set (match_dup 0) 12115 (plus:P (match_dup 3) 12116 (reg:P CA_REGNO))) 12117 (clobber (reg:P CA_REGNO))])] 12118{ 12119 operands[4] = rs6000_emit_eqne (<MODE>mode, 12120 operands[1], operands[2], operands[4]); 12121 12122 if (GET_CODE (operands[5]) == SCRATCH) 12123 operands[5] = gen_reg_rtx (<MODE>mode); 12124} 12125 [(set (attr "length") 12126 (if_then_else (match_test "operands[2] == const0_rtx") 12127 (const_string "8") 12128 (const_string "12")))]) 12129 12130(define_insn_and_split "*plus_ne_<mode>" 12131 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12132 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12133 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 12134 (match_operand:P 3 "gpc_reg_operand" "r"))) 12135 (clobber (match_scratch:P 4 "=r")) 12136 (clobber (match_scratch:P 5 "=r")) 12137 (clobber (reg:P CA_REGNO))] 12138 "" 12139 "#" 12140 "" 12141 [(parallel [(set (match_dup 5) 12142 (plus:P (match_dup 4) 12143 (const_int -1))) 12144 (set (reg:P CA_REGNO) 12145 (ne:P (match_dup 4) 12146 (const_int 0)))]) 12147 (parallel [(set (match_dup 0) 12148 (plus:P (match_dup 3) 12149 (reg:P CA_REGNO))) 12150 (clobber (reg:P CA_REGNO))])] 12151{ 12152 operands[4] = rs6000_emit_eqne (<MODE>mode, 12153 operands[1], operands[2], operands[4]); 12154 12155 if (GET_CODE (operands[5]) == SCRATCH) 12156 operands[5] = gen_reg_rtx (<MODE>mode); 12157} 12158 [(set (attr "length") 12159 (if_then_else (match_test "operands[2] == const0_rtx") 12160 (const_string "8") 12161 (const_string "12")))]) 12162 12163(define_insn_and_split "*minus_eq_<mode>" 12164 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12165 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 12166 (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12167 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12168 (clobber (match_scratch:P 4 "=r")) 12169 (clobber (match_scratch:P 5 "=r")) 12170 (clobber (reg:P CA_REGNO))] 12171 "" 12172 "#" 12173 "" 12174 [(parallel [(set (match_dup 5) 12175 (plus:P (match_dup 4) 12176 (const_int -1))) 12177 (set (reg:P CA_REGNO) 12178 (ne:P (match_dup 4) 12179 (const_int 0)))]) 12180 (parallel [(set (match_dup 0) 12181 (plus:P (plus:P (match_dup 3) 12182 (reg:P CA_REGNO)) 12183 (const_int -1))) 12184 (clobber (reg:P CA_REGNO))])] 12185{ 12186 operands[4] = rs6000_emit_eqne (<MODE>mode, 12187 operands[1], operands[2], operands[4]); 12188 12189 if (GET_CODE (operands[5]) == SCRATCH) 12190 operands[5] = gen_reg_rtx (<MODE>mode); 12191} 12192 [(set (attr "length") 12193 (if_then_else (match_test "operands[2] == const0_rtx") 12194 (const_string "8") 12195 (const_string "12")))]) 12196 12197(define_insn_and_split "*minus_ne_<mode>" 12198 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12199 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 12200 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12201 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12202 (clobber (match_scratch:P 4 "=r")) 12203 (clobber (match_scratch:P 5 "=r")) 12204 (clobber (reg:P CA_REGNO))] 12205 "" 12206 "#" 12207 "" 12208 [(parallel [(set (match_dup 5) 12209 (neg:P (match_dup 4))) 12210 (set (reg:P CA_REGNO) 12211 (eq:P (match_dup 4) 12212 (const_int 0)))]) 12213 (parallel [(set (match_dup 0) 12214 (plus:P (plus:P (match_dup 3) 12215 (reg:P CA_REGNO)) 12216 (const_int -1))) 12217 (clobber (reg:P CA_REGNO))])] 12218{ 12219 operands[4] = rs6000_emit_eqne (<MODE>mode, 12220 operands[1], operands[2], operands[4]); 12221 12222 if (GET_CODE (operands[5]) == SCRATCH) 12223 operands[5] = gen_reg_rtx (<MODE>mode); 12224} 12225 [(set (attr "length") 12226 (if_then_else (match_test "operands[2] == const0_rtx") 12227 (const_string "8") 12228 (const_string "12")))]) 12229 12230(define_insn_and_split "*eqsi3_ext<mode>" 12231 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 12232 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 12233 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 12234 (clobber (match_scratch:SI 3 "=r")) 12235 (clobber (match_scratch:SI 4 "=r"))] 12236 "" 12237 "#" 12238 "" 12239 [(set (match_dup 4) 12240 (clz:SI (match_dup 3))) 12241 (set (match_dup 0) 12242 (zero_extend:EXTSI 12243 (lshiftrt:SI (match_dup 4) 12244 (const_int 5))))] 12245{ 12246 operands[3] = rs6000_emit_eqne (SImode, 12247 operands[1], operands[2], operands[3]); 12248 12249 if (GET_CODE (operands[4]) == SCRATCH) 12250 operands[4] = gen_reg_rtx (SImode); 12251} 12252 [(set (attr "length") 12253 (if_then_else (match_test "operands[2] == const0_rtx") 12254 (const_string "8") 12255 (const_string "12")))]) 12256 12257(define_insn_and_split "*nesi3_ext<mode>" 12258 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 12259 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 12260 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 12261 (clobber (match_scratch:SI 3 "=r")) 12262 (clobber (match_scratch:SI 4 "=r")) 12263 (clobber (match_scratch:EXTSI 5 "=r"))] 12264 "!TARGET_ISEL" 12265 "#" 12266 "&& 1" 12267 [(set (match_dup 4) 12268 (clz:SI (match_dup 3))) 12269 (set (match_dup 5) 12270 (zero_extend:EXTSI 12271 (lshiftrt:SI (match_dup 4) 12272 (const_int 5)))) 12273 (set (match_dup 0) 12274 (xor:EXTSI (match_dup 5) 12275 (const_int 1)))] 12276{ 12277 operands[3] = rs6000_emit_eqne (SImode, 12278 operands[1], operands[2], operands[3]); 12279 12280 if (GET_CODE (operands[4]) == SCRATCH) 12281 operands[4] = gen_reg_rtx (SImode); 12282 if (GET_CODE (operands[5]) == SCRATCH) 12283 operands[5] = gen_reg_rtx (<MODE>mode); 12284} 12285 [(set (attr "length") 12286 (if_then_else (match_test "operands[2] == const0_rtx") 12287 (const_string "12") 12288 (const_string "16")))]) 12289 12290;; Define both directions of branch and return. If we need a reload 12291;; register, we'd rather use CR0 since it is much easier to copy a 12292;; register CC value to there. 12293 12294(define_insn "" 12295 [(set (pc) 12296 (if_then_else (match_operator 1 "branch_comparison_operator" 12297 [(match_operand 2 "cc_reg_operand" "y") 12298 (const_int 0)]) 12299 (label_ref (match_operand 0)) 12300 (pc)))] 12301 "" 12302{ 12303 return output_cbranch (operands[1], "%l0", 0, insn); 12304} 12305 [(set_attr "type" "branch")]) 12306 12307(define_insn "" 12308 [(set (pc) 12309 (if_then_else (match_operator 0 "branch_comparison_operator" 12310 [(match_operand 1 "cc_reg_operand" "y") 12311 (const_int 0)]) 12312 (any_return) 12313 (pc)))] 12314 "<return_pred>" 12315{ 12316 return output_cbranch (operands[0], NULL, 0, insn); 12317} 12318 [(set_attr "type" "jmpreg") 12319 (set_attr "length" "4")]) 12320 12321;; Logic on condition register values. 12322 12323; This pattern matches things like 12324; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0)) 12325; (eq:SI (reg:CCFP 68) (const_int 0))) 12326; (const_int 1))) 12327; which are generated by the branch logic. 12328; Prefer destructive operations where BT = BB (for crXX BT,BA,BB) 12329 12330(define_insn "cceq_ior_compare" 12331 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12332 (compare:CCEQ (match_operator:SI 1 "boolean_operator" 12333 [(match_operator:SI 2 12334 "branch_positive_comparison_operator" 12335 [(match_operand 3 12336 "cc_reg_operand" "y,y") 12337 (const_int 0)]) 12338 (match_operator:SI 4 12339 "branch_positive_comparison_operator" 12340 [(match_operand 5 12341 "cc_reg_operand" "0,y") 12342 (const_int 0)])]) 12343 (const_int 1)))] 12344 "" 12345 "cr%q1 %E0,%j2,%j4" 12346 [(set_attr "type" "cr_logical") 12347 (set_attr "cr_logical_3op" "no,yes")]) 12348 12349; Why is the constant -1 here, but 1 in the previous pattern? 12350; Because ~1 has all but the low bit set. 12351(define_insn "cceq_ior_compare_complement" 12352 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12353 (compare:CCEQ (match_operator:SI 1 "boolean_operator" 12354 [(not:SI (match_operator:SI 2 12355 "branch_positive_comparison_operator" 12356 [(match_operand 3 12357 "cc_reg_operand" "y,y") 12358 (const_int 0)])) 12359 (match_operator:SI 4 12360 "branch_positive_comparison_operator" 12361 [(match_operand 5 12362 "cc_reg_operand" "0,y") 12363 (const_int 0)])]) 12364 (const_int -1)))] 12365 "" 12366 "cr%q1 %E0,%j2,%j4" 12367 [(set_attr "type" "cr_logical") 12368 (set_attr "cr_logical_3op" "no,yes")]) 12369 12370(define_insn "*cceq_rev_compare" 12371 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12372 (compare:CCEQ (match_operator:SI 1 12373 "branch_positive_comparison_operator" 12374 [(match_operand 2 12375 "cc_reg_operand" "0,y") 12376 (const_int 0)]) 12377 (const_int 0)))] 12378 "" 12379 "crnot %E0,%j1" 12380 [(set_attr "type" "cr_logical") 12381 (set_attr "cr_logical_3op" "no,yes")]) 12382 12383;; If we are comparing the result of two comparisons, this can be done 12384;; using creqv or crxor. 12385 12386(define_insn_and_split "" 12387 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y") 12388 (compare:CCEQ (match_operator 1 "branch_comparison_operator" 12389 [(match_operand 2 "cc_reg_operand" "y") 12390 (const_int 0)]) 12391 (match_operator 3 "branch_comparison_operator" 12392 [(match_operand 4 "cc_reg_operand" "y") 12393 (const_int 0)])))] 12394 "" 12395 "#" 12396 "" 12397 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3)) 12398 (match_dup 5)))] 12399{ 12400 int positive_1, positive_2; 12401 12402 positive_1 = branch_positive_comparison_operator (operands[1], 12403 GET_MODE (operands[1])); 12404 positive_2 = branch_positive_comparison_operator (operands[3], 12405 GET_MODE (operands[3])); 12406 12407 if (! positive_1) 12408 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]), 12409 GET_CODE (operands[1])), 12410 SImode, 12411 operands[2], const0_rtx); 12412 else if (GET_MODE (operands[1]) != SImode) 12413 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, 12414 operands[2], const0_rtx); 12415 12416 if (! positive_2) 12417 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]), 12418 GET_CODE (operands[3])), 12419 SImode, 12420 operands[4], const0_rtx); 12421 else if (GET_MODE (operands[3]) != SImode) 12422 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, 12423 operands[4], const0_rtx); 12424 12425 if (positive_1 == positive_2) 12426 { 12427 operands[1] = gen_rtx_NOT (SImode, operands[1]); 12428 operands[5] = constm1_rtx; 12429 } 12430 else 12431 { 12432 operands[5] = const1_rtx; 12433 } 12434}) 12435 12436;; Unconditional branch and return. 12437 12438(define_insn "jump" 12439 [(set (pc) 12440 (label_ref (match_operand 0)))] 12441 "" 12442 "b %l0" 12443 [(set_attr "type" "branch")]) 12444 12445(define_insn "<return_str>return" 12446 [(any_return)] 12447 "<return_pred>" 12448 "blr" 12449 [(set_attr "type" "jmpreg")]) 12450 12451(define_expand "indirect_jump" 12452 [(set (pc) (match_operand 0 "register_operand"))] 12453 "" 12454{ 12455 if (!rs6000_speculate_indirect_jumps) { 12456 rtx ccreg = gen_reg_rtx (CCmode); 12457 if (Pmode == DImode) 12458 emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg)); 12459 else 12460 emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg)); 12461 DONE; 12462 } 12463}) 12464 12465(define_insn "*indirect_jump<mode>" 12466 [(set (pc) 12467 (match_operand:P 0 "register_operand" "c,*l"))] 12468 "rs6000_speculate_indirect_jumps" 12469 "b%T0" 12470 [(set_attr "type" "jmpreg")]) 12471 12472(define_insn "indirect_jump<mode>_nospec" 12473 [(set (pc) (match_operand:P 0 "register_operand" "c,*l")) 12474 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))] 12475 "!rs6000_speculate_indirect_jumps" 12476 "crset %E1\;beq%T0- %1\;b $" 12477 [(set_attr "type" "jmpreg") 12478 (set_attr "length" "12")]) 12479 12480;; Table jump for switch statements: 12481(define_expand "tablejump" 12482 [(use (match_operand 0)) 12483 (use (label_ref (match_operand 1)))] 12484 "" 12485{ 12486 if (rs6000_speculate_indirect_jumps) 12487 { 12488 if (TARGET_32BIT) 12489 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); 12490 else 12491 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); 12492 } 12493 else 12494 { 12495 rtx ccreg = gen_reg_rtx (CCmode); 12496 rtx jump; 12497 if (TARGET_32BIT) 12498 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg); 12499 else 12500 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg); 12501 emit_jump_insn (jump); 12502 } 12503 DONE; 12504}) 12505 12506(define_expand "tablejumpsi" 12507 [(set (match_dup 3) 12508 (plus:SI (match_operand:SI 0) 12509 (match_dup 2))) 12510 (parallel [(set (pc) 12511 (match_dup 3)) 12512 (use (label_ref (match_operand 1)))])] 12513 "TARGET_32BIT && rs6000_speculate_indirect_jumps" 12514{ 12515 operands[0] = force_reg (SImode, operands[0]); 12516 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); 12517 operands[3] = gen_reg_rtx (SImode); 12518}) 12519 12520(define_expand "tablejumpsi_nospec" 12521 [(set (match_dup 4) 12522 (plus:SI (match_operand:SI 0) 12523 (match_dup 3))) 12524 (parallel [(set (pc) 12525 (match_dup 4)) 12526 (use (label_ref (match_operand 1))) 12527 (clobber (match_operand 2))])] 12528 "TARGET_32BIT && !rs6000_speculate_indirect_jumps" 12529{ 12530 operands[0] = force_reg (SImode, operands[0]); 12531 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); 12532 operands[4] = gen_reg_rtx (SImode); 12533}) 12534 12535(define_expand "tablejumpdi" 12536 [(set (match_dup 4) 12537 (sign_extend:DI (match_operand:SI 0 "lwa_operand"))) 12538 (set (match_dup 3) 12539 (plus:DI (match_dup 4) 12540 (match_dup 2))) 12541 (parallel [(set (pc) 12542 (match_dup 3)) 12543 (use (label_ref (match_operand 1)))])] 12544 "TARGET_64BIT && rs6000_speculate_indirect_jumps" 12545{ 12546 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); 12547 operands[3] = gen_reg_rtx (DImode); 12548 operands[4] = gen_reg_rtx (DImode); 12549}) 12550 12551(define_expand "tablejumpdi_nospec" 12552 [(set (match_dup 5) 12553 (sign_extend:DI (match_operand:SI 0 "lwa_operand"))) 12554 (set (match_dup 4) 12555 (plus:DI (match_dup 5) 12556 (match_dup 3))) 12557 (parallel [(set (pc) 12558 (match_dup 4)) 12559 (use (label_ref (match_operand 1))) 12560 (clobber (match_operand 2))])] 12561 "TARGET_64BIT && !rs6000_speculate_indirect_jumps" 12562{ 12563 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); 12564 operands[4] = gen_reg_rtx (DImode); 12565 operands[5] = gen_reg_rtx (DImode); 12566}) 12567 12568(define_insn "*tablejump<mode>_internal1" 12569 [(set (pc) 12570 (match_operand:P 0 "register_operand" "c,*l")) 12571 (use (label_ref (match_operand 1)))] 12572 "rs6000_speculate_indirect_jumps" 12573 "b%T0" 12574 [(set_attr "type" "jmpreg")]) 12575 12576(define_insn "*tablejump<mode>_internal1_nospec" 12577 [(set (pc) 12578 (match_operand:P 0 "register_operand" "c,*l")) 12579 (use (label_ref (match_operand 1))) 12580 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))] 12581 "!rs6000_speculate_indirect_jumps" 12582 "crset %E2\;beq%T0- %2\;b $" 12583 [(set_attr "type" "jmpreg") 12584 (set_attr "length" "12")]) 12585 12586(define_insn "nop" 12587 [(unspec [(const_int 0)] UNSPEC_NOP)] 12588 "" 12589 "nop") 12590 12591(define_insn "group_ending_nop" 12592 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)] 12593 "" 12594{ 12595 operands[0] = gen_rtx_REG (Pmode, 12596 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2); 12597 return "ori %0,%0,0"; 12598}) 12599 12600(define_insn "rs6000_speculation_barrier" 12601 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)] 12602 "" 12603{ 12604 operands[0] = gen_rtx_REG (Pmode, 31); 12605 return "ori %0,%0,0"; 12606}) 12607 12608;; Define the subtract-one-and-jump insns, starting with the template 12609;; so loop.c knows what to generate. 12610 12611(define_expand "doloop_end" 12612 [(use (match_operand 0)) ; loop pseudo 12613 (use (match_operand 1))] ; label 12614 "" 12615{ 12616 if (TARGET_64BIT) 12617 { 12618 if (GET_MODE (operands[0]) != DImode) 12619 FAIL; 12620 emit_jump_insn (gen_ctrdi (operands[0], operands[1])); 12621 } 12622 else 12623 { 12624 if (GET_MODE (operands[0]) != SImode) 12625 FAIL; 12626 emit_jump_insn (gen_ctrsi (operands[0], operands[1])); 12627 } 12628 DONE; 12629}) 12630 12631(define_expand "ctr<mode>" 12632 [(parallel [(set (pc) 12633 (if_then_else (ne (match_operand:P 0 "register_operand") 12634 (const_int 1)) 12635 (label_ref (match_operand 1)) 12636 (pc))) 12637 (set (match_dup 0) 12638 (plus:P (match_dup 0) 12639 (const_int -1))) 12640 (clobber (match_scratch:CC 2)) 12641 (clobber (match_scratch:P 3))])] 12642 "" 12643 "") 12644 12645;; We need to be able to do this for any operand, including MEM, or we 12646;; will cause reload to blow up since we don't allow output reloads on 12647;; JUMP_INSNs. 12648;; For the length attribute to be calculated correctly, the 12649;; label MUST be operand 0. 12650;; rs6000_legitimate_combined_insn prevents combine creating any of 12651;; the ctr<mode> insns. 12652 12653(define_code_iterator eqne [eq ne]) 12654(define_code_attr bd [(eq "bdz") (ne "bdnz")]) 12655(define_code_attr bd_neg [(eq "bdnz") (ne "bdz")]) 12656 12657(define_insn "<bd>_<mode>" 12658 [(set (pc) 12659 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12660 (const_int 1)) 12661 (label_ref (match_operand 0)) 12662 (pc))) 12663 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") 12664 (plus:P (match_dup 1) 12665 (const_int -1))) 12666 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 12667 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 12668 "" 12669{ 12670 if (which_alternative != 0) 12671 return "#"; 12672 else if (get_attr_length (insn) == 4) 12673 return "<bd> %l0"; 12674 else 12675 return "<bd_neg> $+8\;b %l0"; 12676} 12677 [(set_attr "type" "branch") 12678 (set_attr "length" "*,16,20,20")]) 12679 12680;; Now the splitter if we could not allocate the CTR register 12681(define_split 12682 [(set (pc) 12683 (if_then_else (match_operator 2 "comparison_operator" 12684 [(match_operand:P 1 "gpc_reg_operand") 12685 (const_int 1)]) 12686 (match_operand 5) 12687 (match_operand 6))) 12688 (set (match_operand:P 0 "nonimmediate_operand") 12689 (plus:P (match_dup 1) 12690 (const_int -1))) 12691 (clobber (match_scratch:CC 3)) 12692 (clobber (match_scratch:P 4))] 12693 "reload_completed" 12694 [(set (pc) 12695 (if_then_else (match_dup 7) 12696 (match_dup 5) 12697 (match_dup 6)))] 12698{ 12699 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3], 12700 const0_rtx); 12701 emit_insn (gen_rtx_SET (operands[3], 12702 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx))); 12703 if (int_reg_operand (operands[0], <MODE>mode)) 12704 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx)); 12705 else 12706 { 12707 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx)); 12708 emit_move_insn (operands[0], operands[4]); 12709 } 12710 /* No DONE so branch comes from the pattern. */ 12711}) 12712 12713;; patterns for bdnzt/bdnzf/bdzt/bdzf 12714;; Note that in the case of long branches we have to decompose this into 12715;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition 12716;; and the CR bit, which means there is no way to conveniently invert the 12717;; comparison as is done with plain bdnz/bdz. 12718 12719(define_insn "<bd>tf_<mode>" 12720 [(set (pc) 12721 (if_then_else 12722 (and 12723 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12724 (const_int 1)) 12725 (match_operator 3 "branch_comparison_operator" 12726 [(match_operand 4 "cc_reg_operand" "y,y,y,y") 12727 (const_int 0)])) 12728 (label_ref (match_operand 0)) 12729 (pc))) 12730 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") 12731 (plus:P (match_dup 1) 12732 (const_int -1))) 12733 (clobber (match_scratch:P 5 "=X,X,&r,r")) 12734 (clobber (match_scratch:CC 6 "=X,&y,&y,&y")) 12735 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))] 12736 "" 12737{ 12738 if (which_alternative != 0) 12739 return "#"; 12740 else if (get_attr_length (insn) == 4) 12741 { 12742 if (branch_positive_comparison_operator (operands[3], 12743 GET_MODE (operands[3]))) 12744 return "<bd>t %j3,%l0"; 12745 else 12746 return "<bd>f %j3,%l0"; 12747 } 12748 else 12749 { 12750 static char seq[96]; 12751 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn); 12752 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs); 12753 return seq; 12754 } 12755} 12756 [(set_attr "type" "branch") 12757 (set_attr "length" "*,16,20,20")]) 12758 12759;; Now the splitter if we could not allocate the CTR register 12760(define_split 12761 [(set (pc) 12762 (if_then_else 12763 (and 12764 (match_operator 1 "comparison_operator" 12765 [(match_operand:P 0 "gpc_reg_operand") 12766 (const_int 1)]) 12767 (match_operator 3 "branch_comparison_operator" 12768 [(match_operand 2 "cc_reg_operand") 12769 (const_int 0)])) 12770 (match_operand 4) 12771 (match_operand 5))) 12772 (set (match_operand:P 6 "nonimmediate_operand") 12773 (plus:P (match_dup 0) 12774 (const_int -1))) 12775 (clobber (match_scratch:P 7)) 12776 (clobber (match_scratch:CC 8)) 12777 (clobber (match_scratch:CCEQ 9))] 12778 "reload_completed" 12779[(pc)] 12780{ 12781 rtx ctr = operands[0]; 12782 rtx ctrcmp = operands[1]; 12783 rtx ccin = operands[2]; 12784 rtx cccmp = operands[3]; 12785 rtx dst1 = operands[4]; 12786 rtx dst2 = operands[5]; 12787 rtx ctrout = operands[6]; 12788 rtx ctrtmp = operands[7]; 12789 enum rtx_code cmpcode = GET_CODE (ctrcmp); 12790 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp)); 12791 if (!ispos) 12792 cmpcode = reverse_condition (cmpcode); 12793 /* Generate crand/crandc here. */ 12794 emit_insn (gen_rtx_SET (operands[8], 12795 gen_rtx_COMPARE (CCmode, ctr, const1_rtx))); 12796 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx); 12797 12798 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp); 12799 if (ispos) 12800 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc, 12801 operands[8], cccmp, ccin)); 12802 else 12803 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc, 12804 operands[8], cccmp, ccin)); 12805 if (int_reg_operand (ctrout, <MODE>mode)) 12806 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx)); 12807 else 12808 { 12809 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx)); 12810 emit_move_insn (ctrout, ctrtmp); 12811 } 12812 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx); 12813 emit_jump_insn (gen_rtx_SET (pc_rtx, 12814 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp, 12815 dst1, dst2))); 12816 DONE; 12817}) 12818 12819 12820(define_insn "trap" 12821 [(trap_if (const_int 1) (const_int 0))] 12822 "" 12823 "trap" 12824 [(set_attr "type" "trap")]) 12825 12826(define_expand "ctrap<mode>4" 12827 [(trap_if (match_operator 0 "ordered_comparison_operator" 12828 [(match_operand:GPR 1 "register_operand") 12829 (match_operand:GPR 2 "reg_or_short_operand")]) 12830 (match_operand 3 "zero_constant" ""))] 12831 "" 12832 "") 12833 12834(define_insn "" 12835 [(trap_if (match_operator 0 "ordered_comparison_operator" 12836 [(match_operand:GPR 1 "register_operand" "r") 12837 (match_operand:GPR 2 "reg_or_short_operand" "rI")]) 12838 (const_int 0))] 12839 "" 12840 "t<wd>%V0%I2 %1,%2" 12841 [(set_attr "type" "trap")]) 12842 12843;; Insns related to generating the function prologue and epilogue. 12844 12845(define_expand "prologue" 12846 [(use (const_int 0))] 12847 "" 12848{ 12849 rs6000_emit_prologue (); 12850 if (!TARGET_SCHED_PROLOG) 12851 emit_insn (gen_blockage ()); 12852 DONE; 12853}) 12854 12855(define_insn "*movesi_from_cr_one" 12856 [(match_parallel 0 "mfcr_operation" 12857 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 12858 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y") 12859 (match_operand 3 "immediate_operand" "n")] 12860 UNSPEC_MOVESI_FROM_CR))])] 12861 "TARGET_MFCRF" 12862{ 12863 int mask = 0; 12864 int i; 12865 for (i = 0; i < XVECLEN (operands[0], 0); i++) 12866 { 12867 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 12868 operands[4] = GEN_INT (mask); 12869 output_asm_insn ("mfcr %1,%4", operands); 12870 } 12871 return ""; 12872} 12873 [(set_attr "type" "mfcrf")]) 12874 12875;; Don't include the volatile CRs since their values are not used wrt CR save 12876;; in the prologue and doing so prevents shrink-wrapping because we can't move the 12877;; prologue past an insn (early exit test) that defines a register used in the 12878;; prologue. 12879(define_insn "prologue_movesi_from_cr" 12880 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 12881 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO) 12882 (reg:CC CR4_REGNO)] 12883 UNSPEC_MOVESI_FROM_CR))] 12884 "" 12885 "mfcr %0" 12886 [(set_attr "type" "mfcr")]) 12887 12888(define_insn "*crsave" 12889 [(match_parallel 0 "crsave_operation" 12890 [(set (match_operand:SI 1 "memory_operand" "=m") 12891 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 12892 "" 12893 "stw %2,%1" 12894 [(set_attr "type" "store")]) 12895 12896(define_insn "*stmw" 12897 [(match_parallel 0 "stmw_operation" 12898 [(set (match_operand:SI 1 "memory_operand" "=m") 12899 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 12900 "TARGET_MULTIPLE" 12901 "stmw %2,%1" 12902 [(set_attr "type" "store") 12903 (set_attr "update" "yes") 12904 (set_attr "indexed" "yes")]) 12905 12906; The following comment applies to: 12907; save_gpregs_* 12908; save_fpregs_* 12909; restore_gpregs* 12910; return_and_restore_gpregs* 12911; return_and_restore_fpregs* 12912; return_and_restore_fpregs_aix* 12913; 12914; The out-of-line save / restore functions expects one input argument. 12915; Since those are not standard call_insn's, we must avoid using 12916; MATCH_OPERAND for that argument. That way the register rename 12917; optimization will not try to rename this register. 12918; Each pattern is repeated for each possible register number used in 12919; various ABIs (r11, r1, and for some functions r12) 12920 12921(define_insn "*save_gpregs_<mode>_r11" 12922 [(match_parallel 0 "any_parallel_operand" 12923 [(clobber (reg:P LR_REGNO)) 12924 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12925 (use (reg:P 11)) 12926 (set (match_operand:P 2 "memory_operand" "=m") 12927 (match_operand:P 3 "gpc_reg_operand" "r"))])] 12928 "" 12929 "bl %1" 12930 [(set_attr "type" "branch") 12931 (set_attr "length" "4")]) 12932 12933(define_insn "*save_gpregs_<mode>_r12" 12934 [(match_parallel 0 "any_parallel_operand" 12935 [(clobber (reg:P LR_REGNO)) 12936 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12937 (use (reg:P 12)) 12938 (set (match_operand:P 2 "memory_operand" "=m") 12939 (match_operand:P 3 "gpc_reg_operand" "r"))])] 12940 "" 12941 "bl %1" 12942 [(set_attr "type" "branch") 12943 (set_attr "length" "4")]) 12944 12945(define_insn "*save_gpregs_<mode>_r1" 12946 [(match_parallel 0 "any_parallel_operand" 12947 [(clobber (reg:P LR_REGNO)) 12948 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12949 (use (reg:P 1)) 12950 (set (match_operand:P 2 "memory_operand" "=m") 12951 (match_operand:P 3 "gpc_reg_operand" "r"))])] 12952 "" 12953 "bl %1" 12954 [(set_attr "type" "branch") 12955 (set_attr "length" "4")]) 12956 12957(define_insn "*save_fpregs_<mode>_r11" 12958 [(match_parallel 0 "any_parallel_operand" 12959 [(clobber (reg:P LR_REGNO)) 12960 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12961 (use (reg:P 11)) 12962 (set (match_operand:DF 2 "memory_operand" "=m") 12963 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 12964 "" 12965 "bl %1" 12966 [(set_attr "type" "branch") 12967 (set_attr "length" "4")]) 12968 12969(define_insn "*save_fpregs_<mode>_r12" 12970 [(match_parallel 0 "any_parallel_operand" 12971 [(clobber (reg:P LR_REGNO)) 12972 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12973 (use (reg:P 12)) 12974 (set (match_operand:DF 2 "memory_operand" "=m") 12975 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 12976 "" 12977 "bl %1" 12978 [(set_attr "type" "branch") 12979 (set_attr "length" "4")]) 12980 12981(define_insn "*save_fpregs_<mode>_r1" 12982 [(match_parallel 0 "any_parallel_operand" 12983 [(clobber (reg:P LR_REGNO)) 12984 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12985 (use (reg:P 1)) 12986 (set (match_operand:DF 2 "memory_operand" "=m") 12987 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 12988 "" 12989 "bl %1" 12990 [(set_attr "type" "branch") 12991 (set_attr "length" "4")]) 12992 12993; This is to explain that changes to the stack pointer should 12994; not be moved over loads from or stores to stack memory. 12995(define_insn "stack_tie" 12996 [(match_parallel 0 "tie_operand" 12997 [(set (mem:BLK (reg 1)) (const_int 0))])] 12998 "" 12999 "" 13000 [(set_attr "length" "0")]) 13001 13002; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to 13003; stay behind all restores from the stack, it cannot be reordered to before 13004; one. See PR77687. This insn is an add or mr, and a memory clobber. 13005(define_insn "stack_restore_tie" 13006 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 13007 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") 13008 (match_operand:SI 2 "reg_or_cint_operand" "O,rI"))) 13009 (set (mem:BLK (scratch)) (const_int 0))] 13010 "TARGET_32BIT" 13011 "@ 13012 mr %0,%1 13013 add%I2 %0,%1,%2" 13014 [(set_attr "type" "*,add")]) 13015 13016(define_expand "epilogue" 13017 [(use (const_int 0))] 13018 "" 13019{ 13020 if (!TARGET_SCHED_PROLOG) 13021 emit_insn (gen_blockage ()); 13022 rs6000_emit_epilogue (FALSE); 13023 DONE; 13024}) 13025 13026; On some processors, doing the mtcrf one CC register at a time is 13027; faster (like on the 604e). On others, doing them all at once is 13028; faster; for instance, on the 601 and 750. 13029 13030(define_expand "movsi_to_cr_one" 13031 [(set (match_operand:CC 0 "cc_reg_operand") 13032 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand") 13033 (match_dup 2)] UNSPEC_MOVESI_TO_CR))] 13034 "" 13035 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") 13036 13037(define_insn "*movsi_to_cr" 13038 [(match_parallel 0 "mtcrf_operation" 13039 [(set (match_operand:CC 1 "cc_reg_operand" "=y") 13040 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r") 13041 (match_operand 3 "immediate_operand" "n")] 13042 UNSPEC_MOVESI_TO_CR))])] 13043 "" 13044{ 13045 int mask = 0; 13046 int i; 13047 for (i = 0; i < XVECLEN (operands[0], 0); i++) 13048 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 13049 operands[4] = GEN_INT (mask); 13050 return "mtcrf %4,%2"; 13051} 13052 [(set_attr "type" "mtcr")]) 13053 13054(define_insn "*mtcrfsi" 13055 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 13056 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 13057 (match_operand 2 "immediate_operand" "n")] 13058 UNSPEC_MOVESI_TO_CR))] 13059 "GET_CODE (operands[0]) == REG 13060 && CR_REGNO_P (REGNO (operands[0])) 13061 && GET_CODE (operands[2]) == CONST_INT 13062 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))" 13063 "mtcrf %R0,%1" 13064 [(set_attr "type" "mtcr")]) 13065 13066; The load-multiple instructions have similar properties. 13067; Note that "load_multiple" is a name known to the machine-independent 13068; code that actually corresponds to the PowerPC load-string. 13069 13070(define_insn "*lmw" 13071 [(match_parallel 0 "lmw_operation" 13072 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 13073 (match_operand:SI 2 "memory_operand" "m"))])] 13074 "TARGET_MULTIPLE" 13075 "lmw %1,%2" 13076 [(set_attr "type" "load") 13077 (set_attr "update" "yes") 13078 (set_attr "indexed" "yes") 13079 (set_attr "cell_micro" "always")]) 13080 13081; FIXME: This would probably be somewhat simpler if the Cygnus sibcall 13082; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... 13083 13084; The following comment applies to: 13085; save_gpregs_* 13086; save_fpregs_* 13087; restore_gpregs* 13088; return_and_restore_gpregs* 13089; return_and_restore_fpregs* 13090; return_and_restore_fpregs_aix* 13091; 13092; The out-of-line save / restore functions expects one input argument. 13093; Since those are not standard call_insn's, we must avoid using 13094; MATCH_OPERAND for that argument. That way the register rename 13095; optimization will not try to rename this register. 13096; Each pattern is repeated for each possible register number used in 13097; various ABIs (r11, r1, and for some functions r12) 13098 13099(define_insn "*restore_gpregs_<mode>_r11" 13100 [(match_parallel 0 "any_parallel_operand" 13101 [(clobber (reg:P LR_REGNO)) 13102 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13103 (use (reg:P 11)) 13104 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13105 (match_operand:P 3 "memory_operand" "m"))])] 13106 "" 13107 "bl %1" 13108 [(set_attr "type" "branch") 13109 (set_attr "length" "4")]) 13110 13111(define_insn "*restore_gpregs_<mode>_r12" 13112 [(match_parallel 0 "any_parallel_operand" 13113 [(clobber (reg:P LR_REGNO)) 13114 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13115 (use (reg:P 12)) 13116 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13117 (match_operand:P 3 "memory_operand" "m"))])] 13118 "" 13119 "bl %1" 13120 [(set_attr "type" "branch") 13121 (set_attr "length" "4")]) 13122 13123(define_insn "*restore_gpregs_<mode>_r1" 13124 [(match_parallel 0 "any_parallel_operand" 13125 [(clobber (reg:P LR_REGNO)) 13126 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13127 (use (reg:P 1)) 13128 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13129 (match_operand:P 3 "memory_operand" "m"))])] 13130 "" 13131 "bl %1" 13132 [(set_attr "type" "branch") 13133 (set_attr "length" "4")]) 13134 13135(define_insn "*return_and_restore_gpregs_<mode>_r11" 13136 [(match_parallel 0 "any_parallel_operand" 13137 [(return) 13138 (clobber (reg:P LR_REGNO)) 13139 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13140 (use (reg:P 11)) 13141 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13142 (match_operand:P 3 "memory_operand" "m"))])] 13143 "" 13144 "b %1" 13145 [(set_attr "type" "branch") 13146 (set_attr "length" "4")]) 13147 13148(define_insn "*return_and_restore_gpregs_<mode>_r12" 13149 [(match_parallel 0 "any_parallel_operand" 13150 [(return) 13151 (clobber (reg:P LR_REGNO)) 13152 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13153 (use (reg:P 12)) 13154 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13155 (match_operand:P 3 "memory_operand" "m"))])] 13156 "" 13157 "b %1" 13158 [(set_attr "type" "branch") 13159 (set_attr "length" "4")]) 13160 13161(define_insn "*return_and_restore_gpregs_<mode>_r1" 13162 [(match_parallel 0 "any_parallel_operand" 13163 [(return) 13164 (clobber (reg:P LR_REGNO)) 13165 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13166 (use (reg:P 1)) 13167 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13168 (match_operand:P 3 "memory_operand" "m"))])] 13169 "" 13170 "b %1" 13171 [(set_attr "type" "branch") 13172 (set_attr "length" "4")]) 13173 13174(define_insn "*return_and_restore_fpregs_<mode>_r11" 13175 [(match_parallel 0 "any_parallel_operand" 13176 [(return) 13177 (clobber (reg:P LR_REGNO)) 13178 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13179 (use (reg:P 11)) 13180 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13181 (match_operand:DF 3 "memory_operand" "m"))])] 13182 "" 13183 "b %1" 13184 [(set_attr "type" "branch") 13185 (set_attr "length" "4")]) 13186 13187(define_insn "*return_and_restore_fpregs_<mode>_r12" 13188 [(match_parallel 0 "any_parallel_operand" 13189 [(return) 13190 (clobber (reg:P LR_REGNO)) 13191 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13192 (use (reg:P 12)) 13193 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13194 (match_operand:DF 3 "memory_operand" "m"))])] 13195 "" 13196 "b %1" 13197 [(set_attr "type" "branch") 13198 (set_attr "length" "4")]) 13199 13200(define_insn "*return_and_restore_fpregs_<mode>_r1" 13201 [(match_parallel 0 "any_parallel_operand" 13202 [(return) 13203 (clobber (reg:P LR_REGNO)) 13204 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13205 (use (reg:P 1)) 13206 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13207 (match_operand:DF 3 "memory_operand" "m"))])] 13208 "" 13209 "b %1" 13210 [(set_attr "type" "branch") 13211 (set_attr "length" "4")]) 13212 13213(define_insn "*return_and_restore_fpregs_aix_<mode>_r11" 13214 [(match_parallel 0 "any_parallel_operand" 13215 [(return) 13216 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13217 (use (reg:P 11)) 13218 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13219 (match_operand:DF 3 "memory_operand" "m"))])] 13220 "" 13221 "b %1" 13222 [(set_attr "type" "branch") 13223 (set_attr "length" "4")]) 13224 13225(define_insn "*return_and_restore_fpregs_aix_<mode>_r1" 13226 [(match_parallel 0 "any_parallel_operand" 13227 [(return) 13228 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13229 (use (reg:P 1)) 13230 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13231 (match_operand:DF 3 "memory_operand" "m"))])] 13232 "" 13233 "b %1" 13234 [(set_attr "type" "branch") 13235 (set_attr "length" "4")]) 13236 13237; This is used in compiling the unwind routines. 13238(define_expand "eh_return" 13239 [(use (match_operand 0 "general_operand"))] 13240 "" 13241{ 13242 if (TARGET_32BIT) 13243 emit_insn (gen_eh_set_lr_si (operands[0])); 13244 else 13245 emit_insn (gen_eh_set_lr_di (operands[0])); 13246 DONE; 13247}) 13248 13249; We can't expand this before we know where the link register is stored. 13250(define_insn "eh_set_lr_<mode>" 13251 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 13252 UNSPECV_EH_RR) 13253 (clobber (match_scratch:P 1 "=&b"))] 13254 "" 13255 "#") 13256 13257(define_split 13258 [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR) 13259 (clobber (match_scratch 1))] 13260 "reload_completed" 13261 [(const_int 0)] 13262{ 13263 rs6000_emit_eh_reg_restore (operands[0], operands[1]); 13264 DONE; 13265}) 13266 13267(define_insn "prefetch" 13268 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a") 13269 (match_operand:SI 1 "const_int_operand" "n") 13270 (match_operand:SI 2 "const_int_operand" "n"))] 13271 "" 13272{ 13273 if (GET_CODE (operands[0]) == REG) 13274 return INTVAL (operands[1]) ? "dcbtst 0,%0" : "dcbt 0,%0"; 13275 return INTVAL (operands[1]) ? "dcbtst %a0" : "dcbt %a0"; 13276} 13277 [(set_attr "type" "load")]) 13278 13279;; Handle -fsplit-stack. 13280 13281(define_expand "split_stack_prologue" 13282 [(const_int 0)] 13283 "" 13284{ 13285 rs6000_expand_split_stack_prologue (); 13286 DONE; 13287}) 13288 13289(define_expand "load_split_stack_limit" 13290 [(set (match_operand 0) 13291 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))] 13292 "" 13293{ 13294 emit_insn (gen_rtx_SET (operands[0], 13295 gen_rtx_UNSPEC (Pmode, 13296 gen_rtvec (1, const0_rtx), 13297 UNSPEC_STACK_CHECK))); 13298 DONE; 13299}) 13300 13301(define_insn "load_split_stack_limit_di" 13302 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 13303 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))] 13304 "TARGET_64BIT" 13305 "ld %0,-0x7040(13)" 13306 [(set_attr "type" "load") 13307 (set_attr "update" "no") 13308 (set_attr "indexed" "no")]) 13309 13310(define_insn "load_split_stack_limit_si" 13311 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 13312 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))] 13313 "!TARGET_64BIT" 13314 "lwz %0,-0x7020(2)" 13315 [(set_attr "type" "load") 13316 (set_attr "update" "no") 13317 (set_attr "indexed" "no")]) 13318 13319;; A return instruction which the middle-end doesn't see. 13320;; Use r0 to stop regrename twiddling with lr restore insns emitted 13321;; after the call to __morestack. 13322(define_insn "split_stack_return" 13323 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)] 13324 "" 13325 "blr" 13326 [(set_attr "type" "jmpreg")]) 13327 13328;; If there are operand 0 bytes available on the stack, jump to 13329;; operand 1. 13330(define_expand "split_stack_space_check" 13331 [(set (match_dup 2) 13332 (unspec [(const_int 0)] UNSPEC_STACK_CHECK)) 13333 (set (match_dup 3) 13334 (minus (reg STACK_POINTER_REGNUM) 13335 (match_operand 0))) 13336 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2))) 13337 (set (pc) (if_then_else 13338 (geu (match_dup 4) (const_int 0)) 13339 (label_ref (match_operand 1)) 13340 (pc)))] 13341 "" 13342{ 13343 rs6000_split_stack_space_check (operands[0], operands[1]); 13344 DONE; 13345}) 13346 13347(define_insn "bpermd_<mode>" 13348 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 13349 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") 13350 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))] 13351 "TARGET_POPCNTD" 13352 "bpermd %0,%1,%2" 13353 [(set_attr "type" "popcnt")]) 13354 13355 13356;; Builtin fma support. Handle 13357;; Note that the conditions for expansion are in the FMA_F iterator. 13358 13359(define_expand "fma<mode>4" 13360 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13361 (fma:FMA_F 13362 (match_operand:FMA_F 1 "gpc_reg_operand") 13363 (match_operand:FMA_F 2 "gpc_reg_operand") 13364 (match_operand:FMA_F 3 "gpc_reg_operand")))] 13365 "" 13366 "") 13367 13368(define_insn "*fma<mode>4_fpr" 13369 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 13370 (fma:SFDF 13371 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>") 13372 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 13373 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))] 13374 "TARGET_<MODE>_FPR" 13375 "@ 13376 fmadd<Ftrad> %0,%1,%2,%3 13377 xsmadda<Fvsx> %x0,%x1,%x2 13378 xsmaddm<Fvsx> %x0,%x1,%x3" 13379 [(set_attr "type" "fp") 13380 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 13381 13382; Altivec only has fma and nfms. 13383(define_expand "fms<mode>4" 13384 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13385 (fma:FMA_F 13386 (match_operand:FMA_F 1 "gpc_reg_operand") 13387 (match_operand:FMA_F 2 "gpc_reg_operand") 13388 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))] 13389 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13390 "") 13391 13392(define_insn "*fms<mode>4_fpr" 13393 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 13394 (fma:SFDF 13395 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") 13396 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 13397 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] 13398 "TARGET_<MODE>_FPR" 13399 "@ 13400 fmsub<Ftrad> %0,%1,%2,%3 13401 xsmsuba<Fvsx> %x0,%x1,%x2 13402 xsmsubm<Fvsx> %x0,%x1,%x3" 13403 [(set_attr "type" "fp") 13404 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 13405 13406;; If signed zeros are ignored, -(a * b - c) = -a * b + c. 13407(define_expand "fnma<mode>4" 13408 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13409 (neg:FMA_F 13410 (fma:FMA_F 13411 (match_operand:FMA_F 1 "gpc_reg_operand") 13412 (match_operand:FMA_F 2 "gpc_reg_operand") 13413 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))] 13414 "!HONOR_SIGNED_ZEROS (<MODE>mode)" 13415 "") 13416 13417;; If signed zeros are ignored, -(a * b + c) = -a * b - c. 13418(define_expand "fnms<mode>4" 13419 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13420 (neg:FMA_F 13421 (fma:FMA_F 13422 (match_operand:FMA_F 1 "gpc_reg_operand") 13423 (match_operand:FMA_F 2 "gpc_reg_operand") 13424 (match_operand:FMA_F 3 "gpc_reg_operand"))))] 13425 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13426 "") 13427 13428; Not an official optab name, but used from builtins. 13429(define_expand "nfma<mode>4" 13430 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13431 (neg:FMA_F 13432 (fma:FMA_F 13433 (match_operand:FMA_F 1 "gpc_reg_operand") 13434 (match_operand:FMA_F 2 "gpc_reg_operand") 13435 (match_operand:FMA_F 3 "gpc_reg_operand"))))] 13436 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13437 "") 13438 13439(define_insn "*nfma<mode>4_fpr" 13440 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 13441 (neg:SFDF 13442 (fma:SFDF 13443 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") 13444 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 13445 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] 13446 "TARGET_<MODE>_FPR" 13447 "@ 13448 fnmadd<Ftrad> %0,%1,%2,%3 13449 xsnmadda<Fvsx> %x0,%x1,%x2 13450 xsnmaddm<Fvsx> %x0,%x1,%x3" 13451 [(set_attr "type" "fp") 13452 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 13453 13454; Not an official optab name, but used from builtins. 13455(define_expand "nfms<mode>4" 13456 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13457 (neg:FMA_F 13458 (fma:FMA_F 13459 (match_operand:FMA_F 1 "gpc_reg_operand") 13460 (match_operand:FMA_F 2 "gpc_reg_operand") 13461 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))] 13462 "" 13463 "") 13464 13465(define_insn "*nfmssf4_fpr" 13466 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 13467 (neg:SFDF 13468 (fma:SFDF 13469 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") 13470 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 13471 (neg:SFDF 13472 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))] 13473 "TARGET_<MODE>_FPR" 13474 "@ 13475 fnmsub<Ftrad> %0,%1,%2,%3 13476 xsnmsuba<Fvsx> %x0,%x1,%x2 13477 xsnmsubm<Fvsx> %x0,%x1,%x3" 13478 [(set_attr "type" "fp") 13479 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 13480 13481 13482(define_expand "rs6000_get_timebase" 13483 [(use (match_operand:DI 0 "gpc_reg_operand"))] 13484 "" 13485{ 13486 if (TARGET_POWERPC64) 13487 emit_insn (gen_rs6000_mftb_di (operands[0])); 13488 else 13489 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0])); 13490 DONE; 13491}) 13492 13493(define_insn "rs6000_get_timebase_ppc32" 13494 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 13495 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB)) 13496 (clobber (match_scratch:SI 1 "=r")) 13497 (clobber (match_scratch:CC 2 "=y"))] 13498 "!TARGET_POWERPC64" 13499{ 13500 if (WORDS_BIG_ENDIAN) 13501 if (TARGET_MFCRF) 13502 { 13503 return "mfspr %0,269\;" 13504 "mfspr %L0,268\;" 13505 "mfspr %1,269\;" 13506 "cmpw %2,%0,%1\;" 13507 "bne- %2,$-16"; 13508 } 13509 else 13510 { 13511 return "mftbu %0\;" 13512 "mftb %L0\;" 13513 "mftbu %1\;" 13514 "cmpw %2,%0,%1\;" 13515 "bne- %2,$-16"; 13516 } 13517 else 13518 if (TARGET_MFCRF) 13519 { 13520 return "mfspr %L0,269\;" 13521 "mfspr %0,268\;" 13522 "mfspr %1,269\;" 13523 "cmpw %2,%L0,%1\;" 13524 "bne- %2,$-16"; 13525 } 13526 else 13527 { 13528 return "mftbu %L0\;" 13529 "mftb %0\;" 13530 "mftbu %1\;" 13531 "cmpw %2,%L0,%1\;" 13532 "bne- %2,$-16"; 13533 } 13534} 13535 [(set_attr "length" "20")]) 13536 13537(define_insn "rs6000_mftb_<mode>" 13538 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 13539 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))] 13540 "" 13541{ 13542 if (TARGET_MFCRF) 13543 return "mfspr %0,268"; 13544 else 13545 return "mftb %0"; 13546}) 13547 13548 13549(define_insn "rs6000_mffs" 13550 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 13551 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))] 13552 "TARGET_HARD_FLOAT" 13553 "mffs %0") 13554 13555(define_insn "rs6000_mtfsf" 13556 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i") 13557 (match_operand:DF 1 "gpc_reg_operand" "d")] 13558 UNSPECV_MTFSF)] 13559 "TARGET_HARD_FLOAT" 13560 "mtfsf %0,%1") 13561 13562 13563;; Power8 fusion support for fusing an addis instruction with a D-form load of 13564;; a GPR. The addis instruction must be adjacent to the load, and use the same 13565;; register that is being loaded. The fused ops must be physically adjacent. 13566 13567;; There are two parts to addis fusion. The support for fused TOCs occur 13568;; before register allocation, and is meant to reduce the lifetime for the 13569;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try 13570;; to use the register that is being load. The peephole2 then gathers any 13571;; other fused possibilities that it can find after register allocation. If 13572;; power9 fusion is selected, we also fuse floating point loads/stores. 13573 13574;; Fused TOC support: Replace simple GPR loads with a fused form. This is done 13575;; before register allocation, so that we can avoid allocating a temporary base 13576;; register that won't be used, and that we try to load into base registers, 13577;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion 13578;; (addis followed by load) even on power8. 13579 13580(define_split 13581 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand") 13582 (match_operand:INT1 1 "toc_fusion_mem_raw"))] 13583 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()" 13584 [(parallel [(set (match_dup 0) (match_dup 2)) 13585 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) 13586 (use (match_dup 3)) 13587 (clobber (scratch:DI))])] 13588{ 13589 operands[2] = fusion_wrap_memory_address (operands[1]); 13590 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER); 13591}) 13592 13593(define_insn "*toc_fusionload_<mode>" 13594 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r") 13595 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG")) 13596 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) 13597 (use (match_operand:DI 2 "base_reg_operand" "r,r")) 13598 (clobber (match_scratch:DI 3 "=X,&b"))] 13599 "TARGET_TOC_FUSION_INT" 13600{ 13601 if (base_reg_operand (operands[0], <MODE>mode)) 13602 return emit_fusion_gpr_load (operands[0], operands[1]); 13603 13604 return emit_fusion_p9_load (operands[0], operands[1], operands[3]); 13605} 13606 [(set_attr "type" "load") 13607 (set_attr "length" "8")]) 13608 13609(define_insn "*toc_fusionload_di" 13610 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d") 13611 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG")) 13612 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) 13613 (use (match_operand:DI 2 "base_reg_operand" "r,r,r")) 13614 (clobber (match_scratch:DI 3 "=X,&b,&b"))] 13615 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64 13616 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))" 13617{ 13618 if (base_reg_operand (operands[0], DImode)) 13619 return emit_fusion_gpr_load (operands[0], operands[1]); 13620 13621 return emit_fusion_p9_load (operands[0], operands[1], operands[3]); 13622} 13623 [(set_attr "type" "load") 13624 (set_attr "length" "8")]) 13625 13626 13627;; Find cases where the addis that feeds into a load instruction is either used 13628;; once or is the same as the target register, and replace it with the fusion 13629;; insn 13630 13631(define_peephole2 13632 [(set (match_operand:P 0 "base_reg_operand") 13633 (match_operand:P 1 "fusion_gpr_addis")) 13634 (set (match_operand:INT1 2 "base_reg_operand") 13635 (match_operand:INT1 3 "fusion_gpr_mem_load"))] 13636 "TARGET_P8_FUSION 13637 && fusion_gpr_load_p (operands[0], operands[1], operands[2], 13638 operands[3])" 13639 [(const_int 0)] 13640{ 13641 expand_fusion_gpr_load (operands); 13642 DONE; 13643}) 13644 13645;; Fusion insn, created by the define_peephole2 above (and eventually by 13646;; reload) 13647 13648(define_insn "fusion_gpr_load_<mode>" 13649 [(set (match_operand:INT1 0 "base_reg_operand" "=b") 13650 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")] 13651 UNSPEC_FUSION_GPR))] 13652 "TARGET_P8_FUSION" 13653{ 13654 return emit_fusion_gpr_load (operands[0], operands[1]); 13655} 13656 [(set_attr "type" "load") 13657 (set_attr "length" "8")]) 13658 13659 13660;; ISA 3.0 (power9) fusion support 13661;; Merge addis with floating load/store to FPRs (or GPRs). 13662(define_peephole2 13663 [(set (match_operand:P 0 "base_reg_operand") 13664 (match_operand:P 1 "fusion_gpr_addis")) 13665 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand") 13666 (match_operand:SFDF 3 "fusion_offsettable_mem_operand"))] 13667 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0]) 13668 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])" 13669 [(const_int 0)] 13670{ 13671 expand_fusion_p9_load (operands); 13672 DONE; 13673}) 13674 13675(define_peephole2 13676 [(set (match_operand:P 0 "base_reg_operand") 13677 (match_operand:P 1 "fusion_gpr_addis")) 13678 (set (match_operand:SFDF 2 "offsettable_mem_operand") 13679 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand"))] 13680 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0]) 13681 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3]) 13682 && !rtx_equal_p (operands[0], operands[3])" 13683 [(const_int 0)] 13684{ 13685 expand_fusion_p9_store (operands); 13686 DONE; 13687}) 13688 13689(define_peephole2 13690 [(set (match_operand:SDI 0 "int_reg_operand") 13691 (match_operand:SDI 1 "upper16_cint_operand")) 13692 (set (match_dup 0) 13693 (ior:SDI (match_dup 0) 13694 (match_operand:SDI 2 "u_short_cint_operand")))] 13695 "TARGET_P9_FUSION" 13696 [(set (match_dup 0) 13697 (unspec:SDI [(match_dup 1) 13698 (match_dup 2)] UNSPEC_FUSION_P9))]) 13699 13700(define_peephole2 13701 [(set (match_operand:SDI 0 "int_reg_operand") 13702 (match_operand:SDI 1 "upper16_cint_operand")) 13703 (set (match_operand:SDI 2 "int_reg_operand") 13704 (ior:SDI (match_dup 0) 13705 (match_operand:SDI 3 "u_short_cint_operand")))] 13706 "TARGET_P9_FUSION 13707 && !rtx_equal_p (operands[0], operands[2]) 13708 && peep2_reg_dead_p (2, operands[0])" 13709 [(set (match_dup 2) 13710 (unspec:SDI [(match_dup 1) 13711 (match_dup 3)] UNSPEC_FUSION_P9))]) 13712 13713;; Fusion insns, created by the define_peephole2 above (and eventually by 13714;; reload). Because we want to eventually have secondary_reload generate 13715;; these, they have to have a single alternative that gives the register 13716;; classes. This means we need to have separate gpr/fpr/altivec versions. 13717(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load" 13718 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r") 13719 (unspec:GPR_FUSION 13720 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")] 13721 UNSPEC_FUSION_P9)) 13722 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 13723 "TARGET_P9_FUSION" 13724{ 13725 /* This insn is a secondary reload insn, which cannot have alternatives. 13726 If we are not loading up register 0, use the power8 fusion instead. */ 13727 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode)) 13728 return emit_fusion_gpr_load (operands[0], operands[1]); 13729 13730 return emit_fusion_p9_load (operands[0], operands[1], operands[2]); 13731} 13732 [(set_attr "type" "load") 13733 (set_attr "length" "8")]) 13734 13735(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store" 13736 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF") 13737 (unspec:GPR_FUSION 13738 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")] 13739 UNSPEC_FUSION_P9)) 13740 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 13741 "TARGET_P9_FUSION" 13742{ 13743 return emit_fusion_p9_store (operands[0], operands[1], operands[2]); 13744} 13745 [(set_attr "type" "store") 13746 (set_attr "length" "8")]) 13747 13748(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load" 13749 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb") 13750 (unspec:FPR_FUSION 13751 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")] 13752 UNSPEC_FUSION_P9)) 13753 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 13754 "TARGET_P9_FUSION" 13755{ 13756 return emit_fusion_p9_load (operands[0], operands[1], operands[2]); 13757} 13758 [(set_attr "type" "fpload") 13759 (set_attr "length" "8")]) 13760 13761(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store" 13762 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF") 13763 (unspec:FPR_FUSION 13764 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")] 13765 UNSPEC_FUSION_P9)) 13766 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 13767 "TARGET_P9_FUSION" 13768{ 13769 return emit_fusion_p9_store (operands[0], operands[1], operands[2]); 13770} 13771 [(set_attr "type" "fpstore") 13772 (set_attr "length" "8")]) 13773 13774(define_insn "*fusion_p9_<mode>_constant" 13775 [(set (match_operand:SDI 0 "int_reg_operand" "=r") 13776 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L") 13777 (match_operand:SDI 2 "u_short_cint_operand" "K")] 13778 UNSPEC_FUSION_P9))] 13779 "TARGET_P9_FUSION" 13780{ 13781 emit_fusion_addis (operands[0], operands[1]); 13782 return "ori %0,%0,%2"; 13783} 13784 [(set_attr "type" "two") 13785 (set_attr "length" "8")]) 13786 13787 13788;; Optimize cases where we want to do a D-form load (register+offset) on 13789;; ISA 2.06/2.07 to an Altivec register, and the register allocator 13790;; has generated: 13791;; LFD 0,32(3) 13792;; XXLOR 32,0,0 13793;; 13794;; and we change this to: 13795;; LI 0,32 13796;; LXSDX 32,3,9 13797 13798(define_peephole2 13799 [(match_scratch:P 0 "b") 13800 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 13801 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand")) 13802 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand") 13803 (match_dup 1))] 13804 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])" 13805 [(set (match_dup 0) 13806 (match_dup 4)) 13807 (set (match_dup 3) 13808 (match_dup 5))] 13809{ 13810 rtx tmp_reg = operands[0]; 13811 rtx mem = operands[2]; 13812 rtx addr = XEXP (mem, 0); 13813 rtx add_op0, add_op1, new_addr; 13814 13815 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 13816 add_op0 = XEXP (addr, 0); 13817 add_op1 = XEXP (addr, 1); 13818 gcc_assert (REG_P (add_op0)); 13819 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); 13820 13821 operands[4] = add_op1; 13822 operands[5] = change_address (mem, <MODE>mode, new_addr); 13823}) 13824 13825;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an 13826;; Altivec register, and the register allocator has generated: 13827;; XXLOR 0,32,32 13828;; STFD 0,32(3) 13829;; 13830;; and we change this to: 13831;; LI 0,32 13832;; STXSDX 32,3,9 13833 13834(define_peephole2 13835 [(match_scratch:P 0 "b") 13836 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 13837 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand")) 13838 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand") 13839 (match_dup 1))] 13840 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])" 13841 [(set (match_dup 0) 13842 (match_dup 4)) 13843 (set (match_dup 5) 13844 (match_dup 2))] 13845{ 13846 rtx tmp_reg = operands[0]; 13847 rtx mem = operands[3]; 13848 rtx addr = XEXP (mem, 0); 13849 rtx add_op0, add_op1, new_addr; 13850 13851 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 13852 add_op0 = XEXP (addr, 0); 13853 add_op1 = XEXP (addr, 1); 13854 gcc_assert (REG_P (add_op0)); 13855 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); 13856 13857 operands[4] = add_op1; 13858 operands[5] = change_address (mem, <MODE>mode, new_addr); 13859}) 13860 13861 13862;; Miscellaneous ISA 2.06 (power7) instructions 13863(define_insn "addg6s" 13864 [(set (match_operand:SI 0 "register_operand" "=r") 13865 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 13866 (match_operand:SI 2 "register_operand" "r")] 13867 UNSPEC_ADDG6S))] 13868 "TARGET_POPCNTD" 13869 "addg6s %0,%1,%2" 13870 [(set_attr "type" "integer") 13871 (set_attr "length" "4")]) 13872 13873(define_insn "cdtbcd" 13874 [(set (match_operand:SI 0 "register_operand" "=r") 13875 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 13876 UNSPEC_CDTBCD))] 13877 "TARGET_POPCNTD" 13878 "cdtbcd %0,%1" 13879 [(set_attr "type" "integer") 13880 (set_attr "length" "4")]) 13881 13882(define_insn "cbcdtd" 13883 [(set (match_operand:SI 0 "register_operand" "=r") 13884 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 13885 UNSPEC_CBCDTD))] 13886 "TARGET_POPCNTD" 13887 "cbcdtd %0,%1" 13888 [(set_attr "type" "integer") 13889 (set_attr "length" "4")]) 13890 13891(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE 13892 UNSPEC_DIVEU]) 13893 13894(define_int_attr div_extend [(UNSPEC_DIVE "e") 13895 (UNSPEC_DIVEU "eu")]) 13896 13897(define_insn "div<div_extend>_<mode>" 13898 [(set (match_operand:GPR 0 "register_operand" "=r") 13899 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r") 13900 (match_operand:GPR 2 "register_operand" "r")] 13901 UNSPEC_DIV_EXTEND))] 13902 "TARGET_POPCNTD" 13903 "div<wd><div_extend> %0,%1,%2" 13904 [(set_attr "type" "div") 13905 (set_attr "size" "<bits>")]) 13906 13907 13908;; Pack/unpack 128-bit floating point types that take 2 scalar registers 13909 13910; Type of the 64-bit part when packing/unpacking 128-bit floating point types 13911(define_mode_attr FP128_64 [(TF "DF") 13912 (IF "DF") 13913 (TD "DI") 13914 (KF "DI")]) 13915 13916(define_expand "unpack<mode>" 13917 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand") 13918 (unspec:<FP128_64> 13919 [(match_operand:FMOVE128 1 "register_operand") 13920 (match_operand:QI 2 "const_0_to_1_operand")] 13921 UNSPEC_UNPACK_128BIT))] 13922 "FLOAT128_2REG_P (<MODE>mode)" 13923 "") 13924 13925(define_insn_and_split "unpack<mode>_dm" 13926 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m") 13927 (unspec:<FP128_64> 13928 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r") 13929 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")] 13930 UNSPEC_UNPACK_128BIT))] 13931 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)" 13932 "#" 13933 "&& reload_completed" 13934 [(set (match_dup 0) (match_dup 3))] 13935{ 13936 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 13937 13938 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 13939 { 13940 emit_note (NOTE_INSN_DELETED); 13941 DONE; 13942 } 13943 13944 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 13945} 13946 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store") 13947 (set_attr "length" "4")]) 13948 13949(define_insn_and_split "unpack<mode>_nodm" 13950 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m") 13951 (unspec:<FP128_64> 13952 [(match_operand:FMOVE128 1 "register_operand" "d,d") 13953 (match_operand:QI 2 "const_0_to_1_operand" "i,i")] 13954 UNSPEC_UNPACK_128BIT))] 13955 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)" 13956 "#" 13957 "&& reload_completed" 13958 [(set (match_dup 0) (match_dup 3))] 13959{ 13960 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 13961 13962 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 13963 { 13964 emit_note (NOTE_INSN_DELETED); 13965 DONE; 13966 } 13967 13968 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 13969} 13970 [(set_attr "type" "fp,fpstore") 13971 (set_attr "length" "4")]) 13972 13973(define_insn_and_split "pack<mode>" 13974 [(set (match_operand:FMOVE128 0 "register_operand" "=&d") 13975 (unspec:FMOVE128 13976 [(match_operand:<FP128_64> 1 "register_operand" "d") 13977 (match_operand:<FP128_64> 2 "register_operand" "d")] 13978 UNSPEC_PACK_128BIT))] 13979 "FLOAT128_2REG_P (<MODE>mode)" 13980 "#" 13981 "&& reload_completed" 13982 [(set (match_dup 3) (match_dup 1)) 13983 (set (match_dup 4) (match_dup 2))] 13984{ 13985 unsigned dest_hi = REGNO (operands[0]); 13986 unsigned dest_lo = dest_hi + 1; 13987 13988 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo)); 13989 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); 13990 13991 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); 13992 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); 13993} 13994 [(set_attr "type" "fp") 13995 (set_attr "length" "8")]) 13996 13997(define_insn "unpack<mode>" 13998 [(set (match_operand:DI 0 "register_operand" "=wa,wa") 13999 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa") 14000 (match_operand:QI 2 "const_0_to_1_operand" "O,i")] 14001 UNSPEC_UNPACK_128BIT))] 14002 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 14003{ 14004 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0) 14005 return ASM_COMMENT_START " xxpermdi to same register"; 14006 14007 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3); 14008 return "xxpermdi %x0,%x1,%x1,%3"; 14009} 14010 [(set_attr "type" "vecperm")]) 14011 14012(define_insn "pack<mode>" 14013 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa") 14014 (unspec:FMOVE128_VSX 14015 [(match_operand:DI 1 "register_operand" "wa") 14016 (match_operand:DI 2 "register_operand" "wa")] 14017 UNSPEC_PACK_128BIT))] 14018 "TARGET_VSX" 14019 "xxpermdi %x0,%x1,%x2,0" 14020 [(set_attr "type" "vecperm")]) 14021 14022 14023 14024;; ISA 2.08 IEEE 128-bit floating point support. 14025 14026(define_insn "add<mode>3" 14027 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14028 (plus:IEEE128 14029 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14030 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14031 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14032 "xsaddqp %0,%1,%2" 14033 [(set_attr "type" "vecfloat") 14034 (set_attr "size" "128")]) 14035 14036(define_insn "sub<mode>3" 14037 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14038 (minus:IEEE128 14039 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14040 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14041 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14042 "xssubqp %0,%1,%2" 14043 [(set_attr "type" "vecfloat") 14044 (set_attr "size" "128")]) 14045 14046(define_insn "mul<mode>3" 14047 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14048 (mult:IEEE128 14049 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14050 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14051 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14052 "xsmulqp %0,%1,%2" 14053 [(set_attr "type" "qmul") 14054 (set_attr "size" "128")]) 14055 14056(define_insn "div<mode>3" 14057 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14058 (div:IEEE128 14059 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14060 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14061 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14062 "xsdivqp %0,%1,%2" 14063 [(set_attr "type" "vecdiv") 14064 (set_attr "size" "128")]) 14065 14066(define_insn "sqrt<mode>2" 14067 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14068 (sqrt:IEEE128 14069 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14070 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14071 "xssqrtqp %0,%1" 14072 [(set_attr "type" "vecdiv") 14073 (set_attr "size" "128")]) 14074 14075(define_expand "copysign<mode>3" 14076 [(use (match_operand:IEEE128 0 "altivec_register_operand")) 14077 (use (match_operand:IEEE128 1 "altivec_register_operand")) 14078 (use (match_operand:IEEE128 2 "altivec_register_operand"))] 14079 "FLOAT128_IEEE_P (<MODE>mode)" 14080{ 14081 if (TARGET_FLOAT128_HW) 14082 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1], 14083 operands[2])); 14084 else 14085 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1], 14086 operands[2])); 14087 DONE; 14088}) 14089 14090(define_insn "copysign<mode>3_hard" 14091 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14092 (unspec:IEEE128 14093 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14094 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14095 UNSPEC_COPYSIGN))] 14096 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14097 "xscpsgnqp %0,%2,%1" 14098 [(set_attr "type" "vecmove") 14099 (set_attr "size" "128")]) 14100 14101(define_insn "copysign<mode>3_soft" 14102 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14103 (unspec:IEEE128 14104 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14105 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14106 UNSPEC_COPYSIGN)) 14107 (clobber (match_scratch:IEEE128 3 "=&v"))] 14108 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14109 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1" 14110 [(set_attr "type" "veccomplex") 14111 (set_attr "length" "8")]) 14112 14113(define_insn "neg<mode>2_hw" 14114 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14115 (neg:IEEE128 14116 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14117 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14118 "xsnegqp %0,%1" 14119 [(set_attr "type" "vecmove") 14120 (set_attr "size" "128")]) 14121 14122 14123(define_insn "abs<mode>2_hw" 14124 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14125 (abs:IEEE128 14126 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14127 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14128 "xsabsqp %0,%1" 14129 [(set_attr "type" "vecmove") 14130 (set_attr "size" "128")]) 14131 14132 14133(define_insn "*nabs<mode>2_hw" 14134 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14135 (neg:IEEE128 14136 (abs:IEEE128 14137 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))] 14138 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14139 "xsnabsqp %0,%1" 14140 [(set_attr "type" "vecmove") 14141 (set_attr "size" "128")]) 14142 14143;; Initially don't worry about doing fusion 14144(define_insn "fma<mode>4_hw" 14145 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14146 (fma:IEEE128 14147 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14148 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14149 (match_operand:IEEE128 3 "altivec_register_operand" "0")))] 14150 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14151 "xsmaddqp %0,%1,%2" 14152 [(set_attr "type" "qmul") 14153 (set_attr "size" "128")]) 14154 14155(define_insn "*fms<mode>4_hw" 14156 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14157 (fma:IEEE128 14158 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14159 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14160 (neg:IEEE128 14161 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 14162 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14163 "xsmsubqp %0,%1,%2" 14164 [(set_attr "type" "qmul") 14165 (set_attr "size" "128")]) 14166 14167(define_insn "*nfma<mode>4_hw" 14168 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14169 (neg:IEEE128 14170 (fma:IEEE128 14171 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14172 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14173 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 14174 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14175 "xsnmaddqp %0,%1,%2" 14176 [(set_attr "type" "qmul") 14177 (set_attr "size" "128")]) 14178 14179(define_insn "*nfms<mode>4_hw" 14180 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14181 (neg:IEEE128 14182 (fma:IEEE128 14183 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14184 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14185 (neg:IEEE128 14186 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))] 14187 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14188 "xsnmsubqp %0,%1,%2" 14189 [(set_attr "type" "qmul") 14190 (set_attr "size" "128")]) 14191 14192(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw" 14193 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14194 (float_extend:IEEE128 14195 (match_operand:SFDF 1 "altivec_register_operand" "v")))] 14196 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14197 "xscvdpqp %0,%1" 14198 [(set_attr "type" "vecfloat") 14199 (set_attr "size" "128")]) 14200 14201;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating 14202;; point is a simple copy. 14203(define_insn_and_split "extendkftf2" 14204 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa") 14205 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))] 14206 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD" 14207 "@ 14208 # 14209 xxlor %x0,%x1,%x1" 14210 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 14211 [(const_int 0)] 14212{ 14213 emit_note (NOTE_INSN_DELETED); 14214 DONE; 14215} 14216 [(set_attr "type" "*,veclogical") 14217 (set_attr "length" "0,4")]) 14218 14219(define_insn_and_split "trunctfkf2" 14220 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa") 14221 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))] 14222 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD" 14223 "@ 14224 # 14225 xxlor %x0,%x1,%x1" 14226 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 14227 [(const_int 0)] 14228{ 14229 emit_note (NOTE_INSN_DELETED); 14230 DONE; 14231} 14232 [(set_attr "type" "*,veclogical") 14233 (set_attr "length" "0,4")]) 14234 14235(define_insn "trunc<mode>df2_hw" 14236 [(set (match_operand:DF 0 "altivec_register_operand" "=v") 14237 (float_truncate:DF 14238 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14239 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14240 "xscvqpdp %0,%1" 14241 [(set_attr "type" "vecfloat") 14242 (set_attr "size" "128")]) 14243 14244;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing 14245;; the KFmode -> DFmode conversion using round to odd rather than the normal 14246;; conversion 14247(define_insn_and_split "trunc<mode>sf2_hw" 14248 [(set (match_operand:SF 0 "vsx_register_operand" "=wy") 14249 (float_truncate:SF 14250 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 14251 (clobber (match_scratch:DF 2 "=v"))] 14252 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14253 "#" 14254 "&& 1" 14255 [(set (match_dup 2) 14256 (unspec:DF [(match_dup 1)] 14257 UNSPEC_TRUNC_ROUND_TO_ODD)) 14258 (set (match_dup 0) 14259 (float_truncate:SF (match_dup 2)))] 14260{ 14261 if (GET_CODE (operands[2]) == SCRATCH) 14262 operands[2] = gen_reg_rtx (DFmode); 14263} 14264 [(set_attr "type" "vecfloat") 14265 (set_attr "length" "8")]) 14266 14267;; Conversion between IEEE 128-bit and integer types 14268 14269;; The fix function for DImode and SImode was declared earlier as a 14270;; define_expand. It calls into rs6000_expand_float128_convert if we don't 14271;; have IEEE 128-bit hardware support. QImode and HImode are not provided 14272;; unless we have the IEEE 128-bit hardware. 14273;; 14274;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have 14275;; to provide a GPR target that used direct move and a conversion in the GPR 14276;; which works around QImode/HImode not being allowed in vector registers in 14277;; ISA 2.07 (power8). 14278(define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw" 14279 [(set (match_operand:SDI 0 "altivec_register_operand" "=v") 14280 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14281 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14282 "xscvqp<su><wd>z %0,%1" 14283 [(set_attr "type" "vecfloat") 14284 (set_attr "size" "128")]) 14285 14286(define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2" 14287 [(set (match_operand:QHI 0 "altivec_register_operand" "=v") 14288 (any_fix:QHI 14289 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14290 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14291 "xscvqp<su>wz %0,%1" 14292 [(set_attr "type" "vecfloat") 14293 (set_attr "size" "128")]) 14294 14295;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit 14296;; floating point value to 8/16/32-bit integer to GPR in order to save it. 14297(define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem" 14298 [(set (match_operand:QHSI 0 "memory_operand" "=Z") 14299 (any_fix:QHSI 14300 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 14301 (clobber (match_scratch:QHSI 2 "=v"))] 14302 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14303 "#" 14304 "&& reload_completed" 14305 [(set (match_dup 2) 14306 (any_fix:QHSI (match_dup 1))) 14307 (set (match_dup 0) 14308 (match_dup 2))]) 14309 14310(define_insn "float_<mode>di2_hw" 14311 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14312 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))] 14313 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14314 "xscvsdqp %0,%1" 14315 [(set_attr "type" "vecfloat") 14316 (set_attr "size" "128")]) 14317 14318(define_insn_and_split "float_<mode>si2_hw" 14319 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14320 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ"))) 14321 (clobber (match_scratch:DI 2 "=v"))] 14322 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14323 "#" 14324 "&& 1" 14325 [(set (match_dup 2) 14326 (sign_extend:DI (match_dup 1))) 14327 (set (match_dup 0) 14328 (float:IEEE128 (match_dup 2)))] 14329{ 14330 if (GET_CODE (operands[2]) == SCRATCH) 14331 operands[2] = gen_reg_rtx (DImode); 14332 14333 if (MEM_P (operands[1])) 14334 operands[1] = rs6000_address_for_fpconvert (operands[1]); 14335}) 14336 14337(define_insn_and_split "float<QHI:mode><IEEE128:mode>2" 14338 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 14339 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) 14340 (clobber (match_scratch:DI 2 "=X,r,X"))] 14341 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14342 "#" 14343 "&& reload_completed" 14344 [(const_int 0)] 14345{ 14346 rtx dest = operands[0]; 14347 rtx src = operands[1]; 14348 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest)); 14349 14350 if (altivec_register_operand (src, <QHI:MODE>mode)) 14351 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src)); 14352 else if (int_reg_operand (src, <QHI:MODE>mode)) 14353 { 14354 rtx ext_di = operands[2]; 14355 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src)); 14356 emit_move_insn (dest_di, ext_di); 14357 } 14358 else if (MEM_P (src)) 14359 { 14360 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest)); 14361 emit_move_insn (dest_qhi, src); 14362 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi)); 14363 } 14364 else 14365 gcc_unreachable (); 14366 14367 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di)); 14368 DONE; 14369} 14370 [(set_attr "length" "8,12,12") 14371 (set_attr "type" "vecfloat") 14372 (set_attr "size" "128")]) 14373 14374(define_insn "floatuns_<mode>di2_hw" 14375 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14376 (unsigned_float:IEEE128 14377 (match_operand:DI 1 "altivec_register_operand" "v")))] 14378 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14379 "xscvudqp %0,%1" 14380 [(set_attr "type" "vecfloat") 14381 (set_attr "size" "128")]) 14382 14383(define_insn_and_split "floatuns_<mode>si2_hw" 14384 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14385 (unsigned_float:IEEE128 14386 (match_operand:SI 1 "nonimmediate_operand" "vrZ"))) 14387 (clobber (match_scratch:DI 2 "=v"))] 14388 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14389 "#" 14390 "&& 1" 14391 [(set (match_dup 2) 14392 (zero_extend:DI (match_dup 1))) 14393 (set (match_dup 0) 14394 (float:IEEE128 (match_dup 2)))] 14395{ 14396 if (GET_CODE (operands[2]) == SCRATCH) 14397 operands[2] = gen_reg_rtx (DImode); 14398 14399 if (MEM_P (operands[1])) 14400 operands[1] = rs6000_address_for_fpconvert (operands[1]); 14401}) 14402 14403(define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2" 14404 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 14405 (unsigned_float:IEEE128 14406 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) 14407 (clobber (match_scratch:DI 2 "=X,r,X"))] 14408 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14409 "#" 14410 "&& reload_completed" 14411 [(const_int 0)] 14412{ 14413 rtx dest = operands[0]; 14414 rtx src = operands[1]; 14415 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest)); 14416 14417 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src)) 14418 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src)); 14419 else if (int_reg_operand (src, <QHI:MODE>mode)) 14420 { 14421 rtx ext_di = operands[2]; 14422 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src)); 14423 emit_move_insn (dest_di, ext_di); 14424 } 14425 else 14426 gcc_unreachable (); 14427 14428 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di)); 14429 DONE; 14430} 14431 [(set_attr "length" "8,12,8") 14432 (set_attr "type" "vecfloat") 14433 (set_attr "size" "128")]) 14434 14435;; IEEE 128-bit round to integer built-in functions 14436(define_insn "floor<mode>2" 14437 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14438 (unspec:IEEE128 14439 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14440 UNSPEC_FRIM))] 14441 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14442 "xsrqpi 1,%0,%1,3" 14443 [(set_attr "type" "vecfloat") 14444 (set_attr "size" "128")]) 14445 14446(define_insn "ceil<mode>2" 14447 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14448 (unspec:IEEE128 14449 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14450 UNSPEC_FRIP))] 14451 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14452 "xsrqpi 1,%0,%1,2" 14453 [(set_attr "type" "vecfloat") 14454 (set_attr "size" "128")]) 14455 14456(define_insn "btrunc<mode>2" 14457 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14458 (unspec:IEEE128 14459 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14460 UNSPEC_FRIZ))] 14461 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14462 "xsrqpi 1,%0,%1,1" 14463 [(set_attr "type" "vecfloat") 14464 (set_attr "size" "128")]) 14465 14466(define_insn "round<mode>2" 14467 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14468 (unspec:IEEE128 14469 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14470 UNSPEC_FRIN))] 14471 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14472 "xsrqpi 0,%0,%1,0" 14473 [(set_attr "type" "vecfloat") 14474 (set_attr "size" "128")]) 14475 14476;; IEEE 128-bit instructions with round to odd semantics 14477(define_insn "add<mode>3_odd" 14478 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14479 (unspec:IEEE128 14480 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14481 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14482 UNSPEC_ADD_ROUND_TO_ODD))] 14483 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14484 "xsaddqpo %0,%1,%2" 14485 [(set_attr "type" "vecfloat") 14486 (set_attr "size" "128")]) 14487 14488(define_insn "sub<mode>3_odd" 14489 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14490 (unspec:IEEE128 14491 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14492 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14493 UNSPEC_SUB_ROUND_TO_ODD))] 14494 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14495 "xssubqpo %0,%1,%2" 14496 [(set_attr "type" "vecfloat") 14497 (set_attr "size" "128")]) 14498 14499(define_insn "mul<mode>3_odd" 14500 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14501 (unspec:IEEE128 14502 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14503 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14504 UNSPEC_MUL_ROUND_TO_ODD))] 14505 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14506 "xsmulqpo %0,%1,%2" 14507 [(set_attr "type" "qmul") 14508 (set_attr "size" "128")]) 14509 14510(define_insn "div<mode>3_odd" 14511 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14512 (unspec:IEEE128 14513 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14514 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14515 UNSPEC_DIV_ROUND_TO_ODD))] 14516 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14517 "xsdivqpo %0,%1,%2" 14518 [(set_attr "type" "vecdiv") 14519 (set_attr "size" "128")]) 14520 14521(define_insn "sqrt<mode>2_odd" 14522 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14523 (unspec:IEEE128 14524 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14525 UNSPEC_SQRT_ROUND_TO_ODD))] 14526 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14527 "xssqrtqpo %0,%1" 14528 [(set_attr "type" "vecdiv") 14529 (set_attr "size" "128")]) 14530 14531(define_insn "fma<mode>4_odd" 14532 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14533 (unspec:IEEE128 14534 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14535 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14536 (match_operand:IEEE128 3 "altivec_register_operand" "0")] 14537 UNSPEC_FMA_ROUND_TO_ODD))] 14538 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14539 "xsmaddqpo %0,%1,%2" 14540 [(set_attr "type" "qmul") 14541 (set_attr "size" "128")]) 14542 14543(define_insn "*fms<mode>4_odd" 14544 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14545 (unspec:IEEE128 14546 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 14547 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14548 (neg:IEEE128 14549 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] 14550 UNSPEC_FMA_ROUND_TO_ODD))] 14551 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14552 "xsmsubqpo %0,%1,%2" 14553 [(set_attr "type" "qmul") 14554 (set_attr "size" "128")]) 14555 14556(define_insn "*nfma<mode>4_odd" 14557 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14558 (neg:IEEE128 14559 (unspec:IEEE128 14560 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 14561 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14562 (match_operand:IEEE128 3 "altivec_register_operand" "0")] 14563 UNSPEC_FMA_ROUND_TO_ODD)))] 14564 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14565 "xsnmaddqpo %0,%1,%2" 14566 [(set_attr "type" "qmul") 14567 (set_attr "size" "128")]) 14568 14569(define_insn "*nfms<mode>4_odd" 14570 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14571 (neg:IEEE128 14572 (unspec:IEEE128 14573 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 14574 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14575 (neg:IEEE128 14576 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] 14577 UNSPEC_FMA_ROUND_TO_ODD)))] 14578 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14579 "xsnmsubqpo %0,%1,%2" 14580 [(set_attr "type" "qmul") 14581 (set_attr "size" "128")]) 14582 14583(define_insn "trunc<mode>df2_odd" 14584 [(set (match_operand:DF 0 "vsx_register_operand" "=v") 14585 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14586 UNSPEC_TRUNC_ROUND_TO_ODD))] 14587 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14588 "xscvqpdpo %0,%1" 14589 [(set_attr "type" "vecfloat") 14590 (set_attr "size" "128")]) 14591 14592;; IEEE 128-bit comparisons 14593(define_insn "*cmp<mode>_hw" 14594 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 14595 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v") 14596 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14597 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14598 "xscmpuqp %0,%1,%2" 14599 [(set_attr "type" "veccmp") 14600 (set_attr "size" "128")]) 14601 14602;; Miscellaneous ISA 3.0 (power9) instructions 14603 14604(define_insn "darn_32" 14605 [(set (match_operand:SI 0 "register_operand" "=r") 14606 (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))] 14607 "TARGET_P9_MISC" 14608 "darn %0,0" 14609 [(set_attr "type" "integer")]) 14610 14611(define_insn "darn_raw" 14612 [(set (match_operand:DI 0 "register_operand" "=r") 14613 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))] 14614 "TARGET_P9_MISC && TARGET_64BIT" 14615 "darn %0,2" 14616 [(set_attr "type" "integer")]) 14617 14618(define_insn "darn" 14619 [(set (match_operand:DI 0 "register_operand" "=r") 14620 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))] 14621 "TARGET_P9_MISC && TARGET_64BIT" 14622 "darn %0,1" 14623 [(set_attr "type" "integer")]) 14624 14625;; Test byte within range. 14626;; 14627;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14628;; represents a byte whose value is ignored in this context and 14629;; vv, the least significant byte, holds the byte value that is to 14630;; be tested for membership within the range specified by operand 2. 14631;; The bytes of operand 2 are organized as xx:xx:hi:lo. 14632;; 14633;; Return in target register operand 0 a value of 1 if lo <= vv and 14634;; vv <= hi. Otherwise, set register operand 0 to 0. 14635;; 14636;; Though the instructions to which this expansion maps operate on 14637;; 64-bit registers, the current implementation only operates on 14638;; SI-mode operands as the high-order bits provide no information 14639;; that is not already available in the low-order bits. To avoid the 14640;; costs of data widening operations, future enhancements might allow 14641;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 14642(define_expand "cmprb" 14643 [(set (match_dup 3) 14644 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14645 (match_operand:SI 2 "gpc_reg_operand" "r")] 14646 UNSPEC_CMPRB)) 14647 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 14648 (if_then_else:SI (lt (match_dup 3) 14649 (const_int 0)) 14650 (const_int -1) 14651 (if_then_else (gt (match_dup 3) 14652 (const_int 0)) 14653 (const_int 1) 14654 (const_int 0))))] 14655 "TARGET_P9_MISC" 14656{ 14657 operands[3] = gen_reg_rtx (CCmode); 14658}) 14659 14660;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14661;; represents a byte whose value is ignored in this context and 14662;; vv, the least significant byte, holds the byte value that is to 14663;; be tested for membership within the range specified by operand 2. 14664;; The bytes of operand 2 are organized as xx:xx:hi:lo. 14665;; 14666;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if 14667;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other 14668;; 3 bits of the target CR register are all set to 0. 14669(define_insn "*cmprb_internal" 14670 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 14671 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14672 (match_operand:SI 2 "gpc_reg_operand" "r")] 14673 UNSPEC_CMPRB))] 14674 "TARGET_P9_MISC" 14675 "cmprb %0,0,%1,%2" 14676 [(set_attr "type" "logical")]) 14677 14678;; Set operand 0 register to -1 if the LT bit (0x8) of condition 14679;; register operand 1 is on. Otherwise, set operand 0 register to 1 14680;; if the GT bit (0x4) of condition register operand 1 is on. 14681;; Otherwise, set operand 0 to 0. Note that the result stored into 14682;; register operand 0 is non-zero iff either the LT or GT bits are on 14683;; within condition register operand 1. 14684(define_insn "setb_signed" 14685 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 14686 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y") 14687 (const_int 0)) 14688 (const_int -1) 14689 (if_then_else (gt (match_dup 1) 14690 (const_int 0)) 14691 (const_int 1) 14692 (const_int 0))))] 14693 "TARGET_P9_MISC" 14694 "setb %0,%1" 14695 [(set_attr "type" "logical")]) 14696 14697(define_insn "setb_unsigned" 14698 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 14699 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y") 14700 (const_int 0)) 14701 (const_int -1) 14702 (if_then_else (gtu (match_dup 1) 14703 (const_int 0)) 14704 (const_int 1) 14705 (const_int 0))))] 14706 "TARGET_P9_MISC" 14707 "setb %0,%1" 14708 [(set_attr "type" "logical")]) 14709 14710;; Test byte within two ranges. 14711;; 14712;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14713;; represents a byte whose value is ignored in this context and 14714;; vv, the least significant byte, holds the byte value that is to 14715;; be tested for membership within the range specified by operand 2. 14716;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. 14717;; 14718;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and 14719;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register 14720;; operand 0 to 0. 14721;; 14722;; Though the instructions to which this expansion maps operate on 14723;; 64-bit registers, the current implementation only operates on 14724;; SI-mode operands as the high-order bits provide no information 14725;; that is not already available in the low-order bits. To avoid the 14726;; costs of data widening operations, future enhancements might allow 14727;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 14728(define_expand "cmprb2" 14729 [(set (match_dup 3) 14730 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14731 (match_operand:SI 2 "gpc_reg_operand" "r")] 14732 UNSPEC_CMPRB2)) 14733 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 14734 (if_then_else:SI (lt (match_dup 3) 14735 (const_int 0)) 14736 (const_int -1) 14737 (if_then_else (gt (match_dup 3) 14738 (const_int 0)) 14739 (const_int 1) 14740 (const_int 0))))] 14741 "TARGET_P9_MISC" 14742{ 14743 operands[3] = gen_reg_rtx (CCmode); 14744}) 14745 14746;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14747;; represents a byte whose value is ignored in this context and 14748;; vv, the least significant byte, holds the byte value that is to 14749;; be tested for membership within the ranges specified by operand 2. 14750;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. 14751;; 14752;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if 14753;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). 14754;; Otherwise, set the GT bit to 0. The other 3 bits of the target 14755;; CR register are all set to 0. 14756(define_insn "*cmprb2_internal" 14757 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 14758 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14759 (match_operand:SI 2 "gpc_reg_operand" "r")] 14760 UNSPEC_CMPRB2))] 14761 "TARGET_P9_MISC" 14762 "cmprb %0,1,%1,%2" 14763 [(set_attr "type" "logical")]) 14764 14765;; Test byte membership within set of 8 bytes. 14766;; 14767;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14768;; represents a byte whose value is ignored in this context and 14769;; vv, the least significant byte, holds the byte value that is to 14770;; be tested for membership within the set specified by operand 2. 14771;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. 14772;; 14773;; Return in target register operand 0 a value of 1 if vv equals one 14774;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set 14775;; register operand 0 to 0. Note that the 8 byte values held within 14776;; operand 2 need not be unique. 14777;; 14778;; Though the instructions to which this expansion maps operate on 14779;; 64-bit registers, the current implementation requires that operands 14780;; 0 and 1 have mode SI as the high-order bits provide no information 14781;; that is not already available in the low-order bits. To avoid the 14782;; costs of data widening operations, future enhancements might allow 14783;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 14784(define_expand "cmpeqb" 14785 [(set (match_dup 3) 14786 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14787 (match_operand:DI 2 "gpc_reg_operand" "r")] 14788 UNSPEC_CMPEQB)) 14789 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 14790 (if_then_else:SI (lt (match_dup 3) 14791 (const_int 0)) 14792 (const_int -1) 14793 (if_then_else (gt (match_dup 3) 14794 (const_int 0)) 14795 (const_int 1) 14796 (const_int 0))))] 14797 "TARGET_P9_MISC && TARGET_64BIT" 14798{ 14799 operands[3] = gen_reg_rtx (CCmode); 14800}) 14801 14802;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14803;; represents a byte whose value is ignored in this context and 14804;; vv, the least significant byte, holds the byte value that is to 14805;; be tested for membership within the set specified by operand 2. 14806;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. 14807;; 14808;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv 14809;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, 14810;; set the GT bit to zero. The other 3 bits of the target CR register 14811;; are all set to 0. 14812(define_insn "*cmpeqb_internal" 14813 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 14814 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14815 (match_operand:DI 2 "gpc_reg_operand" "r")] 14816 UNSPEC_CMPEQB))] 14817 "TARGET_P9_MISC && TARGET_64BIT" 14818 "cmpeqb %0,%1,%2" 14819 [(set_attr "type" "logical")]) 14820 14821 14822(include "sync.md") 14823(include "vector.md") 14824(include "vsx.md") 14825(include "altivec.md") 14826(include "dfp.md") 14827(include "paired.md") 14828(include "crypto.md") 14829(include "htm.md") 14830