1;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler 2;; Copyright (C) 1990-2018 Free Software Foundation, Inc. 3;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 22 23;; 24;; REGNOS 25;; 26 27(define_constants 28 [(FIRST_GPR_REGNO 0) 29 (STACK_POINTER_REGNUM 1) 30 (TOC_REGNUM 2) 31 (STATIC_CHAIN_REGNUM 11) 32 (HARD_FRAME_POINTER_REGNUM 31) 33 (LAST_GPR_REGNO 31) 34 (FIRST_FPR_REGNO 32) 35 (LAST_FPR_REGNO 63) 36 (LR_REGNO 65) 37 (CTR_REGNO 66) 38 (ARG_POINTER_REGNUM 67) 39 (CR0_REGNO 68) 40 (CR1_REGNO 69) 41 (CR2_REGNO 70) 42 (CR3_REGNO 71) 43 (CR4_REGNO 72) 44 (CR5_REGNO 73) 45 (CR6_REGNO 74) 46 (CR7_REGNO 75) 47 (MAX_CR_REGNO 75) 48 (CA_REGNO 76) 49 (FIRST_ALTIVEC_REGNO 77) 50 (LAST_ALTIVEC_REGNO 108) 51 (VRSAVE_REGNO 109) 52 (VSCR_REGNO 110) 53 (SPE_ACC_REGNO 111) 54 (SPEFSCR_REGNO 112) 55 (FRAME_POINTER_REGNUM 113) 56 (TFHAR_REGNO 114) 57 (TFIAR_REGNO 115) 58 (TEXASR_REGNO 116) 59 (FIRST_SPE_HIGH_REGNO 117) 60 (LAST_SPE_HIGH_REGNO 148) 61 ]) 62 63;; 64;; UNSPEC usage 65;; 66 67(define_c_enum "unspec" 68 [UNSPEC_FRSP ; frsp for POWER machines 69 UNSPEC_PROBE_STACK ; probe stack memory reference 70 UNSPEC_TOCPTR ; address of a word pointing to the TOC 71 UNSPEC_TOC ; address of the TOC (more-or-less) 72 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot 73 UNSPEC_MOVSI_GOT 74 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit 75 UNSPEC_FCTIWZ 76 UNSPEC_FRIM 77 UNSPEC_FRIN 78 UNSPEC_FRIP 79 UNSPEC_FRIZ 80 UNSPEC_XSRDPI 81 UNSPEC_LD_MPIC ; load_macho_picbase 82 UNSPEC_RELD_MPIC ; re-load_macho_picbase 83 UNSPEC_MPIC_CORRECT ; macho_correct_pic 84 UNSPEC_TLSGD 85 UNSPEC_TLSLD 86 UNSPEC_MOVESI_FROM_CR 87 UNSPEC_MOVESI_TO_CR 88 UNSPEC_TLSDTPREL 89 UNSPEC_TLSDTPRELHA 90 UNSPEC_TLSDTPRELLO 91 UNSPEC_TLSGOTDTPREL 92 UNSPEC_TLSTPREL 93 UNSPEC_TLSTPRELHA 94 UNSPEC_TLSTPRELLO 95 UNSPEC_TLSGOTTPREL 96 UNSPEC_TLSTLS 97 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero 98 UNSPEC_MV_CR_GT ; move_from_CR_gt_bit 99 UNSPEC_STFIWX 100 UNSPEC_POPCNTB 101 UNSPEC_FRES 102 UNSPEC_SP_SET 103 UNSPEC_SP_TEST 104 UNSPEC_SYNC 105 UNSPEC_LWSYNC 106 UNSPEC_SYNC_OP 107 UNSPEC_ATOMIC 108 UNSPEC_CMPXCHG 109 UNSPEC_XCHG 110 UNSPEC_AND 111 UNSPEC_DLMZB 112 UNSPEC_DLMZB_CR 113 UNSPEC_DLMZB_STRLEN 114 UNSPEC_RSQRT 115 UNSPEC_TOCREL 116 UNSPEC_MACHOPIC_OFFSET 117 UNSPEC_BPERM 118 UNSPEC_COPYSIGN 119 UNSPEC_PARITY 120 UNSPEC_CMPB 121 UNSPEC_FCTIW 122 UNSPEC_FCTID 123 UNSPEC_LFIWAX 124 UNSPEC_LFIWZX 125 UNSPEC_FCTIWUZ 126 UNSPEC_NOP 127 UNSPEC_GRP_END_NOP 128 UNSPEC_P8V_FMRGOW 129 UNSPEC_P8V_MTVSRWZ 130 UNSPEC_P8V_RELOAD_FROM_GPR 131 UNSPEC_P8V_MTVSRD 132 UNSPEC_P8V_XXPERMDI 133 UNSPEC_P8V_RELOAD_FROM_VSX 134 UNSPEC_ADDG6S 135 UNSPEC_CDTBCD 136 UNSPEC_CBCDTD 137 UNSPEC_DIVE 138 UNSPEC_DIVEO 139 UNSPEC_DIVEU 140 UNSPEC_DIVEUO 141 UNSPEC_UNPACK_128BIT 142 UNSPEC_PACK_128BIT 143 UNSPEC_LSQ 144 UNSPEC_FUSION_GPR 145 UNSPEC_STACK_CHECK 146 UNSPEC_FUSION_P9 147 UNSPEC_FUSION_ADDIS 148 UNSPEC_ROUND_TO_ODD 149 UNSPEC_SIGNBIT 150 UNSPEC_SF_FROM_SI 151 UNSPEC_SI_FROM_SF 152 ]) 153 154;; 155;; UNSPEC_VOLATILE usage 156;; 157 158(define_c_enum "unspecv" 159 [UNSPECV_BLOCK 160 UNSPECV_LL ; load-locked 161 UNSPECV_SC ; store-conditional 162 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses 163 UNSPECV_EH_RR ; eh_reg_restore 164 UNSPECV_ISYNC ; isync instruction 165 UNSPECV_MFTB ; move from time base 166 UNSPECV_NLGR ; non-local goto receiver 167 UNSPECV_MFFS ; Move from FPSCR 168 UNSPECV_MTFSF ; Move to FPSCR Fields 169 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return 170 ]) 171 172 173;; Define an insn type attribute. This is used in function unit delay 174;; computations. 175(define_attr "type" 176 "integer,two,three, 177 add,logical,shift,insert, 178 mul,halfmul,div, 179 exts,cntlz,popcnt,isel, 180 load,store,fpload,fpstore,vecload,vecstore, 181 cmp, 182 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c, 183 cr_logical,delayed_cr,mfcr,mfcrf,mtcr, 184 fpcompare,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt, 185 brinc, 186 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm, 187 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto, 188 veclogical,veccmpfx,vecexts,vecmove, 189 htm,htmsimple,dfp" 190 (const_string "integer")) 191 192;; What data size does this instruction work on? 193;; This is used for insert, mul and others as necessary. 194(define_attr "size" "8,16,32,64,128" (const_string "32")) 195 196;; Is this instruction record form ("dot", signed compare to 0, writing CR0)? 197;; This is used for add, logical, shift, exts, mul. 198(define_attr "dot" "no,yes" (const_string "no")) 199 200;; Does this instruction sign-extend its result? 201;; This is used for load insns. 202(define_attr "sign_extend" "no,yes" (const_string "no")) 203 204;; Does this instruction use indexed (that is, reg+reg) addressing? 205;; This is used for load and store insns. If operand 0 or 1 is a MEM 206;; it is automatically set based on that. If a load or store instruction 207;; has fewer than two operands it needs to set this attribute manually 208;; or the compiler will crash. 209(define_attr "indexed" "no,yes" 210 (if_then_else (ior (match_operand 0 "indexed_address_mem") 211 (match_operand 1 "indexed_address_mem")) 212 (const_string "yes") 213 (const_string "no"))) 214 215;; Does this instruction use update addressing? 216;; This is used for load and store insns. See the comments for "indexed". 217(define_attr "update" "no,yes" 218 (if_then_else (ior (match_operand 0 "update_address_mem") 219 (match_operand 1 "update_address_mem")) 220 (const_string "yes") 221 (const_string "no"))) 222 223;; Is this instruction using operands[2] as shift amount, and can that be a 224;; register? 225;; This is used for shift insns. 226(define_attr "maybe_var_shift" "no,yes" (const_string "no")) 227 228;; Is this instruction using a shift amount from a register? 229;; This is used for shift insns. 230(define_attr "var_shift" "no,yes" 231 (if_then_else (and (eq_attr "type" "shift") 232 (eq_attr "maybe_var_shift" "yes")) 233 (if_then_else (match_operand 2 "gpc_reg_operand") 234 (const_string "yes") 235 (const_string "no")) 236 (const_string "no"))) 237 238;; Is copying of this instruction disallowed? 239(define_attr "cannot_copy" "no,yes" (const_string "no")) 240 241;; Define floating point instruction sub-types for use with Xfpu.md 242(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")) 243 244;; Length (in bytes). 245; '(pc)' in the following doesn't include the instruction itself; it is 246; calculated as if the instruction had zero size. 247(define_attr "length" "" 248 (if_then_else (eq_attr "type" "branch") 249 (if_then_else (and (ge (minus (match_dup 0) (pc)) 250 (const_int -32768)) 251 (lt (minus (match_dup 0) (pc)) 252 (const_int 32764))) 253 (const_int 4) 254 (const_int 8)) 255 (const_int 4))) 256 257;; Processor type -- this attribute must exactly match the processor_type 258;; enumeration in rs6000-opts.h. 259(define_attr "cpu" 260 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630, 261 ppc750,ppc7400,ppc7450, 262 ppc403,ppc405,ppc440,ppc476, 263 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500, 264 power4,power5,power6,power7,power8,power9, 265 rs64a,mpccore,cell,ppca2,titan" 266 (const (symbol_ref "rs6000_cpu_attr"))) 267 268 269;; If this instruction is microcoded on the CELL processor 270; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded 271(define_attr "cell_micro" "not,conditional,always" 272 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul") 273 (eq_attr "dot" "yes")) 274 (and (eq_attr "type" "load") 275 (eq_attr "sign_extend" "yes")) 276 (and (eq_attr "type" "shift") 277 (eq_attr "var_shift" "yes"))) 278 (const_string "always") 279 (const_string "not"))) 280 281(automata_option "ndfa") 282 283(include "rs64.md") 284(include "mpc.md") 285(include "40x.md") 286(include "440.md") 287(include "476.md") 288(include "601.md") 289(include "603.md") 290(include "6xx.md") 291(include "7xx.md") 292(include "7450.md") 293(include "8540.md") 294(include "e300c2c3.md") 295(include "e500mc.md") 296(include "e500mc64.md") 297(include "e5500.md") 298(include "e6500.md") 299(include "power4.md") 300(include "power5.md") 301(include "power6.md") 302(include "power7.md") 303(include "power8.md") 304(include "power9.md") 305(include "cell.md") 306(include "xfpu.md") 307(include "a2.md") 308(include "titan.md") 309 310(include "predicates.md") 311(include "constraints.md") 312 313(include "darwin.md") 314 315 316;; Mode iterators 317 318; This mode iterator allows :GPR to be used to indicate the allowable size 319; of whole values in GPRs. 320(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")]) 321 322; Any supported integer mode. 323(define_mode_iterator INT [QI HI SI DI TI PTI]) 324 325; Any supported integer mode that fits in one register. 326(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")]) 327 328; Integer modes supported in VSX registers with ISA 3.0 instructions 329(define_mode_iterator INT_ISA3 [QI HI SI DI]) 330 331; Everything we can extend QImode to. 332(define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")]) 333 334; Everything we can extend HImode to. 335(define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")]) 336 337; Everything we can extend SImode to. 338(define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")]) 339 340; QImode or HImode for small integer moves and small atomic ops 341(define_mode_iterator QHI [QI HI]) 342 343; QImode, HImode, SImode for fused ops only for GPR loads 344(define_mode_iterator QHSI [QI HI SI]) 345 346; HImode or SImode for sign extended fusion ops 347(define_mode_iterator HSI [HI SI]) 348 349; SImode or DImode, even if DImode doesn't fit in GPRs. 350(define_mode_iterator SDI [SI DI]) 351 352; Types that can be fused with an ADDIS instruction to load or store a GPR 353; register that has reg+offset addressing. 354(define_mode_iterator GPR_FUSION [QI 355 HI 356 SI 357 (DI "TARGET_POWERPC64") 358 SF 359 (DF "TARGET_POWERPC64")]) 360 361; Types that can be fused with an ADDIS instruction to load or store a FPR 362; register that has reg+offset addressing. 363(define_mode_iterator FPR_FUSION [DI SF DF]) 364 365; The size of a pointer. Also, the size of the value that a record-condition 366; (one with a '.') will compare; and the size used for arithmetic carries. 367(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")]) 368 369; Iterator to add PTImode along with TImode (TImode can go in VSX registers, 370; PTImode is GPR only) 371(define_mode_iterator TI2 [TI PTI]) 372 373; Any hardware-supported floating-point mode 374(define_mode_iterator FP [ 375 (SF "TARGET_HARD_FLOAT 376 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) || TARGET_E500_SINGLE)") 377 (DF "TARGET_HARD_FLOAT 378 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)") 379 (TF "TARGET_HARD_FLOAT 380 && (TARGET_FPRS || TARGET_E500_DOUBLE) 381 && TARGET_LONG_DOUBLE_128") 382 (IF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128") 383 (KF "TARGET_FLOAT128_TYPE") 384 (DD "TARGET_DFP") 385 (TD "TARGET_DFP")]) 386 387; Any fma capable floating-point mode. 388(define_mode_iterator FMA_F [ 389 (SF "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT") 390 (DF "(TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT) 391 || VECTOR_UNIT_VSX_P (DFmode)") 392 (V2SF "TARGET_PAIRED_FLOAT") 393 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)") 394 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)") 395 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)") 396 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)") 397 ]) 398 399; Floating point move iterators to combine binary and decimal moves 400(define_mode_iterator FMOVE32 [SF SD]) 401(define_mode_iterator FMOVE64 [DF DD]) 402(define_mode_iterator FMOVE64X [DI DF DD]) 403(define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128") 404 (IF "FLOAT128_IBM_P (IFmode)") 405 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")]) 406 407(define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)") 408 (IF "FLOAT128_2REG_P (IFmode)") 409 (TD "TARGET_HARD_FLOAT && TARGET_FPRS")]) 410 411; Iterators for 128 bit types for direct move 412(define_mode_iterator FMOVE128_GPR [(TI "TARGET_VSX_TIMODE") 413 (V16QI "") 414 (V8HI "") 415 (V4SI "") 416 (V4SF "") 417 (V2DI "") 418 (V2DF "") 419 (V1TI "") 420 (KF "FLOAT128_VECTOR_P (KFmode)") 421 (TF "FLOAT128_VECTOR_P (TFmode)")]) 422 423; Iterator for 128-bit VSX types for pack/unpack 424(define_mode_iterator FMOVE128_VSX [V1TI KF]) 425 426; Whether a floating point move is ok, don't allow SD without hardware FP 427(define_mode_attr fmove_ok [(SF "") 428 (DF "") 429 (SD "TARGET_HARD_FLOAT && TARGET_FPRS") 430 (DD "")]) 431 432; Convert REAL_VALUE to the appropriate bits 433(define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE") 434 (DF "REAL_VALUE_TO_TARGET_DOUBLE") 435 (SD "REAL_VALUE_TO_TARGET_DECIMAL32") 436 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")]) 437 438; Whether 0.0 has an all-zero bit pattern 439(define_mode_attr zero_fp [(SF "j") 440 (DF "j") 441 (TF "j") 442 (IF "j") 443 (KF "j") 444 (SD "wn") 445 (DD "wn") 446 (TD "wn")]) 447 448; Definitions for 64-bit VSX 449(define_mode_attr f64_vsx [(DF "ws") (DD "wn")]) 450 451; Definitions for 64-bit direct move 452(define_mode_attr f64_dm [(DF "wk") (DD "wh")]) 453 454; Definitions for 64-bit use of altivec registers 455(define_mode_attr f64_av [(DF "wv") (DD "wn")]) 456 457; Definitions for 64-bit access to ISA 3.0 (power9) vector 458(define_mode_attr f64_p9 [(DF "wb") (DD "wn")]) 459 460; These modes do not fit in integer registers in 32-bit mode. 461; but on e500v2, the gpr are 64 bit registers 462(define_mode_iterator DIFD [DI (DF "!TARGET_E500_DOUBLE") DD]) 463 464; Iterator for reciprocal estimate instructions 465(define_mode_iterator RECIPF [SF DF V4SF V2DF]) 466 467; Iterator for just SF/DF 468(define_mode_iterator SFDF [SF DF]) 469 470; Like SFDF, but a different name to match conditional move where the 471; comparison operands may be a different mode than the input operands. 472(define_mode_iterator SFDF2 [SF DF]) 473 474; Iterator for 128-bit floating point that uses the IBM double-double format 475(define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)") 476 (TF "FLOAT128_IBM_P (TFmode)")]) 477 478; Iterator for 128-bit floating point that uses IEEE 128-bit float 479(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)") 480 (TF "FLOAT128_IEEE_P (TFmode)")]) 481 482; Iterator for 128-bit floating point 483(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE") 484 (IF "TARGET_FLOAT128_TYPE") 485 (TF "TARGET_LONG_DOUBLE_128")]) 486 487; Iterator for signbit on 64-bit machines with direct move 488(define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)") 489 (TF "FLOAT128_VECTOR_P (TFmode)")]) 490 491; Iterator for ISA 3.0 supported floating point types 492(define_mode_iterator FP_ISA3 [SF DF]) 493 494; SF/DF suffix for traditional floating instructions 495(define_mode_attr Ftrad [(SF "s") (DF "")]) 496 497; SF/DF suffix for VSX instructions 498(define_mode_attr Fvsx [(SF "sp") (DF "dp")]) 499 500; SF/DF constraint for arithmetic on traditional floating point registers 501(define_mode_attr Ff [(SF "f") (DF "d") (DI "d")]) 502 503; SF/DF constraint for arithmetic on VSX registers using instructions added in 504; ISA 2.06 (power7). This includes instructions that normally target DF mode, 505; but are used on SFmode, since internally SFmode values are kept in the DFmode 506; format. 507(define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")]) 508 509; SF/DF constraint for arithmetic on VSX registers. This is intended to be 510; used for DFmode instructions added in ISA 2.06 (power7) and SFmode 511; instructions added in ISA 2.07 (power8) 512(define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")]) 513 514; SF/DF constraint for arithmetic on altivec registers 515(define_mode_attr Fa [(SF "wu") (DF "wv")]) 516 517; s/d suffix for things like fp_addsub_s/fp_addsub_d 518(define_mode_attr Fs [(SF "s") (DF "d")]) 519 520; FRE/FRES support 521(define_mode_attr Ffre [(SF "fres") (DF "fre")]) 522(define_mode_attr FFRE [(SF "FRES") (DF "FRE")]) 523 524; Conditional returns. 525(define_code_iterator any_return [return simple_return]) 526(define_code_attr return_pred [(return "direct_return ()") 527 (simple_return "1")]) 528(define_code_attr return_str [(return "") (simple_return "simple_")]) 529 530; Logical operators. 531(define_code_iterator iorxor [ior xor]) 532(define_code_iterator and_ior_xor [and ior xor]) 533 534; Signed/unsigned variants of ops. 535(define_code_iterator any_extend [sign_extend zero_extend]) 536(define_code_iterator any_fix [fix unsigned_fix]) 537(define_code_iterator any_float [float unsigned_float]) 538 539(define_code_attr u [(sign_extend "") 540 (zero_extend "u") 541 (fix "") 542 (unsigned_fix "u")]) 543 544(define_code_attr su [(sign_extend "s") 545 (zero_extend "u") 546 (fix "s") 547 (unsigned_fix "s") 548 (float "s") 549 (unsigned_float "u")]) 550 551(define_code_attr az [(sign_extend "a") 552 (zero_extend "z") 553 (fix "a") 554 (unsigned_fix "z") 555 (float "a") 556 (unsigned_float "z")]) 557 558(define_code_attr uns [(fix "") 559 (unsigned_fix "uns") 560 (float "") 561 (unsigned_float "uns")]) 562 563; Various instructions that come in SI and DI forms. 564; A generic w/d attribute, for things like cmpw/cmpd. 565(define_mode_attr wd [(QI "b") 566 (HI "h") 567 (SI "w") 568 (DI "d") 569 (V16QI "b") 570 (V8HI "h") 571 (V4SI "w") 572 (V2DI "d") 573 (V1TI "q") 574 (TI "q")]) 575 576;; How many bits in this mode? 577(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")]) 578 579; DImode bits 580(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")]) 581 582;; ISEL/ISEL64 target selection 583(define_mode_attr sel [(SI "") (DI "64")]) 584 585;; Bitmask for shift instructions 586(define_mode_attr hH [(SI "h") (DI "H")]) 587 588;; A mode twice the size of the given mode 589(define_mode_attr dmode [(SI "di") (DI "ti")]) 590(define_mode_attr DMODE [(SI "DI") (DI "TI")]) 591 592;; Suffix for reload patterns 593(define_mode_attr ptrsize [(SI "32bit") 594 (DI "64bit")]) 595 596(define_mode_attr tptrsize [(SI "TARGET_32BIT") 597 (DI "TARGET_64BIT")]) 598 599(define_mode_attr mptrsize [(SI "si") 600 (DI "di")]) 601 602(define_mode_attr ptrload [(SI "lwz") 603 (DI "ld")]) 604 605(define_mode_attr ptrm [(SI "m") 606 (DI "Y")]) 607 608(define_mode_attr rreg [(SF "f") 609 (DF "ws") 610 (TF "f") 611 (TD "f") 612 (V4SF "wf") 613 (V2DF "wd")]) 614 615(define_mode_attr rreg2 [(SF "f") 616 (DF "d")]) 617 618(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS") 619 (DF "TARGET_FCFID")]) 620 621(define_mode_attr E500_CONVERT [(SF "!TARGET_FPRS") 622 (DF "TARGET_E500_DOUBLE")]) 623 624(define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT") 625 (DF "TARGET_DOUBLE_FLOAT")]) 626 627;; Mode iterator for logical operations on 128-bit types 628(define_mode_iterator BOOL_128 [TI 629 PTI 630 (V16QI "TARGET_ALTIVEC") 631 (V8HI "TARGET_ALTIVEC") 632 (V4SI "TARGET_ALTIVEC") 633 (V4SF "TARGET_ALTIVEC") 634 (V2DI "TARGET_ALTIVEC") 635 (V2DF "TARGET_ALTIVEC") 636 (V1TI "TARGET_ALTIVEC")]) 637 638;; For the GPRs we use 3 constraints for register outputs, two that are the 639;; same as the output register, and a third where the output register is an 640;; early clobber, so we don't have to deal with register overlaps. For the 641;; vector types, we prefer to use the vector registers. For TI mode, allow 642;; either. 643 644;; Mode attribute for boolean operation register constraints for output 645(define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v") 646 (PTI "&r,r,r") 647 (V16QI "wa,v,&?r,?r,?r") 648 (V8HI "wa,v,&?r,?r,?r") 649 (V4SI "wa,v,&?r,?r,?r") 650 (V4SF "wa,v,&?r,?r,?r") 651 (V2DI "wa,v,&?r,?r,?r") 652 (V2DF "wa,v,&?r,?r,?r") 653 (V1TI "wa,v,&?r,?r,?r")]) 654 655;; Mode attribute for boolean operation register constraints for operand1 656(define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v") 657 (PTI "r,0,r") 658 (V16QI "wa,v,r,0,r") 659 (V8HI "wa,v,r,0,r") 660 (V4SI "wa,v,r,0,r") 661 (V4SF "wa,v,r,0,r") 662 (V2DI "wa,v,r,0,r") 663 (V2DF "wa,v,r,0,r") 664 (V1TI "wa,v,r,0,r")]) 665 666;; Mode attribute for boolean operation register constraints for operand2 667(define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v") 668 (PTI "r,r,0") 669 (V16QI "wa,v,r,r,0") 670 (V8HI "wa,v,r,r,0") 671 (V4SI "wa,v,r,r,0") 672 (V4SF "wa,v,r,r,0") 673 (V2DI "wa,v,r,r,0") 674 (V2DF "wa,v,r,r,0") 675 (V1TI "wa,v,r,r,0")]) 676 677;; Mode attribute for boolean operation register constraints for operand1 678;; for one_cmpl. To simplify things, we repeat the constraint where 0 679;; is used for operand1 or operand2 680(define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v") 681 (PTI "r,0,0") 682 (V16QI "wa,v,r,0,0") 683 (V8HI "wa,v,r,0,0") 684 (V4SI "wa,v,r,0,0") 685 (V4SF "wa,v,r,0,0") 686 (V2DI "wa,v,r,0,0") 687 (V2DF "wa,v,r,0,0") 688 (V1TI "wa,v,r,0,0")]) 689 690;; Reload iterator for creating the function to allocate a base register to 691;; supplement addressing modes. 692(define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI 693 SF SD SI DF DD DI TI PTI KF IF TF]) 694 695;; Iterate over smin, smax 696(define_code_iterator fp_minmax [smin smax]) 697 698(define_code_attr minmax [(smin "min") 699 (smax "max")]) 700 701(define_code_attr SMINMAX [(smin "SMIN") 702 (smax "SMAX")]) 703 704;; Iterator to optimize the following cases: 705;; D-form load to FPR register & move to Altivec register 706;; Move Altivec register to FPR register and store 707(define_mode_iterator ALTIVEC_DFORM [DI DF SF]) 708 709 710;; Start with fixed-point load and store insns. Here we put only the more 711;; complex forms. Basic data transfer is done later. 712 713(define_insn "zero_extendqi<mode>2" 714 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK") 715 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))] 716 "" 717 "@ 718 lbz%U1%X1 %0,%1 719 rlwinm %0,%1,0,0xff 720 lxsibzx %x0,%y1 721 vextractub %0,%1,7" 722 [(set_attr "type" "load,shift,fpload,vecperm")]) 723 724(define_insn_and_split "*zero_extendqi<mode>2_dot" 725 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 726 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 727 (const_int 0))) 728 (clobber (match_scratch:EXTQI 0 "=r,r"))] 729 "rs6000_gen_cell_microcode" 730 "@ 731 andi. %0,%1,0xff 732 #" 733 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 734 [(set (match_dup 0) 735 (zero_extend:EXTQI (match_dup 1))) 736 (set (match_dup 2) 737 (compare:CC (match_dup 0) 738 (const_int 0)))] 739 "" 740 [(set_attr "type" "logical") 741 (set_attr "dot" "yes") 742 (set_attr "length" "4,8")]) 743 744(define_insn_and_split "*zero_extendqi<mode>2_dot2" 745 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 746 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 747 (const_int 0))) 748 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 749 (zero_extend:EXTQI (match_dup 1)))] 750 "rs6000_gen_cell_microcode" 751 "@ 752 andi. %0,%1,0xff 753 #" 754 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 755 [(set (match_dup 0) 756 (zero_extend:EXTQI (match_dup 1))) 757 (set (match_dup 2) 758 (compare:CC (match_dup 0) 759 (const_int 0)))] 760 "" 761 [(set_attr "type" "logical") 762 (set_attr "dot" "yes") 763 (set_attr "length" "4,8")]) 764 765 766(define_insn "zero_extendhi<mode>2" 767 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK") 768 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))] 769 "" 770 "@ 771 lhz%U1%X1 %0,%1 772 rlwinm %0,%1,0,0xffff 773 lxsihzx %x0,%y1 774 vextractuh %0,%1,6" 775 [(set_attr "type" "load,shift,fpload,vecperm")]) 776 777(define_insn_and_split "*zero_extendhi<mode>2_dot" 778 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 779 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 780 (const_int 0))) 781 (clobber (match_scratch:EXTHI 0 "=r,r"))] 782 "rs6000_gen_cell_microcode" 783 "@ 784 andi. %0,%1,0xffff 785 #" 786 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 787 [(set (match_dup 0) 788 (zero_extend:EXTHI (match_dup 1))) 789 (set (match_dup 2) 790 (compare:CC (match_dup 0) 791 (const_int 0)))] 792 "" 793 [(set_attr "type" "logical") 794 (set_attr "dot" "yes") 795 (set_attr "length" "4,8")]) 796 797(define_insn_and_split "*zero_extendhi<mode>2_dot2" 798 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 799 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 800 (const_int 0))) 801 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 802 (zero_extend:EXTHI (match_dup 1)))] 803 "rs6000_gen_cell_microcode" 804 "@ 805 andi. %0,%1,0xffff 806 #" 807 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 808 [(set (match_dup 0) 809 (zero_extend:EXTHI (match_dup 1))) 810 (set (match_dup 2) 811 (compare:CC (match_dup 0) 812 (const_int 0)))] 813 "" 814 [(set_attr "type" "logical") 815 (set_attr "dot" "yes") 816 (set_attr "length" "4,8")]) 817 818 819(define_insn "zero_extendsi<mode>2" 820 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK") 821 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))] 822 "" 823 "@ 824 lwz%U1%X1 %0,%1 825 rldicl %0,%1,0,32 826 lfiwzx %0,%y1 827 lxsiwzx %x0,%y1 828 mtvsrwz %x0,%1 829 mfvsrwz %0,%x1 830 xxextractuw %x0,%x1,4" 831 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")]) 832 833(define_insn_and_split "*zero_extendsi<mode>2_dot" 834 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 835 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 836 (const_int 0))) 837 (clobber (match_scratch:EXTSI 0 "=r,r"))] 838 "rs6000_gen_cell_microcode" 839 "@ 840 rldicl. %0,%1,0,32 841 #" 842 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 843 [(set (match_dup 0) 844 (zero_extend:DI (match_dup 1))) 845 (set (match_dup 2) 846 (compare:CC (match_dup 0) 847 (const_int 0)))] 848 "" 849 [(set_attr "type" "shift") 850 (set_attr "dot" "yes") 851 (set_attr "length" "4,8")]) 852 853(define_insn_and_split "*zero_extendsi<mode>2_dot2" 854 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 855 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 856 (const_int 0))) 857 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") 858 (zero_extend:EXTSI (match_dup 1)))] 859 "rs6000_gen_cell_microcode" 860 "@ 861 rldicl. %0,%1,0,32 862 #" 863 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 864 [(set (match_dup 0) 865 (zero_extend:EXTSI (match_dup 1))) 866 (set (match_dup 2) 867 (compare:CC (match_dup 0) 868 (const_int 0)))] 869 "" 870 [(set_attr "type" "shift") 871 (set_attr "dot" "yes") 872 (set_attr "length" "4,8")]) 873 874 875(define_insn "extendqi<mode>2" 876 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK") 877 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))] 878 "" 879 "@ 880 extsb %0,%1 881 vextsb2d %0,%1" 882 [(set_attr "type" "exts,vecperm")]) 883 884(define_insn_and_split "*extendqi<mode>2_dot" 885 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 886 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 887 (const_int 0))) 888 (clobber (match_scratch:EXTQI 0 "=r,r"))] 889 "rs6000_gen_cell_microcode" 890 "@ 891 extsb. %0,%1 892 #" 893 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 894 [(set (match_dup 0) 895 (sign_extend:EXTQI (match_dup 1))) 896 (set (match_dup 2) 897 (compare:CC (match_dup 0) 898 (const_int 0)))] 899 "" 900 [(set_attr "type" "exts") 901 (set_attr "dot" "yes") 902 (set_attr "length" "4,8")]) 903 904(define_insn_and_split "*extendqi<mode>2_dot2" 905 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 906 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 907 (const_int 0))) 908 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 909 (sign_extend:EXTQI (match_dup 1)))] 910 "rs6000_gen_cell_microcode" 911 "@ 912 extsb. %0,%1 913 #" 914 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 915 [(set (match_dup 0) 916 (sign_extend:EXTQI (match_dup 1))) 917 (set (match_dup 2) 918 (compare:CC (match_dup 0) 919 (const_int 0)))] 920 "" 921 [(set_attr "type" "exts") 922 (set_attr "dot" "yes") 923 (set_attr "length" "4,8")]) 924 925 926(define_expand "extendhi<mode>2" 927 [(set (match_operand:EXTHI 0 "gpc_reg_operand") 928 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))] 929 "" 930 "") 931 932(define_insn "*extendhi<mode>2" 933 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK") 934 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))] 935 "rs6000_gen_cell_microcode || TARGET_VSX_SMALL_INTEGER" 936 "@ 937 lha%U1%X1 %0,%1 938 extsh %0,%1 939 # 940 vextsh2d %0,%1" 941 [(set_attr "type" "load,exts,fpload,vecperm") 942 (set_attr "sign_extend" "yes") 943 (set_attr "length" "4,4,8,4")]) 944 945(define_split 946 [(set (match_operand:EXTHI 0 "altivec_register_operand") 947 (sign_extend:EXTHI 948 (match_operand:HI 1 "indexed_or_indirect_operand")))] 949 "TARGET_P9_VECTOR && reload_completed" 950 [(set (match_dup 2) 951 (match_dup 1)) 952 (set (match_dup 0) 953 (sign_extend:EXTHI (match_dup 2)))] 954{ 955 operands[2] = gen_rtx_REG (HImode, REGNO (operands[1])); 956}) 957 958(define_insn "*extendhi<mode>2_noload" 959 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r") 960 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r")))] 961 "!rs6000_gen_cell_microcode" 962 "extsh %0,%1" 963 [(set_attr "type" "exts")]) 964 965(define_insn_and_split "*extendhi<mode>2_dot" 966 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 967 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 968 (const_int 0))) 969 (clobber (match_scratch:EXTHI 0 "=r,r"))] 970 "rs6000_gen_cell_microcode" 971 "@ 972 extsh. %0,%1 973 #" 974 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 975 [(set (match_dup 0) 976 (sign_extend:EXTHI (match_dup 1))) 977 (set (match_dup 2) 978 (compare:CC (match_dup 0) 979 (const_int 0)))] 980 "" 981 [(set_attr "type" "exts") 982 (set_attr "dot" "yes") 983 (set_attr "length" "4,8")]) 984 985(define_insn_and_split "*extendhi<mode>2_dot2" 986 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 987 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 988 (const_int 0))) 989 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 990 (sign_extend:EXTHI (match_dup 1)))] 991 "rs6000_gen_cell_microcode" 992 "@ 993 extsh. %0,%1 994 #" 995 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 996 [(set (match_dup 0) 997 (sign_extend:EXTHI (match_dup 1))) 998 (set (match_dup 2) 999 (compare:CC (match_dup 0) 1000 (const_int 0)))] 1001 "" 1002 [(set_attr "type" "exts") 1003 (set_attr "dot" "yes") 1004 (set_attr "length" "4,8")]) 1005 1006 1007(define_insn "extendsi<mode>2" 1008 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wl,wu,wj,wK,wH") 1009 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" "Y,r,Z,Z,r,wK,wH")))] 1010 "" 1011 "@ 1012 lwa%U1%X1 %0,%1 1013 extsw %0,%1 1014 lfiwax %0,%y1 1015 lxsiwax %x0,%y1 1016 mtvsrwa %x0,%1 1017 vextsw2d %0,%1 1018 #" 1019 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm") 1020 (set_attr "sign_extend" "yes") 1021 (set_attr "length" "4,4,4,4,4,4,8")]) 1022 1023(define_split 1024 [(set (match_operand:DI 0 "altivec_register_operand") 1025 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))] 1026 "TARGET_VSX_SMALL_INTEGER && TARGET_P8_VECTOR && !TARGET_P9_VECTOR 1027 && reload_completed" 1028 [(const_int 0)] 1029{ 1030 rtx dest = operands[0]; 1031 rtx src = operands[1]; 1032 int dest_regno = REGNO (dest); 1033 int src_regno = REGNO (src); 1034 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno); 1035 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno); 1036 1037 if (VECTOR_ELT_ORDER_BIG) 1038 { 1039 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si)); 1040 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx)); 1041 } 1042 else 1043 { 1044 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si)); 1045 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx)); 1046 } 1047 DONE; 1048}) 1049 1050(define_insn_and_split "*extendsi<mode>2_dot" 1051 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1052 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 1053 (const_int 0))) 1054 (clobber (match_scratch:EXTSI 0 "=r,r"))] 1055 "rs6000_gen_cell_microcode" 1056 "@ 1057 extsw. %0,%1 1058 #" 1059 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1060 [(set (match_dup 0) 1061 (sign_extend:EXTSI (match_dup 1))) 1062 (set (match_dup 2) 1063 (compare:CC (match_dup 0) 1064 (const_int 0)))] 1065 "" 1066 [(set_attr "type" "exts") 1067 (set_attr "dot" "yes") 1068 (set_attr "length" "4,8")]) 1069 1070(define_insn_and_split "*extendsi<mode>2_dot2" 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 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") 1075 (sign_extend:EXTSI (match_dup 1)))] 1076 "rs6000_gen_cell_microcode" 1077 "@ 1078 extsw. %0,%1 1079 #" 1080 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1081 [(set (match_dup 0) 1082 (sign_extend:EXTSI (match_dup 1))) 1083 (set (match_dup 2) 1084 (compare:CC (match_dup 0) 1085 (const_int 0)))] 1086 "" 1087 [(set_attr "type" "exts") 1088 (set_attr "dot" "yes") 1089 (set_attr "length" "4,8")]) 1090 1091;; IBM 405, 440, 464 and 476 half-word multiplication operations. 1092 1093(define_insn "*macchwc" 1094 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1095 (compare:CC (plus:SI (mult:SI (ashiftrt:SI 1096 (match_operand:SI 2 "gpc_reg_operand" "r") 1097 (const_int 16)) 1098 (sign_extend:SI 1099 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1100 (match_operand:SI 4 "gpc_reg_operand" "0")) 1101 (const_int 0))) 1102 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1103 (plus:SI (mult:SI (ashiftrt:SI 1104 (match_dup 2) 1105 (const_int 16)) 1106 (sign_extend:SI 1107 (match_dup 1))) 1108 (match_dup 4)))] 1109 "TARGET_MULHW" 1110 "macchw. %0,%1,%2" 1111 [(set_attr "type" "halfmul")]) 1112 1113(define_insn "*macchw" 1114 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1115 (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 3 "gpc_reg_operand" "0")))] 1121 "TARGET_MULHW" 1122 "macchw %0,%1,%2" 1123 [(set_attr "type" "halfmul")]) 1124 1125(define_insn "*macchwuc" 1126 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1127 (compare:CC (plus:SI (mult:SI (lshiftrt:SI 1128 (match_operand:SI 2 "gpc_reg_operand" "r") 1129 (const_int 16)) 1130 (zero_extend:SI 1131 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1132 (match_operand:SI 4 "gpc_reg_operand" "0")) 1133 (const_int 0))) 1134 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1135 (plus:SI (mult:SI (lshiftrt:SI 1136 (match_dup 2) 1137 (const_int 16)) 1138 (zero_extend:SI 1139 (match_dup 1))) 1140 (match_dup 4)))] 1141 "TARGET_MULHW" 1142 "macchwu. %0,%1,%2" 1143 [(set_attr "type" "halfmul")]) 1144 1145(define_insn "*macchwu" 1146 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1147 (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 3 "gpc_reg_operand" "0")))] 1153 "TARGET_MULHW" 1154 "macchwu %0,%1,%2" 1155 [(set_attr "type" "halfmul")]) 1156 1157(define_insn "*machhwc" 1158 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1159 (compare:CC (plus:SI (mult:SI (ashiftrt:SI 1160 (match_operand:SI 1 "gpc_reg_operand" "%r") 1161 (const_int 16)) 1162 (ashiftrt:SI 1163 (match_operand:SI 2 "gpc_reg_operand" "r") 1164 (const_int 16))) 1165 (match_operand:SI 4 "gpc_reg_operand" "0")) 1166 (const_int 0))) 1167 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1168 (plus:SI (mult:SI (ashiftrt:SI 1169 (match_dup 1) 1170 (const_int 16)) 1171 (ashiftrt:SI 1172 (match_dup 2) 1173 (const_int 16))) 1174 (match_dup 4)))] 1175 "TARGET_MULHW" 1176 "machhw. %0,%1,%2" 1177 [(set_attr "type" "halfmul")]) 1178 1179(define_insn "*machhw" 1180 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1181 (plus:SI (mult:SI (ashiftrt:SI 1182 (match_operand:SI 1 "gpc_reg_operand" "%r") 1183 (const_int 16)) 1184 (ashiftrt:SI 1185 (match_operand:SI 2 "gpc_reg_operand" "r") 1186 (const_int 16))) 1187 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1188 "TARGET_MULHW" 1189 "machhw %0,%1,%2" 1190 [(set_attr "type" "halfmul")]) 1191 1192(define_insn "*machhwuc" 1193 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1194 (compare:CC (plus:SI (mult:SI (lshiftrt:SI 1195 (match_operand:SI 1 "gpc_reg_operand" "%r") 1196 (const_int 16)) 1197 (lshiftrt:SI 1198 (match_operand:SI 2 "gpc_reg_operand" "r") 1199 (const_int 16))) 1200 (match_operand:SI 4 "gpc_reg_operand" "0")) 1201 (const_int 0))) 1202 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1203 (plus:SI (mult:SI (lshiftrt:SI 1204 (match_dup 1) 1205 (const_int 16)) 1206 (lshiftrt:SI 1207 (match_dup 2) 1208 (const_int 16))) 1209 (match_dup 4)))] 1210 "TARGET_MULHW" 1211 "machhwu. %0,%1,%2" 1212 [(set_attr "type" "halfmul")]) 1213 1214(define_insn "*machhwu" 1215 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1216 (plus:SI (mult:SI (lshiftrt:SI 1217 (match_operand:SI 1 "gpc_reg_operand" "%r") 1218 (const_int 16)) 1219 (lshiftrt:SI 1220 (match_operand:SI 2 "gpc_reg_operand" "r") 1221 (const_int 16))) 1222 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1223 "TARGET_MULHW" 1224 "machhwu %0,%1,%2" 1225 [(set_attr "type" "halfmul")]) 1226 1227(define_insn "*maclhwc" 1228 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1229 (compare:CC (plus:SI (mult:SI (sign_extend:SI 1230 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1231 (sign_extend:SI 1232 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1233 (match_operand:SI 4 "gpc_reg_operand" "0")) 1234 (const_int 0))) 1235 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1236 (plus:SI (mult:SI (sign_extend:SI 1237 (match_dup 1)) 1238 (sign_extend:SI 1239 (match_dup 2))) 1240 (match_dup 4)))] 1241 "TARGET_MULHW" 1242 "maclhw. %0,%1,%2" 1243 [(set_attr "type" "halfmul")]) 1244 1245(define_insn "*maclhw" 1246 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1247 (plus:SI (mult:SI (sign_extend:SI 1248 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1249 (sign_extend:SI 1250 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1251 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1252 "TARGET_MULHW" 1253 "maclhw %0,%1,%2" 1254 [(set_attr "type" "halfmul")]) 1255 1256(define_insn "*maclhwuc" 1257 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1258 (compare:CC (plus:SI (mult:SI (zero_extend:SI 1259 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1260 (zero_extend:SI 1261 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1262 (match_operand:SI 4 "gpc_reg_operand" "0")) 1263 (const_int 0))) 1264 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1265 (plus:SI (mult:SI (zero_extend:SI 1266 (match_dup 1)) 1267 (zero_extend:SI 1268 (match_dup 2))) 1269 (match_dup 4)))] 1270 "TARGET_MULHW" 1271 "maclhwu. %0,%1,%2" 1272 [(set_attr "type" "halfmul")]) 1273 1274(define_insn "*maclhwu" 1275 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1276 (plus:SI (mult:SI (zero_extend:SI 1277 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1278 (zero_extend:SI 1279 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1280 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1281 "TARGET_MULHW" 1282 "maclhwu %0,%1,%2" 1283 [(set_attr "type" "halfmul")]) 1284 1285(define_insn "*nmacchwc" 1286 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1287 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1288 (mult:SI (ashiftrt:SI 1289 (match_operand:SI 2 "gpc_reg_operand" "r") 1290 (const_int 16)) 1291 (sign_extend:SI 1292 (match_operand:HI 1 "gpc_reg_operand" "r")))) 1293 (const_int 0))) 1294 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1295 (minus:SI (match_dup 4) 1296 (mult:SI (ashiftrt:SI 1297 (match_dup 2) 1298 (const_int 16)) 1299 (sign_extend:SI 1300 (match_dup 1)))))] 1301 "TARGET_MULHW" 1302 "nmacchw. %0,%1,%2" 1303 [(set_attr "type" "halfmul")]) 1304 1305(define_insn "*nmacchw" 1306 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1307 (minus:SI (match_operand:SI 3 "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 "TARGET_MULHW" 1314 "nmacchw %0,%1,%2" 1315 [(set_attr "type" "halfmul")]) 1316 1317(define_insn "*nmachhwc" 1318 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1319 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1320 (mult:SI (ashiftrt:SI 1321 (match_operand:SI 1 "gpc_reg_operand" "%r") 1322 (const_int 16)) 1323 (ashiftrt:SI 1324 (match_operand:SI 2 "gpc_reg_operand" "r") 1325 (const_int 16)))) 1326 (const_int 0))) 1327 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1328 (minus:SI (match_dup 4) 1329 (mult:SI (ashiftrt:SI 1330 (match_dup 1) 1331 (const_int 16)) 1332 (ashiftrt:SI 1333 (match_dup 2) 1334 (const_int 16)))))] 1335 "TARGET_MULHW" 1336 "nmachhw. %0,%1,%2" 1337 [(set_attr "type" "halfmul")]) 1338 1339(define_insn "*nmachhw" 1340 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1341 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1342 (mult:SI (ashiftrt:SI 1343 (match_operand:SI 1 "gpc_reg_operand" "%r") 1344 (const_int 16)) 1345 (ashiftrt:SI 1346 (match_operand:SI 2 "gpc_reg_operand" "r") 1347 (const_int 16)))))] 1348 "TARGET_MULHW" 1349 "nmachhw %0,%1,%2" 1350 [(set_attr "type" "halfmul")]) 1351 1352(define_insn "*nmaclhwc" 1353 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1354 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1355 (mult:SI (sign_extend:SI 1356 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1357 (sign_extend:SI 1358 (match_operand:HI 2 "gpc_reg_operand" "r")))) 1359 (const_int 0))) 1360 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1361 (minus:SI (match_dup 4) 1362 (mult:SI (sign_extend:SI 1363 (match_dup 1)) 1364 (sign_extend:SI 1365 (match_dup 2)))))] 1366 "TARGET_MULHW" 1367 "nmaclhw. %0,%1,%2" 1368 [(set_attr "type" "halfmul")]) 1369 1370(define_insn "*nmaclhw" 1371 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1372 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1373 (mult:SI (sign_extend:SI 1374 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1375 (sign_extend:SI 1376 (match_operand:HI 2 "gpc_reg_operand" "r")))))] 1377 "TARGET_MULHW" 1378 "nmaclhw %0,%1,%2" 1379 [(set_attr "type" "halfmul")]) 1380 1381(define_insn "*mulchwc" 1382 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1383 (compare:CC (mult:SI (ashiftrt:SI 1384 (match_operand:SI 2 "gpc_reg_operand" "r") 1385 (const_int 16)) 1386 (sign_extend:SI 1387 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1388 (const_int 0))) 1389 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1390 (mult:SI (ashiftrt:SI 1391 (match_dup 2) 1392 (const_int 16)) 1393 (sign_extend:SI 1394 (match_dup 1))))] 1395 "TARGET_MULHW" 1396 "mulchw. %0,%1,%2" 1397 [(set_attr "type" "halfmul")]) 1398 1399(define_insn "*mulchw" 1400 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1401 (mult:SI (ashiftrt:SI 1402 (match_operand:SI 2 "gpc_reg_operand" "r") 1403 (const_int 16)) 1404 (sign_extend:SI 1405 (match_operand:HI 1 "gpc_reg_operand" "r"))))] 1406 "TARGET_MULHW" 1407 "mulchw %0,%1,%2" 1408 [(set_attr "type" "halfmul")]) 1409 1410(define_insn "*mulchwuc" 1411 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1412 (compare:CC (mult:SI (lshiftrt:SI 1413 (match_operand:SI 2 "gpc_reg_operand" "r") 1414 (const_int 16)) 1415 (zero_extend:SI 1416 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1417 (const_int 0))) 1418 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1419 (mult:SI (lshiftrt:SI 1420 (match_dup 2) 1421 (const_int 16)) 1422 (zero_extend:SI 1423 (match_dup 1))))] 1424 "TARGET_MULHW" 1425 "mulchwu. %0,%1,%2" 1426 [(set_attr "type" "halfmul")]) 1427 1428(define_insn "*mulchwu" 1429 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1430 (mult:SI (lshiftrt:SI 1431 (match_operand:SI 2 "gpc_reg_operand" "r") 1432 (const_int 16)) 1433 (zero_extend:SI 1434 (match_operand:HI 1 "gpc_reg_operand" "r"))))] 1435 "TARGET_MULHW" 1436 "mulchwu %0,%1,%2" 1437 [(set_attr "type" "halfmul")]) 1438 1439(define_insn "*mulhhwc" 1440 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1441 (compare:CC (mult:SI (ashiftrt:SI 1442 (match_operand:SI 1 "gpc_reg_operand" "%r") 1443 (const_int 16)) 1444 (ashiftrt:SI 1445 (match_operand:SI 2 "gpc_reg_operand" "r") 1446 (const_int 16))) 1447 (const_int 0))) 1448 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1449 (mult:SI (ashiftrt:SI 1450 (match_dup 1) 1451 (const_int 16)) 1452 (ashiftrt:SI 1453 (match_dup 2) 1454 (const_int 16))))] 1455 "TARGET_MULHW" 1456 "mulhhw. %0,%1,%2" 1457 [(set_attr "type" "halfmul")]) 1458 1459(define_insn "*mulhhw" 1460 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1461 (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 "TARGET_MULHW" 1468 "mulhhw %0,%1,%2" 1469 [(set_attr "type" "halfmul")]) 1470 1471(define_insn "*mulhhwuc" 1472 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1473 (compare:CC (mult:SI (lshiftrt:SI 1474 (match_operand:SI 1 "gpc_reg_operand" "%r") 1475 (const_int 16)) 1476 (lshiftrt:SI 1477 (match_operand:SI 2 "gpc_reg_operand" "r") 1478 (const_int 16))) 1479 (const_int 0))) 1480 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1481 (mult:SI (lshiftrt:SI 1482 (match_dup 1) 1483 (const_int 16)) 1484 (lshiftrt:SI 1485 (match_dup 2) 1486 (const_int 16))))] 1487 "TARGET_MULHW" 1488 "mulhhwu. %0,%1,%2" 1489 [(set_attr "type" "halfmul")]) 1490 1491(define_insn "*mulhhwu" 1492 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1493 (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 "TARGET_MULHW" 1500 "mulhhwu %0,%1,%2" 1501 [(set_attr "type" "halfmul")]) 1502 1503(define_insn "*mullhwc" 1504 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1505 (compare:CC (mult:SI (sign_extend:SI 1506 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1507 (sign_extend:SI 1508 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1509 (const_int 0))) 1510 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1511 (mult:SI (sign_extend:SI 1512 (match_dup 1)) 1513 (sign_extend:SI 1514 (match_dup 2))))] 1515 "TARGET_MULHW" 1516 "mullhw. %0,%1,%2" 1517 [(set_attr "type" "halfmul")]) 1518 1519(define_insn "*mullhw" 1520 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1521 (mult:SI (sign_extend:SI 1522 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1523 (sign_extend:SI 1524 (match_operand:HI 2 "gpc_reg_operand" "r"))))] 1525 "TARGET_MULHW" 1526 "mullhw %0,%1,%2" 1527 [(set_attr "type" "halfmul")]) 1528 1529(define_insn "*mullhwuc" 1530 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1531 (compare:CC (mult:SI (zero_extend:SI 1532 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1533 (zero_extend:SI 1534 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1535 (const_int 0))) 1536 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1537 (mult:SI (zero_extend:SI 1538 (match_dup 1)) 1539 (zero_extend:SI 1540 (match_dup 2))))] 1541 "TARGET_MULHW" 1542 "mullhwu. %0,%1,%2" 1543 [(set_attr "type" "halfmul")]) 1544 1545(define_insn "*mullhwu" 1546 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1547 (mult:SI (zero_extend:SI 1548 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1549 (zero_extend:SI 1550 (match_operand:HI 2 "gpc_reg_operand" "r"))))] 1551 "TARGET_MULHW" 1552 "mullhwu %0,%1,%2" 1553 [(set_attr "type" "halfmul")]) 1554 1555;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support. 1556(define_insn "dlmzb" 1557 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1558 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 1559 (match_operand:SI 2 "gpc_reg_operand" "r")] 1560 UNSPEC_DLMZB_CR)) 1561 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1562 (unspec:SI [(match_dup 1) 1563 (match_dup 2)] 1564 UNSPEC_DLMZB))] 1565 "TARGET_DLMZB" 1566 "dlmzb. %0,%1,%2") 1567 1568(define_expand "strlensi" 1569 [(set (match_operand:SI 0 "gpc_reg_operand" "") 1570 (unspec:SI [(match_operand:BLK 1 "general_operand" "") 1571 (match_operand:QI 2 "const_int_operand" "") 1572 (match_operand 3 "const_int_operand" "")] 1573 UNSPEC_DLMZB_STRLEN)) 1574 (clobber (match_scratch:CC 4 "=x"))] 1575 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size" 1576{ 1577 rtx result = operands[0]; 1578 rtx src = operands[1]; 1579 rtx search_char = operands[2]; 1580 rtx align = operands[3]; 1581 rtx addr, scratch_string, word1, word2, scratch_dlmzb; 1582 rtx loop_label, end_label, mem, cr0, cond; 1583 if (search_char != const0_rtx 1584 || GET_CODE (align) != CONST_INT 1585 || INTVAL (align) < 8) 1586 FAIL; 1587 word1 = gen_reg_rtx (SImode); 1588 word2 = gen_reg_rtx (SImode); 1589 scratch_dlmzb = gen_reg_rtx (SImode); 1590 scratch_string = gen_reg_rtx (Pmode); 1591 loop_label = gen_label_rtx (); 1592 end_label = gen_label_rtx (); 1593 addr = force_reg (Pmode, XEXP (src, 0)); 1594 emit_move_insn (scratch_string, addr); 1595 emit_label (loop_label); 1596 mem = change_address (src, SImode, scratch_string); 1597 emit_move_insn (word1, mem); 1598 emit_move_insn (word2, adjust_address (mem, SImode, 4)); 1599 cr0 = gen_rtx_REG (CCmode, CR0_REGNO); 1600 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0)); 1601 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx); 1602 emit_jump_insn (gen_rtx_SET (pc_rtx, 1603 gen_rtx_IF_THEN_ELSE (VOIDmode, 1604 cond, 1605 gen_rtx_LABEL_REF 1606 (VOIDmode, 1607 end_label), 1608 pc_rtx))); 1609 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8))); 1610 emit_jump_insn (gen_rtx_SET (pc_rtx, 1611 gen_rtx_LABEL_REF (VOIDmode, loop_label))); 1612 emit_barrier (); 1613 emit_label (end_label); 1614 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb)); 1615 emit_insn (gen_subsi3 (result, scratch_string, addr)); 1616 emit_insn (gen_addsi3 (result, result, constm1_rtx)); 1617 DONE; 1618}) 1619 1620;; Fixed-point arithmetic insns. 1621 1622(define_expand "add<mode>3" 1623 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 1624 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "") 1625 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))] 1626 "" 1627{ 1628 if (<MODE>mode == DImode && !TARGET_POWERPC64) 1629 { 1630 rtx lo0 = gen_lowpart (SImode, operands[0]); 1631 rtx lo1 = gen_lowpart (SImode, operands[1]); 1632 rtx lo2 = gen_lowpart (SImode, operands[2]); 1633 rtx hi0 = gen_highpart (SImode, operands[0]); 1634 rtx hi1 = gen_highpart (SImode, operands[1]); 1635 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]); 1636 1637 if (!reg_or_short_operand (lo2, SImode)) 1638 lo2 = force_reg (SImode, lo2); 1639 if (!adde_operand (hi2, SImode)) 1640 hi2 = force_reg (SImode, hi2); 1641 1642 emit_insn (gen_addsi3_carry (lo0, lo1, lo2)); 1643 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2)); 1644 DONE; 1645 } 1646 1647 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode)) 1648 { 1649 rtx tmp = ((!can_create_pseudo_p () 1650 || rtx_equal_p (operands[0], operands[1])) 1651 ? operands[0] : gen_reg_rtx (<MODE>mode)); 1652 1653 HOST_WIDE_INT val = INTVAL (operands[2]); 1654 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1655 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); 1656 1657 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest))) 1658 FAIL; 1659 1660 /* The ordering here is important for the prolog expander. 1661 When space is allocated from the stack, adding 'low' first may 1662 produce a temporary deallocation (which would be bad). */ 1663 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest))); 1664 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low))); 1665 DONE; 1666 } 1667}) 1668 1669(define_insn "*add<mode>3" 1670 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r") 1671 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b") 1672 (match_operand:GPR 2 "add_operand" "r,I,L")))] 1673 "" 1674 "@ 1675 add %0,%1,%2 1676 addi %0,%1,%2 1677 addis %0,%1,%v2" 1678 [(set_attr "type" "add")]) 1679 1680(define_insn "addsi3_high" 1681 [(set (match_operand:SI 0 "gpc_reg_operand" "=b") 1682 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") 1683 (high:SI (match_operand 2 "" ""))))] 1684 "TARGET_MACHO && !TARGET_64BIT" 1685 "addis %0,%1,ha16(%2)" 1686 [(set_attr "type" "add")]) 1687 1688(define_insn_and_split "*add<mode>3_dot" 1689 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1690 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 1691 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 1692 (const_int 0))) 1693 (clobber (match_scratch:GPR 0 "=r,r"))] 1694 "<MODE>mode == Pmode" 1695 "@ 1696 add. %0,%1,%2 1697 #" 1698 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1699 [(set (match_dup 0) 1700 (plus:GPR (match_dup 1) 1701 (match_dup 2))) 1702 (set (match_dup 3) 1703 (compare:CC (match_dup 0) 1704 (const_int 0)))] 1705 "" 1706 [(set_attr "type" "add") 1707 (set_attr "dot" "yes") 1708 (set_attr "length" "4,8")]) 1709 1710(define_insn_and_split "*add<mode>3_dot2" 1711 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1712 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 1713 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 1714 (const_int 0))) 1715 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1716 (plus:GPR (match_dup 1) 1717 (match_dup 2)))] 1718 "<MODE>mode == Pmode" 1719 "@ 1720 add. %0,%1,%2 1721 #" 1722 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1723 [(set (match_dup 0) 1724 (plus:GPR (match_dup 1) 1725 (match_dup 2))) 1726 (set (match_dup 3) 1727 (compare:CC (match_dup 0) 1728 (const_int 0)))] 1729 "" 1730 [(set_attr "type" "add") 1731 (set_attr "dot" "yes") 1732 (set_attr "length" "4,8")]) 1733 1734(define_insn_and_split "*add<mode>3_imm_dot" 1735 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1736 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b") 1737 (match_operand:GPR 2 "short_cint_operand" "I,I")) 1738 (const_int 0))) 1739 (clobber (match_scratch:GPR 0 "=r,r")) 1740 (clobber (reg:GPR CA_REGNO))] 1741 "<MODE>mode == Pmode" 1742 "@ 1743 addic. %0,%1,%2 1744 #" 1745 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1746 [(set (match_dup 0) 1747 (plus:GPR (match_dup 1) 1748 (match_dup 2))) 1749 (set (match_dup 3) 1750 (compare:CC (match_dup 0) 1751 (const_int 0)))] 1752 "" 1753 [(set_attr "type" "add") 1754 (set_attr "dot" "yes") 1755 (set_attr "length" "4,8")]) 1756 1757(define_insn_and_split "*add<mode>3_imm_dot2" 1758 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1759 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b") 1760 (match_operand:GPR 2 "short_cint_operand" "I,I")) 1761 (const_int 0))) 1762 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1763 (plus:GPR (match_dup 1) 1764 (match_dup 2))) 1765 (clobber (reg:GPR CA_REGNO))] 1766 "<MODE>mode == Pmode" 1767 "@ 1768 addic. %0,%1,%2 1769 #" 1770 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1771 [(set (match_dup 0) 1772 (plus:GPR (match_dup 1) 1773 (match_dup 2))) 1774 (set (match_dup 3) 1775 (compare:CC (match_dup 0) 1776 (const_int 0)))] 1777 "" 1778 [(set_attr "type" "add") 1779 (set_attr "dot" "yes") 1780 (set_attr "length" "4,8")]) 1781 1782;; Split an add that we can't do in one insn into two insns, each of which 1783;; does one 16-bit part. This is used by combine. Note that the low-order 1784;; add should be last in case the result gets used in an address. 1785 1786(define_split 1787 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 1788 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "") 1789 (match_operand:GPR 2 "non_add_cint_operand" "")))] 1790 "" 1791 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3))) 1792 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))] 1793{ 1794 HOST_WIDE_INT val = INTVAL (operands[2]); 1795 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1796 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); 1797 1798 operands[4] = GEN_INT (low); 1799 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest))) 1800 operands[3] = GEN_INT (rest); 1801 else if (can_create_pseudo_p ()) 1802 { 1803 operands[3] = gen_reg_rtx (DImode); 1804 emit_move_insn (operands[3], operands[2]); 1805 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3])); 1806 DONE; 1807 } 1808 else 1809 FAIL; 1810}) 1811 1812 1813(define_insn "add<mode>3_carry" 1814 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1815 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1816 (match_operand:P 2 "reg_or_short_operand" "rI"))) 1817 (set (reg:P CA_REGNO) 1818 (ltu:P (plus:P (match_dup 1) 1819 (match_dup 2)) 1820 (match_dup 1)))] 1821 "" 1822 "add%I2c %0,%1,%2" 1823 [(set_attr "type" "add")]) 1824 1825(define_insn "*add<mode>3_imm_carry_pos" 1826 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1827 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1828 (match_operand:P 2 "short_cint_operand" "n"))) 1829 (set (reg:P CA_REGNO) 1830 (geu:P (match_dup 1) 1831 (match_operand:P 3 "const_int_operand" "n")))] 1832 "INTVAL (operands[2]) > 0 1833 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0" 1834 "addic %0,%1,%2" 1835 [(set_attr "type" "add")]) 1836 1837(define_insn "*add<mode>3_imm_carry_0" 1838 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1839 (match_operand:P 1 "gpc_reg_operand" "r")) 1840 (set (reg:P CA_REGNO) 1841 (const_int 0))] 1842 "" 1843 "addic %0,%1,0" 1844 [(set_attr "type" "add")]) 1845 1846(define_insn "*add<mode>3_imm_carry_m1" 1847 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1848 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1849 (const_int -1))) 1850 (set (reg:P CA_REGNO) 1851 (ne:P (match_dup 1) 1852 (const_int 0)))] 1853 "" 1854 "addic %0,%1,-1" 1855 [(set_attr "type" "add")]) 1856 1857(define_insn "*add<mode>3_imm_carry_neg" 1858 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1859 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1860 (match_operand:P 2 "short_cint_operand" "n"))) 1861 (set (reg:P CA_REGNO) 1862 (gtu:P (match_dup 1) 1863 (match_operand:P 3 "const_int_operand" "n")))] 1864 "INTVAL (operands[2]) < 0 1865 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1" 1866 "addic %0,%1,%2" 1867 [(set_attr "type" "add")]) 1868 1869 1870(define_expand "add<mode>3_carry_in" 1871 [(parallel [ 1872 (set (match_operand:GPR 0 "gpc_reg_operand") 1873 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand") 1874 (match_operand:GPR 2 "adde_operand")) 1875 (reg:GPR CA_REGNO))) 1876 (clobber (reg:GPR CA_REGNO))])] 1877 "" 1878{ 1879 if (operands[2] == const0_rtx) 1880 { 1881 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1])); 1882 DONE; 1883 } 1884 if (operands[2] == constm1_rtx) 1885 { 1886 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1])); 1887 DONE; 1888 } 1889}) 1890 1891(define_insn "*add<mode>3_carry_in_internal" 1892 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1893 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1894 (match_operand:GPR 2 "gpc_reg_operand" "r")) 1895 (reg:GPR CA_REGNO))) 1896 (clobber (reg:GPR CA_REGNO))] 1897 "" 1898 "adde %0,%1,%2" 1899 [(set_attr "type" "add")]) 1900 1901(define_insn "add<mode>3_carry_in_0" 1902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1903 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1904 (reg:GPR CA_REGNO))) 1905 (clobber (reg:GPR CA_REGNO))] 1906 "" 1907 "addze %0,%1" 1908 [(set_attr "type" "add")]) 1909 1910(define_insn "add<mode>3_carry_in_m1" 1911 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1912 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1913 (reg:GPR CA_REGNO)) 1914 (const_int -1))) 1915 (clobber (reg:GPR CA_REGNO))] 1916 "" 1917 "addme %0,%1" 1918 [(set_attr "type" "add")]) 1919 1920 1921(define_expand "one_cmpl<mode>2" 1922 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 1923 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))] 1924 "" 1925{ 1926 if (<MODE>mode == DImode && !TARGET_POWERPC64) 1927 { 1928 rs6000_split_logical (operands, NOT, false, false, false); 1929 DONE; 1930 } 1931}) 1932 1933(define_insn "*one_cmpl<mode>2" 1934 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1935 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 1936 "" 1937 "not %0,%1") 1938 1939(define_insn_and_split "*one_cmpl<mode>2_dot" 1940 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1941 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 1942 (const_int 0))) 1943 (clobber (match_scratch:GPR 0 "=r,r"))] 1944 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 1945 "@ 1946 not. %0,%1 1947 #" 1948 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1949 [(set (match_dup 0) 1950 (not:GPR (match_dup 1))) 1951 (set (match_dup 2) 1952 (compare:CC (match_dup 0) 1953 (const_int 0)))] 1954 "" 1955 [(set_attr "type" "logical") 1956 (set_attr "dot" "yes") 1957 (set_attr "length" "4,8")]) 1958 1959(define_insn_and_split "*one_cmpl<mode>2_dot2" 1960 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1961 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 1962 (const_int 0))) 1963 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1964 (not:GPR (match_dup 1)))] 1965 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 1966 "@ 1967 not. %0,%1 1968 #" 1969 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1970 [(set (match_dup 0) 1971 (not:GPR (match_dup 1))) 1972 (set (match_dup 2) 1973 (compare:CC (match_dup 0) 1974 (const_int 0)))] 1975 "" 1976 [(set_attr "type" "logical") 1977 (set_attr "dot" "yes") 1978 (set_attr "length" "4,8")]) 1979 1980 1981(define_expand "sub<mode>3" 1982 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 1983 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "") 1984 (match_operand:SDI 2 "gpc_reg_operand" "")))] 1985 "" 1986{ 1987 if (<MODE>mode == DImode && !TARGET_POWERPC64) 1988 { 1989 rtx lo0 = gen_lowpart (SImode, operands[0]); 1990 rtx lo1 = gen_lowpart (SImode, operands[1]); 1991 rtx lo2 = gen_lowpart (SImode, operands[2]); 1992 rtx hi0 = gen_highpart (SImode, operands[0]); 1993 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]); 1994 rtx hi2 = gen_highpart (SImode, operands[2]); 1995 1996 if (!reg_or_short_operand (lo1, SImode)) 1997 lo1 = force_reg (SImode, lo1); 1998 if (!adde_operand (hi1, SImode)) 1999 hi1 = force_reg (SImode, hi1); 2000 2001 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1)); 2002 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1)); 2003 DONE; 2004 } 2005 2006 if (short_cint_operand (operands[1], <MODE>mode)) 2007 { 2008 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1])); 2009 DONE; 2010 } 2011}) 2012 2013(define_insn "*subf<mode>3" 2014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2015 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r") 2016 (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2017 "" 2018 "subf %0,%1,%2" 2019 [(set_attr "type" "add")]) 2020 2021(define_insn_and_split "*subf<mode>3_dot" 2022 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2023 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r") 2024 (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2025 (const_int 0))) 2026 (clobber (match_scratch:GPR 0 "=r,r"))] 2027 "<MODE>mode == Pmode" 2028 "@ 2029 subf. %0,%1,%2 2030 #" 2031 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2032 [(set (match_dup 0) 2033 (minus:GPR (match_dup 2) 2034 (match_dup 1))) 2035 (set (match_dup 3) 2036 (compare:CC (match_dup 0) 2037 (const_int 0)))] 2038 "" 2039 [(set_attr "type" "add") 2040 (set_attr "dot" "yes") 2041 (set_attr "length" "4,8")]) 2042 2043(define_insn_and_split "*subf<mode>3_dot2" 2044 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2045 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r") 2046 (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2047 (const_int 0))) 2048 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2049 (minus:GPR (match_dup 2) 2050 (match_dup 1)))] 2051 "<MODE>mode == Pmode" 2052 "@ 2053 subf. %0,%1,%2 2054 #" 2055 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2056 [(set (match_dup 0) 2057 (minus:GPR (match_dup 2) 2058 (match_dup 1))) 2059 (set (match_dup 3) 2060 (compare:CC (match_dup 0) 2061 (const_int 0)))] 2062 "" 2063 [(set_attr "type" "add") 2064 (set_attr "dot" "yes") 2065 (set_attr "length" "4,8")]) 2066 2067(define_insn "subf<mode>3_imm" 2068 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2069 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I") 2070 (match_operand:GPR 1 "gpc_reg_operand" "r"))) 2071 (clobber (reg:GPR CA_REGNO))] 2072 "" 2073 "subfic %0,%1,%2" 2074 [(set_attr "type" "add")]) 2075 2076(define_insn_and_split "subf<mode>3_carry_dot2" 2077 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2078 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r") 2079 (match_operand:P 1 "gpc_reg_operand" "r,r")) 2080 (const_int 0))) 2081 (set (match_operand:P 0 "gpc_reg_operand" "=r,r") 2082 (minus:P (match_dup 2) 2083 (match_dup 1))) 2084 (set (reg:P CA_REGNO) 2085 (leu:P (match_dup 1) 2086 (match_dup 2)))] 2087 "<MODE>mode == Pmode" 2088 "@ 2089 subfc. %0,%1,%2 2090 #" 2091 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2092 [(parallel [(set (match_dup 0) 2093 (minus:P (match_dup 2) 2094 (match_dup 1))) 2095 (set (reg:P CA_REGNO) 2096 (leu:P (match_dup 1) 2097 (match_dup 2)))]) 2098 (set (match_dup 3) 2099 (compare:CC (match_dup 0) 2100 (const_int 0)))] 2101 "" 2102 [(set_attr "type" "add") 2103 (set_attr "dot" "yes") 2104 (set_attr "length" "4,8")]) 2105 2106(define_insn "subf<mode>3_carry" 2107 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2108 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI") 2109 (match_operand:P 1 "gpc_reg_operand" "r"))) 2110 (set (reg:P CA_REGNO) 2111 (leu:P (match_dup 1) 2112 (match_dup 2)))] 2113 "" 2114 "subf%I2c %0,%1,%2" 2115 [(set_attr "type" "add")]) 2116 2117(define_insn "*subf<mode>3_imm_carry_0" 2118 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2119 (neg:P (match_operand:P 1 "gpc_reg_operand" "r"))) 2120 (set (reg:P CA_REGNO) 2121 (eq:P (match_dup 1) 2122 (const_int 0)))] 2123 "" 2124 "subfic %0,%1,0" 2125 [(set_attr "type" "add")]) 2126 2127(define_insn "*subf<mode>3_imm_carry_m1" 2128 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2129 (not:P (match_operand:P 1 "gpc_reg_operand" "r"))) 2130 (set (reg:P CA_REGNO) 2131 (const_int 1))] 2132 "" 2133 "subfic %0,%1,-1" 2134 [(set_attr "type" "add")]) 2135 2136 2137(define_expand "subf<mode>3_carry_in" 2138 [(parallel [ 2139 (set (match_operand:GPR 0 "gpc_reg_operand") 2140 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand")) 2141 (reg:GPR CA_REGNO)) 2142 (match_operand:GPR 2 "adde_operand"))) 2143 (clobber (reg:GPR CA_REGNO))])] 2144 "" 2145{ 2146 if (operands[2] == const0_rtx) 2147 { 2148 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1])); 2149 DONE; 2150 } 2151 if (operands[2] == constm1_rtx) 2152 { 2153 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1])); 2154 DONE; 2155 } 2156}) 2157 2158(define_insn "*subf<mode>3_carry_in_internal" 2159 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2160 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 2161 (reg:GPR CA_REGNO)) 2162 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 2163 (clobber (reg:GPR CA_REGNO))] 2164 "" 2165 "subfe %0,%1,%2" 2166 [(set_attr "type" "add")]) 2167 2168(define_insn "subf<mode>3_carry_in_0" 2169 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2170 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 2171 (reg:GPR CA_REGNO))) 2172 (clobber (reg:GPR CA_REGNO))] 2173 "" 2174 "subfze %0,%1" 2175 [(set_attr "type" "add")]) 2176 2177(define_insn "subf<mode>3_carry_in_m1" 2178 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2179 (plus:GPR (minus:GPR (reg:GPR CA_REGNO) 2180 (match_operand:GPR 1 "gpc_reg_operand" "r")) 2181 (const_int -2))) 2182 (clobber (reg:GPR CA_REGNO))] 2183 "" 2184 "subfme %0,%1" 2185 [(set_attr "type" "add")]) 2186 2187(define_insn "subf<mode>3_carry_in_xx" 2188 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2189 (plus:GPR (reg:GPR CA_REGNO) 2190 (const_int -1))) 2191 (clobber (reg:GPR CA_REGNO))] 2192 "" 2193 "subfe %0,%0,%0" 2194 [(set_attr "type" "add")]) 2195 2196 2197(define_insn "neg<mode>2" 2198 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2199 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2200 "" 2201 "neg %0,%1" 2202 [(set_attr "type" "add")]) 2203 2204(define_insn_and_split "*neg<mode>2_dot" 2205 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2206 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2207 (const_int 0))) 2208 (clobber (match_scratch:GPR 0 "=r,r"))] 2209 "<MODE>mode == Pmode" 2210 "@ 2211 neg. %0,%1 2212 #" 2213 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2214 [(set (match_dup 0) 2215 (neg:GPR (match_dup 1))) 2216 (set (match_dup 2) 2217 (compare:CC (match_dup 0) 2218 (const_int 0)))] 2219 "" 2220 [(set_attr "type" "add") 2221 (set_attr "dot" "yes") 2222 (set_attr "length" "4,8")]) 2223 2224(define_insn_and_split "*neg<mode>2_dot2" 2225 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2226 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2227 (const_int 0))) 2228 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2229 (neg:GPR (match_dup 1)))] 2230 "<MODE>mode == Pmode" 2231 "@ 2232 neg. %0,%1 2233 #" 2234 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2235 [(set (match_dup 0) 2236 (neg:GPR (match_dup 1))) 2237 (set (match_dup 2) 2238 (compare:CC (match_dup 0) 2239 (const_int 0)))] 2240 "" 2241 [(set_attr "type" "add") 2242 (set_attr "dot" "yes") 2243 (set_attr "length" "4,8")]) 2244 2245 2246(define_insn "clz<mode>2" 2247 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2248 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2249 "" 2250 "cntlz<wd> %0,%1" 2251 [(set_attr "type" "cntlz")]) 2252 2253(define_expand "ctz<mode>2" 2254 [(set (match_operand:GPR 0 "gpc_reg_operand") 2255 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2256 "" 2257{ 2258 if (TARGET_CTZ) 2259 { 2260 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1])); 2261 DONE; 2262 } 2263 2264 rtx tmp1 = gen_reg_rtx (<MODE>mode); 2265 rtx tmp2 = gen_reg_rtx (<MODE>mode); 2266 rtx tmp3 = gen_reg_rtx (<MODE>mode); 2267 2268 if (TARGET_POPCNTD) 2269 { 2270 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx)); 2271 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1])); 2272 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2)); 2273 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3)); 2274 } 2275 else 2276 { 2277 emit_insn (gen_neg<mode>2 (tmp1, operands[1])); 2278 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1)); 2279 emit_insn (gen_clz<mode>2 (tmp3, tmp2)); 2280 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3)); 2281 } 2282 2283 DONE; 2284}) 2285 2286(define_insn "ctz<mode>2_hw" 2287 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2288 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2289 "TARGET_CTZ" 2290 "cnttz<wd> %0,%1" 2291 [(set_attr "type" "cntlz")]) 2292 2293(define_expand "ffs<mode>2" 2294 [(set (match_operand:GPR 0 "gpc_reg_operand") 2295 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2296 "" 2297{ 2298 rtx tmp1 = gen_reg_rtx (<MODE>mode); 2299 rtx tmp2 = gen_reg_rtx (<MODE>mode); 2300 rtx tmp3 = gen_reg_rtx (<MODE>mode); 2301 emit_insn (gen_neg<mode>2 (tmp1, operands[1])); 2302 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1)); 2303 emit_insn (gen_clz<mode>2 (tmp3, tmp2)); 2304 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3)); 2305 DONE; 2306}) 2307 2308 2309(define_expand "popcount<mode>2" 2310 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 2311 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] 2312 "TARGET_POPCNTB || TARGET_POPCNTD" 2313{ 2314 rs6000_emit_popcount (operands[0], operands[1]); 2315 DONE; 2316}) 2317 2318(define_insn "popcntb<mode>2" 2319 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2320 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] 2321 UNSPEC_POPCNTB))] 2322 "TARGET_POPCNTB" 2323 "popcntb %0,%1" 2324 [(set_attr "type" "popcnt")]) 2325 2326(define_insn "popcntd<mode>2" 2327 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2328 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2329 "TARGET_POPCNTD" 2330 "popcnt<wd> %0,%1" 2331 [(set_attr "type" "popcnt")]) 2332 2333 2334(define_expand "parity<mode>2" 2335 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 2336 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))] 2337 "TARGET_POPCNTB" 2338{ 2339 rs6000_emit_parity (operands[0], operands[1]); 2340 DONE; 2341}) 2342 2343(define_insn "parity<mode>2_cmpb" 2344 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2345 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))] 2346 "TARGET_CMPB && TARGET_POPCNTB" 2347 "prty<wd> %0,%1" 2348 [(set_attr "type" "popcnt")]) 2349 2350(define_insn "cmpb<mode>3" 2351 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2352 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r") 2353 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))] 2354 "TARGET_CMPB" 2355 "cmpb %0,%1,%2" 2356 [(set_attr "type" "cmp")]) 2357 2358;; Since the hardware zeros the upper part of the register, save generating the 2359;; AND immediate if we are converting to unsigned 2360(define_insn "*bswap<mode>2_extenddi" 2361 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2362 (zero_extend:DI 2363 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))] 2364 "TARGET_POWERPC64" 2365 "l<wd>brx %0,%y1" 2366 [(set_attr "length" "4") 2367 (set_attr "type" "load")]) 2368 2369(define_insn "*bswaphi2_extendsi" 2370 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2371 (zero_extend:SI 2372 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))] 2373 "" 2374 "lhbrx %0,%y1" 2375 [(set_attr "length" "4") 2376 (set_attr "type" "load")]) 2377 2378;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents 2379;; the register allocator from converting a gpr<-gpr swap into a store and then 2380;; load with byte swap, which can be slower than doing it in the registers. It 2381;; also prevents certain failures with the RELOAD register allocator. 2382 2383(define_expand "bswap<mode>2" 2384 [(use (match_operand:HSI 0 "reg_or_mem_operand")) 2385 (use (match_operand:HSI 1 "reg_or_mem_operand"))] 2386 "" 2387{ 2388 rtx dest = operands[0]; 2389 rtx src = operands[1]; 2390 2391 if (!REG_P (dest) && !REG_P (src)) 2392 src = force_reg (<MODE>mode, src); 2393 2394 if (MEM_P (src)) 2395 emit_insn (gen_bswap<mode>2_load (dest, src)); 2396 else if (MEM_P (dest)) 2397 emit_insn (gen_bswap<mode>2_store (dest, src)); 2398 else 2399 emit_insn (gen_bswap<mode>2_reg (dest, src)); 2400 DONE; 2401}) 2402 2403(define_insn "bswap<mode>2_load" 2404 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r") 2405 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))] 2406 "" 2407 "l<wd>brx %0,%y1" 2408 [(set_attr "type" "load")]) 2409 2410(define_insn "bswap<mode>2_store" 2411 [(set (match_operand:HSI 0 "memory_operand" "=Z") 2412 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))] 2413 "" 2414 "st<wd>brx %1,%y0" 2415 [(set_attr "type" "store")]) 2416 2417(define_insn_and_split "bswaphi2_reg" 2418 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r") 2419 (bswap:HI 2420 (match_operand:HI 1 "gpc_reg_operand" "r"))) 2421 (clobber (match_scratch:SI 2 "=&r"))] 2422 "" 2423 "#" 2424 "reload_completed" 2425 [(set (match_dup 3) 2426 (and:SI (lshiftrt:SI (match_dup 4) 2427 (const_int 8)) 2428 (const_int 255))) 2429 (set (match_dup 2) 2430 (and:SI (ashift:SI (match_dup 4) 2431 (const_int 8)) 2432 (const_int 65280))) ;; 0xff00 2433 (set (match_dup 3) 2434 (ior:SI (match_dup 3) 2435 (match_dup 2)))] 2436{ 2437 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0); 2438 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 2439} 2440 [(set_attr "length" "12") 2441 (set_attr "type" "*")]) 2442 2443;; We are always BITS_BIG_ENDIAN, so the bit positions below in 2444;; zero_extract insns do not change for -mlittle. 2445(define_insn_and_split "bswapsi2_reg" 2446 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r") 2447 (bswap:SI 2448 (match_operand:SI 1 "gpc_reg_operand" "r")))] 2449 "" 2450 "#" 2451 "reload_completed" 2452 [(set (match_dup 0) ; DABC 2453 (rotate:SI (match_dup 1) 2454 (const_int 24))) 2455 (set (match_dup 0) ; DCBC 2456 (ior:SI (and:SI (ashift:SI (match_dup 1) 2457 (const_int 8)) 2458 (const_int 16711680)) 2459 (and:SI (match_dup 0) 2460 (const_int -16711681)))) 2461 (set (match_dup 0) ; DCBA 2462 (ior:SI (and:SI (lshiftrt:SI (match_dup 1) 2463 (const_int 24)) 2464 (const_int 255)) 2465 (and:SI (match_dup 0) 2466 (const_int -256))))] 2467 "") 2468 2469;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like 2470;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more 2471;; complex code. 2472 2473(define_expand "bswapdi2" 2474 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "") 2475 (bswap:DI 2476 (match_operand:DI 1 "reg_or_mem_operand" ""))) 2477 (clobber (match_scratch:DI 2 "")) 2478 (clobber (match_scratch:DI 3 ""))])] 2479 "" 2480{ 2481 rtx dest = operands[0]; 2482 rtx src = operands[1]; 2483 2484 if (!REG_P (dest) && !REG_P (src)) 2485 operands[1] = src = force_reg (DImode, src); 2486 2487 if (TARGET_POWERPC64 && TARGET_LDBRX) 2488 { 2489 if (MEM_P (src)) 2490 emit_insn (gen_bswapdi2_load (dest, src)); 2491 else if (MEM_P (dest)) 2492 emit_insn (gen_bswapdi2_store (dest, src)); 2493 else 2494 emit_insn (gen_bswapdi2_reg (dest, src)); 2495 DONE; 2496 } 2497 2498 if (!TARGET_POWERPC64) 2499 { 2500 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode 2501 that uses 64-bit registers needs the same scratch registers as 64-bit 2502 mode. */ 2503 emit_insn (gen_bswapdi2_32bit (dest, src)); 2504 DONE; 2505 } 2506}) 2507 2508;; Power7/cell has ldbrx/stdbrx, so use it directly 2509(define_insn "bswapdi2_load" 2510 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2511 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))] 2512 "TARGET_POWERPC64 && TARGET_LDBRX" 2513 "ldbrx %0,%y1" 2514 [(set_attr "type" "load")]) 2515 2516(define_insn "bswapdi2_store" 2517 [(set (match_operand:DI 0 "memory_operand" "=Z") 2518 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] 2519 "TARGET_POWERPC64 && TARGET_LDBRX" 2520 "stdbrx %1,%y0" 2521 [(set_attr "type" "store")]) 2522 2523(define_insn "bswapdi2_reg" 2524 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") 2525 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) 2526 (clobber (match_scratch:DI 2 "=&r")) 2527 (clobber (match_scratch:DI 3 "=&r"))] 2528 "TARGET_POWERPC64 && TARGET_LDBRX" 2529 "#" 2530 [(set_attr "length" "36")]) 2531 2532;; Non-power7/cell, fall back to use lwbrx/stwbrx 2533(define_insn "*bswapdi2_64bit" 2534 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r") 2535 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) 2536 (clobber (match_scratch:DI 2 "=&b,&b,&r")) 2537 (clobber (match_scratch:DI 3 "=&r,&r,&r"))] 2538 "TARGET_POWERPC64 && !TARGET_LDBRX 2539 && (REG_P (operands[0]) || REG_P (operands[1])) 2540 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) 2541 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))" 2542 "#" 2543 [(set_attr "length" "16,12,36")]) 2544 2545(define_split 2546 [(set (match_operand:DI 0 "gpc_reg_operand" "") 2547 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" ""))) 2548 (clobber (match_operand:DI 2 "gpc_reg_operand" "")) 2549 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] 2550 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" 2551 [(const_int 0)] 2552 " 2553{ 2554 rtx dest = operands[0]; 2555 rtx src = operands[1]; 2556 rtx op2 = operands[2]; 2557 rtx op3 = operands[3]; 2558 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, 2559 BYTES_BIG_ENDIAN ? 4 : 0); 2560 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode, 2561 BYTES_BIG_ENDIAN ? 4 : 0); 2562 rtx addr1; 2563 rtx addr2; 2564 rtx word1; 2565 rtx word2; 2566 2567 addr1 = XEXP (src, 0); 2568 if (GET_CODE (addr1) == PLUS) 2569 { 2570 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2571 if (TARGET_AVOID_XFORM) 2572 { 2573 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2574 addr2 = op2; 2575 } 2576 else 2577 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); 2578 } 2579 else if (TARGET_AVOID_XFORM) 2580 { 2581 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2582 addr2 = op2; 2583 } 2584 else 2585 { 2586 emit_move_insn (op2, GEN_INT (4)); 2587 addr2 = gen_rtx_PLUS (Pmode, op2, addr1); 2588 } 2589 2590 word1 = change_address (src, SImode, addr1); 2591 word2 = change_address (src, SImode, addr2); 2592 2593 if (BYTES_BIG_ENDIAN) 2594 { 2595 emit_insn (gen_bswapsi2 (op3_32, word2)); 2596 emit_insn (gen_bswapsi2 (dest_32, word1)); 2597 } 2598 else 2599 { 2600 emit_insn (gen_bswapsi2 (op3_32, word1)); 2601 emit_insn (gen_bswapsi2 (dest_32, word2)); 2602 } 2603 2604 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32))); 2605 emit_insn (gen_iordi3 (dest, dest, op3)); 2606 DONE; 2607}") 2608 2609(define_split 2610 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "") 2611 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) 2612 (clobber (match_operand:DI 2 "gpc_reg_operand" "")) 2613 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] 2614 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" 2615 [(const_int 0)] 2616 " 2617{ 2618 rtx dest = operands[0]; 2619 rtx src = operands[1]; 2620 rtx op2 = operands[2]; 2621 rtx op3 = operands[3]; 2622 rtx src_si = simplify_gen_subreg (SImode, src, DImode, 2623 BYTES_BIG_ENDIAN ? 4 : 0); 2624 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 2625 BYTES_BIG_ENDIAN ? 4 : 0); 2626 rtx addr1; 2627 rtx addr2; 2628 rtx word1; 2629 rtx word2; 2630 2631 addr1 = XEXP (dest, 0); 2632 if (GET_CODE (addr1) == PLUS) 2633 { 2634 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2635 if (TARGET_AVOID_XFORM) 2636 { 2637 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2638 addr2 = op2; 2639 } 2640 else 2641 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); 2642 } 2643 else if (TARGET_AVOID_XFORM) 2644 { 2645 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2646 addr2 = op2; 2647 } 2648 else 2649 { 2650 emit_move_insn (op2, GEN_INT (4)); 2651 addr2 = gen_rtx_PLUS (Pmode, op2, addr1); 2652 } 2653 2654 word1 = change_address (dest, SImode, addr1); 2655 word2 = change_address (dest, SImode, addr2); 2656 2657 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32))); 2658 2659 if (BYTES_BIG_ENDIAN) 2660 { 2661 emit_insn (gen_bswapsi2 (word1, src_si)); 2662 emit_insn (gen_bswapsi2 (word2, op3_si)); 2663 } 2664 else 2665 { 2666 emit_insn (gen_bswapsi2 (word2, src_si)); 2667 emit_insn (gen_bswapsi2 (word1, op3_si)); 2668 } 2669 DONE; 2670}") 2671 2672(define_split 2673 [(set (match_operand:DI 0 "gpc_reg_operand" "") 2674 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) 2675 (clobber (match_operand:DI 2 "gpc_reg_operand" "")) 2676 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))] 2677 "TARGET_POWERPC64 && reload_completed" 2678 [(const_int 0)] 2679 " 2680{ 2681 rtx dest = operands[0]; 2682 rtx src = operands[1]; 2683 rtx op2 = operands[2]; 2684 rtx op3 = operands[3]; 2685 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0; 2686 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off); 2687 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off); 2688 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off); 2689 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off); 2690 2691 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32))); 2692 emit_insn (gen_bswapsi2 (dest_si, src_si)); 2693 emit_insn (gen_bswapsi2 (op3_si, op2_si)); 2694 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32))); 2695 emit_insn (gen_iordi3 (dest, dest, op3)); 2696 DONE; 2697}") 2698 2699(define_insn "bswapdi2_32bit" 2700 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r") 2701 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) 2702 (clobber (match_scratch:SI 2 "=&b,&b,X"))] 2703 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))" 2704 "#" 2705 [(set_attr "length" "16,12,36")]) 2706 2707(define_split 2708 [(set (match_operand:DI 0 "gpc_reg_operand" "") 2709 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" ""))) 2710 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))] 2711 "!TARGET_POWERPC64 && reload_completed" 2712 [(const_int 0)] 2713 " 2714{ 2715 rtx dest = operands[0]; 2716 rtx src = operands[1]; 2717 rtx op2 = operands[2]; 2718 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); 2719 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); 2720 rtx addr1; 2721 rtx addr2; 2722 rtx word1; 2723 rtx word2; 2724 2725 addr1 = XEXP (src, 0); 2726 if (GET_CODE (addr1) == PLUS) 2727 { 2728 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2729 if (TARGET_AVOID_XFORM 2730 || REGNO (XEXP (addr1, 1)) == REGNO (dest2)) 2731 { 2732 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2733 addr2 = op2; 2734 } 2735 else 2736 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); 2737 } 2738 else if (TARGET_AVOID_XFORM 2739 || REGNO (addr1) == REGNO (dest2)) 2740 { 2741 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2742 addr2 = op2; 2743 } 2744 else 2745 { 2746 emit_move_insn (op2, GEN_INT (4)); 2747 addr2 = gen_rtx_PLUS (SImode, op2, addr1); 2748 } 2749 2750 word1 = change_address (src, SImode, addr1); 2751 word2 = change_address (src, SImode, addr2); 2752 2753 emit_insn (gen_bswapsi2 (dest2, word1)); 2754 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed, 2755 thus allowing us to omit an early clobber on the output. */ 2756 emit_insn (gen_bswapsi2 (dest1, word2)); 2757 DONE; 2758}") 2759 2760(define_split 2761 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "") 2762 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) 2763 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))] 2764 "!TARGET_POWERPC64 && reload_completed" 2765 [(const_int 0)] 2766 " 2767{ 2768 rtx dest = operands[0]; 2769 rtx src = operands[1]; 2770 rtx op2 = operands[2]; 2771 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); 2772 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); 2773 rtx addr1; 2774 rtx addr2; 2775 rtx word1; 2776 rtx word2; 2777 2778 addr1 = XEXP (dest, 0); 2779 if (GET_CODE (addr1) == PLUS) 2780 { 2781 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2782 if (TARGET_AVOID_XFORM) 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 { 2792 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2793 addr2 = op2; 2794 } 2795 else 2796 { 2797 emit_move_insn (op2, GEN_INT (4)); 2798 addr2 = gen_rtx_PLUS (SImode, op2, addr1); 2799 } 2800 2801 word1 = change_address (dest, SImode, addr1); 2802 word2 = change_address (dest, SImode, addr2); 2803 2804 emit_insn (gen_bswapsi2 (word2, src1)); 2805 emit_insn (gen_bswapsi2 (word1, src2)); 2806 DONE; 2807}") 2808 2809(define_split 2810 [(set (match_operand:DI 0 "gpc_reg_operand" "") 2811 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" ""))) 2812 (clobber (match_operand:SI 2 "" ""))] 2813 "!TARGET_POWERPC64 && reload_completed" 2814 [(const_int 0)] 2815 " 2816{ 2817 rtx dest = operands[0]; 2818 rtx src = operands[1]; 2819 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); 2820 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); 2821 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); 2822 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); 2823 2824 emit_insn (gen_bswapsi2 (dest1, src2)); 2825 emit_insn (gen_bswapsi2 (dest2, src1)); 2826 DONE; 2827}") 2828 2829 2830(define_insn "mul<mode>3" 2831 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2832 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 2833 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))] 2834 "" 2835 "@ 2836 mull<wd> %0,%1,%2 2837 mulli %0,%1,%2" 2838 [(set_attr "type" "mul") 2839 (set (attr "size") 2840 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "") 2841 (const_string "8") 2842 (match_operand:GPR 2 "short_cint_operand" "") 2843 (const_string "16")] 2844 (const_string "<bits>")))]) 2845 2846(define_insn_and_split "*mul<mode>3_dot" 2847 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2848 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 2849 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 2850 (const_int 0))) 2851 (clobber (match_scratch:GPR 0 "=r,r"))] 2852 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 2853 "@ 2854 mull<wd>. %0,%1,%2 2855 #" 2856 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2857 [(set (match_dup 0) 2858 (mult:GPR (match_dup 1) 2859 (match_dup 2))) 2860 (set (match_dup 3) 2861 (compare:CC (match_dup 0) 2862 (const_int 0)))] 2863 "" 2864 [(set_attr "type" "mul") 2865 (set_attr "size" "<bits>") 2866 (set_attr "dot" "yes") 2867 (set_attr "length" "4,8")]) 2868 2869(define_insn_and_split "*mul<mode>3_dot2" 2870 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2871 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 2872 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 2873 (const_int 0))) 2874 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2875 (mult:GPR (match_dup 1) 2876 (match_dup 2)))] 2877 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 2878 "@ 2879 mull<wd>. %0,%1,%2 2880 #" 2881 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2882 [(set (match_dup 0) 2883 (mult:GPR (match_dup 1) 2884 (match_dup 2))) 2885 (set (match_dup 3) 2886 (compare:CC (match_dup 0) 2887 (const_int 0)))] 2888 "" 2889 [(set_attr "type" "mul") 2890 (set_attr "size" "<bits>") 2891 (set_attr "dot" "yes") 2892 (set_attr "length" "4,8")]) 2893 2894 2895(define_expand "<su>mul<mode>3_highpart" 2896 [(set (match_operand:GPR 0 "gpc_reg_operand") 2897 (subreg:GPR 2898 (mult:<DMODE> (any_extend:<DMODE> 2899 (match_operand:GPR 1 "gpc_reg_operand")) 2900 (any_extend:<DMODE> 2901 (match_operand:GPR 2 "gpc_reg_operand"))) 2902 0))] 2903 "" 2904{ 2905 if (<MODE>mode == SImode && TARGET_POWERPC64) 2906 { 2907 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1], 2908 operands[2])); 2909 DONE; 2910 } 2911 2912 if (!WORDS_BIG_ENDIAN) 2913 { 2914 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1], 2915 operands[2])); 2916 DONE; 2917 } 2918}) 2919 2920(define_insn "*<su>mul<mode>3_highpart" 2921 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2922 (subreg:GPR 2923 (mult:<DMODE> (any_extend:<DMODE> 2924 (match_operand:GPR 1 "gpc_reg_operand" "r")) 2925 (any_extend:<DMODE> 2926 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 2927 0))] 2928 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)" 2929 "mulh<wd><u> %0,%1,%2" 2930 [(set_attr "type" "mul") 2931 (set_attr "size" "<bits>")]) 2932 2933(define_insn "<su>mulsi3_highpart_le" 2934 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2935 (subreg:SI 2936 (mult:DI (any_extend:DI 2937 (match_operand:SI 1 "gpc_reg_operand" "r")) 2938 (any_extend:DI 2939 (match_operand:SI 2 "gpc_reg_operand" "r"))) 2940 4))] 2941 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64" 2942 "mulhw<u> %0,%1,%2" 2943 [(set_attr "type" "mul")]) 2944 2945(define_insn "<su>muldi3_highpart_le" 2946 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2947 (subreg:DI 2948 (mult:TI (any_extend:TI 2949 (match_operand:DI 1 "gpc_reg_operand" "r")) 2950 (any_extend:TI 2951 (match_operand:DI 2 "gpc_reg_operand" "r"))) 2952 8))] 2953 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64" 2954 "mulhd<u> %0,%1,%2" 2955 [(set_attr "type" "mul") 2956 (set_attr "size" "64")]) 2957 2958(define_insn "<su>mulsi3_highpart_64" 2959 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2960 (truncate:SI 2961 (lshiftrt:DI 2962 (mult:DI (any_extend:DI 2963 (match_operand:SI 1 "gpc_reg_operand" "r")) 2964 (any_extend:DI 2965 (match_operand:SI 2 "gpc_reg_operand" "r"))) 2966 (const_int 32))))] 2967 "TARGET_POWERPC64" 2968 "mulhw<u> %0,%1,%2" 2969 [(set_attr "type" "mul")]) 2970 2971(define_expand "<u>mul<mode><dmode>3" 2972 [(set (match_operand:<DMODE> 0 "gpc_reg_operand") 2973 (mult:<DMODE> (any_extend:<DMODE> 2974 (match_operand:GPR 1 "gpc_reg_operand")) 2975 (any_extend:<DMODE> 2976 (match_operand:GPR 2 "gpc_reg_operand"))))] 2977 "!(<MODE>mode == SImode && TARGET_POWERPC64)" 2978{ 2979 rtx l = gen_reg_rtx (<MODE>mode); 2980 rtx h = gen_reg_rtx (<MODE>mode); 2981 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2])); 2982 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2])); 2983 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l); 2984 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h); 2985 DONE; 2986}) 2987 2988(define_insn "*maddld4" 2989 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2990 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r") 2991 (match_operand:DI 2 "gpc_reg_operand" "r")) 2992 (match_operand:DI 3 "gpc_reg_operand" "r")))] 2993 "TARGET_MADDLD" 2994 "maddld %0,%1,%2,%3" 2995 [(set_attr "type" "mul")]) 2996 2997(define_insn "udiv<mode>3" 2998 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2999 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3000 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3001 "" 3002 "div<wd>u %0,%1,%2" 3003 [(set_attr "type" "div") 3004 (set_attr "size" "<bits>")]) 3005 3006 3007;; For powers of two we can do sra[wd]i/addze for divide and then adjust for 3008;; modulus. If it isn't a power of two, force operands into register and do 3009;; a normal divide. 3010(define_expand "div<mode>3" 3011 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 3012 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") 3013 (match_operand:GPR 2 "reg_or_cint_operand" "")))] 3014 "" 3015{ 3016 if (CONST_INT_P (operands[2]) 3017 && INTVAL (operands[2]) > 0 3018 && exact_log2 (INTVAL (operands[2])) >= 0) 3019 { 3020 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2])); 3021 DONE; 3022 } 3023 3024 operands[2] = force_reg (<MODE>mode, operands[2]); 3025}) 3026 3027(define_insn "*div<mode>3" 3028 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3029 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3030 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3031 "" 3032 "div<wd> %0,%1,%2" 3033 [(set_attr "type" "div") 3034 (set_attr "size" "<bits>")]) 3035 3036(define_insn "div<mode>3_sra" 3037 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3038 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3039 (match_operand:GPR 2 "exact_log2_cint_operand" "N"))) 3040 (clobber (reg:GPR CA_REGNO))] 3041 "" 3042 "sra<wd>i %0,%1,%p2\;addze %0,%0" 3043 [(set_attr "type" "two") 3044 (set_attr "length" "8")]) 3045 3046(define_insn_and_split "*div<mode>3_sra_dot" 3047 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3048 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3049 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")) 3050 (const_int 0))) 3051 (clobber (match_scratch:GPR 0 "=r,r")) 3052 (clobber (reg:GPR CA_REGNO))] 3053 "<MODE>mode == Pmode" 3054 "@ 3055 sra<wd>i %0,%1,%p2\;addze. %0,%0 3056 #" 3057 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3058 [(parallel [(set (match_dup 0) 3059 (div:GPR (match_dup 1) 3060 (match_dup 2))) 3061 (clobber (reg:GPR CA_REGNO))]) 3062 (set (match_dup 3) 3063 (compare:CC (match_dup 0) 3064 (const_int 0)))] 3065 "" 3066 [(set_attr "type" "two") 3067 (set_attr "length" "8,12") 3068 (set_attr "cell_micro" "not")]) 3069 3070(define_insn_and_split "*div<mode>3_sra_dot2" 3071 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3072 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3073 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")) 3074 (const_int 0))) 3075 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3076 (div:GPR (match_dup 1) 3077 (match_dup 2))) 3078 (clobber (reg:GPR CA_REGNO))] 3079 "<MODE>mode == Pmode" 3080 "@ 3081 sra<wd>i %0,%1,%p2\;addze. %0,%0 3082 #" 3083 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3084 [(parallel [(set (match_dup 0) 3085 (div:GPR (match_dup 1) 3086 (match_dup 2))) 3087 (clobber (reg:GPR CA_REGNO))]) 3088 (set (match_dup 3) 3089 (compare:CC (match_dup 0) 3090 (const_int 0)))] 3091 "" 3092 [(set_attr "type" "two") 3093 (set_attr "length" "8,12") 3094 (set_attr "cell_micro" "not")]) 3095 3096(define_expand "mod<mode>3" 3097 [(set (match_operand:GPR 0 "gpc_reg_operand") 3098 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand") 3099 (match_operand:GPR 2 "reg_or_cint_operand")))] 3100 "" 3101{ 3102 int i; 3103 rtx temp1; 3104 rtx temp2; 3105 3106 if (GET_CODE (operands[2]) != CONST_INT 3107 || INTVAL (operands[2]) <= 0 3108 || (i = exact_log2 (INTVAL (operands[2]))) < 0) 3109 { 3110 if (!TARGET_MODULO) 3111 FAIL; 3112 3113 operands[2] = force_reg (<MODE>mode, operands[2]); 3114 } 3115 else 3116 { 3117 temp1 = gen_reg_rtx (<MODE>mode); 3118 temp2 = gen_reg_rtx (<MODE>mode); 3119 3120 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2])); 3121 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i))); 3122 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2)); 3123 DONE; 3124 } 3125}) 3126 3127;; In order to enable using a peephole2 for combining div/mod to eliminate the 3128;; mod, prefer putting the result of mod into a different register 3129(define_insn "*mod<mode>3" 3130 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 3131 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3132 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3133 "TARGET_MODULO" 3134 "mods<wd> %0,%1,%2" 3135 [(set_attr "type" "div") 3136 (set_attr "size" "<bits>")]) 3137 3138 3139(define_insn "umod<mode>3" 3140 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 3141 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3142 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3143 "TARGET_MODULO" 3144 "modu<wd> %0,%1,%2" 3145 [(set_attr "type" "div") 3146 (set_attr "size" "<bits>")]) 3147 3148;; On machines with modulo support, do a combined div/mod the old fashioned 3149;; method, since the multiply/subtract is faster than doing the mod instruction 3150;; after a divide. 3151 3152(define_peephole2 3153 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 3154 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "") 3155 (match_operand:GPR 2 "gpc_reg_operand" ""))) 3156 (set (match_operand:GPR 3 "gpc_reg_operand" "") 3157 (mod:GPR (match_dup 1) 3158 (match_dup 2)))] 3159 "TARGET_MODULO 3160 && ! reg_mentioned_p (operands[0], operands[1]) 3161 && ! reg_mentioned_p (operands[0], operands[2]) 3162 && ! reg_mentioned_p (operands[3], operands[1]) 3163 && ! reg_mentioned_p (operands[3], operands[2])" 3164 [(set (match_dup 0) 3165 (div:GPR (match_dup 1) 3166 (match_dup 2))) 3167 (set (match_dup 3) 3168 (mult:GPR (match_dup 0) 3169 (match_dup 2))) 3170 (set (match_dup 3) 3171 (minus:GPR (match_dup 1) 3172 (match_dup 3)))]) 3173 3174(define_peephole2 3175 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 3176 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "") 3177 (match_operand:GPR 2 "gpc_reg_operand" ""))) 3178 (set (match_operand:GPR 3 "gpc_reg_operand" "") 3179 (umod:GPR (match_dup 1) 3180 (match_dup 2)))] 3181 "TARGET_MODULO 3182 && ! reg_mentioned_p (operands[0], operands[1]) 3183 && ! reg_mentioned_p (operands[0], operands[2]) 3184 && ! reg_mentioned_p (operands[3], operands[1]) 3185 && ! reg_mentioned_p (operands[3], operands[2])" 3186 [(set (match_dup 0) 3187 (udiv:GPR (match_dup 1) 3188 (match_dup 2))) 3189 (set (match_dup 3) 3190 (mult:GPR (match_dup 0) 3191 (match_dup 2))) 3192 (set (match_dup 3) 3193 (minus:GPR (match_dup 1) 3194 (match_dup 3)))]) 3195 3196 3197;; Logical instructions 3198;; The logical instructions are mostly combined by using match_operator, 3199;; but the plain AND insns are somewhat different because there is no 3200;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all 3201;; those rotate-and-mask operations. Thus, the AND insns come first. 3202 3203(define_expand "and<mode>3" 3204 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 3205 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "") 3206 (match_operand:SDI 2 "reg_or_cint_operand" "")))] 3207 "" 3208{ 3209 if (<MODE>mode == DImode && !TARGET_POWERPC64) 3210 { 3211 rs6000_split_logical (operands, AND, false, false, false); 3212 DONE; 3213 } 3214 3215 if (CONST_INT_P (operands[2])) 3216 { 3217 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode)) 3218 { 3219 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2])); 3220 DONE; 3221 } 3222 3223 if (logical_const_operand (operands[2], <MODE>mode) 3224 && rs6000_gen_cell_microcode) 3225 { 3226 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2])); 3227 DONE; 3228 } 3229 3230 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode)) 3231 { 3232 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0); 3233 DONE; 3234 } 3235 3236 operands[2] = force_reg (<MODE>mode, operands[2]); 3237 } 3238}) 3239 3240 3241(define_insn "and<mode>3_imm" 3242 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3243 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3244 (match_operand:GPR 2 "logical_const_operand" "n"))) 3245 (clobber (match_scratch:CC 3 "=x"))] 3246 "rs6000_gen_cell_microcode 3247 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3248 "andi%e2. %0,%1,%u2" 3249 [(set_attr "type" "logical") 3250 (set_attr "dot" "yes")]) 3251 3252(define_insn_and_split "*and<mode>3_imm_dot" 3253 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3254 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3255 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3256 (const_int 0))) 3257 (clobber (match_scratch:GPR 0 "=r,r")) 3258 (clobber (match_scratch:CC 4 "=X,x"))] 3259 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3260 && rs6000_gen_cell_microcode 3261 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3262 "@ 3263 andi%e2. %0,%1,%u2 3264 #" 3265 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3266 [(parallel [(set (match_dup 0) 3267 (and:GPR (match_dup 1) 3268 (match_dup 2))) 3269 (clobber (match_dup 4))]) 3270 (set (match_dup 3) 3271 (compare:CC (match_dup 0) 3272 (const_int 0)))] 3273 "" 3274 [(set_attr "type" "logical") 3275 (set_attr "dot" "yes") 3276 (set_attr "length" "4,8")]) 3277 3278(define_insn_and_split "*and<mode>3_imm_dot2" 3279 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3280 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3281 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3282 (const_int 0))) 3283 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3284 (and:GPR (match_dup 1) 3285 (match_dup 2))) 3286 (clobber (match_scratch:CC 4 "=X,x"))] 3287 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3288 && rs6000_gen_cell_microcode 3289 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3290 "@ 3291 andi%e2. %0,%1,%u2 3292 #" 3293 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3294 [(parallel [(set (match_dup 0) 3295 (and:GPR (match_dup 1) 3296 (match_dup 2))) 3297 (clobber (match_dup 4))]) 3298 (set (match_dup 3) 3299 (compare:CC (match_dup 0) 3300 (const_int 0)))] 3301 "" 3302 [(set_attr "type" "logical") 3303 (set_attr "dot" "yes") 3304 (set_attr "length" "4,8")]) 3305 3306(define_insn_and_split "*and<mode>3_imm_mask_dot" 3307 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3308 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3309 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3310 (const_int 0))) 3311 (clobber (match_scratch:GPR 0 "=r,r"))] 3312 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3313 && rs6000_gen_cell_microcode 3314 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3315 "@ 3316 andi%e2. %0,%1,%u2 3317 #" 3318 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3319 [(set (match_dup 0) 3320 (and:GPR (match_dup 1) 3321 (match_dup 2))) 3322 (set (match_dup 3) 3323 (compare:CC (match_dup 0) 3324 (const_int 0)))] 3325 "" 3326 [(set_attr "type" "logical") 3327 (set_attr "dot" "yes") 3328 (set_attr "length" "4,8")]) 3329 3330(define_insn_and_split "*and<mode>3_imm_mask_dot2" 3331 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3332 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3333 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3334 (const_int 0))) 3335 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3336 (and:GPR (match_dup 1) 3337 (match_dup 2)))] 3338 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3339 && rs6000_gen_cell_microcode 3340 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3341 "@ 3342 andi%e2. %0,%1,%u2 3343 #" 3344 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3345 [(set (match_dup 0) 3346 (and:GPR (match_dup 1) 3347 (match_dup 2))) 3348 (set (match_dup 3) 3349 (compare:CC (match_dup 0) 3350 (const_int 0)))] 3351 "" 3352 [(set_attr "type" "logical") 3353 (set_attr "dot" "yes") 3354 (set_attr "length" "4,8")]) 3355 3356(define_insn "*and<mode>3_imm_dot_shifted" 3357 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 3358 (compare:CC 3359 (and:GPR 3360 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3361 (match_operand:SI 4 "const_int_operand" "n")) 3362 (match_operand:GPR 2 "const_int_operand" "n")) 3363 (const_int 0))) 3364 (clobber (match_scratch:GPR 0 "=r"))] 3365 "logical_const_operand (GEN_INT (UINTVAL (operands[2]) 3366 << INTVAL (operands[4])), 3367 DImode) 3368 && (<MODE>mode == Pmode 3369 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff) 3370 && rs6000_gen_cell_microcode" 3371{ 3372 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4])); 3373 return "andi%e2. %0,%1,%u2"; 3374} 3375 [(set_attr "type" "logical") 3376 (set_attr "dot" "yes")]) 3377 3378 3379(define_insn "and<mode>3_mask" 3380 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3381 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3382 (match_operand:GPR 2 "const_int_operand" "n")))] 3383 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3384{ 3385 return rs6000_insn_for_and_mask (<MODE>mode, operands, false); 3386} 3387 [(set_attr "type" "shift")]) 3388 3389(define_insn_and_split "*and<mode>3_mask_dot" 3390 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3391 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3392 (match_operand:GPR 2 "const_int_operand" "n,n")) 3393 (const_int 0))) 3394 (clobber (match_scratch:GPR 0 "=r,r"))] 3395 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3396 && rs6000_gen_cell_microcode 3397 && !logical_const_operand (operands[2], <MODE>mode) 3398 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3399{ 3400 if (which_alternative == 0) 3401 return rs6000_insn_for_and_mask (<MODE>mode, operands, true); 3402 else 3403 return "#"; 3404} 3405 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3406 [(set (match_dup 0) 3407 (and:GPR (match_dup 1) 3408 (match_dup 2))) 3409 (set (match_dup 3) 3410 (compare:CC (match_dup 0) 3411 (const_int 0)))] 3412 "" 3413 [(set_attr "type" "shift") 3414 (set_attr "dot" "yes") 3415 (set_attr "length" "4,8")]) 3416 3417(define_insn_and_split "*and<mode>3_mask_dot2" 3418 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3419 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3420 (match_operand:GPR 2 "const_int_operand" "n,n")) 3421 (const_int 0))) 3422 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3423 (and:GPR (match_dup 1) 3424 (match_dup 2)))] 3425 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3426 && rs6000_gen_cell_microcode 3427 && !logical_const_operand (operands[2], <MODE>mode) 3428 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3429{ 3430 if (which_alternative == 0) 3431 return rs6000_insn_for_and_mask (<MODE>mode, operands, true); 3432 else 3433 return "#"; 3434} 3435 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3436 [(set (match_dup 0) 3437 (and:GPR (match_dup 1) 3438 (match_dup 2))) 3439 (set (match_dup 3) 3440 (compare:CC (match_dup 0) 3441 (const_int 0)))] 3442 "" 3443 [(set_attr "type" "shift") 3444 (set_attr "dot" "yes") 3445 (set_attr "length" "4,8")]) 3446 3447 3448(define_insn_and_split "*and<mode>3_2insn" 3449 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3450 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3451 (match_operand:GPR 2 "const_int_operand" "n")))] 3452 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3453 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3454 || (logical_const_operand (operands[2], <MODE>mode) 3455 && rs6000_gen_cell_microcode))" 3456 "#" 3457 "&& 1" 3458 [(pc)] 3459{ 3460 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0); 3461 DONE; 3462} 3463 [(set_attr "type" "shift") 3464 (set_attr "length" "8")]) 3465 3466(define_insn_and_split "*and<mode>3_2insn_dot" 3467 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3468 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3469 (match_operand:GPR 2 "const_int_operand" "n,n")) 3470 (const_int 0))) 3471 (clobber (match_scratch:GPR 0 "=r,r"))] 3472 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3473 && rs6000_gen_cell_microcode 3474 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3475 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3476 || (logical_const_operand (operands[2], <MODE>mode) 3477 && rs6000_gen_cell_microcode))" 3478 "#" 3479 "&& reload_completed" 3480 [(pc)] 3481{ 3482 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1); 3483 DONE; 3484} 3485 [(set_attr "type" "shift") 3486 (set_attr "dot" "yes") 3487 (set_attr "length" "8,12")]) 3488 3489(define_insn_and_split "*and<mode>3_2insn_dot2" 3490 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3491 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3492 (match_operand:GPR 2 "const_int_operand" "n,n")) 3493 (const_int 0))) 3494 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3495 (and:GPR (match_dup 1) 3496 (match_dup 2)))] 3497 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3498 && rs6000_gen_cell_microcode 3499 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3500 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3501 || (logical_const_operand (operands[2], <MODE>mode) 3502 && rs6000_gen_cell_microcode))" 3503 "#" 3504 "&& reload_completed" 3505 [(pc)] 3506{ 3507 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2); 3508 DONE; 3509} 3510 [(set_attr "type" "shift") 3511 (set_attr "dot" "yes") 3512 (set_attr "length" "8,12")]) 3513 3514 3515(define_expand "<code><mode>3" 3516 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 3517 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "") 3518 (match_operand:SDI 2 "reg_or_cint_operand" "")))] 3519 "" 3520{ 3521 if (<MODE>mode == DImode && !TARGET_POWERPC64) 3522 { 3523 rs6000_split_logical (operands, <CODE>, false, false, false); 3524 DONE; 3525 } 3526 3527 if (non_logical_cint_operand (operands[2], <MODE>mode)) 3528 { 3529 rtx tmp = ((!can_create_pseudo_p () 3530 || rtx_equal_p (operands[0], operands[1])) 3531 ? operands[0] : gen_reg_rtx (<MODE>mode)); 3532 3533 HOST_WIDE_INT value = INTVAL (operands[2]); 3534 HOST_WIDE_INT lo = value & 0xffff; 3535 HOST_WIDE_INT hi = value - lo; 3536 3537 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi))); 3538 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo))); 3539 DONE; 3540 } 3541 3542 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode)) 3543 operands[2] = force_reg (<MODE>mode, operands[2]); 3544}) 3545 3546(define_split 3547 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 3548 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "") 3549 (match_operand:GPR 2 "non_logical_cint_operand" "")))] 3550 "" 3551 [(set (match_dup 3) 3552 (iorxor:GPR (match_dup 1) 3553 (match_dup 4))) 3554 (set (match_dup 0) 3555 (iorxor:GPR (match_dup 3) 3556 (match_dup 5)))] 3557{ 3558 operands[3] = ((!can_create_pseudo_p () 3559 || rtx_equal_p (operands[0], operands[1])) 3560 ? operands[0] : gen_reg_rtx (<MODE>mode)); 3561 3562 HOST_WIDE_INT value = INTVAL (operands[2]); 3563 HOST_WIDE_INT lo = value & 0xffff; 3564 HOST_WIDE_INT hi = value - lo; 3565 3566 operands[4] = GEN_INT (hi); 3567 operands[5] = GEN_INT (lo); 3568}) 3569 3570(define_insn "*bool<mode>3_imm" 3571 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3572 (match_operator:GPR 3 "boolean_or_operator" 3573 [(match_operand:GPR 1 "gpc_reg_operand" "%r") 3574 (match_operand:GPR 2 "logical_const_operand" "n")]))] 3575 "" 3576 "%q3i%e2 %0,%1,%u2" 3577 [(set_attr "type" "logical")]) 3578 3579(define_insn "*bool<mode>3" 3580 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3581 (match_operator:GPR 3 "boolean_operator" 3582 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3583 (match_operand:GPR 2 "gpc_reg_operand" "r")]))] 3584 "" 3585 "%q3 %0,%1,%2" 3586 [(set_attr "type" "logical")]) 3587 3588(define_insn_and_split "*bool<mode>3_dot" 3589 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3590 (compare:CC (match_operator:GPR 3 "boolean_operator" 3591 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3592 (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) 3593 (const_int 0))) 3594 (clobber (match_scratch:GPR 0 "=r,r"))] 3595 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3596 "@ 3597 %q3. %0,%1,%2 3598 #" 3599 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3600 [(set (match_dup 0) 3601 (match_dup 3)) 3602 (set (match_dup 4) 3603 (compare:CC (match_dup 0) 3604 (const_int 0)))] 3605 "" 3606 [(set_attr "type" "logical") 3607 (set_attr "dot" "yes") 3608 (set_attr "length" "4,8")]) 3609 3610(define_insn_and_split "*bool<mode>3_dot2" 3611 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3612 (compare:CC (match_operator:GPR 3 "boolean_operator" 3613 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3614 (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) 3615 (const_int 0))) 3616 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3617 (match_dup 3))] 3618 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3619 "@ 3620 %q3. %0,%1,%2 3621 #" 3622 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3623 [(set (match_dup 0) 3624 (match_dup 3)) 3625 (set (match_dup 4) 3626 (compare:CC (match_dup 0) 3627 (const_int 0)))] 3628 "" 3629 [(set_attr "type" "logical") 3630 (set_attr "dot" "yes") 3631 (set_attr "length" "4,8")]) 3632 3633 3634(define_insn "*boolc<mode>3" 3635 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3636 (match_operator:GPR 3 "boolean_operator" 3637 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")) 3638 (match_operand:GPR 1 "gpc_reg_operand" "r")]))] 3639 "" 3640 "%q3 %0,%1,%2" 3641 [(set_attr "type" "logical")]) 3642 3643(define_insn_and_split "*boolc<mode>3_dot" 3644 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3645 (compare:CC (match_operator:GPR 3 "boolean_operator" 3646 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3647 (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) 3648 (const_int 0))) 3649 (clobber (match_scratch:GPR 0 "=r,r"))] 3650 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3651 "@ 3652 %q3. %0,%1,%2 3653 #" 3654 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3655 [(set (match_dup 0) 3656 (match_dup 3)) 3657 (set (match_dup 4) 3658 (compare:CC (match_dup 0) 3659 (const_int 0)))] 3660 "" 3661 [(set_attr "type" "logical") 3662 (set_attr "dot" "yes") 3663 (set_attr "length" "4,8")]) 3664 3665(define_insn_and_split "*boolc<mode>3_dot2" 3666 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3667 (compare:CC (match_operator:GPR 3 "boolean_operator" 3668 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3669 (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) 3670 (const_int 0))) 3671 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3672 (match_dup 3))] 3673 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3674 "@ 3675 %q3. %0,%1,%2 3676 #" 3677 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3678 [(set (match_dup 0) 3679 (match_dup 3)) 3680 (set (match_dup 4) 3681 (compare:CC (match_dup 0) 3682 (const_int 0)))] 3683 "" 3684 [(set_attr "type" "logical") 3685 (set_attr "dot" "yes") 3686 (set_attr "length" "4,8")]) 3687 3688 3689(define_insn "*boolcc<mode>3" 3690 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3691 (match_operator:GPR 3 "boolean_operator" 3692 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 3693 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))] 3694 "" 3695 "%q3 %0,%1,%2" 3696 [(set_attr "type" "logical")]) 3697 3698(define_insn_and_split "*boolcc<mode>3_dot" 3699 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3700 (compare:CC (match_operator:GPR 3 "boolean_operator" 3701 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 3702 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) 3703 (const_int 0))) 3704 (clobber (match_scratch:GPR 0 "=r,r"))] 3705 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3706 "@ 3707 %q3. %0,%1,%2 3708 #" 3709 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3710 [(set (match_dup 0) 3711 (match_dup 3)) 3712 (set (match_dup 4) 3713 (compare:CC (match_dup 0) 3714 (const_int 0)))] 3715 "" 3716 [(set_attr "type" "logical") 3717 (set_attr "dot" "yes") 3718 (set_attr "length" "4,8")]) 3719 3720(define_insn_and_split "*boolcc<mode>3_dot2" 3721 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3722 (compare:CC (match_operator:GPR 3 "boolean_operator" 3723 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 3724 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) 3725 (const_int 0))) 3726 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3727 (match_dup 3))] 3728 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 3729 "@ 3730 %q3. %0,%1,%2 3731 #" 3732 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3733 [(set (match_dup 0) 3734 (match_dup 3)) 3735 (set (match_dup 4) 3736 (compare:CC (match_dup 0) 3737 (const_int 0)))] 3738 "" 3739 [(set_attr "type" "logical") 3740 (set_attr "dot" "yes") 3741 (set_attr "length" "4,8")]) 3742 3743 3744;; TODO: Should have dots of this as well. 3745(define_insn "*eqv<mode>3" 3746 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3747 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3748 (match_operand:GPR 2 "gpc_reg_operand" "r"))))] 3749 "" 3750 "eqv %0,%1,%2" 3751 [(set_attr "type" "logical")]) 3752 3753;; Rotate-and-mask and insert. 3754 3755(define_insn "*rotl<mode>3_mask" 3756 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3757 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3758 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3759 (match_operand:SI 2 "reg_or_cint_operand" "rn")]) 3760 (match_operand:GPR 3 "const_int_operand" "n")))] 3761 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3762{ 3763 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false); 3764} 3765 [(set_attr "type" "shift") 3766 (set_attr "maybe_var_shift" "yes")]) 3767 3768(define_insn_and_split "*rotl<mode>3_mask_dot" 3769 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") 3770 (compare:CC 3771 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3772 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3773 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")]) 3774 (match_operand:GPR 3 "const_int_operand" "n,n")) 3775 (const_int 0))) 3776 (clobber (match_scratch:GPR 0 "=r,r"))] 3777 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff) 3778 && rs6000_gen_cell_microcode 3779 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3780{ 3781 if (which_alternative == 0) 3782 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true); 3783 else 3784 return "#"; 3785} 3786 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)" 3787 [(set (match_dup 0) 3788 (and:GPR (match_dup 4) 3789 (match_dup 3))) 3790 (set (match_dup 5) 3791 (compare:CC (match_dup 0) 3792 (const_int 0)))] 3793 "" 3794 [(set_attr "type" "shift") 3795 (set_attr "maybe_var_shift" "yes") 3796 (set_attr "dot" "yes") 3797 (set_attr "length" "4,8")]) 3798 3799(define_insn_and_split "*rotl<mode>3_mask_dot2" 3800 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") 3801 (compare:CC 3802 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3803 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3804 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")]) 3805 (match_operand:GPR 3 "const_int_operand" "n,n")) 3806 (const_int 0))) 3807 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3808 (and:GPR (match_dup 4) 3809 (match_dup 3)))] 3810 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff) 3811 && rs6000_gen_cell_microcode 3812 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3813{ 3814 if (which_alternative == 0) 3815 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true); 3816 else 3817 return "#"; 3818} 3819 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)" 3820 [(set (match_dup 0) 3821 (and:GPR (match_dup 4) 3822 (match_dup 3))) 3823 (set (match_dup 5) 3824 (compare:CC (match_dup 0) 3825 (const_int 0)))] 3826 "" 3827 [(set_attr "type" "shift") 3828 (set_attr "maybe_var_shift" "yes") 3829 (set_attr "dot" "yes") 3830 (set_attr "length" "4,8")]) 3831 3832; Special case for less-than-0. We can do it with just one machine 3833; instruction, but the generic optimizers do not realise it is cheap. 3834(define_insn "*lt0_disi" 3835 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3836 (lt:DI (match_operand:SI 1 "gpc_reg_operand" "r") 3837 (const_int 0)))] 3838 "TARGET_POWERPC64" 3839 "rlwinm %0,%1,1,31,31" 3840 [(set_attr "type" "shift")]) 3841 3842 3843 3844; Two forms for insert (the two arms of the IOR are not canonicalized, 3845; both are an AND so are the same precedence). 3846(define_insn "*rotl<mode>3_insert" 3847 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3848 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3849 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3850 (match_operand:SI 2 "const_int_operand" "n")]) 3851 (match_operand:GPR 3 "const_int_operand" "n")) 3852 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0") 3853 (match_operand:GPR 6 "const_int_operand" "n"))))] 3854 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode) 3855 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0" 3856{ 3857 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false); 3858} 3859 [(set_attr "type" "insert")]) 3860; FIXME: this needs an attr "size", so that the scheduler can see the 3861; difference between rlwimi and rldimi. We also might want dot forms, 3862; but not for rlwimi on POWER4 and similar processors. 3863 3864(define_insn "*rotl<mode>3_insert_2" 3865 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3866 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0") 3867 (match_operand:GPR 6 "const_int_operand" "n")) 3868 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3869 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3870 (match_operand:SI 2 "const_int_operand" "n")]) 3871 (match_operand:GPR 3 "const_int_operand" "n"))))] 3872 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode) 3873 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0" 3874{ 3875 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false); 3876} 3877 [(set_attr "type" "insert")]) 3878 3879; There are also some forms without one of the ANDs. 3880(define_insn "*rotl<mode>3_insert_3" 3881 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3882 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 3883 (match_operand:GPR 4 "const_int_operand" "n")) 3884 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3885 (match_operand:SI 2 "const_int_operand" "n"))))] 3886 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)" 3887{ 3888 if (<MODE>mode == SImode) 3889 return "rlwimi %0,%1,%h2,0,31-%h2"; 3890 else 3891 return "rldimi %0,%1,%H2,0"; 3892} 3893 [(set_attr "type" "insert")]) 3894 3895(define_insn "*rotl<mode>3_insert_4" 3896 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3897 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 3898 (match_operand:GPR 4 "const_int_operand" "n")) 3899 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3900 (match_operand:SI 2 "const_int_operand" "n"))))] 3901 "<MODE>mode == SImode && 3902 GET_MODE_PRECISION (<MODE>mode) 3903 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))" 3904{ 3905 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode) 3906 - INTVAL (operands[2])); 3907 if (<MODE>mode == SImode) 3908 return "rlwimi %0,%1,%h2,32-%h2,31"; 3909 else 3910 return "rldimi %0,%1,%H2,64-%H2"; 3911} 3912 [(set_attr "type" "insert")]) 3913 3914(define_insn "*rotlsi3_insert_5" 3915 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 3916 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r") 3917 (match_operand:SI 2 "const_int_operand" "n,n")) 3918 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0") 3919 (match_operand:SI 4 "const_int_operand" "n,n"))))] 3920 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode) 3921 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0 3922 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 3923 "@ 3924 rlwimi %0,%3,0,%4 3925 rlwimi %0,%1,0,%2" 3926 [(set_attr "type" "insert")]) 3927 3928(define_insn "*rotldi3_insert_6" 3929 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3930 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0") 3931 (match_operand:DI 2 "const_int_operand" "n")) 3932 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r") 3933 (match_operand:DI 4 "const_int_operand" "n"))))] 3934 "exact_log2 (-UINTVAL (operands[2])) > 0 3935 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 3936{ 3937 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2]))); 3938 return "rldimi %0,%3,0,%5"; 3939} 3940 [(set_attr "type" "insert") 3941 (set_attr "size" "64")]) 3942 3943(define_insn "*rotldi3_insert_7" 3944 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3945 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r") 3946 (match_operand:DI 4 "const_int_operand" "n")) 3947 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0") 3948 (match_operand:DI 2 "const_int_operand" "n"))))] 3949 "exact_log2 (-UINTVAL (operands[2])) > 0 3950 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 3951{ 3952 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2]))); 3953 return "rldimi %0,%3,0,%5"; 3954} 3955 [(set_attr "type" "insert") 3956 (set_attr "size" "64")]) 3957 3958 3959; This handles the important case of multiple-precision shifts. There is 3960; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns. 3961(define_split 3962 [(set (match_operand:GPR 0 "gpc_reg_operand") 3963 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 3964 (match_operand:SI 3 "const_int_operand")) 3965 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand") 3966 (match_operand:SI 4 "const_int_operand"))))] 3967 "can_create_pseudo_p () 3968 && INTVAL (operands[3]) + INTVAL (operands[4]) 3969 >= GET_MODE_PRECISION (<MODE>mode)" 3970 [(set (match_dup 5) 3971 (lshiftrt:GPR (match_dup 2) 3972 (match_dup 4))) 3973 (set (match_dup 0) 3974 (ior:GPR (and:GPR (match_dup 5) 3975 (match_dup 6)) 3976 (ashift:GPR (match_dup 1) 3977 (match_dup 3))))] 3978{ 3979 unsigned HOST_WIDE_INT mask = 1; 3980 mask = (mask << INTVAL (operands[3])) - 1; 3981 operands[5] = gen_reg_rtx (<MODE>mode); 3982 operands[6] = GEN_INT (mask); 3983}) 3984 3985(define_split 3986 [(set (match_operand:GPR 0 "gpc_reg_operand") 3987 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand") 3988 (match_operand:SI 4 "const_int_operand")) 3989 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 3990 (match_operand:SI 3 "const_int_operand"))))] 3991 "can_create_pseudo_p () 3992 && INTVAL (operands[3]) + INTVAL (operands[4]) 3993 >= GET_MODE_PRECISION (<MODE>mode)" 3994 [(set (match_dup 5) 3995 (lshiftrt:GPR (match_dup 2) 3996 (match_dup 4))) 3997 (set (match_dup 0) 3998 (ior:GPR (and:GPR (match_dup 5) 3999 (match_dup 6)) 4000 (ashift:GPR (match_dup 1) 4001 (match_dup 3))))] 4002{ 4003 unsigned HOST_WIDE_INT mask = 1; 4004 mask = (mask << INTVAL (operands[3])) - 1; 4005 operands[5] = gen_reg_rtx (<MODE>mode); 4006 operands[6] = GEN_INT (mask); 4007}) 4008 4009 4010; Another important case is setting some bits to 1; we can do that with 4011; an insert instruction, in many cases. 4012(define_insn_and_split "*ior<mode>_mask" 4013 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4014 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0") 4015 (match_operand:GPR 2 "const_int_operand" "n"))) 4016 (clobber (match_scratch:GPR 3 "=r"))] 4017 "!logical_const_operand (operands[2], <MODE>mode) 4018 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)" 4019 "#" 4020 "&& 1" 4021 [(set (match_dup 3) 4022 (const_int -1)) 4023 (set (match_dup 0) 4024 (ior:GPR (and:GPR (rotate:GPR (match_dup 3) 4025 (match_dup 4)) 4026 (match_dup 2)) 4027 (and:GPR (match_dup 1) 4028 (match_dup 5))))] 4029{ 4030 int nb, ne; 4031 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode); 4032 if (GET_CODE (operands[3]) == SCRATCH) 4033 operands[3] = gen_reg_rtx (<MODE>mode); 4034 operands[4] = GEN_INT (ne); 4035 operands[5] = GEN_INT (~UINTVAL (operands[2])); 4036} 4037 [(set_attr "type" "two") 4038 (set_attr "length" "8")]) 4039 4040 4041;; Now the simple shifts. 4042 4043(define_insn "rotl<mode>3" 4044 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4045 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4046 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4047 "" 4048 "rotl<wd>%I2 %0,%1,%<hH>2" 4049 [(set_attr "type" "shift") 4050 (set_attr "maybe_var_shift" "yes")]) 4051 4052(define_insn "*rotlsi3_64" 4053 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4054 (zero_extend:DI 4055 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4056 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4057 "TARGET_POWERPC64" 4058 "rotlw%I2 %0,%1,%h2" 4059 [(set_attr "type" "shift") 4060 (set_attr "maybe_var_shift" "yes")]) 4061 4062(define_insn_and_split "*rotl<mode>3_dot" 4063 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4064 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4065 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4066 (const_int 0))) 4067 (clobber (match_scratch:GPR 0 "=r,r"))] 4068 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4069 "@ 4070 rotl<wd>%I2. %0,%1,%<hH>2 4071 #" 4072 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4073 [(set (match_dup 0) 4074 (rotate:GPR (match_dup 1) 4075 (match_dup 2))) 4076 (set (match_dup 3) 4077 (compare:CC (match_dup 0) 4078 (const_int 0)))] 4079 "" 4080 [(set_attr "type" "shift") 4081 (set_attr "maybe_var_shift" "yes") 4082 (set_attr "dot" "yes") 4083 (set_attr "length" "4,8")]) 4084 4085(define_insn_and_split "*rotl<mode>3_dot2" 4086 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4087 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4088 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4089 (const_int 0))) 4090 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4091 (rotate:GPR (match_dup 1) 4092 (match_dup 2)))] 4093 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4094 "@ 4095 rotl<wd>%I2. %0,%1,%<hH>2 4096 #" 4097 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4098 [(set (match_dup 0) 4099 (rotate:GPR (match_dup 1) 4100 (match_dup 2))) 4101 (set (match_dup 3) 4102 (compare:CC (match_dup 0) 4103 (const_int 0)))] 4104 "" 4105 [(set_attr "type" "shift") 4106 (set_attr "maybe_var_shift" "yes") 4107 (set_attr "dot" "yes") 4108 (set_attr "length" "4,8")]) 4109 4110 4111(define_insn "ashl<mode>3" 4112 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4113 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4114 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4115 "" 4116 "sl<wd>%I2 %0,%1,%<hH>2" 4117 [(set_attr "type" "shift") 4118 (set_attr "maybe_var_shift" "yes")]) 4119 4120(define_insn "*ashlsi3_64" 4121 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4122 (zero_extend:DI 4123 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4124 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4125 "TARGET_POWERPC64" 4126 "slw%I2 %0,%1,%h2" 4127 [(set_attr "type" "shift") 4128 (set_attr "maybe_var_shift" "yes")]) 4129 4130(define_insn_and_split "*ashl<mode>3_dot" 4131 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4132 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4133 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4134 (const_int 0))) 4135 (clobber (match_scratch:GPR 0 "=r,r"))] 4136 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4137 "@ 4138 sl<wd>%I2. %0,%1,%<hH>2 4139 #" 4140 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4141 [(set (match_dup 0) 4142 (ashift:GPR (match_dup 1) 4143 (match_dup 2))) 4144 (set (match_dup 3) 4145 (compare:CC (match_dup 0) 4146 (const_int 0)))] 4147 "" 4148 [(set_attr "type" "shift") 4149 (set_attr "maybe_var_shift" "yes") 4150 (set_attr "dot" "yes") 4151 (set_attr "length" "4,8")]) 4152 4153(define_insn_and_split "*ashl<mode>3_dot2" 4154 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4155 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4156 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4157 (const_int 0))) 4158 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4159 (ashift:GPR (match_dup 1) 4160 (match_dup 2)))] 4161 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4162 "@ 4163 sl<wd>%I2. %0,%1,%<hH>2 4164 #" 4165 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4166 [(set (match_dup 0) 4167 (ashift:GPR (match_dup 1) 4168 (match_dup 2))) 4169 (set (match_dup 3) 4170 (compare:CC (match_dup 0) 4171 (const_int 0)))] 4172 "" 4173 [(set_attr "type" "shift") 4174 (set_attr "maybe_var_shift" "yes") 4175 (set_attr "dot" "yes") 4176 (set_attr "length" "4,8")]) 4177 4178;; Pretend we have a memory form of extswsli until register allocation is done 4179;; so that we use LWZ to load the value from memory, instead of LWA. 4180(define_insn_and_split "ashdi3_extswsli" 4181 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 4182 (ashift:DI 4183 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m")) 4184 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))] 4185 "TARGET_EXTSWSLI" 4186 "@ 4187 extswsli %0,%1,%2 4188 #" 4189 "&& reload_completed && MEM_P (operands[1])" 4190 [(set (match_dup 3) 4191 (match_dup 1)) 4192 (set (match_dup 0) 4193 (ashift:DI (sign_extend:DI (match_dup 3)) 4194 (match_dup 2)))] 4195{ 4196 operands[3] = gen_lowpart (SImode, operands[0]); 4197} 4198 [(set_attr "type" "shift") 4199 (set_attr "maybe_var_shift" "no")]) 4200 4201 4202(define_insn_and_split "ashdi3_extswsli_dot" 4203 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y") 4204 (compare:CC 4205 (ashift:DI 4206 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m")) 4207 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n")) 4208 (const_int 0))) 4209 (clobber (match_scratch:DI 0 "=r,r,r,r"))] 4210 "TARGET_EXTSWSLI" 4211 "@ 4212 extswsli. %0,%1,%2 4213 # 4214 # 4215 #" 4216 "&& reload_completed 4217 && (cc_reg_not_cr0_operand (operands[3], CCmode) 4218 || memory_operand (operands[1], SImode))" 4219 [(pc)] 4220{ 4221 rtx dest = operands[0]; 4222 rtx src = operands[1]; 4223 rtx shift = operands[2]; 4224 rtx cr = operands[3]; 4225 rtx src2; 4226 4227 if (!MEM_P (src)) 4228 src2 = src; 4229 else 4230 { 4231 src2 = gen_lowpart (SImode, dest); 4232 emit_move_insn (src2, src); 4233 } 4234 4235 if (REGNO (cr) == CR0_REGNO) 4236 { 4237 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr)); 4238 DONE; 4239 } 4240 4241 emit_insn (gen_ashdi3_extswsli (dest, src2, shift)); 4242 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx))); 4243 DONE; 4244} 4245 [(set_attr "type" "shift") 4246 (set_attr "maybe_var_shift" "no") 4247 (set_attr "dot" "yes") 4248 (set_attr "length" "4,8,8,12")]) 4249 4250(define_insn_and_split "ashdi3_extswsli_dot2" 4251 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y") 4252 (compare:CC 4253 (ashift:DI 4254 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m")) 4255 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n")) 4256 (const_int 0))) 4257 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") 4258 (ashift:DI (sign_extend:DI (match_dup 1)) 4259 (match_dup 2)))] 4260 "TARGET_EXTSWSLI" 4261 "@ 4262 extswsli. %0,%1,%2 4263 # 4264 # 4265 #" 4266 "&& reload_completed 4267 && (cc_reg_not_cr0_operand (operands[3], CCmode) 4268 || memory_operand (operands[1], SImode))" 4269 [(pc)] 4270{ 4271 rtx dest = operands[0]; 4272 rtx src = operands[1]; 4273 rtx shift = operands[2]; 4274 rtx cr = operands[3]; 4275 rtx src2; 4276 4277 if (!MEM_P (src)) 4278 src2 = src; 4279 else 4280 { 4281 src2 = gen_lowpart (SImode, dest); 4282 emit_move_insn (src2, src); 4283 } 4284 4285 if (REGNO (cr) == CR0_REGNO) 4286 { 4287 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr)); 4288 DONE; 4289 } 4290 4291 emit_insn (gen_ashdi3_extswsli (dest, src2, shift)); 4292 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx))); 4293 DONE; 4294} 4295 [(set_attr "type" "shift") 4296 (set_attr "maybe_var_shift" "no") 4297 (set_attr "dot" "yes") 4298 (set_attr "length" "4,8,8,12")]) 4299 4300(define_insn "lshr<mode>3" 4301 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4302 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4303 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4304 "" 4305 "sr<wd>%I2 %0,%1,%<hH>2" 4306 [(set_attr "type" "shift") 4307 (set_attr "maybe_var_shift" "yes")]) 4308 4309(define_insn "*lshrsi3_64" 4310 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4311 (zero_extend:DI 4312 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4313 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4314 "TARGET_POWERPC64" 4315 "srw%I2 %0,%1,%h2" 4316 [(set_attr "type" "shift") 4317 (set_attr "maybe_var_shift" "yes")]) 4318 4319(define_insn_and_split "*lshr<mode>3_dot" 4320 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4321 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4322 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4323 (const_int 0))) 4324 (clobber (match_scratch:GPR 0 "=r,r"))] 4325 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4326 "@ 4327 sr<wd>%I2. %0,%1,%<hH>2 4328 #" 4329 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4330 [(set (match_dup 0) 4331 (lshiftrt:GPR (match_dup 1) 4332 (match_dup 2))) 4333 (set (match_dup 3) 4334 (compare:CC (match_dup 0) 4335 (const_int 0)))] 4336 "" 4337 [(set_attr "type" "shift") 4338 (set_attr "maybe_var_shift" "yes") 4339 (set_attr "dot" "yes") 4340 (set_attr "length" "4,8")]) 4341 4342(define_insn_and_split "*lshr<mode>3_dot2" 4343 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4344 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4345 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4346 (const_int 0))) 4347 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4348 (lshiftrt:GPR (match_dup 1) 4349 (match_dup 2)))] 4350 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4351 "@ 4352 sr<wd>%I2. %0,%1,%<hH>2 4353 #" 4354 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4355 [(set (match_dup 0) 4356 (lshiftrt:GPR (match_dup 1) 4357 (match_dup 2))) 4358 (set (match_dup 3) 4359 (compare:CC (match_dup 0) 4360 (const_int 0)))] 4361 "" 4362 [(set_attr "type" "shift") 4363 (set_attr "maybe_var_shift" "yes") 4364 (set_attr "dot" "yes") 4365 (set_attr "length" "4,8")]) 4366 4367 4368(define_insn "ashr<mode>3" 4369 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4370 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4371 (match_operand:SI 2 "reg_or_cint_operand" "rn"))) 4372 (clobber (reg:GPR CA_REGNO))] 4373 "" 4374 "sra<wd>%I2 %0,%1,%<hH>2" 4375 [(set_attr "type" "shift") 4376 (set_attr "maybe_var_shift" "yes")]) 4377 4378(define_insn "*ashrsi3_64" 4379 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4380 (sign_extend:DI 4381 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4382 (match_operand:SI 2 "reg_or_cint_operand" "rn")))) 4383 (clobber (reg:SI CA_REGNO))] 4384 "TARGET_POWERPC64" 4385 "sraw%I2 %0,%1,%h2" 4386 [(set_attr "type" "shift") 4387 (set_attr "maybe_var_shift" "yes")]) 4388 4389(define_insn_and_split "*ashr<mode>3_dot" 4390 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4391 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4392 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4393 (const_int 0))) 4394 (clobber (match_scratch:GPR 0 "=r,r")) 4395 (clobber (reg:GPR CA_REGNO))] 4396 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4397 "@ 4398 sra<wd>%I2. %0,%1,%<hH>2 4399 #" 4400 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4401 [(parallel [(set (match_dup 0) 4402 (ashiftrt:GPR (match_dup 1) 4403 (match_dup 2))) 4404 (clobber (reg:GPR CA_REGNO))]) 4405 (set (match_dup 3) 4406 (compare:CC (match_dup 0) 4407 (const_int 0)))] 4408 "" 4409 [(set_attr "type" "shift") 4410 (set_attr "maybe_var_shift" "yes") 4411 (set_attr "dot" "yes") 4412 (set_attr "length" "4,8")]) 4413 4414(define_insn_and_split "*ashr<mode>3_dot2" 4415 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4416 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4417 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4418 (const_int 0))) 4419 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4420 (ashiftrt:GPR (match_dup 1) 4421 (match_dup 2))) 4422 (clobber (reg:GPR CA_REGNO))] 4423 "<MODE>mode == Pmode && rs6000_gen_cell_microcode" 4424 "@ 4425 sra<wd>%I2. %0,%1,%<hH>2 4426 #" 4427 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4428 [(parallel [(set (match_dup 0) 4429 (ashiftrt:GPR (match_dup 1) 4430 (match_dup 2))) 4431 (clobber (reg:GPR CA_REGNO))]) 4432 (set (match_dup 3) 4433 (compare:CC (match_dup 0) 4434 (const_int 0)))] 4435 "" 4436 [(set_attr "type" "shift") 4437 (set_attr "maybe_var_shift" "yes") 4438 (set_attr "dot" "yes") 4439 (set_attr "length" "4,8")]) 4440 4441;; Builtins to replace a division to generate FRE reciprocal estimate 4442;; instructions and the necessary fixup instructions 4443(define_expand "recip<mode>3" 4444 [(match_operand:RECIPF 0 "gpc_reg_operand" "") 4445 (match_operand:RECIPF 1 "gpc_reg_operand" "") 4446 (match_operand:RECIPF 2 "gpc_reg_operand" "")] 4447 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)" 4448{ 4449 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false); 4450 DONE; 4451}) 4452 4453;; Split to create division from FRE/FRES/etc. and fixup instead of the normal 4454;; hardware division. This is only done before register allocation and with 4455;; -ffast-math. This must appear before the divsf3/divdf3 insns. 4456;; We used to also check optimize_insn_for_speed_p () but problems with guessed 4457;; frequencies (pr68212/pr77536) yields that unreliable so it was removed. 4458(define_split 4459 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "") 4460 (div:RECIPF (match_operand 1 "gpc_reg_operand" "") 4461 (match_operand 2 "gpc_reg_operand" "")))] 4462 "RS6000_RECIP_AUTO_RE_P (<MODE>mode) 4463 && can_create_pseudo_p () && flag_finite_math_only 4464 && !flag_trapping_math && flag_reciprocal_math" 4465 [(const_int 0)] 4466{ 4467 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); 4468 DONE; 4469}) 4470 4471;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the 4472;; appropriate fixup. 4473(define_expand "rsqrt<mode>2" 4474 [(match_operand:RECIPF 0 "gpc_reg_operand" "") 4475 (match_operand:RECIPF 1 "gpc_reg_operand" "")] 4476 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 4477{ 4478 rs6000_emit_swsqrt (operands[0], operands[1], 1); 4479 DONE; 4480}) 4481 4482;; Floating-point insns, excluding normal data motion. We combine the SF/DF 4483;; modes here, and also add in conditional vsx/power8-vector support to access 4484;; values in the traditional Altivec registers if the appropriate 4485;; -mupper-regs-{df,sf} option is enabled. 4486 4487(define_expand "abs<mode>2" 4488 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4489 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))] 4490 "TARGET_<MODE>_INSN" 4491 "") 4492 4493(define_insn "*abs<mode>2_fpr" 4494 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4495 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 4496 "TARGET_<MODE>_FPR" 4497 "@ 4498 fabs %0,%1 4499 xsabsdp %x0,%x1" 4500 [(set_attr "type" "fpsimple") 4501 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4502 4503(define_insn "*nabs<mode>2_fpr" 4504 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4505 (neg:SFDF 4506 (abs:SFDF 4507 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))] 4508 "TARGET_<MODE>_FPR" 4509 "@ 4510 fnabs %0,%1 4511 xsnabsdp %x0,%x1" 4512 [(set_attr "type" "fpsimple") 4513 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4514 4515(define_expand "neg<mode>2" 4516 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4517 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))] 4518 "TARGET_<MODE>_INSN" 4519 "") 4520 4521(define_insn "*neg<mode>2_fpr" 4522 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4523 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 4524 "TARGET_<MODE>_FPR" 4525 "@ 4526 fneg %0,%1 4527 xsnegdp %x0,%x1" 4528 [(set_attr "type" "fpsimple") 4529 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4530 4531(define_expand "add<mode>3" 4532 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4533 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4534 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4535 "TARGET_<MODE>_INSN" 4536 "") 4537 4538(define_insn "*add<mode>3_fpr" 4539 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4540 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") 4541 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4542 "TARGET_<MODE>_FPR" 4543 "@ 4544 fadd<Ftrad> %0,%1,%2 4545 xsadd<Fvsx> %x0,%x1,%x2" 4546 [(set_attr "type" "fp") 4547 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4548 4549(define_expand "sub<mode>3" 4550 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4551 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4552 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4553 "TARGET_<MODE>_INSN" 4554 "") 4555 4556(define_insn "*sub<mode>3_fpr" 4557 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4558 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") 4559 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4560 "TARGET_<MODE>_FPR" 4561 "@ 4562 fsub<Ftrad> %0,%1,%2 4563 xssub<Fvsx> %x0,%x1,%x2" 4564 [(set_attr "type" "fp") 4565 (set_attr "fp_type" "fp_addsub_<Fs>")]) 4566 4567(define_expand "mul<mode>3" 4568 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4569 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4570 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4571 "TARGET_<MODE>_INSN" 4572 "") 4573 4574(define_insn "*mul<mode>3_fpr" 4575 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4576 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>") 4577 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4578 "TARGET_<MODE>_FPR" 4579 "@ 4580 fmul<Ftrad> %0,%1,%2 4581 xsmul<Fvsx> %x0,%x1,%x2" 4582 [(set_attr "type" "dmul") 4583 (set_attr "fp_type" "fp_mul_<Fs>")]) 4584 4585(define_expand "div<mode>3" 4586 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4587 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4588 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4589 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU" 4590{ 4591 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode) 4592 && can_create_pseudo_p () && flag_finite_math_only 4593 && !flag_trapping_math && flag_reciprocal_math) 4594 { 4595 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); 4596 DONE; 4597 } 4598}) 4599 4600(define_insn "*div<mode>3_fpr" 4601 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4602 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") 4603 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4604 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU" 4605 "@ 4606 fdiv<Ftrad> %0,%1,%2 4607 xsdiv<Fvsx> %x0,%x1,%x2" 4608 [(set_attr "type" "<Fs>div") 4609 (set_attr "fp_type" "fp_div_<Fs>")]) 4610 4611(define_insn "*sqrt<mode>2_internal" 4612 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4613 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4614 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU 4615 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))" 4616 "@ 4617 fsqrt<Ftrad> %0,%1 4618 xssqrt<Fvsx> %x0,%x1" 4619 [(set_attr "type" "<Fs>sqrt") 4620 (set_attr "fp_type" "fp_sqrt_<Fs>")]) 4621 4622(define_expand "sqrt<mode>2" 4623 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4624 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))] 4625 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU 4626 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))" 4627{ 4628 if (<MODE>mode == SFmode 4629 && TARGET_RECIP_PRECISION 4630 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode) 4631 && !optimize_function_for_size_p (cfun) 4632 && flag_finite_math_only && !flag_trapping_math 4633 && flag_unsafe_math_optimizations) 4634 { 4635 rs6000_emit_swsqrt (operands[0], operands[1], 0); 4636 DONE; 4637 } 4638}) 4639 4640;; Floating point reciprocal approximation 4641(define_insn "fre<Fs>" 4642 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4643 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")] 4644 UNSPEC_FRES))] 4645 "TARGET_<FFRE>" 4646 "@ 4647 fre<Ftrad> %0,%1 4648 xsre<Fvsx> %x0,%x1" 4649 [(set_attr "type" "fp")]) 4650 4651(define_insn "*rsqrt<mode>2" 4652 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>") 4653 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")] 4654 UNSPEC_RSQRT))] 4655 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 4656 "@ 4657 frsqrte<Ftrad> %0,%1 4658 xsrsqrte<Fvsx> %x0,%x1" 4659 [(set_attr "type" "fp")]) 4660 4661;; Floating point comparisons 4662(define_insn "*cmp<mode>_fpr" 4663 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y") 4664 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>") 4665 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))] 4666 "TARGET_<MODE>_FPR" 4667 "@ 4668 fcmpu %0,%1,%2 4669 xscmpudp %0,%x1,%x2" 4670 [(set_attr "type" "fpcompare")]) 4671 4672;; Floating point conversions 4673(define_expand "extendsfdf2" 4674 [(set (match_operand:DF 0 "gpc_reg_operand") 4675 (float_extend:DF (match_operand:SF 1 "reg_or_none500mem_operand")))] 4676 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" 4677{ 4678 if (HONOR_SNANS (SFmode)) 4679 operands[1] = force_reg (SFmode, operands[1]); 4680}) 4681 4682(define_insn_and_split "*extendsfdf2_fpr" 4683 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb") 4684 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))] 4685 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 4686 && !HONOR_SNANS (SFmode)" 4687 "@ 4688 # 4689 fmr %0,%1 4690 lfs%U1%X1 %0,%1 4691 # 4692 xscpsgndp %x0,%x1,%x1 4693 lxsspx %x0,%y1 4694 lxssp %0,%1" 4695 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])" 4696 [(const_int 0)] 4697{ 4698 emit_note (NOTE_INSN_DELETED); 4699 DONE; 4700} 4701 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")]) 4702 4703(define_insn "*extendsfdf2_snan" 4704 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 4705 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))] 4706 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 4707 && HONOR_SNANS (SFmode)" 4708 "@ 4709 frsp %0,%1 4710 xsrsp %x0,%x1" 4711 [(set_attr "type" "fp")]) 4712 4713(define_expand "truncdfsf2" 4714 [(set (match_operand:SF 0 "gpc_reg_operand" "") 4715 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))] 4716 "TARGET_HARD_FLOAT && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" 4717 "") 4718 4719(define_insn "*truncdfsf2_fpr" 4720 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy") 4721 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))] 4722 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 4723 "@ 4724 frsp %0,%1 4725 xsrsp %x0,%x1" 4726 [(set_attr "type" "fp")]) 4727 4728;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in 4729;; builtins.c and optabs.c that are not correct for IBM long double 4730;; when little-endian. 4731(define_expand "signbit<mode>2" 4732 [(set (match_dup 2) 4733 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" ""))) 4734 (set (match_dup 3) 4735 (subreg:DI (match_dup 2) 0)) 4736 (set (match_dup 4) 4737 (match_dup 5)) 4738 (set (match_operand:SI 0 "gpc_reg_operand" "") 4739 (match_dup 6))] 4740 "TARGET_HARD_FLOAT 4741 && (TARGET_FPRS || TARGET_E500_DOUBLE) 4742 && (!FLOAT128_IEEE_P (<MODE>mode) 4743 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))" 4744{ 4745 if (FLOAT128_IEEE_P (<MODE>mode)) 4746 { 4747 if (<MODE>mode == KFmode) 4748 emit_insn (gen_signbitkf2_dm (operands[0], operands[1])); 4749 else if (<MODE>mode == TFmode) 4750 emit_insn (gen_signbittf2_dm (operands[0], operands[1])); 4751 else 4752 gcc_unreachable (); 4753 DONE; 4754 } 4755 operands[2] = gen_reg_rtx (DFmode); 4756 operands[3] = gen_reg_rtx (DImode); 4757 if (TARGET_POWERPC64) 4758 { 4759 operands[4] = gen_reg_rtx (DImode); 4760 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63)); 4761 operands[6] = gen_rtx_SUBREG (SImode, operands[4], 4762 WORDS_BIG_ENDIAN ? 4 : 0); 4763 } 4764 else 4765 { 4766 operands[4] = gen_reg_rtx (SImode); 4767 operands[5] = gen_rtx_SUBREG (SImode, operands[3], 4768 WORDS_BIG_ENDIAN ? 0 : 4); 4769 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31)); 4770 } 4771}) 4772 4773(define_expand "copysign<mode>3" 4774 [(set (match_dup 3) 4775 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" ""))) 4776 (set (match_dup 4) 4777 (neg:SFDF (abs:SFDF (match_dup 1)))) 4778 (set (match_operand:SFDF 0 "gpc_reg_operand" "") 4779 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "") 4780 (match_dup 5)) 4781 (match_dup 3) 4782 (match_dup 4)))] 4783 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> 4784 && ((TARGET_PPC_GFXOPT 4785 && !HONOR_NANS (<MODE>mode) 4786 && !HONOR_SIGNED_ZEROS (<MODE>mode)) 4787 || TARGET_CMPB 4788 || VECTOR_UNIT_VSX_P (<MODE>mode))" 4789{ 4790 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode)) 4791 { 4792 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1], 4793 operands[2])); 4794 DONE; 4795 } 4796 4797 operands[3] = gen_reg_rtx (<MODE>mode); 4798 operands[4] = gen_reg_rtx (<MODE>mode); 4799 operands[5] = CONST0_RTX (<MODE>mode); 4800 }) 4801 4802;; Optimize signbit on 64-bit systems with direct move to avoid doing the store 4803;; and load. 4804(define_insn_and_split "signbit<mode>2_dm" 4805 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r") 4806 (unspec:SI 4807 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")] 4808 UNSPEC_SIGNBIT))] 4809 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 4810 "#" 4811 "&& reload_completed" 4812 [(const_int 0)] 4813{ 4814 rs6000_split_signbit (operands[0], operands[1]); 4815 DONE; 4816} 4817 [(set_attr "length" "8,8,4") 4818 (set_attr "type" "mftgpr,load,integer")]) 4819 4820(define_insn_and_split "*signbit<mode>2_dm_<su>ext" 4821 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r") 4822 (any_extend:DI 4823 (unspec:SI 4824 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")] 4825 UNSPEC_SIGNBIT)))] 4826 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 4827 "#" 4828 "&& reload_completed" 4829 [(const_int 0)] 4830{ 4831 rs6000_split_signbit (operands[0], operands[1]); 4832 DONE; 4833} 4834 [(set_attr "length" "8,8,4") 4835 (set_attr "type" "mftgpr,load,integer")]) 4836 4837;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various 4838;; floating point types, which makes normal SUBREG's problematical. Instead 4839;; use a special pattern to avoid using a normal movdi. 4840(define_insn "signbit<mode>2_dm2" 4841 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4842 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa") 4843 (const_int 0)] 4844 UNSPEC_SIGNBIT))] 4845 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 4846 "mfvsrd %0,%x1" 4847 [(set_attr "type" "mftgpr")]) 4848 4849 4850;; Use an unspec rather providing an if-then-else in RTL, to prevent the 4851;; compiler from optimizing -0.0 4852(define_insn "copysign<mode>3_fcpsgn" 4853 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4854 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") 4855 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")] 4856 UNSPEC_COPYSIGN))] 4857 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))" 4858 "@ 4859 fcpsgn %0,%2,%1 4860 xscpsgndp %x0,%x2,%x1" 4861 [(set_attr "type" "fpsimple")]) 4862 4863;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a 4864;; fsel instruction and some auxiliary computations. Then we just have a 4865;; single DEFINE_INSN for fsel and the define_splits to make them if made by 4866;; combine. 4867;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we 4868;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary 4869;; computations. Then we just have a single DEFINE_INSN for fsel and the 4870;; define_splits to make them if made by combine. On VSX machines we have the 4871;; min/max instructions. 4872;; 4873;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector 4874;; to allow either DF/SF to use only traditional registers. 4875 4876(define_expand "s<minmax><mode>3" 4877 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4878 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4879 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4880 "TARGET_MINMAX_<MODE>" 4881{ 4882 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 4883 DONE; 4884}) 4885 4886(define_insn "*s<minmax><mode>3_vsx" 4887 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 4888 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>") 4889 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))] 4890 "TARGET_VSX && TARGET_<MODE>_FPR" 4891{ 4892 return (TARGET_P9_MINMAX 4893 ? "xs<minmax>cdp %x0,%x1,%x2" 4894 : "xs<minmax>dp %x0,%x1,%x2"); 4895} 4896 [(set_attr "type" "fp")]) 4897 4898;; The conditional move instructions allow us to perform max and min operations 4899;; even when we don't have the appropriate max/min instruction using the FSEL 4900;; instruction. 4901 4902(define_insn_and_split "*s<minmax><mode>3_fpr" 4903 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 4904 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "") 4905 (match_operand:SFDF 2 "gpc_reg_operand" "")))] 4906 "!TARGET_VSX && TARGET_MINMAX_<MODE>" 4907 "#" 4908 "&& 1" 4909 [(const_int 0)] 4910{ 4911 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 4912 DONE; 4913}) 4914 4915(define_expand "mov<mode>cc" 4916 [(set (match_operand:GPR 0 "gpc_reg_operand" "") 4917 (if_then_else:GPR (match_operand 1 "comparison_operator" "") 4918 (match_operand:GPR 2 "gpc_reg_operand" "") 4919 (match_operand:GPR 3 "gpc_reg_operand" "")))] 4920 "TARGET_ISEL<sel>" 4921 " 4922{ 4923 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 4924 DONE; 4925 else 4926 FAIL; 4927}") 4928 4929;; We use the BASE_REGS for the isel input operands because, if rA is 4930;; 0, the value of 0 is placed in rD upon truth. Similarly for rB 4931;; because we may switch the operands and rB may end up being rA. 4932;; 4933;; We need 2 patterns: an unsigned and a signed pattern. We could 4934;; leave out the mode in operand 4 and use one pattern, but reload can 4935;; change the mode underneath our feet and then gets confused trying 4936;; to reload the value. 4937(define_insn "isel_signed_<mode>" 4938 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4939 (if_then_else:GPR 4940 (match_operator 1 "scc_comparison_operator" 4941 [(match_operand:CC 4 "cc_reg_operand" "y,y") 4942 (const_int 0)]) 4943 (match_operand:GPR 2 "reg_or_cint_operand" "O,b") 4944 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] 4945 "TARGET_ISEL<sel>" 4946 "* 4947{ return output_isel (operands); }" 4948 [(set_attr "type" "isel") 4949 (set_attr "length" "4")]) 4950 4951(define_insn "isel_unsigned_<mode>" 4952 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4953 (if_then_else:GPR 4954 (match_operator 1 "scc_comparison_operator" 4955 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y") 4956 (const_int 0)]) 4957 (match_operand:GPR 2 "reg_or_cint_operand" "O,b") 4958 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] 4959 "TARGET_ISEL<sel>" 4960 "* 4961{ return output_isel (operands); }" 4962 [(set_attr "type" "isel") 4963 (set_attr "length" "4")]) 4964 4965;; These patterns can be useful for combine; they let combine know that 4966;; isel can handle reversed comparisons so long as the operands are 4967;; registers. 4968 4969(define_insn "*isel_reversed_signed_<mode>" 4970 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4971 (if_then_else:GPR 4972 (match_operator 1 "scc_rev_comparison_operator" 4973 [(match_operand:CC 4 "cc_reg_operand" "y") 4974 (const_int 0)]) 4975 (match_operand:GPR 2 "gpc_reg_operand" "b") 4976 (match_operand:GPR 3 "gpc_reg_operand" "b")))] 4977 "TARGET_ISEL<sel>" 4978 "* 4979{ return output_isel (operands); }" 4980 [(set_attr "type" "isel") 4981 (set_attr "length" "4")]) 4982 4983(define_insn "*isel_reversed_unsigned_<mode>" 4984 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4985 (if_then_else:GPR 4986 (match_operator 1 "scc_rev_comparison_operator" 4987 [(match_operand:CCUNS 4 "cc_reg_operand" "y") 4988 (const_int 0)]) 4989 (match_operand:GPR 2 "gpc_reg_operand" "b") 4990 (match_operand:GPR 3 "gpc_reg_operand" "b")))] 4991 "TARGET_ISEL<sel>" 4992 "* 4993{ return output_isel (operands); }" 4994 [(set_attr "type" "isel") 4995 (set_attr "length" "4")]) 4996 4997;; Floating point conditional move 4998(define_expand "mov<mode>cc" 4999 [(set (match_operand:SFDF 0 "gpc_reg_operand" "") 5000 (if_then_else:SFDF (match_operand 1 "comparison_operator" "") 5001 (match_operand:SFDF 2 "gpc_reg_operand" "") 5002 (match_operand:SFDF 3 "gpc_reg_operand" "")))] 5003 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT" 5004 " 5005{ 5006 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 5007 DONE; 5008 else 5009 FAIL; 5010}") 5011 5012(define_insn "*fsel<SFDF:mode><SFDF2:mode>4" 5013 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>") 5014 (if_then_else:SFDF 5015 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>") 5016 (match_operand:SFDF2 4 "zero_fp_constant" "F")) 5017 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>") 5018 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))] 5019 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT" 5020 "fsel %0,%1,%2,%3" 5021 [(set_attr "type" "fp")]) 5022 5023(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9" 5024 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 5025 (if_then_else:SFDF 5026 (match_operator:CCFP 1 "fpmask_comparison_operator" 5027 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 5028 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 5029 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 5030 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5031 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 5032 "TARGET_P9_MINMAX" 5033 "#" 5034 "" 5035 [(set (match_dup 6) 5036 (if_then_else:V2DI (match_dup 1) 5037 (match_dup 7) 5038 (match_dup 8))) 5039 (set (match_dup 0) 5040 (if_then_else:SFDF (ne (match_dup 6) 5041 (match_dup 8)) 5042 (match_dup 4) 5043 (match_dup 5)))] 5044{ 5045 if (GET_CODE (operands[6]) == SCRATCH) 5046 operands[6] = gen_reg_rtx (V2DImode); 5047 5048 operands[7] = CONSTM1_RTX (V2DImode); 5049 operands[8] = CONST0_RTX (V2DImode); 5050} 5051 [(set_attr "length" "8") 5052 (set_attr "type" "vecperm")]) 5053 5054;; Handle inverting the fpmask comparisons. 5055(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9" 5056 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 5057 (if_then_else:SFDF 5058 (match_operator:CCFP 1 "invert_fpmask_comparison_operator" 5059 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 5060 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 5061 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 5062 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5063 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 5064 "TARGET_P9_MINMAX" 5065 "#" 5066 "&& 1" 5067 [(set (match_dup 6) 5068 (if_then_else:V2DI (match_dup 9) 5069 (match_dup 7) 5070 (match_dup 8))) 5071 (set (match_dup 0) 5072 (if_then_else:SFDF (ne (match_dup 6) 5073 (match_dup 8)) 5074 (match_dup 5) 5075 (match_dup 4)))] 5076{ 5077 rtx op1 = operands[1]; 5078 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1)); 5079 5080 if (GET_CODE (operands[6]) == SCRATCH) 5081 operands[6] = gen_reg_rtx (V2DImode); 5082 5083 operands[7] = CONSTM1_RTX (V2DImode); 5084 operands[8] = CONST0_RTX (V2DImode); 5085 5086 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]); 5087} 5088 [(set_attr "length" "8") 5089 (set_attr "type" "vecperm")]) 5090 5091(define_insn "*fpmask<mode>" 5092 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa") 5093 (if_then_else:V2DI 5094 (match_operator:CCFP 1 "fpmask_comparison_operator" 5095 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>") 5096 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")]) 5097 (match_operand:V2DI 4 "all_ones_constant" "") 5098 (match_operand:V2DI 5 "zero_constant" "")))] 5099 "TARGET_P9_MINMAX" 5100 "xscmp%V1dp %x0,%x2,%x3" 5101 [(set_attr "type" "fpcompare")]) 5102 5103(define_insn "*xxsel<mode>" 5104 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 5105 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa") 5106 (match_operand:V2DI 2 "zero_constant" "")) 5107 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>") 5108 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))] 5109 "TARGET_P9_MINMAX" 5110 "xxsel %x0,%x4,%x3,%x1" 5111 [(set_attr "type" "vecmove")]) 5112 5113 5114;; Conversions to and from floating-point. 5115 5116; We don't define lfiwax/lfiwzx with the normal definition, because we 5117; don't want to support putting SImode in FPR registers. 5118(define_insn "lfiwax" 5119 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK") 5120 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")] 5121 UNSPEC_LFIWAX))] 5122 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX" 5123 "@ 5124 lfiwax %0,%y1 5125 lxsiwax %x0,%y1 5126 mtvsrwa %x0,%1 5127 vextsw2d %0,%1" 5128 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")]) 5129 5130; This split must be run before register allocation because it allocates the 5131; memory slot that is needed to move values to/from the FPR. We don't allocate 5132; it earlier to allow for the combiner to merge insns together where it might 5133; not be needed and also in case the insns are deleted as dead code. 5134 5135(define_insn_and_split "floatsi<mode>2_lfiwax" 5136 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5137 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) 5138 (clobber (match_scratch:DI 2 "=wi"))] 5139 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX 5140 && <SI_CONVERT_FP> && can_create_pseudo_p ()" 5141 "#" 5142 "" 5143 [(pc)] 5144 " 5145{ 5146 rtx dest = operands[0]; 5147 rtx src = operands[1]; 5148 rtx tmp; 5149 5150 if (!MEM_P (src) && TARGET_POWERPC64 5151 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5152 tmp = convert_to_mode (DImode, src, false); 5153 else 5154 { 5155 tmp = operands[2]; 5156 if (GET_CODE (tmp) == SCRATCH) 5157 tmp = gen_reg_rtx (DImode); 5158 if (MEM_P (src)) 5159 { 5160 src = rs6000_address_for_fpconvert (src); 5161 emit_insn (gen_lfiwax (tmp, src)); 5162 } 5163 else 5164 { 5165 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5166 emit_move_insn (stack, src); 5167 emit_insn (gen_lfiwax (tmp, stack)); 5168 } 5169 } 5170 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5171 DONE; 5172}" 5173 [(set_attr "length" "12") 5174 (set_attr "type" "fpload")]) 5175 5176(define_insn_and_split "floatsi<mode>2_lfiwax_mem" 5177 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5178 (float:SFDF 5179 (sign_extend:DI 5180 (match_operand:SI 1 "indexed_or_indirect_operand" "Z")))) 5181 (clobber (match_scratch:DI 2 "=wi"))] 5182 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX 5183 && <SI_CONVERT_FP>" 5184 "#" 5185 "" 5186 [(pc)] 5187 " 5188{ 5189 operands[1] = rs6000_address_for_fpconvert (operands[1]); 5190 if (GET_CODE (operands[2]) == SCRATCH) 5191 operands[2] = gen_reg_rtx (DImode); 5192 if (TARGET_VSX_SMALL_INTEGER) 5193 emit_insn (gen_extendsidi2 (operands[2], operands[1])); 5194 else 5195 emit_insn (gen_lfiwax (operands[2], operands[1])); 5196 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5197 DONE; 5198}" 5199 [(set_attr "length" "8") 5200 (set_attr "type" "fpload")]) 5201 5202(define_insn "lfiwzx" 5203 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK") 5204 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")] 5205 UNSPEC_LFIWZX))] 5206 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX" 5207 "@ 5208 lfiwzx %0,%y1 5209 lxsiwzx %x0,%y1 5210 mtvsrwz %x0,%1 5211 xxextractuw %x0,%x1,4" 5212 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")]) 5213 5214(define_insn_and_split "floatunssi<mode>2_lfiwzx" 5215 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5216 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r"))) 5217 (clobber (match_scratch:DI 2 "=wi"))] 5218 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX 5219 && <SI_CONVERT_FP>" 5220 "#" 5221 "" 5222 [(pc)] 5223 " 5224{ 5225 rtx dest = operands[0]; 5226 rtx src = operands[1]; 5227 rtx tmp; 5228 5229 if (!MEM_P (src) && TARGET_POWERPC64 5230 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5231 tmp = convert_to_mode (DImode, src, true); 5232 else 5233 { 5234 tmp = operands[2]; 5235 if (GET_CODE (tmp) == SCRATCH) 5236 tmp = gen_reg_rtx (DImode); 5237 if (MEM_P (src)) 5238 { 5239 src = rs6000_address_for_fpconvert (src); 5240 emit_insn (gen_lfiwzx (tmp, src)); 5241 } 5242 else 5243 { 5244 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5245 emit_move_insn (stack, src); 5246 emit_insn (gen_lfiwzx (tmp, stack)); 5247 } 5248 } 5249 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5250 DONE; 5251}" 5252 [(set_attr "length" "12") 5253 (set_attr "type" "fpload")]) 5254 5255(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem" 5256 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 5257 (unsigned_float:SFDF 5258 (zero_extend:DI 5259 (match_operand:SI 1 "indexed_or_indirect_operand" "Z")))) 5260 (clobber (match_scratch:DI 2 "=wi"))] 5261 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX 5262 && <SI_CONVERT_FP>" 5263 "#" 5264 "" 5265 [(pc)] 5266 " 5267{ 5268 operands[1] = rs6000_address_for_fpconvert (operands[1]); 5269 if (GET_CODE (operands[2]) == SCRATCH) 5270 operands[2] = gen_reg_rtx (DImode); 5271 if (TARGET_VSX_SMALL_INTEGER) 5272 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1])); 5273 else 5274 emit_insn (gen_lfiwzx (operands[2], operands[1])); 5275 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5276 DONE; 5277}" 5278 [(set_attr "length" "8") 5279 (set_attr "type" "fpload")]) 5280 5281; For each of these conversions, there is a define_expand, a define_insn 5282; with a '#' template, and a define_split (with C code). The idea is 5283; to allow constant folding with the template of the define_insn, 5284; then to have the insns split later (between sched1 and final). 5285 5286(define_expand "floatsidf2" 5287 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") 5288 (float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) 5289 (use (match_dup 2)) 5290 (use (match_dup 3)) 5291 (clobber (match_dup 4)) 5292 (clobber (match_dup 5)) 5293 (clobber (match_dup 6))])] 5294 "TARGET_HARD_FLOAT 5295 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" 5296 " 5297{ 5298 if (TARGET_E500_DOUBLE) 5299 { 5300 if (!REG_P (operands[1])) 5301 operands[1] = force_reg (SImode, operands[1]); 5302 emit_insn (gen_spe_floatsidf2 (operands[0], operands[1])); 5303 DONE; 5304 } 5305 else if (TARGET_LFIWAX && TARGET_FCFID) 5306 { 5307 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1])); 5308 DONE; 5309 } 5310 else if (TARGET_FCFID) 5311 { 5312 rtx dreg = operands[1]; 5313 if (!REG_P (dreg)) 5314 dreg = force_reg (SImode, dreg); 5315 dreg = convert_to_mode (DImode, dreg, false); 5316 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5317 DONE; 5318 } 5319 5320 if (!REG_P (operands[1])) 5321 operands[1] = force_reg (SImode, operands[1]); 5322 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5323 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); 5324 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5325 operands[5] = gen_reg_rtx (DFmode); 5326 operands[6] = gen_reg_rtx (SImode); 5327}") 5328 5329(define_insn_and_split "*floatsidf2_internal" 5330 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5331 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5332 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5333 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5334 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5335 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) 5336 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] 5337 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 5338 "#" 5339 "" 5340 [(pc)] 5341 " 5342{ 5343 rtx lowword, highword; 5344 gcc_assert (MEM_P (operands[4])); 5345 highword = adjust_address (operands[4], SImode, 0); 5346 lowword = adjust_address (operands[4], SImode, 4); 5347 if (! WORDS_BIG_ENDIAN) 5348 std::swap (lowword, highword); 5349 5350 emit_insn (gen_xorsi3 (operands[6], operands[1], 5351 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff))); 5352 emit_move_insn (lowword, operands[6]); 5353 emit_move_insn (highword, operands[2]); 5354 emit_move_insn (operands[5], operands[4]); 5355 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5356 DONE; 5357}" 5358 [(set_attr "length" "24") 5359 (set_attr "type" "fp")]) 5360 5361;; If we don't have a direct conversion to single precision, don't enable this 5362;; conversion for 32-bit without fast math, because we don't have the insn to 5363;; generate the fixup swizzle to avoid double rounding problems. 5364(define_expand "floatunssisf2" 5365 [(set (match_operand:SF 0 "gpc_reg_operand" "") 5366 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] 5367 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 5368 && (!TARGET_FPRS 5369 || (TARGET_FPRS 5370 && ((TARGET_FCFIDUS && TARGET_LFIWZX) 5371 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID 5372 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))" 5373 " 5374{ 5375 if (!TARGET_FPRS) 5376 { 5377 if (!REG_P (operands[1])) 5378 operands[1] = force_reg (SImode, operands[1]); 5379 } 5380 else if (TARGET_LFIWZX && TARGET_FCFIDUS) 5381 { 5382 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1])); 5383 DONE; 5384 } 5385 else 5386 { 5387 rtx dreg = operands[1]; 5388 if (!REG_P (dreg)) 5389 dreg = force_reg (SImode, dreg); 5390 dreg = convert_to_mode (DImode, dreg, true); 5391 emit_insn (gen_floatdisf2 (operands[0], dreg)); 5392 DONE; 5393 } 5394}") 5395 5396(define_expand "floatunssidf2" 5397 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "") 5398 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" ""))) 5399 (use (match_dup 2)) 5400 (use (match_dup 3)) 5401 (clobber (match_dup 4)) 5402 (clobber (match_dup 5))])] 5403 "TARGET_HARD_FLOAT 5404 && ((TARGET_FPRS && TARGET_DOUBLE_FLOAT) || TARGET_E500_DOUBLE)" 5405 " 5406{ 5407 if (TARGET_E500_DOUBLE) 5408 { 5409 if (!REG_P (operands[1])) 5410 operands[1] = force_reg (SImode, operands[1]); 5411 emit_insn (gen_spe_floatunssidf2 (operands[0], operands[1])); 5412 DONE; 5413 } 5414 else if (TARGET_LFIWZX && TARGET_FCFID) 5415 { 5416 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1])); 5417 DONE; 5418 } 5419 else if (TARGET_FCFID) 5420 { 5421 rtx dreg = operands[1]; 5422 if (!REG_P (dreg)) 5423 dreg = force_reg (SImode, dreg); 5424 dreg = convert_to_mode (DImode, dreg, true); 5425 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5426 DONE; 5427 } 5428 5429 if (!REG_P (operands[1])) 5430 operands[1] = force_reg (SImode, operands[1]); 5431 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5432 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); 5433 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5434 operands[5] = gen_reg_rtx (DFmode); 5435}") 5436 5437(define_insn_and_split "*floatunssidf2_internal" 5438 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5439 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5440 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5441 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5442 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5443 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] 5444 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5445 && !(TARGET_FCFID && TARGET_POWERPC64)" 5446 "#" 5447 "" 5448 [(pc)] 5449 " 5450{ 5451 rtx lowword, highword; 5452 gcc_assert (MEM_P (operands[4])); 5453 highword = adjust_address (operands[4], SImode, 0); 5454 lowword = adjust_address (operands[4], SImode, 4); 5455 if (! WORDS_BIG_ENDIAN) 5456 std::swap (lowword, highword); 5457 5458 emit_move_insn (lowword, operands[1]); 5459 emit_move_insn (highword, operands[2]); 5460 emit_move_insn (operands[5], operands[4]); 5461 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5462 DONE; 5463}" 5464 [(set_attr "length" "20") 5465 (set_attr "type" "fp")]) 5466 5467;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to 5468;; vector registers. These insns favor doing the sign/zero extension in 5469;; the vector registers, rather then loading up a GPR, doing a sign/zero 5470;; extension and then a direct move. 5471 5472(define_expand "float<QHI:mode><FP_ISA3:mode>2" 5473 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") 5474 (float:FP_ISA3 5475 (match_operand:QHI 1 "input_operand"))) 5476 (clobber (match_scratch:DI 2)) 5477 (clobber (match_scratch:DI 3)) 5478 (clobber (match_scratch:<QHI:MODE> 4))])] 5479 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64 5480 && TARGET_VSX_SMALL_INTEGER" 5481{ 5482 if (MEM_P (operands[1])) 5483 operands[1] = rs6000_address_for_fpconvert (operands[1]); 5484}) 5485 5486(define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal" 5487 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>") 5488 (float:FP_ISA3 5489 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z"))) 5490 (clobber (match_scratch:DI 2 "=wK,wi,wK")) 5491 (clobber (match_scratch:DI 3 "=X,r,X")) 5492 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))] 5493 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64 5494 && TARGET_UPPER_REGS_DI && TARGET_VSX_SMALL_INTEGER" 5495 "#" 5496 "&& reload_completed" 5497 [(const_int 0)] 5498{ 5499 rtx result = operands[0]; 5500 rtx input = operands[1]; 5501 rtx di = operands[2]; 5502 5503 if (!MEM_P (input)) 5504 { 5505 rtx tmp = operands[3]; 5506 if (altivec_register_operand (input, <QHI:MODE>mode)) 5507 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5508 else if (GET_CODE (tmp) == SCRATCH) 5509 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5510 else 5511 { 5512 emit_insn (gen_extend<QHI:mode>di2 (tmp, input)); 5513 emit_move_insn (di, tmp); 5514 } 5515 } 5516 else 5517 { 5518 rtx tmp = operands[4]; 5519 emit_move_insn (tmp, input); 5520 emit_insn (gen_extend<QHI:mode>di2 (di, tmp)); 5521 } 5522 5523 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); 5524 DONE; 5525}) 5526 5527(define_expand "floatuns<QHI:mode><FP_ISA3:mode>2" 5528 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") 5529 (unsigned_float:FP_ISA3 5530 (match_operand:QHI 1 "input_operand" ""))) 5531 (clobber (match_scratch:DI 2 "")) 5532 (clobber (match_scratch:DI 3 ""))])] 5533 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64 5534 && TARGET_VSX_SMALL_INTEGER" 5535{ 5536 if (MEM_P (operands[1])) 5537 operands[1] = rs6000_address_for_fpconvert (operands[1]); 5538}) 5539 5540(define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal" 5541 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>") 5542 (unsigned_float:FP_ISA3 5543 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z"))) 5544 (clobber (match_scratch:DI 2 "=wK,wi,wJwK")) 5545 (clobber (match_scratch:DI 3 "=X,r,X"))] 5546 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64 5547 && TARGET_VSX_SMALL_INTEGER" 5548 "#" 5549 "&& reload_completed" 5550 [(const_int 0)] 5551{ 5552 rtx result = operands[0]; 5553 rtx input = operands[1]; 5554 rtx di = operands[2]; 5555 5556 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode)) 5557 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input)); 5558 else 5559 { 5560 rtx tmp = operands[3]; 5561 if (GET_CODE (tmp) == SCRATCH) 5562 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5563 else 5564 { 5565 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input)); 5566 emit_move_insn (di, tmp); 5567 } 5568 } 5569 5570 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); 5571 DONE; 5572}) 5573 5574(define_expand "fix_trunc<mode>si2" 5575 [(set (match_operand:SI 0 "gpc_reg_operand" "") 5576 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))] 5577 "TARGET_HARD_FLOAT && ((TARGET_FPRS && <TARGET_FLOAT>) || <E500_CONVERT>)" 5578 " 5579{ 5580 if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER) 5581 { 5582 rtx src = force_reg (<MODE>mode, operands[1]); 5583 5584 if (TARGET_STFIWX) 5585 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src)); 5586 else 5587 { 5588 rtx tmp = gen_reg_rtx (DImode); 5589 rtx stack = rs6000_allocate_stack_temp (DImode, true, false); 5590 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src, 5591 tmp, stack)); 5592 } 5593 DONE; 5594 } 5595}") 5596 5597; Like the convert to float patterns, this insn must be split before 5598; register allocation so that it can allocate the memory slot if it 5599; needed 5600(define_insn_and_split "fix_trunc<mode>si2_stfiwx" 5601 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5602 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 5603 (clobber (match_scratch:DI 2 "=d"))] 5604 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5605 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT) 5606 && TARGET_STFIWX && can_create_pseudo_p () 5607 && !TARGET_VSX_SMALL_INTEGER" 5608 "#" 5609 "" 5610 [(pc)] 5611{ 5612 rtx dest = operands[0]; 5613 rtx src = operands[1]; 5614 rtx tmp = operands[2]; 5615 5616 if (GET_CODE (tmp) == SCRATCH) 5617 tmp = gen_reg_rtx (DImode); 5618 5619 emit_insn (gen_fctiwz_<mode> (tmp, src)); 5620 if (MEM_P (dest)) 5621 { 5622 dest = rs6000_address_for_fpconvert (dest); 5623 emit_insn (gen_stfiwx (dest, tmp)); 5624 DONE; 5625 } 5626 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5627 { 5628 dest = gen_lowpart (DImode, dest); 5629 emit_move_insn (dest, tmp); 5630 DONE; 5631 } 5632 else 5633 { 5634 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5635 emit_insn (gen_stfiwx (stack, tmp)); 5636 emit_move_insn (dest, stack); 5637 DONE; 5638 } 5639} 5640 [(set_attr "length" "12") 5641 (set_attr "type" "fp")]) 5642 5643(define_insn_and_split "fix_trunc<mode>si2_internal" 5644 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r") 5645 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>"))) 5646 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d")) 5647 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))] 5648 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5649 && !TARGET_VSX_SMALL_INTEGER" 5650 "#" 5651 "" 5652 [(pc)] 5653 " 5654{ 5655 rtx lowword; 5656 gcc_assert (MEM_P (operands[3])); 5657 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 5658 5659 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1])); 5660 emit_move_insn (operands[3], operands[2]); 5661 emit_move_insn (operands[0], lowword); 5662 DONE; 5663}" 5664 [(set_attr "length" "16") 5665 (set_attr "type" "fp")]) 5666 5667(define_expand "fix_trunc<mode>di2" 5668 [(set (match_operand:DI 0 "gpc_reg_operand" "") 5669 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))] 5670 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS 5671 && TARGET_FCFID" 5672 "") 5673 5674(define_insn "*fix_trunc<mode>di2_fctidz" 5675 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5676 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 5677 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS 5678 && TARGET_FCFID" 5679 "@ 5680 fctidz %0,%1 5681 xscvdpsxds %x0,%x1" 5682 [(set_attr "type" "fp")]) 5683 5684(define_expand "fix_trunc<SFDF:mode><QHI:mode>2" 5685 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand") 5686 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand"))) 5687 (clobber (match_scratch:DI 2))])] 5688 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT 5689 && TARGET_VSX_SMALL_INTEGER" 5690{ 5691 if (MEM_P (operands[0])) 5692 operands[0] = rs6000_address_for_fpconvert (operands[0]); 5693}) 5694 5695(define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal" 5696 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ") 5697 (fix:QHI 5698 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5699 (clobber (match_scratch:DI 2 "=X,wi"))] 5700 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT 5701 && TARGET_VSX_SMALL_INTEGER" 5702 "#" 5703 "&& reload_completed" 5704 [(const_int 0)] 5705{ 5706 rtx dest = operands[0]; 5707 rtx src = operands[1]; 5708 5709 if (vsx_register_operand (dest, <QHI:MODE>mode)) 5710 { 5711 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest)); 5712 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src)); 5713 } 5714 else 5715 { 5716 rtx tmp = operands[2]; 5717 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp)); 5718 5719 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src)); 5720 emit_move_insn (dest, tmp2); 5721 } 5722 DONE; 5723}) 5724 5725(define_expand "fixuns_trunc<mode>si2" 5726 [(set (match_operand:SI 0 "gpc_reg_operand" "") 5727 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))] 5728 "TARGET_HARD_FLOAT 5729 && ((TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX) 5730 || <E500_CONVERT>)" 5731 " 5732{ 5733 if (!<E500_CONVERT> && !TARGET_VSX_SMALL_INTEGER) 5734 { 5735 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1])); 5736 DONE; 5737 } 5738}") 5739 5740(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx" 5741 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5742 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 5743 (clobber (match_scratch:DI 2 "=d"))] 5744 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ 5745 && TARGET_STFIWX && can_create_pseudo_p () 5746 && !TARGET_VSX_SMALL_INTEGER" 5747 "#" 5748 "" 5749 [(pc)] 5750{ 5751 rtx dest = operands[0]; 5752 rtx src = operands[1]; 5753 rtx tmp = operands[2]; 5754 5755 if (GET_CODE (tmp) == SCRATCH) 5756 tmp = gen_reg_rtx (DImode); 5757 5758 emit_insn (gen_fctiwuz_<mode> (tmp, src)); 5759 if (MEM_P (dest)) 5760 { 5761 dest = rs6000_address_for_fpconvert (dest); 5762 emit_insn (gen_stfiwx (dest, tmp)); 5763 DONE; 5764 } 5765 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE)) 5766 { 5767 dest = gen_lowpart (DImode, dest); 5768 emit_move_insn (dest, tmp); 5769 DONE; 5770 } 5771 else 5772 { 5773 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5774 emit_insn (gen_stfiwx (stack, tmp)); 5775 emit_move_insn (dest, stack); 5776 DONE; 5777 } 5778} 5779 [(set_attr "length" "12") 5780 (set_attr "type" "fp")]) 5781 5782(define_insn "fixuns_trunc<mode>di2" 5783 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5784 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 5785 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCTIDUZ" 5786 "@ 5787 fctiduz %0,%1 5788 xscvdpuxds %x0,%x1" 5789 [(set_attr "type" "fp")]) 5790 5791(define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2" 5792 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand") 5793 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand"))) 5794 (clobber (match_scratch:DI 2))])] 5795 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT 5796 && TARGET_VSX_SMALL_INTEGER" 5797{ 5798 if (MEM_P (operands[0])) 5799 operands[0] = rs6000_address_for_fpconvert (operands[0]); 5800}) 5801 5802(define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal" 5803 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ") 5804 (unsigned_fix:QHI 5805 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5806 (clobber (match_scratch:DI 2 "=X,wi"))] 5807 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT 5808 && TARGET_VSX_SMALL_INTEGER" 5809 "#" 5810 "&& reload_completed" 5811 [(const_int 0)] 5812{ 5813 rtx dest = operands[0]; 5814 rtx src = operands[1]; 5815 5816 if (vsx_register_operand (dest, <QHI:MODE>mode)) 5817 { 5818 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest)); 5819 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src)); 5820 } 5821 else 5822 { 5823 rtx tmp = operands[2]; 5824 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp)); 5825 5826 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src)); 5827 emit_move_insn (dest, tmp2); 5828 } 5829 DONE; 5830}) 5831 5832;; If -mvsx-small-integer, we can represent the FIX operation directly. On 5833;; older machines, we have to use an UNSPEC to produce a SImode and move it 5834;; to another location, since SImode is not allowed in vector registers. 5835(define_insn "*fctiw<u>z_<mode>_smallint" 5836 [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi") 5837 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 5838 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5839 && TARGET_VSX_SMALL_INTEGER" 5840 "@ 5841 fctiw<u>z %0,%1 5842 xscvdp<su>xws %x0,%x1" 5843 [(set_attr "type" "fp")]) 5844 5845;; Combiner pattern to prevent moving the result of converting a floating point 5846;; value to 32-bit integer to GPR in order to save it. 5847(define_insn_and_split "*fctiw<u>z_<mode>_mem" 5848 [(set (match_operand:SI 0 "memory_operand" "=Z") 5849 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa"))) 5850 (clobber (match_scratch:SI 2 "=wa"))] 5851 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5852 && TARGET_VSX_SMALL_INTEGER" 5853 "#" 5854 "&& reload_completed" 5855 [(set (match_dup 2) 5856 (any_fix:SI (match_dup 1))) 5857 (set (match_dup 0) 5858 (match_dup 2))]) 5859 5860;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) 5861;; rather than (set (subreg:SI (reg)) (fix:SI ...)) 5862;; because the first makes it clear that operand 0 is not live 5863;; before the instruction. 5864(define_insn "fctiwz_<mode>" 5865 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5866 (unspec:DI [(fix:SI 5867 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 5868 UNSPEC_FCTIWZ))] 5869 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT" 5870 "@ 5871 fctiwz %0,%1 5872 xscvdpsxws %x0,%x1" 5873 [(set_attr "type" "fp")]) 5874 5875(define_insn "fctiwuz_<mode>" 5876 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi") 5877 (unspec:DI [(unsigned_fix:SI 5878 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 5879 UNSPEC_FCTIWUZ))] 5880 "TARGET_HARD_FLOAT && TARGET_FPRS && <TARGET_FLOAT> && TARGET_FCTIWUZ" 5881 "@ 5882 fctiwuz %0,%1 5883 xscvdpuxws %x0,%x1" 5884 [(set_attr "type" "fp")]) 5885 5886;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since 5887;; since the friz instruction does not truncate the value if the floating 5888;; point value is < LONG_MIN or > LONG_MAX. 5889(define_insn "*friz" 5890 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 5891 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))] 5892 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_FPRND 5893 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ" 5894 "@ 5895 friz %0,%1 5896 xsrdpiz %x0,%x1" 5897 [(set_attr "type" "fp")]) 5898 5899;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This 5900;; optimization prevents on ISA 2.06 systems and earlier having to store the 5901;; value from the FPR/vector unit to the stack, load the value into a GPR, sign 5902;; extend it, store it back on the stack from the GPR, load it back into the 5903;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07), 5904;; disable using store and load to sign/zero extend the value. 5905(define_insn_and_split "*round32<mode>2_fprs" 5906 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 5907 (float:SFDF 5908 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 5909 (clobber (match_scratch:DI 2 "=d")) 5910 (clobber (match_scratch:DI 3 "=d"))] 5911 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5912 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID 5913 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()" 5914 "#" 5915 "" 5916 [(pc)] 5917{ 5918 rtx dest = operands[0]; 5919 rtx src = operands[1]; 5920 rtx tmp1 = operands[2]; 5921 rtx tmp2 = operands[3]; 5922 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5923 5924 if (GET_CODE (tmp1) == SCRATCH) 5925 tmp1 = gen_reg_rtx (DImode); 5926 if (GET_CODE (tmp2) == SCRATCH) 5927 tmp2 = gen_reg_rtx (DImode); 5928 5929 emit_insn (gen_fctiwz_<mode> (tmp1, src)); 5930 emit_insn (gen_stfiwx (stack, tmp1)); 5931 emit_insn (gen_lfiwax (tmp2, stack)); 5932 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 5933 DONE; 5934} 5935 [(set_attr "type" "fpload") 5936 (set_attr "length" "16")]) 5937 5938(define_insn_and_split "*roundu32<mode>2_fprs" 5939 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 5940 (unsigned_float:SFDF 5941 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 5942 (clobber (match_scratch:DI 2 "=d")) 5943 (clobber (match_scratch:DI 3 "=d"))] 5944 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 5945 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE 5946 && can_create_pseudo_p ()" 5947 "#" 5948 "" 5949 [(pc)] 5950{ 5951 rtx dest = operands[0]; 5952 rtx src = operands[1]; 5953 rtx tmp1 = operands[2]; 5954 rtx tmp2 = operands[3]; 5955 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5956 5957 if (GET_CODE (tmp1) == SCRATCH) 5958 tmp1 = gen_reg_rtx (DImode); 5959 if (GET_CODE (tmp2) == SCRATCH) 5960 tmp2 = gen_reg_rtx (DImode); 5961 5962 emit_insn (gen_fctiwuz_<mode> (tmp1, src)); 5963 emit_insn (gen_stfiwx (stack, tmp1)); 5964 emit_insn (gen_lfiwzx (tmp2, stack)); 5965 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 5966 DONE; 5967} 5968 [(set_attr "type" "fpload") 5969 (set_attr "length" "16")]) 5970 5971;; No VSX equivalent to fctid 5972(define_insn "lrint<mode>di2" 5973 [(set (match_operand:DI 0 "gpc_reg_operand" "=d") 5974 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 5975 UNSPEC_FCTID))] 5976 "TARGET_<MODE>_FPR && TARGET_FPRND" 5977 "fctid %0,%1" 5978 [(set_attr "type" "fp")]) 5979 5980(define_insn "btrunc<mode>2" 5981 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5982 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 5983 UNSPEC_FRIZ))] 5984 "TARGET_<MODE>_FPR && TARGET_FPRND" 5985 "@ 5986 friz %0,%1 5987 xsrdpiz %x0,%x1" 5988 [(set_attr "type" "fp") 5989 (set_attr "fp_type" "fp_addsub_<Fs>")]) 5990 5991(define_insn "ceil<mode>2" 5992 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5993 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 5994 UNSPEC_FRIP))] 5995 "TARGET_<MODE>_FPR && TARGET_FPRND" 5996 "@ 5997 frip %0,%1 5998 xsrdpip %x0,%x1" 5999 [(set_attr "type" "fp") 6000 (set_attr "fp_type" "fp_addsub_<Fs>")]) 6001 6002(define_insn "floor<mode>2" 6003 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 6004 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 6005 UNSPEC_FRIM))] 6006 "TARGET_<MODE>_FPR && TARGET_FPRND" 6007 "@ 6008 frim %0,%1 6009 xsrdpim %x0,%x1" 6010 [(set_attr "type" "fp") 6011 (set_attr "fp_type" "fp_addsub_<Fs>")]) 6012 6013;; No VSX equivalent to frin 6014(define_insn "round<mode>2" 6015 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") 6016 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 6017 UNSPEC_FRIN))] 6018 "TARGET_<MODE>_FPR && TARGET_FPRND" 6019 "frin %0,%1" 6020 [(set_attr "type" "fp") 6021 (set_attr "fp_type" "fp_addsub_<Fs>")]) 6022 6023(define_insn "*xsrdpi<mode>2" 6024 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 6025 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")] 6026 UNSPEC_XSRDPI))] 6027 "TARGET_<MODE>_FPR && TARGET_VSX" 6028 "xsrdpi %x0,%x1" 6029 [(set_attr "type" "fp") 6030 (set_attr "fp_type" "fp_addsub_<Fs>")]) 6031 6032(define_expand "lround<mode>di2" 6033 [(set (match_dup 2) 6034 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")] 6035 UNSPEC_XSRDPI)) 6036 (set (match_operand:DI 0 "gpc_reg_operand" "") 6037 (unspec:DI [(match_dup 2)] 6038 UNSPEC_FCTID))] 6039 "TARGET_<MODE>_FPR && TARGET_VSX" 6040{ 6041 operands[2] = gen_reg_rtx (<MODE>mode); 6042}) 6043 6044; An UNSPEC is used so we don't have to support SImode in FP registers. 6045; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx 6046; is only generated for Power8 or later. 6047(define_insn "stfiwx" 6048 [(set (match_operand:SI 0 "memory_operand" "=Z,Z") 6049 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")] 6050 UNSPEC_STFIWX))] 6051 "TARGET_PPC_GFXOPT" 6052 "@ 6053 stfiwx %1,%y0 6054 stxsiwx %x1,%y0" 6055 [(set_attr "type" "fpstore")]) 6056 6057;; If we don't have a direct conversion to single precision, don't enable this 6058;; conversion for 32-bit without fast math, because we don't have the insn to 6059;; generate the fixup swizzle to avoid double rounding problems. 6060(define_expand "floatsisf2" 6061 [(set (match_operand:SF 0 "gpc_reg_operand" "") 6062 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))] 6063 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT 6064 && (!TARGET_FPRS 6065 || (TARGET_FPRS 6066 && ((TARGET_FCFIDS && TARGET_LFIWAX) 6067 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID 6068 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))))" 6069 " 6070{ 6071 if (!TARGET_FPRS) 6072 { 6073 if (!REG_P (operands[1])) 6074 operands[1] = force_reg (SImode, operands[1]); 6075 } 6076 else if (TARGET_FCFIDS && TARGET_LFIWAX) 6077 { 6078 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1])); 6079 DONE; 6080 } 6081 else if (TARGET_FCFID && TARGET_LFIWAX) 6082 { 6083 rtx dfreg = gen_reg_rtx (DFmode); 6084 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1])); 6085 emit_insn (gen_truncdfsf2 (operands[0], dfreg)); 6086 DONE; 6087 } 6088 else 6089 { 6090 rtx dreg = operands[1]; 6091 if (!REG_P (dreg)) 6092 dreg = force_reg (SImode, dreg); 6093 dreg = convert_to_mode (DImode, dreg, false); 6094 emit_insn (gen_floatdisf2 (operands[0], dreg)); 6095 DONE; 6096 } 6097}") 6098 6099(define_expand "floatdidf2" 6100 [(set (match_operand:DF 0 "gpc_reg_operand" "") 6101 (float:DF (match_operand:DI 1 "gpc_reg_operand" "")))] 6102 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" 6103 "") 6104 6105(define_insn "*floatdidf2_fpr" 6106 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 6107 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 6108 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS" 6109 "@ 6110 fcfid %0,%1 6111 xscvsxddp %x0,%x1" 6112 [(set_attr "type" "fp")]) 6113 6114; Allow the combiner to merge source memory operands to the conversion so that 6115; the optimizer/register allocator doesn't try to load the value too early in a 6116; GPR and then use store/load to move it to a FPR and suffer from a store-load 6117; hit. We will split after reload to avoid the trip through the GPRs 6118 6119(define_insn_and_split "*floatdidf2_mem" 6120 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 6121 (float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 6122 (clobber (match_scratch:DI 2 "=d,wi"))] 6123 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRS && TARGET_FCFID" 6124 "#" 6125 "&& reload_completed" 6126 [(set (match_dup 2) (match_dup 1)) 6127 (set (match_dup 0) (float:DF (match_dup 2)))] 6128 "" 6129 [(set_attr "length" "8") 6130 (set_attr "type" "fpload")]) 6131 6132(define_expand "floatunsdidf2" 6133 [(set (match_operand:DF 0 "gpc_reg_operand" "") 6134 (unsigned_float:DF 6135 (match_operand:DI 1 "gpc_reg_operand" "")))] 6136 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 6137 "") 6138 6139(define_insn "*floatunsdidf2_fcfidu" 6140 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 6141 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 6142 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 6143 "@ 6144 fcfidu %0,%1 6145 xscvuxddp %x0,%x1" 6146 [(set_attr "type" "fp") 6147 (set_attr "length" "4")]) 6148 6149(define_insn_and_split "*floatunsdidf2_mem" 6150 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws") 6151 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 6152 (clobber (match_scratch:DI 2 "=d,wi"))] 6153 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))" 6154 "#" 6155 "&& reload_completed" 6156 [(set (match_dup 2) (match_dup 1)) 6157 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))] 6158 "" 6159 [(set_attr "length" "8") 6160 (set_attr "type" "fpload")]) 6161 6162(define_expand "floatdisf2" 6163 [(set (match_operand:SF 0 "gpc_reg_operand" "") 6164 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] 6165 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 6166 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)" 6167 " 6168{ 6169 if (!TARGET_FCFIDS) 6170 { 6171 rtx val = operands[1]; 6172 if (!flag_unsafe_math_optimizations) 6173 { 6174 rtx label = gen_label_rtx (); 6175 val = gen_reg_rtx (DImode); 6176 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label)); 6177 emit_label (label); 6178 } 6179 emit_insn (gen_floatdisf2_internal1 (operands[0], val)); 6180 DONE; 6181 } 6182}") 6183 6184(define_insn "floatdisf2_fcfids" 6185 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy") 6186 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 6187 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 6188 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS" 6189 "@ 6190 fcfids %0,%1 6191 xscvsxdsp %x0,%x1" 6192 [(set_attr "type" "fp")]) 6193 6194(define_insn_and_split "*floatdisf2_mem" 6195 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy") 6196 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 6197 (clobber (match_scratch:DI 2 "=d,d,wi"))] 6198 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 6199 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS" 6200 "#" 6201 "&& reload_completed" 6202 [(pc)] 6203 " 6204{ 6205 emit_move_insn (operands[2], operands[1]); 6206 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2])); 6207 DONE; 6208}" 6209 [(set_attr "length" "8")]) 6210 6211;; This is not IEEE compliant if rounding mode is "round to nearest". 6212;; If the DI->DF conversion is inexact, then it's possible to suffer 6213;; from double rounding. 6214;; Instead of creating a new cpu type for two FP operations, just use fp 6215(define_insn_and_split "floatdisf2_internal1" 6216 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 6217 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d"))) 6218 (clobber (match_scratch:DF 2 "=d"))] 6219 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 6220 && !TARGET_FCFIDS" 6221 "#" 6222 "&& reload_completed" 6223 [(set (match_dup 2) 6224 (float:DF (match_dup 1))) 6225 (set (match_dup 0) 6226 (float_truncate:SF (match_dup 2)))] 6227 "" 6228 [(set_attr "length" "8") 6229 (set_attr "type" "fp")]) 6230 6231;; Twiddles bits to avoid double rounding. 6232;; Bits that might be truncated when converting to DFmode are replaced 6233;; by a bit that won't be lost at that stage, but is below the SFmode 6234;; rounding position. 6235(define_expand "floatdisf2_internal2" 6236 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "") 6237 (const_int 53))) 6238 (clobber (reg:DI CA_REGNO))]) 6239 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1) 6240 (const_int 2047))) 6241 (set (match_dup 3) (plus:DI (match_dup 3) 6242 (const_int 1))) 6243 (set (match_dup 0) (plus:DI (match_dup 0) 6244 (const_int 2047))) 6245 (set (match_dup 4) (compare:CCUNS (match_dup 3) 6246 (const_int 2))) 6247 (set (match_dup 0) (ior:DI (match_dup 0) 6248 (match_dup 1))) 6249 (set (match_dup 0) (and:DI (match_dup 0) 6250 (const_int -2048))) 6251 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) 6252 (label_ref (match_operand:DI 2 "" "")) 6253 (pc))) 6254 (set (match_dup 0) (match_dup 1))] 6255 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 6256 && !TARGET_FCFIDS" 6257 " 6258{ 6259 operands[3] = gen_reg_rtx (DImode); 6260 operands[4] = gen_reg_rtx (CCUNSmode); 6261}") 6262 6263(define_expand "floatunsdisf2" 6264 [(set (match_operand:SF 0 "gpc_reg_operand" "") 6265 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))] 6266 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 6267 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" 6268 "") 6269 6270(define_insn "floatunsdisf2_fcfidus" 6271 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu") 6272 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))] 6273 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 6274 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" 6275 "@ 6276 fcfidus %0,%1 6277 xscvuxdsp %x0,%x1" 6278 [(set_attr "type" "fp")]) 6279 6280(define_insn_and_split "*floatunsdisf2_mem" 6281 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy") 6282 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 6283 (clobber (match_scratch:DI 2 "=d,d,wi"))] 6284 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 6285 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS" 6286 "#" 6287 "&& reload_completed" 6288 [(pc)] 6289 " 6290{ 6291 emit_move_insn (operands[2], operands[1]); 6292 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2])); 6293 DONE; 6294}" 6295 [(set_attr "length" "8") 6296 (set_attr "type" "fpload")]) 6297 6298;; Define the TImode operations that can be done in a small number 6299;; of instructions. The & constraints are to prevent the register 6300;; allocator from allocating registers that overlap with the inputs 6301;; (for example, having an input in 7,8 and an output in 6,7). We 6302;; also allow for the output being the same as one of the inputs. 6303 6304(define_expand "addti3" 6305 [(set (match_operand:TI 0 "gpc_reg_operand" "") 6306 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "") 6307 (match_operand:TI 2 "reg_or_short_operand" "")))] 6308 "TARGET_64BIT" 6309{ 6310 rtx lo0 = gen_lowpart (DImode, operands[0]); 6311 rtx lo1 = gen_lowpart (DImode, operands[1]); 6312 rtx lo2 = gen_lowpart (DImode, operands[2]); 6313 rtx hi0 = gen_highpart (DImode, operands[0]); 6314 rtx hi1 = gen_highpart (DImode, operands[1]); 6315 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]); 6316 6317 if (!reg_or_short_operand (lo2, DImode)) 6318 lo2 = force_reg (DImode, lo2); 6319 if (!adde_operand (hi2, DImode)) 6320 hi2 = force_reg (DImode, hi2); 6321 6322 emit_insn (gen_adddi3_carry (lo0, lo1, lo2)); 6323 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2)); 6324 DONE; 6325}) 6326 6327(define_expand "subti3" 6328 [(set (match_operand:TI 0 "gpc_reg_operand" "") 6329 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "") 6330 (match_operand:TI 2 "gpc_reg_operand" "")))] 6331 "TARGET_64BIT" 6332{ 6333 rtx lo0 = gen_lowpart (DImode, operands[0]); 6334 rtx lo1 = gen_lowpart (DImode, operands[1]); 6335 rtx lo2 = gen_lowpart (DImode, operands[2]); 6336 rtx hi0 = gen_highpart (DImode, operands[0]); 6337 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]); 6338 rtx hi2 = gen_highpart (DImode, operands[2]); 6339 6340 if (!reg_or_short_operand (lo1, DImode)) 6341 lo1 = force_reg (DImode, lo1); 6342 if (!adde_operand (hi1, DImode)) 6343 hi1 = force_reg (DImode, hi1); 6344 6345 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1)); 6346 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1)); 6347 DONE; 6348}) 6349 6350;; 128-bit logical operations expanders 6351 6352(define_expand "and<mode>3" 6353 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6354 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") 6355 (match_operand:BOOL_128 2 "vlogical_operand" "")))] 6356 "" 6357 "") 6358 6359(define_expand "ior<mode>3" 6360 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6361 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") 6362 (match_operand:BOOL_128 2 "vlogical_operand" "")))] 6363 "" 6364 "") 6365 6366(define_expand "xor<mode>3" 6367 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6368 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") 6369 (match_operand:BOOL_128 2 "vlogical_operand" "")))] 6370 "" 6371 "") 6372 6373(define_expand "one_cmpl<mode>2" 6374 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6375 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))] 6376 "" 6377 "") 6378 6379(define_expand "nor<mode>3" 6380 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6381 (and:BOOL_128 6382 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")) 6383 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))] 6384 "" 6385 "") 6386 6387(define_expand "andc<mode>3" 6388 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6389 (and:BOOL_128 6390 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" "")) 6391 (match_operand:BOOL_128 1 "vlogical_operand" "")))] 6392 "" 6393 "") 6394 6395;; Power8 vector logical instructions. 6396(define_expand "eqv<mode>3" 6397 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6398 (not:BOOL_128 6399 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "") 6400 (match_operand:BOOL_128 2 "vlogical_operand" ""))))] 6401 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6402 "") 6403 6404;; Rewrite nand into canonical form 6405(define_expand "nand<mode>3" 6406 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6407 (ior:BOOL_128 6408 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")) 6409 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))] 6410 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6411 "") 6412 6413;; The canonical form is to have the negated element first, so we need to 6414;; reverse arguments. 6415(define_expand "orc<mode>3" 6416 [(set (match_operand:BOOL_128 0 "vlogical_operand" "") 6417 (ior:BOOL_128 6418 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" "")) 6419 (match_operand:BOOL_128 1 "vlogical_operand" "")))] 6420 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6421 "") 6422 6423;; 128-bit logical operations insns and split operations 6424(define_insn_and_split "*and<mode>3_internal" 6425 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6426 (and:BOOL_128 6427 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 6428 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))] 6429 "" 6430{ 6431 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6432 return "xxland %x0,%x1,%x2"; 6433 6434 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6435 return "vand %0,%1,%2"; 6436 6437 return "#"; 6438} 6439 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6440 [(const_int 0)] 6441{ 6442 rs6000_split_logical (operands, AND, false, false, false); 6443 DONE; 6444} 6445 [(set (attr "type") 6446 (if_then_else 6447 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6448 (const_string "veclogical") 6449 (const_string "integer"))) 6450 (set (attr "length") 6451 (if_then_else 6452 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6453 (const_string "4") 6454 (if_then_else 6455 (match_test "TARGET_POWERPC64") 6456 (const_string "8") 6457 (const_string "16"))))]) 6458 6459;; 128-bit IOR/XOR 6460(define_insn_and_split "*bool<mode>3_internal" 6461 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6462 (match_operator:BOOL_128 3 "boolean_or_operator" 6463 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 6464 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))] 6465 "" 6466{ 6467 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6468 return "xxl%q3 %x0,%x1,%x2"; 6469 6470 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6471 return "v%q3 %0,%1,%2"; 6472 6473 return "#"; 6474} 6475 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6476 [(const_int 0)] 6477{ 6478 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false); 6479 DONE; 6480} 6481 [(set (attr "type") 6482 (if_then_else 6483 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6484 (const_string "veclogical") 6485 (const_string "integer"))) 6486 (set (attr "length") 6487 (if_then_else 6488 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6489 (const_string "4") 6490 (if_then_else 6491 (match_test "TARGET_POWERPC64") 6492 (const_string "8") 6493 (const_string "16"))))]) 6494 6495;; 128-bit ANDC/ORC 6496(define_insn_and_split "*boolc<mode>3_internal1" 6497 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6498 (match_operator:BOOL_128 3 "boolean_operator" 6499 [(not:BOOL_128 6500 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")) 6501 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))] 6502 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 6503{ 6504 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6505 return "xxl%q3 %x0,%x1,%x2"; 6506 6507 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6508 return "v%q3 %0,%1,%2"; 6509 6510 return "#"; 6511} 6512 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 6513 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6514 [(const_int 0)] 6515{ 6516 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 6517 DONE; 6518} 6519 [(set (attr "type") 6520 (if_then_else 6521 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6522 (const_string "veclogical") 6523 (const_string "integer"))) 6524 (set (attr "length") 6525 (if_then_else 6526 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6527 (const_string "4") 6528 (if_then_else 6529 (match_test "TARGET_POWERPC64") 6530 (const_string "8") 6531 (const_string "16"))))]) 6532 6533(define_insn_and_split "*boolc<mode>3_internal2" 6534 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6535 (match_operator:TI2 3 "boolean_operator" 6536 [(not:TI2 6537 (match_operand:TI2 2 "int_reg_operand" "r,0,r")) 6538 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))] 6539 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6540 "#" 6541 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6542 [(const_int 0)] 6543{ 6544 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 6545 DONE; 6546} 6547 [(set_attr "type" "integer") 6548 (set (attr "length") 6549 (if_then_else 6550 (match_test "TARGET_POWERPC64") 6551 (const_string "8") 6552 (const_string "16")))]) 6553 6554;; 128-bit NAND/NOR 6555(define_insn_and_split "*boolcc<mode>3_internal1" 6556 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6557 (match_operator:BOOL_128 3 "boolean_operator" 6558 [(not:BOOL_128 6559 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")) 6560 (not:BOOL_128 6561 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))] 6562 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 6563{ 6564 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6565 return "xxl%q3 %x0,%x1,%x2"; 6566 6567 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6568 return "v%q3 %0,%1,%2"; 6569 6570 return "#"; 6571} 6572 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 6573 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6574 [(const_int 0)] 6575{ 6576 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 6577 DONE; 6578} 6579 [(set (attr "type") 6580 (if_then_else 6581 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6582 (const_string "veclogical") 6583 (const_string "integer"))) 6584 (set (attr "length") 6585 (if_then_else 6586 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6587 (const_string "4") 6588 (if_then_else 6589 (match_test "TARGET_POWERPC64") 6590 (const_string "8") 6591 (const_string "16"))))]) 6592 6593(define_insn_and_split "*boolcc<mode>3_internal2" 6594 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6595 (match_operator:TI2 3 "boolean_operator" 6596 [(not:TI2 6597 (match_operand:TI2 1 "int_reg_operand" "r,0,r")) 6598 (not:TI2 6599 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))] 6600 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6601 "#" 6602 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6603 [(const_int 0)] 6604{ 6605 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 6606 DONE; 6607} 6608 [(set_attr "type" "integer") 6609 (set (attr "length") 6610 (if_then_else 6611 (match_test "TARGET_POWERPC64") 6612 (const_string "8") 6613 (const_string "16")))]) 6614 6615 6616;; 128-bit EQV 6617(define_insn_and_split "*eqv<mode>3_internal1" 6618 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6619 (not:BOOL_128 6620 (xor:BOOL_128 6621 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>") 6622 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))] 6623 "TARGET_P8_VECTOR" 6624{ 6625 if (vsx_register_operand (operands[0], <MODE>mode)) 6626 return "xxleqv %x0,%x1,%x2"; 6627 6628 return "#"; 6629} 6630 "TARGET_P8_VECTOR && reload_completed 6631 && int_reg_operand (operands[0], <MODE>mode)" 6632 [(const_int 0)] 6633{ 6634 rs6000_split_logical (operands, XOR, true, false, false); 6635 DONE; 6636} 6637 [(set (attr "type") 6638 (if_then_else 6639 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6640 (const_string "veclogical") 6641 (const_string "integer"))) 6642 (set (attr "length") 6643 (if_then_else 6644 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6645 (const_string "4") 6646 (if_then_else 6647 (match_test "TARGET_POWERPC64") 6648 (const_string "8") 6649 (const_string "16"))))]) 6650 6651(define_insn_and_split "*eqv<mode>3_internal2" 6652 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6653 (not:TI2 6654 (xor:TI2 6655 (match_operand:TI2 1 "int_reg_operand" "r,0,r") 6656 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))] 6657 "!TARGET_P8_VECTOR" 6658 "#" 6659 "reload_completed && !TARGET_P8_VECTOR" 6660 [(const_int 0)] 6661{ 6662 rs6000_split_logical (operands, XOR, true, false, false); 6663 DONE; 6664} 6665 [(set_attr "type" "integer") 6666 (set (attr "length") 6667 (if_then_else 6668 (match_test "TARGET_POWERPC64") 6669 (const_string "8") 6670 (const_string "16")))]) 6671 6672;; 128-bit one's complement 6673(define_insn_and_split "*one_cmpl<mode>3_internal" 6674 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6675 (not:BOOL_128 6676 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))] 6677 "" 6678{ 6679 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6680 return "xxlnor %x0,%x1,%x1"; 6681 6682 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6683 return "vnor %0,%1,%1"; 6684 6685 return "#"; 6686} 6687 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6688 [(const_int 0)] 6689{ 6690 rs6000_split_logical (operands, NOT, false, false, false); 6691 DONE; 6692} 6693 [(set (attr "type") 6694 (if_then_else 6695 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6696 (const_string "veclogical") 6697 (const_string "integer"))) 6698 (set (attr "length") 6699 (if_then_else 6700 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6701 (const_string "4") 6702 (if_then_else 6703 (match_test "TARGET_POWERPC64") 6704 (const_string "8") 6705 (const_string "16"))))]) 6706 6707 6708;; Now define ways of moving data around. 6709 6710;; Set up a register with a value from the GOT table 6711 6712(define_expand "movsi_got" 6713 [(set (match_operand:SI 0 "gpc_reg_operand" "") 6714 (unspec:SI [(match_operand:SI 1 "got_operand" "") 6715 (match_dup 2)] UNSPEC_MOVSI_GOT))] 6716 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 6717 " 6718{ 6719 if (GET_CODE (operands[1]) == CONST) 6720 { 6721 rtx offset = const0_rtx; 6722 HOST_WIDE_INT value; 6723 6724 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset); 6725 value = INTVAL (offset); 6726 if (value != 0) 6727 { 6728 rtx tmp = (!can_create_pseudo_p () 6729 ? operands[0] 6730 : gen_reg_rtx (Pmode)); 6731 emit_insn (gen_movsi_got (tmp, operands[1])); 6732 emit_insn (gen_addsi3 (operands[0], tmp, offset)); 6733 DONE; 6734 } 6735 } 6736 6737 operands[2] = rs6000_got_register (operands[1]); 6738}") 6739 6740(define_insn "*movsi_got_internal" 6741 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 6742 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") 6743 (match_operand:SI 2 "gpc_reg_operand" "b")] 6744 UNSPEC_MOVSI_GOT))] 6745 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 6746 "lwz %0,%a1@got(%2)" 6747 [(set_attr "type" "load")]) 6748 6749;; Used by sched, shorten_branches and final when the GOT pseudo reg 6750;; didn't get allocated to a hard register. 6751(define_split 6752 [(set (match_operand:SI 0 "gpc_reg_operand" "") 6753 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") 6754 (match_operand:SI 2 "memory_operand" "")] 6755 UNSPEC_MOVSI_GOT))] 6756 "DEFAULT_ABI == ABI_V4 6757 && flag_pic == 1 6758 && (reload_in_progress || reload_completed)" 6759 [(set (match_dup 0) (match_dup 2)) 6760 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 6761 UNSPEC_MOVSI_GOT))] 6762 "") 6763 6764;; For SI, we special-case integers that can't be loaded in one insn. We 6765;; do the load 16-bits at a time. We could do this by loading from memory, 6766;; and this is even supposed to be faster, but it is simpler not to get 6767;; integers in the TOC. 6768(define_insn "movsi_low" 6769 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 6770 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 6771 (match_operand 2 "" ""))))] 6772 "TARGET_MACHO && ! TARGET_64BIT" 6773 "lwz %0,lo16(%2)(%1)" 6774 [(set_attr "type" "load") 6775 (set_attr "length" "4")]) 6776 6777;; MR LA LWZ LFIWZX LXSIWZX 6778;; STW STFIWX STXSIWX LI LIS 6779;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW 6780;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ 6781;; MF%1 MT%0 MT%0 NOP 6782(define_insn "*movsi_internal1" 6783 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" 6784 "=r, r, r, ?*wI, ?*wH, 6785 m, ?Z, ?Z, r, r, 6786 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu, 6787 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r, 6788 r, *c*l, *h, *h") 6789 6790 (match_operand:SI 1 "input_operand" 6791 "r, U, m, Z, Z, 6792 r, wI, wH, I, L, 6793 n, wIwH, O, wM, wB, 6794 O, wM, wS, r, wIwH, 6795 *h, r, r, 0"))] 6796 6797 "!TARGET_SINGLE_FPU && 6798 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" 6799 "@ 6800 mr %0,%1 6801 la %0,%a1 6802 lwz%U1%X1 %0,%1 6803 lfiwzx %0,%y1 6804 lxsiwzx %x0,%y1 6805 stw%U0%X0 %1,%0 6806 stfiwx %1,%y0 6807 stxsiwx %x1,%y0 6808 li %0,%1 6809 lis %0,%v1 6810 # 6811 xxlor %x0,%x1,%x1 6812 xxspltib %x0,0 6813 xxspltib %x0,255 6814 vspltisw %0,%1 6815 xxlxor %x0,%x0,%x0 6816 xxlorc %x0,%x0,%x0 6817 # 6818 mtvsrwz %x0,%1 6819 mfvsrwz %0,%x1 6820 mf%1 %0 6821 mt%0 %1 6822 mt%0 %1 6823 nop" 6824 [(set_attr "type" 6825 "*, *, load, fpload, fpload, 6826 store, fpstore, fpstore, *, *, 6827 *, veclogical, vecsimple, vecsimple, vecsimple, 6828 veclogical, veclogical, vecsimple, mffgpr, mftgpr, 6829 *, *, *, *") 6830 6831 (set_attr "length" 6832 "4, 4, 4, 4, 4, 6833 4, 4, 4, 4, 4, 6834 8, 4, 4, 4, 4, 6835 4, 4, 8, 4, 4, 6836 4, 4, 4, 4")]) 6837 6838(define_insn "*movsi_internal1_single" 6839 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f") 6840 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))] 6841 "TARGET_SINGLE_FPU && 6842 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))" 6843 "@ 6844 mr %0,%1 6845 la %0,%a1 6846 lwz%U1%X1 %0,%1 6847 stw%U0%X0 %1,%0 6848 li %0,%1 6849 lis %0,%v1 6850 # 6851 mf%1 %0 6852 mt%0 %1 6853 mt%0 %1 6854 nop 6855 stfs%U0%X0 %1,%0 6856 lfs%U1%X1 %0,%1" 6857 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload") 6858 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")]) 6859 6860;; Like movsi, but adjust a SF value to be used in a SI context, i.e. 6861;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0)) 6862;; 6863;; Because SF values are actually stored as DF values within the vector 6864;; registers, we need to convert the value to the vector SF format when 6865;; we need to use the bits in a union or similar cases. We only need 6866;; to do this transformation when the value is a vector register. Loads, 6867;; stores, and transfers within GPRs are assumed to be safe. 6868;; 6869;; This is a more general case of reload_gpr_from_vsxsf. That insn must have 6870;; no alternatives, because the call is created as part of secondary_reload, 6871;; and operand #2's register class is used to allocate the temporary register. 6872;; This function is called before reload, and it creates the temporary as 6873;; needed. 6874 6875;; MR LWZ LFIWZX LXSIWZX STW 6876;; STFS STXSSP STXSSPX VSX->GPR MTVSRWZ 6877;; VSX->VSX 6878 6879(define_insn_and_split "movsi_from_sf" 6880 [(set (match_operand:SI 0 "rs6000_nonimmediate_operand" 6881 "=r, r, ?*wI, ?*wH, m, 6882 m, wY, Z, r, wIwH, 6883 ?wK") 6884 6885 (unspec:SI [(match_operand:SF 1 "input_operand" 6886 "r, m, Z, Z, r, 6887 f, wb, wu, wIwH, r, 6888 wK")] 6889 UNSPEC_SI_FROM_SF)) 6890 6891 (clobber (match_scratch:V4SF 2 6892 "=X, X, X, X, X, 6893 X, X, X, wa, X, 6894 wa"))] 6895 6896 "TARGET_NO_SF_SUBREG 6897 && (register_operand (operands[0], SImode) 6898 || register_operand (operands[1], SFmode))" 6899 "@ 6900 mr %0,%1 6901 lwz%U1%X1 %0,%1 6902 lfiwzx %0,%y1 6903 lxsiwzx %x0,%y1 6904 stw%U0%X0 %1,%0 6905 stfs%U0%X0 %1,%0 6906 stxssp %1,%0 6907 stxsspx %x1,%y0 6908 # 6909 mtvsrwz %x0,%1 6910 #" 6911 "&& reload_completed 6912 && register_operand (operands[0], SImode) 6913 && vsx_reg_sfsubreg_ok (operands[1], SFmode)" 6914 [(const_int 0)] 6915{ 6916 rtx op0 = operands[0]; 6917 rtx op1 = operands[1]; 6918 rtx op2 = operands[2]; 6919 rtx op0_di = gen_rtx_REG (DImode, REGNO (op0)); 6920 6921 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 6922 6923 if (int_reg_operand (op0, SImode)) 6924 { 6925 emit_insn (gen_p8_mfvsrd_4_disf (op0_di, op2)); 6926 emit_insn (gen_lshrdi3 (op0_di, op0_di, GEN_INT (32))); 6927 } 6928 else 6929 { 6930 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1)); 6931 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12); 6932 emit_insn (gen_vextract4b (op0_di, op1_v16qi, byte_off)); 6933 } 6934 6935 DONE; 6936} 6937 [(set_attr "type" 6938 "*, load, fpload, fpload, store, 6939 fpstore, fpstore, fpstore, mftgpr, mffgpr, 6940 veclogical") 6941 6942 (set_attr "length" 6943 "4, 4, 4, 4, 4, 6944 4, 4, 4, 12, 4, 6945 8")]) 6946 6947;; movsi_from_sf with zero extension 6948;; 6949;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR 6950;; MTVSRWZ VSX->VSX 6951 6952(define_insn_and_split "*movdi_from_sf_zero_ext" 6953 [(set (match_operand:DI 0 "gpc_reg_operand" 6954 "=r, r, ?*wI, ?*wH, r, 6955 wIwH, ?wK") 6956 6957 (zero_extend:DI 6958 (unspec:SI [(match_operand:SF 1 "input_operand" 6959 "r, m, Z, Z, wIwH, 6960 r, wK")] 6961 UNSPEC_SI_FROM_SF))) 6962 6963 (clobber (match_scratch:V4SF 2 6964 "=X, X, X, X, wa, 6965 X, wa"))] 6966 6967 "TARGET_DIRECT_MOVE_64BIT 6968 && (register_operand (operands[0], DImode) 6969 || register_operand (operands[1], SImode))" 6970 "@ 6971 rldicl %0,%1,0,32 6972 lwz%U1%X1 %0,%1 6973 lfiwzx %0,%y1 6974 lxsiwzx %x0,%y1 6975 # 6976 mtvsrwz %x0,%1 6977 #" 6978 "&& reload_completed 6979 && vsx_reg_sfsubreg_ok (operands[1], SFmode)" 6980 [(const_int 0)] 6981{ 6982 rtx op0 = operands[0]; 6983 rtx op1 = operands[1]; 6984 rtx op2 = operands[2]; 6985 6986 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 6987 6988 if (int_reg_operand (op0, DImode)) 6989 { 6990 emit_insn (gen_p8_mfvsrd_4_disf (op0, op2)); 6991 emit_insn (gen_lshrdi3 (op0, op0, GEN_INT (32))); 6992 } 6993 else 6994 { 6995 rtx op0_si = gen_rtx_REG (SImode, REGNO (op0)); 6996 rtx op1_v16qi = gen_rtx_REG (V16QImode, REGNO (op1)); 6997 rtx byte_off = VECTOR_ELT_ORDER_BIG ? const0_rtx : GEN_INT (12); 6998 emit_insn (gen_vextract4b (op0_si, op1_v16qi, byte_off)); 6999 } 7000 7001 DONE; 7002} 7003 [(set_attr "type" 7004 "*, load, fpload, fpload, mftgpr, 7005 mffgpr, veclogical") 7006 7007 (set_attr "length" 7008 "4, 4, 4, 4, 12, 7009 4, 8")]) 7010 7011;; Split a load of a large constant into the appropriate two-insn 7012;; sequence. 7013 7014(define_split 7015 [(set (match_operand:SI 0 "gpc_reg_operand" "") 7016 (match_operand:SI 1 "const_int_operand" ""))] 7017 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000 7018 && (INTVAL (operands[1]) & 0xffff) != 0" 7019 [(set (match_dup 0) 7020 (match_dup 2)) 7021 (set (match_dup 0) 7022 (ior:SI (match_dup 0) 7023 (match_dup 3)))] 7024 " 7025{ 7026 if (rs6000_emit_set_const (operands[0], operands[1])) 7027 DONE; 7028 else 7029 FAIL; 7030}") 7031 7032;; Split loading -128..127 to use XXSPLITB and VEXTSW2D 7033(define_split 7034 [(set (match_operand:DI 0 "altivec_register_operand") 7035 (match_operand:DI 1 "xxspltib_constant_split"))] 7036 "TARGET_VSX_SMALL_INTEGER && TARGET_P9_VECTOR && reload_completed" 7037 [(const_int 0)] 7038{ 7039 rtx op0 = operands[0]; 7040 rtx op1 = operands[1]; 7041 int r = REGNO (op0); 7042 rtx op0_v16qi = gen_rtx_REG (V16QImode, r); 7043 7044 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1)); 7045 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi)); 7046 DONE; 7047}) 7048 7049(define_insn "*mov<mode>_internal2" 7050 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y") 7051 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r") 7052 (const_int 0))) 7053 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))] 7054 "" 7055 "@ 7056 cmp<wd>i %2,%0,0 7057 mr. %0,%1 7058 #" 7059 [(set_attr "type" "cmp,logical,cmp") 7060 (set_attr "dot" "yes") 7061 (set_attr "length" "4,4,8")]) 7062 7063(define_split 7064 [(set (match_operand:CC 2 "cc_reg_not_micro_cr0_operand" "") 7065 (compare:CC (match_operand:P 1 "gpc_reg_operand" "") 7066 (const_int 0))) 7067 (set (match_operand:P 0 "gpc_reg_operand" "") (match_dup 1))] 7068 "reload_completed" 7069 [(set (match_dup 0) (match_dup 1)) 7070 (set (match_dup 2) 7071 (compare:CC (match_dup 0) 7072 (const_int 0)))] 7073 "") 7074 7075(define_expand "mov<mode>" 7076 [(set (match_operand:INT 0 "general_operand" "") 7077 (match_operand:INT 1 "any_operand" ""))] 7078 "" 7079 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") 7080 7081;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI 7082;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ 7083;; MTVSRWZ MF%1 MT%1 NOP 7084(define_insn "*mov<mode>_internal" 7085 [(set (match_operand:QHI 0 "nonimmediate_operand" 7086 "=r, r, ?*wJwK, m, Z, r, 7087 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r, 7088 ?*wJwK, r, *c*l, *h") 7089 7090 (match_operand:QHI 1 "input_operand" 7091 "r, m, Z, r, wJwK, i, 7092 wJwK, O, wM, wB, wS, ?*wJwK, 7093 r, *h, r, 0"))] 7094 7095 "gpc_reg_operand (operands[0], <MODE>mode) 7096 || gpc_reg_operand (operands[1], <MODE>mode)" 7097 "@ 7098 mr %0,%1 7099 l<wd>z%U1%X1 %0,%1 7100 lxsi<wd>zx %x0,%y1 7101 st<wd>%U0%X0 %1,%0 7102 stxsi<wd>x %x1,%y0 7103 li %0,%1 7104 xxlor %x0,%x1,%x1 7105 xxspltib %x0,0 7106 xxspltib %x0,255 7107 vspltis<wd> %0,%1 7108 # 7109 mfvsrwz %0,%x1 7110 mtvsrwz %x0,%1 7111 mf%1 %0 7112 mt%0 %1 7113 nop" 7114 [(set_attr "type" 7115 "*, load, fpload, store, fpstore, *, 7116 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr, 7117 mffgpr, mfjmpr, mtjmpr, *") 7118 7119 (set_attr "length" 7120 "4, 4, 4, 4, 4, 4, 7121 4, 4, 4, 4, 8, 4, 7122 4, 4, 4, 4")]) 7123 7124 7125;; Here is how to move condition codes around. When we store CC data in 7126;; an integer register or memory, we store just the high-order 4 bits. 7127;; This lets us not shift in the most common case of CR0. 7128(define_expand "movcc" 7129 [(set (match_operand:CC 0 "nonimmediate_operand" "") 7130 (match_operand:CC 1 "nonimmediate_operand" ""))] 7131 "" 7132 "") 7133 7134(define_insn "*movcc_internal1" 7135 [(set (match_operand:CC 0 "nonimmediate_operand" 7136 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m") 7137 (match_operand:CC 1 "general_operand" 7138 " y,r, r,O,x,y,r,I,h, r,m,r"))] 7139 "register_operand (operands[0], CCmode) 7140 || register_operand (operands[1], CCmode)" 7141 "@ 7142 mcrf %0,%1 7143 mtcrf 128,%1 7144 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff 7145 crxor %0,%0,%0 7146 mfcr %0%Q1 7147 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000 7148 mr %0,%1 7149 li %0,%1 7150 mf%1 %0 7151 mt%0 %1 7152 lwz%U1%X1 %0,%1 7153 stw%U0%X0 %1,%0" 7154 [(set (attr "type") 7155 (cond [(eq_attr "alternative" "0,3") 7156 (const_string "cr_logical") 7157 (eq_attr "alternative" "1,2") 7158 (const_string "mtcr") 7159 (eq_attr "alternative" "6,7") 7160 (const_string "integer") 7161 (eq_attr "alternative" "8") 7162 (const_string "mfjmpr") 7163 (eq_attr "alternative" "9") 7164 (const_string "mtjmpr") 7165 (eq_attr "alternative" "10") 7166 (const_string "load") 7167 (eq_attr "alternative" "11") 7168 (const_string "store") 7169 (match_test "TARGET_MFCRF") 7170 (const_string "mfcrf") 7171 ] 7172 (const_string "mfcr"))) 7173 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")]) 7174 7175;; For floating-point, we normally deal with the floating-point registers 7176;; unless -msoft-float is used. The sole exception is that parameter passing 7177;; can produce floating-point values in fixed-point registers. Unless the 7178;; value is a simple constant or already in memory, we deal with this by 7179;; allocating memory and copying the value explicitly via that memory location. 7180 7181;; Move 32-bit binary/decimal floating point 7182(define_expand "mov<mode>" 7183 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "") 7184 (match_operand:FMOVE32 1 "any_operand" ""))] 7185 "<fmove_ok>" 7186 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") 7187 7188(define_split 7189 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "") 7190 (match_operand:FMOVE32 1 "const_double_operand" ""))] 7191 "reload_completed 7192 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 7193 || (GET_CODE (operands[0]) == SUBREG 7194 && GET_CODE (SUBREG_REG (operands[0])) == REG 7195 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7196 [(set (match_dup 2) (match_dup 3))] 7197 " 7198{ 7199 long l; 7200 7201 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7202 7203 if (! TARGET_POWERPC64) 7204 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); 7205 else 7206 operands[2] = gen_lowpart (SImode, operands[0]); 7207 7208 operands[3] = gen_int_mode (l, SImode); 7209}") 7210 7211;; Originally, we tried to keep movsf and movsd common, but the differences 7212;; addressing was making it rather difficult to hide with mode attributes. In 7213;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store 7214;; before the VSX stores meant that the register allocator would tend to do a 7215;; direct move to the GPR (which involves conversion from scalar to 7216;; vector/memory formats) to save values in the traditional Altivec registers, 7217;; while SDmode had problems on power6 if the GPR store was not first due to 7218;; the power6 not having an integer store operation. 7219;; 7220;; LWZ LFS LXSSP LXSSPX STFS STXSSP 7221;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP 7222;; MR MT<x> MF<x> NOP 7223 7224(define_insn "movsf_hardfloat" 7225 [(set (match_operand:SF 0 "nonimmediate_operand" 7226 "=!r, f, wb, wu, m, wY, 7227 Z, m, ww, !r, f, ww, 7228 !r, *c*l, !r, *h") 7229 (match_operand:SF 1 "input_operand" 7230 "m, m, wY, Z, f, wb, 7231 wu, r, j, j, f, ww, 7232 r, r, *h, 0"))] 7233 "(register_operand (operands[0], SFmode) 7234 || register_operand (operands[1], SFmode)) 7235 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 7236 && (TARGET_ALLOW_SF_SUBREG 7237 || valid_sf_si_move (operands[0], operands[1], SFmode))" 7238 "@ 7239 lwz%U1%X1 %0,%1 7240 lfs%U1%X1 %0,%1 7241 lxssp %0,%1 7242 lxsspx %x0,%y1 7243 stfs%U0%X0 %1,%0 7244 stxssp %1,%0 7245 stxsspx %x1,%y0 7246 stw%U0%X0 %1,%0 7247 xxlxor %x0,%x0,%x0 7248 li %0,0 7249 fmr %0,%1 7250 xscpsgndp %x0,%x1,%x1 7251 mr %0,%1 7252 mt%0 %1 7253 mf%1 %0 7254 nop" 7255 [(set_attr "type" 7256 "load, fpload, fpload, fpload, fpstore, fpstore, 7257 fpstore, store, veclogical, integer, fpsimple, fpsimple, 7258 *, mtjmpr, mfjmpr, *")]) 7259 7260;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ 7261;; FMR MR MT%0 MF%1 NOP 7262(define_insn "movsd_hardfloat" 7263 [(set (match_operand:SD 0 "nonimmediate_operand" 7264 "=!r, wz, m, Z, ?wh, ?r, 7265 f, !r, *c*l, !r, *h") 7266 (match_operand:SD 1 "input_operand" 7267 "m, Z, r, wx, r, wh, 7268 f, r, r, *h, 0"))] 7269 "(register_operand (operands[0], SDmode) 7270 || register_operand (operands[1], SDmode)) 7271 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT" 7272 "@ 7273 lwz%U1%X1 %0,%1 7274 lfiwzx %0,%y1 7275 stw%U0%X0 %1,%0 7276 stfiwx %1,%y0 7277 mtvsrwz %x0,%1 7278 mfvsrwz %0,%x1 7279 fmr %0,%1 7280 mr %0,%1 7281 mt%0 %1 7282 mf%1 %0 7283 nop" 7284 [(set_attr "type" 7285 "load, fpload, store, fpstore, mffgpr, mftgpr, 7286 fpsimple, *, mtjmpr, mfjmpr, *")]) 7287 7288(define_insn "*mov<mode>_softfloat" 7289 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h") 7290 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))] 7291 "(gpc_reg_operand (operands[0], <MODE>mode) 7292 || gpc_reg_operand (operands[1], <MODE>mode)) 7293 && (TARGET_SOFT_FLOAT || !TARGET_FPRS)" 7294 "@ 7295 mr %0,%1 7296 mt%0 %1 7297 mf%1 %0 7298 lwz%U1%X1 %0,%1 7299 stw%U0%X0 %1,%0 7300 li %0,%1 7301 lis %0,%v1 7302 # 7303 # 7304 nop" 7305 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*") 7306 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")]) 7307 7308;; Like movsf, but adjust a SI value to be used in a SF context, i.e. 7309;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0)) 7310;; 7311;; Because SF values are actually stored as DF values within the vector 7312;; registers, we need to convert the value to the vector SF format when 7313;; we need to use the bits in a union or similar cases. We only need 7314;; to do this transformation when the value is a vector register. Loads, 7315;; stores, and transfers within GPRs are assumed to be safe. 7316;; 7317;; This is a more general case of reload_vsx_from_gprsf. That insn must have 7318;; no alternatives, because the call is created as part of secondary_reload, 7319;; and operand #2's register class is used to allocate the temporary register. 7320;; This function is called before reload, and it creates the temporary as 7321;; needed. 7322 7323;; LWZ LFS LXSSP LXSSPX STW STFIWX 7324;; STXSIWX GPR->VSX VSX->GPR GPR->GPR 7325(define_insn_and_split "movsf_from_si" 7326 [(set (match_operand:SF 0 "rs6000_nonimmediate_operand" 7327 "=!r, f, wb, wu, m, Z, 7328 Z, wy, ?r, !r") 7329 7330 (unspec:SF [(match_operand:SI 1 "input_operand" 7331 "m, m, wY, Z, r, f, 7332 wu, r, wy, r")] 7333 UNSPEC_SF_FROM_SI)) 7334 7335 (clobber (match_scratch:DI 2 7336 "=X, X, X, X, X, X, 7337 X, r, X, X"))] 7338 7339 "TARGET_NO_SF_SUBREG 7340 && (register_operand (operands[0], SFmode) 7341 || register_operand (operands[1], SImode))" 7342 "@ 7343 lwz%U1%X1 %0,%1 7344 lfs%U1%X1 %0,%1 7345 lxssp %0,%1 7346 lxsspx %x0,%y1 7347 stw%U0%X0 %1,%0 7348 stfiwx %1,%y0 7349 stxsiwx %x1,%y0 7350 # 7351 mfvsrwz %0,%x1 7352 mr %0,%1" 7353 7354 "&& reload_completed 7355 && vsx_reg_sfsubreg_ok (operands[0], SFmode) 7356 && int_reg_operand_not_pseudo (operands[1], SImode)" 7357 [(const_int 0)] 7358{ 7359 rtx op0 = operands[0]; 7360 rtx op1 = operands[1]; 7361 rtx op2 = operands[2]; 7362 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1)); 7363 7364 /* Move SF value to upper 32-bits for xscvspdpn. */ 7365 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 7366 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 7367 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 7368 DONE; 7369} 7370 [(set_attr "length" 7371 "4, 4, 4, 4, 4, 4, 7372 4, 12, 4, 4") 7373 (set_attr "type" 7374 "load, fpload, fpload, fpload, store, fpstore, 7375 fpstore, vecfloat, mffgpr, *")]) 7376 7377 7378;; Move 64-bit binary/decimal floating point 7379(define_expand "mov<mode>" 7380 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "") 7381 (match_operand:FMOVE64 1 "any_operand" ""))] 7382 "" 7383 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") 7384 7385(define_split 7386 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "") 7387 (match_operand:FMOVE64 1 "const_int_operand" ""))] 7388 "! TARGET_POWERPC64 && reload_completed 7389 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 7390 || (GET_CODE (operands[0]) == SUBREG 7391 && GET_CODE (SUBREG_REG (operands[0])) == REG 7392 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7393 [(set (match_dup 2) (match_dup 4)) 7394 (set (match_dup 3) (match_dup 1))] 7395 " 7396{ 7397 int endian = (WORDS_BIG_ENDIAN == 0); 7398 HOST_WIDE_INT value = INTVAL (operands[1]); 7399 7400 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 7401 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 7402 operands[4] = GEN_INT (value >> 32); 7403 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 7404}") 7405 7406(define_split 7407 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "") 7408 (match_operand:FMOVE64 1 "const_double_operand" ""))] 7409 "! TARGET_POWERPC64 && reload_completed 7410 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 7411 || (GET_CODE (operands[0]) == SUBREG 7412 && GET_CODE (SUBREG_REG (operands[0])) == REG 7413 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7414 [(set (match_dup 2) (match_dup 4)) 7415 (set (match_dup 3) (match_dup 5))] 7416 " 7417{ 7418 int endian = (WORDS_BIG_ENDIAN == 0); 7419 long l[2]; 7420 7421 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7422 7423 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 7424 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 7425 operands[4] = gen_int_mode (l[endian], SImode); 7426 operands[5] = gen_int_mode (l[1 - endian], SImode); 7427}") 7428 7429(define_split 7430 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "") 7431 (match_operand:FMOVE64 1 "const_double_operand" ""))] 7432 "TARGET_POWERPC64 && reload_completed 7433 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31) 7434 || (GET_CODE (operands[0]) == SUBREG 7435 && GET_CODE (SUBREG_REG (operands[0])) == REG 7436 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7437 [(set (match_dup 2) (match_dup 3))] 7438 " 7439{ 7440 int endian = (WORDS_BIG_ENDIAN == 0); 7441 long l[2]; 7442 HOST_WIDE_INT val; 7443 7444 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7445 7446 operands[2] = gen_lowpart (DImode, operands[0]); 7447 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ 7448 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 7449 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); 7450 7451 operands[3] = gen_int_mode (val, DImode); 7452}") 7453 7454;; Don't have reload use general registers to load a constant. It is 7455;; less efficient than loading the constant into an FP register, since 7456;; it will probably be used there. 7457 7458;; The move constraints are ordered to prefer floating point registers before 7459;; general purpose registers to avoid doing a store and a load to get the value 7460;; into a floating point register when it is needed for a floating point 7461;; operation. Prefer traditional floating point registers over VSX registers, 7462;; since the D-form version of the memory instructions does not need a GPR for 7463;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec 7464;; registers. 7465 7466;; If we have FPR registers, rs6000_emit_move has moved all constants to memory, 7467;; except for 0.0 which can be created on VSX with an xor instruction. 7468 7469(define_insn "*mov<mode>_hardfloat32" 7470 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_av>,Z,<f64_p9>,wY,<f64_vsx>,<f64_vsx>,!r,Y,r,!r") 7471 (match_operand:FMOVE64 1 "input_operand" "d,m,d,Z,<f64_av>,wY,<f64_p9>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))] 7472 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 7473 && (gpc_reg_operand (operands[0], <MODE>mode) 7474 || gpc_reg_operand (operands[1], <MODE>mode))" 7475 "@ 7476 stfd%U0%X0 %1,%0 7477 lfd%U1%X1 %0,%1 7478 fmr %0,%1 7479 lxsd%U1x %x0,%y1 7480 stxsd%U0x %x1,%y0 7481 lxsd %0,%1 7482 stxsd %1,%0 7483 xxlor %x0,%x1,%x1 7484 xxlxor %x0,%x0,%x0 7485 # 7486 # 7487 # 7488 #" 7489 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two") 7490 (set_attr "size" "64") 7491 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")]) 7492 7493(define_insn "*mov<mode>_softfloat32" 7494 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r") 7495 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))] 7496 "! TARGET_POWERPC64 7497 && ((TARGET_FPRS && TARGET_SINGLE_FLOAT) 7498 || TARGET_SOFT_FLOAT || TARGET_E500_SINGLE 7499 || (<MODE>mode == DDmode && TARGET_E500_DOUBLE)) 7500 && (gpc_reg_operand (operands[0], <MODE>mode) 7501 || gpc_reg_operand (operands[1], <MODE>mode))" 7502 "#" 7503 [(set_attr "type" "store,load,two,*,*,*") 7504 (set_attr "length" "8,8,8,8,12,16")]) 7505 7506; ld/std require word-aligned displacements -> 'Y' constraint. 7507; List Y->r and r->Y before r->r for reload. 7508(define_insn "*mov<mode>_hardfloat64" 7509 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>") 7510 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))] 7511 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 7512 && (gpc_reg_operand (operands[0], <MODE>mode) 7513 || gpc_reg_operand (operands[1], <MODE>mode))" 7514 "@ 7515 stfd%U0%X0 %1,%0 7516 lfd%U1%X1 %0,%1 7517 fmr %0,%1 7518 lxsd %0,%1 7519 stxsd %1,%0 7520 lxsd%U1x %x0,%y1 7521 stxsd%U0x %x1,%y0 7522 xxlor %x0,%x1,%x1 7523 xxlxor %x0,%x0,%x0 7524 li %0,0 7525 std%U0%X0 %1,%0 7526 ld%U1%X1 %0,%1 7527 mr %0,%1 7528 mt%0 %1 7529 mf%1 %0 7530 nop 7531 mftgpr %0,%1 7532 mffgpr %0,%1 7533 mfvsrd %0,%x1 7534 mtvsrd %x0,%1" 7535 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr") 7536 (set_attr "size" "64") 7537 (set_attr "length" "4")]) 7538 7539(define_insn "*mov<mode>_softfloat64" 7540 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h") 7541 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))] 7542 "TARGET_POWERPC64 && (TARGET_SOFT_FLOAT || !TARGET_FPRS) 7543 && (gpc_reg_operand (operands[0], <MODE>mode) 7544 || gpc_reg_operand (operands[1], <MODE>mode))" 7545 "@ 7546 std%U0%X0 %1,%0 7547 ld%U1%X1 %0,%1 7548 mr %0,%1 7549 mt%0 %1 7550 mf%1 %0 7551 # 7552 # 7553 # 7554 nop" 7555 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*") 7556 (set_attr "length" "4,4,4,4,4,8,12,16,4")]) 7557 7558(define_expand "mov<mode>" 7559 [(set (match_operand:FMOVE128 0 "general_operand" "") 7560 (match_operand:FMOVE128 1 "any_operand" ""))] 7561 "" 7562 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }") 7563 7564;; It's important to list Y->r and r->Y before r->r because otherwise 7565;; reload, given m->r, will try to pick r->r and reload it, which 7566;; doesn't make progress. 7567 7568;; We can't split little endian direct moves of TDmode, because the words are 7569;; not swapped like they are for TImode or TFmode. Subregs therefore are 7570;; problematical. Don't allow direct move for this case. 7571 7572(define_insn_and_split "*mov<mode>_64bit_dm" 7573 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh") 7574 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))] 7575 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 7576 && FLOAT128_2REG_P (<MODE>mode) 7577 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN) 7578 && (gpc_reg_operand (operands[0], <MODE>mode) 7579 || gpc_reg_operand (operands[1], <MODE>mode))" 7580 "#" 7581 "&& reload_completed" 7582 [(pc)] 7583{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 7584 [(set_attr "length" "8,8,8,8,12,12,8,8,8")]) 7585 7586(define_insn_and_split "*movtd_64bit_nodm" 7587 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r") 7588 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))] 7589 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN 7590 && (gpc_reg_operand (operands[0], TDmode) 7591 || gpc_reg_operand (operands[1], TDmode))" 7592 "#" 7593 "&& reload_completed" 7594 [(pc)] 7595{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 7596 [(set_attr "length" "8,8,8,12,12,8")]) 7597 7598(define_insn_and_split "*mov<mode>_32bit" 7599 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r") 7600 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))] 7601 "TARGET_HARD_FLOAT && TARGET_FPRS && !TARGET_POWERPC64 7602 && (FLOAT128_2REG_P (<MODE>mode) 7603 || int_reg_operand_not_pseudo (operands[0], <MODE>mode) 7604 || int_reg_operand_not_pseudo (operands[1], <MODE>mode)) 7605 && (gpc_reg_operand (operands[0], <MODE>mode) 7606 || gpc_reg_operand (operands[1], <MODE>mode))" 7607 "#" 7608 "&& reload_completed" 7609 [(pc)] 7610{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 7611 [(set_attr "length" "8,8,8,8,20,20,16")]) 7612 7613(define_insn_and_split "*mov<mode>_softfloat" 7614 [(set (match_operand:FMOVE128 0 "rs6000_nonimmediate_operand" "=Y,r,r") 7615 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))] 7616 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) 7617 && (gpc_reg_operand (operands[0], <MODE>mode) 7618 || gpc_reg_operand (operands[1], <MODE>mode))" 7619 "#" 7620 "&& reload_completed" 7621 [(pc)] 7622{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; } 7623 [(set_attr "length" "20,20,16")]) 7624 7625(define_expand "extenddf<mode>2" 7626 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") 7627 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))] 7628 "TARGET_HARD_FLOAT && (TARGET_FPRS || TARGET_E500_DOUBLE) 7629 && TARGET_LONG_DOUBLE_128" 7630{ 7631 if (FLOAT128_IEEE_P (<MODE>mode)) 7632 rs6000_expand_float128_convert (operands[0], operands[1], false); 7633 else if (TARGET_E500_DOUBLE) 7634 { 7635 gcc_assert (<MODE>mode == TFmode); 7636 emit_insn (gen_spe_extenddftf2 (operands[0], operands[1])); 7637 } 7638 else if (TARGET_VSX) 7639 { 7640 if (<MODE>mode == TFmode) 7641 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1])); 7642 else if (<MODE>mode == IFmode) 7643 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1])); 7644 else 7645 gcc_unreachable (); 7646 } 7647 else 7648 { 7649 rtx zero = gen_reg_rtx (DFmode); 7650 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode); 7651 7652 if (<MODE>mode == TFmode) 7653 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero)); 7654 else if (<MODE>mode == IFmode) 7655 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero)); 7656 else 7657 gcc_unreachable (); 7658 } 7659 DONE; 7660}) 7661 7662;; Allow memory operands for the source to be created by the combiner. 7663(define_insn_and_split "extenddf<mode>2_fprs" 7664 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d") 7665 (float_extend:IBM128 7666 (match_operand:DF 1 "nonimmediate_operand" "d,m,d"))) 7667 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))] 7668 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 7669 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" 7670 "#" 7671 "&& reload_completed" 7672 [(set (match_dup 3) (match_dup 1)) 7673 (set (match_dup 4) (match_dup 2))] 7674{ 7675 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 7676 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 7677 7678 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 7679 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 7680}) 7681 7682(define_insn_and_split "extenddf<mode>2_vsx" 7683 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d") 7684 (float_extend:IBM128 7685 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))] 7686 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)" 7687 "#" 7688 "&& reload_completed" 7689 [(set (match_dup 2) (match_dup 1)) 7690 (set (match_dup 3) (match_dup 4))] 7691{ 7692 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 7693 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 7694 7695 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 7696 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 7697 operands[4] = CONST0_RTX (DFmode); 7698}) 7699 7700(define_expand "extendsf<mode>2" 7701 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") 7702 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))] 7703 "TARGET_HARD_FLOAT 7704 && (TARGET_FPRS || TARGET_E500_DOUBLE) 7705 && TARGET_LONG_DOUBLE_128" 7706{ 7707 if (FLOAT128_IEEE_P (<MODE>mode)) 7708 rs6000_expand_float128_convert (operands[0], operands[1], false); 7709 else 7710 { 7711 rtx tmp = gen_reg_rtx (DFmode); 7712 emit_insn (gen_extendsfdf2 (tmp, operands[1])); 7713 emit_insn (gen_extenddf<mode>2 (operands[0], tmp)); 7714 } 7715 DONE; 7716}) 7717 7718(define_expand "trunc<mode>df2" 7719 [(set (match_operand:DF 0 "gpc_reg_operand" "") 7720 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] 7721 "TARGET_HARD_FLOAT 7722 && (TARGET_FPRS || TARGET_E500_DOUBLE) 7723 && TARGET_LONG_DOUBLE_128" 7724{ 7725 if (FLOAT128_IEEE_P (<MODE>mode)) 7726 { 7727 rs6000_expand_float128_convert (operands[0], operands[1], false); 7728 DONE; 7729 } 7730}) 7731 7732(define_insn_and_split "trunc<mode>df2_internal1" 7733 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d") 7734 (float_truncate:DF 7735 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))] 7736 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT 7737 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" 7738 "@ 7739 # 7740 fmr %0,%1" 7741 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 7742 [(const_int 0)] 7743{ 7744 emit_note (NOTE_INSN_DELETED); 7745 DONE; 7746} 7747 [(set_attr "type" "fpsimple")]) 7748 7749(define_insn "trunc<mode>df2_internal2" 7750 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7751 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 7752 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT 7753 && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 7754 "fadd %0,%1,%L1" 7755 [(set_attr "type" "fp") 7756 (set_attr "fp_type" "fp_addsub_d")]) 7757 7758(define_expand "trunc<mode>sf2" 7759 [(set (match_operand:SF 0 "gpc_reg_operand" "") 7760 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] 7761 "TARGET_HARD_FLOAT 7762 && (TARGET_FPRS || TARGET_E500_DOUBLE) 7763 && TARGET_LONG_DOUBLE_128" 7764{ 7765 if (FLOAT128_IEEE_P (<MODE>mode)) 7766 rs6000_expand_float128_convert (operands[0], operands[1], false); 7767 else if (TARGET_E500_DOUBLE) 7768 { 7769 gcc_assert (<MODE>mode == TFmode); 7770 emit_insn (gen_spe_trunctfsf2 (operands[0], operands[1])); 7771 } 7772 else if (<MODE>mode == TFmode) 7773 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1])); 7774 else if (<MODE>mode == IFmode) 7775 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1])); 7776 else 7777 gcc_unreachable (); 7778 DONE; 7779}) 7780 7781(define_insn_and_split "trunc<mode>sf2_fprs" 7782 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 7783 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d"))) 7784 (clobber (match_scratch:DF 2 "=d"))] 7785 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT 7786 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" 7787 "#" 7788 "&& reload_completed" 7789 [(set (match_dup 2) 7790 (float_truncate:DF (match_dup 1))) 7791 (set (match_dup 0) 7792 (float_truncate:SF (match_dup 2)))] 7793 "") 7794 7795(define_expand "floatsi<mode>2" 7796 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7797 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand"))) 7798 (clobber (match_scratch:DI 2))])] 7799 "TARGET_HARD_FLOAT 7800 && (TARGET_FPRS || TARGET_E500_DOUBLE) 7801 && TARGET_LONG_DOUBLE_128" 7802{ 7803 rtx op0 = operands[0]; 7804 rtx op1 = operands[1]; 7805 7806 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)) 7807 ; 7808 else if (FLOAT128_IEEE_P (<MODE>mode)) 7809 { 7810 rs6000_expand_float128_convert (op0, op1, false); 7811 DONE; 7812 } 7813 else 7814 { 7815 rtx tmp = gen_reg_rtx (DFmode); 7816 expand_float (tmp, op1, false); 7817 if (<MODE>mode == TFmode) 7818 emit_insn (gen_extenddftf2 (op0, tmp)); 7819 else if (<MODE>mode == IFmode) 7820 emit_insn (gen_extenddfif2 (op0, tmp)); 7821 else 7822 gcc_unreachable (); 7823 DONE; 7824 } 7825}) 7826 7827; fadd, but rounding towards zero. 7828; This is probably not the optimal code sequence. 7829(define_insn "fix_trunc_helper<mode>" 7830 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7831 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")] 7832 UNSPEC_FIX_TRUNC_TF)) 7833 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))] 7834 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 7835 && FLOAT128_IBM_P (<MODE>mode)" 7836 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" 7837 [(set_attr "type" "fp") 7838 (set_attr "length" "20")]) 7839 7840(define_expand "fix_trunc<mode>si2" 7841 [(set (match_operand:SI 0 "gpc_reg_operand" "") 7842 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] 7843 "TARGET_HARD_FLOAT 7844 && (TARGET_FPRS || TARGET_E500_DOUBLE) && TARGET_LONG_DOUBLE_128" 7845{ 7846 rtx op0 = operands[0]; 7847 rtx op1 = operands[1]; 7848 7849 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)) 7850 ; 7851 else 7852 { 7853 if (FLOAT128_IEEE_P (<MODE>mode)) 7854 rs6000_expand_float128_convert (op0, op1, false); 7855 else if (TARGET_E500_DOUBLE && <MODE>mode == TFmode) 7856 emit_insn (gen_spe_fix_trunctfsi2 (op0, op1)); 7857 else if (<MODE>mode == TFmode) 7858 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1)); 7859 else if (<MODE>mode == IFmode) 7860 emit_insn (gen_fix_truncifsi2_fprs (op0, op1)); 7861 else 7862 gcc_unreachable (); 7863 DONE; 7864 } 7865}) 7866 7867(define_expand "fix_trunc<mode>si2_fprs" 7868 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") 7869 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" ""))) 7870 (clobber (match_dup 2)) 7871 (clobber (match_dup 3)) 7872 (clobber (match_dup 4)) 7873 (clobber (match_dup 5))])] 7874 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" 7875{ 7876 operands[2] = gen_reg_rtx (DFmode); 7877 operands[3] = gen_reg_rtx (DFmode); 7878 operands[4] = gen_reg_rtx (DImode); 7879 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode)); 7880}) 7881 7882(define_insn_and_split "*fix_trunc<mode>si2_internal" 7883 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 7884 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d"))) 7885 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d")) 7886 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d")) 7887 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d")) 7888 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))] 7889 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_LONG_DOUBLE_128" 7890 "#" 7891 "" 7892 [(pc)] 7893{ 7894 rtx lowword; 7895 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1], 7896 operands[3])); 7897 7898 gcc_assert (MEM_P (operands[5])); 7899 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 7900 7901 emit_insn (gen_fctiwz_df (operands[4], operands[2])); 7902 emit_move_insn (operands[5], operands[4]); 7903 emit_move_insn (operands[0], lowword); 7904 DONE; 7905}) 7906 7907(define_expand "fix_trunc<mode>di2" 7908 [(set (match_operand:DI 0 "gpc_reg_operand" "") 7909 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))] 7910 "TARGET_FLOAT128_TYPE" 7911{ 7912 if (!TARGET_FLOAT128_HW) 7913 { 7914 rs6000_expand_float128_convert (operands[0], operands[1], false); 7915 DONE; 7916 } 7917}) 7918 7919(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2" 7920 [(set (match_operand:SDI 0 "gpc_reg_operand" "") 7921 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))] 7922 "TARGET_FLOAT128_TYPE" 7923{ 7924 rs6000_expand_float128_convert (operands[0], operands[1], true); 7925 DONE; 7926}) 7927 7928(define_expand "floatdi<mode>2" 7929 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "") 7930 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))] 7931 "TARGET_FLOAT128_TYPE" 7932{ 7933 if (!TARGET_FLOAT128_HW) 7934 { 7935 rs6000_expand_float128_convert (operands[0], operands[1], false); 7936 DONE; 7937 } 7938}) 7939 7940(define_expand "floatunsdi<IEEE128:mode>2" 7941 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "") 7942 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))] 7943 "TARGET_FLOAT128_TYPE" 7944{ 7945 if (!TARGET_FLOAT128_HW) 7946 { 7947 rs6000_expand_float128_convert (operands[0], operands[1], true); 7948 DONE; 7949 } 7950}) 7951 7952(define_expand "floatuns<IEEE128:mode>2" 7953 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "") 7954 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))] 7955 "TARGET_FLOAT128_TYPE" 7956{ 7957 rtx op0 = operands[0]; 7958 rtx op1 = operands[1]; 7959 7960 if (TARGET_FLOAT128_HW) 7961 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1)); 7962 else 7963 rs6000_expand_float128_convert (op0, op1, true); 7964 DONE; 7965}) 7966 7967(define_expand "neg<mode>2" 7968 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") 7969 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] 7970 "FLOAT128_IEEE_P (<MODE>mode) 7971 || (FLOAT128_IBM_P (<MODE>mode) 7972 && TARGET_HARD_FLOAT 7973 && (TARGET_FPRS || TARGET_E500_DOUBLE))" 7974 " 7975{ 7976 if (FLOAT128_IEEE_P (<MODE>mode)) 7977 { 7978 if (TARGET_FLOAT128_HW) 7979 { 7980 if (<MODE>mode == TFmode) 7981 emit_insn (gen_negtf2_hw (operands[0], operands[1])); 7982 else if (<MODE>mode == KFmode) 7983 emit_insn (gen_negkf2_hw (operands[0], operands[1])); 7984 else 7985 gcc_unreachable (); 7986 } 7987 else if (TARGET_FLOAT128_TYPE) 7988 { 7989 if (<MODE>mode == TFmode) 7990 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1])); 7991 else if (<MODE>mode == KFmode) 7992 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1])); 7993 else 7994 gcc_unreachable (); 7995 } 7996 else 7997 { 7998 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode); 7999 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST, 8000 <MODE>mode, 8001 operands[1], <MODE>mode); 8002 8003 if (target && !rtx_equal_p (target, operands[0])) 8004 emit_move_insn (operands[0], target); 8005 } 8006 DONE; 8007 } 8008}") 8009 8010(define_insn "neg<mode>2_internal" 8011 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d") 8012 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 8013 "TARGET_HARD_FLOAT && TARGET_FPRS && FLOAT128_IBM_P (TFmode)" 8014 "* 8015{ 8016 if (REGNO (operands[0]) == REGNO (operands[1]) + 1) 8017 return \"fneg %L0,%L1\;fneg %0,%1\"; 8018 else 8019 return \"fneg %0,%1\;fneg %L0,%L1\"; 8020}" 8021 [(set_attr "type" "fpsimple") 8022 (set_attr "length" "8")]) 8023 8024(define_expand "abs<mode>2" 8025 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "") 8026 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))] 8027 "FLOAT128_IEEE_P (<MODE>mode) 8028 || (FLOAT128_IBM_P (<MODE>mode) 8029 && TARGET_HARD_FLOAT 8030 && (TARGET_FPRS || TARGET_E500_DOUBLE))" 8031 " 8032{ 8033 rtx label; 8034 8035 if (FLOAT128_IEEE_P (<MODE>mode)) 8036 { 8037 if (TARGET_FLOAT128_HW) 8038 { 8039 if (<MODE>mode == TFmode) 8040 emit_insn (gen_abstf2_hw (operands[0], operands[1])); 8041 else if (<MODE>mode == KFmode) 8042 emit_insn (gen_abskf2_hw (operands[0], operands[1])); 8043 else 8044 FAIL; 8045 DONE; 8046 } 8047 else if (TARGET_FLOAT128_TYPE) 8048 { 8049 if (<MODE>mode == TFmode) 8050 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1])); 8051 else if (<MODE>mode == KFmode) 8052 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1])); 8053 else 8054 FAIL; 8055 DONE; 8056 } 8057 else 8058 FAIL; 8059 } 8060 8061 label = gen_label_rtx (); 8062 if (TARGET_E500_DOUBLE && <MODE>mode == TFmode) 8063 { 8064 if (flag_finite_math_only && !flag_trapping_math) 8065 emit_insn (gen_spe_abstf2_tst (operands[0], operands[1], label)); 8066 else 8067 emit_insn (gen_spe_abstf2_cmp (operands[0], operands[1], label)); 8068 } 8069 else if (<MODE>mode == TFmode) 8070 emit_insn (gen_abstf2_internal (operands[0], operands[1], label)); 8071 else if (<MODE>mode == TFmode) 8072 emit_insn (gen_absif2_internal (operands[0], operands[1], label)); 8073 else 8074 FAIL; 8075 emit_label (label); 8076 DONE; 8077}") 8078 8079(define_expand "abs<mode>2_internal" 8080 [(set (match_operand:IBM128 0 "gpc_reg_operand" "") 8081 (match_operand:IBM128 1 "gpc_reg_operand" "")) 8082 (set (match_dup 3) (match_dup 5)) 8083 (set (match_dup 5) (abs:DF (match_dup 5))) 8084 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5))) 8085 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0)) 8086 (label_ref (match_operand 2 "" "")) 8087 (pc))) 8088 (set (match_dup 6) (neg:DF (match_dup 6)))] 8089 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT 8090 && TARGET_LONG_DOUBLE_128" 8091 " 8092{ 8093 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 8094 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 8095 operands[3] = gen_reg_rtx (DFmode); 8096 operands[4] = gen_reg_rtx (CCFPmode); 8097 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 8098 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 8099}") 8100 8101 8102;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector 8103;; register 8104 8105(define_expand "ieee_128bit_negative_zero" 8106 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))] 8107 "TARGET_FLOAT128_TYPE" 8108{ 8109 rtvec v = rtvec_alloc (16); 8110 int i, high; 8111 8112 for (i = 0; i < 16; i++) 8113 RTVEC_ELT (v, i) = const0_rtx; 8114 8115 high = (BYTES_BIG_ENDIAN) ? 0 : 15; 8116 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode); 8117 8118 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v)); 8119 DONE; 8120}) 8121 8122;; IEEE 128-bit negate 8123 8124;; We have 2 insns here for negate and absolute value. The first uses 8125;; match_scratch so that phases like combine can recognize neg/abs as generic 8126;; insns, and second insn after the first split pass loads up the bit to 8127;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of 8128;; neg/abs to create the constant just once. 8129 8130(define_insn_and_split "ieee_128bit_vsx_neg<mode>2" 8131 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8132 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8133 (clobber (match_scratch:V16QI 2 "=v"))] 8134 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8135 "#" 8136 "&& 1" 8137 [(parallel [(set (match_dup 0) 8138 (neg:IEEE128 (match_dup 1))) 8139 (use (match_dup 2))])] 8140{ 8141 if (GET_CODE (operands[2]) == SCRATCH) 8142 operands[2] = gen_reg_rtx (V16QImode); 8143 8144 operands[3] = gen_reg_rtx (V16QImode); 8145 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8146} 8147 [(set_attr "length" "8") 8148 (set_attr "type" "vecsimple")]) 8149 8150(define_insn "*ieee_128bit_vsx_neg<mode>2_internal" 8151 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8152 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8153 (use (match_operand:V16QI 2 "register_operand" "v"))] 8154 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8155 "xxlxor %x0,%x1,%x2" 8156 [(set_attr "type" "veclogical")]) 8157 8158;; IEEE 128-bit absolute value 8159(define_insn_and_split "ieee_128bit_vsx_abs<mode>2" 8160 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8161 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8162 (clobber (match_scratch:V16QI 2 "=v"))] 8163 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 8164 "#" 8165 "&& 1" 8166 [(parallel [(set (match_dup 0) 8167 (abs:IEEE128 (match_dup 1))) 8168 (use (match_dup 2))])] 8169{ 8170 if (GET_CODE (operands[2]) == SCRATCH) 8171 operands[2] = gen_reg_rtx (V16QImode); 8172 8173 operands[3] = gen_reg_rtx (V16QImode); 8174 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8175} 8176 [(set_attr "length" "8") 8177 (set_attr "type" "vecsimple")]) 8178 8179(define_insn "*ieee_128bit_vsx_abs<mode>2_internal" 8180 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8181 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8182 (use (match_operand:V16QI 2 "register_operand" "v"))] 8183 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8184 "xxlandc %x0,%x1,%x2" 8185 [(set_attr "type" "veclogical")]) 8186 8187;; IEEE 128-bit negative absolute value 8188(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2" 8189 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8190 (neg:IEEE128 8191 (abs:IEEE128 8192 (match_operand:IEEE128 1 "register_operand" "wa")))) 8193 (clobber (match_scratch:V16QI 2 "=v"))] 8194 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW 8195 && FLOAT128_IEEE_P (<MODE>mode)" 8196 "#" 8197 "&& 1" 8198 [(parallel [(set (match_dup 0) 8199 (neg:IEEE128 (abs:IEEE128 (match_dup 1)))) 8200 (use (match_dup 2))])] 8201{ 8202 if (GET_CODE (operands[2]) == SCRATCH) 8203 operands[2] = gen_reg_rtx (V16QImode); 8204 8205 operands[3] = gen_reg_rtx (V16QImode); 8206 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8207} 8208 [(set_attr "length" "8") 8209 (set_attr "type" "vecsimple")]) 8210 8211(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal" 8212 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8213 (neg:IEEE128 8214 (abs:IEEE128 8215 (match_operand:IEEE128 1 "register_operand" "wa")))) 8216 (use (match_operand:V16QI 2 "register_operand" "v"))] 8217 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8218 "xxlor %x0,%x1,%x2" 8219 [(set_attr "type" "veclogical")]) 8220 8221;; Float128 conversion functions. These expand to library function calls. 8222;; We use expand to convert from IBM double double to IEEE 128-bit 8223;; and trunc for the opposite. 8224(define_expand "extendiftf2" 8225 [(set (match_operand:TF 0 "gpc_reg_operand" "") 8226 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))] 8227 "TARGET_FLOAT128_TYPE" 8228{ 8229 rs6000_expand_float128_convert (operands[0], operands[1], false); 8230 DONE; 8231}) 8232 8233(define_expand "extendifkf2" 8234 [(set (match_operand:KF 0 "gpc_reg_operand" "") 8235 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))] 8236 "TARGET_FLOAT128_TYPE" 8237{ 8238 rs6000_expand_float128_convert (operands[0], operands[1], false); 8239 DONE; 8240}) 8241 8242(define_expand "extendtfkf2" 8243 [(set (match_operand:KF 0 "gpc_reg_operand" "") 8244 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))] 8245 "TARGET_FLOAT128_TYPE" 8246{ 8247 rs6000_expand_float128_convert (operands[0], operands[1], false); 8248 DONE; 8249}) 8250 8251(define_expand "trunciftf2" 8252 [(set (match_operand:IF 0 "gpc_reg_operand" "") 8253 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))] 8254 "TARGET_FLOAT128_TYPE" 8255{ 8256 rs6000_expand_float128_convert (operands[0], operands[1], false); 8257 DONE; 8258}) 8259 8260(define_expand "truncifkf2" 8261 [(set (match_operand:IF 0 "gpc_reg_operand" "") 8262 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))] 8263 "TARGET_FLOAT128_TYPE" 8264{ 8265 rs6000_expand_float128_convert (operands[0], operands[1], false); 8266 DONE; 8267}) 8268 8269(define_expand "trunckftf2" 8270 [(set (match_operand:TF 0 "gpc_reg_operand" "") 8271 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))] 8272 "TARGET_FLOAT128_TYPE" 8273{ 8274 rs6000_expand_float128_convert (operands[0], operands[1], false); 8275 DONE; 8276}) 8277 8278(define_expand "trunctfif2" 8279 [(set (match_operand:IF 0 "gpc_reg_operand" "") 8280 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))] 8281 "TARGET_FLOAT128_TYPE" 8282{ 8283 rs6000_expand_float128_convert (operands[0], operands[1], false); 8284 DONE; 8285}) 8286 8287 8288;; Reload helper functions used by rs6000_secondary_reload. The patterns all 8289;; must have 3 arguments, and scratch register constraint must be a single 8290;; constraint. 8291 8292;; Reload patterns to support gpr load/store with misaligned mem. 8293;; and multiple gpr load/store at offset >= 0xfffc 8294(define_expand "reload_<mode>_store" 8295 [(parallel [(match_operand 0 "memory_operand" "=m") 8296 (match_operand 1 "gpc_reg_operand" "r") 8297 (match_operand:GPR 2 "register_operand" "=&b")])] 8298 "" 8299{ 8300 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true); 8301 DONE; 8302}) 8303 8304(define_expand "reload_<mode>_load" 8305 [(parallel [(match_operand 0 "gpc_reg_operand" "=r") 8306 (match_operand 1 "memory_operand" "m") 8307 (match_operand:GPR 2 "register_operand" "=b")])] 8308 "" 8309{ 8310 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false); 8311 DONE; 8312}) 8313 8314 8315;; Reload patterns for various types using the vector registers. We may need 8316;; an additional base register to convert the reg+offset addressing to reg+reg 8317;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an 8318;; index register for gpr registers. 8319(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store" 8320 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m") 8321 (match_operand:RELOAD 1 "gpc_reg_operand" "wa") 8322 (match_operand:P 2 "register_operand" "=b")])] 8323 "<P:tptrsize>" 8324{ 8325 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true); 8326 DONE; 8327}) 8328 8329(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load" 8330 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa") 8331 (match_operand:RELOAD 1 "memory_operand" "m") 8332 (match_operand:P 2 "register_operand" "=b")])] 8333 "<P:tptrsize>" 8334{ 8335 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false); 8336 DONE; 8337}) 8338 8339 8340;; Reload sometimes tries to move the address to a GPR, and can generate 8341;; invalid RTL for addresses involving AND -16. Allow addresses involving 8342;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16. 8343 8344(define_insn_and_split "*vec_reload_and_plus_<mptrsize>" 8345 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 8346 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 8347 (match_operand:P 2 "reg_or_cint_operand" "rI")) 8348 (const_int -16)))] 8349 "TARGET_ALTIVEC && (reload_in_progress || reload_completed)" 8350 "#" 8351 "&& reload_completed" 8352 [(set (match_dup 0) 8353 (plus:P (match_dup 1) 8354 (match_dup 2))) 8355 (set (match_dup 0) 8356 (and:P (match_dup 0) 8357 (const_int -16)))]) 8358 8359;; Power8 merge instructions to allow direct move to/from floating point 8360;; registers in 32-bit mode. We use TF mode to get two registers to move the 8361;; individual 32-bit parts across. Subreg doesn't work too well on the TF 8362;; value, since it is allocated in reload and not all of the flow information 8363;; is setup for it. We have two patterns to do the two moves between gprs and 8364;; fprs. There isn't a dependancy between the two, but we could potentially 8365;; schedule other instructions between the two instructions. 8366 8367(define_insn "p8_fmrgow_<mode>" 8368 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 8369 (unspec:FMOVE64X [ 8370 (match_operand:DF 1 "register_operand" "d") 8371 (match_operand:DF 2 "register_operand" "d")] 8372 UNSPEC_P8V_FMRGOW))] 8373 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8374 "fmrgow %0,%1,%2" 8375 [(set_attr "type" "fpsimple")]) 8376 8377(define_insn "p8_mtvsrwz" 8378 [(set (match_operand:DF 0 "register_operand" "=d") 8379 (unspec:DF [(match_operand:SI 1 "register_operand" "r")] 8380 UNSPEC_P8V_MTVSRWZ))] 8381 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8382 "mtvsrwz %x0,%1" 8383 [(set_attr "type" "mftgpr")]) 8384 8385(define_insn_and_split "reload_fpr_from_gpr<mode>" 8386 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 8387 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")] 8388 UNSPEC_P8V_RELOAD_FROM_GPR)) 8389 (clobber (match_operand:IF 2 "register_operand" "=d"))] 8390 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8391 "#" 8392 "&& reload_completed" 8393 [(const_int 0)] 8394{ 8395 rtx dest = operands[0]; 8396 rtx src = operands[1]; 8397 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 8398 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 8399 rtx gpr_hi_reg = gen_highpart (SImode, src); 8400 rtx gpr_lo_reg = gen_lowpart (SImode, src); 8401 8402 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg)); 8403 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg)); 8404 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo)); 8405 DONE; 8406} 8407 [(set_attr "length" "12") 8408 (set_attr "type" "three")]) 8409 8410;; Move 128 bit values from GPRs to VSX registers in 64-bit mode 8411(define_insn "p8_mtvsrd_df" 8412 [(set (match_operand:DF 0 "register_operand" "=wa") 8413 (unspec:DF [(match_operand:DI 1 "register_operand" "r")] 8414 UNSPEC_P8V_MTVSRD))] 8415 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8416 "mtvsrd %x0,%1" 8417 [(set_attr "type" "mftgpr")]) 8418 8419(define_insn "p8_xxpermdi_<mode>" 8420 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 8421 (unspec:FMOVE128_GPR [ 8422 (match_operand:DF 1 "register_operand" "wa") 8423 (match_operand:DF 2 "register_operand" "wa")] 8424 UNSPEC_P8V_XXPERMDI))] 8425 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8426 "xxpermdi %x0,%x1,%x2,0" 8427 [(set_attr "type" "vecperm")]) 8428 8429(define_insn_and_split "reload_vsx_from_gpr<mode>" 8430 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 8431 (unspec:FMOVE128_GPR 8432 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")] 8433 UNSPEC_P8V_RELOAD_FROM_GPR)) 8434 (clobber (match_operand:IF 2 "register_operand" "=wa"))] 8435 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8436 "#" 8437 "&& reload_completed" 8438 [(const_int 0)] 8439{ 8440 rtx dest = operands[0]; 8441 rtx src = operands[1]; 8442 /* You might think that we could use op0 as one temp and a DF clobber 8443 as op2, but you'd be wrong. Secondary reload move patterns don't 8444 check for overlap of the clobber and the destination. */ 8445 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 8446 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 8447 rtx gpr_hi_reg = gen_highpart (DImode, src); 8448 rtx gpr_lo_reg = gen_lowpart (DImode, src); 8449 8450 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg)); 8451 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg)); 8452 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo)); 8453 DONE; 8454} 8455 [(set_attr "length" "12") 8456 (set_attr "type" "three")]) 8457 8458(define_split 8459 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "") 8460 (match_operand:FMOVE128_GPR 1 "input_operand" ""))] 8461 "reload_completed 8462 && (int_reg_operand (operands[0], <MODE>mode) 8463 || int_reg_operand (operands[1], <MODE>mode)) 8464 && (!TARGET_DIRECT_MOVE_128 8465 || (!vsx_register_operand (operands[0], <MODE>mode) 8466 && !vsx_register_operand (operands[1], <MODE>mode)))" 8467 [(pc)] 8468{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) 8469 8470;; Move SFmode to a VSX from a GPR register. Because scalar floating point 8471;; type is stored internally as double precision in the VSX registers, we have 8472;; to convert it from the vector format. 8473(define_insn "p8_mtvsrd_sf" 8474 [(set (match_operand:SF 0 "register_operand" "=wa") 8475 (unspec:SF [(match_operand:DI 1 "register_operand" "r")] 8476 UNSPEC_P8V_MTVSRD))] 8477 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8478 "mtvsrd %x0,%1" 8479 [(set_attr "type" "mftgpr")]) 8480 8481(define_insn_and_split "reload_vsx_from_gprsf" 8482 [(set (match_operand:SF 0 "register_operand" "=wa") 8483 (unspec:SF [(match_operand:SF 1 "register_operand" "r")] 8484 UNSPEC_P8V_RELOAD_FROM_GPR)) 8485 (clobber (match_operand:DI 2 "register_operand" "=r"))] 8486 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8487 "#" 8488 "&& reload_completed" 8489 [(const_int 0)] 8490{ 8491 rtx op0 = operands[0]; 8492 rtx op1 = operands[1]; 8493 rtx op2 = operands[2]; 8494 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0); 8495 8496 /* Move SF value to upper 32-bits for xscvspdpn. */ 8497 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 8498 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 8499 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 8500 DONE; 8501} 8502 [(set_attr "length" "8") 8503 (set_attr "type" "two")]) 8504 8505;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a 8506;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value, 8507;; and then doing a move of that. 8508(define_insn "p8_mfvsrd_3_<mode>" 8509 [(set (match_operand:DF 0 "register_operand" "=r") 8510 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 8511 UNSPEC_P8V_RELOAD_FROM_VSX))] 8512 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8513 "mfvsrd %0,%x1" 8514 [(set_attr "type" "mftgpr")]) 8515 8516(define_insn_and_split "reload_gpr_from_vsx<mode>" 8517 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r") 8518 (unspec:FMOVE128_GPR 8519 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 8520 UNSPEC_P8V_RELOAD_FROM_VSX)) 8521 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))] 8522 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8523 "#" 8524 "&& reload_completed" 8525 [(const_int 0)] 8526{ 8527 rtx dest = operands[0]; 8528 rtx src = operands[1]; 8529 rtx tmp = operands[2]; 8530 rtx gpr_hi_reg = gen_highpart (DFmode, dest); 8531 rtx gpr_lo_reg = gen_lowpart (DFmode, dest); 8532 8533 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src)); 8534 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3))); 8535 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp)); 8536 DONE; 8537} 8538 [(set_attr "length" "12") 8539 (set_attr "type" "three")]) 8540 8541;; Move SFmode to a GPR from a VSX register. Because scalar floating point 8542;; type is stored internally as double precision, we have to convert it to the 8543;; vector format. 8544 8545(define_insn_and_split "reload_gpr_from_vsxsf" 8546 [(set (match_operand:SF 0 "register_operand" "=r") 8547 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")] 8548 UNSPEC_P8V_RELOAD_FROM_VSX)) 8549 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))] 8550 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8551 "#" 8552 "&& reload_completed" 8553 [(const_int 0)] 8554{ 8555 rtx op0 = operands[0]; 8556 rtx op1 = operands[1]; 8557 rtx op2 = operands[2]; 8558 rtx diop0 = simplify_gen_subreg (DImode, op0, SFmode, 0); 8559 8560 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 8561 emit_insn (gen_p8_mfvsrd_4_disf (diop0, op2)); 8562 emit_insn (gen_lshrdi3 (diop0, diop0, GEN_INT (32))); 8563 DONE; 8564} 8565 [(set_attr "length" "12") 8566 (set_attr "type" "three")]) 8567 8568(define_insn "p8_mfvsrd_4_disf" 8569 [(set (match_operand:DI 0 "register_operand" "=r") 8570 (unspec:DI [(match_operand:V4SF 1 "register_operand" "wa")] 8571 UNSPEC_P8V_RELOAD_FROM_VSX))] 8572 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8573 "mfvsrd %0,%x1" 8574 [(set_attr "type" "mftgpr")]) 8575 8576 8577;; Next come the multi-word integer load and store and the load and store 8578;; multiple insns. 8579 8580;; List r->r after r->Y, otherwise reload will try to reload a 8581;; non-offsettable address by using r->r which won't make progress. 8582;; Use of fprs is disparaged slightly otherwise reload prefers to reload 8583;; a gpr into a fpr instead of reloading an invalid 'Y' address 8584 8585;; GPR store GPR load GPR move FPR store FPR load FPR move 8586;; GPR const AVX store AVX store AVX load AVX load VSX move 8587;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const 8588;; AVX const 8589 8590(define_insn "*movdi_internal32" 8591 [(set (match_operand:DI 0 "rs6000_nonimmediate_operand" 8592 "=Y, r, r, ^m, ^d, ^d, 8593 r, ^wY, $Z, ^wb, $wv, ^wi, 8594 *wo, *wo, *wv, *wi, *wi, *wv, 8595 *wv") 8596 8597 (match_operand:DI 1 "input_operand" 8598 "r, Y, r, d, m, d, 8599 IJKnGHF, wb, wv, wY, Z, wi, 8600 Oj, wM, OjwM, Oj, wM, wS, 8601 wB"))] 8602 8603 "! TARGET_POWERPC64 8604 && (gpc_reg_operand (operands[0], DImode) 8605 || gpc_reg_operand (operands[1], DImode))" 8606 "@ 8607 # 8608 # 8609 # 8610 stfd%U0%X0 %1,%0 8611 lfd%U1%X1 %0,%1 8612 fmr %0,%1 8613 # 8614 stxsd %1,%0 8615 stxsdx %x1,%y0 8616 lxsd %0,%1 8617 lxsdx %x0,%y1 8618 xxlor %x0,%x1,%x1 8619 xxspltib %x0,0 8620 xxspltib %x0,255 8621 vspltisw %0,%1 8622 xxlxor %x0,%x0,%x0 8623 xxlorc %x0,%x0,%x0 8624 # 8625 #" 8626 [(set_attr "type" 8627 "store, load, *, fpstore, fpload, fpsimple, 8628 *, fpstore, fpstore, fpload, fpload, veclogical, 8629 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple, 8630 vecsimple") 8631 (set_attr "size" "64")]) 8632 8633(define_split 8634 [(set (match_operand:DI 0 "gpc_reg_operand" "") 8635 (match_operand:DI 1 "const_int_operand" ""))] 8636 "! TARGET_POWERPC64 && reload_completed 8637 && gpr_or_gpr_p (operands[0], operands[1]) 8638 && !direct_move_p (operands[0], operands[1])" 8639 [(set (match_dup 2) (match_dup 4)) 8640 (set (match_dup 3) (match_dup 1))] 8641 " 8642{ 8643 HOST_WIDE_INT value = INTVAL (operands[1]); 8644 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 8645 DImode); 8646 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 8647 DImode); 8648 operands[4] = GEN_INT (value >> 32); 8649 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 8650}") 8651 8652(define_split 8653 [(set (match_operand:DIFD 0 "rs6000_nonimmediate_operand" "") 8654 (match_operand:DIFD 1 "input_operand" ""))] 8655 "reload_completed && !TARGET_POWERPC64 8656 && gpr_or_gpr_p (operands[0], operands[1]) 8657 && !direct_move_p (operands[0], operands[1])" 8658 [(pc)] 8659{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) 8660 8661;; GPR store GPR load GPR move GPR li GPR lis GPR # 8662;; FPR store FPR load FPR move AVX store AVX store AVX load 8663;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0 8664;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR 8665;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX 8666(define_insn "*movdi_internal64" 8667 [(set (match_operand:DI 0 "nonimmediate_operand" 8668 "=Y, r, r, r, r, r, 8669 ^m, ^d, ^d, ^wY, $Z, $wb, 8670 $wv, ^wi, *wo, *wo, *wv, *wi, 8671 *wi, *wv, *wv, r, *h, *h, 8672 ?*r, ?*wg, ?*r, ?*wj") 8673 8674 (match_operand:DI 1 "input_operand" 8675 "r, Y, r, I, L, nF, 8676 d, m, d, wb, wv, wY, 8677 Z, wi, Oj, wM, OjwM, Oj, 8678 wM, wS, wB, *h, r, 0, 8679 wg, r, wj, r"))] 8680 8681 "TARGET_POWERPC64 8682 && (gpc_reg_operand (operands[0], DImode) 8683 || gpc_reg_operand (operands[1], DImode))" 8684 "@ 8685 std%U0%X0 %1,%0 8686 ld%U1%X1 %0,%1 8687 mr %0,%1 8688 li %0,%1 8689 lis %0,%v1 8690 # 8691 stfd%U0%X0 %1,%0 8692 lfd%U1%X1 %0,%1 8693 fmr %0,%1 8694 stxsd %1,%0 8695 stxsdx %x1,%y0 8696 lxsd %0,%1 8697 lxsdx %x0,%y1 8698 xxlor %x0,%x1,%x1 8699 xxspltib %x0,0 8700 xxspltib %x0,255 8701 # 8702 xxlxor %x0,%x0,%x0 8703 xxlorc %x0,%x0,%x0 8704 # 8705 # 8706 mf%1 %0 8707 mt%0 %1 8708 nop 8709 mftgpr %0,%1 8710 mffgpr %0,%1 8711 mfvsrd %0,%x1 8712 mtvsrd %x0,%1" 8713 [(set_attr "type" 8714 "store, load, *, *, *, *, 8715 fpstore, fpload, fpsimple, fpstore, fpstore, fpload, 8716 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical, 8717 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *, 8718 mftgpr, mffgpr, mftgpr, mffgpr") 8719 8720 (set_attr "size" "64") 8721 (set_attr "length" 8722 "4, 4, 4, 4, 4, 20, 8723 4, 4, 4, 4, 4, 4, 8724 4, 4, 4, 4, 4, 8, 8725 8, 4, 4, 4, 4, 4, 8726 4, 4, 4, 4")]) 8727 8728; Some DImode loads are best done as a load of -1 followed by a mask 8729; instruction. 8730(define_split 8731 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 8732 (match_operand:DI 1 "const_int_operand"))] 8733 "TARGET_POWERPC64 8734 && num_insns_constant (operands[1], DImode) > 1 8735 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff) 8736 && rs6000_is_valid_and_mask (operands[1], DImode)" 8737 [(set (match_dup 0) 8738 (const_int -1)) 8739 (set (match_dup 0) 8740 (and:DI (match_dup 0) 8741 (match_dup 1)))] 8742 "") 8743 8744;; Split a load of a large constant into the appropriate five-instruction 8745;; sequence. Handle anything in a constant number of insns. 8746;; When non-easy constants can go in the TOC, this should use 8747;; easy_fp_constant predicate. 8748(define_split 8749 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "") 8750 (match_operand:DI 1 "const_int_operand" ""))] 8751 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 8752 [(set (match_dup 0) (match_dup 2)) 8753 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 8754 " 8755{ 8756 if (rs6000_emit_set_const (operands[0], operands[1])) 8757 DONE; 8758 else 8759 FAIL; 8760}") 8761 8762(define_split 8763 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "") 8764 (match_operand:DI 1 "const_scalar_int_operand" ""))] 8765 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 8766 [(set (match_dup 0) (match_dup 2)) 8767 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 8768 " 8769{ 8770 if (rs6000_emit_set_const (operands[0], operands[1])) 8771 DONE; 8772 else 8773 FAIL; 8774}") 8775 8776(define_split 8777 [(set (match_operand:DI 0 "altivec_register_operand" "") 8778 (match_operand:DI 1 "s5bit_cint_operand" ""))] 8779 "TARGET_UPPER_REGS_DI && TARGET_VSX && reload_completed" 8780 [(const_int 0)] 8781{ 8782 rtx op0 = operands[0]; 8783 rtx op1 = operands[1]; 8784 int r = REGNO (op0); 8785 rtx op0_v4si = gen_rtx_REG (V4SImode, r); 8786 8787 emit_insn (gen_altivec_vspltisw (op0_v4si, op1)); 8788 if (op1 != const0_rtx && op1 != constm1_rtx) 8789 { 8790 rtx op0_v2di = gen_rtx_REG (V2DImode, r); 8791 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si)); 8792 } 8793 DONE; 8794}) 8795 8796;; Split integer constants that can be loaded with XXSPLTIB and a 8797;; sign extend operation. 8798(define_split 8799 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "") 8800 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))] 8801 "TARGET_UPPER_REGS_DI && TARGET_P9_VECTOR && reload_completed" 8802 [(const_int 0)] 8803{ 8804 rtx op0 = operands[0]; 8805 rtx op1 = operands[1]; 8806 int r = REGNO (op0); 8807 rtx op0_v16qi = gen_rtx_REG (V16QImode, r); 8808 8809 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1)); 8810 if (<MODE>mode == DImode) 8811 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi)); 8812 else if (<MODE>mode == SImode) 8813 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi)); 8814 else if (<MODE>mode == HImode) 8815 { 8816 rtx op0_v8hi = gen_rtx_REG (V8HImode, r); 8817 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi)); 8818 } 8819 DONE; 8820}) 8821 8822 8823;; TImode/PTImode is similar, except that we usually want to compute the 8824;; address into a register and use lsi/stsi (the exception is during reload). 8825 8826(define_insn "*mov<mode>_string" 8827 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r") 8828 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))] 8829 "! TARGET_POWERPC64 8830 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode)) 8831 && (gpc_reg_operand (operands[0], <MODE>mode) 8832 || gpc_reg_operand (operands[1], <MODE>mode))" 8833 "* 8834{ 8835 switch (which_alternative) 8836 { 8837 default: 8838 gcc_unreachable (); 8839 case 0: 8840 if (TARGET_STRING) 8841 return \"stswi %1,%P0,16\"; 8842 /* FALLTHRU */ 8843 case 1: 8844 return \"#\"; 8845 case 2: 8846 /* If the address is not used in the output, we can use lsi. Otherwise, 8847 fall through to generating four loads. */ 8848 if (TARGET_STRING 8849 && ! reg_overlap_mentioned_p (operands[0], operands[1])) 8850 return \"lswi %0,%P1,16\"; 8851 /* fall through */ 8852 case 3: 8853 case 4: 8854 case 5: 8855 return \"#\"; 8856 } 8857}" 8858 [(set_attr "type" "store,store,load,load,*,*") 8859 (set_attr "update" "yes") 8860 (set_attr "indexed" "yes") 8861 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING") 8862 (const_string "always") 8863 (const_string "conditional")))]) 8864 8865(define_insn "*mov<mode>_ppc64" 8866 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r") 8867 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))] 8868 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode) 8869 && (gpc_reg_operand (operands[0], <MODE>mode) 8870 || gpc_reg_operand (operands[1], <MODE>mode)))" 8871{ 8872 return rs6000_output_move_128bit (operands); 8873} 8874 [(set_attr "type" "store,store,load,load,*,*") 8875 (set_attr "length" "8")]) 8876 8877(define_split 8878 [(set (match_operand:TI2 0 "int_reg_operand" "") 8879 (match_operand:TI2 1 "const_scalar_int_operand" ""))] 8880 "TARGET_POWERPC64 8881 && (VECTOR_MEM_NONE_P (<MODE>mode) 8882 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))" 8883 [(set (match_dup 2) (match_dup 4)) 8884 (set (match_dup 3) (match_dup 5))] 8885 " 8886{ 8887 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 8888 <MODE>mode); 8889 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 8890 <MODE>mode); 8891 if (CONST_WIDE_INT_P (operands[1])) 8892 { 8893 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1)); 8894 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0)); 8895 } 8896 else if (CONST_INT_P (operands[1])) 8897 { 8898 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); 8899 operands[5] = operands[1]; 8900 } 8901 else 8902 FAIL; 8903}") 8904 8905(define_split 8906 [(set (match_operand:TI2 0 "nonimmediate_operand" "") 8907 (match_operand:TI2 1 "input_operand" ""))] 8908 "reload_completed 8909 && gpr_or_gpr_p (operands[0], operands[1]) 8910 && !direct_move_p (operands[0], operands[1]) 8911 && !quad_load_store_p (operands[0], operands[1])" 8912 [(pc)] 8913{ rs6000_split_multireg_move (operands[0], operands[1]); DONE; }) 8914 8915(define_expand "load_multiple" 8916 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 8917 (match_operand:SI 1 "" "")) 8918 (use (match_operand:SI 2 "" ""))])] 8919 "TARGET_STRING && !TARGET_POWERPC64" 8920 " 8921{ 8922 int regno; 8923 int count; 8924 rtx op1; 8925 int i; 8926 8927 /* Support only loading a constant number of fixed-point registers from 8928 memory and only bother with this if more than two; the machine 8929 doesn't support more than eight. */ 8930 if (GET_CODE (operands[2]) != CONST_INT 8931 || INTVAL (operands[2]) <= 2 8932 || INTVAL (operands[2]) > 8 8933 || GET_CODE (operands[1]) != MEM 8934 || GET_CODE (operands[0]) != REG 8935 || REGNO (operands[0]) >= 32) 8936 FAIL; 8937 8938 count = INTVAL (operands[2]); 8939 regno = REGNO (operands[0]); 8940 8941 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count)); 8942 op1 = replace_equiv_address (operands[1], 8943 force_reg (SImode, XEXP (operands[1], 0))); 8944 8945 for (i = 0; i < count; i++) 8946 XVECEXP (operands[3], 0, i) 8947 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i), 8948 adjust_address_nv (op1, SImode, i * 4)); 8949}") 8950 8951(define_insn "*ldmsi8" 8952 [(match_parallel 0 "load_multiple_operation" 8953 [(set (match_operand:SI 2 "gpc_reg_operand" "") 8954 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 8955 (set (match_operand:SI 3 "gpc_reg_operand" "") 8956 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 8957 (set (match_operand:SI 4 "gpc_reg_operand" "") 8958 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 8959 (set (match_operand:SI 5 "gpc_reg_operand" "") 8960 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) 8961 (set (match_operand:SI 6 "gpc_reg_operand" "") 8962 (mem:SI (plus:SI (match_dup 1) (const_int 16)))) 8963 (set (match_operand:SI 7 "gpc_reg_operand" "") 8964 (mem:SI (plus:SI (match_dup 1) (const_int 20)))) 8965 (set (match_operand:SI 8 "gpc_reg_operand" "") 8966 (mem:SI (plus:SI (match_dup 1) (const_int 24)))) 8967 (set (match_operand:SI 9 "gpc_reg_operand" "") 8968 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])] 8969 "TARGET_STRING && XVECLEN (operands[0], 0) == 8" 8970 "* 8971{ return rs6000_output_load_multiple (operands); }" 8972 [(set_attr "type" "load") 8973 (set_attr "update" "yes") 8974 (set_attr "indexed" "yes") 8975 (set_attr "length" "32")]) 8976 8977(define_insn "*ldmsi7" 8978 [(match_parallel 0 "load_multiple_operation" 8979 [(set (match_operand:SI 2 "gpc_reg_operand" "") 8980 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 8981 (set (match_operand:SI 3 "gpc_reg_operand" "") 8982 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 8983 (set (match_operand:SI 4 "gpc_reg_operand" "") 8984 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 8985 (set (match_operand:SI 5 "gpc_reg_operand" "") 8986 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) 8987 (set (match_operand:SI 6 "gpc_reg_operand" "") 8988 (mem:SI (plus:SI (match_dup 1) (const_int 16)))) 8989 (set (match_operand:SI 7 "gpc_reg_operand" "") 8990 (mem:SI (plus:SI (match_dup 1) (const_int 20)))) 8991 (set (match_operand:SI 8 "gpc_reg_operand" "") 8992 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])] 8993 "TARGET_STRING && XVECLEN (operands[0], 0) == 7" 8994 "* 8995{ return rs6000_output_load_multiple (operands); }" 8996 [(set_attr "type" "load") 8997 (set_attr "update" "yes") 8998 (set_attr "indexed" "yes") 8999 (set_attr "length" "32")]) 9000 9001(define_insn "*ldmsi6" 9002 [(match_parallel 0 "load_multiple_operation" 9003 [(set (match_operand:SI 2 "gpc_reg_operand" "") 9004 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 9005 (set (match_operand:SI 3 "gpc_reg_operand" "") 9006 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 9007 (set (match_operand:SI 4 "gpc_reg_operand" "") 9008 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 9009 (set (match_operand:SI 5 "gpc_reg_operand" "") 9010 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) 9011 (set (match_operand:SI 6 "gpc_reg_operand" "") 9012 (mem:SI (plus:SI (match_dup 1) (const_int 16)))) 9013 (set (match_operand:SI 7 "gpc_reg_operand" "") 9014 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])] 9015 "TARGET_STRING && XVECLEN (operands[0], 0) == 6" 9016 "* 9017{ return rs6000_output_load_multiple (operands); }" 9018 [(set_attr "type" "load") 9019 (set_attr "update" "yes") 9020 (set_attr "indexed" "yes") 9021 (set_attr "length" "32")]) 9022 9023(define_insn "*ldmsi5" 9024 [(match_parallel 0 "load_multiple_operation" 9025 [(set (match_operand:SI 2 "gpc_reg_operand" "") 9026 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 9027 (set (match_operand:SI 3 "gpc_reg_operand" "") 9028 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 9029 (set (match_operand:SI 4 "gpc_reg_operand" "") 9030 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 9031 (set (match_operand:SI 5 "gpc_reg_operand" "") 9032 (mem:SI (plus:SI (match_dup 1) (const_int 12)))) 9033 (set (match_operand:SI 6 "gpc_reg_operand" "") 9034 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])] 9035 "TARGET_STRING && XVECLEN (operands[0], 0) == 5" 9036 "* 9037{ return rs6000_output_load_multiple (operands); }" 9038 [(set_attr "type" "load") 9039 (set_attr "update" "yes") 9040 (set_attr "indexed" "yes") 9041 (set_attr "length" "32")]) 9042 9043(define_insn "*ldmsi4" 9044 [(match_parallel 0 "load_multiple_operation" 9045 [(set (match_operand:SI 2 "gpc_reg_operand" "") 9046 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 9047 (set (match_operand:SI 3 "gpc_reg_operand" "") 9048 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 9049 (set (match_operand:SI 4 "gpc_reg_operand" "") 9050 (mem:SI (plus:SI (match_dup 1) (const_int 8)))) 9051 (set (match_operand:SI 5 "gpc_reg_operand" "") 9052 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])] 9053 "TARGET_STRING && XVECLEN (operands[0], 0) == 4" 9054 "* 9055{ return rs6000_output_load_multiple (operands); }" 9056 [(set_attr "type" "load") 9057 (set_attr "update" "yes") 9058 (set_attr "indexed" "yes") 9059 (set_attr "length" "32")]) 9060 9061(define_insn "*ldmsi3" 9062 [(match_parallel 0 "load_multiple_operation" 9063 [(set (match_operand:SI 2 "gpc_reg_operand" "") 9064 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))) 9065 (set (match_operand:SI 3 "gpc_reg_operand" "") 9066 (mem:SI (plus:SI (match_dup 1) (const_int 4)))) 9067 (set (match_operand:SI 4 "gpc_reg_operand" "") 9068 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])] 9069 "TARGET_STRING && XVECLEN (operands[0], 0) == 3" 9070 "* 9071{ return rs6000_output_load_multiple (operands); }" 9072 [(set_attr "type" "load") 9073 (set_attr "update" "yes") 9074 (set_attr "indexed" "yes") 9075 (set_attr "length" "32")]) 9076 9077(define_expand "store_multiple" 9078 [(match_par_dup 3 [(set (match_operand:SI 0 "" "") 9079 (match_operand:SI 1 "" "")) 9080 (clobber (scratch:SI)) 9081 (use (match_operand:SI 2 "" ""))])] 9082 "TARGET_STRING && !TARGET_POWERPC64" 9083 " 9084{ 9085 int regno; 9086 int count; 9087 rtx to; 9088 rtx op0; 9089 int i; 9090 9091 /* Support only storing a constant number of fixed-point registers to 9092 memory and only bother with this if more than two; the machine 9093 doesn't support more than eight. */ 9094 if (GET_CODE (operands[2]) != CONST_INT 9095 || INTVAL (operands[2]) <= 2 9096 || INTVAL (operands[2]) > 8 9097 || GET_CODE (operands[0]) != MEM 9098 || GET_CODE (operands[1]) != REG 9099 || REGNO (operands[1]) >= 32) 9100 FAIL; 9101 9102 count = INTVAL (operands[2]); 9103 regno = REGNO (operands[1]); 9104 9105 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1)); 9106 to = force_reg (SImode, XEXP (operands[0], 0)); 9107 op0 = replace_equiv_address (operands[0], to); 9108 9109 XVECEXP (operands[3], 0, 0) 9110 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]); 9111 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode, 9112 gen_rtx_SCRATCH (SImode)); 9113 9114 for (i = 1; i < count; i++) 9115 XVECEXP (operands[3], 0, i + 1) 9116 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4), 9117 gen_rtx_REG (SImode, regno + i)); 9118}") 9119 9120(define_insn "*stmsi8" 9121 [(match_parallel 0 "store_multiple_operation" 9122 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 9123 (match_operand:SI 2 "gpc_reg_operand" "r")) 9124 (clobber (match_scratch:SI 3 "=X")) 9125 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 9126 (match_operand:SI 4 "gpc_reg_operand" "r")) 9127 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 9128 (match_operand:SI 5 "gpc_reg_operand" "r")) 9129 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 9130 (match_operand:SI 6 "gpc_reg_operand" "r")) 9131 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 9132 (match_operand:SI 7 "gpc_reg_operand" "r")) 9133 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 9134 (match_operand:SI 8 "gpc_reg_operand" "r")) 9135 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) 9136 (match_operand:SI 9 "gpc_reg_operand" "r")) 9137 (set (mem:SI (plus:SI (match_dup 1) (const_int 28))) 9138 (match_operand:SI 10 "gpc_reg_operand" "r"))])] 9139 "TARGET_STRING && XVECLEN (operands[0], 0) == 9" 9140 "stswi %2,%1,%O0" 9141 [(set_attr "type" "store") 9142 (set_attr "update" "yes") 9143 (set_attr "indexed" "yes") 9144 (set_attr "cell_micro" "always")]) 9145 9146(define_insn "*stmsi7" 9147 [(match_parallel 0 "store_multiple_operation" 9148 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 9149 (match_operand:SI 2 "gpc_reg_operand" "r")) 9150 (clobber (match_scratch:SI 3 "=X")) 9151 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 9152 (match_operand:SI 4 "gpc_reg_operand" "r")) 9153 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 9154 (match_operand:SI 5 "gpc_reg_operand" "r")) 9155 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 9156 (match_operand:SI 6 "gpc_reg_operand" "r")) 9157 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 9158 (match_operand:SI 7 "gpc_reg_operand" "r")) 9159 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 9160 (match_operand:SI 8 "gpc_reg_operand" "r")) 9161 (set (mem:SI (plus:SI (match_dup 1) (const_int 24))) 9162 (match_operand:SI 9 "gpc_reg_operand" "r"))])] 9163 "TARGET_STRING && XVECLEN (operands[0], 0) == 8" 9164 "stswi %2,%1,%O0" 9165 [(set_attr "type" "store") 9166 (set_attr "update" "yes") 9167 (set_attr "indexed" "yes") 9168 (set_attr "cell_micro" "always")]) 9169 9170(define_insn "*stmsi6" 9171 [(match_parallel 0 "store_multiple_operation" 9172 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 9173 (match_operand:SI 2 "gpc_reg_operand" "r")) 9174 (clobber (match_scratch:SI 3 "=X")) 9175 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 9176 (match_operand:SI 4 "gpc_reg_operand" "r")) 9177 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 9178 (match_operand:SI 5 "gpc_reg_operand" "r")) 9179 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 9180 (match_operand:SI 6 "gpc_reg_operand" "r")) 9181 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 9182 (match_operand:SI 7 "gpc_reg_operand" "r")) 9183 (set (mem:SI (plus:SI (match_dup 1) (const_int 20))) 9184 (match_operand:SI 8 "gpc_reg_operand" "r"))])] 9185 "TARGET_STRING && XVECLEN (operands[0], 0) == 7" 9186 "stswi %2,%1,%O0" 9187 [(set_attr "type" "store") 9188 (set_attr "update" "yes") 9189 (set_attr "indexed" "yes") 9190 (set_attr "cell_micro" "always")]) 9191 9192(define_insn "*stmsi5" 9193 [(match_parallel 0 "store_multiple_operation" 9194 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 9195 (match_operand:SI 2 "gpc_reg_operand" "r")) 9196 (clobber (match_scratch:SI 3 "=X")) 9197 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 9198 (match_operand:SI 4 "gpc_reg_operand" "r")) 9199 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 9200 (match_operand:SI 5 "gpc_reg_operand" "r")) 9201 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 9202 (match_operand:SI 6 "gpc_reg_operand" "r")) 9203 (set (mem:SI (plus:SI (match_dup 1) (const_int 16))) 9204 (match_operand:SI 7 "gpc_reg_operand" "r"))])] 9205 "TARGET_STRING && XVECLEN (operands[0], 0) == 6" 9206 "stswi %2,%1,%O0" 9207 [(set_attr "type" "store") 9208 (set_attr "update" "yes") 9209 (set_attr "indexed" "yes") 9210 (set_attr "cell_micro" "always")]) 9211 9212(define_insn "*stmsi4" 9213 [(match_parallel 0 "store_multiple_operation" 9214 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 9215 (match_operand:SI 2 "gpc_reg_operand" "r")) 9216 (clobber (match_scratch:SI 3 "=X")) 9217 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 9218 (match_operand:SI 4 "gpc_reg_operand" "r")) 9219 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 9220 (match_operand:SI 5 "gpc_reg_operand" "r")) 9221 (set (mem:SI (plus:SI (match_dup 1) (const_int 12))) 9222 (match_operand:SI 6 "gpc_reg_operand" "r"))])] 9223 "TARGET_STRING && XVECLEN (operands[0], 0) == 5" 9224 "stswi %2,%1,%O0" 9225 [(set_attr "type" "store") 9226 (set_attr "update" "yes") 9227 (set_attr "indexed" "yes") 9228 (set_attr "cell_micro" "always")]) 9229 9230(define_insn "*stmsi3" 9231 [(match_parallel 0 "store_multiple_operation" 9232 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")) 9233 (match_operand:SI 2 "gpc_reg_operand" "r")) 9234 (clobber (match_scratch:SI 3 "=X")) 9235 (set (mem:SI (plus:SI (match_dup 1) (const_int 4))) 9236 (match_operand:SI 4 "gpc_reg_operand" "r")) 9237 (set (mem:SI (plus:SI (match_dup 1) (const_int 8))) 9238 (match_operand:SI 5 "gpc_reg_operand" "r"))])] 9239 "TARGET_STRING && XVECLEN (operands[0], 0) == 4" 9240 "stswi %2,%1,%O0" 9241 [(set_attr "type" "store") 9242 (set_attr "update" "yes") 9243 (set_attr "indexed" "yes") 9244 (set_attr "cell_micro" "always")]) 9245 9246(define_expand "setmemsi" 9247 [(parallel [(set (match_operand:BLK 0 "" "") 9248 (match_operand 2 "const_int_operand" "")) 9249 (use (match_operand:SI 1 "" "")) 9250 (use (match_operand:SI 3 "" ""))])] 9251 "" 9252 " 9253{ 9254 /* If value to set is not zero, use the library routine. */ 9255 if (operands[2] != const0_rtx) 9256 FAIL; 9257 9258 if (expand_block_clear (operands)) 9259 DONE; 9260 else 9261 FAIL; 9262}") 9263 9264;; String compare N insn. 9265;; Argument 0 is the target (result) 9266;; Argument 1 is the destination 9267;; Argument 2 is the source 9268;; Argument 3 is the length 9269;; Argument 4 is the alignment 9270 9271(define_expand "cmpstrnsi" 9272 [(parallel [(set (match_operand:SI 0) 9273 (compare:SI (match_operand:BLK 1) 9274 (match_operand:BLK 2))) 9275 (use (match_operand:SI 3)) 9276 (use (match_operand:SI 4))])] 9277 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)" 9278{ 9279 if (optimize_insn_for_size_p ()) 9280 FAIL; 9281 9282 if (expand_strn_compare (operands, 0)) 9283 DONE; 9284 else 9285 FAIL; 9286}) 9287 9288;; String compare insn. 9289;; Argument 0 is the target (result) 9290;; Argument 1 is the destination 9291;; Argument 2 is the source 9292;; Argument 3 is the alignment 9293 9294(define_expand "cmpstrsi" 9295 [(parallel [(set (match_operand:SI 0) 9296 (compare:SI (match_operand:BLK 1) 9297 (match_operand:BLK 2))) 9298 (use (match_operand:SI 3))])] 9299 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)" 9300{ 9301 if (optimize_insn_for_size_p ()) 9302 FAIL; 9303 9304 if (expand_strn_compare (operands, 1)) 9305 DONE; 9306 else 9307 FAIL; 9308}) 9309 9310;; Block compare insn. 9311;; Argument 0 is the target (result) 9312;; Argument 1 is the destination 9313;; Argument 2 is the source 9314;; Argument 3 is the length 9315;; Argument 4 is the alignment 9316 9317(define_expand "cmpmemsi" 9318 [(parallel [(set (match_operand:SI 0) 9319 (compare:SI (match_operand:BLK 1) 9320 (match_operand:BLK 2))) 9321 (use (match_operand:SI 3)) 9322 (use (match_operand:SI 4))])] 9323 "TARGET_POPCNTD" 9324{ 9325 if (expand_block_compare (operands)) 9326 DONE; 9327 else 9328 FAIL; 9329}) 9330 9331;; String/block move insn. 9332;; Argument 0 is the destination 9333;; Argument 1 is the source 9334;; Argument 2 is the length 9335;; Argument 3 is the alignment 9336 9337(define_expand "movmemsi" 9338 [(parallel [(set (match_operand:BLK 0 "" "") 9339 (match_operand:BLK 1 "" "")) 9340 (use (match_operand:SI 2 "" "")) 9341 (use (match_operand:SI 3 "" ""))])] 9342 "" 9343 " 9344{ 9345 if (expand_block_move (operands)) 9346 DONE; 9347 else 9348 FAIL; 9349}") 9350 9351;; Move up to 32 bytes at a time. The fixed registers are needed because the 9352;; register allocator doesn't have a clue about allocating 8 word registers. 9353;; rD/rS = r5 is preferred, efficient form. 9354(define_expand "movmemsi_8reg" 9355 [(parallel [(set (match_operand 0 "" "") 9356 (match_operand 1 "" "")) 9357 (use (match_operand 2 "" "")) 9358 (use (match_operand 3 "" "")) 9359 (clobber (reg:SI 5)) 9360 (clobber (reg:SI 6)) 9361 (clobber (reg:SI 7)) 9362 (clobber (reg:SI 8)) 9363 (clobber (reg:SI 9)) 9364 (clobber (reg:SI 10)) 9365 (clobber (reg:SI 11)) 9366 (clobber (reg:SI 12)) 9367 (clobber (match_scratch:SI 4 ""))])] 9368 "TARGET_STRING" 9369 "") 9370 9371(define_insn "" 9372 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) 9373 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) 9374 (use (match_operand:SI 2 "immediate_operand" "i")) 9375 (use (match_operand:SI 3 "immediate_operand" "i")) 9376 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) 9377 (clobber (reg:SI 6)) 9378 (clobber (reg:SI 7)) 9379 (clobber (reg:SI 8)) 9380 (clobber (reg:SI 9)) 9381 (clobber (reg:SI 10)) 9382 (clobber (reg:SI 11)) 9383 (clobber (reg:SI 12)) 9384 (clobber (match_scratch:SI 5 "=X"))] 9385 "TARGET_STRING 9386 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32) 9387 || INTVAL (operands[2]) == 0) 9388 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12) 9389 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12) 9390 && REGNO (operands[4]) == 5" 9391 "lswi %4,%1,%2\;stswi %4,%0,%2" 9392 [(set_attr "type" "store") 9393 (set_attr "update" "yes") 9394 (set_attr "indexed" "yes") 9395 (set_attr "cell_micro" "always") 9396 (set_attr "length" "8")]) 9397 9398;; Move up to 24 bytes at a time. The fixed registers are needed because the 9399;; register allocator doesn't have a clue about allocating 6 word registers. 9400;; rD/rS = r5 is preferred, efficient form. 9401(define_expand "movmemsi_6reg" 9402 [(parallel [(set (match_operand 0 "" "") 9403 (match_operand 1 "" "")) 9404 (use (match_operand 2 "" "")) 9405 (use (match_operand 3 "" "")) 9406 (clobber (reg:SI 5)) 9407 (clobber (reg:SI 6)) 9408 (clobber (reg:SI 7)) 9409 (clobber (reg:SI 8)) 9410 (clobber (reg:SI 9)) 9411 (clobber (reg:SI 10)) 9412 (clobber (match_scratch:SI 4 ""))])] 9413 "TARGET_STRING" 9414 "") 9415 9416(define_insn "" 9417 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) 9418 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) 9419 (use (match_operand:SI 2 "immediate_operand" "i")) 9420 (use (match_operand:SI 3 "immediate_operand" "i")) 9421 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) 9422 (clobber (reg:SI 6)) 9423 (clobber (reg:SI 7)) 9424 (clobber (reg:SI 8)) 9425 (clobber (reg:SI 9)) 9426 (clobber (reg:SI 10)) 9427 (clobber (match_scratch:SI 5 "=X"))] 9428 "TARGET_STRING 9429 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32 9430 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10) 9431 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10) 9432 && REGNO (operands[4]) == 5" 9433 "lswi %4,%1,%2\;stswi %4,%0,%2" 9434 [(set_attr "type" "store") 9435 (set_attr "update" "yes") 9436 (set_attr "indexed" "yes") 9437 (set_attr "cell_micro" "always") 9438 (set_attr "length" "8")]) 9439 9440;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill 9441;; problems with TImode. 9442;; rD/rS = r5 is preferred, efficient form. 9443(define_expand "movmemsi_4reg" 9444 [(parallel [(set (match_operand 0 "" "") 9445 (match_operand 1 "" "")) 9446 (use (match_operand 2 "" "")) 9447 (use (match_operand 3 "" "")) 9448 (clobber (reg:SI 5)) 9449 (clobber (reg:SI 6)) 9450 (clobber (reg:SI 7)) 9451 (clobber (reg:SI 8)) 9452 (clobber (match_scratch:SI 4 ""))])] 9453 "TARGET_STRING" 9454 "") 9455 9456(define_insn "" 9457 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) 9458 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) 9459 (use (match_operand:SI 2 "immediate_operand" "i")) 9460 (use (match_operand:SI 3 "immediate_operand" "i")) 9461 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r")) 9462 (clobber (reg:SI 6)) 9463 (clobber (reg:SI 7)) 9464 (clobber (reg:SI 8)) 9465 (clobber (match_scratch:SI 5 "=X"))] 9466 "TARGET_STRING 9467 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16 9468 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8) 9469 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8) 9470 && REGNO (operands[4]) == 5" 9471 "lswi %4,%1,%2\;stswi %4,%0,%2" 9472 [(set_attr "type" "store") 9473 (set_attr "update" "yes") 9474 (set_attr "indexed" "yes") 9475 (set_attr "cell_micro" "always") 9476 (set_attr "length" "8")]) 9477 9478;; Move up to 8 bytes at a time. 9479(define_expand "movmemsi_2reg" 9480 [(parallel [(set (match_operand 0 "" "") 9481 (match_operand 1 "" "")) 9482 (use (match_operand 2 "" "")) 9483 (use (match_operand 3 "" "")) 9484 (clobber (match_scratch:DI 4 "")) 9485 (clobber (match_scratch:SI 5 ""))])] 9486 "TARGET_STRING && ! TARGET_POWERPC64" 9487 "") 9488 9489(define_insn "" 9490 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b")) 9491 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b"))) 9492 (use (match_operand:SI 2 "immediate_operand" "i")) 9493 (use (match_operand:SI 3 "immediate_operand" "i")) 9494 (clobber (match_scratch:DI 4 "=&r")) 9495 (clobber (match_scratch:SI 5 "=X"))] 9496 "TARGET_STRING && ! TARGET_POWERPC64 9497 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8" 9498 "lswi %4,%1,%2\;stswi %4,%0,%2" 9499 [(set_attr "type" "store") 9500 (set_attr "update" "yes") 9501 (set_attr "indexed" "yes") 9502 (set_attr "cell_micro" "always") 9503 (set_attr "length" "8")]) 9504 9505;; Move up to 4 bytes at a time. 9506(define_expand "movmemsi_1reg" 9507 [(parallel [(set (match_operand 0 "" "") 9508 (match_operand 1 "" "")) 9509 (use (match_operand 2 "" "")) 9510 (use (match_operand 3 "" "")) 9511 (clobber (match_scratch:SI 4 "")) 9512 (clobber (match_scratch:SI 5 ""))])] 9513 "TARGET_STRING" 9514 "") 9515 9516(define_insn "" 9517 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b")) 9518 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b"))) 9519 (use (match_operand:SI 2 "immediate_operand" "i")) 9520 (use (match_operand:SI 3 "immediate_operand" "i")) 9521 (clobber (match_scratch:SI 4 "=&r")) 9522 (clobber (match_scratch:SI 5 "=X"))] 9523 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4" 9524 "lswi %4,%1,%2\;stswi %4,%0,%2" 9525 [(set_attr "type" "store") 9526 (set_attr "update" "yes") 9527 (set_attr "indexed" "yes") 9528 (set_attr "cell_micro" "always") 9529 (set_attr "length" "8")]) 9530 9531;; Define insns that do load or store with update. Some of these we can 9532;; get by using pre-decrement or pre-increment, but the hardware can also 9533;; do cases where the increment is not the size of the object. 9534;; 9535;; In all these cases, we use operands 0 and 1 for the register being 9536;; incremented because those are the operands that local-alloc will 9537;; tie and these are the pair most likely to be tieable (and the ones 9538;; that will benefit the most). 9539 9540(define_insn "*movdi_update1" 9541 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r") 9542 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") 9543 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))) 9544 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") 9545 (plus:DI (match_dup 1) (match_dup 2)))] 9546 "TARGET_POWERPC64 && TARGET_UPDATE 9547 && (!avoiding_indexed_address_p (DImode) 9548 || !gpc_reg_operand (operands[2], DImode))" 9549 "@ 9550 ldux %3,%0,%2 9551 ldu %3,%2(%0)" 9552 [(set_attr "type" "load") 9553 (set_attr "update" "yes") 9554 (set_attr "indexed" "yes,no")]) 9555 9556(define_insn "movdi_<mode>_update" 9557 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9558 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) 9559 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 9560 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9561 (plus:P (match_dup 1) (match_dup 2)))] 9562 "TARGET_POWERPC64 && TARGET_UPDATE 9563 && (!avoiding_indexed_address_p (Pmode) 9564 || !gpc_reg_operand (operands[2], Pmode) 9565 || (REG_P (operands[0]) 9566 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 9567 "@ 9568 stdux %3,%0,%2 9569 stdu %3,%2(%0)" 9570 [(set_attr "type" "store") 9571 (set_attr "update" "yes") 9572 (set_attr "indexed" "yes,no")]) 9573 9574;; This pattern is only conditional on TARGET_POWERPC64, as it is 9575;; needed for stack allocation, even if the user passes -mno-update. 9576(define_insn "movdi_<mode>_update_stack" 9577 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9578 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) 9579 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 9580 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9581 (plus:P (match_dup 1) (match_dup 2)))] 9582 "TARGET_POWERPC64" 9583 "@ 9584 stdux %3,%0,%2 9585 stdu %3,%2(%0)" 9586 [(set_attr "type" "store") 9587 (set_attr "update" "yes") 9588 (set_attr "indexed" "yes,no")]) 9589 9590(define_insn "*movsi_update1" 9591 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 9592 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9593 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9594 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9595 (plus:SI (match_dup 1) (match_dup 2)))] 9596 "TARGET_UPDATE 9597 && (!avoiding_indexed_address_p (SImode) 9598 || !gpc_reg_operand (operands[2], SImode))" 9599 "@ 9600 lwzux %3,%0,%2 9601 lwzu %3,%2(%0)" 9602 [(set_attr "type" "load") 9603 (set_attr "update" "yes") 9604 (set_attr "indexed" "yes,no")]) 9605 9606(define_insn "*movsi_update2" 9607 [(set (match_operand:DI 3 "gpc_reg_operand" "=r") 9608 (sign_extend:DI 9609 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0") 9610 (match_operand:DI 2 "gpc_reg_operand" "r"))))) 9611 (set (match_operand:DI 0 "gpc_reg_operand" "=b") 9612 (plus:DI (match_dup 1) (match_dup 2)))] 9613 "TARGET_POWERPC64 && rs6000_gen_cell_microcode 9614 && !avoiding_indexed_address_p (DImode)" 9615 "lwaux %3,%0,%2" 9616 [(set_attr "type" "load") 9617 (set_attr "sign_extend" "yes") 9618 (set_attr "update" "yes") 9619 (set_attr "indexed" "yes")]) 9620 9621(define_insn "movsi_update" 9622 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9623 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9624 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 9625 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9626 (plus:SI (match_dup 1) (match_dup 2)))] 9627 "TARGET_UPDATE 9628 && (!avoiding_indexed_address_p (SImode) 9629 || !gpc_reg_operand (operands[2], SImode) 9630 || (REG_P (operands[0]) 9631 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 9632 "@ 9633 stwux %3,%0,%2 9634 stwu %3,%2(%0)" 9635 [(set_attr "type" "store") 9636 (set_attr "update" "yes") 9637 (set_attr "indexed" "yes,no")]) 9638 9639;; This is an unconditional pattern; needed for stack allocation, even 9640;; if the user passes -mno-update. 9641(define_insn "movsi_update_stack" 9642 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9643 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9644 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 9645 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9646 (plus:SI (match_dup 1) (match_dup 2)))] 9647 "" 9648 "@ 9649 stwux %3,%0,%2 9650 stwu %3,%2(%0)" 9651 [(set_attr "type" "store") 9652 (set_attr "update" "yes") 9653 (set_attr "indexed" "yes,no")]) 9654 9655(define_insn "*movhi_update1" 9656 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r") 9657 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9658 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9659 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9660 (plus:SI (match_dup 1) (match_dup 2)))] 9661 "TARGET_UPDATE 9662 && (!avoiding_indexed_address_p (SImode) 9663 || !gpc_reg_operand (operands[2], SImode))" 9664 "@ 9665 lhzux %3,%0,%2 9666 lhzu %3,%2(%0)" 9667 [(set_attr "type" "load") 9668 (set_attr "update" "yes") 9669 (set_attr "indexed" "yes,no")]) 9670 9671(define_insn "*movhi_update2" 9672 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 9673 (zero_extend:SI 9674 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9675 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) 9676 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9677 (plus:SI (match_dup 1) (match_dup 2)))] 9678 "TARGET_UPDATE 9679 && (!avoiding_indexed_address_p (SImode) 9680 || !gpc_reg_operand (operands[2], SImode))" 9681 "@ 9682 lhzux %3,%0,%2 9683 lhzu %3,%2(%0)" 9684 [(set_attr "type" "load") 9685 (set_attr "update" "yes") 9686 (set_attr "indexed" "yes,no")]) 9687 9688(define_insn "*movhi_update3" 9689 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 9690 (sign_extend:SI 9691 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9692 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) 9693 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9694 (plus:SI (match_dup 1) (match_dup 2)))] 9695 "TARGET_UPDATE && rs6000_gen_cell_microcode 9696 && (!avoiding_indexed_address_p (SImode) 9697 || !gpc_reg_operand (operands[2], SImode))" 9698 "@ 9699 lhaux %3,%0,%2 9700 lhau %3,%2(%0)" 9701 [(set_attr "type" "load") 9702 (set_attr "sign_extend" "yes") 9703 (set_attr "update" "yes") 9704 (set_attr "indexed" "yes,no")]) 9705 9706(define_insn "*movhi_update4" 9707 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9708 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9709 (match_operand:HI 3 "gpc_reg_operand" "r,r")) 9710 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9711 (plus:SI (match_dup 1) (match_dup 2)))] 9712 "TARGET_UPDATE 9713 && (!avoiding_indexed_address_p (SImode) 9714 || !gpc_reg_operand (operands[2], SImode))" 9715 "@ 9716 sthux %3,%0,%2 9717 sthu %3,%2(%0)" 9718 [(set_attr "type" "store") 9719 (set_attr "update" "yes") 9720 (set_attr "indexed" "yes,no")]) 9721 9722(define_insn "*movqi_update1" 9723 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r") 9724 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9725 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9726 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9727 (plus:SI (match_dup 1) (match_dup 2)))] 9728 "TARGET_UPDATE 9729 && (!avoiding_indexed_address_p (SImode) 9730 || !gpc_reg_operand (operands[2], SImode))" 9731 "@ 9732 lbzux %3,%0,%2 9733 lbzu %3,%2(%0)" 9734 [(set_attr "type" "load") 9735 (set_attr "update" "yes") 9736 (set_attr "indexed" "yes,no")]) 9737 9738(define_insn "*movqi_update2" 9739 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 9740 (zero_extend:SI 9741 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9742 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))) 9743 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9744 (plus:SI (match_dup 1) (match_dup 2)))] 9745 "TARGET_UPDATE 9746 && (!avoiding_indexed_address_p (SImode) 9747 || !gpc_reg_operand (operands[2], SImode))" 9748 "@ 9749 lbzux %3,%0,%2 9750 lbzu %3,%2(%0)" 9751 [(set_attr "type" "load") 9752 (set_attr "update" "yes") 9753 (set_attr "indexed" "yes,no")]) 9754 9755(define_insn "*movqi_update3" 9756 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9757 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9758 (match_operand:QI 3 "gpc_reg_operand" "r,r")) 9759 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9760 (plus:SI (match_dup 1) (match_dup 2)))] 9761 "TARGET_UPDATE 9762 && (!avoiding_indexed_address_p (SImode) 9763 || !gpc_reg_operand (operands[2], SImode))" 9764 "@ 9765 stbux %3,%0,%2 9766 stbu %3,%2(%0)" 9767 [(set_attr "type" "store") 9768 (set_attr "update" "yes") 9769 (set_attr "indexed" "yes,no")]) 9770 9771(define_insn "*movsf_update1" 9772 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f") 9773 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9774 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9775 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9776 (plus:SI (match_dup 1) (match_dup 2)))] 9777 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE 9778 && (!avoiding_indexed_address_p (SImode) 9779 || !gpc_reg_operand (operands[2], SImode))" 9780 "@ 9781 lfsux %3,%0,%2 9782 lfsu %3,%2(%0)" 9783 [(set_attr "type" "fpload") 9784 (set_attr "update" "yes") 9785 (set_attr "indexed" "yes,no")]) 9786 9787(define_insn "*movsf_update2" 9788 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9789 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9790 (match_operand:SF 3 "gpc_reg_operand" "f,f")) 9791 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9792 (plus:SI (match_dup 1) (match_dup 2)))] 9793 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE 9794 && (!avoiding_indexed_address_p (SImode) 9795 || !gpc_reg_operand (operands[2], SImode))" 9796 "@ 9797 stfsux %3,%0,%2 9798 stfsu %3,%2(%0)" 9799 [(set_attr "type" "fpstore") 9800 (set_attr "update" "yes") 9801 (set_attr "indexed" "yes,no")]) 9802 9803(define_insn "*movsf_update3" 9804 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r") 9805 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9806 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9807 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9808 (plus:SI (match_dup 1) (match_dup 2)))] 9809 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE 9810 && (!avoiding_indexed_address_p (SImode) 9811 || !gpc_reg_operand (operands[2], SImode))" 9812 "@ 9813 lwzux %3,%0,%2 9814 lwzu %3,%2(%0)" 9815 [(set_attr "type" "load") 9816 (set_attr "update" "yes") 9817 (set_attr "indexed" "yes,no")]) 9818 9819(define_insn "*movsf_update4" 9820 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9821 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9822 (match_operand:SF 3 "gpc_reg_operand" "r,r")) 9823 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9824 (plus:SI (match_dup 1) (match_dup 2)))] 9825 "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE 9826 && (!avoiding_indexed_address_p (SImode) 9827 || !gpc_reg_operand (operands[2], SImode))" 9828 "@ 9829 stwux %3,%0,%2 9830 stwu %3,%2(%0)" 9831 [(set_attr "type" "store") 9832 (set_attr "update" "yes") 9833 (set_attr "indexed" "yes,no")]) 9834 9835(define_insn "*movdf_update1" 9836 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d") 9837 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9838 (match_operand:SI 2 "reg_or_short_operand" "r,I")))) 9839 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9840 (plus:SI (match_dup 1) (match_dup 2)))] 9841 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE 9842 && (!avoiding_indexed_address_p (SImode) 9843 || !gpc_reg_operand (operands[2], SImode))" 9844 "@ 9845 lfdux %3,%0,%2 9846 lfdu %3,%2(%0)" 9847 [(set_attr "type" "fpload") 9848 (set_attr "update" "yes") 9849 (set_attr "indexed" "yes,no") 9850 (set_attr "size" "64")]) 9851 9852(define_insn "*movdf_update2" 9853 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9854 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9855 (match_operand:DF 3 "gpc_reg_operand" "d,d")) 9856 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9857 (plus:SI (match_dup 1) (match_dup 2)))] 9858 "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE 9859 && (!avoiding_indexed_address_p (SImode) 9860 || !gpc_reg_operand (operands[2], SImode))" 9861 "@ 9862 stfdux %3,%0,%2 9863 stfdu %3,%2(%0)" 9864 [(set_attr "type" "fpstore") 9865 (set_attr "update" "yes") 9866 (set_attr "indexed" "yes,no")]) 9867 9868 9869;; After inserting conditional returns we can sometimes have 9870;; unnecessary register moves. Unfortunately we cannot have a 9871;; modeless peephole here, because some single SImode sets have early 9872;; clobber outputs. Although those sets expand to multi-ppc-insn 9873;; sequences, using get_attr_length here will smash the operands 9874;; array. Neither is there an early_cobbler_p predicate. 9875;; Disallow subregs for E500 so we don't munge frob_di_df_2. 9876;; Also this optimization interferes with scalars going into 9877;; altivec registers (the code does reloading through the FPRs). 9878(define_peephole2 9879 [(set (match_operand:DF 0 "gpc_reg_operand" "") 9880 (match_operand:DF 1 "any_operand" "")) 9881 (set (match_operand:DF 2 "gpc_reg_operand" "") 9882 (match_dup 0))] 9883 "!(TARGET_E500_DOUBLE && GET_CODE (operands[2]) == SUBREG) 9884 && !TARGET_UPPER_REGS_DF 9885 && peep2_reg_dead_p (2, operands[0])" 9886 [(set (match_dup 2) (match_dup 1))]) 9887 9888(define_peephole2 9889 [(set (match_operand:SF 0 "gpc_reg_operand" "") 9890 (match_operand:SF 1 "any_operand" "")) 9891 (set (match_operand:SF 2 "gpc_reg_operand" "") 9892 (match_dup 0))] 9893 "!TARGET_UPPER_REGS_SF 9894 && peep2_reg_dead_p (2, operands[0])" 9895 [(set (match_dup 2) (match_dup 1))]) 9896 9897 9898;; TLS support. 9899 9900;; Mode attributes for different ABIs. 9901(define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")]) 9902(define_mode_attr tls_abi_suffix [(SI "32") (DI "64")]) 9903(define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")]) 9904(define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")]) 9905 9906(define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>" 9907 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9908 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) 9909 (match_operand 4 "" "g"))) 9910 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9911 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9912 UNSPEC_TLSGD) 9913 (clobber (reg:SI LR_REGNO))] 9914 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 9915{ 9916 if (TARGET_CMODEL != CMODEL_SMALL) 9917 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;" 9918 "bl %z3\;nop"; 9919 else 9920 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop"; 9921} 9922 "&& TARGET_TLS_MARKERS" 9923 [(set (match_dup 0) 9924 (unspec:TLSmode [(match_dup 1) 9925 (match_dup 2)] 9926 UNSPEC_TLSGD)) 9927 (parallel [(set (match_dup 0) 9928 (call (mem:TLSmode (match_dup 3)) 9929 (match_dup 4))) 9930 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) 9931 (clobber (reg:SI LR_REGNO))])] 9932 "" 9933 [(set_attr "type" "two") 9934 (set (attr "length") 9935 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9936 (const_int 16) 9937 (const_int 12)))]) 9938 9939(define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>" 9940 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9941 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s")) 9942 (match_operand 4 "" "g"))) 9943 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9944 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9945 UNSPEC_TLSGD) 9946 (clobber (reg:SI LR_REGNO))] 9947 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" 9948{ 9949 if (flag_pic) 9950 { 9951 if (TARGET_SECURE_PLT && flag_pic == 2) 9952 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt"; 9953 else 9954 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt"; 9955 } 9956 else 9957 return "addi %0,%1,%2@got@tlsgd\;bl %z3"; 9958} 9959 "&& TARGET_TLS_MARKERS" 9960 [(set (match_dup 0) 9961 (unspec:TLSmode [(match_dup 1) 9962 (match_dup 2)] 9963 UNSPEC_TLSGD)) 9964 (parallel [(set (match_dup 0) 9965 (call (mem:TLSmode (match_dup 3)) 9966 (match_dup 4))) 9967 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD) 9968 (clobber (reg:SI LR_REGNO))])] 9969 "" 9970 [(set_attr "type" "two") 9971 (set_attr "length" "8")]) 9972 9973(define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>" 9974 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9975 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 9976 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 9977 UNSPEC_TLSGD))] 9978 "HAVE_AS_TLS && TARGET_TLS_MARKERS" 9979 "addi %0,%1,%2@got@tlsgd" 9980 "&& TARGET_CMODEL != CMODEL_SMALL" 9981 [(set (match_dup 3) 9982 (high:TLSmode 9983 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) 9984 (set (match_dup 0) 9985 (lo_sum:TLSmode (match_dup 3) 9986 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))] 9987 " 9988{ 9989 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9990}" 9991 [(set (attr "length") 9992 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9993 (const_int 8) 9994 (const_int 4)))]) 9995 9996(define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>" 9997 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 9998 (high:TLSmode 9999 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10000 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10001 UNSPEC_TLSGD)))] 10002 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 10003 "addis %0,%1,%2@got@tlsgd@ha" 10004 [(set_attr "length" "4")]) 10005 10006(define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>" 10007 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10008 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 10009 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") 10010 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10011 UNSPEC_TLSGD)))] 10012 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 10013 "addi %0,%1,%2@got@tlsgd@l" 10014 [(set_attr "length" "4")]) 10015 10016(define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>" 10017 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10018 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 10019 (match_operand 2 "" "g"))) 10020 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] 10021 UNSPEC_TLSGD) 10022 (clobber (reg:SI LR_REGNO))] 10023 "HAVE_AS_TLS && TARGET_TLS_MARKERS 10024 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 10025 "bl %z1(%3@tlsgd)\;nop" 10026 [(set_attr "type" "branch") 10027 (set_attr "length" "8")]) 10028 10029(define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>" 10030 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10031 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 10032 (match_operand 2 "" "g"))) 10033 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")] 10034 UNSPEC_TLSGD) 10035 (clobber (reg:SI LR_REGNO))] 10036 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" 10037{ 10038 if (flag_pic) 10039 { 10040 if (TARGET_SECURE_PLT && flag_pic == 2) 10041 return "bl %z1+32768(%3@tlsgd)@plt"; 10042 return "bl %z1(%3@tlsgd)@plt"; 10043 } 10044 return "bl %z1(%3@tlsgd)"; 10045} 10046 [(set_attr "type" "branch") 10047 (set_attr "length" "4")]) 10048 10049(define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>" 10050 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10051 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) 10052 (match_operand 3 "" "g"))) 10053 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 10054 UNSPEC_TLSLD) 10055 (clobber (reg:SI LR_REGNO))] 10056 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 10057{ 10058 if (TARGET_CMODEL != CMODEL_SMALL) 10059 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;" 10060 "bl %z2\;nop"; 10061 else 10062 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop"; 10063} 10064 "&& TARGET_TLS_MARKERS" 10065 [(set (match_dup 0) 10066 (unspec:TLSmode [(match_dup 1)] 10067 UNSPEC_TLSLD)) 10068 (parallel [(set (match_dup 0) 10069 (call (mem:TLSmode (match_dup 2)) 10070 (match_dup 3))) 10071 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 10072 (clobber (reg:SI LR_REGNO))])] 10073 "" 10074 [(set_attr "type" "two") 10075 (set (attr "length") 10076 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 10077 (const_int 16) 10078 (const_int 12)))]) 10079 10080(define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>" 10081 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10082 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s")) 10083 (match_operand 3 "" "g"))) 10084 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 10085 UNSPEC_TLSLD) 10086 (clobber (reg:SI LR_REGNO))] 10087 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4" 10088{ 10089 if (flag_pic) 10090 { 10091 if (TARGET_SECURE_PLT && flag_pic == 2) 10092 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt"; 10093 else 10094 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt"; 10095 } 10096 else 10097 return "addi %0,%1,%&@got@tlsld\;bl %z2"; 10098} 10099 "&& TARGET_TLS_MARKERS" 10100 [(set (match_dup 0) 10101 (unspec:TLSmode [(match_dup 1)] 10102 UNSPEC_TLSLD)) 10103 (parallel [(set (match_dup 0) 10104 (call (mem:TLSmode (match_dup 2)) 10105 (match_dup 3))) 10106 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 10107 (clobber (reg:SI LR_REGNO))])] 10108 "" 10109 [(set_attr "length" "8")]) 10110 10111(define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>" 10112 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10113 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")] 10114 UNSPEC_TLSLD))] 10115 "HAVE_AS_TLS && TARGET_TLS_MARKERS" 10116 "addi %0,%1,%&@got@tlsld" 10117 "&& TARGET_CMODEL != CMODEL_SMALL" 10118 [(set (match_dup 2) 10119 (high:TLSmode 10120 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD))) 10121 (set (match_dup 0) 10122 (lo_sum:TLSmode (match_dup 2) 10123 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))] 10124 " 10125{ 10126 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 10127}" 10128 [(set (attr "length") 10129 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 10130 (const_int 8) 10131 (const_int 4)))]) 10132 10133(define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>" 10134 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10135 (high:TLSmode 10136 (unspec:TLSmode [(const_int 0) 10137 (match_operand:TLSmode 1 "gpc_reg_operand" "b")] 10138 UNSPEC_TLSLD)))] 10139 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 10140 "addis %0,%1,%&@got@tlsld@ha" 10141 [(set_attr "length" "4")]) 10142 10143(define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>" 10144 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10145 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 10146 (unspec:TLSmode [(const_int 0) 10147 (match_operand:TLSmode 2 "gpc_reg_operand" "b")] 10148 UNSPEC_TLSLD)))] 10149 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL" 10150 "addi %0,%1,%&@got@tlsld@l" 10151 [(set_attr "length" "4")]) 10152 10153(define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>" 10154 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10155 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 10156 (match_operand 2 "" "g"))) 10157 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 10158 (clobber (reg:SI LR_REGNO))] 10159 "HAVE_AS_TLS && TARGET_TLS_MARKERS 10160 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)" 10161 "bl %z1(%&@tlsld)\;nop" 10162 [(set_attr "type" "branch") 10163 (set_attr "length" "8")]) 10164 10165(define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>" 10166 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10167 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s")) 10168 (match_operand 2 "" "g"))) 10169 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD) 10170 (clobber (reg:SI LR_REGNO))] 10171 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS" 10172{ 10173 if (flag_pic) 10174 { 10175 if (TARGET_SECURE_PLT && flag_pic == 2) 10176 return "bl %z1+32768(%&@tlsld)@plt"; 10177 return "bl %z1(%&@tlsld)@plt"; 10178 } 10179 return "bl %z1(%&@tlsld)"; 10180} 10181 [(set_attr "type" "branch") 10182 (set_attr "length" "4")]) 10183 10184(define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>" 10185 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 10186 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10187 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10188 UNSPEC_TLSDTPREL))] 10189 "HAVE_AS_TLS" 10190 "addi %0,%1,%2@dtprel") 10191 10192(define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>" 10193 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 10194 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10195 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10196 UNSPEC_TLSDTPRELHA))] 10197 "HAVE_AS_TLS" 10198 "addis %0,%1,%2@dtprel@ha") 10199 10200(define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>" 10201 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 10202 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10203 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10204 UNSPEC_TLSDTPRELLO))] 10205 "HAVE_AS_TLS" 10206 "addi %0,%1,%2@dtprel@l") 10207 10208(define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>" 10209 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 10210 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10211 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10212 UNSPEC_TLSGOTDTPREL))] 10213 "HAVE_AS_TLS" 10214 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)" 10215 "&& TARGET_CMODEL != CMODEL_SMALL" 10216 [(set (match_dup 3) 10217 (high:TLSmode 10218 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) 10219 (set (match_dup 0) 10220 (lo_sum:TLSmode (match_dup 3) 10221 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))] 10222 " 10223{ 10224 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 10225}" 10226 [(set (attr "length") 10227 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 10228 (const_int 8) 10229 (const_int 4)))]) 10230 10231(define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>" 10232 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10233 (high:TLSmode 10234 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10235 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10236 UNSPEC_TLSGOTDTPREL)))] 10237 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 10238 "addis %0,%1,%2@got@dtprel@ha" 10239 [(set_attr "length" "4")]) 10240 10241(define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>" 10242 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 10243 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 10244 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") 10245 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10246 UNSPEC_TLSGOTDTPREL)))] 10247 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 10248 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)" 10249 [(set_attr "length" "4")]) 10250 10251(define_insn "tls_tprel_<TLSmode:tls_abi_suffix>" 10252 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 10253 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10254 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10255 UNSPEC_TLSTPREL))] 10256 "HAVE_AS_TLS" 10257 "addi %0,%1,%2@tprel") 10258 10259(define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>" 10260 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 10261 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10262 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10263 UNSPEC_TLSTPRELHA))] 10264 "HAVE_AS_TLS" 10265 "addis %0,%1,%2@tprel@ha") 10266 10267(define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>" 10268 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 10269 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10270 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10271 UNSPEC_TLSTPRELLO))] 10272 "HAVE_AS_TLS" 10273 "addi %0,%1,%2@tprel@l") 10274 10275;; "b" output constraint here and on tls_tls input to support linker tls 10276;; optimization. The linker may edit the instructions emitted by a 10277;; tls_got_tprel/tls_tls pair to addis,addi. 10278(define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>" 10279 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10280 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10281 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10282 UNSPEC_TLSGOTTPREL))] 10283 "HAVE_AS_TLS" 10284 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)" 10285 "&& TARGET_CMODEL != CMODEL_SMALL" 10286 [(set (match_dup 3) 10287 (high:TLSmode 10288 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) 10289 (set (match_dup 0) 10290 (lo_sum:TLSmode (match_dup 3) 10291 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))] 10292 " 10293{ 10294 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 10295}" 10296 [(set (attr "length") 10297 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 10298 (const_int 8) 10299 (const_int 4)))]) 10300 10301(define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>" 10302 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b") 10303 (high:TLSmode 10304 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10305 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10306 UNSPEC_TLSGOTTPREL)))] 10307 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 10308 "addis %0,%1,%2@got@tprel@ha" 10309 [(set_attr "length" "4")]) 10310 10311(define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>" 10312 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 10313 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b") 10314 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b") 10315 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10316 UNSPEC_TLSGOTTPREL)))] 10317 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 10318 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)" 10319 [(set_attr "length" "4")]) 10320 10321(define_insn "tls_tls_<TLSmode:tls_abi_suffix>" 10322 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r") 10323 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b") 10324 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")] 10325 UNSPEC_TLSTLS))] 10326 "TARGET_ELF && HAVE_AS_TLS" 10327 "add %0,%1,%2@tls") 10328 10329(define_expand "tls_get_tpointer" 10330 [(set (match_operand:SI 0 "gpc_reg_operand" "") 10331 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))] 10332 "TARGET_XCOFF && HAVE_AS_TLS" 10333 " 10334{ 10335 emit_insn (gen_tls_get_tpointer_internal ()); 10336 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); 10337 DONE; 10338}") 10339 10340(define_insn "tls_get_tpointer_internal" 10341 [(set (reg:SI 3) 10342 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS)) 10343 (clobber (reg:SI LR_REGNO))] 10344 "TARGET_XCOFF && HAVE_AS_TLS" 10345 "bla __get_tpointer") 10346 10347(define_expand "tls_get_addr<mode>" 10348 [(set (match_operand:P 0 "gpc_reg_operand" "") 10349 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "") 10350 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))] 10351 "TARGET_XCOFF && HAVE_AS_TLS" 10352 " 10353{ 10354 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]); 10355 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]); 10356 emit_insn (gen_tls_get_addr_internal<mode> ()); 10357 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3)); 10358 DONE; 10359}") 10360 10361(define_insn "tls_get_addr_internal<mode>" 10362 [(set (reg:P 3) 10363 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS)) 10364 (clobber (reg:P 0)) 10365 (clobber (reg:P 4)) 10366 (clobber (reg:P 5)) 10367 (clobber (reg:P 11)) 10368 (clobber (reg:CC CR0_REGNO)) 10369 (clobber (reg:P LR_REGNO))] 10370 "TARGET_XCOFF && HAVE_AS_TLS" 10371 "bla __tls_get_addr") 10372 10373;; Next come insns related to the calling sequence. 10374;; 10375;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). 10376;; We move the back-chain and decrement the stack pointer. 10377 10378(define_expand "allocate_stack" 10379 [(set (match_operand 0 "gpc_reg_operand" "") 10380 (minus (reg 1) (match_operand 1 "reg_or_short_operand" ""))) 10381 (set (reg 1) 10382 (minus (reg 1) (match_dup 1)))] 10383 "" 10384 " 10385{ rtx chain = gen_reg_rtx (Pmode); 10386 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); 10387 rtx neg_op0; 10388 rtx insn, par, set, mem; 10389 10390 emit_move_insn (chain, stack_bot); 10391 10392 /* Check stack bounds if necessary. */ 10393 if (crtl->limit_stack) 10394 { 10395 rtx available; 10396 available = expand_binop (Pmode, sub_optab, 10397 stack_pointer_rtx, stack_limit_rtx, 10398 NULL_RTX, 1, OPTAB_WIDEN); 10399 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx)); 10400 } 10401 10402 if (GET_CODE (operands[1]) != CONST_INT 10403 || INTVAL (operands[1]) < -32767 10404 || INTVAL (operands[1]) > 32768) 10405 { 10406 neg_op0 = gen_reg_rtx (Pmode); 10407 if (TARGET_32BIT) 10408 emit_insn (gen_negsi2 (neg_op0, operands[1])); 10409 else 10410 emit_insn (gen_negdi2 (neg_op0, operands[1])); 10411 } 10412 else 10413 neg_op0 = GEN_INT (- INTVAL (operands[1])); 10414 10415 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack 10416 : gen_movdi_di_update_stack)) 10417 (stack_pointer_rtx, stack_pointer_rtx, neg_op0, 10418 chain)); 10419 /* Since we didn't use gen_frame_mem to generate the MEM, grab 10420 it now and set the alias set/attributes. The above gen_*_update 10421 calls will generate a PARALLEL with the MEM set being the first 10422 operation. */ 10423 par = PATTERN (insn); 10424 gcc_assert (GET_CODE (par) == PARALLEL); 10425 set = XVECEXP (par, 0, 0); 10426 gcc_assert (GET_CODE (set) == SET); 10427 mem = SET_DEST (set); 10428 gcc_assert (MEM_P (mem)); 10429 MEM_NOTRAP_P (mem) = 1; 10430 set_mem_alias_set (mem, get_frame_alias_set ()); 10431 10432 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 10433 DONE; 10434}") 10435 10436;; These patterns say how to save and restore the stack pointer. We need not 10437;; save the stack pointer at function level since we are careful to 10438;; preserve the backchain. At block level, we have to restore the backchain 10439;; when we restore the stack pointer. 10440;; 10441;; For nonlocal gotos, we must save both the stack pointer and its 10442;; backchain and restore both. Note that in the nonlocal case, the 10443;; save area is a memory location. 10444 10445(define_expand "save_stack_function" 10446 [(match_operand 0 "any_operand" "") 10447 (match_operand 1 "any_operand" "")] 10448 "" 10449 "DONE;") 10450 10451(define_expand "restore_stack_function" 10452 [(match_operand 0 "any_operand" "") 10453 (match_operand 1 "any_operand" "")] 10454 "" 10455 "DONE;") 10456 10457;; Adjust stack pointer (op0) to a new value (op1). 10458;; First copy old stack backchain to new location, and ensure that the 10459;; scheduler won't reorder the sp assignment before the backchain write. 10460(define_expand "restore_stack_block" 10461 [(set (match_dup 2) (match_dup 3)) 10462 (set (match_dup 4) (match_dup 2)) 10463 (match_dup 5) 10464 (set (match_operand 0 "register_operand" "") 10465 (match_operand 1 "register_operand" ""))] 10466 "" 10467 " 10468{ 10469 rtvec p; 10470 10471 operands[1] = force_reg (Pmode, operands[1]); 10472 operands[2] = gen_reg_rtx (Pmode); 10473 operands[3] = gen_frame_mem (Pmode, operands[0]); 10474 operands[4] = gen_frame_mem (Pmode, operands[1]); 10475 p = rtvec_alloc (1); 10476 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 10477 const0_rtx); 10478 operands[5] = gen_rtx_PARALLEL (VOIDmode, p); 10479}") 10480 10481(define_expand "save_stack_nonlocal" 10482 [(set (match_dup 3) (match_dup 4)) 10483 (set (match_operand 0 "memory_operand" "") (match_dup 3)) 10484 (set (match_dup 2) (match_operand 1 "register_operand" ""))] 10485 "" 10486 " 10487{ 10488 int units_per_word = (TARGET_32BIT) ? 4 : 8; 10489 10490 /* Copy the backchain to the first word, sp to the second. */ 10491 operands[0] = adjust_address_nv (operands[0], Pmode, 0); 10492 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word); 10493 operands[3] = gen_reg_rtx (Pmode); 10494 operands[4] = gen_frame_mem (Pmode, operands[1]); 10495}") 10496 10497(define_expand "restore_stack_nonlocal" 10498 [(set (match_dup 2) (match_operand 1 "memory_operand" "")) 10499 (set (match_dup 3) (match_dup 4)) 10500 (set (match_dup 5) (match_dup 2)) 10501 (match_dup 6) 10502 (set (match_operand 0 "register_operand" "") (match_dup 3))] 10503 "" 10504 " 10505{ 10506 int units_per_word = (TARGET_32BIT) ? 4 : 8; 10507 rtvec p; 10508 10509 /* Restore the backchain from the first word, sp from the second. */ 10510 operands[2] = gen_reg_rtx (Pmode); 10511 operands[3] = gen_reg_rtx (Pmode); 10512 operands[1] = adjust_address_nv (operands[1], Pmode, 0); 10513 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word); 10514 operands[5] = gen_frame_mem (Pmode, operands[3]); 10515 p = rtvec_alloc (1); 10516 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 10517 const0_rtx); 10518 operands[6] = gen_rtx_PARALLEL (VOIDmode, p); 10519}") 10520 10521;; TOC register handling. 10522 10523;; Code to initialize the TOC register... 10524 10525(define_insn "load_toc_aix_si" 10526 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10527 (unspec:SI [(const_int 0)] UNSPEC_TOC)) 10528 (use (reg:SI 2))])] 10529 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT" 10530 "* 10531{ 10532 char buf[30]; 10533 extern int need_toc_init; 10534 need_toc_init = 1; 10535 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1); 10536 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 10537 operands[2] = gen_rtx_REG (Pmode, 2); 10538 return \"lwz %0,%1(%2)\"; 10539}" 10540 [(set_attr "type" "load") 10541 (set_attr "update" "no") 10542 (set_attr "indexed" "no")]) 10543 10544(define_insn "load_toc_aix_di" 10545 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10546 (unspec:DI [(const_int 0)] UNSPEC_TOC)) 10547 (use (reg:DI 2))])] 10548 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT" 10549 "* 10550{ 10551 char buf[30]; 10552 extern int need_toc_init; 10553 need_toc_init = 1; 10554 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 10555 !TARGET_ELF || !TARGET_MINIMAL_TOC); 10556 if (TARGET_ELF) 10557 strcat (buf, \"@toc\"); 10558 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 10559 operands[2] = gen_rtx_REG (Pmode, 2); 10560 return \"ld %0,%1(%2)\"; 10561}" 10562 [(set_attr "type" "load") 10563 (set_attr "update" "no") 10564 (set_attr "indexed" "no")]) 10565 10566(define_insn "load_toc_v4_pic_si" 10567 [(set (reg:SI LR_REGNO) 10568 (unspec:SI [(const_int 0)] UNSPEC_TOC))] 10569 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT" 10570 "bl _GLOBAL_OFFSET_TABLE_@local-4" 10571 [(set_attr "type" "branch") 10572 (set_attr "length" "4")]) 10573 10574(define_expand "load_toc_v4_PIC_1" 10575 [(parallel [(set (reg:SI LR_REGNO) 10576 (match_operand:SI 0 "immediate_operand" "s")) 10577 (use (unspec [(match_dup 0)] UNSPEC_TOC))])] 10578 "TARGET_ELF && DEFAULT_ABI == ABI_V4 10579 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10580 "") 10581 10582(define_insn "load_toc_v4_PIC_1_normal" 10583 [(set (reg:SI LR_REGNO) 10584 (match_operand:SI 0 "immediate_operand" "s")) 10585 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 10586 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 10587 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10588 "bcl 20,31,%0\\n%0:" 10589 [(set_attr "type" "branch") 10590 (set_attr "length" "4") 10591 (set_attr "cannot_copy" "yes")]) 10592 10593(define_insn "load_toc_v4_PIC_1_476" 10594 [(set (reg:SI LR_REGNO) 10595 (match_operand:SI 0 "immediate_operand" "s")) 10596 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 10597 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 10598 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10599 "* 10600{ 10601 char name[32]; 10602 static char templ[32]; 10603 10604 get_ppc476_thunk_name (name); 10605 sprintf (templ, \"bl %s\\n%%0:\", name); 10606 return templ; 10607}" 10608 [(set_attr "type" "branch") 10609 (set_attr "length" "4") 10610 (set_attr "cannot_copy" "yes")]) 10611 10612(define_expand "load_toc_v4_PIC_1b" 10613 [(parallel [(set (reg:SI LR_REGNO) 10614 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10615 (label_ref (match_operand 1 "" ""))] 10616 UNSPEC_TOCPTR)) 10617 (match_dup 1)])] 10618 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10619 "") 10620 10621(define_insn "load_toc_v4_PIC_1b_normal" 10622 [(set (reg:SI LR_REGNO) 10623 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10624 (label_ref (match_operand 1 "" ""))] 10625 UNSPEC_TOCPTR)) 10626 (match_dup 1)] 10627 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10628 "bcl 20,31,$+8\;.long %0-$" 10629 [(set_attr "type" "branch") 10630 (set_attr "length" "8")]) 10631 10632(define_insn "load_toc_v4_PIC_1b_476" 10633 [(set (reg:SI LR_REGNO) 10634 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10635 (label_ref (match_operand 1 "" ""))] 10636 UNSPEC_TOCPTR)) 10637 (match_dup 1)] 10638 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10639 "* 10640{ 10641 char name[32]; 10642 static char templ[32]; 10643 10644 get_ppc476_thunk_name (name); 10645 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name); 10646 return templ; 10647}" 10648 [(set_attr "type" "branch") 10649 (set_attr "length" "16")]) 10650 10651(define_insn "load_toc_v4_PIC_2" 10652 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10653 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") 10654 (minus:SI (match_operand:SI 2 "immediate_operand" "s") 10655 (match_operand:SI 3 "immediate_operand" "s")))))] 10656 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10657 "lwz %0,%2-%3(%1)" 10658 [(set_attr "type" "load")]) 10659 10660(define_insn "load_toc_v4_PIC_3b" 10661 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10662 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") 10663 (high:SI 10664 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 10665 (match_operand:SI 3 "symbol_ref_operand" "s")))))] 10666 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 10667 "addis %0,%1,%2-%3@ha") 10668 10669(define_insn "load_toc_v4_PIC_3c" 10670 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10671 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 10672 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 10673 (match_operand:SI 3 "symbol_ref_operand" "s"))))] 10674 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 10675 "addi %0,%1,%2-%3@l") 10676 10677;; If the TOC is shared over a translation unit, as happens with all 10678;; the kinds of PIC that we support, we need to restore the TOC 10679;; pointer only when jumping over units of translation. 10680;; On Darwin, we need to reload the picbase. 10681 10682(define_expand "builtin_setjmp_receiver" 10683 [(use (label_ref (match_operand 0 "" "")))] 10684 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1) 10685 || (TARGET_TOC && TARGET_MINIMAL_TOC) 10686 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)" 10687 " 10688{ 10689#if TARGET_MACHO 10690 if (DEFAULT_ABI == ABI_DARWIN) 10691 { 10692 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); 10693 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 10694 rtx tmplabrtx; 10695 char tmplab[20]; 10696 10697 crtl->uses_pic_offset_table = 1; 10698 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\", 10699 CODE_LABEL_NUMBER (operands[0])); 10700 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); 10701 10702 emit_insn (gen_load_macho_picbase (tmplabrtx)); 10703 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); 10704 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx)); 10705 } 10706 else 10707#endif 10708 rs6000_emit_load_toc_table (FALSE); 10709 DONE; 10710}") 10711 10712;; Largetoc support 10713(define_insn "*largetoc_high" 10714 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 10715 (high:DI 10716 (unspec [(match_operand:DI 1 "" "") 10717 (match_operand:DI 2 "gpc_reg_operand" "b")] 10718 UNSPEC_TOCREL)))] 10719 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10720 "addis %0,%2,%1@toc@ha") 10721 10722(define_insn "*largetoc_high_aix<mode>" 10723 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 10724 (high:P 10725 (unspec [(match_operand:P 1 "" "") 10726 (match_operand:P 2 "gpc_reg_operand" "b")] 10727 UNSPEC_TOCREL)))] 10728 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10729 "addis %0,%1@u(%2)") 10730 10731(define_insn "*largetoc_high_plus" 10732 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 10733 (high:DI 10734 (plus:DI 10735 (unspec [(match_operand:DI 1 "" "") 10736 (match_operand:DI 2 "gpc_reg_operand" "b")] 10737 UNSPEC_TOCREL) 10738 (match_operand:DI 3 "add_cint_operand" "n"))))] 10739 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10740 "addis %0,%2,%1+%3@toc@ha") 10741 10742(define_insn "*largetoc_high_plus_aix<mode>" 10743 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 10744 (high:P 10745 (plus:P 10746 (unspec [(match_operand:P 1 "" "") 10747 (match_operand:P 2 "gpc_reg_operand" "b")] 10748 UNSPEC_TOCREL) 10749 (match_operand:P 3 "add_cint_operand" "n"))))] 10750 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10751 "addis %0,%1+%3@u(%2)") 10752 10753(define_insn "*largetoc_low" 10754 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10755 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 10756 (match_operand:DI 2 "" "")))] 10757 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10758 "addi %0,%1,%2@l") 10759 10760(define_insn "*largetoc_low_aix<mode>" 10761 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10762 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 10763 (match_operand:P 2 "" "")))] 10764 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10765 "la %0,%2@l(%1)") 10766 10767(define_insn_and_split "*tocref<mode>" 10768 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10769 (match_operand:P 1 "small_toc_ref" "R"))] 10770 "TARGET_TOC" 10771 "la %0,%a1" 10772 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed" 10773 [(set (match_dup 0) (high:P (match_dup 1))) 10774 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))]) 10775 10776;; Elf specific ways of loading addresses for non-PIC code. 10777;; The output of this could be r0, but we make a very strong 10778;; preference for a base register because it will usually 10779;; be needed there. 10780(define_insn "elf_high" 10781 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") 10782 (high:SI (match_operand 1 "" "")))] 10783 "TARGET_ELF && !TARGET_64BIT && !flag_pic" 10784 "lis %0,%1@ha") 10785 10786(define_insn "elf_low" 10787 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10788 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 10789 (match_operand 2 "" "")))] 10790 "TARGET_ELF && !TARGET_64BIT && !flag_pic" 10791 "la %0,%2@l(%1)") 10792 10793;; Call and call_value insns 10794(define_expand "call" 10795 [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) 10796 (match_operand 1 "" "")) 10797 (use (match_operand 2 "" "")) 10798 (clobber (reg:SI LR_REGNO))])] 10799 "" 10800 " 10801{ 10802#if TARGET_MACHO 10803 if (MACHOPIC_INDIRECT) 10804 operands[0] = machopic_indirect_call_target (operands[0]); 10805#endif 10806 10807 gcc_assert (GET_CODE (operands[0]) == MEM); 10808 gcc_assert (GET_CODE (operands[1]) == CONST_INT); 10809 10810 operands[0] = XEXP (operands[0], 0); 10811 10812 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10813 { 10814 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]); 10815 DONE; 10816 } 10817 10818 if (GET_CODE (operands[0]) != SYMBOL_REF 10819 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0)) 10820 { 10821 if (INTVAL (operands[2]) & CALL_LONG) 10822 operands[0] = rs6000_longcall_ref (operands[0]); 10823 10824 switch (DEFAULT_ABI) 10825 { 10826 case ABI_V4: 10827 case ABI_DARWIN: 10828 operands[0] = force_reg (Pmode, operands[0]); 10829 break; 10830 10831 default: 10832 gcc_unreachable (); 10833 } 10834 } 10835}") 10836 10837(define_expand "call_value" 10838 [(parallel [(set (match_operand 0 "" "") 10839 (call (mem:SI (match_operand 1 "address_operand" "")) 10840 (match_operand 2 "" ""))) 10841 (use (match_operand 3 "" "")) 10842 (clobber (reg:SI LR_REGNO))])] 10843 "" 10844 " 10845{ 10846#if TARGET_MACHO 10847 if (MACHOPIC_INDIRECT) 10848 operands[1] = machopic_indirect_call_target (operands[1]); 10849#endif 10850 10851 gcc_assert (GET_CODE (operands[1]) == MEM); 10852 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 10853 10854 operands[1] = XEXP (operands[1], 0); 10855 10856 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10857 { 10858 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]); 10859 DONE; 10860 } 10861 10862 if (GET_CODE (operands[1]) != SYMBOL_REF 10863 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0)) 10864 { 10865 if (INTVAL (operands[3]) & CALL_LONG) 10866 operands[1] = rs6000_longcall_ref (operands[1]); 10867 10868 switch (DEFAULT_ABI) 10869 { 10870 case ABI_V4: 10871 case ABI_DARWIN: 10872 operands[1] = force_reg (Pmode, operands[1]); 10873 break; 10874 10875 default: 10876 gcc_unreachable (); 10877 } 10878 } 10879}") 10880 10881;; Call to function in current module. No TOC pointer reload needed. 10882;; Operand2 is nonzero if we are using the V.4 calling sequence and 10883;; either the function was not prototyped, or it was prototyped as a 10884;; variable argument function. It is > 0 if FP registers were passed 10885;; and < 0 if they were not. 10886 10887(define_insn "*call_local32" 10888 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) 10889 (match_operand 1 "" "g,g")) 10890 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10891 (clobber (reg:SI LR_REGNO))] 10892 "(INTVAL (operands[2]) & CALL_LONG) == 0" 10893 "* 10894{ 10895 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10896 output_asm_insn (\"crxor 6,6,6\", operands); 10897 10898 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10899 output_asm_insn (\"creqv 6,6,6\", operands); 10900 10901 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; 10902}" 10903 [(set_attr "type" "branch") 10904 (set_attr "length" "4,8")]) 10905 10906(define_insn "*call_local64" 10907 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) 10908 (match_operand 1 "" "g,g")) 10909 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10910 (clobber (reg:SI LR_REGNO))] 10911 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" 10912 "* 10913{ 10914 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10915 output_asm_insn (\"crxor 6,6,6\", operands); 10916 10917 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10918 output_asm_insn (\"creqv 6,6,6\", operands); 10919 10920 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\"; 10921}" 10922 [(set_attr "type" "branch") 10923 (set_attr "length" "4,8")]) 10924 10925(define_insn "*call_value_local32" 10926 [(set (match_operand 0 "" "") 10927 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) 10928 (match_operand 2 "" "g,g"))) 10929 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10930 (clobber (reg:SI LR_REGNO))] 10931 "(INTVAL (operands[3]) & CALL_LONG) == 0" 10932 "* 10933{ 10934 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10935 output_asm_insn (\"crxor 6,6,6\", operands); 10936 10937 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10938 output_asm_insn (\"creqv 6,6,6\", operands); 10939 10940 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; 10941}" 10942 [(set_attr "type" "branch") 10943 (set_attr "length" "4,8")]) 10944 10945 10946(define_insn "*call_value_local64" 10947 [(set (match_operand 0 "" "") 10948 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) 10949 (match_operand 2 "" "g,g"))) 10950 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10951 (clobber (reg:SI LR_REGNO))] 10952 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" 10953 "* 10954{ 10955 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10956 output_asm_insn (\"crxor 6,6,6\", operands); 10957 10958 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10959 output_asm_insn (\"creqv 6,6,6\", operands); 10960 10961 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\"; 10962}" 10963 [(set_attr "type" "branch") 10964 (set_attr "length" "4,8")]) 10965 10966 10967;; A function pointer under System V is just a normal pointer 10968;; operands[0] is the function pointer 10969;; operands[1] is the stack size to clean up 10970;; operands[2] is the value FUNCTION_ARG returns for the VOID argument 10971;; which indicates how to set cr1 10972 10973(define_insn "*call_indirect_nonlocal_sysv<mode>" 10974 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l")) 10975 (match_operand 1 "" "g,g,g,g")) 10976 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n")) 10977 (clobber (reg:SI LR_REGNO))] 10978 "DEFAULT_ABI == ABI_V4 10979 || DEFAULT_ABI == ABI_DARWIN" 10980{ 10981 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10982 output_asm_insn ("crxor 6,6,6", operands); 10983 10984 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10985 output_asm_insn ("creqv 6,6,6", operands); 10986 10987 return "b%T0l"; 10988} 10989 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") 10990 (set_attr "length" "4,4,8,8")]) 10991 10992(define_insn_and_split "*call_nonlocal_sysv<mode>" 10993 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 10994 (match_operand 1 "" "g,g")) 10995 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10996 (clobber (reg:SI LR_REGNO))] 10997 "(DEFAULT_ABI == ABI_DARWIN 10998 || (DEFAULT_ABI == ABI_V4 10999 && (INTVAL (operands[2]) & CALL_LONG) == 0))" 11000{ 11001 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11002 output_asm_insn ("crxor 6,6,6", operands); 11003 11004 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11005 output_asm_insn ("creqv 6,6,6", operands); 11006 11007#if TARGET_MACHO 11008 return output_call(insn, operands, 0, 2); 11009#else 11010 if (DEFAULT_ABI == ABI_V4 && flag_pic) 11011 { 11012 gcc_assert (!TARGET_SECURE_PLT); 11013 return "bl %z0@plt"; 11014 } 11015 else 11016 return "bl %z0"; 11017#endif 11018} 11019 "DEFAULT_ABI == ABI_V4 11020 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) 11021 && (INTVAL (operands[2]) & CALL_LONG) == 0" 11022 [(parallel [(call (mem:SI (match_dup 0)) 11023 (match_dup 1)) 11024 (use (match_dup 2)) 11025 (use (match_dup 3)) 11026 (clobber (reg:SI LR_REGNO))])] 11027{ 11028 operands[3] = pic_offset_table_rtx; 11029} 11030 [(set_attr "type" "branch,branch") 11031 (set_attr "length" "4,8")]) 11032 11033(define_insn "*call_nonlocal_sysv_secure<mode>" 11034 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 11035 (match_operand 1 "" "g,g")) 11036 (use (match_operand:SI 2 "immediate_operand" "O,n")) 11037 (use (match_operand:SI 3 "register_operand" "r,r")) 11038 (clobber (reg:SI LR_REGNO))] 11039 "(DEFAULT_ABI == ABI_V4 11040 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) 11041 && (INTVAL (operands[2]) & CALL_LONG) == 0)" 11042{ 11043 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11044 output_asm_insn ("crxor 6,6,6", operands); 11045 11046 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11047 output_asm_insn ("creqv 6,6,6", operands); 11048 11049 if (flag_pic == 2) 11050 /* The magic 32768 offset here and in the other sysv call insns 11051 corresponds to the offset of r30 in .got2, as given by LCTOC1. 11052 See sysv4.h:toc_section. */ 11053 return "bl %z0+32768@plt"; 11054 else 11055 return "bl %z0@plt"; 11056} 11057 [(set_attr "type" "branch,branch") 11058 (set_attr "length" "4,8")]) 11059 11060(define_insn "*call_value_indirect_nonlocal_sysv<mode>" 11061 [(set (match_operand 0 "" "") 11062 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l")) 11063 (match_operand 2 "" "g,g,g,g"))) 11064 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n")) 11065 (clobber (reg:SI LR_REGNO))] 11066 "DEFAULT_ABI == ABI_V4 11067 || DEFAULT_ABI == ABI_DARWIN" 11068{ 11069 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11070 output_asm_insn ("crxor 6,6,6", operands); 11071 11072 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11073 output_asm_insn ("creqv 6,6,6", operands); 11074 11075 return "b%T1l"; 11076} 11077 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg") 11078 (set_attr "length" "4,4,8,8")]) 11079 11080(define_insn_and_split "*call_value_nonlocal_sysv<mode>" 11081 [(set (match_operand 0 "" "") 11082 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) 11083 (match_operand 2 "" "g,g"))) 11084 (use (match_operand:SI 3 "immediate_operand" "O,n")) 11085 (clobber (reg:SI LR_REGNO))] 11086 "(DEFAULT_ABI == ABI_DARWIN 11087 || (DEFAULT_ABI == ABI_V4 11088 && (INTVAL (operands[3]) & CALL_LONG) == 0))" 11089{ 11090 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11091 output_asm_insn ("crxor 6,6,6", operands); 11092 11093 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11094 output_asm_insn ("creqv 6,6,6", operands); 11095 11096#if TARGET_MACHO 11097 return output_call(insn, operands, 1, 3); 11098#else 11099 if (DEFAULT_ABI == ABI_V4 && flag_pic) 11100 { 11101 gcc_assert (!TARGET_SECURE_PLT); 11102 return "bl %z1@plt"; 11103 } 11104 else 11105 return "bl %z1"; 11106#endif 11107} 11108 "DEFAULT_ABI == ABI_V4 11109 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) 11110 && (INTVAL (operands[3]) & CALL_LONG) == 0" 11111 [(parallel [(set (match_dup 0) 11112 (call (mem:SI (match_dup 1)) 11113 (match_dup 2))) 11114 (use (match_dup 3)) 11115 (use (match_dup 4)) 11116 (clobber (reg:SI LR_REGNO))])] 11117{ 11118 operands[4] = pic_offset_table_rtx; 11119} 11120 [(set_attr "type" "branch,branch") 11121 (set_attr "length" "4,8")]) 11122 11123(define_insn "*call_value_nonlocal_sysv_secure<mode>" 11124 [(set (match_operand 0 "" "") 11125 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) 11126 (match_operand 2 "" "g,g"))) 11127 (use (match_operand:SI 3 "immediate_operand" "O,n")) 11128 (use (match_operand:SI 4 "register_operand" "r,r")) 11129 (clobber (reg:SI LR_REGNO))] 11130 "(DEFAULT_ABI == ABI_V4 11131 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) 11132 && (INTVAL (operands[3]) & CALL_LONG) == 0)" 11133{ 11134 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11135 output_asm_insn ("crxor 6,6,6", operands); 11136 11137 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11138 output_asm_insn ("creqv 6,6,6", operands); 11139 11140 if (flag_pic == 2) 11141 return "bl %z1+32768@plt"; 11142 else 11143 return "bl %z1@plt"; 11144} 11145 [(set_attr "type" "branch,branch") 11146 (set_attr "length" "4,8")]) 11147 11148 11149;; Call to AIX abi function in the same module. 11150 11151(define_insn "*call_local_aix<mode>" 11152 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s")) 11153 (match_operand 1 "" "g")) 11154 (clobber (reg:P LR_REGNO))] 11155 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11156 "bl %z0" 11157 [(set_attr "type" "branch") 11158 (set_attr "length" "4")]) 11159 11160(define_insn "*call_value_local_aix<mode>" 11161 [(set (match_operand 0 "" "") 11162 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s")) 11163 (match_operand 2 "" "g"))) 11164 (clobber (reg:P LR_REGNO))] 11165 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11166 "bl %z1" 11167 [(set_attr "type" "branch") 11168 (set_attr "length" "4")]) 11169 11170;; Call to AIX abi function which may be in another module. 11171;; Restore the TOC pointer (r2) after the call. 11172 11173(define_insn "*call_nonlocal_aix<mode>" 11174 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s")) 11175 (match_operand 1 "" "g")) 11176 (clobber (reg:P LR_REGNO))] 11177 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11178 "bl %z0\;nop" 11179 [(set_attr "type" "branch") 11180 (set_attr "length" "8")]) 11181 11182(define_insn "*call_value_nonlocal_aix<mode>" 11183 [(set (match_operand 0 "" "") 11184 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 11185 (match_operand 2 "" "g"))) 11186 (clobber (reg:P LR_REGNO))] 11187 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11188 "bl %z1\;nop" 11189 [(set_attr "type" "branch") 11190 (set_attr "length" "8")]) 11191 11192;; Call to indirect functions with the AIX abi using a 3 word descriptor. 11193;; Operand0 is the addresss of the function to call 11194;; Operand2 is the location in the function descriptor to load r2 from 11195;; Operand3 is the offset of the stack location holding the current TOC pointer 11196 11197(define_insn "*call_indirect_aix<mode>" 11198 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) 11199 (match_operand 1 "" "g,g")) 11200 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>")) 11201 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 11202 (clobber (reg:P LR_REGNO))] 11203 "DEFAULT_ABI == ABI_AIX" 11204 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)" 11205 [(set_attr "type" "jmpreg") 11206 (set_attr "length" "12")]) 11207 11208(define_insn "*call_value_indirect_aix<mode>" 11209 [(set (match_operand 0 "" "") 11210 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) 11211 (match_operand 2 "" "g,g"))) 11212 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>")) 11213 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 11214 (clobber (reg:P LR_REGNO))] 11215 "DEFAULT_ABI == ABI_AIX" 11216 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)" 11217 [(set_attr "type" "jmpreg") 11218 (set_attr "length" "12")]) 11219 11220;; Call to indirect functions with the ELFv2 ABI. 11221;; Operand0 is the addresss of the function to call 11222;; Operand2 is the offset of the stack location holding the current TOC pointer 11223 11224(define_insn "*call_indirect_elfv2<mode>" 11225 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l")) 11226 (match_operand 1 "" "g,g")) 11227 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 11228 (clobber (reg:P LR_REGNO))] 11229 "DEFAULT_ABI == ABI_ELFv2" 11230 "b%T0l\;<ptrload> 2,%2(1)" 11231 [(set_attr "type" "jmpreg") 11232 (set_attr "length" "8")]) 11233 11234(define_insn "*call_value_indirect_elfv2<mode>" 11235 [(set (match_operand 0 "" "") 11236 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l")) 11237 (match_operand 2 "" "g,g"))) 11238 (set (reg:P TOC_REGNUM) (unspec [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT)) 11239 (clobber (reg:P LR_REGNO))] 11240 "DEFAULT_ABI == ABI_ELFv2" 11241 "b%T1l\;<ptrload> 2,%3(1)" 11242 [(set_attr "type" "jmpreg") 11243 (set_attr "length" "8")]) 11244 11245 11246;; Call subroutine returning any type. 11247(define_expand "untyped_call" 11248 [(parallel [(call (match_operand 0 "" "") 11249 (const_int 0)) 11250 (match_operand 1 "" "") 11251 (match_operand 2 "" "")])] 11252 "" 11253 " 11254{ 11255 int i; 11256 11257 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); 11258 11259 for (i = 0; i < XVECLEN (operands[2], 0); i++) 11260 { 11261 rtx set = XVECEXP (operands[2], 0, i); 11262 emit_move_insn (SET_DEST (set), SET_SRC (set)); 11263 } 11264 11265 /* The optimizer does not know that the call sets the function value 11266 registers we stored in the result block. We avoid problems by 11267 claiming that all hard registers are used and clobbered at this 11268 point. */ 11269 emit_insn (gen_blockage ()); 11270 11271 DONE; 11272}") 11273 11274;; sibling call patterns 11275(define_expand "sibcall" 11276 [(parallel [(call (mem:SI (match_operand 0 "address_operand" "")) 11277 (match_operand 1 "" "")) 11278 (use (match_operand 2 "" "")) 11279 (simple_return)])] 11280 "" 11281 " 11282{ 11283#if TARGET_MACHO 11284 if (MACHOPIC_INDIRECT) 11285 operands[0] = machopic_indirect_call_target (operands[0]); 11286#endif 11287 11288 gcc_assert (GET_CODE (operands[0]) == MEM); 11289 gcc_assert (GET_CODE (operands[1]) == CONST_INT); 11290 11291 operands[0] = XEXP (operands[0], 0); 11292 11293 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 11294 { 11295 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); 11296 DONE; 11297 } 11298}") 11299 11300(define_expand "sibcall_value" 11301 [(parallel [(set (match_operand 0 "register_operand" "") 11302 (call (mem:SI (match_operand 1 "address_operand" "")) 11303 (match_operand 2 "" ""))) 11304 (use (match_operand 3 "" "")) 11305 (simple_return)])] 11306 "" 11307 " 11308{ 11309#if TARGET_MACHO 11310 if (MACHOPIC_INDIRECT) 11311 operands[1] = machopic_indirect_call_target (operands[1]); 11312#endif 11313 11314 gcc_assert (GET_CODE (operands[1]) == MEM); 11315 gcc_assert (GET_CODE (operands[2]) == CONST_INT); 11316 11317 operands[1] = XEXP (operands[1], 0); 11318 11319 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 11320 { 11321 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]); 11322 DONE; 11323 } 11324}") 11325 11326(define_insn "*sibcall_local32" 11327 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) 11328 (match_operand 1 "" "g,g")) 11329 (use (match_operand:SI 2 "immediate_operand" "O,n")) 11330 (simple_return)] 11331 "(INTVAL (operands[2]) & CALL_LONG) == 0" 11332 "* 11333{ 11334 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11335 output_asm_insn (\"crxor 6,6,6\", operands); 11336 11337 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11338 output_asm_insn (\"creqv 6,6,6\", operands); 11339 11340 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; 11341}" 11342 [(set_attr "type" "branch") 11343 (set_attr "length" "4,8")]) 11344 11345(define_insn "*sibcall_local64" 11346 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) 11347 (match_operand 1 "" "g,g")) 11348 (use (match_operand:SI 2 "immediate_operand" "O,n")) 11349 (simple_return)] 11350 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" 11351 "* 11352{ 11353 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11354 output_asm_insn (\"crxor 6,6,6\", operands); 11355 11356 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11357 output_asm_insn (\"creqv 6,6,6\", operands); 11358 11359 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\"; 11360}" 11361 [(set_attr "type" "branch") 11362 (set_attr "length" "4,8")]) 11363 11364(define_insn "*sibcall_value_local32" 11365 [(set (match_operand 0 "" "") 11366 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) 11367 (match_operand 2 "" "g,g"))) 11368 (use (match_operand:SI 3 "immediate_operand" "O,n")) 11369 (simple_return)] 11370 "(INTVAL (operands[3]) & CALL_LONG) == 0" 11371 "* 11372{ 11373 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11374 output_asm_insn (\"crxor 6,6,6\", operands); 11375 11376 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11377 output_asm_insn (\"creqv 6,6,6\", operands); 11378 11379 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; 11380}" 11381 [(set_attr "type" "branch") 11382 (set_attr "length" "4,8")]) 11383 11384(define_insn "*sibcall_value_local64" 11385 [(set (match_operand 0 "" "") 11386 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) 11387 (match_operand 2 "" "g,g"))) 11388 (use (match_operand:SI 3 "immediate_operand" "O,n")) 11389 (simple_return)] 11390 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" 11391 "* 11392{ 11393 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11394 output_asm_insn (\"crxor 6,6,6\", operands); 11395 11396 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11397 output_asm_insn (\"creqv 6,6,6\", operands); 11398 11399 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\"; 11400}" 11401 [(set_attr "type" "branch") 11402 (set_attr "length" "4,8")]) 11403 11404(define_insn "*sibcall_nonlocal_sysv<mode>" 11405 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c")) 11406 (match_operand 1 "" "")) 11407 (use (match_operand 2 "immediate_operand" "O,n,O,n")) 11408 (simple_return)] 11409 "(DEFAULT_ABI == ABI_DARWIN 11410 || DEFAULT_ABI == ABI_V4) 11411 && (INTVAL (operands[2]) & CALL_LONG) == 0" 11412 "* 11413{ 11414 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11415 output_asm_insn (\"crxor 6,6,6\", operands); 11416 11417 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11418 output_asm_insn (\"creqv 6,6,6\", operands); 11419 11420 if (which_alternative >= 2) 11421 return \"b%T0\"; 11422 else if (DEFAULT_ABI == ABI_V4 && flag_pic) 11423 { 11424 gcc_assert (!TARGET_SECURE_PLT); 11425 return \"b %z0@plt\"; 11426 } 11427 else 11428 return \"b %z0\"; 11429}" 11430 [(set_attr "type" "branch") 11431 (set_attr "length" "4,8,4,8")]) 11432 11433(define_insn "*sibcall_value_nonlocal_sysv<mode>" 11434 [(set (match_operand 0 "" "") 11435 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c")) 11436 (match_operand 2 "" ""))) 11437 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n")) 11438 (simple_return)] 11439 "(DEFAULT_ABI == ABI_DARWIN 11440 || DEFAULT_ABI == ABI_V4) 11441 && (INTVAL (operands[3]) & CALL_LONG) == 0" 11442 "* 11443{ 11444 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11445 output_asm_insn (\"crxor 6,6,6\", operands); 11446 11447 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11448 output_asm_insn (\"creqv 6,6,6\", operands); 11449 11450 if (which_alternative >= 2) 11451 return \"b%T1\"; 11452 else if (DEFAULT_ABI == ABI_V4 && flag_pic) 11453 { 11454 gcc_assert (!TARGET_SECURE_PLT); 11455 return \"b %z1@plt\"; 11456 } 11457 else 11458 return \"b %z1\"; 11459}" 11460 [(set_attr "type" "branch") 11461 (set_attr "length" "4,8,4,8")]) 11462 11463;; AIX ABI sibling call patterns. 11464 11465(define_insn "*sibcall_aix<mode>" 11466 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) 11467 (match_operand 1 "" "g,g")) 11468 (simple_return)] 11469 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11470 "@ 11471 b %z0 11472 b%T0" 11473 [(set_attr "type" "branch") 11474 (set_attr "length" "4")]) 11475 11476(define_insn "*sibcall_value_aix<mode>" 11477 [(set (match_operand 0 "" "") 11478 (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) 11479 (match_operand 2 "" "g,g"))) 11480 (simple_return)] 11481 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11482 "@ 11483 b %z1 11484 b%T1" 11485 [(set_attr "type" "branch") 11486 (set_attr "length" "4")]) 11487 11488(define_expand "sibcall_epilogue" 11489 [(use (const_int 0))] 11490 "" 11491{ 11492 if (!TARGET_SCHED_PROLOG) 11493 emit_insn (gen_blockage ()); 11494 rs6000_emit_epilogue (TRUE); 11495 DONE; 11496}) 11497 11498;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 11499;; all of memory. This blocks insns from being moved across this point. 11500 11501(define_insn "blockage" 11502 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] 11503 "" 11504 "") 11505 11506(define_expand "probe_stack_address" 11507 [(use (match_operand 0 "address_operand"))] 11508 "" 11509{ 11510 operands[0] = gen_rtx_MEM (Pmode, operands[0]); 11511 MEM_VOLATILE_P (operands[0]) = 1; 11512 11513 if (TARGET_64BIT) 11514 emit_insn (gen_probe_stack_di (operands[0])); 11515 else 11516 emit_insn (gen_probe_stack_si (operands[0])); 11517 DONE; 11518}) 11519 11520(define_insn "probe_stack_<mode>" 11521 [(set (match_operand:P 0 "memory_operand" "=m") 11522 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))] 11523 "" 11524{ 11525 operands[1] = gen_rtx_REG (Pmode, 0); 11526 return "st<wd>%U0%X0 %1,%0"; 11527} 11528 [(set_attr "type" "store") 11529 (set (attr "update") 11530 (if_then_else (match_operand 0 "update_address_mem") 11531 (const_string "yes") 11532 (const_string "no"))) 11533 (set (attr "indexed") 11534 (if_then_else (match_operand 0 "indexed_address_mem") 11535 (const_string "yes") 11536 (const_string "no"))) 11537 (set_attr "length" "4")]) 11538 11539(define_insn "probe_stack_range<P:mode>" 11540 [(set (match_operand:P 0 "register_operand" "=r") 11541 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 11542 (match_operand:P 2 "register_operand" "r")] 11543 UNSPECV_PROBE_STACK_RANGE))] 11544 "" 11545 "* return output_probe_stack_range (operands[0], operands[2]);" 11546 [(set_attr "type" "three")]) 11547 11548;; Compare insns are next. Note that the RS/6000 has two types of compares, 11549;; signed & unsigned, and one type of branch. 11550;; 11551;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc 11552;; insns, and branches. 11553 11554(define_expand "cbranch<mode>4" 11555 [(use (match_operator 0 "rs6000_cbranch_operator" 11556 [(match_operand:GPR 1 "gpc_reg_operand" "") 11557 (match_operand:GPR 2 "reg_or_short_operand" "")])) 11558 (use (match_operand 3 ""))] 11559 "" 11560 " 11561{ 11562 /* Take care of the possibility that operands[2] might be negative but 11563 this might be a logical operation. That insn doesn't exist. */ 11564 if (GET_CODE (operands[2]) == CONST_INT 11565 && INTVAL (operands[2]) < 0) 11566 { 11567 operands[2] = force_reg (<MODE>mode, operands[2]); 11568 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]), 11569 GET_MODE (operands[0]), 11570 operands[1], operands[2]); 11571 } 11572 11573 rs6000_emit_cbranch (<MODE>mode, operands); 11574 DONE; 11575}") 11576 11577(define_expand "cbranch<mode>4" 11578 [(use (match_operator 0 "rs6000_cbranch_operator" 11579 [(match_operand:FP 1 "gpc_reg_operand" "") 11580 (match_operand:FP 2 "gpc_reg_operand" "")])) 11581 (use (match_operand 3 ""))] 11582 "" 11583 " 11584{ 11585 rs6000_emit_cbranch (<MODE>mode, operands); 11586 DONE; 11587}") 11588 11589(define_expand "cstore<mode>4_signed" 11590 [(use (match_operator 1 "signed_comparison_operator" 11591 [(match_operand:P 2 "gpc_reg_operand") 11592 (match_operand:P 3 "gpc_reg_operand")])) 11593 (clobber (match_operand:P 0 "gpc_reg_operand"))] 11594 "" 11595{ 11596 enum rtx_code cond_code = GET_CODE (operands[1]); 11597 11598 rtx op0 = operands[0]; 11599 rtx op1 = operands[2]; 11600 rtx op2 = operands[3]; 11601 11602 if (cond_code == GE || cond_code == LT) 11603 { 11604 cond_code = swap_condition (cond_code); 11605 std::swap (op1, op2); 11606 } 11607 11608 rtx tmp1 = gen_reg_rtx (<MODE>mode); 11609 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11610 rtx tmp3 = gen_reg_rtx (<MODE>mode); 11611 11612 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11613 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh))); 11614 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh))); 11615 11616 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2)); 11617 11618 if (cond_code == LE) 11619 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2)); 11620 else 11621 { 11622 rtx tmp4 = gen_reg_rtx (<MODE>mode); 11623 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2)); 11624 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx)); 11625 } 11626 11627 DONE; 11628}) 11629 11630(define_expand "cstore<mode>4_unsigned" 11631 [(use (match_operator 1 "unsigned_comparison_operator" 11632 [(match_operand:P 2 "gpc_reg_operand") 11633 (match_operand:P 3 "reg_or_short_operand")])) 11634 (clobber (match_operand:P 0 "gpc_reg_operand"))] 11635 "" 11636{ 11637 enum rtx_code cond_code = GET_CODE (operands[1]); 11638 11639 rtx op0 = operands[0]; 11640 rtx op1 = operands[2]; 11641 rtx op2 = operands[3]; 11642 11643 if (cond_code == GEU || cond_code == LTU) 11644 { 11645 cond_code = swap_condition (cond_code); 11646 std::swap (op1, op2); 11647 } 11648 11649 if (!gpc_reg_operand (op1, <MODE>mode)) 11650 op1 = force_reg (<MODE>mode, op1); 11651 if (!reg_or_short_operand (op2, <MODE>mode)) 11652 op2 = force_reg (<MODE>mode, op2); 11653 11654 rtx tmp = gen_reg_rtx (<MODE>mode); 11655 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11656 11657 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2)); 11658 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2)); 11659 11660 if (cond_code == LEU) 11661 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx)); 11662 else 11663 emit_insn (gen_neg<mode>2 (op0, tmp2)); 11664 11665 DONE; 11666}) 11667 11668(define_expand "cstore_si_as_di" 11669 [(use (match_operator 1 "unsigned_comparison_operator" 11670 [(match_operand:SI 2 "gpc_reg_operand") 11671 (match_operand:SI 3 "reg_or_short_operand")])) 11672 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 11673 "" 11674{ 11675 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0; 11676 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1])); 11677 11678 operands[2] = force_reg (SImode, operands[2]); 11679 operands[3] = force_reg (SImode, operands[3]); 11680 rtx op1 = gen_reg_rtx (DImode); 11681 rtx op2 = gen_reg_rtx (DImode); 11682 convert_move (op1, operands[2], uns_flag); 11683 convert_move (op2, operands[3], uns_flag); 11684 11685 if (cond_code == GT || cond_code == LE) 11686 { 11687 cond_code = swap_condition (cond_code); 11688 std::swap (op1, op2); 11689 } 11690 11691 rtx tmp = gen_reg_rtx (DImode); 11692 rtx tmp2 = gen_reg_rtx (DImode); 11693 emit_insn (gen_subdi3 (tmp, op1, op2)); 11694 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63))); 11695 11696 rtx tmp3; 11697 switch (cond_code) 11698 { 11699 default: 11700 gcc_unreachable (); 11701 case LT: 11702 tmp3 = tmp2; 11703 break; 11704 case GE: 11705 tmp3 = gen_reg_rtx (DImode); 11706 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx)); 11707 break; 11708 } 11709 11710 convert_move (operands[0], tmp3, 1); 11711 11712 DONE; 11713}) 11714 11715(define_expand "cstore<mode>4_signed_imm" 11716 [(use (match_operator 1 "signed_comparison_operator" 11717 [(match_operand:GPR 2 "gpc_reg_operand") 11718 (match_operand:GPR 3 "immediate_operand")])) 11719 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11720 "" 11721{ 11722 bool invert = false; 11723 11724 enum rtx_code cond_code = GET_CODE (operands[1]); 11725 11726 rtx op0 = operands[0]; 11727 rtx op1 = operands[2]; 11728 HOST_WIDE_INT val = INTVAL (operands[3]); 11729 11730 if (cond_code == GE || cond_code == GT) 11731 { 11732 cond_code = reverse_condition (cond_code); 11733 invert = true; 11734 } 11735 11736 if (cond_code == LE) 11737 val++; 11738 11739 rtx tmp = gen_reg_rtx (<MODE>mode); 11740 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 11741 rtx x = gen_reg_rtx (<MODE>mode); 11742 if (val < 0) 11743 emit_insn (gen_and<mode>3 (x, op1, tmp)); 11744 else 11745 emit_insn (gen_ior<mode>3 (x, op1, tmp)); 11746 11747 if (invert) 11748 { 11749 rtx tmp = gen_reg_rtx (<MODE>mode); 11750 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 11751 x = tmp; 11752 } 11753 11754 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11755 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 11756 11757 DONE; 11758}) 11759 11760(define_expand "cstore<mode>4_unsigned_imm" 11761 [(use (match_operator 1 "unsigned_comparison_operator" 11762 [(match_operand:GPR 2 "gpc_reg_operand") 11763 (match_operand:GPR 3 "immediate_operand")])) 11764 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11765 "" 11766{ 11767 bool invert = false; 11768 11769 enum rtx_code cond_code = GET_CODE (operands[1]); 11770 11771 rtx op0 = operands[0]; 11772 rtx op1 = operands[2]; 11773 HOST_WIDE_INT val = INTVAL (operands[3]); 11774 11775 if (cond_code == GEU || cond_code == GTU) 11776 { 11777 cond_code = reverse_condition (cond_code); 11778 invert = true; 11779 } 11780 11781 if (cond_code == LEU) 11782 val++; 11783 11784 rtx tmp = gen_reg_rtx (<MODE>mode); 11785 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11786 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 11787 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1)); 11788 rtx x = gen_reg_rtx (<MODE>mode); 11789 if (val < 0) 11790 emit_insn (gen_ior<mode>3 (x, tmp, tmp2)); 11791 else 11792 emit_insn (gen_and<mode>3 (x, tmp, tmp2)); 11793 11794 if (invert) 11795 { 11796 rtx tmp = gen_reg_rtx (<MODE>mode); 11797 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 11798 x = tmp; 11799 } 11800 11801 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11802 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 11803 11804 DONE; 11805}) 11806 11807(define_expand "cstore<mode>4" 11808 [(use (match_operator 1 "rs6000_cbranch_operator" 11809 [(match_operand:GPR 2 "gpc_reg_operand") 11810 (match_operand:GPR 3 "reg_or_short_operand")])) 11811 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11812 "" 11813{ 11814 /* Use ISEL if the user asked for it. */ 11815 if (TARGET_ISEL) 11816 rs6000_emit_sISEL (<MODE>mode, operands); 11817 11818 /* Expanding EQ and NE directly to some machine instructions does not help 11819 but does hurt combine. So don't. */ 11820 else if (GET_CODE (operands[1]) == EQ) 11821 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3])); 11822 else if (<MODE>mode == Pmode 11823 && GET_CODE (operands[1]) == NE) 11824 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3])); 11825 else if (GET_CODE (operands[1]) == NE) 11826 { 11827 rtx tmp = gen_reg_rtx (<MODE>mode); 11828 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3])); 11829 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); 11830 } 11831 11832 /* Expanding the unsigned comparisons however helps a lot: all the neg_ltu 11833 etc. combinations magically work out just right. */ 11834 else if (<MODE>mode == Pmode 11835 && unsigned_comparison_operator (operands[1], VOIDmode)) 11836 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1], 11837 operands[2], operands[3])); 11838 11839 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */ 11840 else if (<MODE>mode == SImode && Pmode == DImode) 11841 emit_insn (gen_cstore_si_as_di (operands[0], operands[1], 11842 operands[2], operands[3])); 11843 11844 /* For signed comparisons against a constant, we can do some simple 11845 bit-twiddling. */ 11846 else if (signed_comparison_operator (operands[1], VOIDmode) 11847 && CONST_INT_P (operands[3])) 11848 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1], 11849 operands[2], operands[3])); 11850 11851 /* And similarly for unsigned comparisons. */ 11852 else if (unsigned_comparison_operator (operands[1], VOIDmode) 11853 && CONST_INT_P (operands[3])) 11854 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1], 11855 operands[2], operands[3])); 11856 11857 /* We also do not want to use mfcr for signed comparisons. */ 11858 else if (<MODE>mode == Pmode 11859 && signed_comparison_operator (operands[1], VOIDmode)) 11860 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1], 11861 operands[2], operands[3])); 11862 11863 /* Everything else, use the mfcr brute force. */ 11864 else 11865 rs6000_emit_sCOND (<MODE>mode, operands); 11866 11867 DONE; 11868}) 11869 11870(define_expand "cstore<mode>4" 11871 [(use (match_operator 1 "rs6000_cbranch_operator" 11872 [(match_operand:FP 2 "gpc_reg_operand") 11873 (match_operand:FP 3 "gpc_reg_operand")])) 11874 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 11875 "" 11876{ 11877 rs6000_emit_sCOND (<MODE>mode, operands); 11878 DONE; 11879}) 11880 11881 11882(define_expand "stack_protect_set" 11883 [(match_operand 0 "memory_operand") 11884 (match_operand 1 "memory_operand")] 11885 "" 11886{ 11887 if (rs6000_stack_protector_guard == SSP_TLS) 11888 { 11889 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg); 11890 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset); 11891 rtx addr = gen_rtx_PLUS (Pmode, reg, offset); 11892 operands[1] = gen_rtx_MEM (Pmode, addr); 11893 } 11894 11895 if (TARGET_64BIT) 11896 emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); 11897 else 11898 emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); 11899 11900 DONE; 11901}) 11902 11903(define_insn "stack_protect_setsi" 11904 [(set (match_operand:SI 0 "memory_operand" "=m") 11905 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 11906 (set (match_scratch:SI 2 "=&r") (const_int 0))] 11907 "TARGET_32BIT" 11908 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0" 11909 [(set_attr "type" "three") 11910 (set_attr "length" "12")]) 11911 11912(define_insn "stack_protect_setdi" 11913 [(set (match_operand:DI 0 "memory_operand" "=Y") 11914 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET)) 11915 (set (match_scratch:DI 2 "=&r") (const_int 0))] 11916 "TARGET_64BIT" 11917 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0" 11918 [(set_attr "type" "three") 11919 (set_attr "length" "12")]) 11920 11921(define_expand "stack_protect_test" 11922 [(match_operand 0 "memory_operand") 11923 (match_operand 1 "memory_operand") 11924 (match_operand 2 "")] 11925 "" 11926{ 11927 rtx guard = operands[1]; 11928 11929 if (rs6000_stack_protector_guard == SSP_TLS) 11930 { 11931 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg); 11932 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset); 11933 rtx addr = gen_rtx_PLUS (Pmode, reg, offset); 11934 guard = gen_rtx_MEM (Pmode, addr); 11935 } 11936 11937 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST); 11938 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]); 11939 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]); 11940 emit_jump_insn (jump); 11941 11942 DONE; 11943}) 11944 11945(define_insn "stack_protect_testsi" 11946 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 11947 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m") 11948 (match_operand:SI 2 "memory_operand" "m,m")] 11949 UNSPEC_SP_TEST)) 11950 (set (match_scratch:SI 4 "=r,r") (const_int 0)) 11951 (clobber (match_scratch:SI 3 "=&r,&r"))] 11952 "TARGET_32BIT" 11953 "@ 11954 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 11955 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0" 11956 [(set_attr "length" "16,20")]) 11957 11958(define_insn "stack_protect_testdi" 11959 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 11960 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y") 11961 (match_operand:DI 2 "memory_operand" "Y,Y")] 11962 UNSPEC_SP_TEST)) 11963 (set (match_scratch:DI 4 "=r,r") (const_int 0)) 11964 (clobber (match_scratch:DI 3 "=&r,&r"))] 11965 "TARGET_64BIT" 11966 "@ 11967 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 11968 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0" 11969 [(set_attr "length" "16,20")]) 11970 11971 11972;; Here are the actual compare insns. 11973(define_insn "*cmp<mode>_signed" 11974 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 11975 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r") 11976 (match_operand:GPR 2 "reg_or_short_operand" "rI")))] 11977 "" 11978 "cmp<wd>%I2 %0,%1,%2" 11979 [(set_attr "type" "cmp")]) 11980 11981(define_insn "*cmp<mode>_unsigned" 11982 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") 11983 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r") 11984 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))] 11985 "" 11986 "cmpl<wd>%I2 %0,%1,%2" 11987 [(set_attr "type" "cmp")]) 11988 11989;; If we are comparing a register for equality with a large constant, 11990;; we can do this with an XOR followed by a compare. But this is profitable 11991;; only if the large constant is only used for the comparison (and in this 11992;; case we already have a register to reuse as scratch). 11993;; 11994;; For 64-bit registers, we could only do so if the constant's bit 15 is clear: 11995;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available. 11996 11997(define_peephole2 11998 [(set (match_operand:SI 0 "register_operand") 11999 (match_operand:SI 1 "logical_const_operand" "")) 12000 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator" 12001 [(match_dup 0) 12002 (match_operand:SI 2 "logical_const_operand" "")])) 12003 (set (match_operand:CC 4 "cc_reg_operand" "") 12004 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "") 12005 (match_dup 0))) 12006 (set (pc) 12007 (if_then_else (match_operator 6 "equality_operator" 12008 [(match_dup 4) (const_int 0)]) 12009 (match_operand 7 "" "") 12010 (match_operand 8 "" "")))] 12011 "peep2_reg_dead_p (3, operands[0]) 12012 && peep2_reg_dead_p (4, operands[4]) 12013 && REGNO (operands[0]) != REGNO (operands[5])" 12014 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9))) 12015 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10))) 12016 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))] 12017 12018{ 12019 /* Get the constant we are comparing against, and see what it looks like 12020 when sign-extended from 16 to 32 bits. Then see what constant we could 12021 XOR with SEXTC to get the sign-extended value. */ 12022 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]), 12023 SImode, 12024 operands[1], operands[2]); 12025 HOST_WIDE_INT c = INTVAL (cnst); 12026 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000; 12027 HOST_WIDE_INT xorv = c ^ sextc; 12028 12029 operands[9] = GEN_INT (xorv); 12030 operands[10] = GEN_INT (sextc); 12031}) 12032 12033;; The following two insns don't exist as single insns, but if we provide 12034;; them, we can swap an add and compare, which will enable us to overlap more 12035;; of the required delay between a compare and branch. We generate code for 12036;; them by splitting. 12037 12038(define_insn "" 12039 [(set (match_operand:CC 3 "cc_reg_operand" "=y") 12040 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r") 12041 (match_operand:SI 2 "short_cint_operand" "i"))) 12042 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 12043 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] 12044 "" 12045 "#" 12046 [(set_attr "length" "8")]) 12047 12048(define_insn "" 12049 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y") 12050 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r") 12051 (match_operand:SI 2 "u_short_cint_operand" "i"))) 12052 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 12053 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))] 12054 "" 12055 "#" 12056 [(set_attr "length" "8")]) 12057 12058(define_split 12059 [(set (match_operand:CC 3 "cc_reg_operand" "") 12060 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "") 12061 (match_operand:SI 2 "short_cint_operand" ""))) 12062 (set (match_operand:SI 0 "gpc_reg_operand" "") 12063 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))] 12064 "" 12065 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2))) 12066 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) 12067 12068(define_split 12069 [(set (match_operand:CCUNS 3 "cc_reg_operand" "") 12070 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "") 12071 (match_operand:SI 2 "u_short_cint_operand" ""))) 12072 (set (match_operand:SI 0 "gpc_reg_operand" "") 12073 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))] 12074 "" 12075 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2))) 12076 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))]) 12077 12078;; Only need to compare second words if first words equal 12079(define_insn "*cmp<mode>_internal1" 12080 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 12081 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 12082 (match_operand:IBM128 2 "gpc_reg_operand" "d")))] 12083 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) 12084 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 12085 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" 12086 [(set_attr "type" "fpcompare") 12087 (set_attr "length" "12")]) 12088 12089(define_insn_and_split "*cmp<mode>_internal2" 12090 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 12091 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 12092 (match_operand:IBM128 2 "gpc_reg_operand" "d"))) 12093 (clobber (match_scratch:DF 3 "=d")) 12094 (clobber (match_scratch:DF 4 "=d")) 12095 (clobber (match_scratch:DF 5 "=d")) 12096 (clobber (match_scratch:DF 6 "=d")) 12097 (clobber (match_scratch:DF 7 "=d")) 12098 (clobber (match_scratch:DF 8 "=d")) 12099 (clobber (match_scratch:DF 9 "=d")) 12100 (clobber (match_scratch:DF 10 "=d")) 12101 (clobber (match_scratch:GPR 11 "=b"))] 12102 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) 12103 && TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128" 12104 "#" 12105 "&& reload_completed" 12106 [(set (match_dup 3) (match_dup 14)) 12107 (set (match_dup 4) (match_dup 15)) 12108 (set (match_dup 9) (abs:DF (match_dup 5))) 12109 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) 12110 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) 12111 (label_ref (match_dup 12)) 12112 (pc))) 12113 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) 12114 (set (pc) (label_ref (match_dup 13))) 12115 (match_dup 12) 12116 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) 12117 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) 12118 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) 12119 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4))) 12120 (match_dup 13)] 12121{ 12122 REAL_VALUE_TYPE rv; 12123 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 12124 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 12125 12126 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word); 12127 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word); 12128 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word); 12129 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word); 12130 operands[12] = gen_label_rtx (); 12131 operands[13] = gen_label_rtx (); 12132 real_inf (&rv); 12133 operands[14] = force_const_mem (DFmode, 12134 const_double_from_real_value (rv, DFmode)); 12135 operands[15] = force_const_mem (DFmode, 12136 const_double_from_real_value (dconst0, 12137 DFmode)); 12138 if (TARGET_TOC) 12139 { 12140 rtx tocref; 12141 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]); 12142 operands[14] = gen_const_mem (DFmode, tocref); 12143 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]); 12144 operands[15] = gen_const_mem (DFmode, tocref); 12145 set_mem_alias_set (operands[14], get_TOC_alias_set ()); 12146 set_mem_alias_set (operands[15], get_TOC_alias_set ()); 12147 } 12148}) 12149 12150;; Now we have the scc insns. We can do some combinations because of the 12151;; way the machine works. 12152;; 12153;; Note that this is probably faster if we can put an insn between the 12154;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most 12155;; cases the insns below which don't use an intermediate CR field will 12156;; be used instead. 12157(define_insn "" 12158 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 12159 (match_operator:SI 1 "scc_comparison_operator" 12160 [(match_operand 2 "cc_reg_operand" "y") 12161 (const_int 0)]))] 12162 "" 12163 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" 12164 [(set (attr "type") 12165 (cond [(match_test "TARGET_MFCRF") 12166 (const_string "mfcrf") 12167 ] 12168 (const_string "mfcr"))) 12169 (set_attr "length" "8")]) 12170 12171;; Same as above, but get the GT bit. 12172(define_insn "move_from_CR_gt_bit" 12173 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 12174 (unspec:SI [(match_operand 1 "cc_reg_operand" "y")] UNSPEC_MV_CR_GT))] 12175 "TARGET_HARD_FLOAT && !TARGET_FPRS" 12176 "mfcr %0\;rlwinm %0,%0,%D1,31,31" 12177 [(set_attr "type" "mfcr") 12178 (set_attr "length" "8")]) 12179 12180;; Same as above, but get the OV/ORDERED bit. 12181(define_insn "move_from_CR_ov_bit" 12182 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 12183 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")] 12184 UNSPEC_MV_CR_OV))] 12185 "TARGET_ISEL" 12186 "mfcr %0\;rlwinm %0,%0,%t1,1" 12187 [(set_attr "type" "mfcr") 12188 (set_attr "length" "8")]) 12189 12190(define_insn "" 12191 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 12192 (match_operator:DI 1 "scc_comparison_operator" 12193 [(match_operand 2 "cc_reg_operand" "y") 12194 (const_int 0)]))] 12195 "TARGET_POWERPC64" 12196 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" 12197 [(set (attr "type") 12198 (cond [(match_test "TARGET_MFCRF") 12199 (const_string "mfcrf") 12200 ] 12201 (const_string "mfcr"))) 12202 (set_attr "length" "8")]) 12203 12204(define_insn "" 12205 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") 12206 (compare:CC (match_operator:SI 1 "scc_comparison_operator" 12207 [(match_operand 2 "cc_reg_operand" "y,y") 12208 (const_int 0)]) 12209 (const_int 0))) 12210 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 12211 (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 12212 "TARGET_32BIT" 12213 "@ 12214 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1 12215 #" 12216 [(set_attr "type" "shift") 12217 (set_attr "dot" "yes") 12218 (set_attr "length" "8,16")]) 12219 12220(define_split 12221 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "") 12222 (compare:CC (match_operator:SI 1 "scc_comparison_operator" 12223 [(match_operand 2 "cc_reg_operand" "") 12224 (const_int 0)]) 12225 (const_int 0))) 12226 (set (match_operand:SI 3 "gpc_reg_operand" "") 12227 (match_op_dup 1 [(match_dup 2) (const_int 0)]))] 12228 "TARGET_32BIT && reload_completed" 12229 [(set (match_dup 3) 12230 (match_op_dup 1 [(match_dup 2) (const_int 0)])) 12231 (set (match_dup 0) 12232 (compare:CC (match_dup 3) 12233 (const_int 0)))] 12234 "") 12235 12236(define_insn "" 12237 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 12238 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" 12239 [(match_operand 2 "cc_reg_operand" "y") 12240 (const_int 0)]) 12241 (match_operand:SI 3 "const_int_operand" "n")))] 12242 "" 12243 "* 12244{ 12245 int is_bit = ccr_bit (operands[1], 1); 12246 int put_bit = 31 - (INTVAL (operands[3]) & 31); 12247 int count; 12248 12249 if (is_bit >= put_bit) 12250 count = is_bit - put_bit; 12251 else 12252 count = 32 - (put_bit - is_bit); 12253 12254 operands[4] = GEN_INT (count); 12255 operands[5] = GEN_INT (put_bit); 12256 12257 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\"; 12258}" 12259 [(set (attr "type") 12260 (cond [(match_test "TARGET_MFCRF") 12261 (const_string "mfcrf") 12262 ] 12263 (const_string "mfcr"))) 12264 (set_attr "length" "8")]) 12265 12266(define_insn "" 12267 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y") 12268 (compare:CC 12269 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" 12270 [(match_operand 2 "cc_reg_operand" "y,y") 12271 (const_int 0)]) 12272 (match_operand:SI 3 "const_int_operand" "n,n")) 12273 (const_int 0))) 12274 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r") 12275 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) 12276 (match_dup 3)))] 12277 "" 12278 "* 12279{ 12280 int is_bit = ccr_bit (operands[1], 1); 12281 int put_bit = 31 - (INTVAL (operands[3]) & 31); 12282 int count; 12283 12284 /* Force split for non-cc0 compare. */ 12285 if (which_alternative == 1) 12286 return \"#\"; 12287 12288 if (is_bit >= put_bit) 12289 count = is_bit - put_bit; 12290 else 12291 count = 32 - (put_bit - is_bit); 12292 12293 operands[5] = GEN_INT (count); 12294 operands[6] = GEN_INT (put_bit); 12295 12296 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\"; 12297}" 12298 [(set_attr "type" "shift") 12299 (set_attr "dot" "yes") 12300 (set_attr "length" "8,16")]) 12301 12302(define_split 12303 [(set (match_operand:CC 0 "cc_reg_not_micro_cr0_operand" "") 12304 (compare:CC 12305 (ashift:SI (match_operator:SI 1 "scc_comparison_operator" 12306 [(match_operand 2 "cc_reg_operand" "") 12307 (const_int 0)]) 12308 (match_operand:SI 3 "const_int_operand" "")) 12309 (const_int 0))) 12310 (set (match_operand:SI 4 "gpc_reg_operand" "") 12311 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) 12312 (match_dup 3)))] 12313 "reload_completed" 12314 [(set (match_dup 4) 12315 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)]) 12316 (match_dup 3))) 12317 (set (match_dup 0) 12318 (compare:CC (match_dup 4) 12319 (const_int 0)))] 12320 "") 12321 12322 12323(define_mode_attr scc_eq_op2 [(SI "rKLI") 12324 (DI "rKJI")]) 12325 12326(define_insn_and_split "eq<mode>3" 12327 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12328 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 12329 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 12330 (clobber (match_scratch:GPR 3 "=r")) 12331 (clobber (match_scratch:GPR 4 "=r"))] 12332 "" 12333 "#" 12334 "" 12335 [(set (match_dup 4) 12336 (clz:GPR (match_dup 3))) 12337 (set (match_dup 0) 12338 (lshiftrt:GPR (match_dup 4) 12339 (match_dup 5)))] 12340{ 12341 operands[3] = rs6000_emit_eqne (<MODE>mode, 12342 operands[1], operands[2], operands[3]); 12343 12344 if (GET_CODE (operands[4]) == SCRATCH) 12345 operands[4] = gen_reg_rtx (<MODE>mode); 12346 12347 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode))); 12348} 12349 [(set (attr "length") 12350 (if_then_else (match_test "operands[2] == const0_rtx") 12351 (const_string "8") 12352 (const_string "12")))]) 12353 12354(define_insn_and_split "ne<mode>3" 12355 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12356 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12357 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) 12358 (clobber (match_scratch:P 3 "=r")) 12359 (clobber (match_scratch:P 4 "=r")) 12360 (clobber (reg:P CA_REGNO))] 12361 "!TARGET_ISEL" 12362 "#" 12363 "" 12364 [(parallel [(set (match_dup 4) 12365 (plus:P (match_dup 3) 12366 (const_int -1))) 12367 (set (reg:P CA_REGNO) 12368 (ne:P (match_dup 3) 12369 (const_int 0)))]) 12370 (parallel [(set (match_dup 0) 12371 (plus:P (plus:P (not:P (match_dup 4)) 12372 (reg:P CA_REGNO)) 12373 (match_dup 3))) 12374 (clobber (reg:P CA_REGNO))])] 12375{ 12376 operands[3] = rs6000_emit_eqne (<MODE>mode, 12377 operands[1], operands[2], operands[3]); 12378 12379 if (GET_CODE (operands[4]) == SCRATCH) 12380 operands[4] = gen_reg_rtx (<MODE>mode); 12381} 12382 [(set (attr "length") 12383 (if_then_else (match_test "operands[2] == const0_rtx") 12384 (const_string "8") 12385 (const_string "12")))]) 12386 12387(define_insn_and_split "*neg_eq_<mode>" 12388 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12389 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12390 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12391 (clobber (match_scratch:P 3 "=r")) 12392 (clobber (match_scratch:P 4 "=r")) 12393 (clobber (reg:P CA_REGNO))] 12394 "" 12395 "#" 12396 "" 12397 [(parallel [(set (match_dup 4) 12398 (plus:P (match_dup 3) 12399 (const_int -1))) 12400 (set (reg:P CA_REGNO) 12401 (ne:P (match_dup 3) 12402 (const_int 0)))]) 12403 (parallel [(set (match_dup 0) 12404 (plus:P (reg:P CA_REGNO) 12405 (const_int -1))) 12406 (clobber (reg:P CA_REGNO))])] 12407{ 12408 operands[3] = rs6000_emit_eqne (<MODE>mode, 12409 operands[1], operands[2], operands[3]); 12410 12411 if (GET_CODE (operands[4]) == SCRATCH) 12412 operands[4] = gen_reg_rtx (<MODE>mode); 12413} 12414 [(set (attr "length") 12415 (if_then_else (match_test "operands[2] == const0_rtx") 12416 (const_string "8") 12417 (const_string "12")))]) 12418 12419(define_insn_and_split "*neg_ne_<mode>" 12420 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12421 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12422 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12423 (clobber (match_scratch:P 3 "=r")) 12424 (clobber (match_scratch:P 4 "=r")) 12425 (clobber (reg:P CA_REGNO))] 12426 "" 12427 "#" 12428 "" 12429 [(parallel [(set (match_dup 4) 12430 (neg:P (match_dup 3))) 12431 (set (reg:P CA_REGNO) 12432 (eq:P (match_dup 3) 12433 (const_int 0)))]) 12434 (parallel [(set (match_dup 0) 12435 (plus:P (reg:P CA_REGNO) 12436 (const_int -1))) 12437 (clobber (reg:P CA_REGNO))])] 12438{ 12439 operands[3] = rs6000_emit_eqne (<MODE>mode, 12440 operands[1], operands[2], operands[3]); 12441 12442 if (GET_CODE (operands[4]) == SCRATCH) 12443 operands[4] = gen_reg_rtx (<MODE>mode); 12444} 12445 [(set (attr "length") 12446 (if_then_else (match_test "operands[2] == const0_rtx") 12447 (const_string "8") 12448 (const_string "12")))]) 12449 12450(define_insn_and_split "*plus_eq_<mode>" 12451 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12452 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12453 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 12454 (match_operand:P 3 "gpc_reg_operand" "r"))) 12455 (clobber (match_scratch:P 4 "=r")) 12456 (clobber (match_scratch:P 5 "=r")) 12457 (clobber (reg:P CA_REGNO))] 12458 "" 12459 "#" 12460 "" 12461 [(parallel [(set (match_dup 5) 12462 (neg:P (match_dup 4))) 12463 (set (reg:P CA_REGNO) 12464 (eq:P (match_dup 4) 12465 (const_int 0)))]) 12466 (parallel [(set (match_dup 0) 12467 (plus:P (match_dup 3) 12468 (reg:P CA_REGNO))) 12469 (clobber (reg:P CA_REGNO))])] 12470{ 12471 operands[4] = rs6000_emit_eqne (<MODE>mode, 12472 operands[1], operands[2], operands[4]); 12473 12474 if (GET_CODE (operands[5]) == SCRATCH) 12475 operands[5] = gen_reg_rtx (<MODE>mode); 12476} 12477 [(set (attr "length") 12478 (if_then_else (match_test "operands[2] == const0_rtx") 12479 (const_string "8") 12480 (const_string "12")))]) 12481 12482(define_insn_and_split "*plus_ne_<mode>" 12483 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12484 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12485 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 12486 (match_operand:P 3 "gpc_reg_operand" "r"))) 12487 (clobber (match_scratch:P 4 "=r")) 12488 (clobber (match_scratch:P 5 "=r")) 12489 (clobber (reg:P CA_REGNO))] 12490 "" 12491 "#" 12492 "" 12493 [(parallel [(set (match_dup 5) 12494 (plus:P (match_dup 4) 12495 (const_int -1))) 12496 (set (reg:P CA_REGNO) 12497 (ne:P (match_dup 4) 12498 (const_int 0)))]) 12499 (parallel [(set (match_dup 0) 12500 (plus:P (match_dup 3) 12501 (reg:P CA_REGNO))) 12502 (clobber (reg:P CA_REGNO))])] 12503{ 12504 operands[4] = rs6000_emit_eqne (<MODE>mode, 12505 operands[1], operands[2], operands[4]); 12506 12507 if (GET_CODE (operands[5]) == SCRATCH) 12508 operands[5] = gen_reg_rtx (<MODE>mode); 12509} 12510 [(set (attr "length") 12511 (if_then_else (match_test "operands[2] == const0_rtx") 12512 (const_string "8") 12513 (const_string "12")))]) 12514 12515(define_insn_and_split "*minus_eq_<mode>" 12516 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12517 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 12518 (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12519 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12520 (clobber (match_scratch:P 4 "=r")) 12521 (clobber (match_scratch:P 5 "=r")) 12522 (clobber (reg:P CA_REGNO))] 12523 "" 12524 "#" 12525 "" 12526 [(parallel [(set (match_dup 5) 12527 (plus:P (match_dup 4) 12528 (const_int -1))) 12529 (set (reg:P CA_REGNO) 12530 (ne:P (match_dup 4) 12531 (const_int 0)))]) 12532 (parallel [(set (match_dup 0) 12533 (plus:P (plus:P (match_dup 3) 12534 (reg:P CA_REGNO)) 12535 (const_int -1))) 12536 (clobber (reg:P CA_REGNO))])] 12537{ 12538 operands[4] = rs6000_emit_eqne (<MODE>mode, 12539 operands[1], operands[2], operands[4]); 12540 12541 if (GET_CODE (operands[5]) == SCRATCH) 12542 operands[5] = gen_reg_rtx (<MODE>mode); 12543} 12544 [(set (attr "length") 12545 (if_then_else (match_test "operands[2] == const0_rtx") 12546 (const_string "8") 12547 (const_string "12")))]) 12548 12549(define_insn_and_split "*minus_ne_<mode>" 12550 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12551 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 12552 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12553 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12554 (clobber (match_scratch:P 4 "=r")) 12555 (clobber (match_scratch:P 5 "=r")) 12556 (clobber (reg:P CA_REGNO))] 12557 "" 12558 "#" 12559 "" 12560 [(parallel [(set (match_dup 5) 12561 (neg:P (match_dup 4))) 12562 (set (reg:P CA_REGNO) 12563 (eq:P (match_dup 4) 12564 (const_int 0)))]) 12565 (parallel [(set (match_dup 0) 12566 (plus:P (plus:P (match_dup 3) 12567 (reg:P CA_REGNO)) 12568 (const_int -1))) 12569 (clobber (reg:P CA_REGNO))])] 12570{ 12571 operands[4] = rs6000_emit_eqne (<MODE>mode, 12572 operands[1], operands[2], operands[4]); 12573 12574 if (GET_CODE (operands[5]) == SCRATCH) 12575 operands[5] = gen_reg_rtx (<MODE>mode); 12576} 12577 [(set (attr "length") 12578 (if_then_else (match_test "operands[2] == const0_rtx") 12579 (const_string "8") 12580 (const_string "12")))]) 12581 12582(define_insn_and_split "*eqsi3_ext<mode>" 12583 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 12584 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 12585 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 12586 (clobber (match_scratch:SI 3 "=r")) 12587 (clobber (match_scratch:SI 4 "=r"))] 12588 "" 12589 "#" 12590 "" 12591 [(set (match_dup 4) 12592 (clz:SI (match_dup 3))) 12593 (set (match_dup 0) 12594 (zero_extend:EXTSI 12595 (lshiftrt:SI (match_dup 4) 12596 (const_int 5))))] 12597{ 12598 operands[3] = rs6000_emit_eqne (SImode, 12599 operands[1], operands[2], operands[3]); 12600 12601 if (GET_CODE (operands[4]) == SCRATCH) 12602 operands[4] = gen_reg_rtx (SImode); 12603} 12604 [(set (attr "length") 12605 (if_then_else (match_test "operands[2] == const0_rtx") 12606 (const_string "8") 12607 (const_string "12")))]) 12608 12609(define_insn_and_split "*nesi3_ext<mode>" 12610 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 12611 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 12612 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 12613 (clobber (match_scratch:SI 3 "=r")) 12614 (clobber (match_scratch:SI 4 "=r")) 12615 (clobber (match_scratch:EXTSI 5 "=r"))] 12616 "" 12617 "#" 12618 "" 12619 [(set (match_dup 4) 12620 (clz:SI (match_dup 3))) 12621 (set (match_dup 5) 12622 (zero_extend:EXTSI 12623 (lshiftrt:SI (match_dup 4) 12624 (const_int 5)))) 12625 (set (match_dup 0) 12626 (xor:EXTSI (match_dup 5) 12627 (const_int 1)))] 12628{ 12629 operands[3] = rs6000_emit_eqne (SImode, 12630 operands[1], operands[2], operands[3]); 12631 12632 if (GET_CODE (operands[4]) == SCRATCH) 12633 operands[4] = gen_reg_rtx (SImode); 12634 if (GET_CODE (operands[5]) == SCRATCH) 12635 operands[5] = gen_reg_rtx (<MODE>mode); 12636} 12637 [(set (attr "length") 12638 (if_then_else (match_test "operands[2] == const0_rtx") 12639 (const_string "12") 12640 (const_string "16")))]) 12641 12642;; Define both directions of branch and return. If we need a reload 12643;; register, we'd rather use CR0 since it is much easier to copy a 12644;; register CC value to there. 12645 12646(define_insn "" 12647 [(set (pc) 12648 (if_then_else (match_operator 1 "branch_comparison_operator" 12649 [(match_operand 2 12650 "cc_reg_operand" "y") 12651 (const_int 0)]) 12652 (label_ref (match_operand 0 "" "")) 12653 (pc)))] 12654 "" 12655 "* 12656{ 12657 return output_cbranch (operands[1], \"%l0\", 0, insn); 12658}" 12659 [(set_attr "type" "branch")]) 12660 12661(define_insn "" 12662 [(set (pc) 12663 (if_then_else (match_operator 0 "branch_comparison_operator" 12664 [(match_operand 1 12665 "cc_reg_operand" "y") 12666 (const_int 0)]) 12667 (any_return) 12668 (pc)))] 12669 "<return_pred>" 12670 "* 12671{ 12672 return output_cbranch (operands[0], NULL, 0, insn); 12673}" 12674 [(set_attr "type" "jmpreg") 12675 (set_attr "length" "4")]) 12676 12677(define_insn "" 12678 [(set (pc) 12679 (if_then_else (match_operator 1 "branch_comparison_operator" 12680 [(match_operand 2 12681 "cc_reg_operand" "y") 12682 (const_int 0)]) 12683 (pc) 12684 (label_ref (match_operand 0 "" ""))))] 12685 "" 12686 "* 12687{ 12688 return output_cbranch (operands[1], \"%l0\", 1, insn); 12689}" 12690 [(set_attr "type" "branch")]) 12691 12692(define_insn "" 12693 [(set (pc) 12694 (if_then_else (match_operator 0 "branch_comparison_operator" 12695 [(match_operand 1 12696 "cc_reg_operand" "y") 12697 (const_int 0)]) 12698 (pc) 12699 (any_return)))] 12700 "<return_pred>" 12701 "* 12702{ 12703 return output_cbranch (operands[0], NULL, 1, insn); 12704}" 12705 [(set_attr "type" "jmpreg") 12706 (set_attr "length" "4")]) 12707 12708;; Logic on condition register values. 12709 12710; This pattern matches things like 12711; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0)) 12712; (eq:SI (reg:CCFP 68) (const_int 0))) 12713; (const_int 1))) 12714; which are generated by the branch logic. 12715; Prefer destructive operations where BT = BB (for crXX BT,BA,BB) 12716 12717(define_insn "*cceq_ior_compare" 12718 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12719 (compare:CCEQ (match_operator:SI 1 "boolean_operator" 12720 [(match_operator:SI 2 12721 "branch_positive_comparison_operator" 12722 [(match_operand 3 12723 "cc_reg_operand" "y,y") 12724 (const_int 0)]) 12725 (match_operator:SI 4 12726 "branch_positive_comparison_operator" 12727 [(match_operand 5 12728 "cc_reg_operand" "0,y") 12729 (const_int 0)])]) 12730 (const_int 1)))] 12731 "" 12732 "cr%q1 %E0,%j2,%j4" 12733 [(set_attr "type" "cr_logical,delayed_cr")]) 12734 12735; Why is the constant -1 here, but 1 in the previous pattern? 12736; Because ~1 has all but the low bit set. 12737(define_insn "" 12738 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12739 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator" 12740 [(not:SI (match_operator:SI 2 12741 "branch_positive_comparison_operator" 12742 [(match_operand 3 12743 "cc_reg_operand" "y,y") 12744 (const_int 0)])) 12745 (match_operator:SI 4 12746 "branch_positive_comparison_operator" 12747 [(match_operand 5 12748 "cc_reg_operand" "0,y") 12749 (const_int 0)])]) 12750 (const_int -1)))] 12751 "" 12752 "cr%q1 %E0,%j2,%j4" 12753 [(set_attr "type" "cr_logical,delayed_cr")]) 12754 12755(define_insn "*cceq_rev_compare" 12756 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12757 (compare:CCEQ (match_operator:SI 1 12758 "branch_positive_comparison_operator" 12759 [(match_operand 2 12760 "cc_reg_operand" "0,y") 12761 (const_int 0)]) 12762 (const_int 0)))] 12763 "" 12764 "crnot %E0,%j1" 12765 [(set_attr "type" "cr_logical,delayed_cr")]) 12766 12767;; If we are comparing the result of two comparisons, this can be done 12768;; using creqv or crxor. 12769 12770(define_insn_and_split "" 12771 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y") 12772 (compare:CCEQ (match_operator 1 "branch_comparison_operator" 12773 [(match_operand 2 "cc_reg_operand" "y") 12774 (const_int 0)]) 12775 (match_operator 3 "branch_comparison_operator" 12776 [(match_operand 4 "cc_reg_operand" "y") 12777 (const_int 0)])))] 12778 "" 12779 "#" 12780 "" 12781 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3)) 12782 (match_dup 5)))] 12783 " 12784{ 12785 int positive_1, positive_2; 12786 12787 positive_1 = branch_positive_comparison_operator (operands[1], 12788 GET_MODE (operands[1])); 12789 positive_2 = branch_positive_comparison_operator (operands[3], 12790 GET_MODE (operands[3])); 12791 12792 if (! positive_1) 12793 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]), 12794 GET_CODE (operands[1])), 12795 SImode, 12796 operands[2], const0_rtx); 12797 else if (GET_MODE (operands[1]) != SImode) 12798 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, 12799 operands[2], const0_rtx); 12800 12801 if (! positive_2) 12802 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]), 12803 GET_CODE (operands[3])), 12804 SImode, 12805 operands[4], const0_rtx); 12806 else if (GET_MODE (operands[3]) != SImode) 12807 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, 12808 operands[4], const0_rtx); 12809 12810 if (positive_1 == positive_2) 12811 { 12812 operands[1] = gen_rtx_NOT (SImode, operands[1]); 12813 operands[5] = constm1_rtx; 12814 } 12815 else 12816 { 12817 operands[5] = const1_rtx; 12818 } 12819}") 12820 12821;; Unconditional branch and return. 12822 12823(define_insn "jump" 12824 [(set (pc) 12825 (label_ref (match_operand 0 "" "")))] 12826 "" 12827 "b %l0" 12828 [(set_attr "type" "branch")]) 12829 12830(define_insn "<return_str>return" 12831 [(any_return)] 12832 "<return_pred>" 12833 "blr" 12834 [(set_attr "type" "jmpreg")]) 12835 12836(define_expand "indirect_jump" 12837 [(set (pc) (match_operand 0 "register_operand" ""))]) 12838 12839(define_insn "*indirect_jump<mode>" 12840 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))] 12841 "" 12842 "@ 12843 bctr 12844 blr" 12845 [(set_attr "type" "jmpreg")]) 12846 12847;; Table jump for switch statements: 12848(define_expand "tablejump" 12849 [(use (match_operand 0 "" "")) 12850 (use (label_ref (match_operand 1 "" "")))] 12851 "" 12852 " 12853{ 12854 if (TARGET_32BIT) 12855 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); 12856 else 12857 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); 12858 DONE; 12859}") 12860 12861(define_expand "tablejumpsi" 12862 [(set (match_dup 3) 12863 (plus:SI (match_operand:SI 0 "" "") 12864 (match_dup 2))) 12865 (parallel [(set (pc) (match_dup 3)) 12866 (use (label_ref (match_operand 1 "" "")))])] 12867 "TARGET_32BIT" 12868 " 12869{ operands[0] = force_reg (SImode, operands[0]); 12870 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); 12871 operands[3] = gen_reg_rtx (SImode); 12872}") 12873 12874(define_expand "tablejumpdi" 12875 [(set (match_dup 4) 12876 (sign_extend:DI (match_operand:SI 0 "lwa_operand" ""))) 12877 (set (match_dup 3) 12878 (plus:DI (match_dup 4) 12879 (match_dup 2))) 12880 (parallel [(set (pc) (match_dup 3)) 12881 (use (label_ref (match_operand 1 "" "")))])] 12882 "TARGET_64BIT" 12883 " 12884{ operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); 12885 operands[3] = gen_reg_rtx (DImode); 12886 operands[4] = gen_reg_rtx (DImode); 12887}") 12888 12889(define_insn "*tablejump<mode>_internal1" 12890 [(set (pc) 12891 (match_operand:P 0 "register_operand" "c,*l")) 12892 (use (label_ref (match_operand 1 "" "")))] 12893 "" 12894 "@ 12895 bctr 12896 blr" 12897 [(set_attr "type" "jmpreg")]) 12898 12899(define_insn "nop" 12900 [(unspec [(const_int 0)] UNSPEC_NOP)] 12901 "" 12902 "nop") 12903 12904(define_insn "group_ending_nop" 12905 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)] 12906 "" 12907 "* 12908{ 12909 if (rs6000_cpu_attr == CPU_POWER6) 12910 return \"ori 1,1,0\"; 12911 return \"ori 2,2,0\"; 12912}") 12913 12914;; Define the subtract-one-and-jump insns, starting with the template 12915;; so loop.c knows what to generate. 12916 12917(define_expand "doloop_end" 12918 [(use (match_operand 0 "" "")) ; loop pseudo 12919 (use (match_operand 1 "" ""))] ; label 12920 "" 12921 " 12922{ 12923 if (TARGET_64BIT) 12924 { 12925 if (GET_MODE (operands[0]) != DImode) 12926 FAIL; 12927 emit_jump_insn (gen_ctrdi (operands[0], operands[1])); 12928 } 12929 else 12930 { 12931 if (GET_MODE (operands[0]) != SImode) 12932 FAIL; 12933 emit_jump_insn (gen_ctrsi (operands[0], operands[1])); 12934 } 12935 DONE; 12936}") 12937 12938(define_expand "ctr<mode>" 12939 [(parallel [(set (pc) 12940 (if_then_else (ne (match_operand:P 0 "register_operand" "") 12941 (const_int 1)) 12942 (label_ref (match_operand 1 "" "")) 12943 (pc))) 12944 (set (match_dup 0) 12945 (plus:P (match_dup 0) 12946 (const_int -1))) 12947 (clobber (match_scratch:CC 2 "")) 12948 (clobber (match_scratch:P 3 ""))])] 12949 "" 12950 "") 12951 12952;; We need to be able to do this for any operand, including MEM, or we 12953;; will cause reload to blow up since we don't allow output reloads on 12954;; JUMP_INSNs. 12955;; For the length attribute to be calculated correctly, the 12956;; label MUST be operand 0. 12957;; rs6000_legitimate_combined_insn prevents combine creating any of 12958;; the ctr<mode> insns. 12959 12960(define_insn "ctr<mode>_internal1" 12961 [(set (pc) 12962 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12963 (const_int 1)) 12964 (label_ref (match_operand 0 "" "")) 12965 (pc))) 12966 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") 12967 (plus:P (match_dup 1) 12968 (const_int -1))) 12969 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 12970 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 12971 "" 12972 "* 12973{ 12974 if (which_alternative != 0) 12975 return \"#\"; 12976 else if (get_attr_length (insn) == 4) 12977 return \"bdnz %l0\"; 12978 else 12979 return \"bdz $+8\;b %l0\"; 12980}" 12981 [(set_attr "type" "branch") 12982 (set_attr "length" "*,16,20,20")]) 12983 12984(define_insn "ctr<mode>_internal2" 12985 [(set (pc) 12986 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12987 (const_int 1)) 12988 (pc) 12989 (label_ref (match_operand 0 "" "")))) 12990 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") 12991 (plus:P (match_dup 1) 12992 (const_int -1))) 12993 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 12994 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 12995 "" 12996 "* 12997{ 12998 if (which_alternative != 0) 12999 return \"#\"; 13000 else if (get_attr_length (insn) == 4) 13001 return \"bdz %l0\"; 13002 else 13003 return \"bdnz $+8\;b %l0\"; 13004}" 13005 [(set_attr "type" "branch") 13006 (set_attr "length" "*,16,20,20")]) 13007 13008;; Similar but use EQ 13009 13010(define_insn "ctr<mode>_internal3" 13011 [(set (pc) 13012 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b") 13013 (const_int 1)) 13014 (label_ref (match_operand 0 "" "")) 13015 (pc))) 13016 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") 13017 (plus:P (match_dup 1) 13018 (const_int -1))) 13019 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 13020 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 13021 "" 13022 "* 13023{ 13024 if (which_alternative != 0) 13025 return \"#\"; 13026 else if (get_attr_length (insn) == 4) 13027 return \"bdz %l0\"; 13028 else 13029 return \"bdnz $+8\;b %l0\"; 13030}" 13031 [(set_attr "type" "branch") 13032 (set_attr "length" "*,16,20,20")]) 13033 13034(define_insn "ctr<mode>_internal4" 13035 [(set (pc) 13036 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b") 13037 (const_int 1)) 13038 (pc) 13039 (label_ref (match_operand 0 "" "")))) 13040 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l") 13041 (plus:P (match_dup 1) 13042 (const_int -1))) 13043 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 13044 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 13045 "" 13046 "* 13047{ 13048 if (which_alternative != 0) 13049 return \"#\"; 13050 else if (get_attr_length (insn) == 4) 13051 return \"bdnz %l0\"; 13052 else 13053 return \"bdz $+8\;b %l0\"; 13054}" 13055 [(set_attr "type" "branch") 13056 (set_attr "length" "*,16,20,20")]) 13057 13058;; Now the splitters if we could not allocate the CTR register 13059 13060(define_split 13061 [(set (pc) 13062 (if_then_else (match_operator 2 "comparison_operator" 13063 [(match_operand:P 1 "gpc_reg_operand" "") 13064 (const_int 1)]) 13065 (match_operand 5 "" "") 13066 (match_operand 6 "" ""))) 13067 (set (match_operand:P 0 "int_reg_operand" "") 13068 (plus:P (match_dup 1) (const_int -1))) 13069 (clobber (match_scratch:CC 3 "")) 13070 (clobber (match_scratch:P 4 ""))] 13071 "reload_completed" 13072 [(set (match_dup 3) 13073 (compare:CC (match_dup 1) 13074 (const_int 1))) 13075 (set (match_dup 0) 13076 (plus:P (match_dup 1) 13077 (const_int -1))) 13078 (set (pc) (if_then_else (match_dup 7) 13079 (match_dup 5) 13080 (match_dup 6)))] 13081 " 13082{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, 13083 operands[3], const0_rtx); }") 13084 13085(define_split 13086 [(set (pc) 13087 (if_then_else (match_operator 2 "comparison_operator" 13088 [(match_operand:P 1 "gpc_reg_operand" "") 13089 (const_int 1)]) 13090 (match_operand 5 "" "") 13091 (match_operand 6 "" ""))) 13092 (set (match_operand:P 0 "nonimmediate_operand" "") 13093 (plus:P (match_dup 1) (const_int -1))) 13094 (clobber (match_scratch:CC 3 "")) 13095 (clobber (match_scratch:P 4 ""))] 13096 "reload_completed && ! gpc_reg_operand (operands[0], SImode)" 13097 [(set (match_dup 3) 13098 (compare:CC (match_dup 1) 13099 (const_int 1))) 13100 (set (match_dup 4) 13101 (plus:P (match_dup 1) 13102 (const_int -1))) 13103 (set (match_dup 0) 13104 (match_dup 4)) 13105 (set (pc) (if_then_else (match_dup 7) 13106 (match_dup 5) 13107 (match_dup 6)))] 13108 " 13109{ operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, 13110 operands[3], const0_rtx); }") 13111 13112(define_insn "trap" 13113 [(trap_if (const_int 1) (const_int 0))] 13114 "" 13115 "trap" 13116 [(set_attr "type" "trap")]) 13117 13118(define_expand "ctrap<mode>4" 13119 [(trap_if (match_operator 0 "ordered_comparison_operator" 13120 [(match_operand:GPR 1 "register_operand") 13121 (match_operand:GPR 2 "reg_or_short_operand")]) 13122 (match_operand 3 "zero_constant" ""))] 13123 "" 13124 "") 13125 13126(define_insn "" 13127 [(trap_if (match_operator 0 "ordered_comparison_operator" 13128 [(match_operand:GPR 1 "register_operand" "r") 13129 (match_operand:GPR 2 "reg_or_short_operand" "rI")]) 13130 (const_int 0))] 13131 "" 13132 "t<wd>%V0%I2 %1,%2" 13133 [(set_attr "type" "trap")]) 13134 13135;; Insns related to generating the function prologue and epilogue. 13136 13137(define_expand "prologue" 13138 [(use (const_int 0))] 13139 "" 13140{ 13141 rs6000_emit_prologue (); 13142 if (!TARGET_SCHED_PROLOG) 13143 emit_insn (gen_blockage ()); 13144 DONE; 13145}) 13146 13147(define_insn "*movesi_from_cr_one" 13148 [(match_parallel 0 "mfcr_operation" 13149 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 13150 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y") 13151 (match_operand 3 "immediate_operand" "n")] 13152 UNSPEC_MOVESI_FROM_CR))])] 13153 "TARGET_MFCRF" 13154 "* 13155{ 13156 int mask = 0; 13157 int i; 13158 for (i = 0; i < XVECLEN (operands[0], 0); i++) 13159 { 13160 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 13161 operands[4] = GEN_INT (mask); 13162 output_asm_insn (\"mfcr %1,%4\", operands); 13163 } 13164 return \"\"; 13165}" 13166 [(set_attr "type" "mfcrf")]) 13167 13168(define_insn "movesi_from_cr" 13169 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 13170 (unspec:SI [(reg:CC CR0_REGNO) (reg:CC CR1_REGNO) 13171 (reg:CC CR2_REGNO) (reg:CC CR3_REGNO) 13172 (reg:CC CR4_REGNO) (reg:CC CR5_REGNO) 13173 (reg:CC CR6_REGNO) (reg:CC CR7_REGNO)] 13174 UNSPEC_MOVESI_FROM_CR))] 13175 "" 13176 "mfcr %0" 13177 [(set_attr "type" "mfcr")]) 13178 13179(define_insn "*crsave" 13180 [(match_parallel 0 "crsave_operation" 13181 [(set (match_operand:SI 1 "memory_operand" "=m") 13182 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 13183 "" 13184 "stw %2,%1" 13185 [(set_attr "type" "store")]) 13186 13187(define_insn "*stmw" 13188 [(match_parallel 0 "stmw_operation" 13189 [(set (match_operand:SI 1 "memory_operand" "=m") 13190 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 13191 "TARGET_MULTIPLE" 13192 "stmw %2,%1" 13193 [(set_attr "type" "store") 13194 (set_attr "update" "yes") 13195 (set_attr "indexed" "yes")]) 13196 13197; The following comment applies to: 13198; save_gpregs_* 13199; save_fpregs_* 13200; restore_gpregs* 13201; return_and_restore_gpregs* 13202; return_and_restore_fpregs* 13203; return_and_restore_fpregs_aix* 13204; 13205; The out-of-line save / restore functions expects one input argument. 13206; Since those are not standard call_insn's, we must avoid using 13207; MATCH_OPERAND for that argument. That way the register rename 13208; optimization will not try to rename this register. 13209; Each pattern is repeated for each possible register number used in 13210; various ABIs (r11, r1, and for some functions r12) 13211 13212(define_insn "*save_gpregs_<mode>_r11" 13213 [(match_parallel 0 "any_parallel_operand" 13214 [(clobber (reg:P LR_REGNO)) 13215 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13216 (use (reg:P 11)) 13217 (set (match_operand:P 2 "memory_operand" "=m") 13218 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13219 "" 13220 "bl %1" 13221 [(set_attr "type" "branch") 13222 (set_attr "length" "4")]) 13223 13224(define_insn "*save_gpregs_<mode>_r12" 13225 [(match_parallel 0 "any_parallel_operand" 13226 [(clobber (reg:P LR_REGNO)) 13227 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13228 (use (reg:P 12)) 13229 (set (match_operand:P 2 "memory_operand" "=m") 13230 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13231 "" 13232 "bl %1" 13233 [(set_attr "type" "branch") 13234 (set_attr "length" "4")]) 13235 13236(define_insn "*save_gpregs_<mode>_r1" 13237 [(match_parallel 0 "any_parallel_operand" 13238 [(clobber (reg:P LR_REGNO)) 13239 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13240 (use (reg:P 1)) 13241 (set (match_operand:P 2 "memory_operand" "=m") 13242 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13243 "" 13244 "bl %1" 13245 [(set_attr "type" "branch") 13246 (set_attr "length" "4")]) 13247 13248(define_insn "*save_fpregs_<mode>_r11" 13249 [(match_parallel 0 "any_parallel_operand" 13250 [(clobber (reg:P LR_REGNO)) 13251 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13252 (use (reg:P 11)) 13253 (set (match_operand:DF 2 "memory_operand" "=m") 13254 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13255 "" 13256 "bl %1" 13257 [(set_attr "type" "branch") 13258 (set_attr "length" "4")]) 13259 13260(define_insn "*save_fpregs_<mode>_r12" 13261 [(match_parallel 0 "any_parallel_operand" 13262 [(clobber (reg:P LR_REGNO)) 13263 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13264 (use (reg:P 12)) 13265 (set (match_operand:DF 2 "memory_operand" "=m") 13266 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13267 "" 13268 "bl %1" 13269 [(set_attr "type" "branch") 13270 (set_attr "length" "4")]) 13271 13272(define_insn "*save_fpregs_<mode>_r1" 13273 [(match_parallel 0 "any_parallel_operand" 13274 [(clobber (reg:P LR_REGNO)) 13275 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13276 (use (reg:P 1)) 13277 (set (match_operand:DF 2 "memory_operand" "=m") 13278 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13279 "" 13280 "bl %1" 13281 [(set_attr "type" "branch") 13282 (set_attr "length" "4")]) 13283 13284; This is to explain that changes to the stack pointer should 13285; not be moved over loads from or stores to stack memory. 13286(define_insn "stack_tie" 13287 [(match_parallel 0 "tie_operand" 13288 [(set (mem:BLK (reg 1)) (const_int 0))])] 13289 "" 13290 "" 13291 [(set_attr "length" "0")]) 13292 13293; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to 13294; stay behind all restores from the stack, it cannot be reordered to before 13295; one. See PR77687. This insn is an add or mr, and a stack_tie on the 13296; operands of that. 13297(define_insn "stack_restore_tie" 13298 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 13299 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") 13300 (match_operand:SI 2 "reg_or_cint_operand" "O,rI"))) 13301 (set (mem:BLK (match_dup 0)) (const_int 0)) 13302 (set (mem:BLK (match_dup 1)) (const_int 0))] 13303 "TARGET_32BIT" 13304 "@ 13305 mr %0,%1 13306 add%I2 %0,%1,%2" 13307 [(set_attr "type" "*,add")]) 13308 13309(define_expand "epilogue" 13310 [(use (const_int 0))] 13311 "" 13312{ 13313 if (!TARGET_SCHED_PROLOG) 13314 emit_insn (gen_blockage ()); 13315 rs6000_emit_epilogue (FALSE); 13316 DONE; 13317}) 13318 13319; On some processors, doing the mtcrf one CC register at a time is 13320; faster (like on the 604e). On others, doing them all at once is 13321; faster; for instance, on the 601 and 750. 13322 13323(define_expand "movsi_to_cr_one" 13324 [(set (match_operand:CC 0 "cc_reg_operand" "") 13325 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "") 13326 (match_dup 2)] UNSPEC_MOVESI_TO_CR))] 13327 "" 13328 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));") 13329 13330(define_insn "*movsi_to_cr" 13331 [(match_parallel 0 "mtcrf_operation" 13332 [(set (match_operand:CC 1 "cc_reg_operand" "=y") 13333 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r") 13334 (match_operand 3 "immediate_operand" "n")] 13335 UNSPEC_MOVESI_TO_CR))])] 13336 "" 13337 "* 13338{ 13339 int mask = 0; 13340 int i; 13341 for (i = 0; i < XVECLEN (operands[0], 0); i++) 13342 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 13343 operands[4] = GEN_INT (mask); 13344 return \"mtcrf %4,%2\"; 13345}" 13346 [(set_attr "type" "mtcr")]) 13347 13348(define_insn "*mtcrfsi" 13349 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 13350 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 13351 (match_operand 2 "immediate_operand" "n")] 13352 UNSPEC_MOVESI_TO_CR))] 13353 "GET_CODE (operands[0]) == REG 13354 && CR_REGNO_P (REGNO (operands[0])) 13355 && GET_CODE (operands[2]) == CONST_INT 13356 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))" 13357 "mtcrf %R0,%1" 13358 [(set_attr "type" "mtcr")]) 13359 13360; The load-multiple instructions have similar properties. 13361; Note that "load_multiple" is a name known to the machine-independent 13362; code that actually corresponds to the PowerPC load-string. 13363 13364(define_insn "*lmw" 13365 [(match_parallel 0 "lmw_operation" 13366 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 13367 (match_operand:SI 2 "memory_operand" "m"))])] 13368 "TARGET_MULTIPLE" 13369 "lmw %1,%2" 13370 [(set_attr "type" "load") 13371 (set_attr "update" "yes") 13372 (set_attr "indexed" "yes") 13373 (set_attr "cell_micro" "always")]) 13374 13375; FIXME: This would probably be somewhat simpler if the Cygnus sibcall 13376; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible... 13377 13378; The following comment applies to: 13379; save_gpregs_* 13380; save_fpregs_* 13381; restore_gpregs* 13382; return_and_restore_gpregs* 13383; return_and_restore_fpregs* 13384; return_and_restore_fpregs_aix* 13385; 13386; The out-of-line save / restore functions expects one input argument. 13387; Since those are not standard call_insn's, we must avoid using 13388; MATCH_OPERAND for that argument. That way the register rename 13389; optimization will not try to rename this register. 13390; Each pattern is repeated for each possible register number used in 13391; various ABIs (r11, r1, and for some functions r12) 13392 13393(define_insn "*restore_gpregs_<mode>_r11" 13394 [(match_parallel 0 "any_parallel_operand" 13395 [(clobber (reg:P LR_REGNO)) 13396 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13397 (use (reg:P 11)) 13398 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13399 (match_operand:P 3 "memory_operand" "m"))])] 13400 "" 13401 "bl %1" 13402 [(set_attr "type" "branch") 13403 (set_attr "length" "4")]) 13404 13405(define_insn "*restore_gpregs_<mode>_r12" 13406 [(match_parallel 0 "any_parallel_operand" 13407 [(clobber (reg:P LR_REGNO)) 13408 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13409 (use (reg:P 12)) 13410 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13411 (match_operand:P 3 "memory_operand" "m"))])] 13412 "" 13413 "bl %1" 13414 [(set_attr "type" "branch") 13415 (set_attr "length" "4")]) 13416 13417(define_insn "*restore_gpregs_<mode>_r1" 13418 [(match_parallel 0 "any_parallel_operand" 13419 [(clobber (reg:P LR_REGNO)) 13420 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13421 (use (reg:P 1)) 13422 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13423 (match_operand:P 3 "memory_operand" "m"))])] 13424 "" 13425 "bl %1" 13426 [(set_attr "type" "branch") 13427 (set_attr "length" "4")]) 13428 13429(define_insn "*return_and_restore_gpregs_<mode>_r11" 13430 [(match_parallel 0 "any_parallel_operand" 13431 [(return) 13432 (clobber (reg:P LR_REGNO)) 13433 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13434 (use (reg:P 11)) 13435 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13436 (match_operand:P 3 "memory_operand" "m"))])] 13437 "" 13438 "b %1" 13439 [(set_attr "type" "branch") 13440 (set_attr "length" "4")]) 13441 13442(define_insn "*return_and_restore_gpregs_<mode>_r12" 13443 [(match_parallel 0 "any_parallel_operand" 13444 [(return) 13445 (clobber (reg:P LR_REGNO)) 13446 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13447 (use (reg:P 12)) 13448 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13449 (match_operand:P 3 "memory_operand" "m"))])] 13450 "" 13451 "b %1" 13452 [(set_attr "type" "branch") 13453 (set_attr "length" "4")]) 13454 13455(define_insn "*return_and_restore_gpregs_<mode>_r1" 13456 [(match_parallel 0 "any_parallel_operand" 13457 [(return) 13458 (clobber (reg:P LR_REGNO)) 13459 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13460 (use (reg:P 1)) 13461 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13462 (match_operand:P 3 "memory_operand" "m"))])] 13463 "" 13464 "b %1" 13465 [(set_attr "type" "branch") 13466 (set_attr "length" "4")]) 13467 13468(define_insn "*return_and_restore_fpregs_<mode>_r11" 13469 [(match_parallel 0 "any_parallel_operand" 13470 [(return) 13471 (clobber (reg:P LR_REGNO)) 13472 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13473 (use (reg:P 11)) 13474 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13475 (match_operand:DF 3 "memory_operand" "m"))])] 13476 "" 13477 "b %1" 13478 [(set_attr "type" "branch") 13479 (set_attr "length" "4")]) 13480 13481(define_insn "*return_and_restore_fpregs_<mode>_r12" 13482 [(match_parallel 0 "any_parallel_operand" 13483 [(return) 13484 (clobber (reg:P LR_REGNO)) 13485 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13486 (use (reg:P 12)) 13487 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13488 (match_operand:DF 3 "memory_operand" "m"))])] 13489 "" 13490 "b %1" 13491 [(set_attr "type" "branch") 13492 (set_attr "length" "4")]) 13493 13494(define_insn "*return_and_restore_fpregs_<mode>_r1" 13495 [(match_parallel 0 "any_parallel_operand" 13496 [(return) 13497 (clobber (reg:P LR_REGNO)) 13498 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13499 (use (reg:P 1)) 13500 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13501 (match_operand:DF 3 "memory_operand" "m"))])] 13502 "" 13503 "b %1" 13504 [(set_attr "type" "branch") 13505 (set_attr "length" "4")]) 13506 13507(define_insn "*return_and_restore_fpregs_aix_<mode>_r11" 13508 [(match_parallel 0 "any_parallel_operand" 13509 [(return) 13510 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13511 (use (reg:P 11)) 13512 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13513 (match_operand:DF 3 "memory_operand" "m"))])] 13514 "" 13515 "b %1" 13516 [(set_attr "type" "branch") 13517 (set_attr "length" "4")]) 13518 13519(define_insn "*return_and_restore_fpregs_aix_<mode>_r1" 13520 [(match_parallel 0 "any_parallel_operand" 13521 [(return) 13522 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13523 (use (reg:P 1)) 13524 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13525 (match_operand:DF 3 "memory_operand" "m"))])] 13526 "" 13527 "b %1" 13528 [(set_attr "type" "branch") 13529 (set_attr "length" "4")]) 13530 13531; This is used in compiling the unwind routines. 13532(define_expand "eh_return" 13533 [(use (match_operand 0 "general_operand" ""))] 13534 "" 13535 " 13536{ 13537 if (TARGET_32BIT) 13538 emit_insn (gen_eh_set_lr_si (operands[0])); 13539 else 13540 emit_insn (gen_eh_set_lr_di (operands[0])); 13541 DONE; 13542}") 13543 13544; We can't expand this before we know where the link register is stored. 13545(define_insn "eh_set_lr_<mode>" 13546 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] 13547 UNSPECV_EH_RR) 13548 (clobber (match_scratch:P 1 "=&b"))] 13549 "" 13550 "#") 13551 13552(define_split 13553 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR) 13554 (clobber (match_scratch 1 ""))] 13555 "reload_completed" 13556 [(const_int 0)] 13557 " 13558{ 13559 rs6000_emit_eh_reg_restore (operands[0], operands[1]); 13560 DONE; 13561}") 13562 13563(define_insn "prefetch" 13564 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a") 13565 (match_operand:SI 1 "const_int_operand" "n") 13566 (match_operand:SI 2 "const_int_operand" "n"))] 13567 "" 13568 "* 13569{ 13570 if (GET_CODE (operands[0]) == REG) 13571 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\"; 13572 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\"; 13573}" 13574 [(set_attr "type" "load")]) 13575 13576;; Handle -fsplit-stack. 13577 13578(define_expand "split_stack_prologue" 13579 [(const_int 0)] 13580 "" 13581{ 13582 rs6000_expand_split_stack_prologue (); 13583 DONE; 13584}) 13585 13586(define_expand "load_split_stack_limit" 13587 [(set (match_operand 0) 13588 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))] 13589 "" 13590{ 13591 emit_insn (gen_rtx_SET (operands[0], 13592 gen_rtx_UNSPEC (Pmode, 13593 gen_rtvec (1, const0_rtx), 13594 UNSPEC_STACK_CHECK))); 13595 DONE; 13596}) 13597 13598(define_insn "load_split_stack_limit_di" 13599 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 13600 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))] 13601 "TARGET_64BIT" 13602 "ld %0,-0x7040(13)" 13603 [(set_attr "type" "load") 13604 (set_attr "update" "no") 13605 (set_attr "indexed" "no")]) 13606 13607(define_insn "load_split_stack_limit_si" 13608 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 13609 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))] 13610 "!TARGET_64BIT" 13611 "lwz %0,-0x7020(2)" 13612 [(set_attr "type" "load") 13613 (set_attr "update" "no") 13614 (set_attr "indexed" "no")]) 13615 13616;; A return instruction which the middle-end doesn't see. 13617;; Use r0 to stop regrename twiddling with lr restore insns emitted 13618;; after the call to __morestack. 13619(define_insn "split_stack_return" 13620 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)] 13621 "" 13622 "blr" 13623 [(set_attr "type" "jmpreg")]) 13624 13625;; If there are operand 0 bytes available on the stack, jump to 13626;; operand 1. 13627(define_expand "split_stack_space_check" 13628 [(set (match_dup 2) 13629 (unspec [(const_int 0)] UNSPEC_STACK_CHECK)) 13630 (set (match_dup 3) 13631 (minus (reg STACK_POINTER_REGNUM) 13632 (match_operand 0))) 13633 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2))) 13634 (set (pc) (if_then_else 13635 (geu (match_dup 4) (const_int 0)) 13636 (label_ref (match_operand 1)) 13637 (pc)))] 13638 "" 13639{ 13640 rs6000_split_stack_space_check (operands[0], operands[1]); 13641 DONE; 13642}) 13643 13644(define_insn "bpermd_<mode>" 13645 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 13646 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") 13647 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))] 13648 "TARGET_POPCNTD" 13649 "bpermd %0,%1,%2" 13650 [(set_attr "type" "popcnt")]) 13651 13652 13653;; Builtin fma support. Handle 13654;; Note that the conditions for expansion are in the FMA_F iterator. 13655 13656(define_expand "fma<mode>4" 13657 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") 13658 (fma:FMA_F 13659 (match_operand:FMA_F 1 "gpc_reg_operand" "") 13660 (match_operand:FMA_F 2 "gpc_reg_operand" "") 13661 (match_operand:FMA_F 3 "gpc_reg_operand" "")))] 13662 "" 13663 "") 13664 13665(define_insn "*fma<mode>4_fpr" 13666 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 13667 (fma:SFDF 13668 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>") 13669 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 13670 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))] 13671 "TARGET_<MODE>_FPR" 13672 "@ 13673 fmadd<Ftrad> %0,%1,%2,%3 13674 xsmadda<Fvsx> %x0,%x1,%x2 13675 xsmaddm<Fvsx> %x0,%x1,%x3" 13676 [(set_attr "type" "fp") 13677 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 13678 13679; Altivec only has fma and nfms. 13680(define_expand "fms<mode>4" 13681 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") 13682 (fma:FMA_F 13683 (match_operand:FMA_F 1 "gpc_reg_operand" "") 13684 (match_operand:FMA_F 2 "gpc_reg_operand" "") 13685 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))] 13686 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13687 "") 13688 13689(define_insn "*fms<mode>4_fpr" 13690 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 13691 (fma:SFDF 13692 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") 13693 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 13694 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] 13695 "TARGET_<MODE>_FPR" 13696 "@ 13697 fmsub<Ftrad> %0,%1,%2,%3 13698 xsmsuba<Fvsx> %x0,%x1,%x2 13699 xsmsubm<Fvsx> %x0,%x1,%x3" 13700 [(set_attr "type" "fp") 13701 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 13702 13703;; If signed zeros are ignored, -(a * b - c) = -a * b + c. 13704(define_expand "fnma<mode>4" 13705 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") 13706 (neg:FMA_F 13707 (fma:FMA_F 13708 (match_operand:FMA_F 1 "gpc_reg_operand" "") 13709 (match_operand:FMA_F 2 "gpc_reg_operand" "") 13710 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))] 13711 "!HONOR_SIGNED_ZEROS (<MODE>mode)" 13712 "") 13713 13714;; If signed zeros are ignored, -(a * b + c) = -a * b - c. 13715(define_expand "fnms<mode>4" 13716 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") 13717 (neg:FMA_F 13718 (fma:FMA_F 13719 (match_operand:FMA_F 1 "gpc_reg_operand" "") 13720 (match_operand:FMA_F 2 "gpc_reg_operand" "") 13721 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))] 13722 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13723 "") 13724 13725; Not an official optab name, but used from builtins. 13726(define_expand "nfma<mode>4" 13727 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") 13728 (neg:FMA_F 13729 (fma:FMA_F 13730 (match_operand:FMA_F 1 "gpc_reg_operand" "") 13731 (match_operand:FMA_F 2 "gpc_reg_operand" "") 13732 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))] 13733 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13734 "") 13735 13736(define_insn "*nfma<mode>4_fpr" 13737 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 13738 (neg:SFDF 13739 (fma:SFDF 13740 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") 13741 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 13742 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))] 13743 "TARGET_<MODE>_FPR" 13744 "@ 13745 fnmadd<Ftrad> %0,%1,%2,%3 13746 xsnmadda<Fvsx> %x0,%x1,%x2 13747 xsnmaddm<Fvsx> %x0,%x1,%x3" 13748 [(set_attr "type" "fp") 13749 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 13750 13751; Not an official optab name, but used from builtins. 13752(define_expand "nfms<mode>4" 13753 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "") 13754 (neg:FMA_F 13755 (fma:FMA_F 13756 (match_operand:FMA_F 1 "gpc_reg_operand" "") 13757 (match_operand:FMA_F 2 "gpc_reg_operand" "") 13758 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))] 13759 "" 13760 "") 13761 13762(define_insn "*nfmssf4_fpr" 13763 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>") 13764 (neg:SFDF 13765 (fma:SFDF 13766 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>") 13767 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0") 13768 (neg:SFDF 13769 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))] 13770 "TARGET_<MODE>_FPR" 13771 "@ 13772 fnmsub<Ftrad> %0,%1,%2,%3 13773 xsnmsuba<Fvsx> %x0,%x1,%x2 13774 xsnmsubm<Fvsx> %x0,%x1,%x3" 13775 [(set_attr "type" "fp") 13776 (set_attr "fp_type" "fp_maddsub_<Fs>")]) 13777 13778 13779(define_expand "rs6000_get_timebase" 13780 [(use (match_operand:DI 0 "gpc_reg_operand" ""))] 13781 "" 13782{ 13783 if (TARGET_POWERPC64) 13784 emit_insn (gen_rs6000_mftb_di (operands[0])); 13785 else 13786 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0])); 13787 DONE; 13788}) 13789 13790(define_insn "rs6000_get_timebase_ppc32" 13791 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 13792 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB)) 13793 (clobber (match_scratch:SI 1 "=r")) 13794 (clobber (match_scratch:CC 2 "=y"))] 13795 "!TARGET_POWERPC64" 13796{ 13797 if (WORDS_BIG_ENDIAN) 13798 if (TARGET_MFCRF) 13799 { 13800 return "mfspr %0,269\;" 13801 "mfspr %L0,268\;" 13802 "mfspr %1,269\;" 13803 "cmpw %2,%0,%1\;" 13804 "bne- %2,$-16"; 13805 } 13806 else 13807 { 13808 return "mftbu %0\;" 13809 "mftb %L0\;" 13810 "mftbu %1\;" 13811 "cmpw %2,%0,%1\;" 13812 "bne- %2,$-16"; 13813 } 13814 else 13815 if (TARGET_MFCRF) 13816 { 13817 return "mfspr %L0,269\;" 13818 "mfspr %0,268\;" 13819 "mfspr %1,269\;" 13820 "cmpw %2,%L0,%1\;" 13821 "bne- %2,$-16"; 13822 } 13823 else 13824 { 13825 return "mftbu %L0\;" 13826 "mftb %0\;" 13827 "mftbu %1\;" 13828 "cmpw %2,%L0,%1\;" 13829 "bne- %2,$-16"; 13830 } 13831} 13832 [(set_attr "length" "20")]) 13833 13834(define_insn "rs6000_mftb_<mode>" 13835 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 13836 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))] 13837 "" 13838{ 13839 if (TARGET_MFCRF) 13840 return "mfspr %0,268"; 13841 else 13842 return "mftb %0"; 13843}) 13844 13845 13846(define_insn "rs6000_mffs" 13847 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 13848 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))] 13849 "TARGET_HARD_FLOAT && TARGET_FPRS" 13850 "mffs %0") 13851 13852(define_insn "rs6000_mtfsf" 13853 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i") 13854 (match_operand:DF 1 "gpc_reg_operand" "d")] 13855 UNSPECV_MTFSF)] 13856 "TARGET_HARD_FLOAT && TARGET_FPRS" 13857 "mtfsf %0,%1") 13858 13859 13860;; Power8 fusion support for fusing an addis instruction with a D-form load of 13861;; a GPR. The addis instruction must be adjacent to the load, and use the same 13862;; register that is being loaded. The fused ops must be physically adjacent. 13863 13864;; There are two parts to addis fusion. The support for fused TOCs occur 13865;; before register allocation, and is meant to reduce the lifetime for the 13866;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try 13867;; to use the register that is being load. The peephole2 then gathers any 13868;; other fused possibilities that it can find after register allocation. If 13869;; power9 fusion is selected, we also fuse floating point loads/stores. 13870 13871;; Fused TOC support: Replace simple GPR loads with a fused form. This is done 13872;; before register allocation, so that we can avoid allocating a temporary base 13873;; register that won't be used, and that we try to load into base registers, 13874;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion 13875;; (addis followed by load) even on power8. 13876 13877(define_split 13878 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "") 13879 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))] 13880 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()" 13881 [(parallel [(set (match_dup 0) (match_dup 2)) 13882 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) 13883 (use (match_dup 3)) 13884 (clobber (scratch:DI))])] 13885{ 13886 operands[2] = fusion_wrap_memory_address (operands[1]); 13887 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER); 13888}) 13889 13890(define_insn "*toc_fusionload_<mode>" 13891 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r") 13892 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG")) 13893 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) 13894 (use (match_operand:DI 2 "base_reg_operand" "r,r")) 13895 (clobber (match_scratch:DI 3 "=X,&b"))] 13896 "TARGET_TOC_FUSION_INT" 13897{ 13898 if (base_reg_operand (operands[0], <MODE>mode)) 13899 return emit_fusion_gpr_load (operands[0], operands[1]); 13900 13901 return emit_fusion_p9_load (operands[0], operands[1], operands[3]); 13902} 13903 [(set_attr "type" "load") 13904 (set_attr "length" "8")]) 13905 13906(define_insn "*toc_fusionload_di" 13907 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d") 13908 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG")) 13909 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS) 13910 (use (match_operand:DI 2 "base_reg_operand" "r,r,r")) 13911 (clobber (match_scratch:DI 3 "=X,&b,&b"))] 13912 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64 13913 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))" 13914{ 13915 if (base_reg_operand (operands[0], DImode)) 13916 return emit_fusion_gpr_load (operands[0], operands[1]); 13917 13918 return emit_fusion_p9_load (operands[0], operands[1], operands[3]); 13919} 13920 [(set_attr "type" "load") 13921 (set_attr "length" "8")]) 13922 13923 13924;; Find cases where the addis that feeds into a load instruction is either used 13925;; once or is the same as the target register, and replace it with the fusion 13926;; insn 13927 13928(define_peephole2 13929 [(set (match_operand:P 0 "base_reg_operand" "") 13930 (match_operand:P 1 "fusion_gpr_addis" "")) 13931 (set (match_operand:INT1 2 "base_reg_operand" "") 13932 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))] 13933 "TARGET_P8_FUSION 13934 && fusion_gpr_load_p (operands[0], operands[1], operands[2], 13935 operands[3])" 13936 [(const_int 0)] 13937{ 13938 expand_fusion_gpr_load (operands); 13939 DONE; 13940}) 13941 13942;; Fusion insn, created by the define_peephole2 above (and eventually by 13943;; reload) 13944 13945(define_insn "fusion_gpr_load_<mode>" 13946 [(set (match_operand:INT1 0 "base_reg_operand" "=b") 13947 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")] 13948 UNSPEC_FUSION_GPR))] 13949 "TARGET_P8_FUSION" 13950{ 13951 return emit_fusion_gpr_load (operands[0], operands[1]); 13952} 13953 [(set_attr "type" "load") 13954 (set_attr "length" "8")]) 13955 13956 13957;; ISA 3.0 (power9) fusion support 13958;; Merge addis with floating load/store to FPRs (or GPRs). 13959(define_peephole2 13960 [(set (match_operand:P 0 "base_reg_operand" "") 13961 (match_operand:P 1 "fusion_gpr_addis" "")) 13962 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "") 13963 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))] 13964 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0]) 13965 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])" 13966 [(const_int 0)] 13967{ 13968 expand_fusion_p9_load (operands); 13969 DONE; 13970}) 13971 13972(define_peephole2 13973 [(set (match_operand:P 0 "base_reg_operand" "") 13974 (match_operand:P 1 "fusion_gpr_addis" "")) 13975 (set (match_operand:SFDF 2 "offsettable_mem_operand" "") 13976 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))] 13977 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0]) 13978 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3]) 13979 && !rtx_equal_p (operands[0], operands[3])" 13980 [(const_int 0)] 13981{ 13982 expand_fusion_p9_store (operands); 13983 DONE; 13984}) 13985 13986(define_peephole2 13987 [(set (match_operand:SDI 0 "int_reg_operand" "") 13988 (match_operand:SDI 1 "upper16_cint_operand" "")) 13989 (set (match_dup 0) 13990 (ior:SDI (match_dup 0) 13991 (match_operand:SDI 2 "u_short_cint_operand" "")))] 13992 "TARGET_P9_FUSION" 13993 [(set (match_dup 0) 13994 (unspec:SDI [(match_dup 1) 13995 (match_dup 2)] UNSPEC_FUSION_P9))]) 13996 13997(define_peephole2 13998 [(set (match_operand:SDI 0 "int_reg_operand" "") 13999 (match_operand:SDI 1 "upper16_cint_operand" "")) 14000 (set (match_operand:SDI 2 "int_reg_operand" "") 14001 (ior:SDI (match_dup 0) 14002 (match_operand:SDI 3 "u_short_cint_operand" "")))] 14003 "TARGET_P9_FUSION 14004 && !rtx_equal_p (operands[0], operands[2]) 14005 && peep2_reg_dead_p (2, operands[0])" 14006 [(set (match_dup 2) 14007 (unspec:SDI [(match_dup 1) 14008 (match_dup 3)] UNSPEC_FUSION_P9))]) 14009 14010;; Fusion insns, created by the define_peephole2 above (and eventually by 14011;; reload). Because we want to eventually have secondary_reload generate 14012;; these, they have to have a single alternative that gives the register 14013;; classes. This means we need to have separate gpr/fpr/altivec versions. 14014(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load" 14015 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r") 14016 (unspec:GPR_FUSION 14017 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")] 14018 UNSPEC_FUSION_P9)) 14019 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 14020 "TARGET_P9_FUSION" 14021{ 14022 /* This insn is a secondary reload insn, which cannot have alternatives. 14023 If we are not loading up register 0, use the power8 fusion instead. */ 14024 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode)) 14025 return emit_fusion_gpr_load (operands[0], operands[1]); 14026 14027 return emit_fusion_p9_load (operands[0], operands[1], operands[2]); 14028} 14029 [(set_attr "type" "load") 14030 (set_attr "length" "8")]) 14031 14032(define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store" 14033 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF") 14034 (unspec:GPR_FUSION 14035 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")] 14036 UNSPEC_FUSION_P9)) 14037 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 14038 "TARGET_P9_FUSION" 14039{ 14040 return emit_fusion_p9_store (operands[0], operands[1], operands[2]); 14041} 14042 [(set_attr "type" "store") 14043 (set_attr "length" "8")]) 14044 14045(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load" 14046 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb") 14047 (unspec:FPR_FUSION 14048 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")] 14049 UNSPEC_FUSION_P9)) 14050 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 14051 "TARGET_P9_FUSION" 14052{ 14053 return emit_fusion_p9_load (operands[0], operands[1], operands[2]); 14054} 14055 [(set_attr "type" "fpload") 14056 (set_attr "length" "8")]) 14057 14058(define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store" 14059 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF") 14060 (unspec:FPR_FUSION 14061 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")] 14062 UNSPEC_FUSION_P9)) 14063 (clobber (match_operand:P 2 "base_reg_operand" "=b"))] 14064 "TARGET_P9_FUSION" 14065{ 14066 return emit_fusion_p9_store (operands[0], operands[1], operands[2]); 14067} 14068 [(set_attr "type" "fpstore") 14069 (set_attr "length" "8")]) 14070 14071(define_insn "*fusion_p9_<mode>_constant" 14072 [(set (match_operand:SDI 0 "int_reg_operand" "=r") 14073 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L") 14074 (match_operand:SDI 2 "u_short_cint_operand" "K")] 14075 UNSPEC_FUSION_P9))] 14076 "TARGET_P9_FUSION" 14077{ 14078 emit_fusion_addis (operands[0], operands[1], "constant", "<MODE>"); 14079 return "ori %0,%0,%2"; 14080} 14081 [(set_attr "type" "two") 14082 (set_attr "length" "8")]) 14083 14084 14085;; Optimize cases where we want to do a D-form load (register+offset) on 14086;; ISA 2.06/2.07 to an Altivec register, and the register allocator 14087;; has generated: 14088;; LFD 0,32(3) 14089;; XXLOR 32,0,0 14090;; 14091;; and we change this to: 14092;; LI 0,32 14093;; LXSDX 32,3,9 14094 14095(define_peephole2 14096 [(match_scratch:DI 0 "b") 14097 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 14098 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand")) 14099 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand") 14100 (match_dup 1))] 14101 "TARGET_VSX && TARGET_POWERPC64 && TARGET_UPPER_REGS_<MODE> 14102 && !TARGET_P9_DFORM_SCALAR && peep2_reg_dead_p (2, operands[1])" 14103 [(set (match_dup 0) 14104 (match_dup 4)) 14105 (set (match_dup 3) 14106 (match_dup 5))] 14107{ 14108 rtx tmp_reg = operands[0]; 14109 rtx mem = operands[2]; 14110 rtx addr = XEXP (mem, 0); 14111 rtx add_op0, add_op1, new_addr; 14112 14113 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 14114 add_op0 = XEXP (addr, 0); 14115 add_op1 = XEXP (addr, 1); 14116 gcc_assert (REG_P (add_op0)); 14117 new_addr = gen_rtx_PLUS (DImode, add_op0, tmp_reg); 14118 14119 operands[4] = add_op1; 14120 operands[5] = change_address (mem, <MODE>mode, new_addr); 14121}) 14122 14123;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an 14124;; Altivec register, and the register allocator has generated: 14125;; XXLOR 0,32,32 14126;; STFD 0,32(3) 14127;; 14128;; and we change this to: 14129;; LI 0,32 14130;; STXSDX 32,3,9 14131 14132(define_peephole2 14133 [(match_scratch:DI 0 "b") 14134 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 14135 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand")) 14136 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand") 14137 (match_dup 1))] 14138 "TARGET_VSX && TARGET_POWERPC64 && TARGET_UPPER_REGS_<MODE> 14139 && !TARGET_P9_DFORM_SCALAR && peep2_reg_dead_p (2, operands[1])" 14140 [(set (match_dup 0) 14141 (match_dup 4)) 14142 (set (match_dup 5) 14143 (match_dup 2))] 14144{ 14145 rtx tmp_reg = operands[0]; 14146 rtx mem = operands[3]; 14147 rtx addr = XEXP (mem, 0); 14148 rtx add_op0, add_op1, new_addr; 14149 14150 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 14151 add_op0 = XEXP (addr, 0); 14152 add_op1 = XEXP (addr, 1); 14153 gcc_assert (REG_P (add_op0)); 14154 new_addr = gen_rtx_PLUS (DImode, add_op0, tmp_reg); 14155 14156 operands[4] = add_op1; 14157 operands[5] = change_address (mem, <MODE>mode, new_addr); 14158}) 14159 14160 14161;; Miscellaneous ISA 2.06 (power7) instructions 14162(define_insn "addg6s" 14163 [(set (match_operand:SI 0 "register_operand" "=r") 14164 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 14165 (match_operand:SI 2 "register_operand" "r")] 14166 UNSPEC_ADDG6S))] 14167 "TARGET_POPCNTD" 14168 "addg6s %0,%1,%2" 14169 [(set_attr "type" "integer") 14170 (set_attr "length" "4")]) 14171 14172(define_insn "cdtbcd" 14173 [(set (match_operand:SI 0 "register_operand" "=r") 14174 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 14175 UNSPEC_CDTBCD))] 14176 "TARGET_POPCNTD" 14177 "cdtbcd %0,%1" 14178 [(set_attr "type" "integer") 14179 (set_attr "length" "4")]) 14180 14181(define_insn "cbcdtd" 14182 [(set (match_operand:SI 0 "register_operand" "=r") 14183 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 14184 UNSPEC_CBCDTD))] 14185 "TARGET_POPCNTD" 14186 "cbcdtd %0,%1" 14187 [(set_attr "type" "integer") 14188 (set_attr "length" "4")]) 14189 14190(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE 14191 UNSPEC_DIVEO 14192 UNSPEC_DIVEU 14193 UNSPEC_DIVEUO]) 14194 14195(define_int_attr div_extend [(UNSPEC_DIVE "e") 14196 (UNSPEC_DIVEO "eo") 14197 (UNSPEC_DIVEU "eu") 14198 (UNSPEC_DIVEUO "euo")]) 14199 14200(define_insn "div<div_extend>_<mode>" 14201 [(set (match_operand:GPR 0 "register_operand" "=r") 14202 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r") 14203 (match_operand:GPR 2 "register_operand" "r")] 14204 UNSPEC_DIV_EXTEND))] 14205 "TARGET_POPCNTD" 14206 "div<wd><div_extend> %0,%1,%2" 14207 [(set_attr "type" "div") 14208 (set_attr "size" "<bits>")]) 14209 14210 14211;; Pack/unpack 128-bit floating point types that take 2 scalar registers 14212 14213; Type of the 64-bit part when packing/unpacking 128-bit floating point types 14214(define_mode_attr FP128_64 [(TF "DF") 14215 (IF "DF") 14216 (TD "DI") 14217 (KF "DI")]) 14218 14219(define_expand "unpack<mode>" 14220 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "") 14221 (unspec:<FP128_64> 14222 [(match_operand:FMOVE128 1 "register_operand" "") 14223 (match_operand:QI 2 "const_0_to_1_operand" "")] 14224 UNSPEC_UNPACK_128BIT))] 14225 "FLOAT128_2REG_P (<MODE>mode)" 14226 "") 14227 14228(define_insn_and_split "unpack<mode>_dm" 14229 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m") 14230 (unspec:<FP128_64> 14231 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r") 14232 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")] 14233 UNSPEC_UNPACK_128BIT))] 14234 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)" 14235 "#" 14236 "&& reload_completed" 14237 [(set (match_dup 0) (match_dup 3))] 14238{ 14239 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 14240 14241 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 14242 { 14243 emit_note (NOTE_INSN_DELETED); 14244 DONE; 14245 } 14246 14247 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 14248} 14249 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store") 14250 (set_attr "length" "4")]) 14251 14252(define_insn_and_split "unpack<mode>_nodm" 14253 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m") 14254 (unspec:<FP128_64> 14255 [(match_operand:FMOVE128 1 "register_operand" "d,d") 14256 (match_operand:QI 2 "const_0_to_1_operand" "i,i")] 14257 UNSPEC_UNPACK_128BIT))] 14258 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)" 14259 "#" 14260 "&& reload_completed" 14261 [(set (match_dup 0) (match_dup 3))] 14262{ 14263 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 14264 14265 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 14266 { 14267 emit_note (NOTE_INSN_DELETED); 14268 DONE; 14269 } 14270 14271 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 14272} 14273 [(set_attr "type" "fp,fpstore") 14274 (set_attr "length" "4")]) 14275 14276(define_insn_and_split "pack<mode>" 14277 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d") 14278 (unspec:FMOVE128 14279 [(match_operand:<FP128_64> 1 "register_operand" "0,d") 14280 (match_operand:<FP128_64> 2 "register_operand" "d,d")] 14281 UNSPEC_PACK_128BIT))] 14282 "FLOAT128_2REG_P (<MODE>mode)" 14283 "@ 14284 fmr %L0,%2 14285 #" 14286 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])" 14287 [(set (match_dup 3) (match_dup 1)) 14288 (set (match_dup 4) (match_dup 2))] 14289{ 14290 unsigned dest_hi = REGNO (operands[0]); 14291 unsigned dest_lo = dest_hi + 1; 14292 14293 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo)); 14294 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); 14295 14296 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); 14297 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); 14298} 14299 [(set_attr "type" "fpsimple,fp") 14300 (set_attr "length" "4,8")]) 14301 14302(define_insn "unpack<mode>" 14303 [(set (match_operand:DI 0 "register_operand" "=d,d") 14304 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa") 14305 (match_operand:QI 2 "const_0_to_1_operand" "O,i")] 14306 UNSPEC_UNPACK_128BIT))] 14307 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 14308{ 14309 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0) 14310 return ASM_COMMENT_START " xxpermdi to same register"; 14311 14312 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3); 14313 return "xxpermdi %x0,%x1,%x1,%3"; 14314} 14315 [(set_attr "type" "vecperm")]) 14316 14317(define_insn "pack<mode>" 14318 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa") 14319 (unspec:FMOVE128_VSX 14320 [(match_operand:DI 1 "register_operand" "d") 14321 (match_operand:DI 2 "register_operand" "d")] 14322 UNSPEC_PACK_128BIT))] 14323 "TARGET_VSX" 14324 "xxpermdi %x0,%x1,%x2,0" 14325 [(set_attr "type" "vecperm")]) 14326 14327 14328 14329;; ISA 2.08 IEEE 128-bit floating point support. 14330 14331(define_insn "add<mode>3" 14332 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14333 (plus:IEEE128 14334 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14335 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14336 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14337 "xsaddqp %0,%1,%2" 14338 [(set_attr "type" "vecfloat") 14339 (set_attr "size" "128")]) 14340 14341(define_insn "sub<mode>3" 14342 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14343 (minus:IEEE128 14344 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14345 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14346 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14347 "xssubqp %0,%1,%2" 14348 [(set_attr "type" "vecfloat") 14349 (set_attr "size" "128")]) 14350 14351(define_insn "mul<mode>3" 14352 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14353 (mult:IEEE128 14354 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14355 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14356 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14357 "xsmulqp %0,%1,%2" 14358 [(set_attr "type" "vecfloat") 14359 (set_attr "size" "128")]) 14360 14361(define_insn "div<mode>3" 14362 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14363 (div:IEEE128 14364 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14365 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14366 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14367 "xsdivqp %0,%1,%2" 14368 [(set_attr "type" "vecdiv") 14369 (set_attr "size" "128")]) 14370 14371(define_insn "sqrt<mode>2" 14372 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14373 (sqrt:IEEE128 14374 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14375 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14376 "xssqrtqp %0,%1" 14377 [(set_attr "type" "vecdiv") 14378 (set_attr "size" "128")]) 14379 14380(define_expand "copysign<mode>3" 14381 [(use (match_operand:IEEE128 0 "altivec_register_operand")) 14382 (use (match_operand:IEEE128 1 "altivec_register_operand")) 14383 (use (match_operand:IEEE128 2 "altivec_register_operand"))] 14384 "FLOAT128_IEEE_P (<MODE>mode)" 14385{ 14386 if (TARGET_FLOAT128_HW) 14387 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1], 14388 operands[2])); 14389 else 14390 { 14391 rtx tmp = gen_reg_rtx (<MODE>mode); 14392 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1], 14393 operands[2], tmp)); 14394 } 14395 DONE; 14396}) 14397 14398(define_insn "copysign<mode>3_hard" 14399 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14400 (unspec:IEEE128 14401 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14402 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14403 UNSPEC_COPYSIGN))] 14404 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14405 "xscpsgnqp %0,%2,%1" 14406 [(set_attr "type" "vecmove") 14407 (set_attr "size" "128")]) 14408 14409(define_insn "copysign<mode>3_soft" 14410 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14411 (unspec:IEEE128 14412 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14413 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14414 (match_operand:IEEE128 3 "altivec_register_operand" "+v")] 14415 UNSPEC_COPYSIGN))] 14416 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14417 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1" 14418 [(set_attr "type" "veccomplex") 14419 (set_attr "length" "8")]) 14420 14421(define_insn "neg<mode>2_hw" 14422 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14423 (neg:IEEE128 14424 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14425 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14426 "xsnegqp %0,%1" 14427 [(set_attr "type" "vecmove") 14428 (set_attr "size" "128")]) 14429 14430 14431(define_insn "abs<mode>2_hw" 14432 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14433 (abs:IEEE128 14434 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14435 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14436 "xsabsqp %0,%1" 14437 [(set_attr "type" "vecmove") 14438 (set_attr "size" "128")]) 14439 14440 14441(define_insn "*nabs<mode>2_hw" 14442 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14443 (neg:IEEE128 14444 (abs:IEEE128 14445 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))] 14446 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14447 "xsnabsqp %0,%1" 14448 [(set_attr "type" "vecmove") 14449 (set_attr "size" "128")]) 14450 14451;; Initially don't worry about doing fusion 14452(define_insn "*fma<mode>4_hw" 14453 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14454 (fma:IEEE128 14455 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14456 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14457 (match_operand:IEEE128 3 "altivec_register_operand" "0")))] 14458 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14459 "xsmaddqp %0,%1,%2" 14460 [(set_attr "type" "vecfloat") 14461 (set_attr "size" "128")]) 14462 14463(define_insn "*fms<mode>4_hw" 14464 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14465 (fma:IEEE128 14466 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14467 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14468 (neg:IEEE128 14469 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 14470 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14471 "xsmsubqp %0,%1,%2" 14472 [(set_attr "type" "vecfloat") 14473 (set_attr "size" "128")]) 14474 14475(define_insn "*nfma<mode>4_hw" 14476 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14477 (neg:IEEE128 14478 (fma:IEEE128 14479 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14480 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14481 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 14482 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14483 "xsnmaddqp %0,%1,%2" 14484 [(set_attr "type" "vecfloat") 14485 (set_attr "size" "128")]) 14486 14487(define_insn "*nfms<mode>4_hw" 14488 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14489 (neg:IEEE128 14490 (fma:IEEE128 14491 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14492 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14493 (neg:IEEE128 14494 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))] 14495 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14496 "xsnmsubqp %0,%1,%2" 14497 [(set_attr "type" "vecfloat") 14498 (set_attr "size" "128")]) 14499 14500(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw" 14501 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14502 (float_extend:IEEE128 14503 (match_operand:SFDF 1 "altivec_register_operand" "v")))] 14504 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14505 "xscvdpqp %0,%1" 14506 [(set_attr "type" "vecfloat") 14507 (set_attr "size" "128")]) 14508 14509;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating 14510;; point is a simple copy. 14511(define_insn_and_split "extendkftf2" 14512 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa") 14513 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))] 14514 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD" 14515 "@ 14516 # 14517 xxlor %x0,%x1,%x1" 14518 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 14519 [(const_int 0)] 14520{ 14521 emit_note (NOTE_INSN_DELETED); 14522 DONE; 14523} 14524 [(set_attr "type" "*,veclogical") 14525 (set_attr "length" "0,4")]) 14526 14527(define_insn_and_split "trunctfkf2" 14528 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa") 14529 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))] 14530 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD" 14531 "@ 14532 # 14533 xxlor %x0,%x1,%x1" 14534 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 14535 [(const_int 0)] 14536{ 14537 emit_note (NOTE_INSN_DELETED); 14538 DONE; 14539} 14540 [(set_attr "type" "*,veclogical") 14541 (set_attr "length" "0,4")]) 14542 14543(define_insn "trunc<mode>df2_hw" 14544 [(set (match_operand:DF 0 "altivec_register_operand" "=v") 14545 (float_truncate:DF 14546 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14547 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14548 "xscvqpdp %0,%1" 14549 [(set_attr "type" "vecfloat") 14550 (set_attr "size" "128")]) 14551 14552;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing 14553;; the KFmode -> DFmode conversion using round to odd rather than the normal 14554;; conversion 14555(define_insn_and_split "trunc<mode>sf2_hw" 14556 [(set (match_operand:SF 0 "vsx_register_operand" "=wy") 14557 (float_truncate:SF 14558 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 14559 (clobber (match_scratch:DF 2 "=v"))] 14560 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14561 "#" 14562 "&& 1" 14563 [(set (match_dup 2) 14564 (unspec:DF [(match_dup 1)] UNSPEC_ROUND_TO_ODD)) 14565 (set (match_dup 0) 14566 (float_truncate:SF (match_dup 2)))] 14567{ 14568 if (GET_CODE (operands[2]) == SCRATCH) 14569 operands[2] = gen_reg_rtx (DFmode); 14570} 14571 [(set_attr "type" "vecfloat") 14572 (set_attr "length" "8")]) 14573 14574;; Conversion between IEEE 128-bit and integer types 14575(define_insn "fix_<mode>di2_hw" 14576 [(set (match_operand:DI 0 "altivec_register_operand" "=v") 14577 (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14578 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14579 "xscvqpsdz %0,%1" 14580 [(set_attr "type" "vecfloat") 14581 (set_attr "size" "128")]) 14582 14583(define_insn "fixuns_<mode>di2_hw" 14584 [(set (match_operand:DI 0 "altivec_register_operand" "=v") 14585 (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14586 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14587 "xscvqpudz %0,%1" 14588 [(set_attr "type" "vecfloat") 14589 (set_attr "size" "128")]) 14590 14591(define_insn "fix_<mode>si2_hw" 14592 [(set (match_operand:SI 0 "altivec_register_operand" "=v") 14593 (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14594 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14595 "xscvqpswz %0,%1" 14596 [(set_attr "type" "vecfloat") 14597 (set_attr "size" "128")]) 14598 14599(define_insn "fixuns_<mode>si2_hw" 14600 [(set (match_operand:SI 0 "altivec_register_operand" "=v") 14601 (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14602 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14603 "xscvqpuwz %0,%1" 14604 [(set_attr "type" "vecfloat") 14605 (set_attr "size" "128")]) 14606 14607;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit 14608;; floating point value to 32-bit integer to GPR in order to save it. 14609(define_insn_and_split "*fix<uns>_<mode>_mem" 14610 [(set (match_operand:SI 0 "memory_operand" "=Z") 14611 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 14612 (clobber (match_scratch:SI 2 "=v"))] 14613 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14614 "#" 14615 "&& reload_completed" 14616 [(set (match_dup 2) 14617 (any_fix:SI (match_dup 1))) 14618 (set (match_dup 0) 14619 (match_dup 2))]) 14620 14621(define_insn "float_<mode>di2_hw" 14622 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14623 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))] 14624 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14625 "xscvsdqp %0,%1" 14626 [(set_attr "type" "vecfloat") 14627 (set_attr "size" "128")]) 14628 14629(define_insn_and_split "float_<mode>si2_hw" 14630 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14631 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ"))) 14632 (clobber (match_scratch:DI 2 "=v"))] 14633 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14634 "#" 14635 "&& 1" 14636 [(set (match_dup 2) 14637 (sign_extend:DI (match_dup 1))) 14638 (set (match_dup 0) 14639 (float:IEEE128 (match_dup 2)))] 14640{ 14641 if (GET_CODE (operands[2]) == SCRATCH) 14642 operands[2] = gen_reg_rtx (DImode); 14643}) 14644 14645(define_insn_and_split "float<QHI:mode><IEEE128:mode>2" 14646 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 14647 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) 14648 (clobber (match_scratch:DI 2 "=X,r,X"))] 14649 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14650 "#" 14651 "&& reload_completed" 14652 [(const_int 0)] 14653{ 14654 rtx dest = operands[0]; 14655 rtx src = operands[1]; 14656 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest)); 14657 14658 if (altivec_register_operand (src, <QHI:MODE>mode)) 14659 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src)); 14660 else if (int_reg_operand (src, <QHI:MODE>mode)) 14661 { 14662 rtx ext_di = operands[2]; 14663 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src)); 14664 emit_move_insn (dest_di, ext_di); 14665 } 14666 else if (MEM_P (src)) 14667 { 14668 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest)); 14669 emit_move_insn (dest_qhi, src); 14670 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi)); 14671 } 14672 else 14673 gcc_unreachable (); 14674 14675 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di)); 14676 DONE; 14677} 14678 [(set_attr "length" "8,12,12") 14679 (set_attr "type" "vecfloat") 14680 (set_attr "size" "128")]) 14681 14682(define_insn "floatuns_<mode>di2_hw" 14683 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14684 (unsigned_float:IEEE128 14685 (match_operand:DI 1 "altivec_register_operand" "v")))] 14686 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14687 "xscvudqp %0,%1" 14688 [(set_attr "type" "vecfloat") 14689 (set_attr "size" "128")]) 14690 14691(define_insn_and_split "floatuns_<mode>si2_hw" 14692 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14693 (unsigned_float:IEEE128 14694 (match_operand:SI 1 "nonimmediate_operand" "vrZ"))) 14695 (clobber (match_scratch:DI 2 "=v"))] 14696 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14697 "#" 14698 "&& 1" 14699 [(set (match_dup 2) 14700 (zero_extend:DI (match_dup 1))) 14701 (set (match_dup 0) 14702 (float:IEEE128 (match_dup 2)))] 14703{ 14704 if (GET_CODE (operands[2]) == SCRATCH) 14705 operands[2] = gen_reg_rtx (DImode); 14706}) 14707 14708(define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2" 14709 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 14710 (unsigned_float:IEEE128 14711 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) 14712 (clobber (match_scratch:DI 2 "=X,r,X"))] 14713 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14714 "#" 14715 "&& reload_completed" 14716 [(const_int 0)] 14717{ 14718 rtx dest = operands[0]; 14719 rtx src = operands[1]; 14720 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest)); 14721 14722 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src)) 14723 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src)); 14724 else if (int_reg_operand (src, <QHI:MODE>mode)) 14725 { 14726 rtx ext_di = operands[2]; 14727 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src)); 14728 emit_move_insn (dest_di, ext_di); 14729 } 14730 else 14731 gcc_unreachable (); 14732 14733 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di)); 14734 DONE; 14735} 14736 [(set_attr "length" "8,12,8") 14737 (set_attr "type" "vecfloat") 14738 (set_attr "size" "128")]) 14739 14740;; IEEE 128-bit instructions with round to odd semantics 14741(define_insn "*trunc<mode>df2_odd" 14742 [(set (match_operand:DF 0 "vsx_register_operand" "=v") 14743 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14744 UNSPEC_ROUND_TO_ODD))] 14745 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14746 "xscvqpdpo %0,%1" 14747 [(set_attr "type" "vecfloat") 14748 (set_attr "size" "128")]) 14749 14750;; IEEE 128-bit comparisons 14751(define_insn "*cmp<mode>_hw" 14752 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 14753 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v") 14754 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14755 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14756 "xscmpuqp %0,%1,%2" 14757 [(set_attr "type" "veccmp") 14758 (set_attr "size" "128")]) 14759 14760 14761 14762(include "sync.md") 14763(include "vector.md") 14764(include "vsx.md") 14765(include "altivec.md") 14766(include "spe.md") 14767(include "dfp.md") 14768(include "paired.md") 14769(include "crypto.md") 14770(include "htm.md") 14771