1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler 2 ;; Copyright (C) 1990-2022 Free Software Foundation, Inc. 3 ;; Contributed by Richard Kenner (kenner (a] 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 (FIRST_ALTIVEC_REGNO 64) 37 (LAST_ALTIVEC_REGNO 95) 38 (LR_REGNO 96) 39 (CTR_REGNO 97) 40 (CA_REGNO 98) 41 (ARG_POINTER_REGNUM 99) 42 (CR0_REGNO 100) 43 (CR1_REGNO 101) 44 (CR2_REGNO 102) 45 (CR3_REGNO 103) 46 (CR4_REGNO 104) 47 (CR5_REGNO 105) 48 (CR6_REGNO 106) 49 (CR7_REGNO 107) 50 (MAX_CR_REGNO 107) 51 (VRSAVE_REGNO 108) 52 (VSCR_REGNO 109) 53 (FRAME_POINTER_REGNUM 110) 54 ]) 55 56 ;; 57 ;; UNSPEC usage 58 ;; 59 60 (define_c_enum "unspec" 61 [UNSPEC_PROBE_STACK ; probe stack memory reference 62 UNSPEC_TOCPTR ; address of a word pointing to the TOC 63 UNSPEC_TOC ; address of the TOC (more-or-less) 64 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot 65 UNSPEC_MOVSI_GOT 66 UNSPEC_FCTIWZ 67 UNSPEC_FRIM 68 UNSPEC_FRIN 69 UNSPEC_FRIP 70 UNSPEC_FRIZ 71 UNSPEC_XSRDPI 72 UNSPEC_LD_MPIC ; load_macho_picbase 73 UNSPEC_RELD_MPIC ; re-load_macho_picbase 74 UNSPEC_MPIC_CORRECT ; macho_correct_pic 75 UNSPEC_TLSGD 76 UNSPEC_TLSLD 77 UNSPEC_TLS_GET_ADDR 78 UNSPEC_MOVESI_FROM_CR 79 UNSPEC_MOVESI_TO_CR 80 UNSPEC_XVTLSBB 81 UNSPEC_TLSDTPREL 82 UNSPEC_TLSDTPRELHA 83 UNSPEC_TLSDTPRELLO 84 UNSPEC_TLSGOTDTPREL 85 UNSPEC_TLSTPREL 86 UNSPEC_TLSTPRELHA 87 UNSPEC_TLSTPRELLO 88 UNSPEC_TLSGOTTPREL 89 UNSPEC_TLSTLS 90 UNSPEC_TLSTLS_PCREL 91 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero 92 UNSPEC_STFIWX 93 UNSPEC_POPCNTB 94 UNSPEC_FRES 95 UNSPEC_SP_SET 96 UNSPEC_SP_TEST 97 UNSPEC_SYNC 98 UNSPEC_LWSYNC 99 UNSPEC_SYNC_OP 100 UNSPEC_ATOMIC 101 UNSPEC_CMPXCHG 102 UNSPEC_XCHG 103 UNSPEC_AND 104 UNSPEC_DLMZB 105 UNSPEC_DLMZB_CR 106 UNSPEC_DLMZB_STRLEN 107 UNSPEC_RSQRT 108 UNSPEC_TOCREL 109 UNSPEC_MACHOPIC_OFFSET 110 UNSPEC_BPERM 111 UNSPEC_COPYSIGN 112 UNSPEC_PARITY 113 UNSPEC_CMPB 114 UNSPEC_FCTIW 115 UNSPEC_FCTID 116 UNSPEC_LFIWAX 117 UNSPEC_LFIWZX 118 UNSPEC_FCTIWUZ 119 UNSPEC_NOP 120 UNSPEC_GRP_END_NOP 121 UNSPEC_P8V_FMRGOW 122 UNSPEC_P8V_MTVSRWZ 123 UNSPEC_P8V_RELOAD_FROM_GPR 124 UNSPEC_P8V_MTVSRD 125 UNSPEC_P8V_XXPERMDI 126 UNSPEC_P8V_RELOAD_FROM_VSX 127 UNSPEC_ADDG6S 128 UNSPEC_CDTBCD 129 UNSPEC_CBCDTD 130 UNSPEC_DIVE 131 UNSPEC_DIVEU 132 UNSPEC_UNPACK_128BIT 133 UNSPEC_PACK_128BIT 134 UNSPEC_LSQ 135 UNSPEC_FUSION_GPR 136 UNSPEC_STACK_CHECK 137 UNSPEC_CMPRB 138 UNSPEC_CMPRB2 139 UNSPEC_CMPEQB 140 UNSPEC_ADD_ROUND_TO_ODD 141 UNSPEC_SUB_ROUND_TO_ODD 142 UNSPEC_MUL_ROUND_TO_ODD 143 UNSPEC_DIV_ROUND_TO_ODD 144 UNSPEC_FMA_ROUND_TO_ODD 145 UNSPEC_SQRT_ROUND_TO_ODD 146 UNSPEC_TRUNC_ROUND_TO_ODD 147 UNSPEC_SIGNBIT 148 UNSPEC_SF_FROM_SI 149 UNSPEC_SI_FROM_SF 150 UNSPEC_PLTSEQ 151 UNSPEC_PLT16_HA 152 UNSPEC_CFUGED 153 UNSPEC_CNTLZDM 154 UNSPEC_CNTTZDM 155 UNSPEC_PDEPD 156 UNSPEC_PEXTD 157 UNSPEC_HASHST 158 UNSPEC_HASHCHK 159 UNSPEC_XXSPLTIDP_CONST 160 UNSPEC_XXSPLTIW_CONST 161 ]) 162 163 ;; 164 ;; UNSPEC_VOLATILE usage 165 ;; 166 167 (define_c_enum "unspecv" 168 [UNSPECV_BLOCK 169 UNSPECV_LL ; load-locked 170 UNSPECV_SC ; store-conditional 171 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses 172 UNSPECV_EH_RR ; eh_reg_restore 173 UNSPECV_ISYNC ; isync instruction 174 UNSPECV_MFTB ; move from time base 175 UNSPECV_DARN ; darn (deliver a random number) 176 UNSPECV_NLGR ; non-local goto receiver 177 UNSPECV_MFFS ; Move from FPSCR 178 UNSPECV_MFFSL ; Move from FPSCR light instruction version 179 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode 180 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode 181 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15 182 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7 183 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0 184 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1 185 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return 186 UNSPECV_SPEC_BARRIER ; Speculation barrier 187 UNSPECV_PLT16_LO 188 UNSPECV_PLT_PCREL 189 ]) 190 191 ; The three different kinds of epilogue. 192 (define_enum "epilogue_type" [normal sibcall eh_return]) 193 195 ;; Define an insn type attribute. This is used in function unit delay 196 ;; computations. 197 (define_attr "type" 198 "integer,two,three, 199 add,logical,shift,insert, 200 mul,halfmul,div, 201 exts,cntlz,popcnt,isel, 202 load,store,fpload,fpstore,vecload,vecstore, 203 cmp, 204 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c, 205 cr_logical,mfcr,mfcrf,mtcr, 206 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt, 207 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm, 208 vecfloat,vecfdiv,vecdouble,mtvsr,mfvsr,crypto, 209 veclogical,veccmpfx,vecexts,vecmove, 210 htm,htmsimple,dfp,mma, 211 fused_arith_logical, 212 fused_cmp_isel, 213 fused_carry, 214 fused_load_cmpi, 215 fused_load_load,fused_store_store, 216 fused_addis_load, 217 fused_mtbc, 218 fused_vector" 219 (const_string "integer")) 220 ;; Attr type definitions for fused pairs: 221 ;; fused_arith_logical is used for scalar logical+add/subf and 222 ;; add/subf+logical pairs of instructions. 223 ;; fused_load_cmpi is used for a D-form load fused with 224 ;; a compare immediate. 225 ;; fused_load_load is for a fused pair of loads to adjacent addresses. 226 ;; fused_store_store is for a fused pair of stores to adjacent addresses. 227 ;; fused_addis_load is for addis fused to D-form load for a larger immediate. 228 ;; fused_mtbc is for fused mtlr and bclr[l] pairs. 229 ;; fused_vector is for a fused pair of vector logical instructions. 230 231 ;; What data size does this instruction work on? 232 ;; This is used for insert, mul and others as necessary. 233 (define_attr "size" "8,16,32,64,128,256" (const_string "32")) 234 235 ;; What is the insn_cost for this insn? The target hook can still override 236 ;; this. For optimizing for size the "length" attribute is used instead. 237 (define_attr "cost" "" (const_int 0)) 238 239 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)? 240 ;; This is used for add, logical, shift, exts, mul. 241 (define_attr "dot" "no,yes" (const_string "no")) 242 243 ;; Does this instruction sign-extend its result? 244 ;; This is used for load insns. 245 (define_attr "sign_extend" "no,yes" (const_string "no")) 246 247 ;; Does this cr_logical instruction have three operands? That is, BT != BB. 248 (define_attr "cr_logical_3op" "no,yes" (const_string "no")) 249 250 ;; Does this instruction use indexed (that is, reg+reg) addressing? 251 ;; This is used for load and store insns. If operand 0 or 1 is a MEM 252 ;; it is automatically set based on that. If a load or store instruction 253 ;; has fewer than two operands it needs to set this attribute manually 254 ;; or the compiler will crash. 255 (define_attr "indexed" "no,yes" 256 (if_then_else (ior (match_operand 0 "indexed_address_mem") 257 (match_operand 1 "indexed_address_mem")) 258 (const_string "yes") 259 (const_string "no"))) 260 261 ;; Does this instruction use update addressing? 262 ;; This is used for load and store insns. See the comments for "indexed". 263 (define_attr "update" "no,yes" 264 (if_then_else (ior (match_operand 0 "update_address_mem") 265 (match_operand 1 "update_address_mem")) 266 (const_string "yes") 267 (const_string "no"))) 268 269 ;; Is this instruction using operands[2] as shift amount, and can that be a 270 ;; register? 271 ;; This is used for shift insns. 272 (define_attr "maybe_var_shift" "no,yes" (const_string "no")) 273 274 ;; Is this instruction using a shift amount from a register? 275 ;; This is used for shift insns. 276 (define_attr "var_shift" "no,yes" 277 (if_then_else (and (eq_attr "type" "shift") 278 (eq_attr "maybe_var_shift" "yes")) 279 (if_then_else (match_operand 2 "gpc_reg_operand") 280 (const_string "yes") 281 (const_string "no")) 282 (const_string "no"))) 283 284 ;; Is copying of this instruction disallowed? 285 (define_attr "cannot_copy" "no,yes" (const_string "no")) 286 287 288 ;; Whether this insn has a prefixed form and a non-prefixed form. 289 (define_attr "maybe_prefixed" "no,yes" 290 (if_then_else (eq_attr "type" "load,fpload,vecload,store,fpstore,vecstore, 291 integer,add,fused_load_cmpi") 292 (const_string "yes") 293 (const_string "no"))) 294 295 ;; Whether an insn is a prefixed insn. A prefixed instruction has a prefix 296 ;; instruction word that conveys additional information such as a larger 297 ;; immediate, additional operands, etc., in addition to the normal instruction 298 ;; word. The default "length" attribute will also be adjusted by default to 299 ;; be 12 bytes. 300 (define_attr "prefixed" "no,yes" 301 (cond [(ior (match_test "!TARGET_PREFIXED") 302 (match_test "!NONJUMP_INSN_P (insn)") 303 (eq_attr "maybe_prefixed" "no")) 304 (const_string "no") 305 306 (eq_attr "type" "load,fpload,vecload,fused_load_cmpi") 307 (if_then_else (match_test "prefixed_load_p (insn)") 308 (const_string "yes") 309 (const_string "no")) 310 311 (eq_attr "type" "store,fpstore,vecstore") 312 (if_then_else (match_test "prefixed_store_p (insn)") 313 (const_string "yes") 314 (const_string "no")) 315 316 (eq_attr "type" "integer,add") 317 (if_then_else (match_test "prefixed_paddi_p (insn)") 318 (const_string "yes") 319 (const_string "no"))] 320 321 (const_string "no"))) 322 323 ;; Whether an insn loads an external address for the PCREL_OPT optimizaton. 324 (define_attr "loads_external_address" "no,yes" 325 (const_string "no")) 326 327 ;; Return the number of real hardware instructions in a combined insn. If it 328 ;; is 0, just use the length / 4. 329 (define_attr "num_insns" "" (const_int 0)) 330 331 ;; If an insn is prefixed, return the maximum number of prefixed instructions 332 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the 333 ;; insn length. 334 (define_attr "max_prefixed_insns" "" (const_int 1)) 335 336 ;; Length of the instruction (in bytes). This length does not consider the 337 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust 338 ;; the length if there are prefixed instructions. 339 ;; 340 ;; While it might be tempting to use num_insns to calculate the length, it can 341 ;; be problematical unless all insn lengths are adjusted to use num_insns 342 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get 343 ;; num_insns and recurse). 344 (define_attr "length" "" (const_int 4)) 345 346 ;; Processor type -- this attribute must exactly match the processor_type 347 ;; enumeration in rs6000-opts.h. 348 (define_attr "cpu" 349 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630, 350 ppc750,ppc7400,ppc7450, 351 ppc403,ppc405,ppc440,ppc476, 352 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500, 353 power4,power5,power6,power7,power8,power9,power10, 354 rs64a,mpccore,cell,ppca2,titan" 355 (const (symbol_ref "(enum attr_cpu) rs6000_tune"))) 356 357 ;; The ISA we implement. 358 (define_attr "isa" "any,p5,p6,p7,p7v,p8,p8v,p9,p9v,p9kf,p9tf,p10" 359 (const_string "any")) 360 361 ;; Is this alternative enabled for the current CPU/ISA/etc.? 362 (define_attr "enabled" "" 363 (cond 364 [(eq_attr "isa" "any") 365 (const_int 1) 366 367 (and (eq_attr "isa" "p5") 368 (match_test "TARGET_POPCNTB")) 369 (const_int 1) 370 371 (and (eq_attr "isa" "p6") 372 (match_test "TARGET_CMPB")) 373 (const_int 1) 374 375 (and (eq_attr "isa" "p7") 376 (match_test "TARGET_POPCNTD")) 377 (const_int 1) 378 379 (and (eq_attr "isa" "p7v") 380 (match_test "TARGET_VSX")) 381 (const_int 1) 382 383 (and (eq_attr "isa" "p8") 384 (match_test "TARGET_POWER8")) 385 (const_int 1) 386 387 (and (eq_attr "isa" "p8v") 388 (match_test "TARGET_P8_VECTOR")) 389 (const_int 1) 390 391 (and (eq_attr "isa" "p9") 392 (match_test "TARGET_MODULO")) 393 (const_int 1) 394 395 (and (eq_attr "isa" "p9v") 396 (match_test "TARGET_P9_VECTOR")) 397 (const_int 1) 398 399 (and (eq_attr "isa" "p9kf") 400 (match_test "TARGET_FLOAT128_TYPE")) 401 (const_int 1) 402 403 (and (eq_attr "isa" "p9tf") 404 (match_test "FLOAT128_VECTOR_P (TFmode)")) 405 (const_int 1) 406 407 (and (eq_attr "isa" "p10") 408 (match_test "TARGET_POWER10")) 409 (const_int 1) 410 ] (const_int 0))) 411 412 ;; If this instruction is microcoded on the CELL processor 413 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded 414 (define_attr "cell_micro" "not,conditional,always" 415 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul") 416 (eq_attr "dot" "yes")) 417 (and (eq_attr "type" "load") 418 (eq_attr "sign_extend" "yes")) 419 (and (eq_attr "type" "shift") 420 (eq_attr "var_shift" "yes"))) 421 (const_string "always") 422 (const_string "not"))) 423 424 (automata_option "ndfa") 425 426 (include "rs64.md") 427 (include "mpc.md") 428 (include "40x.md") 429 (include "440.md") 430 (include "476.md") 431 (include "601.md") 432 (include "603.md") 433 (include "6xx.md") 434 (include "7xx.md") 435 (include "7450.md") 436 (include "8540.md") 437 (include "e300c2c3.md") 438 (include "e500mc.md") 439 (include "e500mc64.md") 440 (include "e5500.md") 441 (include "e6500.md") 442 (include "power4.md") 443 (include "power5.md") 444 (include "power6.md") 445 (include "power7.md") 446 (include "power8.md") 447 (include "power9.md") 448 (include "power10.md") 449 (include "cell.md") 450 (include "a2.md") 451 (include "titan.md") 452 453 (include "predicates.md") 454 (include "constraints.md") 455 456 458 ;; Mode iterators 459 460 ; This mode iterator allows :GPR to be used to indicate the allowable size 461 ; of whole values in GPRs. 462 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")]) 463 464 ; And again, for patterns that need two (potentially) different integer modes. 465 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")]) 466 467 ; Any supported integer mode. 468 (define_mode_iterator INT [QI HI SI DI TI PTI]) 469 470 ; Any supported integer mode that fits in one register. 471 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")]) 472 473 ; Integer modes supported in VSX registers with ISA 3.0 instructions 474 (define_mode_iterator INT_ISA3 [QI HI SI DI]) 475 476 ; Everything we can extend QImode to. 477 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")]) 478 479 ; Everything we can extend HImode to. 480 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")]) 481 482 ; Everything we can extend SImode to. 483 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")]) 484 485 ; QImode or HImode for small integer moves and small atomic ops 486 (define_mode_iterator QHI [QI HI]) 487 488 ; QImode, HImode, SImode for fused ops only for GPR loads 489 (define_mode_iterator QHSI [QI HI SI]) 490 491 ; HImode or SImode for sign extended fusion ops 492 (define_mode_iterator HSI [HI SI]) 493 494 ; SImode or DImode, even if DImode doesn't fit in GPRs. 495 (define_mode_iterator SDI [SI DI]) 496 497 ; The size of a pointer. Also, the size of the value that a record-condition 498 ; (one with a '.') will compare; and the size used for arithmetic carries. 499 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")]) 500 501 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers, 502 ; PTImode is GPR only) 503 (define_mode_iterator TI2 [TI PTI]) 504 505 ; Any hardware-supported floating-point mode 506 (define_mode_iterator FP [ 507 (SF "TARGET_HARD_FLOAT") 508 (DF "TARGET_HARD_FLOAT") 509 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128") 510 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128") 511 (KF "TARGET_FLOAT128_TYPE") 512 (DD "TARGET_DFP") 513 (TD "TARGET_DFP")]) 514 515 ; Any fma capable floating-point mode. 516 (define_mode_iterator FMA_F [ 517 (SF "TARGET_HARD_FLOAT") 518 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)") 519 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)") 520 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)") 521 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)") 522 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)") 523 ]) 524 525 ; Floating point move iterators to combine binary and decimal moves 526 (define_mode_iterator FMOVE32 [SF SD]) 527 (define_mode_iterator FMOVE64 [DF DD]) 528 (define_mode_iterator FMOVE64X [DI DF DD]) 529 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128") 530 (IF "FLOAT128_IBM_P (IFmode)") 531 (TD "TARGET_HARD_FLOAT")]) 532 533 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)") 534 (IF "FLOAT128_2REG_P (IFmode)") 535 (TD "TARGET_HARD_FLOAT")]) 536 537 ; Iterators for 128 bit types for direct move 538 (define_mode_iterator FMOVE128_GPR [TI 539 V16QI 540 V8HI 541 V4SI 542 V4SF 543 V2DI 544 V2DF 545 V1TI 546 (KF "FLOAT128_VECTOR_P (KFmode)") 547 (TF "FLOAT128_VECTOR_P (TFmode)")]) 548 549 ; Iterator for 128-bit VSX types for pack/unpack 550 (define_mode_iterator FMOVE128_VSX [V1TI KF]) 551 552 ; Iterators for converting to/from TFmode 553 (define_mode_iterator IFKF [IF KF]) 554 555 ; Constraints for moving IF/KFmode. 556 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")]) 557 558 ; Whether a floating point move is ok, don't allow SD without hardware FP 559 (define_mode_attr fmove_ok [(SF "") 560 (DF "") 561 (SD "TARGET_HARD_FLOAT") 562 (DD "")]) 563 564 ; Convert REAL_VALUE to the appropriate bits 565 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE") 566 (DF "REAL_VALUE_TO_TARGET_DOUBLE") 567 (SD "REAL_VALUE_TO_TARGET_DECIMAL32") 568 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")]) 569 570 ; Whether 0.0 has an all-zero bit pattern 571 (define_mode_attr zero_fp [(SF "j") 572 (DF "j") 573 (TF "j") 574 (IF "j") 575 (KF "j") 576 (SD "wn") 577 (DD "wn") 578 (TD "wn")]) 579 580 ; Definitions for 64-bit VSX 581 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")]) 582 583 ; Definitions for 64-bit direct move 584 (define_mode_attr f64_dm [(DF "wa") (DD "d")]) 585 586 ; Definitions for 64-bit use of altivec registers 587 (define_mode_attr f64_av [(DF "v") (DD "wn")]) 588 589 ; Definitions for 64-bit access to ISA 3.0 (power9) vector 590 (define_mode_attr f64_p9 [(DF "v") (DD "wn")]) 591 592 ; These modes do not fit in integer registers in 32-bit mode. 593 (define_mode_iterator DIFD [DI DF DD]) 594 595 ; Iterator for reciprocal estimate instructions 596 (define_mode_iterator RECIPF [SF DF V4SF V2DF]) 597 598 ; SFmode or DFmode. 599 (define_mode_iterator SFDF [SF DF]) 600 601 ; And again, for when we need two FP modes in a pattern. 602 (define_mode_iterator SFDF2 [SF DF]) 603 604 ; A generic s/d attribute, for sp/dp for example. 605 (define_mode_attr sd [(SF "s") (DF "d") 606 (V4SF "s") (V2DF "d")]) 607 608 ; "s" or nothing, for fmuls/fmul for example. 609 (define_mode_attr s [(SF "s") (DF "")]) 610 611 ; Iterator for 128-bit floating point that uses the IBM double-double format 612 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)") 613 (TF "FLOAT128_IBM_P (TFmode)")]) 614 615 ; Iterator for 128-bit floating point that uses IEEE 128-bit float 616 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)") 617 (TF "FLOAT128_IEEE_P (TFmode)")]) 618 619 ; Iterator for 128-bit floating point 620 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE") 621 (IF "TARGET_FLOAT128_TYPE") 622 (TF "TARGET_LONG_DOUBLE_128")]) 623 624 ; Iterator for signbit on 64-bit machines with direct move 625 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)") 626 (TF "FLOAT128_VECTOR_P (TFmode)")]) 627 628 ; Iterator for ISA 3.0 supported floating point types 629 (define_mode_iterator FP_ISA3 [SF DF]) 630 631 ; SF/DF constraint for arithmetic on traditional floating point registers 632 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")]) 633 634 ; SF/DF constraint for arithmetic on VSX registers using instructions added in 635 ; ISA 2.06 (power7). This includes instructions that normally target DF mode, 636 ; but are used on SFmode, since internally SFmode values are kept in the DFmode 637 ; format. 638 (define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")]) 639 640 ; Which isa is needed for those float instructions? 641 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")]) 642 643 ; FRE/FRES support 644 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")]) 645 646 ; Conditional returns. 647 (define_code_iterator any_return [return simple_return]) 648 (define_code_attr return_pred [(return "direct_return ()") 649 (simple_return "1")]) 650 (define_code_attr return_str [(return "") (simple_return "simple_")]) 651 652 ; Logical operators. 653 (define_code_iterator iorxor [ior xor]) 654 (define_code_iterator and_ior_xor [and ior xor]) 655 656 ; Signed/unsigned variants of ops. 657 (define_code_iterator any_extend [sign_extend zero_extend]) 658 (define_code_iterator any_fix [fix unsigned_fix]) 659 (define_code_iterator any_float [float unsigned_float]) 660 661 (define_code_attr u [(sign_extend "") 662 (zero_extend "u") 663 (fix "") 664 (unsigned_fix "u")]) 665 666 (define_code_attr su [(sign_extend "s") 667 (zero_extend "u") 668 (fix "s") 669 (unsigned_fix "u") 670 (float "s") 671 (unsigned_float "u")]) 672 673 (define_code_attr az [(sign_extend "a") 674 (zero_extend "z") 675 (fix "a") 676 (unsigned_fix "z") 677 (float "a") 678 (unsigned_float "z")]) 679 680 (define_code_attr uns [(fix "") 681 (unsigned_fix "uns") 682 (float "") 683 (unsigned_float "uns")]) 684 685 ; Various instructions that come in SI and DI forms. 686 ; A generic w/d attribute, for things like cmpw/cmpd. 687 (define_mode_attr wd [(QI "b") 688 (HI "h") 689 (SI "w") 690 (DI "d") 691 (V16QI "b") 692 (V8HI "h") 693 (V4SI "w") 694 (V2DI "d") 695 (V1TI "q") 696 (TI "q")]) 697 698 ; For double extract from different origin types 699 (define_mode_attr du_or_d [(QI "du") 700 (HI "du") 701 (SI "du") 702 (DI "d") 703 (V16QI "du") 704 (V8HI "du") 705 (V4SI "du") 706 (V2DI "d")]) 707 708 ;; How many bits (per element) in this mode? 709 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64") 710 (SF "32") (DF "64") 711 (DD "64") (TD "128") 712 (V4SI "32") (V2DI "64")]) 713 714 ; DImode bits 715 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")]) 716 717 ;; Bitmask for shift instructions 718 (define_mode_attr hH [(SI "h") (DI "H")]) 719 720 ;; A mode twice the size of the given mode 721 (define_mode_attr dmode [(SI "di") (DI "ti")]) 722 (define_mode_attr DMODE [(SI "DI") (DI "TI")]) 723 724 ;; Suffix for reload patterns 725 (define_mode_attr ptrsize [(SI "32bit") 726 (DI "64bit")]) 727 728 (define_mode_attr tptrsize [(SI "TARGET_32BIT") 729 (DI "TARGET_64BIT")]) 730 731 (define_mode_attr mptrsize [(SI "si") 732 (DI "di")]) 733 734 (define_mode_attr ptrload [(SI "lwz") 735 (DI "ld")]) 736 737 (define_mode_attr ptrm [(SI "m") 738 (DI "Y")]) 739 740 (define_mode_attr rreg [(SF "f") 741 (DF "wa") 742 (TF "f") 743 (TD "f") 744 (V4SF "wa") 745 (V2DF "wa")]) 746 747 (define_mode_attr rreg2 [(SF "f") 748 (DF "d")]) 749 750 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS") 751 (DF "TARGET_FCFID")]) 752 753 ;; Mode iterator for logical operations on 128-bit types 754 (define_mode_iterator BOOL_128 [TI 755 PTI 756 (V16QI "TARGET_ALTIVEC") 757 (V8HI "TARGET_ALTIVEC") 758 (V4SI "TARGET_ALTIVEC") 759 (V4SF "TARGET_ALTIVEC") 760 (V2DI "TARGET_ALTIVEC") 761 (V2DF "TARGET_ALTIVEC") 762 (V1TI "TARGET_ALTIVEC")]) 763 764 ;; For the GPRs we use 3 constraints for register outputs, two that are the 765 ;; same as the output register, and a third where the output register is an 766 ;; early clobber, so we don't have to deal with register overlaps. For the 767 ;; vector types, we prefer to use the vector registers. For TI mode, allow 768 ;; either. 769 770 ;; Mode attribute for boolean operation register constraints for output 771 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v") 772 (PTI "&r,r,r") 773 (V16QI "wa,v,&?r,?r,?r") 774 (V8HI "wa,v,&?r,?r,?r") 775 (V4SI "wa,v,&?r,?r,?r") 776 (V4SF "wa,v,&?r,?r,?r") 777 (V2DI "wa,v,&?r,?r,?r") 778 (V2DF "wa,v,&?r,?r,?r") 779 (V1TI "wa,v,&?r,?r,?r")]) 780 781 ;; Mode attribute for boolean operation register constraints for operand1 782 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v") 783 (PTI "r,0,r") 784 (V16QI "wa,v,r,0,r") 785 (V8HI "wa,v,r,0,r") 786 (V4SI "wa,v,r,0,r") 787 (V4SF "wa,v,r,0,r") 788 (V2DI "wa,v,r,0,r") 789 (V2DF "wa,v,r,0,r") 790 (V1TI "wa,v,r,0,r")]) 791 792 ;; Mode attribute for boolean operation register constraints for operand2 793 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v") 794 (PTI "r,r,0") 795 (V16QI "wa,v,r,r,0") 796 (V8HI "wa,v,r,r,0") 797 (V4SI "wa,v,r,r,0") 798 (V4SF "wa,v,r,r,0") 799 (V2DI "wa,v,r,r,0") 800 (V2DF "wa,v,r,r,0") 801 (V1TI "wa,v,r,r,0")]) 802 803 ;; Mode attribute for boolean operation register constraints for operand1 804 ;; for one_cmpl. To simplify things, we repeat the constraint where 0 805 ;; is used for operand1 or operand2 806 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v") 807 (PTI "r,0,0") 808 (V16QI "wa,v,r,0,0") 809 (V8HI "wa,v,r,0,0") 810 (V4SI "wa,v,r,0,0") 811 (V4SF "wa,v,r,0,0") 812 (V2DI "wa,v,r,0,0") 813 (V2DF "wa,v,r,0,0") 814 (V1TI "wa,v,r,0,0")]) 815 816 ;; Reload iterator for creating the function to allocate a base register to 817 ;; supplement addressing modes. 818 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI 819 SF SD SI DF DD DI TI PTI KF IF TF 820 OO XO]) 821 822 ;; Iterate over smin, smax 823 (define_code_iterator fp_minmax [smin smax]) 824 825 (define_code_attr minmax [(smin "min") 826 (smax "max")]) 827 828 (define_code_attr SMINMAX [(smin "SMIN") 829 (smax "SMAX")]) 830 831 ;; Iterator to optimize the following cases: 832 ;; D-form load to FPR register & move to Altivec register 833 ;; Move Altivec register to FPR register and store 834 (define_mode_iterator ALTIVEC_DFORM [DF 835 (SF "TARGET_P8_VECTOR") 836 (DI "TARGET_POWERPC64")]) 837 838 (include "darwin.md") 839 841 ;; Start with fixed-point load and store insns. Here we put only the more 842 ;; complex forms. Basic data transfer is done later. 843 844 (define_insn "zero_extendqi<mode>2" 845 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,wa,^v") 846 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,?Z,v")))] 847 "" 848 "@ 849 lbz%U1%X1 %0,%1 850 rlwinm %0,%1,0,0xff 851 lxsibzx %x0,%y1 852 vextractub %0,%1,7" 853 [(set_attr "type" "load,shift,fpload,vecperm") 854 (set_attr "isa" "*,*,p9v,p9v")]) 855 856 (define_insn_and_split "*zero_extendqi<mode>2_dot" 857 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 858 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 859 (const_int 0))) 860 (clobber (match_scratch:EXTQI 0 "=r,r"))] 861 "" 862 "@ 863 andi. %0,%1,0xff 864 #" 865 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 866 [(set (match_dup 0) 867 (zero_extend:EXTQI (match_dup 1))) 868 (set (match_dup 2) 869 (compare:CC (match_dup 0) 870 (const_int 0)))] 871 "" 872 [(set_attr "type" "logical") 873 (set_attr "dot" "yes") 874 (set_attr "length" "4,8")]) 875 876 (define_insn_and_split "*zero_extendqi<mode>2_dot2" 877 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 878 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 879 (const_int 0))) 880 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 881 (zero_extend:EXTQI (match_dup 1)))] 882 "" 883 "@ 884 andi. %0,%1,0xff 885 #" 886 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 887 [(set (match_dup 0) 888 (zero_extend:EXTQI (match_dup 1))) 889 (set (match_dup 2) 890 (compare:CC (match_dup 0) 891 (const_int 0)))] 892 "" 893 [(set_attr "type" "logical") 894 (set_attr "dot" "yes") 895 (set_attr "length" "4,8")]) 896 897 898 (define_insn "zero_extendhi<mode>2" 899 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,wa,^v") 900 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,?Z,v")))] 901 "" 902 "@ 903 lhz%U1%X1 %0,%1 904 rlwinm %0,%1,0,0xffff 905 lxsihzx %x0,%y1 906 vextractuh %0,%1,6" 907 [(set_attr "type" "load,shift,fpload,vecperm") 908 (set_attr "isa" "*,*,p9v,p9v")]) 909 910 (define_insn_and_split "*zero_extendhi<mode>2_dot" 911 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 912 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 913 (const_int 0))) 914 (clobber (match_scratch:EXTHI 0 "=r,r"))] 915 "" 916 "@ 917 andi. %0,%1,0xffff 918 #" 919 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 920 [(set (match_dup 0) 921 (zero_extend:EXTHI (match_dup 1))) 922 (set (match_dup 2) 923 (compare:CC (match_dup 0) 924 (const_int 0)))] 925 "" 926 [(set_attr "type" "logical") 927 (set_attr "dot" "yes") 928 (set_attr "length" "4,8")]) 929 930 (define_insn_and_split "*zero_extendhi<mode>2_dot2" 931 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 932 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 933 (const_int 0))) 934 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 935 (zero_extend:EXTHI (match_dup 1)))] 936 "" 937 "@ 938 andi. %0,%1,0xffff 939 #" 940 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 941 [(set (match_dup 0) 942 (zero_extend:EXTHI (match_dup 1))) 943 (set (match_dup 2) 944 (compare:CC (match_dup 0) 945 (const_int 0)))] 946 "" 947 [(set_attr "type" "logical") 948 (set_attr "dot" "yes") 949 (set_attr "length" "4,8")]) 950 951 952 (define_insn "zero_extendsi<mode>2" 953 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa") 954 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,?Z,?Z,r,wa,wa")))] 955 "" 956 "@ 957 lwz%U1%X1 %0,%1 958 rldicl %0,%1,0,32 959 lfiwzx %0,%y1 960 lxsiwzx %x0,%y1 961 mtvsrwz %x0,%1 962 mfvsrwz %0,%x1 963 xxextractuw %x0,%x1,4" 964 [(set_attr "type" "load,shift,fpload,fpload,mtvsr,mfvsr,vecexts") 965 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")]) 966 967 (define_insn_and_split "*zero_extendsi<mode>2_dot" 968 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 969 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 970 (const_int 0))) 971 (clobber (match_scratch:EXTSI 0 "=r,r"))] 972 "" 973 "@ 974 rldicl. %0,%1,0,32 975 #" 976 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 977 [(set (match_dup 0) 978 (zero_extend:DI (match_dup 1))) 979 (set (match_dup 2) 980 (compare:CC (match_dup 0) 981 (const_int 0)))] 982 "" 983 [(set_attr "type" "shift") 984 (set_attr "dot" "yes") 985 (set_attr "length" "4,8")]) 986 987 (define_insn_and_split "*zero_extendsi<mode>2_dot2" 988 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 989 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 990 (const_int 0))) 991 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") 992 (zero_extend:EXTSI (match_dup 1)))] 993 "" 994 "@ 995 rldicl. %0,%1,0,32 996 #" 997 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 998 [(set (match_dup 0) 999 (zero_extend:EXTSI (match_dup 1))) 1000 (set (match_dup 2) 1001 (compare:CC (match_dup 0) 1002 (const_int 0)))] 1003 "" 1004 [(set_attr "type" "shift") 1005 (set_attr "dot" "yes") 1006 (set_attr "length" "4,8")]) 1007 1008 1009 (define_insn "extendqi<mode>2" 1010 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v") 1011 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))] 1012 "" 1013 "@ 1014 extsb %0,%1 1015 vextsb2d %0,%1" 1016 [(set_attr "type" "exts,vecperm") 1017 (set_attr "isa" "*,p9v")]) 1018 1019 (define_insn_and_split "*extendqi<mode>2_dot" 1020 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1021 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 1022 (const_int 0))) 1023 (clobber (match_scratch:EXTQI 0 "=r,r"))] 1024 "" 1025 "@ 1026 extsb. %0,%1 1027 #" 1028 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1029 [(set (match_dup 0) 1030 (sign_extend:EXTQI (match_dup 1))) 1031 (set (match_dup 2) 1032 (compare:CC (match_dup 0) 1033 (const_int 0)))] 1034 "" 1035 [(set_attr "type" "exts") 1036 (set_attr "dot" "yes") 1037 (set_attr "length" "4,8")]) 1038 1039 (define_insn_and_split "*extendqi<mode>2_dot2" 1040 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1041 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 1042 (const_int 0))) 1043 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 1044 (sign_extend:EXTQI (match_dup 1)))] 1045 "" 1046 "@ 1047 extsb. %0,%1 1048 #" 1049 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1050 [(set (match_dup 0) 1051 (sign_extend:EXTQI (match_dup 1))) 1052 (set (match_dup 2) 1053 (compare:CC (match_dup 0) 1054 (const_int 0)))] 1055 "" 1056 [(set_attr "type" "exts") 1057 (set_attr "dot" "yes") 1058 (set_attr "length" "4,8")]) 1059 1060 1061 (define_expand "extendhi<mode>2" 1062 [(set (match_operand:EXTHI 0 "gpc_reg_operand") 1063 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))] 1064 "" 1065 "") 1066 1067 (define_insn "*extendhi<mode>2" 1068 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v") 1069 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))] 1070 "" 1071 "@ 1072 lha%U1%X1 %0,%1 1073 extsh %0,%1 1074 # 1075 vextsh2d %0,%1" 1076 [(set_attr "type" "load,exts,fpload,vecperm") 1077 (set_attr "sign_extend" "yes") 1078 (set_attr "length" "*,*,8,*") 1079 (set_attr "isa" "*,*,p9v,p9v")]) 1080 1081 (define_split 1082 [(set (match_operand:EXTHI 0 "altivec_register_operand") 1083 (sign_extend:EXTHI 1084 (match_operand:HI 1 "indexed_or_indirect_operand")))] 1085 "TARGET_P9_VECTOR && reload_completed" 1086 [(set (match_dup 2) 1087 (match_dup 1)) 1088 (set (match_dup 0) 1089 (sign_extend:EXTHI (match_dup 2)))] 1090 { 1091 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0])); 1092 }) 1093 1094 (define_insn_and_split "*extendhi<mode>2_dot" 1095 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1096 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 1097 (const_int 0))) 1098 (clobber (match_scratch:EXTHI 0 "=r,r"))] 1099 "" 1100 "@ 1101 extsh. %0,%1 1102 #" 1103 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1104 [(set (match_dup 0) 1105 (sign_extend:EXTHI (match_dup 1))) 1106 (set (match_dup 2) 1107 (compare:CC (match_dup 0) 1108 (const_int 0)))] 1109 "" 1110 [(set_attr "type" "exts") 1111 (set_attr "dot" "yes") 1112 (set_attr "length" "4,8")]) 1113 1114 (define_insn_and_split "*extendhi<mode>2_dot2" 1115 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1116 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 1117 (const_int 0))) 1118 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 1119 (sign_extend:EXTHI (match_dup 1)))] 1120 "" 1121 "@ 1122 extsh. %0,%1 1123 #" 1124 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1125 [(set (match_dup 0) 1126 (sign_extend:EXTHI (match_dup 1))) 1127 (set (match_dup 2) 1128 (compare:CC (match_dup 0) 1129 (const_int 0)))] 1130 "" 1131 [(set_attr "type" "exts") 1132 (set_attr "dot" "yes") 1133 (set_attr "length" "4,8")]) 1134 1135 1136 (define_insn "extendsi<mode>2" 1137 [(set (match_operand:EXTSI 0 "gpc_reg_operand" 1138 "=r, r, d, wa, wa, v, v, wr") 1139 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" 1140 "YZ, r, Z, Z, r, v, v, ?wa")))] 1141 "" 1142 "@ 1143 lwa%U1%X1 %0,%1 1144 extsw %0,%1 1145 lfiwax %0,%y1 1146 lxsiwax %x0,%y1 1147 mtvsrwa %x0,%1 1148 vextsw2d %0,%1 1149 # 1150 #" 1151 [(set_attr "type" "load,exts,fpload,fpload,mtvsr,vecexts,vecperm,mfvsr") 1152 (set_attr "sign_extend" "yes") 1153 (set_attr "length" "*,*,*,*,*,*,8,8") 1154 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")]) 1155 1156 (define_split 1157 [(set (match_operand:EXTSI 0 "int_reg_operand") 1158 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))] 1159 "TARGET_DIRECT_MOVE_64BIT && reload_completed" 1160 [(set (match_dup 2) 1161 (match_dup 1)) 1162 (set (match_dup 0) 1163 (sign_extend:DI (match_dup 2)))] 1164 { 1165 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0])); 1166 }) 1167 1168 (define_split 1169 [(set (match_operand:DI 0 "altivec_register_operand") 1170 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))] 1171 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed" 1172 [(const_int 0)] 1173 { 1174 rtx dest = operands[0]; 1175 rtx src = operands[1]; 1176 int dest_regno = REGNO (dest); 1177 int src_regno = REGNO (src); 1178 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno); 1179 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno); 1180 1181 if (BYTES_BIG_ENDIAN) 1182 { 1183 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si)); 1184 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx)); 1185 } 1186 else 1187 { 1188 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si)); 1189 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx)); 1190 } 1191 DONE; 1192 }) 1193 1194 (define_insn_and_split "*extendsi<mode>2_dot" 1195 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1196 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 1197 (const_int 0))) 1198 (clobber (match_scratch:EXTSI 0 "=r,r"))] 1199 "" 1200 "@ 1201 extsw. %0,%1 1202 #" 1203 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1204 [(set (match_dup 0) 1205 (sign_extend:EXTSI (match_dup 1))) 1206 (set (match_dup 2) 1207 (compare:CC (match_dup 0) 1208 (const_int 0)))] 1209 "" 1210 [(set_attr "type" "exts") 1211 (set_attr "dot" "yes") 1212 (set_attr "length" "4,8")]) 1213 1214 (define_insn_and_split "*extendsi<mode>2_dot2" 1215 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1216 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 1217 (const_int 0))) 1218 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") 1219 (sign_extend:EXTSI (match_dup 1)))] 1220 "" 1221 "@ 1222 extsw. %0,%1 1223 #" 1224 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1225 [(set (match_dup 0) 1226 (sign_extend:EXTSI (match_dup 1))) 1227 (set (match_dup 2) 1228 (compare:CC (match_dup 0) 1229 (const_int 0)))] 1230 "" 1231 [(set_attr "type" "exts") 1232 (set_attr "dot" "yes") 1233 (set_attr "length" "4,8")]) 1234 1236 ;; IBM 405, 440, 464 and 476 half-word multiplication operations. 1237 1238 (define_insn "*macchwc" 1239 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1240 (compare:CC (plus:SI (mult:SI (ashiftrt:SI 1241 (match_operand:SI 2 "gpc_reg_operand" "r") 1242 (const_int 16)) 1243 (sign_extend:SI 1244 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1245 (match_operand:SI 4 "gpc_reg_operand" "0")) 1246 (const_int 0))) 1247 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1248 (plus:SI (mult:SI (ashiftrt:SI 1249 (match_dup 2) 1250 (const_int 16)) 1251 (sign_extend:SI 1252 (match_dup 1))) 1253 (match_dup 4)))] 1254 "TARGET_MULHW" 1255 "macchw. %0,%1,%2" 1256 [(set_attr "type" "halfmul")]) 1257 1258 (define_insn "*macchw" 1259 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1260 (plus:SI (mult:SI (ashiftrt:SI 1261 (match_operand:SI 2 "gpc_reg_operand" "r") 1262 (const_int 16)) 1263 (sign_extend:SI 1264 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1265 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1266 "TARGET_MULHW" 1267 "macchw %0,%1,%2" 1268 [(set_attr "type" "halfmul")]) 1269 1270 (define_insn "*macchwuc" 1271 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1272 (compare:CC (plus:SI (mult:SI (lshiftrt:SI 1273 (match_operand:SI 2 "gpc_reg_operand" "r") 1274 (const_int 16)) 1275 (zero_extend:SI 1276 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1277 (match_operand:SI 4 "gpc_reg_operand" "0")) 1278 (const_int 0))) 1279 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1280 (plus:SI (mult:SI (lshiftrt:SI 1281 (match_dup 2) 1282 (const_int 16)) 1283 (zero_extend:SI 1284 (match_dup 1))) 1285 (match_dup 4)))] 1286 "TARGET_MULHW" 1287 "macchwu. %0,%1,%2" 1288 [(set_attr "type" "halfmul")]) 1289 1290 (define_insn "*macchwu" 1291 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1292 (plus:SI (mult:SI (lshiftrt:SI 1293 (match_operand:SI 2 "gpc_reg_operand" "r") 1294 (const_int 16)) 1295 (zero_extend:SI 1296 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1297 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1298 "TARGET_MULHW" 1299 "macchwu %0,%1,%2" 1300 [(set_attr "type" "halfmul")]) 1301 1302 (define_insn "*machhwc" 1303 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1304 (compare:CC (plus:SI (mult:SI (ashiftrt:SI 1305 (match_operand:SI 1 "gpc_reg_operand" "%r") 1306 (const_int 16)) 1307 (ashiftrt:SI 1308 (match_operand:SI 2 "gpc_reg_operand" "r") 1309 (const_int 16))) 1310 (match_operand:SI 4 "gpc_reg_operand" "0")) 1311 (const_int 0))) 1312 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1313 (plus:SI (mult:SI (ashiftrt:SI 1314 (match_dup 1) 1315 (const_int 16)) 1316 (ashiftrt:SI 1317 (match_dup 2) 1318 (const_int 16))) 1319 (match_dup 4)))] 1320 "TARGET_MULHW" 1321 "machhw. %0,%1,%2" 1322 [(set_attr "type" "halfmul")]) 1323 1324 (define_insn "*machhw" 1325 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1326 (plus:SI (mult:SI (ashiftrt:SI 1327 (match_operand:SI 1 "gpc_reg_operand" "%r") 1328 (const_int 16)) 1329 (ashiftrt:SI 1330 (match_operand:SI 2 "gpc_reg_operand" "r") 1331 (const_int 16))) 1332 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1333 "TARGET_MULHW" 1334 "machhw %0,%1,%2" 1335 [(set_attr "type" "halfmul")]) 1336 1337 (define_insn "*machhwuc" 1338 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1339 (compare:CC (plus:SI (mult:SI (lshiftrt:SI 1340 (match_operand:SI 1 "gpc_reg_operand" "%r") 1341 (const_int 16)) 1342 (lshiftrt:SI 1343 (match_operand:SI 2 "gpc_reg_operand" "r") 1344 (const_int 16))) 1345 (match_operand:SI 4 "gpc_reg_operand" "0")) 1346 (const_int 0))) 1347 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1348 (plus:SI (mult:SI (lshiftrt:SI 1349 (match_dup 1) 1350 (const_int 16)) 1351 (lshiftrt:SI 1352 (match_dup 2) 1353 (const_int 16))) 1354 (match_dup 4)))] 1355 "TARGET_MULHW" 1356 "machhwu. %0,%1,%2" 1357 [(set_attr "type" "halfmul")]) 1358 1359 (define_insn "*machhwu" 1360 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1361 (plus:SI (mult:SI (lshiftrt:SI 1362 (match_operand:SI 1 "gpc_reg_operand" "%r") 1363 (const_int 16)) 1364 (lshiftrt:SI 1365 (match_operand:SI 2 "gpc_reg_operand" "r") 1366 (const_int 16))) 1367 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1368 "TARGET_MULHW" 1369 "machhwu %0,%1,%2" 1370 [(set_attr "type" "halfmul")]) 1371 1372 (define_insn "*maclhwc" 1373 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1374 (compare:CC (plus:SI (mult:SI (sign_extend:SI 1375 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1376 (sign_extend:SI 1377 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1378 (match_operand:SI 4 "gpc_reg_operand" "0")) 1379 (const_int 0))) 1380 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1381 (plus:SI (mult:SI (sign_extend:SI 1382 (match_dup 1)) 1383 (sign_extend:SI 1384 (match_dup 2))) 1385 (match_dup 4)))] 1386 "TARGET_MULHW" 1387 "maclhw. %0,%1,%2" 1388 [(set_attr "type" "halfmul")]) 1389 1390 (define_insn "*maclhw" 1391 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1392 (plus:SI (mult:SI (sign_extend:SI 1393 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1394 (sign_extend:SI 1395 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1396 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1397 "TARGET_MULHW" 1398 "maclhw %0,%1,%2" 1399 [(set_attr "type" "halfmul")]) 1400 1401 (define_insn "*maclhwuc" 1402 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1403 (compare:CC (plus:SI (mult:SI (zero_extend:SI 1404 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1405 (zero_extend:SI 1406 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1407 (match_operand:SI 4 "gpc_reg_operand" "0")) 1408 (const_int 0))) 1409 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1410 (plus:SI (mult:SI (zero_extend:SI 1411 (match_dup 1)) 1412 (zero_extend:SI 1413 (match_dup 2))) 1414 (match_dup 4)))] 1415 "TARGET_MULHW" 1416 "maclhwu. %0,%1,%2" 1417 [(set_attr "type" "halfmul")]) 1418 1419 (define_insn "*maclhwu" 1420 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1421 (plus:SI (mult:SI (zero_extend:SI 1422 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1423 (zero_extend:SI 1424 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1425 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1426 "TARGET_MULHW" 1427 "maclhwu %0,%1,%2" 1428 [(set_attr "type" "halfmul")]) 1429 1430 (define_insn "*nmacchwc" 1431 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1432 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1433 (mult:SI (ashiftrt:SI 1434 (match_operand:SI 2 "gpc_reg_operand" "r") 1435 (const_int 16)) 1436 (sign_extend:SI 1437 (match_operand:HI 1 "gpc_reg_operand" "r")))) 1438 (const_int 0))) 1439 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1440 (minus:SI (match_dup 4) 1441 (mult:SI (ashiftrt:SI 1442 (match_dup 2) 1443 (const_int 16)) 1444 (sign_extend:SI 1445 (match_dup 1)))))] 1446 "TARGET_MULHW" 1447 "nmacchw. %0,%1,%2" 1448 [(set_attr "type" "halfmul")]) 1449 1450 (define_insn "*nmacchw" 1451 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1452 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1453 (mult:SI (ashiftrt:SI 1454 (match_operand:SI 2 "gpc_reg_operand" "r") 1455 (const_int 16)) 1456 (sign_extend:SI 1457 (match_operand:HI 1 "gpc_reg_operand" "r")))))] 1458 "TARGET_MULHW" 1459 "nmacchw %0,%1,%2" 1460 [(set_attr "type" "halfmul")]) 1461 1462 (define_insn "*nmachhwc" 1463 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1464 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1465 (mult:SI (ashiftrt:SI 1466 (match_operand:SI 1 "gpc_reg_operand" "%r") 1467 (const_int 16)) 1468 (ashiftrt:SI 1469 (match_operand:SI 2 "gpc_reg_operand" "r") 1470 (const_int 16)))) 1471 (const_int 0))) 1472 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1473 (minus:SI (match_dup 4) 1474 (mult:SI (ashiftrt:SI 1475 (match_dup 1) 1476 (const_int 16)) 1477 (ashiftrt:SI 1478 (match_dup 2) 1479 (const_int 16)))))] 1480 "TARGET_MULHW" 1481 "nmachhw. %0,%1,%2" 1482 [(set_attr "type" "halfmul")]) 1483 1484 (define_insn "*nmachhw" 1485 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1486 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1487 (mult:SI (ashiftrt:SI 1488 (match_operand:SI 1 "gpc_reg_operand" "%r") 1489 (const_int 16)) 1490 (ashiftrt:SI 1491 (match_operand:SI 2 "gpc_reg_operand" "r") 1492 (const_int 16)))))] 1493 "TARGET_MULHW" 1494 "nmachhw %0,%1,%2" 1495 [(set_attr "type" "halfmul")]) 1496 1497 (define_insn "*nmaclhwc" 1498 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1499 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1500 (mult:SI (sign_extend:SI 1501 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1502 (sign_extend:SI 1503 (match_operand:HI 2 "gpc_reg_operand" "r")))) 1504 (const_int 0))) 1505 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1506 (minus:SI (match_dup 4) 1507 (mult:SI (sign_extend:SI 1508 (match_dup 1)) 1509 (sign_extend:SI 1510 (match_dup 2)))))] 1511 "TARGET_MULHW" 1512 "nmaclhw. %0,%1,%2" 1513 [(set_attr "type" "halfmul")]) 1514 1515 (define_insn "*nmaclhw" 1516 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1517 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1518 (mult:SI (sign_extend:SI 1519 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1520 (sign_extend:SI 1521 (match_operand:HI 2 "gpc_reg_operand" "r")))))] 1522 "TARGET_MULHW" 1523 "nmaclhw %0,%1,%2" 1524 [(set_attr "type" "halfmul")]) 1525 1526 (define_insn "*mulchwc" 1527 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1528 (compare:CC (mult:SI (ashiftrt:SI 1529 (match_operand:SI 2 "gpc_reg_operand" "r") 1530 (const_int 16)) 1531 (sign_extend:SI 1532 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1533 (const_int 0))) 1534 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1535 (mult:SI (ashiftrt:SI 1536 (match_dup 2) 1537 (const_int 16)) 1538 (sign_extend:SI 1539 (match_dup 1))))] 1540 "TARGET_MULHW" 1541 "mulchw. %0,%1,%2" 1542 [(set_attr "type" "halfmul")]) 1543 1544 (define_insn "*mulchw" 1545 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1546 (mult:SI (ashiftrt:SI 1547 (match_operand:SI 2 "gpc_reg_operand" "r") 1548 (const_int 16)) 1549 (sign_extend:SI 1550 (match_operand:HI 1 "gpc_reg_operand" "r"))))] 1551 "TARGET_MULHW" 1552 "mulchw %0,%1,%2" 1553 [(set_attr "type" "halfmul")]) 1554 1555 (define_insn "*mulchwuc" 1556 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1557 (compare:CC (mult:SI (lshiftrt:SI 1558 (match_operand:SI 2 "gpc_reg_operand" "r") 1559 (const_int 16)) 1560 (zero_extend:SI 1561 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1562 (const_int 0))) 1563 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1564 (mult:SI (lshiftrt:SI 1565 (match_dup 2) 1566 (const_int 16)) 1567 (zero_extend:SI 1568 (match_dup 1))))] 1569 "TARGET_MULHW" 1570 "mulchwu. %0,%1,%2" 1571 [(set_attr "type" "halfmul")]) 1572 1573 (define_insn "*mulchwu" 1574 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1575 (mult:SI (lshiftrt:SI 1576 (match_operand:SI 2 "gpc_reg_operand" "r") 1577 (const_int 16)) 1578 (zero_extend:SI 1579 (match_operand:HI 1 "gpc_reg_operand" "r"))))] 1580 "TARGET_MULHW" 1581 "mulchwu %0,%1,%2" 1582 [(set_attr "type" "halfmul")]) 1583 1584 (define_insn "*mulhhwc" 1585 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1586 (compare:CC (mult:SI (ashiftrt:SI 1587 (match_operand:SI 1 "gpc_reg_operand" "%r") 1588 (const_int 16)) 1589 (ashiftrt:SI 1590 (match_operand:SI 2 "gpc_reg_operand" "r") 1591 (const_int 16))) 1592 (const_int 0))) 1593 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1594 (mult:SI (ashiftrt:SI 1595 (match_dup 1) 1596 (const_int 16)) 1597 (ashiftrt:SI 1598 (match_dup 2) 1599 (const_int 16))))] 1600 "TARGET_MULHW" 1601 "mulhhw. %0,%1,%2" 1602 [(set_attr "type" "halfmul")]) 1603 1604 (define_insn "*mulhhw" 1605 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1606 (mult:SI (ashiftrt:SI 1607 (match_operand:SI 1 "gpc_reg_operand" "%r") 1608 (const_int 16)) 1609 (ashiftrt:SI 1610 (match_operand:SI 2 "gpc_reg_operand" "r") 1611 (const_int 16))))] 1612 "TARGET_MULHW" 1613 "mulhhw %0,%1,%2" 1614 [(set_attr "type" "halfmul")]) 1615 1616 (define_insn "*mulhhwuc" 1617 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1618 (compare:CC (mult:SI (lshiftrt:SI 1619 (match_operand:SI 1 "gpc_reg_operand" "%r") 1620 (const_int 16)) 1621 (lshiftrt:SI 1622 (match_operand:SI 2 "gpc_reg_operand" "r") 1623 (const_int 16))) 1624 (const_int 0))) 1625 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1626 (mult:SI (lshiftrt:SI 1627 (match_dup 1) 1628 (const_int 16)) 1629 (lshiftrt:SI 1630 (match_dup 2) 1631 (const_int 16))))] 1632 "TARGET_MULHW" 1633 "mulhhwu. %0,%1,%2" 1634 [(set_attr "type" "halfmul")]) 1635 1636 (define_insn "*mulhhwu" 1637 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1638 (mult:SI (lshiftrt:SI 1639 (match_operand:SI 1 "gpc_reg_operand" "%r") 1640 (const_int 16)) 1641 (lshiftrt:SI 1642 (match_operand:SI 2 "gpc_reg_operand" "r") 1643 (const_int 16))))] 1644 "TARGET_MULHW" 1645 "mulhhwu %0,%1,%2" 1646 [(set_attr "type" "halfmul")]) 1647 1648 (define_insn "*mullhwc" 1649 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1650 (compare:CC (mult:SI (sign_extend:SI 1651 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1652 (sign_extend:SI 1653 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1654 (const_int 0))) 1655 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1656 (mult:SI (sign_extend:SI 1657 (match_dup 1)) 1658 (sign_extend:SI 1659 (match_dup 2))))] 1660 "TARGET_MULHW" 1661 "mullhw. %0,%1,%2" 1662 [(set_attr "type" "halfmul")]) 1663 1664 (define_insn "*mullhw" 1665 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1666 (mult:SI (sign_extend:SI 1667 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1668 (sign_extend:SI 1669 (match_operand:HI 2 "gpc_reg_operand" "r"))))] 1670 "TARGET_MULHW" 1671 "mullhw %0,%1,%2" 1672 [(set_attr "type" "halfmul")]) 1673 1674 (define_insn "*mullhwuc" 1675 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1676 (compare:CC (mult:SI (zero_extend:SI 1677 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1678 (zero_extend:SI 1679 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1680 (const_int 0))) 1681 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1682 (mult:SI (zero_extend:SI 1683 (match_dup 1)) 1684 (zero_extend:SI 1685 (match_dup 2))))] 1686 "TARGET_MULHW" 1687 "mullhwu. %0,%1,%2" 1688 [(set_attr "type" "halfmul")]) 1689 1690 (define_insn "*mullhwu" 1691 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1692 (mult:SI (zero_extend:SI 1693 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1694 (zero_extend:SI 1695 (match_operand:HI 2 "gpc_reg_operand" "r"))))] 1696 "TARGET_MULHW" 1697 "mullhwu %0,%1,%2" 1698 [(set_attr "type" "halfmul")]) 1699 1701 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support. 1702 (define_insn "dlmzb" 1703 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1704 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 1705 (match_operand:SI 2 "gpc_reg_operand" "r")] 1706 UNSPEC_DLMZB_CR)) 1707 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1708 (unspec:SI [(match_dup 1) 1709 (match_dup 2)] 1710 UNSPEC_DLMZB))] 1711 "TARGET_DLMZB" 1712 "dlmzb. %0,%1,%2") 1713 1714 (define_expand "strlensi" 1715 [(set (match_operand:SI 0 "gpc_reg_operand") 1716 (unspec:SI [(match_operand:BLK 1 "general_operand") 1717 (match_operand:QI 2 "const_int_operand") 1718 (match_operand 3 "const_int_operand")] 1719 UNSPEC_DLMZB_STRLEN)) 1720 (clobber (match_scratch:CC 4))] 1721 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size" 1722 { 1723 rtx result = operands[0]; 1724 rtx src = operands[1]; 1725 rtx search_char = operands[2]; 1726 rtx align = operands[3]; 1727 rtx addr, scratch_string, word1, word2, scratch_dlmzb; 1728 rtx loop_label, end_label, mem, cr0, cond; 1729 if (search_char != const0_rtx 1730 || !CONST_INT_P (align) 1731 || INTVAL (align) < 8) 1732 FAIL; 1733 word1 = gen_reg_rtx (SImode); 1734 word2 = gen_reg_rtx (SImode); 1735 scratch_dlmzb = gen_reg_rtx (SImode); 1736 scratch_string = gen_reg_rtx (Pmode); 1737 loop_label = gen_label_rtx (); 1738 end_label = gen_label_rtx (); 1739 addr = force_reg (Pmode, XEXP (src, 0)); 1740 emit_move_insn (scratch_string, addr); 1741 emit_label (loop_label); 1742 mem = change_address (src, SImode, scratch_string); 1743 emit_move_insn (word1, mem); 1744 emit_move_insn (word2, adjust_address (mem, SImode, 4)); 1745 cr0 = gen_rtx_REG (CCmode, CR0_REGNO); 1746 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0)); 1747 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx); 1748 emit_jump_insn (gen_rtx_SET (pc_rtx, 1749 gen_rtx_IF_THEN_ELSE (VOIDmode, 1750 cond, 1751 gen_rtx_LABEL_REF 1752 (VOIDmode, 1753 end_label), 1754 pc_rtx))); 1755 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8))); 1756 emit_jump_insn (gen_rtx_SET (pc_rtx, 1757 gen_rtx_LABEL_REF (VOIDmode, loop_label))); 1758 emit_barrier (); 1759 emit_label (end_label); 1760 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb)); 1761 emit_insn (gen_subsi3 (result, scratch_string, addr)); 1762 emit_insn (gen_addsi3 (result, result, constm1_rtx)); 1763 DONE; 1764 }) 1765 1767 ;; Fixed-point arithmetic insns. 1768 1769 (define_expand "add<mode>3" 1770 [(set (match_operand:SDI 0 "gpc_reg_operand") 1771 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand") 1772 (match_operand:SDI 2 "reg_or_add_cint_operand")))] 1773 "" 1774 { 1775 if (<MODE>mode == DImode && !TARGET_POWERPC64) 1776 { 1777 rtx lo0 = gen_lowpart (SImode, operands[0]); 1778 rtx lo1 = gen_lowpart (SImode, operands[1]); 1779 rtx lo2 = gen_lowpart (SImode, operands[2]); 1780 rtx hi0 = gen_highpart (SImode, operands[0]); 1781 rtx hi1 = gen_highpart (SImode, operands[1]); 1782 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]); 1783 1784 if (!reg_or_short_operand (lo2, SImode)) 1785 lo2 = force_reg (SImode, lo2); 1786 if (!adde_operand (hi2, SImode)) 1787 hi2 = force_reg (SImode, hi2); 1788 1789 emit_insn (gen_addsi3_carry (lo0, lo1, lo2)); 1790 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2)); 1791 DONE; 1792 } 1793 1794 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode)) 1795 { 1796 rtx tmp = ((!can_create_pseudo_p () 1797 || rtx_equal_p (operands[0], operands[1])) 1798 ? operands[0] : gen_reg_rtx (<MODE>mode)); 1799 1800 /* Adding a constant to r0 is not a valid insn, so use a different 1801 strategy in that case. */ 1802 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0) 1803 { 1804 if (operands[0] == operands[1]) 1805 FAIL; 1806 rs6000_emit_move (operands[0], operands[2], <MODE>mode); 1807 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0])); 1808 DONE; 1809 } 1810 1811 HOST_WIDE_INT val = INTVAL (operands[2]); 1812 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1813 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); 1814 1815 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest))) 1816 FAIL; 1817 1818 /* The ordering here is important for the prolog expander. 1819 When space is allocated from the stack, adding 'low' first may 1820 produce a temporary deallocation (which would be bad). */ 1821 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest))); 1822 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low))); 1823 DONE; 1824 } 1825 }) 1826 1827 (define_insn "*add<mode>3" 1828 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r") 1829 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b") 1830 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))] 1831 "" 1832 "@ 1833 add %0,%1,%2 1834 addi %0,%1,%2 1835 addis %0,%1,%v2 1836 addi %0,%1,%2" 1837 [(set_attr "type" "add") 1838 (set_attr "isa" "*,*,*,p10")]) 1839 1840 (define_insn "*addsi3_high" 1841 [(set (match_operand:SI 0 "gpc_reg_operand" "=b") 1842 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") 1843 (high:SI (match_operand 2 "" ""))))] 1844 "TARGET_MACHO && !TARGET_64BIT" 1845 "addis %0,%1,ha16(%2)" 1846 [(set_attr "type" "add")]) 1847 1848 (define_insn_and_split "*add<mode>3_dot" 1849 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1850 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 1851 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 1852 (const_int 0))) 1853 (clobber (match_scratch:GPR 0 "=r,r"))] 1854 "<MODE>mode == Pmode" 1855 "@ 1856 add. %0,%1,%2 1857 #" 1858 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1859 [(set (match_dup 0) 1860 (plus:GPR (match_dup 1) 1861 (match_dup 2))) 1862 (set (match_dup 3) 1863 (compare:CC (match_dup 0) 1864 (const_int 0)))] 1865 "" 1866 [(set_attr "type" "add") 1867 (set_attr "dot" "yes") 1868 (set_attr "length" "4,8")]) 1869 1870 (define_insn_and_split "*add<mode>3_dot2" 1871 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1872 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 1873 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 1874 (const_int 0))) 1875 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1876 (plus:GPR (match_dup 1) 1877 (match_dup 2)))] 1878 "<MODE>mode == Pmode" 1879 "@ 1880 add. %0,%1,%2 1881 #" 1882 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1883 [(set (match_dup 0) 1884 (plus:GPR (match_dup 1) 1885 (match_dup 2))) 1886 (set (match_dup 3) 1887 (compare:CC (match_dup 0) 1888 (const_int 0)))] 1889 "" 1890 [(set_attr "type" "add") 1891 (set_attr "dot" "yes") 1892 (set_attr "length" "4,8")]) 1893 1894 (define_insn_and_split "*add<mode>3_imm_dot" 1895 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1896 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b") 1897 (match_operand:GPR 2 "short_cint_operand" "I,I")) 1898 (const_int 0))) 1899 (clobber (match_scratch:GPR 0 "=r,r")) 1900 (clobber (reg:GPR CA_REGNO))] 1901 "<MODE>mode == Pmode" 1902 "@ 1903 addic. %0,%1,%2 1904 #" 1905 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1906 [(set (match_dup 0) 1907 (plus:GPR (match_dup 1) 1908 (match_dup 2))) 1909 (set (match_dup 3) 1910 (compare:CC (match_dup 0) 1911 (const_int 0)))] 1912 "" 1913 [(set_attr "type" "add") 1914 (set_attr "dot" "yes") 1915 (set_attr "length" "4,8")]) 1916 1917 (define_insn_and_split "*add<mode>3_imm_dot2" 1918 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1919 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b") 1920 (match_operand:GPR 2 "short_cint_operand" "I,I")) 1921 (const_int 0))) 1922 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1923 (plus:GPR (match_dup 1) 1924 (match_dup 2))) 1925 (clobber (reg:GPR CA_REGNO))] 1926 "<MODE>mode == Pmode" 1927 "@ 1928 addic. %0,%1,%2 1929 #" 1930 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1931 [(set (match_dup 0) 1932 (plus:GPR (match_dup 1) 1933 (match_dup 2))) 1934 (set (match_dup 3) 1935 (compare:CC (match_dup 0) 1936 (const_int 0)))] 1937 "" 1938 [(set_attr "type" "add") 1939 (set_attr "dot" "yes") 1940 (set_attr "length" "4,8")]) 1941 1942 ;; Split an add that we can't do in one insn into two insns, each of which 1943 ;; does one 16-bit part. This is used by combine. Note that the low-order 1944 ;; add should be last in case the result gets used in an address. 1945 1946 (define_split 1947 [(set (match_operand:GPR 0 "gpc_reg_operand") 1948 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand") 1949 (match_operand:GPR 2 "non_add_cint_operand")))] 1950 "" 1951 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3))) 1952 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))] 1953 { 1954 HOST_WIDE_INT val = INTVAL (operands[2]); 1955 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1956 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); 1957 1958 operands[4] = GEN_INT (low); 1959 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest))) 1960 operands[3] = GEN_INT (rest); 1961 else if (can_create_pseudo_p ()) 1962 { 1963 operands[3] = gen_reg_rtx (DImode); 1964 emit_move_insn (operands[3], operands[2]); 1965 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3])); 1966 DONE; 1967 } 1968 else 1969 FAIL; 1970 }) 1971 1972 1973 (define_insn "add<mode>3_carry" 1974 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1975 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1976 (match_operand:P 2 "reg_or_short_operand" "rI"))) 1977 (set (reg:P CA_REGNO) 1978 (ltu:P (plus:P (match_dup 1) 1979 (match_dup 2)) 1980 (match_dup 1)))] 1981 "" 1982 "add%I2c %0,%1,%2" 1983 [(set_attr "type" "add")]) 1984 1985 (define_insn "*add<mode>3_imm_carry_pos" 1986 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1987 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1988 (match_operand:P 2 "short_cint_operand" "n"))) 1989 (set (reg:P CA_REGNO) 1990 (geu:P (match_dup 1) 1991 (match_operand:P 3 "const_int_operand" "n")))] 1992 "INTVAL (operands[2]) > 0 1993 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0" 1994 "addic %0,%1,%2" 1995 [(set_attr "type" "add")]) 1996 1997 (define_insn "*add<mode>3_imm_carry_0" 1998 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1999 (match_operand:P 1 "gpc_reg_operand" "r")) 2000 (set (reg:P CA_REGNO) 2001 (const_int 0))] 2002 "" 2003 "addic %0,%1,0" 2004 [(set_attr "type" "add")]) 2005 2006 (define_insn "*add<mode>3_imm_carry_m1" 2007 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2008 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 2009 (const_int -1))) 2010 (set (reg:P CA_REGNO) 2011 (ne:P (match_dup 1) 2012 (const_int 0)))] 2013 "" 2014 "addic %0,%1,-1" 2015 [(set_attr "type" "add")]) 2016 2017 (define_insn "*add<mode>3_imm_carry_neg" 2018 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2019 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 2020 (match_operand:P 2 "short_cint_operand" "n"))) 2021 (set (reg:P CA_REGNO) 2022 (gtu:P (match_dup 1) 2023 (match_operand:P 3 "const_int_operand" "n")))] 2024 "INTVAL (operands[2]) < 0 2025 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1" 2026 "addic %0,%1,%2" 2027 [(set_attr "type" "add")]) 2028 2029 2030 (define_expand "add<mode>3_carry_in" 2031 [(parallel [ 2032 (set (match_operand:GPR 0 "gpc_reg_operand") 2033 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand") 2034 (match_operand:GPR 2 "adde_operand")) 2035 (reg:GPR CA_REGNO))) 2036 (clobber (reg:GPR CA_REGNO))])] 2037 "" 2038 { 2039 if (operands[2] == const0_rtx) 2040 { 2041 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1])); 2042 DONE; 2043 } 2044 if (operands[2] == constm1_rtx) 2045 { 2046 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1])); 2047 DONE; 2048 } 2049 }) 2050 2051 (define_insn "*add<mode>3_carry_in_internal" 2052 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2053 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 2054 (match_operand:GPR 2 "gpc_reg_operand" "r")) 2055 (reg:GPR CA_REGNO))) 2056 (clobber (reg:GPR CA_REGNO))] 2057 "" 2058 "adde %0,%1,%2" 2059 [(set_attr "type" "add")]) 2060 2061 (define_insn "*add<mode>3_carry_in_internal2" 2062 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2063 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 2064 (reg:GPR CA_REGNO)) 2065 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 2066 (clobber (reg:GPR CA_REGNO))] 2067 "" 2068 "adde %0,%1,%2" 2069 [(set_attr "type" "add")]) 2070 2071 (define_insn "add<mode>3_carry_in_0" 2072 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2073 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 2074 (reg:GPR CA_REGNO))) 2075 (clobber (reg:GPR CA_REGNO))] 2076 "" 2077 "addze %0,%1" 2078 [(set_attr "type" "add")]) 2079 2080 (define_insn "add<mode>3_carry_in_m1" 2081 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2082 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 2083 (reg:GPR CA_REGNO)) 2084 (const_int -1))) 2085 (clobber (reg:GPR CA_REGNO))] 2086 "" 2087 "addme %0,%1" 2088 [(set_attr "type" "add")]) 2089 2090 2091 (define_expand "one_cmpl<mode>2" 2092 [(set (match_operand:SDI 0 "gpc_reg_operand") 2093 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))] 2094 "" 2095 { 2096 if (<MODE>mode == DImode && !TARGET_POWERPC64) 2097 { 2098 rs6000_split_logical (operands, NOT, false, false, false); 2099 DONE; 2100 } 2101 }) 2102 2103 (define_insn "*one_cmpl<mode>2" 2104 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2105 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2106 "" 2107 "not %0,%1") 2108 2109 (define_insn_and_split "*one_cmpl<mode>2_dot" 2110 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2111 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2112 (const_int 0))) 2113 (clobber (match_scratch:GPR 0 "=r,r"))] 2114 "<MODE>mode == Pmode" 2115 "@ 2116 not. %0,%1 2117 #" 2118 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2119 [(set (match_dup 0) 2120 (not:GPR (match_dup 1))) 2121 (set (match_dup 2) 2122 (compare:CC (match_dup 0) 2123 (const_int 0)))] 2124 "" 2125 [(set_attr "type" "logical") 2126 (set_attr "dot" "yes") 2127 (set_attr "length" "4,8")]) 2128 2129 (define_insn_and_split "*one_cmpl<mode>2_dot2" 2130 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2131 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2132 (const_int 0))) 2133 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2134 (not:GPR (match_dup 1)))] 2135 "<MODE>mode == Pmode" 2136 "@ 2137 not. %0,%1 2138 #" 2139 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2140 [(set (match_dup 0) 2141 (not:GPR (match_dup 1))) 2142 (set (match_dup 2) 2143 (compare:CC (match_dup 0) 2144 (const_int 0)))] 2145 "" 2146 [(set_attr "type" "logical") 2147 (set_attr "dot" "yes") 2148 (set_attr "length" "4,8")]) 2149 2150 2151 (define_expand "sub<mode>3" 2152 [(set (match_operand:SDI 0 "gpc_reg_operand") 2153 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand") 2154 (match_operand:SDI 2 "gpc_reg_operand")))] 2155 "" 2156 { 2157 if (<MODE>mode == DImode && !TARGET_POWERPC64) 2158 { 2159 rtx lo0 = gen_lowpart (SImode, operands[0]); 2160 rtx lo1 = gen_lowpart (SImode, operands[1]); 2161 rtx lo2 = gen_lowpart (SImode, operands[2]); 2162 rtx hi0 = gen_highpart (SImode, operands[0]); 2163 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]); 2164 rtx hi2 = gen_highpart (SImode, operands[2]); 2165 2166 if (!reg_or_short_operand (lo1, SImode)) 2167 lo1 = force_reg (SImode, lo1); 2168 if (!adde_operand (hi1, SImode)) 2169 hi1 = force_reg (SImode, hi1); 2170 2171 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1)); 2172 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1)); 2173 DONE; 2174 } 2175 2176 if (short_cint_operand (operands[1], <MODE>mode)) 2177 { 2178 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1])); 2179 DONE; 2180 } 2181 }) 2182 2183 (define_insn "*subf<mode>3" 2184 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2185 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r") 2186 (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2187 "" 2188 "subf %0,%1,%2" 2189 [(set_attr "type" "add")]) 2190 2191 (define_insn_and_split "*subf<mode>3_dot" 2192 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2193 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r") 2194 (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2195 (const_int 0))) 2196 (clobber (match_scratch:GPR 0 "=r,r"))] 2197 "<MODE>mode == Pmode" 2198 "@ 2199 subf. %0,%1,%2 2200 #" 2201 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2202 [(set (match_dup 0) 2203 (minus:GPR (match_dup 2) 2204 (match_dup 1))) 2205 (set (match_dup 3) 2206 (compare:CC (match_dup 0) 2207 (const_int 0)))] 2208 "" 2209 [(set_attr "type" "add") 2210 (set_attr "dot" "yes") 2211 (set_attr "length" "4,8")]) 2212 2213 (define_insn_and_split "*subf<mode>3_dot2" 2214 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2215 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r") 2216 (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2217 (const_int 0))) 2218 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2219 (minus:GPR (match_dup 2) 2220 (match_dup 1)))] 2221 "<MODE>mode == Pmode" 2222 "@ 2223 subf. %0,%1,%2 2224 #" 2225 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2226 [(set (match_dup 0) 2227 (minus:GPR (match_dup 2) 2228 (match_dup 1))) 2229 (set (match_dup 3) 2230 (compare:CC (match_dup 0) 2231 (const_int 0)))] 2232 "" 2233 [(set_attr "type" "add") 2234 (set_attr "dot" "yes") 2235 (set_attr "length" "4,8")]) 2236 2237 (define_insn "subf<mode>3_imm" 2238 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2239 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I") 2240 (match_operand:GPR 1 "gpc_reg_operand" "r"))) 2241 (clobber (reg:GPR CA_REGNO))] 2242 "" 2243 "subfic %0,%1,%2" 2244 [(set_attr "type" "add")]) 2245 2246 (define_insn_and_split "subf<mode>3_carry_dot2" 2247 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2248 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r") 2249 (match_operand:P 1 "gpc_reg_operand" "r,r")) 2250 (const_int 0))) 2251 (set (match_operand:P 0 "gpc_reg_operand" "=r,r") 2252 (minus:P (match_dup 2) 2253 (match_dup 1))) 2254 (set (reg:P CA_REGNO) 2255 (leu:P (match_dup 1) 2256 (match_dup 2)))] 2257 "<MODE>mode == Pmode" 2258 "@ 2259 subfc. %0,%1,%2 2260 #" 2261 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2262 [(parallel [(set (match_dup 0) 2263 (minus:P (match_dup 2) 2264 (match_dup 1))) 2265 (set (reg:P CA_REGNO) 2266 (leu:P (match_dup 1) 2267 (match_dup 2)))]) 2268 (set (match_dup 3) 2269 (compare:CC (match_dup 0) 2270 (const_int 0)))] 2271 "" 2272 [(set_attr "type" "add") 2273 (set_attr "dot" "yes") 2274 (set_attr "length" "4,8")]) 2275 2276 (define_insn "subf<mode>3_carry" 2277 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2278 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI") 2279 (match_operand:P 1 "gpc_reg_operand" "r"))) 2280 (set (reg:P CA_REGNO) 2281 (leu:P (match_dup 1) 2282 (match_dup 2)))] 2283 "" 2284 "subf%I2c %0,%1,%2" 2285 [(set_attr "type" "add")]) 2286 2287 (define_insn "*subf<mode>3_imm_carry_0" 2288 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2289 (neg:P (match_operand:P 1 "gpc_reg_operand" "r"))) 2290 (set (reg:P CA_REGNO) 2291 (eq:P (match_dup 1) 2292 (const_int 0)))] 2293 "" 2294 "subfic %0,%1,0" 2295 [(set_attr "type" "add")]) 2296 2297 (define_insn "*subf<mode>3_imm_carry_m1" 2298 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2299 (not:P (match_operand:P 1 "gpc_reg_operand" "r"))) 2300 (set (reg:P CA_REGNO) 2301 (const_int 1))] 2302 "" 2303 "subfic %0,%1,-1" 2304 [(set_attr "type" "add")]) 2305 2306 2307 (define_expand "subf<mode>3_carry_in" 2308 [(parallel [ 2309 (set (match_operand:GPR 0 "gpc_reg_operand") 2310 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand")) 2311 (reg:GPR CA_REGNO)) 2312 (match_operand:GPR 2 "adde_operand"))) 2313 (clobber (reg:GPR CA_REGNO))])] 2314 "" 2315 { 2316 if (operands[2] == const0_rtx) 2317 { 2318 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1])); 2319 DONE; 2320 } 2321 if (operands[2] == constm1_rtx) 2322 { 2323 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1])); 2324 DONE; 2325 } 2326 }) 2327 2328 (define_insn "*subf<mode>3_carry_in_internal" 2329 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2330 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 2331 (reg:GPR CA_REGNO)) 2332 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 2333 (clobber (reg:GPR CA_REGNO))] 2334 "" 2335 "subfe %0,%1,%2" 2336 [(set_attr "type" "add")]) 2337 2338 (define_insn "subf<mode>3_carry_in_0" 2339 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2340 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 2341 (reg:GPR CA_REGNO))) 2342 (clobber (reg:GPR CA_REGNO))] 2343 "" 2344 "subfze %0,%1" 2345 [(set_attr "type" "add")]) 2346 2347 (define_insn "subf<mode>3_carry_in_m1" 2348 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2349 (plus:GPR (minus:GPR (reg:GPR CA_REGNO) 2350 (match_operand:GPR 1 "gpc_reg_operand" "r")) 2351 (const_int -2))) 2352 (clobber (reg:GPR CA_REGNO))] 2353 "" 2354 "subfme %0,%1" 2355 [(set_attr "type" "add")]) 2356 2357 (define_insn "subf<mode>3_carry_in_xx" 2358 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2359 (plus:GPR (reg:GPR CA_REGNO) 2360 (const_int -1))) 2361 (clobber (reg:GPR CA_REGNO))] 2362 "" 2363 "subfe %0,%0,%0" 2364 [(set_attr "type" "add")]) 2365 2366 2367 (define_insn "@neg<mode>2" 2368 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2369 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2370 "" 2371 "neg %0,%1" 2372 [(set_attr "type" "add")]) 2373 2374 (define_insn_and_split "*neg<mode>2_dot" 2375 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2376 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2377 (const_int 0))) 2378 (clobber (match_scratch:GPR 0 "=r,r"))] 2379 "<MODE>mode == Pmode" 2380 "@ 2381 neg. %0,%1 2382 #" 2383 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2384 [(set (match_dup 0) 2385 (neg:GPR (match_dup 1))) 2386 (set (match_dup 2) 2387 (compare:CC (match_dup 0) 2388 (const_int 0)))] 2389 "" 2390 [(set_attr "type" "add") 2391 (set_attr "dot" "yes") 2392 (set_attr "length" "4,8")]) 2393 2394 (define_insn_and_split "*neg<mode>2_dot2" 2395 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2396 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2397 (const_int 0))) 2398 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2399 (neg:GPR (match_dup 1)))] 2400 "<MODE>mode == Pmode" 2401 "@ 2402 neg. %0,%1 2403 #" 2404 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2405 [(set (match_dup 0) 2406 (neg:GPR (match_dup 1))) 2407 (set (match_dup 2) 2408 (compare:CC (match_dup 0) 2409 (const_int 0)))] 2410 "" 2411 [(set_attr "type" "add") 2412 (set_attr "dot" "yes") 2413 (set_attr "length" "4,8")]) 2414 2415 2416 (define_insn "clz<mode>2" 2417 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2418 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2419 "" 2420 "cntlz<wd> %0,%1" 2421 [(set_attr "type" "cntlz")]) 2422 2423 (define_expand "ctz<mode>2" 2424 [(set (match_operand:GPR 0 "gpc_reg_operand") 2425 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2426 "" 2427 { 2428 if (TARGET_CTZ) 2429 { 2430 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1])); 2431 DONE; 2432 } 2433 2434 rtx tmp1 = gen_reg_rtx (<MODE>mode); 2435 rtx tmp2 = gen_reg_rtx (<MODE>mode); 2436 rtx tmp3 = gen_reg_rtx (<MODE>mode); 2437 2438 if (TARGET_POPCNTD) 2439 { 2440 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx)); 2441 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1])); 2442 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2)); 2443 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3)); 2444 } 2445 else 2446 { 2447 emit_insn (gen_neg<mode>2 (tmp1, operands[1])); 2448 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1)); 2449 emit_insn (gen_clz<mode>2 (tmp3, tmp2)); 2450 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3)); 2451 } 2452 2453 DONE; 2454 }) 2455 2456 (define_insn "ctz<mode>2_hw" 2457 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2458 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2459 "TARGET_CTZ" 2460 "cnttz<wd> %0,%1" 2461 [(set_attr "type" "cntlz")]) 2462 2463 (define_expand "ffs<mode>2" 2464 [(set (match_operand:GPR 0 "gpc_reg_operand") 2465 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2466 "" 2467 { 2468 rtx tmp1 = gen_reg_rtx (<MODE>mode); 2469 rtx tmp2 = gen_reg_rtx (<MODE>mode); 2470 rtx tmp3 = gen_reg_rtx (<MODE>mode); 2471 emit_insn (gen_neg<mode>2 (tmp1, operands[1])); 2472 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1)); 2473 emit_insn (gen_clz<mode>2 (tmp3, tmp2)); 2474 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3)); 2475 DONE; 2476 }) 2477 2478 2479 (define_expand "popcount<mode>2" 2480 [(set (match_operand:GPR 0 "gpc_reg_operand") 2481 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2482 "TARGET_POPCNTB || TARGET_POPCNTD" 2483 { 2484 rs6000_emit_popcount (operands[0], operands[1]); 2485 DONE; 2486 }) 2487 2488 (define_insn "popcntb<mode>2" 2489 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2490 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] 2491 UNSPEC_POPCNTB))] 2492 "TARGET_POPCNTB" 2493 "popcntb %0,%1" 2494 [(set_attr "type" "popcnt")]) 2495 2496 (define_insn "popcntd<mode>2" 2497 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2498 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2499 "TARGET_POPCNTD" 2500 "popcnt<wd> %0,%1" 2501 [(set_attr "type" "popcnt")]) 2502 2503 2504 (define_expand "parity<mode>2" 2505 [(set (match_operand:GPR 0 "gpc_reg_operand") 2506 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2507 "TARGET_POPCNTB" 2508 { 2509 rs6000_emit_parity (operands[0], operands[1]); 2510 DONE; 2511 }) 2512 2513 (define_insn "parity<mode>2_cmpb" 2514 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2515 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))] 2516 "TARGET_CMPB && TARGET_POPCNTB" 2517 "prty<wd> %0,%1" 2518 [(set_attr "type" "popcnt")]) 2519 2520 (define_insn "cfuged" 2521 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2522 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r") 2523 (match_operand:DI 2 "gpc_reg_operand" "r")] 2524 UNSPEC_CFUGED))] 2525 "TARGET_POWER10 && TARGET_64BIT" 2526 "cfuged %0,%1,%2" 2527 [(set_attr "type" "integer")]) 2528 2529 (define_insn "cntlzdm" 2530 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2531 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r") 2532 (match_operand:DI 2 "gpc_reg_operand" "r")] 2533 UNSPEC_CNTLZDM))] 2534 "TARGET_POWER10 && TARGET_POWERPC64" 2535 "cntlzdm %0,%1,%2" 2536 [(set_attr "type" "integer")]) 2537 2538 (define_insn "cnttzdm" 2539 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2540 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r") 2541 (match_operand:DI 2 "gpc_reg_operand" "r")] 2542 UNSPEC_CNTTZDM))] 2543 "TARGET_POWER10 && TARGET_POWERPC64" 2544 "cnttzdm %0,%1,%2" 2545 [(set_attr "type" "integer")]) 2546 2547 (define_insn "pdepd" 2548 [(set (match_operand:DI 0 "register_operand" "=r") 2549 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r") 2550 (match_operand:DI 2 "gpc_reg_operand" "r")] 2551 UNSPEC_PDEPD))] 2552 "TARGET_POWER10 && TARGET_POWERPC64" 2553 "pdepd %0,%1,%2" 2554 [(set_attr "type" "integer")]) 2555 2556 (define_insn "pextd" 2557 [(set (match_operand:DI 0 "register_operand" "=r") 2558 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r") 2559 (match_operand:DI 2 "gpc_reg_operand" "r")] 2560 UNSPEC_PEXTD))] 2561 "TARGET_POWER10 && TARGET_POWERPC64" 2562 "pextd %0,%1,%2" 2563 [(set_attr "type" "integer")]) 2564 2565 (define_insn "cmpb<mode>3" 2566 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2567 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r") 2568 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))] 2569 "TARGET_CMPB" 2570 "cmpb %0,%1,%2" 2571 [(set_attr "type" "cmp")]) 2572 2573 ;; Since the hardware zeros the upper part of the register, save generating the 2574 ;; AND immediate if we are converting to unsigned 2575 (define_insn "*bswap<mode>2_extenddi" 2576 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2577 (zero_extend:DI 2578 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))] 2579 "TARGET_POWERPC64" 2580 "l<wd>brx %0,%y1" 2581 [(set_attr "type" "load")]) 2582 2583 (define_insn "*bswaphi2_extendsi" 2584 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2585 (zero_extend:SI 2586 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))] 2587 "" 2588 "lhbrx %0,%y1" 2589 [(set_attr "type" "load")]) 2590 2591 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents 2592 ;; the register allocator from converting a gpr<-gpr swap into a store and then 2593 ;; load with byte swap, which can be slower than doing it in the registers. It 2594 ;; also prevents certain failures with the RELOAD register allocator. 2595 2596 (define_expand "bswap<mode>2" 2597 [(use (match_operand:HSI 0 "reg_or_mem_operand")) 2598 (use (match_operand:HSI 1 "reg_or_mem_operand"))] 2599 "" 2600 { 2601 rtx dest = operands[0]; 2602 rtx src = operands[1]; 2603 2604 if (!REG_P (dest) && !REG_P (src)) 2605 src = force_reg (<MODE>mode, src); 2606 2607 if (MEM_P (src)) 2608 { 2609 src = rs6000_force_indexed_or_indirect_mem (src); 2610 emit_insn (gen_bswap<mode>2_load (dest, src)); 2611 } 2612 else if (MEM_P (dest)) 2613 { 2614 dest = rs6000_force_indexed_or_indirect_mem (dest); 2615 emit_insn (gen_bswap<mode>2_store (dest, src)); 2616 } 2617 else 2618 emit_insn (gen_bswap<mode>2_reg (dest, src)); 2619 DONE; 2620 }) 2621 2622 (define_insn "bswap<mode>2_load" 2623 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r") 2624 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))] 2625 "" 2626 "l<wd>brx %0,%y1" 2627 [(set_attr "type" "load")]) 2628 2629 (define_insn "bswap<mode>2_store" 2630 [(set (match_operand:HSI 0 "memory_operand" "=Z") 2631 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))] 2632 "" 2633 "st<wd>brx %1,%y0" 2634 [(set_attr "type" "store")]) 2635 2636 (define_insn_and_split "bswaphi2_reg" 2637 [(set (match_operand:HI 0 "gpc_reg_operand" "=r,&r,wa") 2638 (bswap:HI 2639 (match_operand:HI 1 "gpc_reg_operand" "r,r,wa"))) 2640 (clobber (match_scratch:SI 2 "=X,&r,X"))] 2641 "" 2642 "@ 2643 brh %0,%1 2644 # 2645 xxbrh %x0,%x1" 2646 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], HImode)" 2647 [(set (match_dup 3) 2648 (and:SI (lshiftrt:SI (match_dup 4) 2649 (const_int 8)) 2650 (const_int 255))) 2651 (set (match_dup 2) 2652 (and:SI (ashift:SI (match_dup 4) 2653 (const_int 8)) 2654 (const_int 65280))) ;; 0xff00 2655 (set (match_dup 3) 2656 (ior:SI (match_dup 3) 2657 (match_dup 2)))] 2658 { 2659 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0); 2660 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 2661 } 2662 [(set_attr "length" "*,12,*") 2663 (set_attr "type" "shift,*,vecperm") 2664 (set_attr "isa" "p10,*,p9v")]) 2665 2666 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in 2667 ;; zero_extract insns do not change for -mlittle. 2668 (define_insn_and_split "bswapsi2_reg" 2669 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,&r,wa") 2670 (bswap:SI 2671 (match_operand:SI 1 "gpc_reg_operand" "r,r,wa")))] 2672 "" 2673 "@ 2674 brw %0,%1 2675 # 2676 xxbrw %x0,%x1" 2677 "reload_completed && !TARGET_POWER10 && int_reg_operand (operands[0], SImode)" 2678 [(set (match_dup 0) ; DABC 2679 (rotate:SI (match_dup 1) 2680 (const_int 24))) 2681 (set (match_dup 0) ; DCBC 2682 (ior:SI (and:SI (ashift:SI (match_dup 1) 2683 (const_int 8)) 2684 (const_int 16711680)) 2685 (and:SI (match_dup 0) 2686 (const_int -16711681)))) 2687 (set (match_dup 0) ; DCBA 2688 (ior:SI (and:SI (lshiftrt:SI (match_dup 1) 2689 (const_int 24)) 2690 (const_int 255)) 2691 (and:SI (match_dup 0) 2692 (const_int -256))))] 2693 "" 2694 [(set_attr "length" "4,12,4") 2695 (set_attr "type" "shift,*,vecperm") 2696 (set_attr "isa" "p10,*,p9v")]) 2697 2698 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like 2699 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more 2700 ;; complex code. 2701 2702 (define_expand "bswapdi2" 2703 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand") 2704 (bswap:DI 2705 (match_operand:DI 1 "reg_or_mem_operand"))) 2706 (clobber (match_scratch:DI 2)) 2707 (clobber (match_scratch:DI 3))])] 2708 "" 2709 { 2710 rtx dest = operands[0]; 2711 rtx src = operands[1]; 2712 2713 if (!REG_P (dest) && !REG_P (src)) 2714 operands[1] = src = force_reg (DImode, src); 2715 2716 if (TARGET_POWERPC64 && TARGET_LDBRX) 2717 { 2718 if (MEM_P (src)) 2719 { 2720 src = rs6000_force_indexed_or_indirect_mem (src); 2721 emit_insn (gen_bswapdi2_load (dest, src)); 2722 } 2723 else if (MEM_P (dest)) 2724 { 2725 dest = rs6000_force_indexed_or_indirect_mem (dest); 2726 emit_insn (gen_bswapdi2_store (dest, src)); 2727 } 2728 else if (TARGET_P9_VECTOR) 2729 emit_insn (gen_bswapdi2_brd (dest, src)); 2730 else 2731 emit_insn (gen_bswapdi2_reg (dest, src)); 2732 DONE; 2733 } 2734 2735 if (!TARGET_POWERPC64) 2736 { 2737 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode 2738 that uses 64-bit registers needs the same scratch registers as 64-bit 2739 mode. */ 2740 emit_insn (gen_bswapdi2_32bit (dest, src)); 2741 DONE; 2742 } 2743 }) 2744 2745 ;; Power7/cell has ldbrx/stdbrx, so use it directly 2746 (define_insn "bswapdi2_load" 2747 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2748 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))] 2749 "TARGET_POWERPC64 && TARGET_LDBRX" 2750 "ldbrx %0,%y1" 2751 [(set_attr "type" "load")]) 2752 2753 (define_insn "bswapdi2_store" 2754 [(set (match_operand:DI 0 "memory_operand" "=Z") 2755 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] 2756 "TARGET_POWERPC64 && TARGET_LDBRX" 2757 "stdbrx %1,%y0" 2758 [(set_attr "type" "store")]) 2759 2760 (define_insn "bswapdi2_brd" 2761 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,wa") 2762 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r,wa")))] 2763 "TARGET_P9_VECTOR" 2764 "@ 2765 brd %0,%1 2766 xxbrd %x0,%x1" 2767 [(set_attr "type" "shift,vecperm") 2768 (set_attr "isa" "p10,p9v")]) 2769 2770 (define_insn "bswapdi2_reg" 2771 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") 2772 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) 2773 (clobber (match_scratch:DI 2 "=&r")) 2774 (clobber (match_scratch:DI 3 "=&r"))] 2775 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR" 2776 "#" 2777 [(set_attr "length" "36")]) 2778 2779 ;; Non-power7/cell, fall back to use lwbrx/stwbrx 2780 (define_insn "*bswapdi2_64bit" 2781 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r") 2782 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) 2783 (clobber (match_scratch:DI 2 "=&b,&b,&r")) 2784 (clobber (match_scratch:DI 3 "=&r,&r,&r"))] 2785 "TARGET_POWERPC64 && !TARGET_LDBRX 2786 && (REG_P (operands[0]) || REG_P (operands[1])) 2787 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) 2788 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))" 2789 "#" 2790 [(set_attr "length" "16,12,36")]) 2791 2792 (define_split 2793 [(set (match_operand:DI 0 "gpc_reg_operand") 2794 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand"))) 2795 (clobber (match_operand:DI 2 "gpc_reg_operand")) 2796 (clobber (match_operand:DI 3 "gpc_reg_operand"))] 2797 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" 2798 [(const_int 0)] 2799 { 2800 rtx dest = operands[0]; 2801 rtx src = operands[1]; 2802 rtx op2 = operands[2]; 2803 rtx op3 = operands[3]; 2804 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, 2805 BYTES_BIG_ENDIAN ? 4 : 0); 2806 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode, 2807 BYTES_BIG_ENDIAN ? 4 : 0); 2808 rtx addr1; 2809 rtx addr2; 2810 rtx word1; 2811 rtx word2; 2812 2813 addr1 = XEXP (src, 0); 2814 if (GET_CODE (addr1) == PLUS) 2815 { 2816 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2817 if (TARGET_AVOID_XFORM) 2818 { 2819 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2820 addr2 = op2; 2821 } 2822 else 2823 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); 2824 } 2825 else if (TARGET_AVOID_XFORM) 2826 { 2827 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2828 addr2 = op2; 2829 } 2830 else 2831 { 2832 emit_move_insn (op2, GEN_INT (4)); 2833 addr2 = gen_rtx_PLUS (Pmode, op2, addr1); 2834 } 2835 2836 word1 = change_address (src, SImode, addr1); 2837 word2 = change_address (src, SImode, addr2); 2838 2839 if (BYTES_BIG_ENDIAN) 2840 { 2841 emit_insn (gen_bswapsi2 (op3_32, word2)); 2842 emit_insn (gen_bswapsi2 (dest_32, word1)); 2843 } 2844 else 2845 { 2846 emit_insn (gen_bswapsi2 (op3_32, word1)); 2847 emit_insn (gen_bswapsi2 (dest_32, word2)); 2848 } 2849 2850 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32))); 2851 emit_insn (gen_iordi3 (dest, dest, op3)); 2852 DONE; 2853 }) 2854 2855 (define_split 2856 [(set (match_operand:DI 0 "indexed_or_indirect_operand") 2857 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 2858 (clobber (match_operand:DI 2 "gpc_reg_operand")) 2859 (clobber (match_operand:DI 3 "gpc_reg_operand"))] 2860 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" 2861 [(const_int 0)] 2862 { 2863 rtx dest = operands[0]; 2864 rtx src = operands[1]; 2865 rtx op2 = operands[2]; 2866 rtx op3 = operands[3]; 2867 rtx src_si = simplify_gen_subreg (SImode, src, DImode, 2868 BYTES_BIG_ENDIAN ? 4 : 0); 2869 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 2870 BYTES_BIG_ENDIAN ? 4 : 0); 2871 rtx addr1; 2872 rtx addr2; 2873 rtx word1; 2874 rtx word2; 2875 2876 addr1 = XEXP (dest, 0); 2877 if (GET_CODE (addr1) == PLUS) 2878 { 2879 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2880 if (TARGET_AVOID_XFORM) 2881 { 2882 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2883 addr2 = op2; 2884 } 2885 else 2886 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); 2887 } 2888 else if (TARGET_AVOID_XFORM) 2889 { 2890 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2891 addr2 = op2; 2892 } 2893 else 2894 { 2895 emit_move_insn (op2, GEN_INT (4)); 2896 addr2 = gen_rtx_PLUS (Pmode, op2, addr1); 2897 } 2898 2899 word1 = change_address (dest, SImode, addr1); 2900 word2 = change_address (dest, SImode, addr2); 2901 2902 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32))); 2903 2904 if (BYTES_BIG_ENDIAN) 2905 { 2906 emit_insn (gen_bswapsi2 (word1, src_si)); 2907 emit_insn (gen_bswapsi2 (word2, op3_si)); 2908 } 2909 else 2910 { 2911 emit_insn (gen_bswapsi2 (word2, src_si)); 2912 emit_insn (gen_bswapsi2 (word1, op3_si)); 2913 } 2914 DONE; 2915 }) 2916 2917 (define_split 2918 [(set (match_operand:DI 0 "gpc_reg_operand") 2919 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 2920 (clobber (match_operand:DI 2 "gpc_reg_operand")) 2921 (clobber (match_operand:DI 3 "gpc_reg_operand"))] 2922 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed" 2923 [(const_int 0)] 2924 { 2925 rtx dest = operands[0]; 2926 rtx src = operands[1]; 2927 rtx op2 = operands[2]; 2928 rtx op3 = operands[3]; 2929 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0; 2930 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off); 2931 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off); 2932 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off); 2933 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off); 2934 2935 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32))); 2936 emit_insn (gen_bswapsi2 (dest_si, src_si)); 2937 emit_insn (gen_bswapsi2 (op3_si, op2_si)); 2938 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32))); 2939 emit_insn (gen_iordi3 (dest, dest, op3)); 2940 DONE; 2941 }) 2942 2943 (define_insn "bswapdi2_32bit" 2944 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r") 2945 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) 2946 (clobber (match_scratch:SI 2 "=&b,&b,X"))] 2947 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))" 2948 "#" 2949 [(set_attr "length" "16,12,36")]) 2950 2951 (define_split 2952 [(set (match_operand:DI 0 "gpc_reg_operand") 2953 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand"))) 2954 (clobber (match_operand:SI 2 "gpc_reg_operand"))] 2955 "!TARGET_POWERPC64 && reload_completed" 2956 [(const_int 0)] 2957 { 2958 rtx dest = operands[0]; 2959 rtx src = operands[1]; 2960 rtx op2 = operands[2]; 2961 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); 2962 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); 2963 rtx addr1; 2964 rtx addr2; 2965 rtx word1; 2966 rtx word2; 2967 2968 addr1 = XEXP (src, 0); 2969 if (GET_CODE (addr1) == PLUS) 2970 { 2971 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2972 if (TARGET_AVOID_XFORM 2973 || REGNO (XEXP (addr1, 1)) == REGNO (dest2)) 2974 { 2975 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2976 addr2 = op2; 2977 } 2978 else 2979 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); 2980 } 2981 else if (TARGET_AVOID_XFORM 2982 || REGNO (addr1) == REGNO (dest2)) 2983 { 2984 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2985 addr2 = op2; 2986 } 2987 else 2988 { 2989 emit_move_insn (op2, GEN_INT (4)); 2990 addr2 = gen_rtx_PLUS (SImode, op2, addr1); 2991 } 2992 2993 word1 = change_address (src, SImode, addr1); 2994 word2 = change_address (src, SImode, addr2); 2995 2996 emit_insn (gen_bswapsi2 (dest2, word1)); 2997 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed, 2998 thus allowing us to omit an early clobber on the output. */ 2999 emit_insn (gen_bswapsi2 (dest1, word2)); 3000 DONE; 3001 }) 3002 3003 (define_split 3004 [(set (match_operand:DI 0 "indexed_or_indirect_operand") 3005 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 3006 (clobber (match_operand:SI 2 "gpc_reg_operand"))] 3007 "!TARGET_POWERPC64 && reload_completed" 3008 [(const_int 0)] 3009 { 3010 rtx dest = operands[0]; 3011 rtx src = operands[1]; 3012 rtx op2 = operands[2]; 3013 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); 3014 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); 3015 rtx addr1; 3016 rtx addr2; 3017 rtx word1; 3018 rtx word2; 3019 3020 addr1 = XEXP (dest, 0); 3021 if (GET_CODE (addr1) == PLUS) 3022 { 3023 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 3024 if (TARGET_AVOID_XFORM) 3025 { 3026 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 3027 addr2 = op2; 3028 } 3029 else 3030 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); 3031 } 3032 else if (TARGET_AVOID_XFORM) 3033 { 3034 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 3035 addr2 = op2; 3036 } 3037 else 3038 { 3039 emit_move_insn (op2, GEN_INT (4)); 3040 addr2 = gen_rtx_PLUS (SImode, op2, addr1); 3041 } 3042 3043 word1 = change_address (dest, SImode, addr1); 3044 word2 = change_address (dest, SImode, addr2); 3045 3046 emit_insn (gen_bswapsi2 (word2, src1)); 3047 emit_insn (gen_bswapsi2 (word1, src2)); 3048 DONE; 3049 }) 3050 3051 (define_split 3052 [(set (match_operand:DI 0 "gpc_reg_operand") 3053 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 3054 (clobber (match_operand:SI 2 ""))] 3055 "!TARGET_POWERPC64 && reload_completed" 3056 [(const_int 0)] 3057 { 3058 rtx dest = operands[0]; 3059 rtx src = operands[1]; 3060 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); 3061 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); 3062 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); 3063 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); 3064 3065 emit_insn (gen_bswapsi2 (dest1, src2)); 3066 emit_insn (gen_bswapsi2 (dest2, src1)); 3067 DONE; 3068 }) 3069 3070 3071 (define_insn "mul<mode>3" 3072 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3073 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3074 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))] 3075 "" 3076 "@ 3077 mull<wd> %0,%1,%2 3078 mulli %0,%1,%2" 3079 [(set_attr "type" "mul") 3080 (set (attr "size") 3081 (cond [(match_operand:GPR 2 "s8bit_cint_operand") 3082 (const_string "8") 3083 (match_operand:GPR 2 "short_cint_operand") 3084 (const_string "16")] 3085 (const_string "<bits>")))]) 3086 3087 (define_insn_and_split "*mul<mode>3_dot" 3088 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3089 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3090 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3091 (const_int 0))) 3092 (clobber (match_scratch:GPR 0 "=r,r"))] 3093 "<MODE>mode == Pmode" 3094 "@ 3095 mull<wd>. %0,%1,%2 3096 #" 3097 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3098 [(set (match_dup 0) 3099 (mult:GPR (match_dup 1) 3100 (match_dup 2))) 3101 (set (match_dup 3) 3102 (compare:CC (match_dup 0) 3103 (const_int 0)))] 3104 "" 3105 [(set_attr "type" "mul") 3106 (set_attr "size" "<bits>") 3107 (set_attr "dot" "yes") 3108 (set_attr "length" "4,8")]) 3109 3110 (define_insn_and_split "*mul<mode>3_dot2" 3111 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3112 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3113 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3114 (const_int 0))) 3115 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3116 (mult:GPR (match_dup 1) 3117 (match_dup 2)))] 3118 "<MODE>mode == Pmode" 3119 "@ 3120 mull<wd>. %0,%1,%2 3121 #" 3122 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3123 [(set (match_dup 0) 3124 (mult:GPR (match_dup 1) 3125 (match_dup 2))) 3126 (set (match_dup 3) 3127 (compare:CC (match_dup 0) 3128 (const_int 0)))] 3129 "" 3130 [(set_attr "type" "mul") 3131 (set_attr "size" "<bits>") 3132 (set_attr "dot" "yes") 3133 (set_attr "length" "4,8")]) 3134 3135 3136 (define_expand "<su>mul<mode>3_highpart" 3137 [(set (match_operand:GPR 0 "gpc_reg_operand") 3138 (subreg:GPR 3139 (mult:<DMODE> (any_extend:<DMODE> 3140 (match_operand:GPR 1 "gpc_reg_operand")) 3141 (any_extend:<DMODE> 3142 (match_operand:GPR 2 "gpc_reg_operand"))) 3143 0))] 3144 "" 3145 { 3146 if (<MODE>mode == SImode && TARGET_POWERPC64) 3147 { 3148 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1], 3149 operands[2])); 3150 DONE; 3151 } 3152 3153 if (!WORDS_BIG_ENDIAN) 3154 { 3155 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1], 3156 operands[2])); 3157 DONE; 3158 } 3159 }) 3160 3161 (define_insn "*<su>mul<mode>3_highpart" 3162 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3163 (subreg:GPR 3164 (mult:<DMODE> (any_extend:<DMODE> 3165 (match_operand:GPR 1 "gpc_reg_operand" "r")) 3166 (any_extend:<DMODE> 3167 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 3168 0))] 3169 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)" 3170 "mulh<wd><u> %0,%1,%2" 3171 [(set_attr "type" "mul") 3172 (set_attr "size" "<bits>")]) 3173 3174 (define_insn "<su>mulsi3_highpart_le" 3175 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 3176 (subreg:SI 3177 (mult:DI (any_extend:DI 3178 (match_operand:SI 1 "gpc_reg_operand" "r")) 3179 (any_extend:DI 3180 (match_operand:SI 2 "gpc_reg_operand" "r"))) 3181 4))] 3182 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64" 3183 "mulhw<u> %0,%1,%2" 3184 [(set_attr "type" "mul")]) 3185 3186 (define_insn "<su>muldi3_highpart_le" 3187 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3188 (subreg:DI 3189 (mult:TI (any_extend:TI 3190 (match_operand:DI 1 "gpc_reg_operand" "r")) 3191 (any_extend:TI 3192 (match_operand:DI 2 "gpc_reg_operand" "r"))) 3193 8))] 3194 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64" 3195 "mulhd<u> %0,%1,%2" 3196 [(set_attr "type" "mul") 3197 (set_attr "size" "64")]) 3198 3199 (define_insn "<su>mulsi3_highpart_64" 3200 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 3201 (truncate:SI 3202 (lshiftrt:DI 3203 (mult:DI (any_extend:DI 3204 (match_operand:SI 1 "gpc_reg_operand" "r")) 3205 (any_extend:DI 3206 (match_operand:SI 2 "gpc_reg_operand" "r"))) 3207 (const_int 32))))] 3208 "TARGET_POWERPC64" 3209 "mulhw<u> %0,%1,%2" 3210 [(set_attr "type" "mul")]) 3211 3212 (define_expand "<u>mul<mode><dmode>3" 3213 [(set (match_operand:<DMODE> 0 "gpc_reg_operand") 3214 (mult:<DMODE> (any_extend:<DMODE> 3215 (match_operand:GPR 1 "gpc_reg_operand")) 3216 (any_extend:<DMODE> 3217 (match_operand:GPR 2 "gpc_reg_operand"))))] 3218 "!(<MODE>mode == SImode && TARGET_POWERPC64)" 3219 { 3220 rtx l = gen_reg_rtx (<MODE>mode); 3221 rtx h = gen_reg_rtx (<MODE>mode); 3222 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2])); 3223 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2])); 3224 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l); 3225 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h); 3226 DONE; 3227 }) 3228 3229 (define_insn "*maddld<mode>4" 3230 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3231 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3232 (match_operand:GPR 2 "gpc_reg_operand" "r")) 3233 (match_operand:GPR 3 "gpc_reg_operand" "r")))] 3234 "TARGET_MADDLD" 3235 "maddld %0,%1,%2,%3" 3236 [(set_attr "type" "mul")]) 3237 3238 (define_insn "udiv<mode>3" 3239 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3240 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3241 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3242 "" 3243 "div<wd>u %0,%1,%2" 3244 [(set_attr "type" "div") 3245 (set_attr "size" "<bits>")]) 3246 3247 (define_insn "udivti3" 3248 [(set (match_operand:TI 0 "altivec_register_operand" "=v") 3249 (udiv:TI (match_operand:TI 1 "altivec_register_operand" "v") 3250 (match_operand:TI 2 "altivec_register_operand" "v")))] 3251 "TARGET_POWER10 && TARGET_POWERPC64" 3252 "vdivuq %0,%1,%2" 3253 [(set_attr "type" "vecdiv") 3254 (set_attr "size" "128")]) 3255 3256 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for 3257 ;; modulus. If it isn't a power of two, force operands into register and do 3258 ;; a normal divide. 3259 (define_expand "div<mode>3" 3260 [(set (match_operand:GPR 0 "gpc_reg_operand") 3261 (div:GPR (match_operand:GPR 1 "gpc_reg_operand") 3262 (match_operand:GPR 2 "reg_or_cint_operand")))] 3263 "" 3264 { 3265 if (CONST_INT_P (operands[2]) 3266 && INTVAL (operands[2]) > 0 3267 && exact_log2 (INTVAL (operands[2])) >= 0) 3268 { 3269 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2])); 3270 DONE; 3271 } 3272 3273 operands[2] = force_reg (<MODE>mode, operands[2]); 3274 }) 3275 3276 (define_insn "*div<mode>3" 3277 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3278 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3279 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3280 "" 3281 "div<wd> %0,%1,%2" 3282 [(set_attr "type" "div") 3283 (set_attr "size" "<bits>")]) 3284 3285 (define_insn "div<mode>3_sra" 3286 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3287 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3288 (match_operand:GPR 2 "exact_log2_cint_operand" "N"))) 3289 (clobber (reg:GPR CA_REGNO))] 3290 "" 3291 "sra<wd>i %0,%1,%p2\;addze %0,%0" 3292 [(set_attr "type" "two") 3293 (set_attr "length" "8")]) 3294 3295 (define_insn_and_split "*div<mode>3_sra_dot" 3296 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3297 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3298 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")) 3299 (const_int 0))) 3300 (clobber (match_scratch:GPR 0 "=r,r")) 3301 (clobber (reg:GPR CA_REGNO))] 3302 "<MODE>mode == Pmode" 3303 "@ 3304 sra<wd>i %0,%1,%p2\;addze. %0,%0 3305 #" 3306 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3307 [(parallel [(set (match_dup 0) 3308 (div:GPR (match_dup 1) 3309 (match_dup 2))) 3310 (clobber (reg:GPR CA_REGNO))]) 3311 (set (match_dup 3) 3312 (compare:CC (match_dup 0) 3313 (const_int 0)))] 3314 "" 3315 [(set_attr "type" "two") 3316 (set_attr "length" "8,12") 3317 (set_attr "cell_micro" "not")]) 3318 3319 (define_insn_and_split "*div<mode>3_sra_dot2" 3320 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3321 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3322 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")) 3323 (const_int 0))) 3324 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3325 (div:GPR (match_dup 1) 3326 (match_dup 2))) 3327 (clobber (reg:GPR CA_REGNO))] 3328 "<MODE>mode == Pmode" 3329 "@ 3330 sra<wd>i %0,%1,%p2\;addze. %0,%0 3331 #" 3332 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3333 [(parallel [(set (match_dup 0) 3334 (div:GPR (match_dup 1) 3335 (match_dup 2))) 3336 (clobber (reg:GPR CA_REGNO))]) 3337 (set (match_dup 3) 3338 (compare:CC (match_dup 0) 3339 (const_int 0)))] 3340 "" 3341 [(set_attr "type" "two") 3342 (set_attr "length" "8,12") 3343 (set_attr "cell_micro" "not")]) 3344 3345 (define_insn "divti3" 3346 [(set (match_operand:TI 0 "altivec_register_operand" "=v") 3347 (div:TI (match_operand:TI 1 "altivec_register_operand" "v") 3348 (match_operand:TI 2 "altivec_register_operand" "v")))] 3349 "TARGET_POWER10 && TARGET_POWERPC64" 3350 "vdivsq %0,%1,%2" 3351 [(set_attr "type" "vecdiv") 3352 (set_attr "size" "128")]) 3353 3354 (define_expand "mod<mode>3" 3355 [(set (match_operand:GPR 0 "gpc_reg_operand") 3356 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand") 3357 (match_operand:GPR 2 "reg_or_cint_operand")))] 3358 "" 3359 { 3360 int i; 3361 rtx temp1; 3362 rtx temp2; 3363 3364 if (!CONST_INT_P (operands[2]) 3365 || INTVAL (operands[2]) <= 0 3366 || (i = exact_log2 (INTVAL (operands[2]))) < 0) 3367 { 3368 if (!TARGET_MODULO) 3369 FAIL; 3370 3371 operands[2] = force_reg (<MODE>mode, operands[2]); 3372 3373 if (RS6000_DISABLE_SCALAR_MODULO) 3374 { 3375 temp1 = gen_reg_rtx (<MODE>mode); 3376 temp2 = gen_reg_rtx (<MODE>mode); 3377 3378 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2])); 3379 emit_insn (gen_mul<mode>3 (temp2, temp1, operands[2])); 3380 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2)); 3381 DONE; 3382 } 3383 } 3384 else 3385 { 3386 temp1 = gen_reg_rtx (<MODE>mode); 3387 temp2 = gen_reg_rtx (<MODE>mode); 3388 3389 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2])); 3390 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i))); 3391 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2)); 3392 DONE; 3393 } 3394 }) 3395 3396 ;; In order to enable using a peephole2 for combining div/mod to eliminate the 3397 ;; mod, prefer putting the result of mod into a different register 3398 (define_insn "*mod<mode>3" 3399 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 3400 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3401 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3402 "TARGET_MODULO && !RS6000_DISABLE_SCALAR_MODULO" 3403 "mods<wd> %0,%1,%2" 3404 [(set_attr "type" "div") 3405 (set_attr "size" "<bits>")]) 3406 3407 ;; This define_expand can be removed when RS6000_DISABLE_SCALAR_MODULO is 3408 ;; removed. 3409 (define_expand "umod<mode>3" 3410 [(set (match_operand:GPR 0 "gpc_reg_operand") 3411 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand") 3412 (match_operand:GPR 2 "gpc_reg_operand")))] 3413 "TARGET_MODULO" 3414 { 3415 if (RS6000_DISABLE_SCALAR_MODULO) 3416 { 3417 rtx temp1 = gen_reg_rtx (<MODE>mode); 3418 rtx temp2 = gen_reg_rtx (<MODE>mode); 3419 3420 emit_insn (gen_udiv<mode>3 (temp1, operands[1], operands[2])); 3421 emit_insn (gen_mul<mode>3 (temp2, temp1, operands[2])); 3422 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2)); 3423 DONE; 3424 } 3425 }) 3426 3427 (define_insn "*umod<mode>3" 3428 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 3429 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3430 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3431 "TARGET_MODULO && !RS6000_DISABLE_SCALAR_MODULO" 3432 "modu<wd> %0,%1,%2" 3433 [(set_attr "type" "div") 3434 (set_attr "size" "<bits>")]) 3435 3436 ;; On machines with modulo support, do a combined div/mod the old fashioned 3437 ;; method, since the multiply/subtract is faster than doing the mod instruction 3438 ;; after a divide. 3439 3440 (define_peephole2 3441 [(set (match_operand:GPR 0 "gpc_reg_operand") 3442 (div:GPR (match_operand:GPR 1 "gpc_reg_operand") 3443 (match_operand:GPR 2 "gpc_reg_operand"))) 3444 (set (match_operand:GPR 3 "gpc_reg_operand") 3445 (mod:GPR (match_dup 1) 3446 (match_dup 2)))] 3447 "TARGET_MODULO 3448 && ! reg_mentioned_p (operands[0], operands[1]) 3449 && ! reg_mentioned_p (operands[0], operands[2]) 3450 && ! reg_mentioned_p (operands[3], operands[1]) 3451 && ! reg_mentioned_p (operands[3], operands[2])" 3452 [(set (match_dup 0) 3453 (div:GPR (match_dup 1) 3454 (match_dup 2))) 3455 (set (match_dup 3) 3456 (mult:GPR (match_dup 0) 3457 (match_dup 2))) 3458 (set (match_dup 3) 3459 (minus:GPR (match_dup 1) 3460 (match_dup 3)))]) 3461 3462 (define_peephole2 3463 [(set (match_operand:GPR 0 "gpc_reg_operand") 3464 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand") 3465 (match_operand:GPR 2 "gpc_reg_operand"))) 3466 (set (match_operand:GPR 3 "gpc_reg_operand") 3467 (umod:GPR (match_dup 1) 3468 (match_dup 2)))] 3469 "TARGET_MODULO 3470 && ! reg_mentioned_p (operands[0], operands[1]) 3471 && ! reg_mentioned_p (operands[0], operands[2]) 3472 && ! reg_mentioned_p (operands[3], operands[1]) 3473 && ! reg_mentioned_p (operands[3], operands[2])" 3474 [(set (match_dup 0) 3475 (udiv:GPR (match_dup 1) 3476 (match_dup 2))) 3477 (set (match_dup 3) 3478 (mult:GPR (match_dup 0) 3479 (match_dup 2))) 3480 (set (match_dup 3) 3481 (minus:GPR (match_dup 1) 3482 (match_dup 3)))]) 3483 3484 (define_insn "umodti3" 3485 [(set (match_operand:TI 0 "altivec_register_operand" "=v") 3486 (umod:TI (match_operand:TI 1 "altivec_register_operand" "v") 3487 (match_operand:TI 2 "altivec_register_operand" "v")))] 3488 "TARGET_POWER10 && TARGET_POWERPC64 && !RS6000_DISABLE_SCALAR_MODULO" 3489 "vmoduq %0,%1,%2" 3490 [(set_attr "type" "vecdiv") 3491 (set_attr "size" "128")]) 3492 3493 (define_insn "modti3" 3494 [(set (match_operand:TI 0 "altivec_register_operand" "=v") 3495 (mod:TI (match_operand:TI 1 "altivec_register_operand" "v") 3496 (match_operand:TI 2 "altivec_register_operand" "v")))] 3497 "TARGET_POWER10 && TARGET_POWERPC64 && !RS6000_DISABLE_SCALAR_MODULO" 3498 "vmodsq %0,%1,%2" 3499 [(set_attr "type" "vecdiv") 3500 (set_attr "size" "128")]) 3501 3503 ;; Logical instructions 3504 ;; The logical instructions are mostly combined by using match_operator, 3505 ;; but the plain AND insns are somewhat different because there is no 3506 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all 3507 ;; those rotate-and-mask operations. Thus, the AND insns come first. 3508 3509 (define_expand "and<mode>3" 3510 [(set (match_operand:SDI 0 "gpc_reg_operand") 3511 (and:SDI (match_operand:SDI 1 "gpc_reg_operand") 3512 (match_operand:SDI 2 "reg_or_cint_operand")))] 3513 "" 3514 { 3515 if (<MODE>mode == DImode && !TARGET_POWERPC64) 3516 { 3517 rs6000_split_logical (operands, AND, false, false, false); 3518 DONE; 3519 } 3520 3521 if (CONST_INT_P (operands[2])) 3522 { 3523 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode)) 3524 { 3525 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2])); 3526 DONE; 3527 } 3528 3529 if (logical_const_operand (operands[2], <MODE>mode)) 3530 { 3531 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2])); 3532 DONE; 3533 } 3534 3535 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode)) 3536 { 3537 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0); 3538 DONE; 3539 } 3540 3541 operands[2] = force_reg (<MODE>mode, operands[2]); 3542 } 3543 }) 3544 3545 3546 (define_insn "and<mode>3_imm" 3547 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3548 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3549 (match_operand:GPR 2 "logical_const_operand" "n"))) 3550 (clobber (match_scratch:CC 3 "=x"))] 3551 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3552 "andi%e2. %0,%1,%u2" 3553 [(set_attr "type" "logical") 3554 (set_attr "dot" "yes")]) 3555 3556 (define_insn_and_split "*and<mode>3_imm_dot" 3557 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3558 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3559 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3560 (const_int 0))) 3561 (clobber (match_scratch:GPR 0 "=r,r")) 3562 (clobber (match_scratch:CC 4 "=X,x"))] 3563 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3564 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3565 "@ 3566 andi%e2. %0,%1,%u2 3567 #" 3568 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3569 [(parallel [(set (match_dup 0) 3570 (and:GPR (match_dup 1) 3571 (match_dup 2))) 3572 (clobber (match_dup 4))]) 3573 (set (match_dup 3) 3574 (compare:CC (match_dup 0) 3575 (const_int 0)))] 3576 "" 3577 [(set_attr "type" "logical") 3578 (set_attr "dot" "yes") 3579 (set_attr "length" "4,8")]) 3580 3581 (define_insn_and_split "*and<mode>3_imm_dot2" 3582 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3583 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3584 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3585 (const_int 0))) 3586 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3587 (and:GPR (match_dup 1) 3588 (match_dup 2))) 3589 (clobber (match_scratch:CC 4 "=X,x"))] 3590 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3591 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3592 "@ 3593 andi%e2. %0,%1,%u2 3594 #" 3595 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3596 [(parallel [(set (match_dup 0) 3597 (and:GPR (match_dup 1) 3598 (match_dup 2))) 3599 (clobber (match_dup 4))]) 3600 (set (match_dup 3) 3601 (compare:CC (match_dup 0) 3602 (const_int 0)))] 3603 "" 3604 [(set_attr "type" "logical") 3605 (set_attr "dot" "yes") 3606 (set_attr "length" "4,8")]) 3607 3608 (define_insn_and_split "*and<mode>3_imm_mask_dot" 3609 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3610 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3611 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3612 (const_int 0))) 3613 (clobber (match_scratch:GPR 0 "=r,r"))] 3614 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3615 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3616 "@ 3617 andi%e2. %0,%1,%u2 3618 #" 3619 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3620 [(set (match_dup 0) 3621 (and:GPR (match_dup 1) 3622 (match_dup 2))) 3623 (set (match_dup 3) 3624 (compare:CC (match_dup 0) 3625 (const_int 0)))] 3626 "" 3627 [(set_attr "type" "logical") 3628 (set_attr "dot" "yes") 3629 (set_attr "length" "4,8")]) 3630 3631 (define_insn_and_split "*and<mode>3_imm_mask_dot2" 3632 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3633 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3634 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3635 (const_int 0))) 3636 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3637 (and:GPR (match_dup 1) 3638 (match_dup 2)))] 3639 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3640 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3641 "@ 3642 andi%e2. %0,%1,%u2 3643 #" 3644 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3645 [(set (match_dup 0) 3646 (and:GPR (match_dup 1) 3647 (match_dup 2))) 3648 (set (match_dup 3) 3649 (compare:CC (match_dup 0) 3650 (const_int 0)))] 3651 "" 3652 [(set_attr "type" "logical") 3653 (set_attr "dot" "yes") 3654 (set_attr "length" "4,8")]) 3655 3656 (define_insn "*and<mode>3_imm_dot_shifted" 3657 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 3658 (compare:CC 3659 (and:GPR 3660 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3661 (match_operand:SI 4 "const_int_operand" "n")) 3662 (match_operand:GPR 2 "const_int_operand" "n")) 3663 (const_int 0))) 3664 (clobber (match_scratch:GPR 0 "=r"))] 3665 "logical_const_operand (GEN_INT (UINTVAL (operands[2]) 3666 << INTVAL (operands[4])), 3667 DImode) 3668 && (<MODE>mode == Pmode 3669 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)" 3670 { 3671 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4])); 3672 return "andi%e2. %0,%1,%u2"; 3673 } 3674 [(set_attr "type" "logical") 3675 (set_attr "dot" "yes")]) 3676 3677 3678 (define_insn "and<mode>3_mask" 3679 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3680 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3681 (match_operand:GPR 2 "const_int_operand" "n")))] 3682 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3683 { 3684 return rs6000_insn_for_and_mask (<MODE>mode, operands, false); 3685 } 3686 [(set_attr "type" "shift")]) 3687 3688 (define_insn_and_split "*and<mode>3_mask_dot" 3689 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3690 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3691 (match_operand:GPR 2 "const_int_operand" "n,n")) 3692 (const_int 0))) 3693 (clobber (match_scratch:GPR 0 "=r,r"))] 3694 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3695 && !logical_const_operand (operands[2], <MODE>mode) 3696 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3697 { 3698 if (which_alternative == 0) 3699 return rs6000_insn_for_and_mask (<MODE>mode, operands, true); 3700 else 3701 return "#"; 3702 } 3703 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3704 [(set (match_dup 0) 3705 (and:GPR (match_dup 1) 3706 (match_dup 2))) 3707 (set (match_dup 3) 3708 (compare:CC (match_dup 0) 3709 (const_int 0)))] 3710 "" 3711 [(set_attr "type" "shift") 3712 (set_attr "dot" "yes") 3713 (set_attr "length" "4,8")]) 3714 3715 (define_insn_and_split "*and<mode>3_mask_dot2" 3716 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3717 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3718 (match_operand:GPR 2 "const_int_operand" "n,n")) 3719 (const_int 0))) 3720 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3721 (and:GPR (match_dup 1) 3722 (match_dup 2)))] 3723 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3724 && !logical_const_operand (operands[2], <MODE>mode) 3725 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3726 { 3727 if (which_alternative == 0) 3728 return rs6000_insn_for_and_mask (<MODE>mode, operands, true); 3729 else 3730 return "#"; 3731 } 3732 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3733 [(set (match_dup 0) 3734 (and:GPR (match_dup 1) 3735 (match_dup 2))) 3736 (set (match_dup 3) 3737 (compare:CC (match_dup 0) 3738 (const_int 0)))] 3739 "" 3740 [(set_attr "type" "shift") 3741 (set_attr "dot" "yes") 3742 (set_attr "length" "4,8")]) 3743 3744 3745 (define_insn_and_split "*and<mode>3_2insn" 3746 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3747 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3748 (match_operand:GPR 2 "const_int_operand" "n")))] 3749 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3750 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3751 || logical_const_operand (operands[2], <MODE>mode))" 3752 "#" 3753 "&& 1" 3754 [(pc)] 3755 { 3756 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0); 3757 DONE; 3758 } 3759 [(set_attr "type" "shift") 3760 (set_attr "length" "8")]) 3761 3762 (define_insn_and_split "*and<mode>3_2insn_dot" 3763 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3764 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3765 (match_operand:GPR 2 "const_int_operand" "n,n")) 3766 (const_int 0))) 3767 (clobber (match_scratch:GPR 0 "=r,r"))] 3768 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3769 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3770 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3771 || logical_const_operand (operands[2], <MODE>mode))" 3772 "#" 3773 "&& reload_completed" 3774 [(pc)] 3775 { 3776 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1); 3777 DONE; 3778 } 3779 [(set_attr "type" "shift") 3780 (set_attr "dot" "yes") 3781 (set_attr "length" "8,12")]) 3782 3783 (define_insn_and_split "*and<mode>3_2insn_dot2" 3784 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3785 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3786 (match_operand:GPR 2 "const_int_operand" "n,n")) 3787 (const_int 0))) 3788 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3789 (and:GPR (match_dup 1) 3790 (match_dup 2)))] 3791 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3792 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3793 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3794 || logical_const_operand (operands[2], <MODE>mode))" 3795 "#" 3796 "&& reload_completed" 3797 [(pc)] 3798 { 3799 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2); 3800 DONE; 3801 } 3802 [(set_attr "type" "shift") 3803 (set_attr "dot" "yes") 3804 (set_attr "length" "8,12")]) 3805 3806 (define_insn_and_split "*branch_anddi3_dot" 3807 [(set (pc) 3808 (if_then_else (eq (and:DI (match_operand:DI 1 "gpc_reg_operand" "%r,r") 3809 (match_operand:DI 2 "const_int_operand" "n,n")) 3810 (const_int 0)) 3811 (label_ref (match_operand 3 "")) 3812 (pc))) 3813 (clobber (match_scratch:DI 0 "=r,r")) 3814 (clobber (reg:CC CR0_REGNO))] 3815 "rs6000_is_valid_rotate_dot_mask (operands[2], DImode) 3816 && TARGET_POWERPC64" 3817 "#" 3818 "&& reload_completed" 3819 [(pc)] 3820 { 3821 int nb, ne; 3822 if (rs6000_is_valid_mask (operands[2], &nb, &ne, DImode) 3823 && nb >= ne 3824 && ne > 0) 3825 { 3826 unsigned HOST_WIDE_INT val = INTVAL (operands[2]); 3827 int shift = 63 - nb; 3828 rtx tmp = gen_rtx_ASHIFT (DImode, operands[1], GEN_INT (shift)); 3829 tmp = gen_rtx_AND (DImode, tmp, GEN_INT (val << shift)); 3830 rtx cr0 = gen_rtx_REG (CCmode, CR0_REGNO); 3831 rs6000_emit_dot_insn (operands[0], tmp, 1, cr0); 3832 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[3]); 3833 rtx cond = gen_rtx_EQ (CCEQmode, cr0, const0_rtx); 3834 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx); 3835 emit_jump_insn (gen_rtx_SET (pc_rtx, ite)); 3836 DONE; 3837 } 3838 else 3839 FAIL; 3840 } 3841 [(set_attr "type" "shift") 3842 (set_attr "dot" "yes") 3843 (set_attr "length" "8,12")]) 3844 3845 (define_expand "<code><mode>3" 3846 [(set (match_operand:SDI 0 "gpc_reg_operand") 3847 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand") 3848 (match_operand:SDI 2 "reg_or_cint_operand")))] 3849 "" 3850 { 3851 if (<MODE>mode == DImode && !TARGET_POWERPC64) 3852 { 3853 rs6000_split_logical (operands, <CODE>, false, false, false); 3854 DONE; 3855 } 3856 3857 if (non_logical_cint_operand (operands[2], <MODE>mode)) 3858 { 3859 rtx tmp = ((!can_create_pseudo_p () 3860 || rtx_equal_p (operands[0], operands[1])) 3861 ? operands[0] : gen_reg_rtx (<MODE>mode)); 3862 3863 HOST_WIDE_INT value = INTVAL (operands[2]); 3864 HOST_WIDE_INT lo = value & 0xffff; 3865 HOST_WIDE_INT hi = value - lo; 3866 3867 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi))); 3868 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo))); 3869 DONE; 3870 } 3871 3872 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode)) 3873 operands[2] = force_reg (<MODE>mode, operands[2]); 3874 }) 3875 3876 (define_split 3877 [(set (match_operand:GPR 0 "gpc_reg_operand") 3878 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand") 3879 (match_operand:GPR 2 "non_logical_cint_operand")))] 3880 "" 3881 [(set (match_dup 3) 3882 (iorxor:GPR (match_dup 1) 3883 (match_dup 4))) 3884 (set (match_dup 0) 3885 (iorxor:GPR (match_dup 3) 3886 (match_dup 5)))] 3887 { 3888 operands[3] = ((!can_create_pseudo_p () 3889 || rtx_equal_p (operands[0], operands[1])) 3890 ? operands[0] : gen_reg_rtx (<MODE>mode)); 3891 3892 HOST_WIDE_INT value = INTVAL (operands[2]); 3893 HOST_WIDE_INT lo = value & 0xffff; 3894 HOST_WIDE_INT hi = value - lo; 3895 3896 operands[4] = GEN_INT (hi); 3897 operands[5] = GEN_INT (lo); 3898 }) 3899 3900 (define_insn "*bool<mode>3_imm" 3901 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3902 (match_operator:GPR 3 "boolean_or_operator" 3903 [(match_operand:GPR 1 "gpc_reg_operand" "%r") 3904 (match_operand:GPR 2 "logical_const_operand" "n")]))] 3905 "" 3906 "%q3i%e2 %0,%1,%u2" 3907 [(set_attr "type" "logical")]) 3908 3909 (define_insn "*bool<mode>3" 3910 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3911 (match_operator:GPR 3 "boolean_operator" 3912 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3913 (match_operand:GPR 2 "gpc_reg_operand" "r")]))] 3914 "" 3915 "%q3 %0,%1,%2" 3916 [(set_attr "type" "logical")]) 3917 3918 (define_insn_and_split "*bool<mode>3_dot" 3919 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3920 (compare:CC (match_operator:GPR 3 "boolean_operator" 3921 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3922 (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) 3923 (const_int 0))) 3924 (clobber (match_scratch:GPR 0 "=r,r"))] 3925 "<MODE>mode == Pmode" 3926 "@ 3927 %q3. %0,%1,%2 3928 #" 3929 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3930 [(set (match_dup 0) 3931 (match_dup 3)) 3932 (set (match_dup 4) 3933 (compare:CC (match_dup 0) 3934 (const_int 0)))] 3935 "" 3936 [(set_attr "type" "logical") 3937 (set_attr "dot" "yes") 3938 (set_attr "length" "4,8")]) 3939 3940 (define_insn_and_split "*bool<mode>3_dot2" 3941 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3942 (compare:CC (match_operator:GPR 3 "boolean_operator" 3943 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3944 (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) 3945 (const_int 0))) 3946 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3947 (match_dup 3))] 3948 "<MODE>mode == Pmode" 3949 "@ 3950 %q3. %0,%1,%2 3951 #" 3952 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3953 [(set (match_dup 0) 3954 (match_dup 3)) 3955 (set (match_dup 4) 3956 (compare:CC (match_dup 0) 3957 (const_int 0)))] 3958 "" 3959 [(set_attr "type" "logical") 3960 (set_attr "dot" "yes") 3961 (set_attr "length" "4,8")]) 3962 3963 3964 (define_insn "*boolc<mode>3" 3965 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3966 (match_operator:GPR 3 "boolean_operator" 3967 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")) 3968 (match_operand:GPR 1 "gpc_reg_operand" "r")]))] 3969 "" 3970 "%q3 %0,%1,%2" 3971 [(set_attr "type" "logical")]) 3972 3973 (define_insn_and_split "*boolc<mode>3_dot" 3974 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3975 (compare:CC (match_operator:GPR 3 "boolean_operator" 3976 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3977 (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) 3978 (const_int 0))) 3979 (clobber (match_scratch:GPR 0 "=r,r"))] 3980 "<MODE>mode == Pmode" 3981 "@ 3982 %q3. %0,%1,%2 3983 #" 3984 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3985 [(set (match_dup 0) 3986 (match_dup 3)) 3987 (set (match_dup 4) 3988 (compare:CC (match_dup 0) 3989 (const_int 0)))] 3990 "" 3991 [(set_attr "type" "logical") 3992 (set_attr "dot" "yes") 3993 (set_attr "length" "4,8")]) 3994 3995 (define_insn_and_split "*boolc<mode>3_dot2" 3996 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3997 (compare:CC (match_operator:GPR 3 "boolean_operator" 3998 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3999 (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) 4000 (const_int 0))) 4001 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4002 (match_dup 3))] 4003 "<MODE>mode == Pmode" 4004 "@ 4005 %q3. %0,%1,%2 4006 #" 4007 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 4008 [(set (match_dup 0) 4009 (match_dup 3)) 4010 (set (match_dup 4) 4011 (compare:CC (match_dup 0) 4012 (const_int 0)))] 4013 "" 4014 [(set_attr "type" "logical") 4015 (set_attr "dot" "yes") 4016 (set_attr "length" "4,8")]) 4017 4018 4019 (define_insn "*boolcc<mode>3" 4020 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4021 (match_operator:GPR 3 "boolean_operator" 4022 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 4023 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))] 4024 "" 4025 "%q3 %0,%1,%2" 4026 [(set_attr "type" "logical")]) 4027 4028 (define_insn_and_split "*boolcc<mode>3_dot" 4029 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 4030 (compare:CC (match_operator:GPR 3 "boolean_operator" 4031 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 4032 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) 4033 (const_int 0))) 4034 (clobber (match_scratch:GPR 0 "=r,r"))] 4035 "<MODE>mode == Pmode" 4036 "@ 4037 %q3. %0,%1,%2 4038 #" 4039 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 4040 [(set (match_dup 0) 4041 (match_dup 3)) 4042 (set (match_dup 4) 4043 (compare:CC (match_dup 0) 4044 (const_int 0)))] 4045 "" 4046 [(set_attr "type" "logical") 4047 (set_attr "dot" "yes") 4048 (set_attr "length" "4,8")]) 4049 4050 (define_insn_and_split "*boolcc<mode>3_dot2" 4051 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 4052 (compare:CC (match_operator:GPR 3 "boolean_operator" 4053 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 4054 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) 4055 (const_int 0))) 4056 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4057 (match_dup 3))] 4058 "<MODE>mode == Pmode" 4059 "@ 4060 %q3. %0,%1,%2 4061 #" 4062 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 4063 [(set (match_dup 0) 4064 (match_dup 3)) 4065 (set (match_dup 4) 4066 (compare:CC (match_dup 0) 4067 (const_int 0)))] 4068 "" 4069 [(set_attr "type" "logical") 4070 (set_attr "dot" "yes") 4071 (set_attr "length" "4,8")]) 4072 4073 4074 ;; TODO: Should have dots of this as well. 4075 (define_insn "*eqv<mode>3" 4076 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4077 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4078 (match_operand:GPR 2 "gpc_reg_operand" "r"))))] 4079 "" 4080 "eqv %0,%1,%2" 4081 [(set_attr "type" "logical")]) 4082 4084 ;; Rotate-and-mask and insert. 4085 4086 (define_insn "*rotl<mode>3_mask" 4087 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4088 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 4089 [(match_operand:GPR 1 "gpc_reg_operand" "r") 4090 (match_operand:SI 2 "reg_or_cint_operand" "rn")]) 4091 (match_operand:GPR 3 "const_int_operand" "n")))] 4092 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 4093 { 4094 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false); 4095 } 4096 [(set_attr "type" "shift") 4097 (set_attr "maybe_var_shift" "yes")]) 4098 4099 (define_insn_and_split "*rotl<mode>3_mask_dot" 4100 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") 4101 (compare:CC 4102 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 4103 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 4104 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")]) 4105 (match_operand:GPR 3 "const_int_operand" "n,n")) 4106 (const_int 0))) 4107 (clobber (match_scratch:GPR 0 "=r,r"))] 4108 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff) 4109 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 4110 { 4111 if (which_alternative == 0) 4112 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true); 4113 else 4114 return "#"; 4115 } 4116 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)" 4117 [(set (match_dup 0) 4118 (and:GPR (match_dup 4) 4119 (match_dup 3))) 4120 (set (match_dup 5) 4121 (compare:CC (match_dup 0) 4122 (const_int 0)))] 4123 "" 4124 [(set_attr "type" "shift") 4125 (set_attr "maybe_var_shift" "yes") 4126 (set_attr "dot" "yes") 4127 (set_attr "length" "4,8")]) 4128 4129 (define_insn_and_split "*rotl<mode>3_mask_dot2" 4130 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") 4131 (compare:CC 4132 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 4133 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 4134 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")]) 4135 (match_operand:GPR 3 "const_int_operand" "n,n")) 4136 (const_int 0))) 4137 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4138 (and:GPR (match_dup 4) 4139 (match_dup 3)))] 4140 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff) 4141 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 4142 { 4143 if (which_alternative == 0) 4144 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true); 4145 else 4146 return "#"; 4147 } 4148 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)" 4149 [(set (match_dup 0) 4150 (and:GPR (match_dup 4) 4151 (match_dup 3))) 4152 (set (match_dup 5) 4153 (compare:CC (match_dup 0) 4154 (const_int 0)))] 4155 "" 4156 [(set_attr "type" "shift") 4157 (set_attr "maybe_var_shift" "yes") 4158 (set_attr "dot" "yes") 4159 (set_attr "length" "4,8")]) 4160 4161 ; Special case for less-than-0. We can do it with just one machine 4162 ; instruction, but the generic optimizers do not realise it is cheap. 4163 (define_insn "*lt0_<mode>di" 4164 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4165 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r") 4166 (const_int 0)))] 4167 "TARGET_POWERPC64" 4168 "srdi %0,%1,63" 4169 [(set_attr "type" "shift")]) 4170 4171 (define_insn "*lt0_<mode>si" 4172 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4173 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r") 4174 (const_int 0)))] 4175 "" 4176 "rlwinm %0,%1,1,31,31" 4177 [(set_attr "type" "shift")]) 4178 4179 4180 4181 ; Two forms for insert (the two arms of the IOR are not canonicalized, 4182 ; both are an AND so are the same precedence). 4183 (define_insn "*rotl<mode>3_insert" 4184 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4185 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 4186 [(match_operand:GPR 1 "gpc_reg_operand" "r") 4187 (match_operand:SI 2 "const_int_operand" "n")]) 4188 (match_operand:GPR 3 "const_int_operand" "n")) 4189 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0") 4190 (match_operand:GPR 6 "const_int_operand" "n"))))] 4191 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode) 4192 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0" 4193 { 4194 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false); 4195 } 4196 [(set_attr "type" "insert")]) 4197 ; FIXME: this needs an attr "size", so that the scheduler can see the 4198 ; difference between rlwimi and rldimi. We also might want dot forms, 4199 ; but not for rlwimi on POWER4 and similar processors. 4200 4201 (define_insn "*rotl<mode>3_insert_2" 4202 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4203 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0") 4204 (match_operand:GPR 6 "const_int_operand" "n")) 4205 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 4206 [(match_operand:GPR 1 "gpc_reg_operand" "r") 4207 (match_operand:SI 2 "const_int_operand" "n")]) 4208 (match_operand:GPR 3 "const_int_operand" "n"))))] 4209 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode) 4210 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0" 4211 { 4212 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false); 4213 } 4214 [(set_attr "type" "insert")]) 4215 4216 ; There are also some forms without one of the ANDs. 4217 (define_insn "rotl<mode>3_insert_3" 4218 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4219 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 4220 (match_operand:GPR 4 "const_int_operand" "n")) 4221 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4222 (match_operand:SI 2 "const_int_operand" "n"))))] 4223 "INTVAL (operands[2]) > 0 4224 && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)" 4225 { 4226 if (<MODE>mode == SImode) 4227 return "rlwimi %0,%1,%h2,0,31-%h2"; 4228 else 4229 return "rldimi %0,%1,%H2,0"; 4230 } 4231 [(set_attr "type" "insert")]) 4232 4233 ; Canonicalize the PLUS and XOR forms to IOR for rotl<mode>3_insert_3 4234 (define_code_iterator plus_xor [plus xor]) 4235 4236 (define_insn_and_split "*rotl<mode>3_insert_3_<code>" 4237 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4238 (plus_xor:GPR 4239 (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 4240 (match_operand:GPR 4 "const_int_operand" "n")) 4241 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4242 (match_operand:SI 2 "const_int_operand" "n"))))] 4243 "INTVAL (operands[2]) > 0 4244 && INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)" 4245 "#" 4246 "&& 1" 4247 [(set (match_dup 0) 4248 (ior:GPR (and:GPR (match_dup 3) (match_dup 4)) 4249 (ashift:GPR (match_dup 1) (match_dup 2))))]) 4250 4251 (define_code_iterator plus_ior_xor [plus ior xor]) 4252 4253 (define_split 4254 [(set (match_operand:GPR 0 "gpc_reg_operand") 4255 (plus_ior_xor:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 4256 (match_operand:SI 2 "const_int_operand")) 4257 (match_operand:GPR 3 "gpc_reg_operand")))] 4258 "nonzero_bits (operands[3], <MODE>mode) 4259 < HOST_WIDE_INT_1U << INTVAL (operands[2])" 4260 [(set (match_dup 0) 4261 (ior:GPR (and:GPR (match_dup 3) 4262 (match_dup 4)) 4263 (ashift:GPR (match_dup 1) 4264 (match_dup 2))))] 4265 { 4266 operands[4] = GEN_INT ((HOST_WIDE_INT_1U << INTVAL (operands[2])) - 1); 4267 }) 4268 4269 (define_insn "*rotl<mode>3_insert_4" 4270 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4271 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 4272 (match_operand:GPR 4 "const_int_operand" "n")) 4273 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4274 (match_operand:SI 2 "const_int_operand" "n"))))] 4275 "<MODE>mode == SImode && 4276 GET_MODE_PRECISION (<MODE>mode) 4277 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))" 4278 { 4279 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode) 4280 - INTVAL (operands[2])); 4281 if (<MODE>mode == SImode) 4282 return "rlwimi %0,%1,%h2,32-%h2,31"; 4283 else 4284 return "rldimi %0,%1,%H2,64-%H2"; 4285 } 4286 [(set_attr "type" "insert")]) 4287 4288 (define_insn "*rotlsi3_insert_5" 4289 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 4290 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r") 4291 (match_operand:SI 2 "const_int_operand" "n,n")) 4292 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0") 4293 (match_operand:SI 4 "const_int_operand" "n,n"))))] 4294 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode) 4295 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0 4296 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 4297 "@ 4298 rlwimi %0,%3,0,%4 4299 rlwimi %0,%1,0,%2" 4300 [(set_attr "type" "insert")]) 4301 4302 (define_insn "*rotldi3_insert_6" 4303 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4304 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0") 4305 (match_operand:DI 2 "const_int_operand" "n")) 4306 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r") 4307 (match_operand:DI 4 "const_int_operand" "n"))))] 4308 "exact_log2 (-UINTVAL (operands[2])) > 0 4309 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 4310 { 4311 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2]))); 4312 return "rldimi %0,%3,0,%5"; 4313 } 4314 [(set_attr "type" "insert") 4315 (set_attr "size" "64")]) 4316 4317 (define_insn "*rotldi3_insert_7" 4318 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4319 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r") 4320 (match_operand:DI 4 "const_int_operand" "n")) 4321 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0") 4322 (match_operand:DI 2 "const_int_operand" "n"))))] 4323 "exact_log2 (-UINTVAL (operands[2])) > 0 4324 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 4325 { 4326 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2]))); 4327 return "rldimi %0,%3,0,%5"; 4328 } 4329 [(set_attr "type" "insert") 4330 (set_attr "size" "64")]) 4331 4332 4333 ; This handles the important case of multiple-precision shifts. There is 4334 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns. 4335 (define_split 4336 [(set (match_operand:GPR 0 "gpc_reg_operand") 4337 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 4338 (match_operand:SI 3 "const_int_operand")) 4339 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand") 4340 (match_operand:SI 4 "const_int_operand"))))] 4341 "can_create_pseudo_p () 4342 && INTVAL (operands[3]) + INTVAL (operands[4]) 4343 >= GET_MODE_PRECISION (<MODE>mode)" 4344 [(set (match_dup 5) 4345 (lshiftrt:GPR (match_dup 2) 4346 (match_dup 4))) 4347 (set (match_dup 0) 4348 (ior:GPR (and:GPR (match_dup 5) 4349 (match_dup 6)) 4350 (ashift:GPR (match_dup 1) 4351 (match_dup 3))))] 4352 { 4353 unsigned HOST_WIDE_INT mask = 1; 4354 mask = (mask << INTVAL (operands[3])) - 1; 4355 operands[5] = gen_reg_rtx (<MODE>mode); 4356 operands[6] = GEN_INT (mask); 4357 }) 4358 4359 (define_split 4360 [(set (match_operand:GPR 0 "gpc_reg_operand") 4361 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand") 4362 (match_operand:SI 4 "const_int_operand")) 4363 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 4364 (match_operand:SI 3 "const_int_operand"))))] 4365 "can_create_pseudo_p () 4366 && INTVAL (operands[3]) + INTVAL (operands[4]) 4367 >= GET_MODE_PRECISION (<MODE>mode)" 4368 [(set (match_dup 5) 4369 (lshiftrt:GPR (match_dup 2) 4370 (match_dup 4))) 4371 (set (match_dup 0) 4372 (ior:GPR (and:GPR (match_dup 5) 4373 (match_dup 6)) 4374 (ashift:GPR (match_dup 1) 4375 (match_dup 3))))] 4376 { 4377 unsigned HOST_WIDE_INT mask = 1; 4378 mask = (mask << INTVAL (operands[3])) - 1; 4379 operands[5] = gen_reg_rtx (<MODE>mode); 4380 operands[6] = GEN_INT (mask); 4381 }) 4382 4383 4384 ; Another important case is setting some bits to 1; we can do that with 4385 ; an insert instruction, in many cases. 4386 (define_insn_and_split "*ior<mode>_mask" 4387 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4388 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0") 4389 (match_operand:GPR 2 "const_int_operand" "n"))) 4390 (clobber (match_scratch:GPR 3 "=r"))] 4391 "!logical_const_operand (operands[2], <MODE>mode) 4392 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)" 4393 "#" 4394 "&& 1" 4395 [(set (match_dup 3) 4396 (const_int -1)) 4397 (set (match_dup 0) 4398 (ior:GPR (and:GPR (rotate:GPR (match_dup 3) 4399 (match_dup 4)) 4400 (match_dup 2)) 4401 (and:GPR (match_dup 1) 4402 (match_dup 5))))] 4403 { 4404 int nb, ne; 4405 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode); 4406 if (GET_CODE (operands[3]) == SCRATCH) 4407 operands[3] = gen_reg_rtx (<MODE>mode); 4408 operands[4] = GEN_INT (ne); 4409 operands[5] = GEN_INT (~UINTVAL (operands[2])); 4410 } 4411 [(set_attr "type" "two") 4412 (set_attr "length" "8")]) 4413 4414 4415 ; Yet another case is an rldimi with the second value coming from memory. 4416 ; The zero_extend that should become part of the rldimi is merged into the 4417 ; load from memory instead. Split things properly again. 4418 (define_split 4419 [(set (match_operand:DI 0 "gpc_reg_operand") 4420 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand") 4421 (match_operand:SI 2 "const_int_operand")) 4422 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))] 4423 "INTVAL (operands[2]) == <bits>" 4424 [(set (match_dup 4) 4425 (zero_extend:DI (match_dup 3))) 4426 (set (match_dup 0) 4427 (ior:DI (and:DI (match_dup 4) 4428 (match_dup 5)) 4429 (ashift:DI (match_dup 1) 4430 (match_dup 2))))] 4431 { 4432 operands[4] = gen_reg_rtx (DImode); 4433 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1); 4434 }) 4435 4436 ; rldimi with UNSPEC_SI_FROM_SF. 4437 (define_insn_and_split "*rotldi3_insert_sf" 4438 [(set (match_operand:DI 0 "gpc_reg_operand") 4439 (ior:DI 4440 (ashift:DI (match_operand:DI 1 "gpc_reg_operand") 4441 (match_operand:SI 2 "const_int_operand")) 4442 (zero_extend:DI 4443 (unspec:QHSI 4444 [(match_operand:SF 3 "memory_operand")] 4445 UNSPEC_SI_FROM_SF)))) 4446 (clobber (match_scratch:V4SF 4))] 4447 "TARGET_POWERPC64 && INTVAL (operands[2]) == <bits>" 4448 "#" 4449 "&& 1" 4450 [(parallel [(set (match_dup 5) 4451 (zero_extend:DI (unspec:QHSI [(match_dup 3)] UNSPEC_SI_FROM_SF))) 4452 (clobber (match_dup 4))]) 4453 (set (match_dup 0) 4454 (ior:DI 4455 (and:DI (match_dup 5) (match_dup 6)) 4456 (ashift:DI (match_dup 1) (match_dup 2))))] 4457 { 4458 operands[5] = gen_reg_rtx (DImode); 4459 operands[6] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1); 4460 }) 4461 4462 ; rlwimi, too. 4463 (define_split 4464 [(set (match_operand:SI 0 "gpc_reg_operand") 4465 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand") 4466 (match_operand:SI 2 "const_int_operand")) 4467 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))] 4468 "INTVAL (operands[2]) == <bits>" 4469 [(set (match_dup 4) 4470 (zero_extend:SI (match_dup 3))) 4471 (set (match_dup 0) 4472 (ior:SI (and:SI (match_dup 4) 4473 (match_dup 5)) 4474 (ashift:SI (match_dup 1) 4475 (match_dup 2))))] 4476 { 4477 operands[4] = gen_reg_rtx (SImode); 4478 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1); 4479 }) 4480 4481 4482 ;; Now the simple shifts. 4483 4484 (define_insn "rotl<mode>3" 4485 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4486 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4487 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4488 "" 4489 "rotl<wd>%I2 %0,%1,%<hH>2" 4490 [(set_attr "type" "shift") 4491 (set_attr "maybe_var_shift" "yes")]) 4492 4493 (define_insn "*rotlsi3_64" 4494 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4495 (zero_extend:DI 4496 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4497 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4498 "TARGET_POWERPC64" 4499 "rotlw%I2 %0,%1,%h2" 4500 [(set_attr "type" "shift") 4501 (set_attr "maybe_var_shift" "yes")]) 4502 4503 (define_insn_and_split "*rotl<mode>3_dot" 4504 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4505 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4506 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4507 (const_int 0))) 4508 (clobber (match_scratch:GPR 0 "=r,r"))] 4509 "<MODE>mode == Pmode" 4510 "@ 4511 rotl<wd>%I2. %0,%1,%<hH>2 4512 #" 4513 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4514 [(set (match_dup 0) 4515 (rotate:GPR (match_dup 1) 4516 (match_dup 2))) 4517 (set (match_dup 3) 4518 (compare:CC (match_dup 0) 4519 (const_int 0)))] 4520 "" 4521 [(set_attr "type" "shift") 4522 (set_attr "maybe_var_shift" "yes") 4523 (set_attr "dot" "yes") 4524 (set_attr "length" "4,8")]) 4525 4526 (define_insn_and_split "*rotl<mode>3_dot2" 4527 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4528 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4529 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4530 (const_int 0))) 4531 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4532 (rotate:GPR (match_dup 1) 4533 (match_dup 2)))] 4534 "<MODE>mode == Pmode" 4535 "@ 4536 rotl<wd>%I2. %0,%1,%<hH>2 4537 #" 4538 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4539 [(set (match_dup 0) 4540 (rotate:GPR (match_dup 1) 4541 (match_dup 2))) 4542 (set (match_dup 3) 4543 (compare:CC (match_dup 0) 4544 (const_int 0)))] 4545 "" 4546 [(set_attr "type" "shift") 4547 (set_attr "maybe_var_shift" "yes") 4548 (set_attr "dot" "yes") 4549 (set_attr "length" "4,8")]) 4550 4551 4552 (define_insn "ashl<mode>3" 4553 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4554 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4555 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4556 "" 4557 "sl<wd>%I2 %0,%1,%<hH>2" 4558 [(set_attr "type" "shift") 4559 (set_attr "maybe_var_shift" "yes")]) 4560 4561 (define_insn "*ashlsi3_64" 4562 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4563 (zero_extend:DI 4564 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4565 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4566 "TARGET_POWERPC64" 4567 "slw%I2 %0,%1,%h2" 4568 [(set_attr "type" "shift") 4569 (set_attr "maybe_var_shift" "yes")]) 4570 4571 (define_insn_and_split "*ashl<mode>3_dot" 4572 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4573 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4574 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4575 (const_int 0))) 4576 (clobber (match_scratch:GPR 0 "=r,r"))] 4577 "<MODE>mode == Pmode" 4578 "@ 4579 sl<wd>%I2. %0,%1,%<hH>2 4580 #" 4581 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4582 [(set (match_dup 0) 4583 (ashift:GPR (match_dup 1) 4584 (match_dup 2))) 4585 (set (match_dup 3) 4586 (compare:CC (match_dup 0) 4587 (const_int 0)))] 4588 "" 4589 [(set_attr "type" "shift") 4590 (set_attr "maybe_var_shift" "yes") 4591 (set_attr "dot" "yes") 4592 (set_attr "length" "4,8")]) 4593 4594 (define_insn_and_split "*ashl<mode>3_dot2" 4595 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4596 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4597 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4598 (const_int 0))) 4599 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4600 (ashift:GPR (match_dup 1) 4601 (match_dup 2)))] 4602 "<MODE>mode == Pmode" 4603 "@ 4604 sl<wd>%I2. %0,%1,%<hH>2 4605 #" 4606 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4607 [(set (match_dup 0) 4608 (ashift:GPR (match_dup 1) 4609 (match_dup 2))) 4610 (set (match_dup 3) 4611 (compare:CC (match_dup 0) 4612 (const_int 0)))] 4613 "" 4614 [(set_attr "type" "shift") 4615 (set_attr "maybe_var_shift" "yes") 4616 (set_attr "dot" "yes") 4617 (set_attr "length" "4,8")]) 4618 4619 ;; Pretend we have a memory form of extswsli until register allocation is done 4620 ;; so that we use LWZ to load the value from memory, instead of LWA. 4621 (define_insn_and_split "ashdi3_extswsli" 4622 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 4623 (ashift:DI 4624 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m")) 4625 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))] 4626 "TARGET_EXTSWSLI" 4627 "@ 4628 extswsli %0,%1,%2 4629 #" 4630 "&& reload_completed && MEM_P (operands[1])" 4631 [(set (match_dup 3) 4632 (match_dup 1)) 4633 (set (match_dup 0) 4634 (ashift:DI (sign_extend:DI (match_dup 3)) 4635 (match_dup 2)))] 4636 { 4637 operands[3] = gen_lowpart (SImode, operands[0]); 4638 } 4639 [(set_attr "type" "shift") 4640 (set_attr "maybe_var_shift" "no")]) 4641 4642 4643 (define_insn_and_split "ashdi3_extswsli_dot" 4644 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y") 4645 (compare:CC 4646 (ashift:DI 4647 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m")) 4648 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n")) 4649 (const_int 0))) 4650 (clobber (match_scratch:DI 0 "=r,r,r,r"))] 4651 "TARGET_EXTSWSLI" 4652 "@ 4653 extswsli. %0,%1,%2 4654 # 4655 # 4656 #" 4657 "&& reload_completed 4658 && (cc_reg_not_cr0_operand (operands[3], CCmode) 4659 || memory_operand (operands[1], SImode))" 4660 [(pc)] 4661 { 4662 rtx dest = operands[0]; 4663 rtx src = operands[1]; 4664 rtx shift = operands[2]; 4665 rtx cr = operands[3]; 4666 rtx src2; 4667 4668 if (!MEM_P (src)) 4669 src2 = src; 4670 else 4671 { 4672 src2 = gen_lowpart (SImode, dest); 4673 emit_move_insn (src2, src); 4674 } 4675 4676 if (REGNO (cr) == CR0_REGNO) 4677 { 4678 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr)); 4679 DONE; 4680 } 4681 4682 emit_insn (gen_ashdi3_extswsli (dest, src2, shift)); 4683 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx))); 4684 DONE; 4685 } 4686 [(set_attr "type" "shift") 4687 (set_attr "maybe_var_shift" "no") 4688 (set_attr "dot" "yes") 4689 (set_attr "length" "4,8,8,12")]) 4690 4691 (define_insn_and_split "ashdi3_extswsli_dot2" 4692 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y") 4693 (compare:CC 4694 (ashift:DI 4695 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m")) 4696 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n")) 4697 (const_int 0))) 4698 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") 4699 (ashift:DI (sign_extend:DI (match_dup 1)) 4700 (match_dup 2)))] 4701 "TARGET_EXTSWSLI" 4702 "@ 4703 extswsli. %0,%1,%2 4704 # 4705 # 4706 #" 4707 "&& reload_completed 4708 && (cc_reg_not_cr0_operand (operands[3], CCmode) 4709 || memory_operand (operands[1], SImode))" 4710 [(pc)] 4711 { 4712 rtx dest = operands[0]; 4713 rtx src = operands[1]; 4714 rtx shift = operands[2]; 4715 rtx cr = operands[3]; 4716 rtx src2; 4717 4718 if (!MEM_P (src)) 4719 src2 = src; 4720 else 4721 { 4722 src2 = gen_lowpart (SImode, dest); 4723 emit_move_insn (src2, src); 4724 } 4725 4726 if (REGNO (cr) == CR0_REGNO) 4727 { 4728 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr)); 4729 DONE; 4730 } 4731 4732 emit_insn (gen_ashdi3_extswsli (dest, src2, shift)); 4733 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx))); 4734 DONE; 4735 } 4736 [(set_attr "type" "shift") 4737 (set_attr "maybe_var_shift" "no") 4738 (set_attr "dot" "yes") 4739 (set_attr "length" "4,8,8,12")]) 4740 4741 (define_insn "lshr<mode>3" 4742 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4743 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4744 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4745 "" 4746 "sr<wd>%I2 %0,%1,%<hH>2" 4747 [(set_attr "type" "shift") 4748 (set_attr "maybe_var_shift" "yes")]) 4749 4750 (define_insn "*lshrsi3_64" 4751 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4752 (zero_extend:DI 4753 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4754 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4755 "TARGET_POWERPC64" 4756 "srw%I2 %0,%1,%h2" 4757 [(set_attr "type" "shift") 4758 (set_attr "maybe_var_shift" "yes")]) 4759 4760 (define_insn_and_split "*lshr<mode>3_dot" 4761 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4762 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4763 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4764 (const_int 0))) 4765 (clobber (match_scratch:GPR 0 "=r,r"))] 4766 "<MODE>mode == Pmode" 4767 "@ 4768 sr<wd>%I2. %0,%1,%<hH>2 4769 #" 4770 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4771 [(set (match_dup 0) 4772 (lshiftrt:GPR (match_dup 1) 4773 (match_dup 2))) 4774 (set (match_dup 3) 4775 (compare:CC (match_dup 0) 4776 (const_int 0)))] 4777 "" 4778 [(set_attr "type" "shift") 4779 (set_attr "maybe_var_shift" "yes") 4780 (set_attr "dot" "yes") 4781 (set_attr "length" "4,8")]) 4782 4783 (define_insn_and_split "*lshr<mode>3_dot2" 4784 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4785 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4786 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4787 (const_int 0))) 4788 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4789 (lshiftrt:GPR (match_dup 1) 4790 (match_dup 2)))] 4791 "<MODE>mode == Pmode" 4792 "@ 4793 sr<wd>%I2. %0,%1,%<hH>2 4794 #" 4795 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4796 [(set (match_dup 0) 4797 (lshiftrt:GPR (match_dup 1) 4798 (match_dup 2))) 4799 (set (match_dup 3) 4800 (compare:CC (match_dup 0) 4801 (const_int 0)))] 4802 "" 4803 [(set_attr "type" "shift") 4804 (set_attr "maybe_var_shift" "yes") 4805 (set_attr "dot" "yes") 4806 (set_attr "length" "4,8")]) 4807 4808 4809 (define_insn "ashr<mode>3" 4810 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4811 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4812 (match_operand:SI 2 "reg_or_cint_operand" "rn"))) 4813 (clobber (reg:GPR CA_REGNO))] 4814 "" 4815 "sra<wd>%I2 %0,%1,%<hH>2" 4816 [(set_attr "type" "shift") 4817 (set_attr "maybe_var_shift" "yes")]) 4818 4819 (define_insn "*ashrsi3_64" 4820 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4821 (sign_extend:DI 4822 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4823 (match_operand:SI 2 "reg_or_cint_operand" "rn")))) 4824 (clobber (reg:SI CA_REGNO))] 4825 "TARGET_POWERPC64" 4826 "sraw%I2 %0,%1,%h2" 4827 [(set_attr "type" "shift") 4828 (set_attr "maybe_var_shift" "yes")]) 4829 4830 (define_insn_and_split "*ashr<mode>3_dot" 4831 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4832 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4833 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4834 (const_int 0))) 4835 (clobber (match_scratch:GPR 0 "=r,r")) 4836 (clobber (reg:GPR CA_REGNO))] 4837 "<MODE>mode == Pmode" 4838 "@ 4839 sra<wd>%I2. %0,%1,%<hH>2 4840 #" 4841 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4842 [(parallel [(set (match_dup 0) 4843 (ashiftrt:GPR (match_dup 1) 4844 (match_dup 2))) 4845 (clobber (reg:GPR CA_REGNO))]) 4846 (set (match_dup 3) 4847 (compare:CC (match_dup 0) 4848 (const_int 0)))] 4849 "" 4850 [(set_attr "type" "shift") 4851 (set_attr "maybe_var_shift" "yes") 4852 (set_attr "dot" "yes") 4853 (set_attr "length" "4,8")]) 4854 4855 (define_insn_and_split "*ashr<mode>3_dot2" 4856 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4857 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4858 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4859 (const_int 0))) 4860 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4861 (ashiftrt:GPR (match_dup 1) 4862 (match_dup 2))) 4863 (clobber (reg:GPR CA_REGNO))] 4864 "<MODE>mode == Pmode" 4865 "@ 4866 sra<wd>%I2. %0,%1,%<hH>2 4867 #" 4868 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4869 [(parallel [(set (match_dup 0) 4870 (ashiftrt:GPR (match_dup 1) 4871 (match_dup 2))) 4872 (clobber (reg:GPR CA_REGNO))]) 4873 (set (match_dup 3) 4874 (compare:CC (match_dup 0) 4875 (const_int 0)))] 4876 "" 4877 [(set_attr "type" "shift") 4878 (set_attr "maybe_var_shift" "yes") 4879 (set_attr "dot" "yes") 4880 (set_attr "length" "4,8")]) 4881 4883 ;; Builtins to replace a division to generate FRE reciprocal estimate 4884 ;; instructions and the necessary fixup instructions 4885 (define_expand "recip<mode>3" 4886 [(match_operand:RECIPF 0 "gpc_reg_operand") 4887 (match_operand:RECIPF 1 "gpc_reg_operand") 4888 (match_operand:RECIPF 2 "gpc_reg_operand")] 4889 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)" 4890 { 4891 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false); 4892 DONE; 4893 }) 4894 4895 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal 4896 ;; hardware division. This is only done before register allocation and with 4897 ;; -ffast-math. This must appear before the divsf3/divdf3 insns. 4898 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed 4899 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed. 4900 (define_split 4901 [(set (match_operand:RECIPF 0 "gpc_reg_operand") 4902 (div:RECIPF (match_operand 1 "gpc_reg_operand") 4903 (match_operand 2 "gpc_reg_operand")))] 4904 "RS6000_RECIP_AUTO_RE_P (<MODE>mode) 4905 && can_create_pseudo_p () && flag_finite_math_only 4906 && !flag_trapping_math && flag_reciprocal_math" 4907 [(const_int 0)] 4908 { 4909 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); 4910 DONE; 4911 }) 4912 4913 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the 4914 ;; appropriate fixup. 4915 (define_expand "rsqrt<mode>2" 4916 [(match_operand:RECIPF 0 "gpc_reg_operand") 4917 (match_operand:RECIPF 1 "gpc_reg_operand")] 4918 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 4919 { 4920 rs6000_emit_swsqrt (operands[0], operands[1], 1); 4921 DONE; 4922 }) 4923 4925 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF 4926 ;; modes here, and also add in conditional vsx/power8-vector support to access 4927 ;; values in the traditional Altivec registers if the appropriate 4928 ;; -mupper-regs-{df,sf} option is enabled. 4929 4930 (define_expand "abs<mode>2" 4931 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4932 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] 4933 "TARGET_HARD_FLOAT" 4934 "") 4935 4936 (define_insn "*abs<mode>2_fpr" 4937 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4938 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 4939 "TARGET_HARD_FLOAT" 4940 "@ 4941 fabs %0,%1 4942 xsabsdp %x0,%x1" 4943 [(set_attr "type" "fpsimple")]) 4944 4945 (define_insn "*nabs<mode>2_fpr" 4946 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4947 (neg:SFDF 4948 (abs:SFDF 4949 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))] 4950 "TARGET_HARD_FLOAT" 4951 "@ 4952 fnabs %0,%1 4953 xsnabsdp %x0,%x1" 4954 [(set_attr "type" "fpsimple")]) 4955 4956 (define_expand "neg<mode>2" 4957 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4958 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] 4959 "TARGET_HARD_FLOAT" 4960 "") 4961 4962 (define_insn "*neg<mode>2_fpr" 4963 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4964 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 4965 "TARGET_HARD_FLOAT" 4966 "@ 4967 fneg %0,%1 4968 xsnegdp %x0,%x1" 4969 [(set_attr "type" "fpsimple")]) 4970 4971 (define_expand "add<mode>3" 4972 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4973 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4974 (match_operand:SFDF 2 "gpc_reg_operand")))] 4975 "TARGET_HARD_FLOAT" 4976 "") 4977 4978 (define_insn "*add<mode>3_fpr" 4979 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 4980 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa") 4981 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 4982 "TARGET_HARD_FLOAT" 4983 "@ 4984 fadd<s> %0,%1,%2 4985 xsadd<sd>p %x0,%x1,%x2" 4986 [(set_attr "type" "fp") 4987 (set_attr "isa" "*,<Fisa>")]) 4988 4989 (define_expand "sub<mode>3" 4990 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4991 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4992 (match_operand:SFDF 2 "gpc_reg_operand")))] 4993 "TARGET_HARD_FLOAT" 4994 "") 4995 4996 (define_insn "*sub<mode>3_fpr" 4997 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 4998 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa") 4999 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 5000 "TARGET_HARD_FLOAT" 5001 "@ 5002 fsub<s> %0,%1,%2 5003 xssub<sd>p %x0,%x1,%x2" 5004 [(set_attr "type" "fp") 5005 (set_attr "isa" "*,<Fisa>")]) 5006 5007 (define_expand "mul<mode>3" 5008 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5009 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 5010 (match_operand:SFDF 2 "gpc_reg_operand")))] 5011 "TARGET_HARD_FLOAT" 5012 "") 5013 5014 (define_insn "*mul<mode>3_fpr" 5015 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 5016 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa") 5017 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 5018 "TARGET_HARD_FLOAT" 5019 "@ 5020 fmul<s> %0,%1,%2 5021 xsmul<sd>p %x0,%x1,%x2" 5022 [(set_attr "type" "dmul") 5023 (set_attr "isa" "*,<Fisa>")]) 5024 5025 (define_expand "div<mode>3" 5026 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5027 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 5028 (match_operand:SFDF 2 "gpc_reg_operand")))] 5029 "TARGET_HARD_FLOAT" 5030 { 5031 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode) 5032 && can_create_pseudo_p () && flag_finite_math_only 5033 && !flag_trapping_math && flag_reciprocal_math) 5034 { 5035 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); 5036 DONE; 5037 } 5038 }) 5039 5040 (define_insn "*div<mode>3_fpr" 5041 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 5042 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa") 5043 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 5044 "TARGET_HARD_FLOAT" 5045 "@ 5046 fdiv<s> %0,%1,%2 5047 xsdiv<sd>p %x0,%x1,%x2" 5048 [(set_attr "type" "<sd>div") 5049 (set_attr "isa" "*,<Fisa>")]) 5050 5051 (define_insn "*sqrt<mode>2_internal" 5052 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 5053 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))] 5054 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT" 5055 "@ 5056 fsqrt<s> %0,%1 5057 xssqrt<sd>p %x0,%x1" 5058 [(set_attr "type" "<sd>sqrt") 5059 (set_attr "isa" "*,<Fisa>")]) 5060 5061 (define_expand "sqrt<mode>2" 5062 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5063 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] 5064 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT" 5065 { 5066 if (<MODE>mode == SFmode 5067 && TARGET_RECIP_PRECISION 5068 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode) 5069 && !optimize_function_for_size_p (cfun) 5070 && flag_finite_math_only && !flag_trapping_math 5071 && flag_unsafe_math_optimizations) 5072 { 5073 rs6000_emit_swsqrt (operands[0], operands[1], 0); 5074 DONE; 5075 } 5076 }) 5077 5078 ;; Floating point reciprocal approximation 5079 (define_insn "fre<sd>" 5080 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 5081 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")] 5082 UNSPEC_FRES))] 5083 "TARGET_<FFRE>" 5084 "@ 5085 fre<s> %0,%1 5086 xsre<sd>p %x0,%x1" 5087 [(set_attr "type" "fp") 5088 (set_attr "isa" "*,<Fisa>")]) 5089 5090 (define_expand "fmod<mode>3" 5091 [(use (match_operand:SFDF 0 "gpc_reg_operand")) 5092 (use (match_operand:SFDF 1 "gpc_reg_operand")) 5093 (use (match_operand:SFDF 2 "gpc_reg_operand"))] 5094 "TARGET_HARD_FLOAT 5095 && TARGET_FPRND 5096 && flag_unsafe_math_optimizations" 5097 { 5098 rtx div = gen_reg_rtx (<MODE>mode); 5099 emit_insn (gen_div<mode>3 (div, operands[1], operands[2])); 5100 5101 rtx friz = gen_reg_rtx (<MODE>mode); 5102 emit_insn (gen_btrunc<mode>2 (friz, div)); 5103 5104 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], friz, operands[1])); 5105 DONE; 5106 }) 5107 5108 (define_expand "remainder<mode>3" 5109 [(use (match_operand:SFDF 0 "gpc_reg_operand")) 5110 (use (match_operand:SFDF 1 "gpc_reg_operand")) 5111 (use (match_operand:SFDF 2 "gpc_reg_operand"))] 5112 "TARGET_HARD_FLOAT 5113 && TARGET_FPRND 5114 && flag_unsafe_math_optimizations" 5115 { 5116 rtx div = gen_reg_rtx (<MODE>mode); 5117 emit_insn (gen_div<mode>3 (div, operands[1], operands[2])); 5118 5119 rtx frin = gen_reg_rtx (<MODE>mode); 5120 emit_insn (gen_round<mode>2 (frin, div)); 5121 5122 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], frin, operands[1])); 5123 DONE; 5124 }) 5125 5126 (define_insn "*rsqrt<mode>2" 5127 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 5128 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")] 5129 UNSPEC_RSQRT))] 5130 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 5131 "@ 5132 frsqrte<s> %0,%1 5133 xsrsqrte<sd>p %x0,%x1" 5134 [(set_attr "type" "fp") 5135 (set_attr "isa" "*,<Fisa>")]) 5136 5137 ;; Floating point comparisons 5138 (define_insn "*cmp<mode>_fpr" 5139 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y") 5140 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa") 5141 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 5142 "TARGET_HARD_FLOAT" 5143 "@ 5144 fcmpu %0,%1,%2 5145 xscmpudp %0,%x1,%x2" 5146 [(set_attr "type" "fpcompare") 5147 (set_attr "isa" "*,<Fisa>")]) 5148 5149 ;; Floating point conversions 5150 (define_expand "extendsfdf2" 5151 [(set (match_operand:DF 0 "gpc_reg_operand") 5152 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))] 5153 "TARGET_HARD_FLOAT" 5154 { 5155 if (HONOR_SNANS (SFmode)) 5156 operands[1] = force_reg (SFmode, operands[1]); 5157 }) 5158 5159 (define_insn_and_split "*extendsfdf2_fpr" 5160 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v") 5161 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))] 5162 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)" 5163 "@ 5164 # 5165 fmr %0,%1 5166 lfs%U1%X1 %0,%1 5167 # 5168 xscpsgndp %x0,%x1,%x1 5169 lxsspx %x0,%y1 5170 lxssp %0,%1" 5171 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])" 5172 [(const_int 0)] 5173 { 5174 emit_note (NOTE_INSN_DELETED); 5175 DONE; 5176 } 5177 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload") 5178 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")]) 5179 5180 (define_insn "*extendsfdf2_snan" 5181 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 5182 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))] 5183 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)" 5184 "@ 5185 frsp %0,%1 5186 xsrsp %x0,%x1" 5187 [(set_attr "type" "fp") 5188 (set_attr "isa" "*,p8v")]) 5189 5190 (define_expand "truncdfsf2" 5191 [(set (match_operand:SF 0 "gpc_reg_operand") 5192 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))] 5193 "TARGET_HARD_FLOAT" 5194 "") 5195 5196 (define_insn "*truncdfsf2_fpr" 5197 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa") 5198 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))] 5199 "TARGET_HARD_FLOAT" 5200 "@ 5201 frsp %0,%1 5202 xsrsp %x0,%x1" 5203 [(set_attr "type" "fp") 5204 (set_attr "isa" "*,p8v")]) 5205 5206 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in 5207 ;; builtins.cc and optabs.cc that are not correct for IBM long double 5208 ;; when little-endian. 5209 (define_expand "signbit<mode>2" 5210 [(set (match_dup 2) 5211 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand"))) 5212 (set (match_dup 3) 5213 (subreg:DI (match_dup 2) 0)) 5214 (set (match_dup 4) 5215 (match_dup 5)) 5216 (set (match_operand:SI 0 "gpc_reg_operand") 5217 (match_dup 6))] 5218 "TARGET_HARD_FLOAT 5219 && (!FLOAT128_IEEE_P (<MODE>mode) 5220 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))" 5221 { 5222 if (FLOAT128_IEEE_P (<MODE>mode)) 5223 { 5224 rtx dest = operands[0]; 5225 rtx src = operands[1]; 5226 rtx tmp = gen_reg_rtx (DImode); 5227 rtx dest_di = gen_lowpart (DImode, dest); 5228 5229 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src)); 5230 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63))); 5231 DONE; 5232 } 5233 operands[2] = gen_reg_rtx (DFmode); 5234 operands[3] = gen_reg_rtx (DImode); 5235 if (TARGET_POWERPC64) 5236 { 5237 operands[4] = gen_reg_rtx (DImode); 5238 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63)); 5239 operands[6] = gen_rtx_SUBREG (SImode, operands[4], 5240 WORDS_BIG_ENDIAN ? 4 : 0); 5241 } 5242 else 5243 { 5244 operands[4] = gen_reg_rtx (SImode); 5245 operands[5] = gen_rtx_SUBREG (SImode, operands[3], 5246 WORDS_BIG_ENDIAN ? 0 : 4); 5247 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31)); 5248 } 5249 }) 5250 5251 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid 5252 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the 5253 ;; register allocator would typically move the entire _Float128 item to GPRs (2 5254 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07). 5255 ;; 5256 ;; After register allocation, if the _Float128 had originally been in GPRs, the 5257 ;; split allows the post reload phases to eliminate the move, and do the shift 5258 ;; directly with the register that contains the signbit. 5259 (define_insn_and_split "@signbit<mode>2_dm" 5260 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 5261 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")] 5262 UNSPEC_SIGNBIT))] 5263 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 5264 "@ 5265 mfvsrd %0,%x1 5266 #" 5267 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)" 5268 [(set (match_dup 0) 5269 (match_dup 2))] 5270 { 5271 operands[2] = gen_highpart (DImode, operands[1]); 5272 } 5273 [(set_attr "type" "mfvsr,*")]) 5274 5275 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector 5276 ;; register and then doing a direct move if the value comes from memory. On 5277 ;; little endian, we have to load the 2nd double-word to get the sign bit. 5278 (define_insn_and_split "*signbit<mode>2_dm_mem" 5279 [(set (match_operand:DI 0 "gpc_reg_operand" "=b") 5280 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")] 5281 UNSPEC_SIGNBIT))] 5282 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 5283 "#" 5284 "&& 1" 5285 [(set (match_dup 0) 5286 (match_dup 2))] 5287 { 5288 rtx dest = operands[0]; 5289 rtx src = operands[1]; 5290 rtx addr = XEXP (src, 0); 5291 5292 if (WORDS_BIG_ENDIAN) 5293 operands[2] = adjust_address (src, DImode, 0); 5294 5295 else if (REG_P (addr) || SUBREG_P (addr)) 5296 operands[2] = adjust_address (src, DImode, 8); 5297 5298 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0)) 5299 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode)) 5300 operands[2] = adjust_address (src, DImode, 8); 5301 5302 else 5303 { 5304 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest; 5305 emit_insn (gen_rtx_SET (tmp, addr)); 5306 operands[2] = change_address (src, DImode, 5307 gen_rtx_PLUS (DImode, tmp, GEN_INT (8))); 5308 } 5309 }) 5310 5311 (define_expand "copysign<mode>3" 5312 [(set (match_dup 3) 5313 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand"))) 5314 (set (match_dup 4) 5315 (neg:SFDF (abs:SFDF (match_dup 1)))) 5316 (set (match_operand:SFDF 0 "gpc_reg_operand") 5317 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand") 5318 (match_dup 5)) 5319 (match_dup 3) 5320 (match_dup 4)))] 5321 "TARGET_HARD_FLOAT 5322 && ((TARGET_PPC_GFXOPT 5323 && !HONOR_NANS (<MODE>mode) 5324 && !HONOR_SIGNED_ZEROS (<MODE>mode)) 5325 || TARGET_CMPB 5326 || VECTOR_UNIT_VSX_P (<MODE>mode))" 5327 { 5328 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode)) 5329 { 5330 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1], 5331 operands[2])); 5332 DONE; 5333 } 5334 5335 operands[3] = gen_reg_rtx (<MODE>mode); 5336 operands[4] = gen_reg_rtx (<MODE>mode); 5337 operands[5] = CONST0_RTX (<MODE>mode); 5338 }) 5339 5340 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the 5341 ;; compiler from optimizing -0.0 5342 (define_insn "copysign<mode>3_fcpsgn" 5343 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5344 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") 5345 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")] 5346 UNSPEC_COPYSIGN))] 5347 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))" 5348 "@ 5349 fcpsgn %0,%2,%1 5350 xscpsgndp %x0,%x2,%x1" 5351 [(set_attr "type" "fpsimple")]) 5352 5353 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a 5354 ;; fsel instruction and some auxiliary computations. Then we just have a 5355 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by 5356 ;; combine. 5357 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we 5358 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary 5359 ;; computations. Then we just have a single DEFINE_INSN for fsel and the 5360 ;; define_splits to make them if made by combine. On VSX machines we have the 5361 ;; min/max instructions. 5362 ;; 5363 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector 5364 ;; to allow either DF/SF to use only traditional registers. 5365 5366 (define_expand "s<minmax><mode>3" 5367 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5368 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 5369 (match_operand:SFDF 2 "gpc_reg_operand")))] 5370 "TARGET_MINMAX" 5371 { 5372 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 5373 DONE; 5374 }) 5375 5376 (define_insn "*s<minmax><mode>3_vsx" 5377 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 5378 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>") 5379 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))] 5380 "TARGET_VSX && TARGET_HARD_FLOAT" 5381 { 5382 return (TARGET_P9_MINMAX 5383 ? "xs<minmax>cdp %x0,%x1,%x2" 5384 : "xs<minmax>dp %x0,%x1,%x2"); 5385 } 5386 [(set_attr "type" "fp")]) 5387 5388 ;; Min/max for ISA 3.1 IEEE 128-bit floating point 5389 (define_insn "s<minmax><mode>3" 5390 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 5391 (fp_minmax:IEEE128 5392 (match_operand:IEEE128 1 "altivec_register_operand" "v") 5393 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 5394 "TARGET_POWER10 && TARGET_FLOAT128_HW" 5395 "xs<minmax>cqp %0,%1,%2" 5396 [(set_attr "type" "vecfloat") 5397 (set_attr "size" "128")]) 5398 5399 ;; The conditional move instructions allow us to perform max and min operations 5400 ;; even when we don't have the appropriate max/min instruction using the FSEL 5401 ;; instruction. 5402 5403 (define_insn_and_split "*s<minmax><mode>3_fpr" 5404 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5405 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 5406 (match_operand:SFDF 2 "gpc_reg_operand")))] 5407 "!TARGET_VSX && TARGET_MINMAX" 5408 "#" 5409 "&& 1" 5410 [(const_int 0)] 5411 { 5412 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 5413 DONE; 5414 }) 5415 5416 (define_expand "mov<mode>cc" 5417 [(set (match_operand:GPR 0 "gpc_reg_operand") 5418 (if_then_else:GPR (match_operand 1 "comparison_operator") 5419 (match_operand:GPR 2 "gpc_reg_operand") 5420 (match_operand:GPR 3 "gpc_reg_operand")))] 5421 "TARGET_ISEL" 5422 { 5423 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 5424 DONE; 5425 else 5426 FAIL; 5427 }) 5428 5429 ;; We use the BASE_REGS for the isel input operands because, if rA is 5430 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB 5431 ;; because we may switch the operands and rB may end up being rA. 5432 ;; 5433 ;; We need 2 patterns: an unsigned and a signed pattern. We could 5434 ;; leave out the mode in operand 4 and use one pattern, but reload can 5435 ;; change the mode underneath our feet and then gets confused trying 5436 ;; to reload the value. 5437 (define_mode_iterator CCEITHER [CC CCUNS]) 5438 (define_mode_attr un [(CC "") (CCUNS "un")]) 5439 (define_insn "isel_<un>signed_<GPR:mode>" 5440 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 5441 (if_then_else:GPR 5442 (match_operator 1 "scc_comparison_operator" 5443 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y") 5444 (const_int 0)]) 5445 (match_operand:GPR 2 "reg_or_zero_operand" "O,b") 5446 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] 5447 "TARGET_ISEL" 5448 "isel %0,%2,%3,%j1" 5449 [(set_attr "type" "isel")]) 5450 5451 ;; These patterns can be useful for combine; they let combine know that 5452 ;; isel can handle reversed comparisons so long as the operands are 5453 ;; registers. 5454 5455 (define_insn "*isel_reversed_<un>signed_<GPR:mode>" 5456 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 5457 (if_then_else:GPR 5458 (match_operator 1 "scc_rev_comparison_operator" 5459 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y") 5460 (const_int 0)]) 5461 (match_operand:GPR 2 "gpc_reg_operand" "r,r") 5462 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))] 5463 "TARGET_ISEL" 5464 { 5465 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1]))); 5466 return "isel %0,%3,%2,%j1"; 5467 } 5468 [(set_attr "type" "isel")]) 5469 5470 ; Set Boolean Condition (Reverse) 5471 (define_insn "setbc_<un>signed_<GPR:mode>" 5472 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 5473 (match_operator:GPR 1 "scc_comparison_operator" 5474 [(match_operand:CCEITHER 2 "cc_reg_operand" "y") 5475 (const_int 0)]))] 5476 "TARGET_POWER10" 5477 "setbc %0,%j1" 5478 [(set_attr "type" "isel")]) 5479 5480 (define_insn "*setbcr_<un>signed_<GPR:mode>" 5481 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 5482 (match_operator:GPR 1 "scc_rev_comparison_operator" 5483 [(match_operand:CCEITHER 2 "cc_reg_operand" "y") 5484 (const_int 0)]))] 5485 "TARGET_POWER10" 5486 "setbcr %0,%j1" 5487 [(set_attr "type" "isel")]) 5488 5489 ; Set Negative Boolean Condition (Reverse) 5490 (define_insn "*setnbc_<un>signed_<GPR:mode>" 5491 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 5492 (neg:GPR (match_operator:GPR 1 "scc_comparison_operator" 5493 [(match_operand:CCEITHER 2 "cc_reg_operand" "y") 5494 (const_int 0)])))] 5495 "TARGET_POWER10" 5496 "setnbc %0,%j1" 5497 [(set_attr "type" "isel")]) 5498 5499 (define_insn "*setnbcr_<un>signed_<GPR:mode>" 5500 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 5501 (neg:GPR (match_operator:GPR 1 "scc_rev_comparison_operator" 5502 [(match_operand:CCEITHER 2 "cc_reg_operand" "y") 5503 (const_int 0)])))] 5504 "TARGET_POWER10" 5505 "setnbcr %0,%j1" 5506 [(set_attr "type" "isel")]) 5507 5508 ;; Floating point conditional move 5509 (define_expand "mov<mode>cc" 5510 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5511 (if_then_else:SFDF (match_operand 1 "comparison_operator") 5512 (match_operand:SFDF 2 "gpc_reg_operand") 5513 (match_operand:SFDF 3 "gpc_reg_operand")))] 5514 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT" 5515 { 5516 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 5517 DONE; 5518 else 5519 FAIL; 5520 }) 5521 5522 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4" 5523 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>") 5524 (if_then_else:SFDF 5525 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>") 5526 (match_operand:SFDF2 4 "zero_fp_constant" "F")) 5527 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>") 5528 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))] 5529 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT" 5530 "fsel %0,%1,%2,%3" 5531 [(set_attr "type" "fp")]) 5532 5533 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9" 5534 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 5535 (if_then_else:SFDF 5536 (match_operator:CCFP 1 "fpmask_comparison_operator" 5537 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 5538 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 5539 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 5540 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5541 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 5542 "TARGET_P9_MINMAX" 5543 "#" 5544 "&& 1" 5545 [(set (match_dup 6) 5546 (if_then_else:V2DI (match_dup 1) 5547 (match_dup 7) 5548 (match_dup 8))) 5549 (set (match_dup 0) 5550 (if_then_else:SFDF (ne (match_dup 6) 5551 (match_dup 8)) 5552 (match_dup 4) 5553 (match_dup 5)))] 5554 { 5555 if (GET_CODE (operands[6]) == SCRATCH) 5556 operands[6] = gen_reg_rtx (V2DImode); 5557 5558 operands[7] = CONSTM1_RTX (V2DImode); 5559 operands[8] = CONST0_RTX (V2DImode); 5560 } 5561 [(set_attr "length" "8") 5562 (set_attr "type" "vecperm")]) 5563 5564 ;; Handle inverting the fpmask comparisons. 5565 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9" 5566 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 5567 (if_then_else:SFDF 5568 (match_operator:CCFP 1 "invert_fpmask_comparison_operator" 5569 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 5570 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 5571 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 5572 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5573 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 5574 "TARGET_P9_MINMAX" 5575 "#" 5576 "&& 1" 5577 [(set (match_dup 6) 5578 (if_then_else:V2DI (match_dup 9) 5579 (match_dup 7) 5580 (match_dup 8))) 5581 (set (match_dup 0) 5582 (if_then_else:SFDF (ne (match_dup 6) 5583 (match_dup 8)) 5584 (match_dup 5) 5585 (match_dup 4)))] 5586 { 5587 rtx op1 = operands[1]; 5588 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1)); 5589 5590 if (GET_CODE (operands[6]) == SCRATCH) 5591 operands[6] = gen_reg_rtx (V2DImode); 5592 5593 operands[7] = CONSTM1_RTX (V2DImode); 5594 operands[8] = CONST0_RTX (V2DImode); 5595 5596 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]); 5597 } 5598 [(set_attr "length" "8") 5599 (set_attr "type" "vecperm")]) 5600 5601 (define_insn "*fpmask<mode>" 5602 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa") 5603 (if_then_else:V2DI 5604 (match_operator:CCFP 1 "fpmask_comparison_operator" 5605 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>") 5606 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")]) 5607 (match_operand:V2DI 4 "all_ones_constant" "") 5608 (match_operand:V2DI 5 "zero_constant" "")))] 5609 "TARGET_P9_MINMAX" 5610 "xscmp%V1dp %x0,%x2,%x3" 5611 [(set_attr "type" "fpcompare")]) 5612 5613 (define_insn "*xxsel<mode>" 5614 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 5615 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa") 5616 (match_operand:V2DI 2 "zero_constant" "")) 5617 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>") 5618 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))] 5619 "TARGET_P9_MINMAX" 5620 "xxsel %x0,%x4,%x3,%x1" 5621 [(set_attr "type" "vecmove")]) 5622 5623 ;; Support for ISA 3.1 IEEE 128-bit conditional move. The mode used in the 5624 ;; comparison must be the same as used in the move. 5625 (define_expand "mov<mode>cc" 5626 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 5627 (if_then_else:IEEE128 (match_operand 1 "comparison_operator") 5628 (match_operand:IEEE128 2 "gpc_reg_operand") 5629 (match_operand:IEEE128 3 "gpc_reg_operand")))] 5630 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 5631 { 5632 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 5633 DONE; 5634 else 5635 FAIL; 5636 }) 5637 5638 (define_insn_and_split "*mov<mode>cc_p10" 5639 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v") 5640 (if_then_else:IEEE128 5641 (match_operator:CCFP 1 "fpmask_comparison_operator" 5642 [(match_operand:IEEE128 2 "altivec_register_operand" "v,v") 5643 (match_operand:IEEE128 3 "altivec_register_operand" "v,v")]) 5644 (match_operand:IEEE128 4 "altivec_register_operand" "v,v") 5645 (match_operand:IEEE128 5 "altivec_register_operand" "v,v"))) 5646 (clobber (match_scratch:V2DI 6 "=0,&v"))] 5647 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 5648 "#" 5649 "&& 1" 5650 [(set (match_dup 6) 5651 (if_then_else:V2DI (match_dup 1) 5652 (match_dup 7) 5653 (match_dup 8))) 5654 (set (match_dup 0) 5655 (if_then_else:IEEE128 (ne (match_dup 6) 5656 (match_dup 8)) 5657 (match_dup 4) 5658 (match_dup 5)))] 5659 { 5660 if (GET_CODE (operands[6]) == SCRATCH) 5661 operands[6] = gen_reg_rtx (V2DImode); 5662 5663 operands[7] = CONSTM1_RTX (V2DImode); 5664 operands[8] = CONST0_RTX (V2DImode); 5665 } 5666 [(set_attr "length" "8") 5667 (set_attr "type" "vecperm")]) 5668 5669 ;; Handle inverting the fpmask comparisons. 5670 (define_insn_and_split "*mov<mode>cc_invert_p10" 5671 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=&v,v") 5672 (if_then_else:IEEE128 5673 (match_operator:CCFP 1 "invert_fpmask_comparison_operator" 5674 [(match_operand:IEEE128 2 "altivec_register_operand" "v,v") 5675 (match_operand:IEEE128 3 "altivec_register_operand" "v,v")]) 5676 (match_operand:IEEE128 4 "altivec_register_operand" "v,v") 5677 (match_operand:IEEE128 5 "altivec_register_operand" "v,v"))) 5678 (clobber (match_scratch:V2DI 6 "=0,&v"))] 5679 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 5680 "#" 5681 "&& 1" 5682 [(set (match_dup 6) 5683 (if_then_else:V2DI (match_dup 9) 5684 (match_dup 7) 5685 (match_dup 8))) 5686 (set (match_dup 0) 5687 (if_then_else:IEEE128 (ne (match_dup 6) 5688 (match_dup 8)) 5689 (match_dup 5) 5690 (match_dup 4)))] 5691 { 5692 rtx op1 = operands[1]; 5693 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1)); 5694 5695 if (GET_CODE (operands[6]) == SCRATCH) 5696 operands[6] = gen_reg_rtx (V2DImode); 5697 5698 operands[7] = CONSTM1_RTX (V2DImode); 5699 operands[8] = CONST0_RTX (V2DImode); 5700 5701 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]); 5702 } 5703 [(set_attr "length" "8") 5704 (set_attr "type" "vecperm")]) 5705 5706 (define_insn "*fpmask<mode>" 5707 [(set (match_operand:V2DI 0 "altivec_register_operand" "=v") 5708 (if_then_else:V2DI 5709 (match_operator:CCFP 1 "fpmask_comparison_operator" 5710 [(match_operand:IEEE128 2 "altivec_register_operand" "v") 5711 (match_operand:IEEE128 3 "altivec_register_operand" "v")]) 5712 (match_operand:V2DI 4 "all_ones_constant" "") 5713 (match_operand:V2DI 5 "zero_constant" "")))] 5714 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 5715 "xscmp%V1qp %0,%2,%3" 5716 [(set_attr "type" "fpcompare")]) 5717 5718 (define_insn "*xxsel<mode>" 5719 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 5720 (if_then_else:IEEE128 5721 (ne (match_operand:V2DI 1 "altivec_register_operand" "v") 5722 (match_operand:V2DI 2 "zero_constant" "")) 5723 (match_operand:IEEE128 3 "altivec_register_operand" "v") 5724 (match_operand:IEEE128 4 "altivec_register_operand" "v")))] 5725 "TARGET_POWER10 && TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 5726 "xxsel %x0,%x4,%x3,%x1" 5727 [(set_attr "type" "vecmove")]) 5728 5729 5731 ;; Conversions to and from floating-point. 5732 5733 ; We don't define lfiwax/lfiwzx with the normal definition, because we 5734 ; don't want to support putting SImode in FPR registers. 5735 (define_insn "lfiwax" 5736 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v") 5737 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")] 5738 UNSPEC_LFIWAX))] 5739 "TARGET_HARD_FLOAT && TARGET_LFIWAX" 5740 "@ 5741 lfiwax %0,%y1 5742 lxsiwax %x0,%y1 5743 mtvsrwa %x0,%1 5744 vextsw2d %0,%1" 5745 [(set_attr "type" "fpload,fpload,mtvsr,vecexts") 5746 (set_attr "isa" "*,p8v,p8v,p9v")]) 5747 5748 ; This split must be run before register allocation because it allocates the 5749 ; memory slot that is needed to move values to/from the FPR. We don't allocate 5750 ; it earlier to allow for the combiner to merge insns together where it might 5751 ; not be needed and also in case the insns are deleted as dead code. 5752 5753 (define_insn_and_split "floatsi<mode>2_lfiwax" 5754 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5755 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r"))) 5756 (clobber (match_scratch:DI 2 "=d,wa"))] 5757 "TARGET_HARD_FLOAT && TARGET_LFIWAX 5758 && <SI_CONVERT_FP> && can_create_pseudo_p ()" 5759 "#" 5760 "&& 1" 5761 [(pc)] 5762 { 5763 rtx dest = operands[0]; 5764 rtx src = operands[1]; 5765 rtx tmp; 5766 5767 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE) 5768 tmp = convert_to_mode (DImode, src, false); 5769 else 5770 { 5771 tmp = operands[2]; 5772 if (GET_CODE (tmp) == SCRATCH) 5773 tmp = gen_reg_rtx (DImode); 5774 if (MEM_P (src)) 5775 { 5776 src = rs6000_force_indexed_or_indirect_mem (src); 5777 emit_insn (gen_lfiwax (tmp, src)); 5778 } 5779 else 5780 { 5781 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5782 emit_move_insn (stack, src); 5783 emit_insn (gen_lfiwax (tmp, stack)); 5784 } 5785 } 5786 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5787 DONE; 5788 } 5789 [(set_attr "length" "12") 5790 (set_attr "type" "fpload")]) 5791 5792 (define_insn_and_split "floatsi<mode>2_lfiwax_mem" 5793 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5794 (float:SFDF 5795 (sign_extend:DI 5796 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z")))) 5797 (clobber (match_scratch:DI 2 "=d,wa"))] 5798 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>" 5799 "#" 5800 "&& 1" 5801 [(pc)] 5802 { 5803 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 5804 if (GET_CODE (operands[2]) == SCRATCH) 5805 operands[2] = gen_reg_rtx (DImode); 5806 if (TARGET_P8_VECTOR) 5807 emit_insn (gen_extendsidi2 (operands[2], operands[1])); 5808 else 5809 emit_insn (gen_lfiwax (operands[2], operands[1])); 5810 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5811 DONE; 5812 } 5813 [(set_attr "length" "8") 5814 (set_attr "type" "fpload")]) 5815 5816 (define_insn_and_split "floatsi<SFDF:mode>2_lfiwax_<QHI:mode>_mem_zext" 5817 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5818 (float:SFDF 5819 (zero_extend:SI 5820 (match_operand:QHI 1 "indexed_or_indirect_operand" "Z,Z")))) 5821 (clobber (match_scratch:DI 2 "=d,wa"))] 5822 "TARGET_HARD_FLOAT && <SI_CONVERT_FP> && TARGET_P9_VECTOR 5823 && TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 5824 "#" 5825 "&& 1" 5826 [(pc)] 5827 { 5828 if (GET_CODE (operands[2]) == SCRATCH) 5829 operands[2] = gen_reg_rtx (DImode); 5830 emit_insn (gen_zero_extendhidi2 (operands[2], operands[1])); 5831 emit_insn (gen_floatdi<SFDF:mode>2 (operands[0], operands[2])); 5832 DONE; 5833 } 5834 [(set_attr "length" "8") 5835 (set_attr "type" "fpload")]) 5836 5837 (define_insn "lfiwzx" 5838 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa") 5839 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")] 5840 UNSPEC_LFIWZX))] 5841 "TARGET_HARD_FLOAT && TARGET_LFIWZX" 5842 "@ 5843 lfiwzx %0,%y1 5844 lxsiwzx %x0,%y1 5845 mtvsrwz %x0,%1 5846 xxextractuw %x0,%x1,4" 5847 [(set_attr "type" "fpload,fpload,mtvsr,vecexts") 5848 (set_attr "isa" "*,p8v,p8v,p9v")]) 5849 5850 (define_insn_and_split "floatunssi<mode>2_lfiwzx" 5851 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5852 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r"))) 5853 (clobber (match_scratch:DI 2 "=d,wa"))] 5854 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" 5855 "#" 5856 "&& 1" 5857 [(pc)] 5858 { 5859 rtx dest = operands[0]; 5860 rtx src = operands[1]; 5861 rtx tmp; 5862 5863 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE) 5864 tmp = convert_to_mode (DImode, src, true); 5865 else 5866 { 5867 tmp = operands[2]; 5868 if (GET_CODE (tmp) == SCRATCH) 5869 tmp = gen_reg_rtx (DImode); 5870 if (MEM_P (src)) 5871 { 5872 src = rs6000_force_indexed_or_indirect_mem (src); 5873 emit_insn (gen_lfiwzx (tmp, src)); 5874 } 5875 else 5876 { 5877 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5878 emit_move_insn (stack, src); 5879 emit_insn (gen_lfiwzx (tmp, stack)); 5880 } 5881 } 5882 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5883 DONE; 5884 } 5885 [(set_attr "length" "12") 5886 (set_attr "type" "fpload")]) 5887 5888 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem" 5889 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5890 (unsigned_float:SFDF 5891 (zero_extend:DI 5892 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z")))) 5893 (clobber (match_scratch:DI 2 "=d,wa"))] 5894 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" 5895 "#" 5896 "&& 1" 5897 [(pc)] 5898 { 5899 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 5900 if (GET_CODE (operands[2]) == SCRATCH) 5901 operands[2] = gen_reg_rtx (DImode); 5902 if (TARGET_P8_VECTOR) 5903 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1])); 5904 else 5905 emit_insn (gen_lfiwzx (operands[2], operands[1])); 5906 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5907 DONE; 5908 } 5909 [(set_attr "length" "8") 5910 (set_attr "type" "fpload")]) 5911 5912 ; For each of these conversions, there is a define_expand, a define_insn 5913 ; with a '#' template, and a define_split (with C code). The idea is 5914 ; to allow constant folding with the template of the define_insn, 5915 ; then to have the insns split later (between sched1 and final). 5916 5917 (define_expand "floatsidf2" 5918 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand") 5919 (float:DF (match_operand:SI 1 "nonimmediate_operand"))) 5920 (use (match_dup 2)) 5921 (use (match_dup 3)) 5922 (clobber (match_dup 4)) 5923 (clobber (match_dup 5)) 5924 (clobber (match_dup 6))])] 5925 "TARGET_HARD_FLOAT" 5926 { 5927 if (TARGET_LFIWAX && TARGET_FCFID) 5928 { 5929 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1])); 5930 DONE; 5931 } 5932 else if (TARGET_FCFID) 5933 { 5934 rtx dreg = operands[1]; 5935 if (!REG_P (dreg)) 5936 dreg = force_reg (SImode, dreg); 5937 dreg = convert_to_mode (DImode, dreg, false); 5938 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5939 DONE; 5940 } 5941 5942 if (!REG_P (operands[1])) 5943 operands[1] = force_reg (SImode, operands[1]); 5944 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5945 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); 5946 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5947 operands[5] = gen_reg_rtx (DFmode); 5948 operands[6] = gen_reg_rtx (SImode); 5949 }) 5950 5951 (define_insn_and_split "*floatsidf2_internal" 5952 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5953 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5954 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5955 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5956 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5957 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) 5958 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] 5959 "!TARGET_FCFID && TARGET_HARD_FLOAT" 5960 "#" 5961 "&& 1" 5962 [(pc)] 5963 { 5964 rtx lowword, highword; 5965 gcc_assert (MEM_P (operands[4])); 5966 highword = adjust_address (operands[4], SImode, 0); 5967 lowword = adjust_address (operands[4], SImode, 4); 5968 if (! WORDS_BIG_ENDIAN) 5969 std::swap (lowword, highword); 5970 5971 emit_insn (gen_xorsi3 (operands[6], operands[1], 5972 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff))); 5973 emit_move_insn (lowword, operands[6]); 5974 emit_move_insn (highword, operands[2]); 5975 emit_move_insn (operands[5], operands[4]); 5976 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5977 DONE; 5978 } 5979 [(set_attr "length" "24") 5980 (set_attr "type" "fp")]) 5981 5982 ;; If we don't have a direct conversion to single precision, don't enable this 5983 ;; conversion for 32-bit without fast math, because we don't have the insn to 5984 ;; generate the fixup swizzle to avoid double rounding problems. 5985 (define_expand "floatunssisf2" 5986 [(set (match_operand:SF 0 "gpc_reg_operand") 5987 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))] 5988 "TARGET_HARD_FLOAT 5989 && ((TARGET_FCFIDUS && TARGET_LFIWZX) 5990 || (TARGET_FCFID 5991 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" 5992 { 5993 if (TARGET_LFIWZX && TARGET_FCFIDUS) 5994 { 5995 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1])); 5996 DONE; 5997 } 5998 else 5999 { 6000 rtx dreg = operands[1]; 6001 if (!REG_P (dreg)) 6002 dreg = force_reg (SImode, dreg); 6003 dreg = convert_to_mode (DImode, dreg, true); 6004 emit_insn (gen_floatdisf2 (operands[0], dreg)); 6005 DONE; 6006 } 6007 }) 6008 6009 (define_expand "floatunssidf2" 6010 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand") 6011 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand"))) 6012 (use (match_dup 2)) 6013 (use (match_dup 3)) 6014 (clobber (match_dup 4)) 6015 (clobber (match_dup 5))])] 6016 "TARGET_HARD_FLOAT" 6017 { 6018 if (TARGET_LFIWZX && TARGET_FCFID) 6019 { 6020 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1])); 6021 DONE; 6022 } 6023 else if (TARGET_FCFID) 6024 { 6025 rtx dreg = operands[1]; 6026 if (!REG_P (dreg)) 6027 dreg = force_reg (SImode, dreg); 6028 dreg = convert_to_mode (DImode, dreg, true); 6029 emit_insn (gen_floatdidf2 (operands[0], dreg)); 6030 DONE; 6031 } 6032 6033 if (!REG_P (operands[1])) 6034 operands[1] = force_reg (SImode, operands[1]); 6035 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 6036 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); 6037 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 6038 operands[5] = gen_reg_rtx (DFmode); 6039 }) 6040 6041 (define_insn_and_split "*floatunssidf2_internal" 6042 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 6043 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 6044 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 6045 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 6046 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 6047 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] 6048 "!TARGET_FCFIDU && TARGET_HARD_FLOAT 6049 && !(TARGET_FCFID && TARGET_POWERPC64)" 6050 "#" 6051 "&& 1" 6052 [(pc)] 6053 { 6054 rtx lowword, highword; 6055 gcc_assert (MEM_P (operands[4])); 6056 highword = adjust_address (operands[4], SImode, 0); 6057 lowword = adjust_address (operands[4], SImode, 4); 6058 if (! WORDS_BIG_ENDIAN) 6059 std::swap (lowword, highword); 6060 6061 emit_move_insn (lowword, operands[1]); 6062 emit_move_insn (highword, operands[2]); 6063 emit_move_insn (operands[5], operands[4]); 6064 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 6065 DONE; 6066 } 6067 [(set_attr "length" "20") 6068 (set_attr "type" "fp")]) 6069 6070 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to 6071 ;; vector registers. These insns favor doing the sign/zero extension in 6072 ;; the vector registers, rather then loading up a GPR, doing a sign/zero 6073 ;; extension and then a direct move. 6074 6075 (define_expand "float<QHI:mode><FP_ISA3:mode>2" 6076 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") 6077 (float:FP_ISA3 6078 (match_operand:QHI 1 "input_operand"))) 6079 (clobber (match_scratch:DI 2)) 6080 (clobber (match_scratch:DI 3)) 6081 (clobber (match_scratch:<QHI:MODE> 4))])] 6082 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 6083 { 6084 if (MEM_P (operands[1])) 6085 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 6086 }) 6087 6088 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal" 6089 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>") 6090 (float:FP_ISA3 6091 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z"))) 6092 (clobber (match_scratch:DI 2 "=v,wa,v")) 6093 (clobber (match_scratch:DI 3 "=X,r,X")) 6094 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))] 6095 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 6096 "#" 6097 "&& reload_completed" 6098 [(const_int 0)] 6099 { 6100 rtx result = operands[0]; 6101 rtx input = operands[1]; 6102 rtx di = operands[2]; 6103 6104 if (!MEM_P (input)) 6105 { 6106 rtx tmp = operands[3]; 6107 if (altivec_register_operand (input, <QHI:MODE>mode)) 6108 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 6109 else if (GET_CODE (tmp) == SCRATCH) 6110 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 6111 else 6112 { 6113 emit_insn (gen_extend<QHI:mode>di2 (tmp, input)); 6114 emit_move_insn (di, tmp); 6115 } 6116 } 6117 else 6118 { 6119 rtx tmp = operands[4]; 6120 emit_move_insn (tmp, input); 6121 emit_insn (gen_extend<QHI:mode>di2 (di, tmp)); 6122 } 6123 6124 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); 6125 DONE; 6126 } 6127 [(set_attr "isa" "p9v,*,p9v")]) 6128 6129 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2" 6130 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") 6131 (unsigned_float:FP_ISA3 6132 (match_operand:QHI 1 "input_operand"))) 6133 (clobber (match_scratch:DI 2)) 6134 (clobber (match_scratch:DI 3))])] 6135 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 6136 { 6137 if (MEM_P (operands[1])) 6138 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 6139 }) 6140 6141 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal" 6142 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>") 6143 (unsigned_float:FP_ISA3 6144 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z"))) 6145 (clobber (match_scratch:DI 2 "=v,wa,wa")) 6146 (clobber (match_scratch:DI 3 "=X,r,X"))] 6147 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 6148 "#" 6149 "&& reload_completed" 6150 [(const_int 0)] 6151 { 6152 rtx result = operands[0]; 6153 rtx input = operands[1]; 6154 rtx di = operands[2]; 6155 6156 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode)) 6157 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input)); 6158 else 6159 { 6160 rtx tmp = operands[3]; 6161 if (GET_CODE (tmp) == SCRATCH) 6162 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 6163 else 6164 { 6165 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input)); 6166 emit_move_insn (di, tmp); 6167 } 6168 } 6169 6170 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); 6171 DONE; 6172 } 6173 [(set_attr "isa" "p9v,*,p9v")]) 6174 6175 (define_expand "fix_trunc<mode>si2" 6176 [(set (match_operand:SI 0 "gpc_reg_operand") 6177 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))] 6178 "TARGET_HARD_FLOAT" 6179 { 6180 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)) 6181 { 6182 rtx src = force_reg (<MODE>mode, operands[1]); 6183 6184 if (TARGET_STFIWX) 6185 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src)); 6186 else 6187 { 6188 rtx tmp = gen_reg_rtx (DImode); 6189 rtx stack = rs6000_allocate_stack_temp (DImode, true, false); 6190 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src, 6191 tmp, stack)); 6192 } 6193 DONE; 6194 } 6195 }) 6196 6197 ; Like the convert to float patterns, this insn must be split before 6198 ; register allocation so that it can allocate the memory slot if it 6199 ; needed 6200 (define_insn_and_split "fix_trunc<mode>si2_stfiwx" 6201 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 6202 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 6203 (clobber (match_scratch:DI 2 "=d"))] 6204 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p () 6205 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" 6206 "#" 6207 "&& 1" 6208 [(pc)] 6209 { 6210 rtx dest = operands[0]; 6211 rtx src = operands[1]; 6212 rtx tmp = operands[2]; 6213 6214 if (GET_CODE (tmp) == SCRATCH) 6215 tmp = gen_reg_rtx (DImode); 6216 6217 emit_insn (gen_fctiwz_<mode> (tmp, src)); 6218 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32)) 6219 { 6220 dest = rs6000_force_indexed_or_indirect_mem (dest); 6221 emit_insn (gen_stfiwx (dest, tmp)); 6222 DONE; 6223 } 6224 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest)) 6225 { 6226 dest = gen_lowpart (DImode, dest); 6227 emit_move_insn (dest, tmp); 6228 DONE; 6229 } 6230 else 6231 { 6232 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 6233 emit_insn (gen_stfiwx (stack, tmp)); 6234 emit_move_insn (dest, stack); 6235 DONE; 6236 } 6237 } 6238 [(set_attr "length" "12") 6239 (set_attr "type" "fp")]) 6240 6241 (define_insn_and_split "fix_trunc<mode>si2_internal" 6242 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r") 6243 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>"))) 6244 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d")) 6245 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))] 6246 "TARGET_HARD_FLOAT 6247 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" 6248 "#" 6249 "&& 1" 6250 [(pc)] 6251 { 6252 rtx lowword; 6253 gcc_assert (MEM_P (operands[3])); 6254 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 6255 6256 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1])); 6257 emit_move_insn (operands[3], operands[2]); 6258 emit_move_insn (operands[0], lowword); 6259 DONE; 6260 } 6261 [(set_attr "length" "16") 6262 (set_attr "type" "fp")]) 6263 6264 (define_expand "fix_trunc<mode>di2" 6265 [(set (match_operand:DI 0 "gpc_reg_operand") 6266 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))] 6267 "TARGET_HARD_FLOAT && TARGET_FCFID" 6268 "") 6269 6270 (define_insn "*fix_trunc<mode>di2_fctidz" 6271 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 6272 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 6273 "TARGET_HARD_FLOAT && TARGET_FCFID" 6274 "@ 6275 fctidz %0,%1 6276 xscvdpsxds %x0,%x1" 6277 [(set_attr "type" "fp")]) 6278 6279 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR 6280 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the 6281 ;; vector registers, so we need to do direct moves to the GPRs, but SImode 6282 ;; values can go in VSX registers. Keeping the direct move part through 6283 ;; register allocation prevents the register allocator from doing a direct move 6284 ;; of the SImode value to a GPR, and then a store/load. 6285 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2" 6286 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r") 6287 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa"))) 6288 (clobber (match_scratch:SI 2 "=X,X,wa"))] 6289 "TARGET_DIRECT_MOVE" 6290 "@ 6291 fctiw<u>z %0,%1 6292 xscvdp<su>xws %x0,%x1 6293 #" 6294 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)" 6295 [(set (match_dup 2) 6296 (any_fix:SI (match_dup 1))) 6297 (set (match_dup 3) 6298 (match_dup 2))] 6299 { 6300 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0])); 6301 } 6302 [(set_attr "type" "fp") 6303 (set_attr "length" "4,4,8") 6304 (set_attr "isa" "p9v,p9v,*")]) 6305 6306 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8" 6307 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa") 6308 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))] 6309 "TARGET_DIRECT_MOVE" 6310 "@ 6311 fctiw<u>z %0,%1 6312 xscvdp<su>xws %x0,%x1" 6313 [(set_attr "type" "fp")]) 6314 6315 ;; Keep the convert and store together through register allocation to prevent 6316 ;; the register allocator from getting clever and doing a direct move to a GPR 6317 ;; and then store for reg+offset stores. 6318 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem" 6319 [(set (match_operand:QHSI 0 "memory_operand" "=Z") 6320 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa"))) 6321 (clobber (match_scratch:SI 2 "=wa"))] 6322 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR" 6323 "#" 6324 "&& reload_completed" 6325 [(set (match_dup 2) 6326 (any_fix:SI (match_dup 1))) 6327 (set (match_dup 0) 6328 (match_dup 3))] 6329 { 6330 operands[3] = (<QHSI:MODE>mode == SImode 6331 ? operands[2] 6332 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2]))); 6333 }) 6334 6335 (define_expand "fixuns_trunc<mode>si2" 6336 [(set (match_operand:SI 0 "gpc_reg_operand") 6337 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))] 6338 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX" 6339 { 6340 if (!TARGET_P8_VECTOR) 6341 { 6342 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1])); 6343 DONE; 6344 } 6345 }) 6346 6347 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx" 6348 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 6349 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 6350 (clobber (match_scratch:DI 2 "=d"))] 6351 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ 6352 && TARGET_STFIWX && can_create_pseudo_p () 6353 && !TARGET_P8_VECTOR" 6354 "#" 6355 "&& 1" 6356 [(pc)] 6357 { 6358 rtx dest = operands[0]; 6359 rtx src = operands[1]; 6360 rtx tmp = operands[2]; 6361 6362 if (GET_CODE (tmp) == SCRATCH) 6363 tmp = gen_reg_rtx (DImode); 6364 6365 emit_insn (gen_fctiwuz_<mode> (tmp, src)); 6366 if (MEM_P (dest)) 6367 { 6368 dest = rs6000_force_indexed_or_indirect_mem (dest); 6369 emit_insn (gen_stfiwx (dest, tmp)); 6370 DONE; 6371 } 6372 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE) 6373 { 6374 dest = gen_lowpart (DImode, dest); 6375 emit_move_insn (dest, tmp); 6376 DONE; 6377 } 6378 else 6379 { 6380 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 6381 emit_insn (gen_stfiwx (stack, tmp)); 6382 emit_move_insn (dest, stack); 6383 DONE; 6384 } 6385 } 6386 [(set_attr "length" "12") 6387 (set_attr "type" "fp")]) 6388 6389 (define_insn "fixuns_trunc<mode>di2" 6390 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 6391 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 6392 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ" 6393 "@ 6394 fctiduz %0,%1 6395 xscvdpuxds %x0,%x1" 6396 [(set_attr "type" "fp")]) 6397 6398 (define_insn "rs6000_mtfsb0" 6399 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")] 6400 UNSPECV_MTFSB0)] 6401 "TARGET_HARD_FLOAT" 6402 "mtfsb0 %0" 6403 [(set_attr "type" "fp")]) 6404 6405 (define_insn "rs6000_mtfsb1" 6406 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")] 6407 UNSPECV_MTFSB1)] 6408 "TARGET_HARD_FLOAT" 6409 "mtfsb1 %0" 6410 [(set_attr "type" "fp")]) 6411 6412 (define_insn "rs6000_mffscrn" 6413 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 6414 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] 6415 UNSPECV_MFFSCRN))] 6416 "TARGET_P9_MISC" 6417 "mffscrn %0,%1" 6418 [(set_attr "type" "fp")]) 6419 6420 (define_insn "rs6000_mffscrni" 6421 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 6422 (unspec_volatile:DF [(match_operand:SI 1 "const_0_to_3_operand" "n")] 6423 UNSPECV_MFFSCRN))] 6424 "TARGET_P9_MISC" 6425 "mffscrni %0,%1" 6426 [(set_attr "type" "fp")]) 6427 6428 (define_insn "rs6000_mffscdrn" 6429 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 6430 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN)) 6431 (use (match_operand:DF 1 "gpc_reg_operand" "d"))] 6432 "TARGET_P9_MISC" 6433 "mffscdrn %0,%1" 6434 [(set_attr "type" "fp")]) 6435 6436 (define_expand "rs6000_set_fpscr_rn" 6437 [(match_operand:SI 0 "reg_or_cint_operand")] 6438 "TARGET_HARD_FLOAT" 6439 { 6440 rtx tmp_df = gen_reg_rtx (DFmode); 6441 6442 /* The floating point rounding control bits are FPSCR[62:63]. Put the 6443 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */ 6444 if (TARGET_P9_MISC) 6445 { 6446 if (const_0_to_3_operand (operands[0], VOIDmode)) 6447 emit_insn (gen_rs6000_mffscrni (tmp_df, operands[0])); 6448 else 6449 { 6450 rtx op0 = convert_to_mode (DImode, operands[0], false); 6451 rtx src_df = simplify_gen_subreg (DFmode, op0, DImode, 0); 6452 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df)); 6453 } 6454 DONE; 6455 } 6456 6457 if (CONST_INT_P (operands[0])) 6458 { 6459 if ((INTVAL (operands[0]) & 0x1) == 0x1) 6460 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31))); 6461 else 6462 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31))); 6463 6464 if ((INTVAL (operands[0]) & 0x2) == 0x2) 6465 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30))); 6466 else 6467 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30))); 6468 } 6469 else 6470 { 6471 rtx tmp_rn = gen_reg_rtx (DImode); 6472 rtx tmp_di = gen_reg_rtx (DImode); 6473 6474 /* Extract new RN mode from operand. */ 6475 rtx op0 = convert_to_mode (DImode, operands[0], false); 6476 emit_insn (gen_anddi3 (tmp_rn, op0, GEN_INT (3))); 6477 6478 /* Insert new RN mode into FSCPR. */ 6479 emit_insn (gen_rs6000_mffs (tmp_df)); 6480 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); 6481 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4))); 6482 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn)); 6483 6484 /* Need to write to field k=15. The fields are [0:15]. Hence with 6485 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an 6486 8-bit field[0:7]. Need to set the bit that corresponds to the 6487 value of i that you want [0:7]. */ 6488 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); 6489 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df)); 6490 } 6491 DONE; 6492 }) 6493 6494 (define_expand "rs6000_set_fpscr_drn" 6495 [(match_operand:DI 0 "gpc_reg_operand")] 6496 "TARGET_HARD_FLOAT" 6497 { 6498 rtx tmp_df = gen_reg_rtx (DFmode); 6499 6500 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the 6501 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */ 6502 if (TARGET_P9_MISC) 6503 { 6504 rtx src_df = gen_reg_rtx (DFmode); 6505 6506 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32))); 6507 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0); 6508 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df)); 6509 } 6510 else 6511 { 6512 rtx tmp_rn = gen_reg_rtx (DImode); 6513 rtx tmp_di = gen_reg_rtx (DImode); 6514 6515 /* Extract new DRN mode from operand. */ 6516 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7))); 6517 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32))); 6518 6519 /* Insert new RN mode into FSCPR. */ 6520 emit_insn (gen_rs6000_mffs (tmp_df)); 6521 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); 6522 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL))); 6523 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn)); 6524 6525 /* Need to write to field 7. The fields are [0:15]. The equation to 6526 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set 6527 i to 0x1 to get field 7 where i selects the field. */ 6528 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); 6529 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df)); 6530 } 6531 DONE; 6532 }) 6533 6534 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) 6535 ;; rather than (set (subreg:SI (reg)) (fix:SI ...)) 6536 ;; because the first makes it clear that operand 0 is not live 6537 ;; before the instruction. 6538 (define_insn "fctiwz_<mode>" 6539 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 6540 (unspec:DI [(fix:SI 6541 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 6542 UNSPEC_FCTIWZ))] 6543 "TARGET_HARD_FLOAT" 6544 "@ 6545 fctiwz %0,%1 6546 xscvdpsxws %x0,%x1" 6547 [(set_attr "type" "fp")]) 6548 6549 (define_insn "fctiwuz_<mode>" 6550 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 6551 (unspec:DI [(unsigned_fix:SI 6552 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 6553 UNSPEC_FCTIWUZ))] 6554 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ" 6555 "@ 6556 fctiwuz %0,%1 6557 xscvdpuxws %x0,%x1" 6558 [(set_attr "type" "fp")]) 6559 6560 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since 6561 ;; since the friz instruction does not truncate the value if the floating 6562 ;; point value is < LONG_MIN or > LONG_MAX. 6563 (define_insn "*friz" 6564 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6565 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))] 6566 "TARGET_HARD_FLOAT && TARGET_FPRND 6567 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ" 6568 "@ 6569 friz %0,%1 6570 xsrdpiz %x0,%x1" 6571 [(set_attr "type" "fp")]) 6572 6573 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This 6574 ;; optimization prevents on ISA 2.06 systems and earlier having to store the 6575 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign 6576 ;; extend it, store it back on the stack from the GPR, load it back into the 6577 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07), 6578 ;; disable using store and load to sign/zero extend the value. 6579 (define_insn_and_split "*round32<mode>2_fprs" 6580 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 6581 (float:SFDF 6582 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 6583 (clobber (match_scratch:DI 2 "=d")) 6584 (clobber (match_scratch:DI 3 "=d"))] 6585 "TARGET_HARD_FLOAT 6586 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID 6587 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()" 6588 "#" 6589 "&& 1" 6590 [(pc)] 6591 { 6592 rtx dest = operands[0]; 6593 rtx src = operands[1]; 6594 rtx tmp1 = operands[2]; 6595 rtx tmp2 = operands[3]; 6596 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 6597 6598 if (GET_CODE (tmp1) == SCRATCH) 6599 tmp1 = gen_reg_rtx (DImode); 6600 if (GET_CODE (tmp2) == SCRATCH) 6601 tmp2 = gen_reg_rtx (DImode); 6602 6603 emit_insn (gen_fctiwz_<mode> (tmp1, src)); 6604 emit_insn (gen_stfiwx (stack, tmp1)); 6605 emit_insn (gen_lfiwax (tmp2, stack)); 6606 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 6607 DONE; 6608 } 6609 [(set_attr "type" "fpload") 6610 (set_attr "length" "16")]) 6611 6612 (define_insn_and_split "*roundu32<mode>2_fprs" 6613 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 6614 (unsigned_float:SFDF 6615 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 6616 (clobber (match_scratch:DI 2 "=d")) 6617 (clobber (match_scratch:DI 3 "=d"))] 6618 "TARGET_HARD_FLOAT 6619 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE 6620 && can_create_pseudo_p ()" 6621 "#" 6622 "&& 1" 6623 [(pc)] 6624 { 6625 rtx dest = operands[0]; 6626 rtx src = operands[1]; 6627 rtx tmp1 = operands[2]; 6628 rtx tmp2 = operands[3]; 6629 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 6630 6631 if (GET_CODE (tmp1) == SCRATCH) 6632 tmp1 = gen_reg_rtx (DImode); 6633 if (GET_CODE (tmp2) == SCRATCH) 6634 tmp2 = gen_reg_rtx (DImode); 6635 6636 emit_insn (gen_fctiwuz_<mode> (tmp1, src)); 6637 emit_insn (gen_stfiwx (stack, tmp1)); 6638 emit_insn (gen_lfiwzx (tmp2, stack)); 6639 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 6640 DONE; 6641 } 6642 [(set_attr "type" "fpload") 6643 (set_attr "length" "16")]) 6644 6645 ;; No VSX equivalent to fctid 6646 (define_insn "lrint<mode>di2" 6647 [(set (match_operand:DI 0 "gpc_reg_operand" "=d") 6648 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 6649 UNSPEC_FCTID))] 6650 "TARGET_HARD_FLOAT && TARGET_FPRND" 6651 "fctid %0,%1" 6652 [(set_attr "type" "fp")]) 6653 6654 (define_insn "btrunc<mode>2" 6655 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 6656 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 6657 UNSPEC_FRIZ))] 6658 "TARGET_HARD_FLOAT && TARGET_FPRND" 6659 "@ 6660 friz %0,%1 6661 xsrdpiz %x0,%x1" 6662 [(set_attr "type" "fp")]) 6663 6664 (define_insn "ceil<mode>2" 6665 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 6666 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 6667 UNSPEC_FRIP))] 6668 "TARGET_HARD_FLOAT && TARGET_FPRND" 6669 "@ 6670 frip %0,%1 6671 xsrdpip %x0,%x1" 6672 [(set_attr "type" "fp")]) 6673 6674 (define_insn "floor<mode>2" 6675 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 6676 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 6677 UNSPEC_FRIM))] 6678 "TARGET_HARD_FLOAT && TARGET_FPRND" 6679 "@ 6680 frim %0,%1 6681 xsrdpim %x0,%x1" 6682 [(set_attr "type" "fp")]) 6683 6684 ;; No VSX equivalent to frin 6685 (define_insn "round<mode>2" 6686 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") 6687 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 6688 UNSPEC_FRIN))] 6689 "TARGET_HARD_FLOAT && TARGET_FPRND" 6690 "frin %0,%1" 6691 [(set_attr "type" "fp")]) 6692 6693 (define_insn "*xsrdpi<mode>2" 6694 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 6695 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")] 6696 UNSPEC_XSRDPI))] 6697 "TARGET_HARD_FLOAT && TARGET_VSX" 6698 "xsrdpi %x0,%x1" 6699 [(set_attr "type" "fp")]) 6700 6701 (define_expand "lround<mode>di2" 6702 [(set (match_dup 2) 6703 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")] 6704 UNSPEC_XSRDPI)) 6705 (set (match_operand:DI 0 "gpc_reg_operand") 6706 (unspec:DI [(match_dup 2)] 6707 UNSPEC_FCTID))] 6708 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND" 6709 { 6710 operands[2] = gen_reg_rtx (<MODE>mode); 6711 }) 6712 6713 ; An UNSPEC is used so we don't have to support SImode in FP registers. 6714 (define_insn "stfiwx" 6715 [(set (match_operand:SI 0 "memory_operand" "=Z,Z") 6716 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")] 6717 UNSPEC_STFIWX))] 6718 "TARGET_PPC_GFXOPT" 6719 "@ 6720 stfiwx %1,%y0 6721 stxsiwx %x1,%y0" 6722 [(set_attr "type" "fpstore") 6723 (set_attr "isa" "*,p8v")]) 6724 6725 ;; If we don't have a direct conversion to single precision, don't enable this 6726 ;; conversion for 32-bit without fast math, because we don't have the insn to 6727 ;; generate the fixup swizzle to avoid double rounding problems. 6728 (define_expand "floatsisf2" 6729 [(set (match_operand:SF 0 "gpc_reg_operand") 6730 (float:SF (match_operand:SI 1 "nonimmediate_operand")))] 6731 "TARGET_HARD_FLOAT 6732 && ((TARGET_FCFIDS && TARGET_LFIWAX) 6733 || (TARGET_FCFID 6734 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" 6735 { 6736 if (TARGET_FCFIDS && TARGET_LFIWAX) 6737 { 6738 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1])); 6739 DONE; 6740 } 6741 else if (TARGET_FCFID && TARGET_LFIWAX) 6742 { 6743 rtx dfreg = gen_reg_rtx (DFmode); 6744 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1])); 6745 emit_insn (gen_truncdfsf2 (operands[0], dfreg)); 6746 DONE; 6747 } 6748 else 6749 { 6750 rtx dreg = operands[1]; 6751 if (!REG_P (dreg)) 6752 dreg = force_reg (SImode, dreg); 6753 dreg = convert_to_mode (DImode, dreg, false); 6754 emit_insn (gen_floatdisf2 (operands[0], dreg)); 6755 DONE; 6756 } 6757 }) 6758 6759 (define_insn "floatdidf2" 6760 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6761 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6762 "TARGET_FCFID && TARGET_HARD_FLOAT" 6763 "@ 6764 fcfid %0,%1 6765 xscvsxddp %x0,%x1" 6766 [(set_attr "type" "fp")]) 6767 6768 (define_insn "floatti<mode>2" 6769 [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v") 6770 (float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))] 6771 "TARGET_POWER10" 6772 { 6773 return "xscvsqqp %0,%1"; 6774 } 6775 [(set_attr "type" "fp")]) 6776 6777 (define_insn "floatunsti<mode>2" 6778 [(set (match_operand:IEEE128 0 "vsx_register_operand" "=v") 6779 (unsigned_float:IEEE128 (match_operand:TI 1 "vsx_register_operand" "v")))] 6780 "TARGET_POWER10" 6781 { 6782 return "xscvuqqp %0,%1"; 6783 } 6784 [(set_attr "type" "fp")]) 6785 6786 (define_insn "fix_trunc<mode>ti2" 6787 [(set (match_operand:TI 0 "vsx_register_operand" "=v") 6788 (fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))] 6789 "TARGET_POWER10" 6790 { 6791 return "xscvqpsqz %0,%1"; 6792 } 6793 [(set_attr "type" "fp")]) 6794 6795 (define_insn "fixuns_trunc<mode>ti2" 6796 [(set (match_operand:TI 0 "vsx_register_operand" "=v") 6797 (unsigned_fix:TI (match_operand:IEEE128 1 "vsx_register_operand" "v")))] 6798 "TARGET_POWER10" 6799 { 6800 return "xscvqpuqz %0,%1"; 6801 } 6802 [(set_attr "type" "fp")]) 6803 6804 ; Allow the combiner to merge source memory operands to the conversion so that 6805 ; the optimizer/register allocator doesn't try to load the value too early in a 6806 ; GPR and then use store/load to move it to a FPR and suffer from a store-load 6807 ; hit. We will split after reload to avoid the trip through the GPRs 6808 6809 (define_insn_and_split "*floatdidf2_mem" 6810 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6811 (float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 6812 (clobber (match_scratch:DI 2 "=d,wa"))] 6813 "TARGET_HARD_FLOAT && TARGET_FCFID" 6814 "#" 6815 "&& reload_completed" 6816 [(set (match_dup 2) (match_dup 1)) 6817 (set (match_dup 0) (float:DF (match_dup 2)))] 6818 "" 6819 [(set_attr "length" "8") 6820 (set_attr "type" "fpload")]) 6821 6822 (define_expand "floatunsdidf2" 6823 [(set (match_operand:DF 0 "gpc_reg_operand") 6824 (unsigned_float:DF 6825 (match_operand:DI 1 "gpc_reg_operand")))] 6826 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 6827 "") 6828 6829 (define_insn "*floatunsdidf2_fcfidu" 6830 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6831 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6832 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 6833 "@ 6834 fcfidu %0,%1 6835 xscvuxddp %x0,%x1" 6836 [(set_attr "type" "fp")]) 6837 6838 (define_insn_and_split "*floatunsdidf2_mem" 6839 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6840 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 6841 (clobber (match_scratch:DI 2 "=d,wa"))] 6842 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))" 6843 "#" 6844 "&& reload_completed" 6845 [(set (match_dup 2) (match_dup 1)) 6846 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))] 6847 "" 6848 [(set_attr "length" "8") 6849 (set_attr "type" "fpload")]) 6850 6851 (define_expand "floatdisf2" 6852 [(set (match_operand:SF 0 "gpc_reg_operand") 6853 (float:SF (match_operand:DI 1 "gpc_reg_operand")))] 6854 "TARGET_FCFID && TARGET_HARD_FLOAT 6855 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)" 6856 { 6857 if (!TARGET_FCFIDS) 6858 { 6859 rtx val = operands[1]; 6860 if (!flag_unsafe_math_optimizations) 6861 { 6862 rtx label = gen_label_rtx (); 6863 val = gen_reg_rtx (DImode); 6864 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label)); 6865 emit_label (label); 6866 } 6867 emit_insn (gen_floatdisf2_internal1 (operands[0], val)); 6868 DONE; 6869 } 6870 }) 6871 6872 (define_insn "floatdisf2_fcfids" 6873 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa") 6874 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6875 "TARGET_HARD_FLOAT && TARGET_FCFIDS" 6876 "@ 6877 fcfids %0,%1 6878 xscvsxdsp %x0,%x1" 6879 [(set_attr "type" "fp") 6880 (set_attr "isa" "*,p8v")]) 6881 6882 (define_insn_and_split "*floatdisf2_mem" 6883 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa") 6884 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 6885 (clobber (match_scratch:DI 2 "=d,d,wa"))] 6886 "TARGET_HARD_FLOAT && TARGET_FCFIDS" 6887 "#" 6888 "&& reload_completed" 6889 [(pc)] 6890 { 6891 emit_move_insn (operands[2], operands[1]); 6892 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2])); 6893 DONE; 6894 } 6895 [(set_attr "length" "8") 6896 (set_attr "isa" "*,p8v,p8v")]) 6897 6898 ;; This is not IEEE compliant if rounding mode is "round to nearest". 6899 ;; If the DI->DF conversion is inexact, then it's possible to suffer 6900 ;; from double rounding. 6901 ;; Instead of creating a new cpu type for two FP operations, just use fp 6902 (define_insn_and_split "floatdisf2_internal1" 6903 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 6904 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d"))) 6905 (clobber (match_scratch:DF 2 "=d"))] 6906 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS" 6907 "#" 6908 "&& reload_completed" 6909 [(set (match_dup 2) 6910 (float:DF (match_dup 1))) 6911 (set (match_dup 0) 6912 (float_truncate:SF (match_dup 2)))] 6913 "" 6914 [(set_attr "length" "8") 6915 (set_attr "type" "fp")]) 6916 6917 ;; Twiddles bits to avoid double rounding. 6918 ;; Bits that might be truncated when converting to DFmode are replaced 6919 ;; by a bit that won't be lost at that stage, but is below the SFmode 6920 ;; rounding position. 6921 (define_expand "floatdisf2_internal2" 6922 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "") 6923 (const_int 53))) 6924 (clobber (reg:DI CA_REGNO))]) 6925 (set (match_operand:DI 0 "") (and:DI (match_dup 1) 6926 (const_int 2047))) 6927 (set (match_dup 3) (plus:DI (match_dup 3) 6928 (const_int 1))) 6929 (set (match_dup 0) (plus:DI (match_dup 0) 6930 (const_int 2047))) 6931 (set (match_dup 4) (compare:CCUNS (match_dup 3) 6932 (const_int 2))) 6933 (set (match_dup 0) (ior:DI (match_dup 0) 6934 (match_dup 1))) 6935 (set (match_dup 0) (and:DI (match_dup 0) 6936 (const_int -2048))) 6937 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) 6938 (label_ref (match_operand:DI 2 "")) 6939 (pc))) 6940 (set (match_dup 0) (match_dup 1))] 6941 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS" 6942 { 6943 operands[3] = gen_reg_rtx (DImode); 6944 operands[4] = gen_reg_rtx (CCUNSmode); 6945 }) 6946 6947 (define_expand "floatunsdisf2" 6948 [(set (match_operand:SF 0 "gpc_reg_operand") 6949 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))] 6950 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" 6951 "") 6952 6953 (define_insn "floatunsdisf2_fcfidus" 6954 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa") 6955 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6956 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" 6957 "@ 6958 fcfidus %0,%1 6959 xscvuxdsp %x0,%x1" 6960 [(set_attr "type" "fp") 6961 (set_attr "isa" "*,p8v")]) 6962 6963 (define_insn_and_split "*floatunsdisf2_mem" 6964 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa") 6965 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 6966 (clobber (match_scratch:DI 2 "=d,d,wa"))] 6967 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" 6968 "#" 6969 "&& reload_completed" 6970 [(pc)] 6971 { 6972 emit_move_insn (operands[2], operands[1]); 6973 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2])); 6974 DONE; 6975 } 6976 [(set_attr "type" "fpload") 6977 (set_attr "length" "8") 6978 (set_attr "isa" "*,p8v,p8v")]) 6979 6980 ;; int fegetround(void) 6981 ;; 6982 ;; This expansion for the C99 function only expands for compatible 6983 ;; target libcs, because it needs to return one of FE_DOWNWARD, 6984 ;; FE_TONEAREST, FE_TOWARDZERO or FE_UPWARD with the values as defined 6985 ;; by the target libc, and since the libc is free to choose the values 6986 ;; (and they may differ from the hardware) and the expander needs to 6987 ;; know then beforehand, this expanded only expands for target libcs 6988 ;; that it can handle the values is knows. 6989 ;; Because of these restriction, this only expands on the desired 6990 ;; case and fallback to a call to libc otherwise. 6991 (define_expand "fegetroundsi" 6992 [(set (match_operand:SI 0 "gpc_reg_operand") 6993 (unspec_volatile:SI [(const_int 0)] UNSPECV_MFFSL))] 6994 "TARGET_HARD_FLOAT" 6995 { 6996 if (!OPTION_GLIBC) 6997 FAIL; 6998 6999 rtx tmp_df = gen_reg_rtx (DFmode); 7000 emit_insn (gen_rs6000_mffsl (tmp_df)); 7001 7002 rtx tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); 7003 rtx tmp_di_2 = gen_reg_rtx (DImode); 7004 emit_insn (gen_anddi3 (tmp_di_2, tmp_di, GEN_INT (3))); 7005 rtx tmp_si = gen_reg_rtx (SImode); 7006 tmp_si = gen_lowpart (SImode, tmp_di_2); 7007 emit_move_insn (operands[0], tmp_si); 7008 DONE; 7009 }) 7010 7011 ;; int feclearexcept(int excepts) 7012 ;; 7013 ;; This expansion for the C99 function only works when EXCEPTS is a 7014 ;; constant known at compile time and specifies any one of 7015 ;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags. 7016 ;; It doesn't handle values out of range, and always returns 0. 7017 ;; Note that FE_INVALID is unsupported because it maps to more than 7018 ;; one bit of the FPSCR register. 7019 ;; The FE_* are defined in the target libc, and since they are free to 7020 ;; choose the values and the expand needs to know them beforehand, 7021 ;; this expander only expands for target libcs that it can handle the 7022 ;; values it knows. 7023 ;; Because of these restrictions, this only expands on the desired 7024 ;; cases and fallback to a call to libc on any other case. 7025 (define_expand "feclearexceptsi" 7026 [(use (match_operand:SI 1 "const_int_operand" "n")) 7027 (set (match_operand:SI 0 "gpc_reg_operand") 7028 (const_int 0))] 7029 "TARGET_HARD_FLOAT" 7030 { 7031 if (!OPTION_GLIBC) 7032 FAIL; 7033 7034 unsigned int fe = INTVAL (operands[1]); 7035 if (fe != (fe & 0x1e000000)) 7036 FAIL; 7037 7038 if (fe & 0x02000000) /* FE_INEXACT */ 7039 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 6))); 7040 if (fe & 0x04000000) /* FE_DIVBYZERO */ 7041 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 5))); 7042 if (fe & 0x08000000) /* FE_UNDERFLOW */ 7043 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 4))); 7044 if (fe & 0x10000000) /* FE_OVERFLOW */ 7045 emit_insn (gen_rs6000_mtfsb0 (gen_rtx_CONST_INT (SImode, 3))); 7046 7047 emit_move_insn (operands[0], const0_rtx); 7048 DONE; 7049 }) 7050 7051 ;; int feraiseexcept(int excepts) 7052 ;; 7053 ;; This expansion for the C99 function only works when excepts is a 7054 ;; constant known at compile time and specifies any one of 7055 ;; FE_INEXACT, FE_DIVBYZERO, FE_UNDERFLOW and FE_OVERFLOW flags. 7056 ;; It doesn't handle values out of range, and always returns 0. 7057 ;; Note that FE_INVALID is unsupported because it maps to more than 7058 ;; one bit of the FPSCR register. 7059 ;; The FE_* are defined in the target libc, and since they are free to 7060 ;; choose the values and the expand needs to know them beforehand, 7061 ;; this expander only expands for target libcs that it can handle the 7062 ;; values it knows. 7063 ;; Because of these restrictions, this only expands on the desired 7064 ;; cases and fallback to a call to libc on any other case. 7065 (define_expand "feraiseexceptsi" 7066 [(use (match_operand:SI 1 "const_int_operand" "n")) 7067 (set (match_operand:SI 0 "gpc_reg_operand") 7068 (const_int 0))] 7069 "TARGET_HARD_FLOAT" 7070 { 7071 if (!OPTION_GLIBC) 7072 FAIL; 7073 7074 unsigned int fe = INTVAL (operands[1]); 7075 if (fe != (fe & 0x1e000000)) 7076 FAIL; 7077 7078 if (fe & 0x02000000) /* FE_INEXACT */ 7079 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 6))); 7080 if (fe & 0x04000000) /* FE_DIVBYZERO */ 7081 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 5))); 7082 if (fe & 0x08000000) /* FE_UNDERFLOW */ 7083 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 4))); 7084 if (fe & 0x10000000) /* FE_OVERFLOW */ 7085 emit_insn (gen_rs6000_mtfsb1 (gen_rtx_CONST_INT (SImode, 3))); 7086 7087 emit_move_insn (operands[0], const0_rtx); 7088 DONE; 7089 }) 7090 7092 ;; Define the TImode operations that can be done in a small number 7093 ;; of instructions. The & constraints are to prevent the register 7094 ;; allocator from allocating registers that overlap with the inputs 7095 ;; (for example, having an input in 7,8 and an output in 6,7). We 7096 ;; also allow for the output being the same as one of the inputs. 7097 7098 (define_expand "addti3" 7099 [(set (match_operand:TI 0 "gpc_reg_operand") 7100 (plus:TI (match_operand:TI 1 "gpc_reg_operand") 7101 (match_operand:TI 2 "reg_or_short_operand")))] 7102 "TARGET_64BIT" 7103 { 7104 rtx lo0 = gen_lowpart (DImode, operands[0]); 7105 rtx lo1 = gen_lowpart (DImode, operands[1]); 7106 rtx lo2 = gen_lowpart (DImode, operands[2]); 7107 rtx hi0 = gen_highpart (DImode, operands[0]); 7108 rtx hi1 = gen_highpart (DImode, operands[1]); 7109 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]); 7110 7111 if (!reg_or_short_operand (lo2, DImode)) 7112 lo2 = force_reg (DImode, lo2); 7113 if (!adde_operand (hi2, DImode)) 7114 hi2 = force_reg (DImode, hi2); 7115 7116 emit_insn (gen_adddi3_carry (lo0, lo1, lo2)); 7117 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2)); 7118 DONE; 7119 }) 7120 7121 (define_expand "subti3" 7122 [(set (match_operand:TI 0 "gpc_reg_operand") 7123 (minus:TI (match_operand:TI 1 "reg_or_short_operand") 7124 (match_operand:TI 2 "gpc_reg_operand")))] 7125 "TARGET_64BIT" 7126 { 7127 rtx lo0 = gen_lowpart (DImode, operands[0]); 7128 rtx lo1 = gen_lowpart (DImode, operands[1]); 7129 rtx lo2 = gen_lowpart (DImode, operands[2]); 7130 rtx hi0 = gen_highpart (DImode, operands[0]); 7131 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]); 7132 rtx hi2 = gen_highpart (DImode, operands[2]); 7133 7134 if (!reg_or_short_operand (lo1, DImode)) 7135 lo1 = force_reg (DImode, lo1); 7136 if (!adde_operand (hi1, DImode)) 7137 hi1 = force_reg (DImode, hi1); 7138 7139 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1)); 7140 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1)); 7141 DONE; 7142 }) 7143 7145 ;; 128-bit logical operations expanders 7146 7147 (define_expand "and<mode>3" 7148 [(set (match_operand:BOOL_128 0 "vlogical_operand") 7149 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 7150 (match_operand:BOOL_128 2 "vlogical_operand")))] 7151 "" 7152 "") 7153 7154 (define_expand "ior<mode>3" 7155 [(set (match_operand:BOOL_128 0 "vlogical_operand") 7156 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 7157 (match_operand:BOOL_128 2 "vlogical_operand")))] 7158 "" 7159 "") 7160 7161 (define_expand "xor<mode>3" 7162 [(set (match_operand:BOOL_128 0 "vlogical_operand") 7163 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 7164 (match_operand:BOOL_128 2 "vlogical_operand")))] 7165 "" 7166 "") 7167 7168 (define_expand "nor<mode>3" 7169 [(set (match_operand:BOOL_128 0 "vlogical_operand") 7170 (and:BOOL_128 7171 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")) 7172 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))] 7173 "" 7174 "") 7175 7176 (define_expand "andc<mode>3" 7177 [(set (match_operand:BOOL_128 0 "vlogical_operand") 7178 (and:BOOL_128 7179 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand")) 7180 (match_operand:BOOL_128 1 "vlogical_operand")))] 7181 "" 7182 "") 7183 7184 ;; Power8 vector logical instructions. 7185 (define_expand "eqv<mode>3" 7186 [(set (match_operand:BOOL_128 0 "vlogical_operand") 7187 (not:BOOL_128 7188 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 7189 (match_operand:BOOL_128 2 "vlogical_operand"))))] 7190 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 7191 "") 7192 7193 ;; Rewrite nand into canonical form 7194 (define_expand "nand<mode>3" 7195 [(set (match_operand:BOOL_128 0 "vlogical_operand") 7196 (ior:BOOL_128 7197 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")) 7198 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))] 7199 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 7200 "") 7201 7202 ;; The canonical form is to have the negated element first, so we need to 7203 ;; reverse arguments. 7204 (define_expand "orc<mode>3" 7205 [(set (match_operand:BOOL_128 0 "vlogical_operand") 7206 (ior:BOOL_128 7207 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand")) 7208 (match_operand:BOOL_128 1 "vlogical_operand")))] 7209 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 7210 "") 7211 7212 ;; 128-bit logical operations insns and split operations 7213 (define_insn_and_split "*and<mode>3_internal" 7214 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 7215 (and:BOOL_128 7216 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 7217 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))] 7218 "" 7219 { 7220 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 7221 return "xxland %x0,%x1,%x2"; 7222 7223 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 7224 return "vand %0,%1,%2"; 7225 7226 return "#"; 7227 } 7228 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 7229 [(const_int 0)] 7230 { 7231 rs6000_split_logical (operands, AND, false, false, false); 7232 DONE; 7233 } 7234 [(set (attr "type") 7235 (if_then_else 7236 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7237 (const_string "veclogical") 7238 (const_string "integer"))) 7239 (set (attr "length") 7240 (if_then_else 7241 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7242 (const_string "4") 7243 (if_then_else 7244 (match_test "TARGET_POWERPC64") 7245 (const_string "8") 7246 (const_string "16"))))]) 7247 7248 ;; 128-bit IOR/XOR 7249 (define_insn_and_split "*bool<mode>3_internal" 7250 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 7251 (match_operator:BOOL_128 3 "boolean_or_operator" 7252 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 7253 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))] 7254 "" 7255 { 7256 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 7257 return "xxl%q3 %x0,%x1,%x2"; 7258 7259 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 7260 return "v%q3 %0,%1,%2"; 7261 7262 return "#"; 7263 } 7264 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 7265 [(const_int 0)] 7266 { 7267 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false); 7268 DONE; 7269 } 7270 [(set (attr "type") 7271 (if_then_else 7272 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7273 (const_string "veclogical") 7274 (const_string "integer"))) 7275 (set (attr "length") 7276 (if_then_else 7277 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7278 (const_string "4") 7279 (if_then_else 7280 (match_test "TARGET_POWERPC64") 7281 (const_string "8") 7282 (const_string "16"))))]) 7283 7284 ;; 128-bit ANDC/ORC 7285 (define_insn_and_split "*boolc<mode>3_internal1" 7286 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 7287 (match_operator:BOOL_128 3 "boolean_operator" 7288 [(not:BOOL_128 7289 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")) 7290 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))] 7291 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 7292 { 7293 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 7294 return "xxl%q3 %x0,%x1,%x2"; 7295 7296 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 7297 return "v%q3 %0,%1,%2"; 7298 7299 return "#"; 7300 } 7301 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 7302 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 7303 [(const_int 0)] 7304 { 7305 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 7306 DONE; 7307 } 7308 [(set (attr "type") 7309 (if_then_else 7310 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7311 (const_string "veclogical") 7312 (const_string "integer"))) 7313 (set (attr "length") 7314 (if_then_else 7315 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7316 (const_string "4") 7317 (if_then_else 7318 (match_test "TARGET_POWERPC64") 7319 (const_string "8") 7320 (const_string "16"))))]) 7321 7322 (define_insn_and_split "*boolc<mode>3_internal2" 7323 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 7324 (match_operator:TI2 3 "boolean_operator" 7325 [(not:TI2 7326 (match_operand:TI2 2 "int_reg_operand" "r,0,r")) 7327 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))] 7328 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 7329 "#" 7330 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 7331 [(const_int 0)] 7332 { 7333 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 7334 DONE; 7335 } 7336 [(set_attr "type" "integer") 7337 (set (attr "length") 7338 (if_then_else 7339 (match_test "TARGET_POWERPC64") 7340 (const_string "8") 7341 (const_string "16")))]) 7342 7343 ;; 128-bit NAND/NOR 7344 (define_insn_and_split "*boolcc<mode>3_internal1" 7345 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 7346 (match_operator:BOOL_128 3 "boolean_operator" 7347 [(not:BOOL_128 7348 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")) 7349 (not:BOOL_128 7350 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))] 7351 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 7352 { 7353 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 7354 return "xxl%q3 %x0,%x1,%x2"; 7355 7356 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 7357 return "v%q3 %0,%1,%2"; 7358 7359 return "#"; 7360 } 7361 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 7362 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 7363 [(const_int 0)] 7364 { 7365 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 7366 DONE; 7367 } 7368 [(set (attr "type") 7369 (if_then_else 7370 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7371 (const_string "veclogical") 7372 (const_string "integer"))) 7373 (set (attr "length") 7374 (if_then_else 7375 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7376 (const_string "4") 7377 (if_then_else 7378 (match_test "TARGET_POWERPC64") 7379 (const_string "8") 7380 (const_string "16"))))]) 7381 7382 (define_insn_and_split "*boolcc<mode>3_internal2" 7383 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 7384 (match_operator:TI2 3 "boolean_operator" 7385 [(not:TI2 7386 (match_operand:TI2 1 "int_reg_operand" "r,0,r")) 7387 (not:TI2 7388 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))] 7389 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 7390 "#" 7391 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 7392 [(const_int 0)] 7393 { 7394 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 7395 DONE; 7396 } 7397 [(set_attr "type" "integer") 7398 (set (attr "length") 7399 (if_then_else 7400 (match_test "TARGET_POWERPC64") 7401 (const_string "8") 7402 (const_string "16")))]) 7403 7404 7405 ;; 128-bit EQV 7406 (define_insn_and_split "*eqv<mode>3_internal1" 7407 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 7408 (not:BOOL_128 7409 (xor:BOOL_128 7410 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>") 7411 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))] 7412 "TARGET_P8_VECTOR" 7413 { 7414 if (vsx_register_operand (operands[0], <MODE>mode)) 7415 return "xxleqv %x0,%x1,%x2"; 7416 7417 return "#"; 7418 } 7419 "TARGET_P8_VECTOR && reload_completed 7420 && int_reg_operand (operands[0], <MODE>mode)" 7421 [(const_int 0)] 7422 { 7423 rs6000_split_logical (operands, XOR, true, false, false); 7424 DONE; 7425 } 7426 [(set (attr "type") 7427 (if_then_else 7428 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7429 (const_string "veclogical") 7430 (const_string "integer"))) 7431 (set (attr "length") 7432 (if_then_else 7433 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7434 (const_string "4") 7435 (if_then_else 7436 (match_test "TARGET_POWERPC64") 7437 (const_string "8") 7438 (const_string "16"))))]) 7439 7440 (define_insn_and_split "*eqv<mode>3_internal2" 7441 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 7442 (not:TI2 7443 (xor:TI2 7444 (match_operand:TI2 1 "int_reg_operand" "r,0,r") 7445 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))] 7446 "!TARGET_P8_VECTOR" 7447 "#" 7448 "reload_completed && !TARGET_P8_VECTOR" 7449 [(const_int 0)] 7450 { 7451 rs6000_split_logical (operands, XOR, true, false, false); 7452 DONE; 7453 } 7454 [(set_attr "type" "integer") 7455 (set (attr "length") 7456 (if_then_else 7457 (match_test "TARGET_POWERPC64") 7458 (const_string "8") 7459 (const_string "16")))]) 7460 7461 ;; 128-bit one's complement 7462 (define_insn_and_split "one_cmpl<mode>2" 7463 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 7464 (not:BOOL_128 7465 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))] 7466 "" 7467 { 7468 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 7469 return "xxlnor %x0,%x1,%x1"; 7470 7471 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 7472 return "vnor %0,%1,%1"; 7473 7474 return "#"; 7475 } 7476 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 7477 [(const_int 0)] 7478 { 7479 rs6000_split_logical (operands, NOT, false, false, false); 7480 DONE; 7481 } 7482 [(set (attr "type") 7483 (if_then_else 7484 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7485 (const_string "veclogical") 7486 (const_string "integer"))) 7487 (set (attr "length") 7488 (if_then_else 7489 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 7490 (const_string "4") 7491 (if_then_else 7492 (match_test "TARGET_POWERPC64") 7493 (const_string "8") 7494 (const_string "16"))))]) 7495 7496 7498 ;; Now define ways of moving data around. 7499 7500 ;; Set up a register with a value from the GOT table 7501 7502 (define_expand "movsi_got" 7503 [(set (match_operand:SI 0 "gpc_reg_operand") 7504 (unspec:SI [(match_operand:SI 1 "got_operand") 7505 (match_dup 2)] UNSPEC_MOVSI_GOT))] 7506 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 7507 { 7508 if (GET_CODE (operands[1]) == CONST) 7509 { 7510 rtx offset = const0_rtx; 7511 HOST_WIDE_INT value; 7512 7513 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset); 7514 value = INTVAL (offset); 7515 if (value != 0) 7516 { 7517 rtx tmp = (!can_create_pseudo_p () 7518 ? operands[0] 7519 : gen_reg_rtx (Pmode)); 7520 emit_insn (gen_movsi_got (tmp, operands[1])); 7521 emit_insn (gen_addsi3 (operands[0], tmp, offset)); 7522 DONE; 7523 } 7524 } 7525 7526 operands[2] = rs6000_got_register (operands[1]); 7527 }) 7528 7529 (define_insn "*movsi_got_internal" 7530 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 7531 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") 7532 (match_operand:SI 2 "gpc_reg_operand" "b")] 7533 UNSPEC_MOVSI_GOT))] 7534 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 7535 "lwz %0,%a1@got(%2)" 7536 [(set_attr "type" "load")]) 7537 7538 ;; Used by sched, shorten_branches and final when the GOT pseudo reg 7539 ;; didn't get allocated to a hard register. 7540 (define_split 7541 [(set (match_operand:SI 0 "gpc_reg_operand") 7542 (unspec:SI [(match_operand:SI 1 "got_no_const_operand") 7543 (match_operand:SI 2 "memory_operand")] 7544 UNSPEC_MOVSI_GOT))] 7545 "DEFAULT_ABI == ABI_V4 7546 && flag_pic == 1 7547 && reload_completed" 7548 [(set (match_dup 0) (match_dup 2)) 7549 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 7550 UNSPEC_MOVSI_GOT))] 7551 "") 7552 7553 ;; MR LA 7554 ;; LWZ LFIWZX LXSIWZX 7555 ;; STW STFIWX STXSIWX 7556 ;; LI LIS PLI # 7557 ;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW 7558 ;; XXLXOR 0 XXLORC -1 P9 const 7559 ;; MTVSRWZ MFVSRWZ 7560 ;; MF%1 MT%0 NOP 7561 7562 (define_insn "*movsi_internal1" 7563 [(set (match_operand:SI 0 "nonimmediate_operand" 7564 "=r, r, 7565 r, d, v, 7566 m, ?Z, ?Z, 7567 r, r, r, r, 7568 wa, wa, wa, v, 7569 wa, v, v, 7570 wa, r, 7571 r, *h, *h") 7572 (match_operand:SI 1 "input_operand" 7573 "r, U, 7574 m, ?Z, ?Z, 7575 r, d, v, 7576 I, L, eI, n, 7577 wa, O, wM, wB, 7578 O, wM, wS, 7579 r, wa, 7580 *h, r, 0"))] 7581 "gpc_reg_operand (operands[0], SImode) 7582 || gpc_reg_operand (operands[1], SImode)" 7583 "@ 7584 mr %0,%1 7585 la %0,%a1 7586 lwz%U1%X1 %0,%1 7587 lfiwzx %0,%y1 7588 lxsiwzx %x0,%y1 7589 stw%U0%X0 %1,%0 7590 stfiwx %1,%y0 7591 stxsiwx %x1,%y0 7592 li %0,%1 7593 lis %0,%v1 7594 li %0,%1 7595 # 7596 xxlor %x0,%x1,%x1 7597 xxspltib %x0,0 7598 xxspltib %x0,255 7599 vspltisw %0,%1 7600 xxlxor %x0,%x0,%x0 7601 xxlorc %x0,%x0,%x0 7602 # 7603 mtvsrwz %x0,%1 7604 mfvsrwz %0,%x1 7605 mf%1 %0 7606 mt%0 %1 7607 nop" 7608 [(set_attr "type" 7609 "*, *, 7610 load, fpload, fpload, 7611 store, fpstore, fpstore, 7612 *, *, *, *, 7613 veclogical, vecsimple, vecsimple, vecsimple, 7614 veclogical, veclogical, vecsimple, 7615 mtvsr, mfvsr, 7616 *, *, *") 7617 (set_attr "length" 7618 "*, *, 7619 *, *, *, 7620 *, *, *, 7621 *, *, *, 8, 7622 *, *, *, *, 7623 *, *, 8, 7624 *, *, 7625 *, *, *") 7626 (set_attr "isa" 7627 "*, *, 7628 *, p8v, p8v, 7629 *, p8v, p8v, 7630 *, *, p10, *, 7631 p8v, p9v, p9v, p8v, 7632 p9v, p8v, p9v, 7633 p8v, p8v, 7634 *, *, *")]) 7635 7636 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e. 7637 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0)) 7638 ;; 7639 ;; Because SF values are actually stored as DF values within the vector 7640 ;; registers, we need to convert the value to the vector SF format when 7641 ;; we need to use the bits in a union or similar cases. We only need 7642 ;; to do this transformation when the value is a vector register. Loads, 7643 ;; stores, and transfers within GPRs are assumed to be safe. 7644 ;; 7645 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have 7646 ;; no alternatives, because the call is created as part of secondary_reload, 7647 ;; and operand #2's register class is used to allocate the temporary register. 7648 ;; This function is called before reload, and it creates the temporary as 7649 ;; needed. 7650 7651 ;; MR LWZ LFIWZX LXSIWZX STW 7652 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX 7653 ;; MTVSRWZ 7654 7655 (define_insn_and_split "movsi_from_sf" 7656 [(set (match_operand:SI 0 "nonimmediate_operand" 7657 "=r, r, ?*d, ?*v, m, 7658 m, wY, Z, r, ?*wa, 7659 wa") 7660 (unspec:SI [(match_operand:SF 1 "input_operand" 7661 "r, m, Z, Z, r, 7662 f, v, wa, wa, wa, 7663 r")] 7664 UNSPEC_SI_FROM_SF)) 7665 (clobber (match_scratch:V4SF 2 7666 "=X, X, X, X, X, 7667 X, X, X, wa, X, 7668 X"))] 7669 "TARGET_NO_SF_SUBREG 7670 && (register_operand (operands[0], SImode) 7671 || register_operand (operands[1], SFmode))" 7672 "@ 7673 mr %0,%1 7674 lwz%U1%X1 %0,%1 7675 lfiwzx %0,%y1 7676 lxsiwzx %x0,%y1 7677 stw%U0%X0 %1,%0 7678 stfs%U0%X0 %1,%0 7679 stxssp %1,%0 7680 stxsspx %x1,%y0 7681 # 7682 xscvdpspn %x0,%x1 7683 mtvsrwz %x0,%1" 7684 "&& reload_completed 7685 && int_reg_operand (operands[0], SImode) 7686 && vsx_reg_sfsubreg_ok (operands[1], SFmode)" 7687 [(const_int 0)] 7688 { 7689 rtx op0 = operands[0]; 7690 rtx op1 = operands[1]; 7691 rtx op2 = operands[2]; 7692 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0)); 7693 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 7694 7695 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 7696 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si)); 7697 DONE; 7698 } 7699 [(set_attr "type" 7700 "*, load, fpload, fpload, store, 7701 fpstore, fpstore, fpstore, mfvsr, fp, 7702 mtvsr") 7703 (set_attr "length" 7704 "*, *, *, *, *, 7705 *, *, *, 8, *, 7706 *") 7707 (set_attr "isa" 7708 "*, *, p8v, p8v, *, 7709 *, p9v, p8v, p8v, p8v, 7710 p8v")]) 7711 7712 ;; movsi_from_sf with zero extension 7713 ;; 7714 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR 7715 ;; VSX->VSX MTVSRWZ 7716 7717 (define_insn_and_split "*movdi_from_sf_zero_ext" 7718 [(set (match_operand:DI 0 "gpc_reg_operand" 7719 "=r, r, ?*d, ?*v, r, 7720 ?v, wa") 7721 (zero_extend:DI 7722 (unspec:SI [(match_operand:SF 1 "input_operand" 7723 "r, m, Z, Z, wa, 7724 wa, r")] 7725 UNSPEC_SI_FROM_SF))) 7726 (clobber (match_scratch:V4SF 2 7727 "=X, X, X, X, wa, 7728 wa, X"))] 7729 "TARGET_DIRECT_MOVE_64BIT 7730 && (register_operand (operands[0], DImode) 7731 || register_operand (operands[1], SImode))" 7732 "@ 7733 rldicl %0,%1,0,32 7734 lwz%U1%X1 %0,%1 7735 lfiwzx %0,%y1 7736 lxsiwzx %x0,%y1 7737 # 7738 # 7739 mtvsrwz %x0,%1" 7740 "&& reload_completed 7741 && register_operand (operands[0], DImode) 7742 && vsx_reg_sfsubreg_ok (operands[1], SFmode)" 7743 [(const_int 0)] 7744 { 7745 rtx op0 = operands[0]; 7746 rtx op1 = operands[1]; 7747 rtx op2 = operands[2]; 7748 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 7749 7750 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 7751 emit_insn (gen_zero_extendsidi2 (op0, op2_si)); 7752 DONE; 7753 } 7754 [(set_attr "type" 7755 "*, load, fpload, fpload, two, 7756 two, mtvsr") 7757 (set_attr "length" 7758 "*, *, *, *, 8, 7759 8, *") 7760 (set_attr "isa" 7761 "*, *, p8v, p8v, p8v, 7762 p9v, p8v")]) 7763 7764 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before 7765 ;; moving it to SImode. We cannot do a SFmode store without having to do the 7766 ;; conversion explicitly since that doesn't work in most cases if the input 7767 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the 7768 ;; former handles cases where the input will not fit in a SFmode, and the 7769 ;; latter assumes the value has already been rounded. 7770 (define_insn "*movsi_from_df" 7771 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa") 7772 (unspec:SI [(float_truncate:SF 7773 (match_operand:DF 1 "gpc_reg_operand" "wa"))] 7774 UNSPEC_SI_FROM_SF))] 7775 "TARGET_NO_SF_SUBREG" 7776 "xscvdpsp %x0,%x1" 7777 [(set_attr "type" "fp")]) 7778 7779 ;; Split a load of a large constant into the appropriate two-insn 7780 ;; sequence. 7781 7782 (define_split 7783 [(set (match_operand:SI 0 "gpc_reg_operand") 7784 (match_operand:SI 1 "const_int_operand"))] 7785 "num_insns_constant (operands[1], SImode) > 1" 7786 [(set (match_dup 0) 7787 (match_dup 2)) 7788 (set (match_dup 0) 7789 (ior:SI (match_dup 0) 7790 (match_dup 3)))] 7791 { 7792 if (rs6000_emit_set_const (operands[0], operands[1])) 7793 DONE; 7794 else 7795 FAIL; 7796 }) 7797 7798 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D 7799 (define_split 7800 [(set (match_operand:DI 0 "altivec_register_operand") 7801 (match_operand:DI 1 "xxspltib_constant_split"))] 7802 "TARGET_P9_VECTOR && reload_completed" 7803 [(const_int 0)] 7804 { 7805 rtx op0 = operands[0]; 7806 rtx op1 = operands[1]; 7807 int r = REGNO (op0); 7808 rtx op0_v16qi = gen_rtx_REG (V16QImode, r); 7809 7810 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1)); 7811 emit_insn (gen_vsx_sign_extend_v16qi_si (operands[0], op0_v16qi)); 7812 DONE; 7813 }) 7814 7815 (define_insn "*mov<mode>_internal2" 7816 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y") 7817 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r") 7818 (const_int 0))) 7819 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))] 7820 "" 7821 "@ 7822 cmp<wd>i %2,%0,0 7823 mr. %0,%1 7824 #" 7825 [(set_attr "type" "cmp,logical,cmp") 7826 (set_attr "dot" "yes") 7827 (set_attr "length" "4,4,8")]) 7828 7829 (define_split 7830 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand") 7831 (compare:CC (match_operand:P 1 "gpc_reg_operand") 7832 (const_int 0))) 7833 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))] 7834 "reload_completed" 7835 [(set (match_dup 0) (match_dup 1)) 7836 (set (match_dup 2) 7837 (compare:CC (match_dup 0) 7838 (const_int 0)))] 7839 "") 7840 7842 (define_expand "mov<mode>" 7843 [(set (match_operand:INT 0 "general_operand") 7844 (match_operand:INT 1 "any_operand"))] 7845 "" 7846 { 7847 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7848 DONE; 7849 }) 7850 7851 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI 7852 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ 7853 ;; MTVSRWZ MF%1 MT%1 NOP 7854 (define_insn "*mov<mode>_internal" 7855 [(set (match_operand:QHI 0 "nonimmediate_operand" 7856 "=r, r, wa, m, ?Z, r, 7857 wa, wa, wa, v, ?v, r, 7858 wa, r, *c*l, *h") 7859 (match_operand:QHI 1 "input_operand" 7860 "r, m, ?Z, r, wa, i, 7861 wa, O, wM, wB, wS, wa, 7862 r, *h, r, 0"))] 7863 "gpc_reg_operand (operands[0], <MODE>mode) 7864 || gpc_reg_operand (operands[1], <MODE>mode)" 7865 "@ 7866 mr %0,%1 7867 l<wd>z%U1%X1 %0,%1 7868 lxsi<wd>zx %x0,%y1 7869 st<wd>%U0%X0 %1,%0 7870 stxsi<wd>x %x1,%y0 7871 li %0,%1 7872 xxlor %x0,%x1,%x1 7873 xxspltib %x0,0 7874 xxspltib %x0,255 7875 vspltis<wd> %0,%1 7876 # 7877 mfvsrwz %0,%x1 7878 mtvsrwz %x0,%1 7879 mf%1 %0 7880 mt%0 %1 7881 nop" 7882 [(set_attr "type" 7883 "*, load, fpload, store, fpstore, *, 7884 vecsimple, vecperm, vecperm, vecperm, vecperm, mfvsr, 7885 mtvsr, mfjmpr, mtjmpr, *") 7886 (set_attr "length" 7887 "*, *, *, *, *, *, 7888 *, *, *, *, 8, *, 7889 *, *, *, *") 7890 (set_attr "isa" 7891 "*, *, p9v, *, p9v, *, 7892 p9v, p9v, p9v, p9v, p9v, p9v, 7893 p9v, *, *, *")]) 7894 7895 7897 ;; Here is how to move condition codes around. When we store CC data in 7898 ;; an integer register or memory, we store just the high-order 4 bits. 7899 ;; This lets us not shift in the most common case of CR0. 7900 (define_expand "movcc" 7901 [(set (match_operand:CC 0 "nonimmediate_operand") 7902 (match_operand:CC 1 "nonimmediate_operand"))] 7903 "" 7904 "") 7905 7906 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP]) 7907 7908 (define_insn "*movcc_<mode>" 7909 [(set (match_operand:CC_any 0 "nonimmediate_operand" 7910 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m") 7911 (match_operand:CC_any 1 "general_operand" 7912 " y,r, r,O,x,y,r,I,*h, r,m,r"))] 7913 "register_operand (operands[0], <MODE>mode) 7914 || register_operand (operands[1], <MODE>mode)" 7915 "@ 7916 mcrf %0,%1 7917 mtcrf 128,%1 7918 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff 7919 crxor %0,%0,%0 7920 mfcr %0%Q1 7921 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000 7922 mr %0,%1 7923 li %0,%1 7924 mf%1 %0 7925 mt%0 %1 7926 lwz%U1%X1 %0,%1 7927 stw%U0%X0 %1,%0" 7928 [(set_attr_alternative "type" 7929 [(const_string "cr_logical") 7930 (const_string "mtcr") 7931 (const_string "mtcr") 7932 (const_string "cr_logical") 7933 (if_then_else (match_test "TARGET_MFCRF") 7934 (const_string "mfcrf") (const_string "mfcr")) 7935 (if_then_else (match_test "TARGET_MFCRF") 7936 (const_string "mfcrf") (const_string "mfcr")) 7937 (const_string "integer") 7938 (const_string "integer") 7939 (const_string "mfjmpr") 7940 (const_string "mtjmpr") 7941 (const_string "load") 7942 (const_string "store")]) 7943 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")]) 7944 7946 ;; For floating-point, we normally deal with the floating-point registers 7947 ;; unless -msoft-float is used. The sole exception is that parameter passing 7948 ;; can produce floating-point values in fixed-point registers. Unless the 7949 ;; value is a simple constant or already in memory, we deal with this by 7950 ;; allocating memory and copying the value explicitly via that memory location. 7951 7952 ;; Move 32-bit binary/decimal floating point 7953 (define_expand "mov<mode>" 7954 [(set (match_operand:FMOVE32 0 "nonimmediate_operand") 7955 (match_operand:FMOVE32 1 "any_operand"))] 7956 "<fmove_ok>" 7957 { 7958 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7959 DONE; 7960 }) 7961 7962 (define_split 7963 [(set (match_operand:FMOVE32 0 "gpc_reg_operand") 7964 (match_operand:FMOVE32 1 "const_double_operand"))] 7965 "reload_completed 7966 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 7967 || (SUBREG_P (operands[0]) 7968 && REG_P (SUBREG_REG (operands[0])) 7969 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7970 [(set (match_dup 2) (match_dup 3))] 7971 { 7972 long l; 7973 7974 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7975 7976 if (! TARGET_POWERPC64) 7977 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); 7978 else 7979 operands[2] = gen_lowpart (SImode, operands[0]); 7980 7981 operands[3] = gen_int_mode (l, SImode); 7982 }) 7983 7984 ;; Originally, we tried to keep movsf and movsd common, but the differences 7985 ;; addressing was making it rather difficult to hide with mode attributes. In 7986 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store 7987 ;; before the VSX stores meant that the register allocator would tend to do a 7988 ;; direct move to the GPR (which involves conversion from scalar to 7989 ;; vector/memory formats) to save values in the traditional Altivec registers, 7990 ;; while SDmode had problems on power6 if the GPR store was not first due to 7991 ;; the power6 not having an integer store operation. 7992 ;; 7993 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP 7994 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP 7995 ;; MR MT<x> MF<x> NOP XXSPLTIDP 7996 7997 (define_insn "movsf_hardfloat" 7998 [(set (match_operand:SF 0 "nonimmediate_operand" 7999 "=!r, f, v, wa, m, wY, 8000 Z, m, wa, !r, f, wa, 8001 !r, *c*l, !r, *h, wa") 8002 (match_operand:SF 1 "input_operand" 8003 "m, m, wY, Z, f, v, 8004 wa, r, j, j, f, wa, 8005 r, r, *h, 0, eP"))] 8006 "(register_operand (operands[0], SFmode) 8007 || register_operand (operands[1], SFmode)) 8008 && TARGET_HARD_FLOAT 8009 && (TARGET_ALLOW_SF_SUBREG 8010 || valid_sf_si_move (operands[0], operands[1], SFmode))" 8011 "@ 8012 lwz%U1%X1 %0,%1 8013 lfs%U1%X1 %0,%1 8014 lxssp %0,%1 8015 lxsspx %x0,%y1 8016 stfs%U0%X0 %1,%0 8017 stxssp %1,%0 8018 stxsspx %x1,%y0 8019 stw%U0%X0 %1,%0 8020 xxlxor %x0,%x0,%x0 8021 li %0,0 8022 fmr %0,%1 8023 xscpsgndp %x0,%x1,%x1 8024 mr %0,%1 8025 mt%0 %1 8026 mf%1 %0 8027 nop 8028 #" 8029 [(set_attr "type" 8030 "load, fpload, fpload, fpload, fpstore, fpstore, 8031 fpstore, store, veclogical, integer, fpsimple, fpsimple, 8032 *, mtjmpr, mfjmpr, *, vecperm") 8033 (set_attr "isa" 8034 "*, *, p9v, p8v, *, p9v, 8035 p8v, *, *, *, *, *, 8036 *, *, *, *, p10") 8037 (set_attr "prefixed" 8038 "*, *, *, *, *, *, 8039 *, *, *, *, *, *, 8040 *, *, *, *, yes")]) 8041 8042 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ 8043 ;; FMR MR MT%0 MF%1 NOP 8044 (define_insn "movsd_hardfloat" 8045 [(set (match_operand:SD 0 "nonimmediate_operand" 8046 "=!r, d, m, ?Z, ?d, ?r, 8047 f, !r, *c*l, !r, *h") 8048 (match_operand:SD 1 "input_operand" 8049 "m, ?Z, r, wx, r, d, 8050 f, r, r, *h, 0"))] 8051 "(register_operand (operands[0], SDmode) 8052 || register_operand (operands[1], SDmode)) 8053 && TARGET_HARD_FLOAT" 8054 "@ 8055 lwz%U1%X1 %0,%1 8056 lfiwzx %0,%y1 8057 stw%U0%X0 %1,%0 8058 stfiwx %1,%y0 8059 mtvsrwz %x0,%1 8060 mfvsrwz %0,%x1 8061 fmr %0,%1 8062 mr %0,%1 8063 mt%0 %1 8064 mf%1 %0 8065 nop" 8066 [(set_attr "type" 8067 "load, fpload, store, fpstore, mtvsr, mfvsr, 8068 fpsimple, *, mtjmpr, mfjmpr, *") 8069 (set_attr "isa" 8070 "*, p7, *, *, p8v, p8v, 8071 *, *, *, *, *")]) 8072 8073 ;; MR MT%0 MF%0 LWZ STW LI 8074 ;; LIS G-const. F/n-const NOP 8075 (define_insn "*mov<mode>_softfloat" 8076 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" 8077 "=r, *c*l, r, r, m, r, 8078 r, r, r, *h") 8079 8080 (match_operand:FMOVE32 1 "input_operand" 8081 "r, r, *h, m, r, I, 8082 L, G, Fn, 0"))] 8083 8084 "(gpc_reg_operand (operands[0], <MODE>mode) 8085 || gpc_reg_operand (operands[1], <MODE>mode)) 8086 && TARGET_SOFT_FLOAT" 8087 "@ 8088 mr %0,%1 8089 mt%0 %1 8090 mf%1 %0 8091 lwz%U1%X1 %0,%1 8092 stw%U0%X0 %1,%0 8093 li %0,%1 8094 lis %0,%v1 8095 # 8096 # 8097 nop" 8098 [(set_attr "type" 8099 "*, mtjmpr, mfjmpr, load, store, *, 8100 *, *, *, *") 8101 8102 (set_attr "length" 8103 "*, *, *, *, *, *, 8104 *, *, 8, *")]) 8105 8106 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e. 8107 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0)) 8108 ;; 8109 ;; Because SF values are actually stored as DF values within the vector 8110 ;; registers, we need to convert the value to the vector SF format when 8111 ;; we need to use the bits in a union or similar cases. We only need 8112 ;; to do this transformation when the value is a vector register. Loads, 8113 ;; stores, and transfers within GPRs are assumed to be safe. 8114 ;; 8115 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have 8116 ;; no alternatives, because the call is created as part of secondary_reload, 8117 ;; and operand #2's register class is used to allocate the temporary register. 8118 ;; This function is called before reload, and it creates the temporary as 8119 ;; needed. 8120 8121 ;; LWZ LFS LXSSP LXSSPX STW STFIWX 8122 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR 8123 (define_insn_and_split "movsf_from_si" 8124 [(set (match_operand:SF 0 "nonimmediate_operand" 8125 "=!r, f, v, wa, m, Z, 8126 Z, wa, ?r, !r") 8127 (unspec:SF [(match_operand:SI 1 "input_operand" 8128 "m, m, wY, Z, r, f, 8129 wa, r, wa, r")] 8130 UNSPEC_SF_FROM_SI)) 8131 (clobber (match_scratch:DI 2 8132 "=X, X, X, X, X, X, 8133 X, r, X, X"))] 8134 "TARGET_NO_SF_SUBREG 8135 && (register_operand (operands[0], SFmode) 8136 || register_operand (operands[1], SImode))" 8137 "@ 8138 lwz%U1%X1 %0,%1 8139 lfs%U1%X1 %0,%1 8140 lxssp %0,%1 8141 lxsspx %x0,%y1 8142 stw%U0%X0 %1,%0 8143 stfiwx %1,%y0 8144 stxsiwx %x1,%y0 8145 # 8146 mfvsrwz %0,%x1 8147 mr %0,%1" 8148 8149 "&& reload_completed 8150 && vsx_reg_sfsubreg_ok (operands[0], SFmode) 8151 && int_reg_operand_not_pseudo (operands[1], SImode)" 8152 [(const_int 0)] 8153 { 8154 rtx op0 = operands[0]; 8155 rtx op1 = operands[1]; 8156 rtx op2 = operands[2]; 8157 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1)); 8158 8159 /* Move SF value to upper 32-bits for xscvspdpn. */ 8160 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 8161 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 8162 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 8163 DONE; 8164 } 8165 [(set_attr "length" 8166 "*, *, *, *, *, *, 8167 *, 12, *, *") 8168 (set_attr "type" 8169 "load, fpload, fpload, fpload, store, fpstore, 8170 fpstore, vecfloat, mfvsr, *") 8171 (set_attr "isa" 8172 "*, *, p9v, p8v, *, *, 8173 p8v, p8v, p8v, *")]) 8174 8175 ;; For extracting high part element from DImode register like: 8176 ;; {%1:SF=unspec[r122:DI>>0x20#0] 86;clobber scratch;} 8177 ;; split it before reload with "and mask" to avoid generating shift right 8178 ;; 32 bit then shift left 32 bit. 8179 (define_insn_and_split "movsf_from_si2" 8180 [(set (match_operand:SF 0 "gpc_reg_operand" "=wa") 8181 (unspec:SF 8182 [(subreg:SI 8183 (ashiftrt:DI 8184 (match_operand:DI 1 "input_operand" "r") 8185 (const_int 32)) 8186 0)] 8187 UNSPEC_SF_FROM_SI)) 8188 (clobber (match_scratch:DI 2 "=r"))] 8189 "TARGET_NO_SF_SUBREG" 8190 "#" 8191 "&& 1" 8192 [(const_int 0)] 8193 { 8194 if (GET_CODE (operands[2]) == SCRATCH) 8195 operands[2] = gen_reg_rtx (DImode); 8196 8197 rtx mask = GEN_INT (HOST_WIDE_INT_M1U << 32); 8198 emit_insn (gen_anddi3 (operands[2], operands[1], mask)); 8199 emit_insn (gen_p8_mtvsrd_sf (operands[0], operands[2])); 8200 emit_insn (gen_vsx_xscvspdpn_directmove (operands[0], operands[0])); 8201 DONE; 8202 } 8203 [(set_attr "length" "12") 8204 (set_attr "type" "vecfloat") 8205 (set_attr "isa" "p8v")]) 8206 8208 ;; Move 64-bit binary/decimal floating point 8209 (define_expand "mov<mode>" 8210 [(set (match_operand:FMOVE64 0 "nonimmediate_operand") 8211 (match_operand:FMOVE64 1 "any_operand"))] 8212 "" 8213 { 8214 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 8215 DONE; 8216 }) 8217 8218 (define_split 8219 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 8220 (match_operand:FMOVE64 1 "const_int_operand"))] 8221 "! TARGET_POWERPC64 && reload_completed 8222 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 8223 || (SUBREG_P (operands[0]) 8224 && REG_P (SUBREG_REG (operands[0])) 8225 && REGNO (SUBREG_REG (operands[0])) <= 31))" 8226 [(set (match_dup 2) (match_dup 4)) 8227 (set (match_dup 3) (match_dup 1))] 8228 { 8229 int endian = (WORDS_BIG_ENDIAN == 0); 8230 HOST_WIDE_INT value = INTVAL (operands[1]); 8231 8232 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 8233 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 8234 operands[4] = GEN_INT (value >> 32); 8235 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 8236 }) 8237 8238 (define_split 8239 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 8240 (match_operand:FMOVE64 1 "const_double_operand"))] 8241 "! TARGET_POWERPC64 && reload_completed 8242 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 8243 || (SUBREG_P (operands[0]) 8244 && REG_P (SUBREG_REG (operands[0])) 8245 && REGNO (SUBREG_REG (operands[0])) <= 31))" 8246 [(set (match_dup 2) (match_dup 4)) 8247 (set (match_dup 3) (match_dup 5))] 8248 { 8249 int endian = (WORDS_BIG_ENDIAN == 0); 8250 long l[2]; 8251 8252 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 8253 8254 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 8255 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 8256 operands[4] = gen_int_mode (l[endian], SImode); 8257 operands[5] = gen_int_mode (l[1 - endian], SImode); 8258 }) 8259 8260 (define_split 8261 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 8262 (match_operand:FMOVE64 1 "const_double_operand"))] 8263 "TARGET_POWERPC64 && reload_completed 8264 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 8265 || (SUBREG_P (operands[0]) 8266 && REG_P (SUBREG_REG (operands[0])) 8267 && REGNO (SUBREG_REG (operands[0])) <= 31))" 8268 [(set (match_dup 2) (match_dup 3))] 8269 { 8270 int endian = (WORDS_BIG_ENDIAN == 0); 8271 long l[2]; 8272 HOST_WIDE_INT val; 8273 8274 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 8275 8276 operands[2] = gen_lowpart (DImode, operands[0]); 8277 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ 8278 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 8279 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); 8280 8281 operands[3] = gen_int_mode (val, DImode); 8282 }) 8283 8284 ;; Don't have reload use general registers to load a constant. It is 8285 ;; less efficient than loading the constant into an FP register, since 8286 ;; it will probably be used there. 8287 8288 ;; The move constraints are ordered to prefer floating point registers before 8289 ;; general purpose registers to avoid doing a store and a load to get the value 8290 ;; into a floating point register when it is needed for a floating point 8291 ;; operation. Prefer traditional floating point registers over VSX registers, 8292 ;; since the D-form version of the memory instructions does not need a GPR for 8293 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec 8294 ;; registers. 8295 8296 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory, 8297 ;; except for 0.0 which can be created on VSX with an xor instruction. 8298 8299 ;; STFD LFD FMR LXSD STXSD 8300 ;; LXSD STXSD XXLOR XXLXOR GPR<-0 8301 ;; LWZ STW MR XXSPLTIDP 8302 8303 8304 (define_insn "*mov<mode>_hardfloat32" 8305 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 8306 "=m, d, d, <f64_p9>, wY, 8307 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r, 8308 Y, r, !r, wa") 8309 (match_operand:FMOVE64 1 "input_operand" 8310 "d, m, d, wY, <f64_p9>, 8311 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>, 8312 r, Y, r, eP"))] 8313 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT 8314 && (gpc_reg_operand (operands[0], <MODE>mode) 8315 || gpc_reg_operand (operands[1], <MODE>mode))" 8316 "@ 8317 stfd%U0%X0 %1,%0 8318 lfd%U1%X1 %0,%1 8319 fmr %0,%1 8320 lxsd %0,%1 8321 stxsd %1,%0 8322 lxsdx %x0,%y1 8323 stxsdx %x1,%y0 8324 xxlor %x0,%x1,%x1 8325 xxlxor %x0,%x0,%x0 8326 # 8327 # 8328 # 8329 # 8330 #" 8331 [(set_attr "type" 8332 "fpstore, fpload, fpsimple, fpload, fpstore, 8333 fpload, fpstore, veclogical, veclogical, two, 8334 store, load, two, vecperm") 8335 (set_attr "size" "64") 8336 (set_attr "length" 8337 "*, *, *, *, *, 8338 *, *, *, *, 8, 8339 8, 8, 8, *") 8340 (set_attr "isa" 8341 "*, *, *, p9v, p9v, 8342 p7v, p7v, *, *, *, 8343 *, *, *, p10") 8344 (set_attr "prefixed" 8345 "*, *, *, *, *, 8346 *, *, *, *, *, 8347 *, *, *, yes")]) 8348 8349 ;; STW LWZ MR G-const H-const F-const 8350 8351 (define_insn "*mov<mode>_softfloat32" 8352 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 8353 "=Y, r, r, r, r, r") 8354 8355 (match_operand:FMOVE64 1 "input_operand" 8356 "r, Y, r, G, H, F"))] 8357 8358 "!TARGET_POWERPC64 8359 && (gpc_reg_operand (operands[0], <MODE>mode) 8360 || gpc_reg_operand (operands[1], <MODE>mode))" 8361 "#" 8362 [(set_attr "type" 8363 "store, load, two, *, *, *") 8364 8365 (set_attr "length" 8366 "8, 8, 8, 8, 12, 16")]) 8367 8368 ; ld/std require word-aligned displacements -> 'Y' constraint. 8369 ; List Y->r and r->Y before r->r for reload. 8370 8371 ;; STFD LFD FMR LXSD STXSD 8372 ;; LXSDX STXSDX XXLOR XXLXOR LI 0 8373 ;; STD LD MR MT{CTR,LR} MF{CTR,LR} 8374 ;; NOP MFVSRD MTVSRD XXSPLTIDP 8375 8376 (define_insn "*mov<mode>_hardfloat64" 8377 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 8378 "=m, d, d, <f64_p9>, wY, 8379 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r, 8380 YZ, r, !r, *c*l, !r, 8381 *h, r, <f64_dm>, wa") 8382 (match_operand:FMOVE64 1 "input_operand" 8383 "d, m, d, wY, <f64_p9>, 8384 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>, 8385 r, YZ, r, r, *h, 8386 0, <f64_dm>, r, eP"))] 8387 "TARGET_POWERPC64 && TARGET_HARD_FLOAT 8388 && (gpc_reg_operand (operands[0], <MODE>mode) 8389 || gpc_reg_operand (operands[1], <MODE>mode))" 8390 "@ 8391 stfd%U0%X0 %1,%0 8392 lfd%U1%X1 %0,%1 8393 fmr %0,%1 8394 lxsd %0,%1 8395 stxsd %1,%0 8396 lxsdx %x0,%y1 8397 stxsdx %x1,%y0 8398 xxlor %x0,%x1,%x1 8399 xxlxor %x0,%x0,%x0 8400 li %0,0 8401 std%U0%X0 %1,%0 8402 ld%U1%X1 %0,%1 8403 mr %0,%1 8404 mt%0 %1 8405 mf%1 %0 8406 nop 8407 mfvsrd %0,%x1 8408 mtvsrd %x0,%1 8409 #" 8410 [(set_attr "type" 8411 "fpstore, fpload, fpsimple, fpload, fpstore, 8412 fpload, fpstore, veclogical, veclogical, integer, 8413 store, load, *, mtjmpr, mfjmpr, 8414 *, mfvsr, mtvsr, vecperm") 8415 (set_attr "size" "64") 8416 (set_attr "isa" 8417 "*, *, *, p9v, p9v, 8418 p7v, p7v, *, *, *, 8419 *, *, *, *, *, 8420 *, p8v, p8v, p10") 8421 (set_attr "prefixed" 8422 "*, *, *, *, *, 8423 *, *, *, *, *, 8424 *, *, *, *, *, 8425 *, *, *, *")]) 8426 8427 ;; STD LD MR MT<SPR> MF<SPR> G-const 8428 ;; H-const F-const Special 8429 8430 (define_insn "*mov<mode>_softfloat64" 8431 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 8432 "=Y, r, r, *c*l, r, r, 8433 r, r, *h") 8434 8435 (match_operand:FMOVE64 1 "input_operand" 8436 "r, Y, r, r, *h, G, 8437 H, F, 0"))] 8438 8439 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT 8440 && (gpc_reg_operand (operands[0], <MODE>mode) 8441 || gpc_reg_operand (operands[1], <MODE>mode))" 8442 "@ 8443 std%U0%X0 %1,%0 8444 ld%U1%X1 %0,%1 8445 mr %0,%1 8446 mt%0 %1 8447 mf%1 %0 8448 # 8449 # 8450 # 8451 nop" 8452 [(set_attr "type" 8453 "store, load, *, mtjmpr, mfjmpr, *, 8454 *, *, *") 8455 8456 (set_attr "length" 8457 "*, *, *, *, *, 8, 8458 12, 16, *")]) 8459 8460 ;; Split the VSX prefixed instruction to support SFmode and DFmode scalar 8461 ;; constants that look like DFmode floating point values where both elements 8462 ;; are the same. The constant has to be expressible as a SFmode constant that 8463 ;; is not a SFmode denormal value. 8464 ;; 8465 ;; We don't need splitters for the 128-bit types, since the function 8466 ;; rs6000_output_move_128bit handles the generation of XXSPLTIDP. 8467 (define_insn "xxspltidp_<mode>_internal" 8468 [(set (match_operand:SFDF 0 "register_operand" "=wa") 8469 (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")] 8470 UNSPEC_XXSPLTIDP_CONST))] 8471 "TARGET_POWER10" 8472 "xxspltidp %x0,%1" 8473 [(set_attr "type" "vecperm") 8474 (set_attr "prefixed" "yes")]) 8475 8476 (define_insn "xxspltiw_<mode>_internal" 8477 [(set (match_operand:SFDF 0 "register_operand" "=wa") 8478 (unspec:SFDF [(match_operand:SI 1 "c32bit_cint_operand" "n")] 8479 UNSPEC_XXSPLTIW_CONST))] 8480 "TARGET_POWER10" 8481 "xxspltiw %x0,%1" 8482 [(set_attr "type" "vecperm") 8483 (set_attr "prefixed" "yes")]) 8484 8485 (define_split 8486 [(set (match_operand:SFDF 0 "vsx_register_operand") 8487 (match_operand:SFDF 1 "vsx_prefixed_constant"))] 8488 "TARGET_POWER10" 8489 [(pc)] 8490 { 8491 rtx dest = operands[0]; 8492 rtx src = operands[1]; 8493 vec_const_128bit_type vsx_const; 8494 8495 if (!vec_const_128bit_to_bytes (src, <MODE>mode, &vsx_const)) 8496 gcc_unreachable (); 8497 8498 unsigned imm = constant_generates_xxspltidp (&vsx_const); 8499 if (imm) 8500 { 8501 emit_insn (gen_xxspltidp_<mode>_internal (dest, GEN_INT (imm))); 8502 DONE; 8503 } 8504 8505 imm = constant_generates_xxspltiw (&vsx_const); 8506 if (imm) 8507 { 8508 emit_insn (gen_xxspltiw_<mode>_internal (dest, GEN_INT (imm))); 8509 DONE; 8510 } 8511 8512 else 8513 gcc_unreachable (); 8514 }) 8515 8517 (define_expand "mov<mode>" 8518 [(set (match_operand:FMOVE128 0 "general_operand") 8519 (match_operand:FMOVE128 1 "any_operand"))] 8520 "" 8521 { 8522 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 8523 DONE; 8524 }) 8525 8526 ;; It's important to list Y->r and r->Y before r->r because otherwise 8527 ;; reload, given m->r, will try to pick r->r and reload it, which 8528 ;; doesn't make progress. 8529 8530 ;; We can't split little endian direct moves of TDmode, because the words are 8531 ;; not swapped like they are for TImode or TFmode. Subregs therefore are 8532 ;; problematical. Don't allow direct move for this case. 8533 8534 ;; FPR load FPR store FPR move FPR zero GPR load 8535 ;; GPR zero GPR store GPR move MFVSRD MTVSRD 8536 8537 (define_insn_and_split "*mov<mode>_64bit_dm" 8538 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" 8539 "=m, d, d, d, Y, 8540 r, r, r, r, d") 8541 8542 (match_operand:FMOVE128_FPR 1 "input_operand" 8543 "d, m, d, <zero_fp>, r, 8544 <zero_fp>, Y, r, d, r"))] 8545 8546 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode) 8547 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN) 8548 && (gpc_reg_operand (operands[0], <MODE>mode) 8549 || gpc_reg_operand (operands[1], <MODE>mode))" 8550 "#" 8551 "&& reload_completed" 8552 [(pc)] 8553 { 8554 rs6000_split_multireg_move (operands[0], operands[1]); 8555 DONE; 8556 } 8557 [(set_attr "length" "8") 8558 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v") 8559 (set_attr "max_prefixed_insns" "2") 8560 (set_attr "num_insns" "2")]) 8561 8562 (define_insn_and_split "*movtd_64bit_nodm" 8563 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r") 8564 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))] 8565 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN 8566 && (gpc_reg_operand (operands[0], TDmode) 8567 || gpc_reg_operand (operands[1], TDmode))" 8568 "#" 8569 "&& reload_completed" 8570 [(pc)] 8571 { 8572 rs6000_split_multireg_move (operands[0], operands[1]); 8573 DONE; 8574 } 8575 [(set_attr "length" "8,8,8,12,12,8") 8576 (set_attr "max_prefixed_insns" "2") 8577 (set_attr "num_insns" "2,2,2,3,3,2")]) 8578 8579 (define_insn_and_split "*mov<mode>_32bit" 8580 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r") 8581 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))] 8582 "TARGET_HARD_FLOAT && !TARGET_POWERPC64 8583 && (FLOAT128_2REG_P (<MODE>mode) 8584 || int_reg_operand_not_pseudo (operands[0], <MODE>mode) 8585 || int_reg_operand_not_pseudo (operands[1], <MODE>mode)) 8586 && (gpc_reg_operand (operands[0], <MODE>mode) 8587 || gpc_reg_operand (operands[1], <MODE>mode))" 8588 "#" 8589 "&& reload_completed" 8590 [(pc)] 8591 { 8592 rs6000_split_multireg_move (operands[0], operands[1]); 8593 DONE; 8594 } 8595 [(set_attr "length" "8,8,8,8,20,20,16")]) 8596 8597 (define_insn_and_split "*mov<mode>_softfloat" 8598 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r") 8599 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))] 8600 "TARGET_SOFT_FLOAT 8601 && (gpc_reg_operand (operands[0], <MODE>mode) 8602 || gpc_reg_operand (operands[1], <MODE>mode))" 8603 "#" 8604 "&& reload_completed" 8605 [(pc)] 8606 { 8607 rs6000_split_multireg_move (operands[0], operands[1]); 8608 DONE; 8609 } 8610 [(set_attr_alternative "length" 8611 [(if_then_else (match_test "TARGET_POWERPC64") 8612 (const_string "8") 8613 (const_string "16")) 8614 (if_then_else (match_test "TARGET_POWERPC64") 8615 (const_string "8") 8616 (const_string "16")) 8617 (if_then_else (match_test "TARGET_POWERPC64") 8618 (const_string "16") 8619 (const_string "32")) 8620 (if_then_else (match_test "TARGET_POWERPC64") 8621 (const_string "8") 8622 (const_string "16"))])]) 8623 8624 (define_expand "@extenddf<mode>2" 8625 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 8626 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))] 8627 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8628 { 8629 if (FLOAT128_IEEE_P (<MODE>mode)) 8630 rs6000_expand_float128_convert (operands[0], operands[1], false); 8631 else if (TARGET_VSX) 8632 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1])); 8633 else 8634 { 8635 rtx zero = gen_reg_rtx (DFmode); 8636 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode); 8637 8638 emit_insn (gen_extenddf2_fprs (<MODE>mode, 8639 operands[0], operands[1], zero)); 8640 } 8641 DONE; 8642 }) 8643 8644 ;; Allow memory operands for the source to be created by the combiner. 8645 (define_insn_and_split "@extenddf<mode>2_fprs" 8646 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d") 8647 (float_extend:IBM128 8648 (match_operand:DF 1 "nonimmediate_operand" "d,m,d"))) 8649 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))] 8650 "!TARGET_VSX && TARGET_HARD_FLOAT 8651 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" 8652 "#" 8653 "&& reload_completed" 8654 [(set (match_dup 3) (match_dup 1)) 8655 (set (match_dup 4) (match_dup 2))] 8656 { 8657 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 8658 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 8659 8660 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 8661 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 8662 }) 8663 8664 (define_insn_and_split "@extenddf<mode>2_vsx" 8665 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d") 8666 (float_extend:IBM128 8667 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))] 8668 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)" 8669 "#" 8670 "&& reload_completed" 8671 [(set (match_dup 2) (match_dup 1)) 8672 (set (match_dup 3) (match_dup 4))] 8673 { 8674 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 8675 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 8676 8677 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 8678 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 8679 operands[4] = CONST0_RTX (DFmode); 8680 }) 8681 8682 (define_expand "extendsf<mode>2" 8683 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 8684 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))] 8685 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8686 { 8687 if (FLOAT128_IEEE_P (<MODE>mode)) 8688 rs6000_expand_float128_convert (operands[0], operands[1], false); 8689 else 8690 { 8691 rtx tmp = gen_reg_rtx (DFmode); 8692 emit_insn (gen_extendsfdf2 (tmp, operands[1])); 8693 emit_insn (gen_extenddf<mode>2 (operands[0], tmp)); 8694 } 8695 DONE; 8696 }) 8697 8698 (define_expand "trunc<mode>df2" 8699 [(set (match_operand:DF 0 "gpc_reg_operand") 8700 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8701 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8702 { 8703 if (FLOAT128_IEEE_P (<MODE>mode)) 8704 { 8705 rs6000_expand_float128_convert (operands[0], operands[1], false); 8706 DONE; 8707 } 8708 }) 8709 8710 (define_insn_and_split "trunc<mode>df2_internal1" 8711 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d") 8712 (float_truncate:DF 8713 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))] 8714 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT 8715 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8716 "@ 8717 # 8718 fmr %0,%1" 8719 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 8720 [(const_int 0)] 8721 { 8722 emit_note (NOTE_INSN_DELETED); 8723 DONE; 8724 } 8725 [(set_attr "type" "fpsimple")]) 8726 8727 (define_insn "trunc<mode>df2_internal2" 8728 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 8729 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 8730 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT 8731 && TARGET_LONG_DOUBLE_128" 8732 "fadd %0,%1,%L1" 8733 [(set_attr "type" "fp")]) 8734 8735 (define_expand "trunc<mode>sf2" 8736 [(set (match_operand:SF 0 "gpc_reg_operand") 8737 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8738 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8739 { 8740 if (FLOAT128_IEEE_P (<MODE>mode)) 8741 rs6000_expand_float128_convert (operands[0], operands[1], false); 8742 else 8743 { 8744 rtx tmp = gen_reg_rtx (DFmode); 8745 emit_insn (gen_trunc<mode>df2 (tmp, operands[1])); 8746 emit_insn (gen_truncdfsf2 (operands[0], tmp)); 8747 } 8748 DONE; 8749 }) 8750 8751 (define_expand "floatsi<mode>2" 8752 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 8753 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand"))) 8754 (clobber (match_scratch:DI 2))])] 8755 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8756 { 8757 rtx op0 = operands[0]; 8758 rtx op1 = operands[1]; 8759 8760 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)) 8761 ; 8762 else if (FLOAT128_IEEE_P (<MODE>mode)) 8763 { 8764 rs6000_expand_float128_convert (op0, op1, false); 8765 DONE; 8766 } 8767 else 8768 { 8769 rtx tmp = gen_reg_rtx (DFmode); 8770 expand_float (tmp, op1, false); 8771 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp)); 8772 DONE; 8773 } 8774 }) 8775 8776 ; fadd, but rounding towards zero. 8777 ; This is probably not the optimal code sequence. 8778 (define_insn "fix_trunc_helper<mode>" 8779 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 8780 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")] 8781 UNSPEC_FIX_TRUNC_TF)) 8782 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))] 8783 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)" 8784 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" 8785 [(set_attr "type" "fp") 8786 (set_attr "length" "20")]) 8787 8788 (define_expand "fix_trunc<mode>si2" 8789 [(set (match_operand:SI 0 "gpc_reg_operand") 8790 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8791 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8792 { 8793 rtx op0 = operands[0]; 8794 rtx op1 = operands[1]; 8795 8796 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)) 8797 ; 8798 else 8799 { 8800 if (FLOAT128_IEEE_P (<MODE>mode)) 8801 rs6000_expand_float128_convert (op0, op1, false); 8802 else 8803 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1)); 8804 DONE; 8805 } 8806 }) 8807 8808 (define_expand "@fix_trunc<mode>si2_fprs" 8809 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand") 8810 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand"))) 8811 (clobber (match_dup 2)) 8812 (clobber (match_dup 3)) 8813 (clobber (match_dup 4)) 8814 (clobber (match_dup 5))])] 8815 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8816 { 8817 operands[2] = gen_reg_rtx (DFmode); 8818 operands[3] = gen_reg_rtx (DFmode); 8819 operands[4] = gen_reg_rtx (DImode); 8820 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode)); 8821 }) 8822 8823 (define_insn_and_split "*fix_trunc<mode>si2_internal" 8824 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 8825 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d"))) 8826 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d")) 8827 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d")) 8828 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d")) 8829 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))] 8830 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8831 "#" 8832 "&& 1" 8833 [(pc)] 8834 { 8835 rtx lowword; 8836 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1], 8837 operands[3])); 8838 8839 gcc_assert (MEM_P (operands[5])); 8840 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 8841 8842 emit_insn (gen_fctiwz_df (operands[4], operands[2])); 8843 emit_move_insn (operands[5], operands[4]); 8844 emit_move_insn (operands[0], lowword); 8845 DONE; 8846 }) 8847 8848 (define_expand "fix_trunc<mode>di2" 8849 [(set (match_operand:DI 0 "gpc_reg_operand") 8850 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))] 8851 "TARGET_FLOAT128_TYPE" 8852 { 8853 if (!TARGET_FLOAT128_HW) 8854 { 8855 rs6000_expand_float128_convert (operands[0], operands[1], false); 8856 DONE; 8857 } 8858 }) 8859 8860 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2" 8861 [(set (match_operand:SDI 0 "gpc_reg_operand") 8862 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))] 8863 "TARGET_FLOAT128_TYPE" 8864 { 8865 rs6000_expand_float128_convert (operands[0], operands[1], true); 8866 DONE; 8867 }) 8868 8869 (define_expand "floatdi<mode>2" 8870 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 8871 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))] 8872 "TARGET_FLOAT128_TYPE" 8873 { 8874 if (!TARGET_FLOAT128_HW) 8875 { 8876 rs6000_expand_float128_convert (operands[0], operands[1], false); 8877 DONE; 8878 } 8879 }) 8880 8881 (define_expand "floatunsdi<IEEE128:mode>2" 8882 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 8883 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))] 8884 "TARGET_FLOAT128_TYPE" 8885 { 8886 if (!TARGET_FLOAT128_HW) 8887 { 8888 rs6000_expand_float128_convert (operands[0], operands[1], true); 8889 DONE; 8890 } 8891 }) 8892 8893 (define_expand "floatuns<IEEE128:mode>2" 8894 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 8895 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))] 8896 "TARGET_FLOAT128_TYPE" 8897 { 8898 rtx op0 = operands[0]; 8899 rtx op1 = operands[1]; 8900 8901 if (TARGET_FLOAT128_HW) 8902 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1)); 8903 else 8904 rs6000_expand_float128_convert (op0, op1, true); 8905 DONE; 8906 }) 8907 8908 (define_expand "neg<mode>2" 8909 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 8910 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8911 "FLOAT128_IEEE_P (<MODE>mode) 8912 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" 8913 { 8914 if (FLOAT128_IEEE_P (<MODE>mode)) 8915 { 8916 if (TARGET_FLOAT128_HW) 8917 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1])); 8918 else if (TARGET_FLOAT128_TYPE) 8919 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode, 8920 operands[0], operands[1])); 8921 else 8922 { 8923 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode); 8924 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST, 8925 <MODE>mode, 8926 operands[1], <MODE>mode); 8927 8928 if (target && !rtx_equal_p (target, operands[0])) 8929 emit_move_insn (operands[0], target); 8930 } 8931 DONE; 8932 } 8933 }) 8934 8935 (define_insn "neg<mode>2_internal" 8936 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d") 8937 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 8938 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)" 8939 { 8940 if (REGNO (operands[0]) == REGNO (operands[1]) + 1) 8941 return "fneg %L0,%L1\;fneg %0,%1"; 8942 else 8943 return "fneg %0,%1\;fneg %L0,%L1"; 8944 } 8945 [(set_attr "type" "fpsimple") 8946 (set_attr "length" "8")]) 8947 8948 (define_expand "abs<mode>2" 8949 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 8950 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8951 "FLOAT128_IEEE_P (<MODE>mode) 8952 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" 8953 { 8954 rtx label; 8955 8956 if (FLOAT128_IEEE_P (<MODE>mode)) 8957 { 8958 if (TARGET_FLOAT128_HW) 8959 { 8960 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1])); 8961 DONE; 8962 } 8963 else if (TARGET_FLOAT128_TYPE) 8964 { 8965 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode, 8966 operands[0], operands[1])); 8967 DONE; 8968 } 8969 else 8970 FAIL; 8971 } 8972 8973 label = gen_label_rtx (); 8974 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label)); 8975 emit_label (label); 8976 DONE; 8977 }) 8978 8979 (define_expand "@abs<mode>2_internal" 8980 [(set (match_operand:IBM128 0 "gpc_reg_operand") 8981 (match_operand:IBM128 1 "gpc_reg_operand")) 8982 (set (match_dup 3) (match_dup 5)) 8983 (set (match_dup 5) (abs:DF (match_dup 5))) 8984 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5))) 8985 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0)) 8986 (label_ref (match_operand 2 "")) 8987 (pc))) 8988 (set (match_dup 6) (neg:DF (match_dup 6)))] 8989 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8990 { 8991 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 8992 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 8993 operands[3] = gen_reg_rtx (DFmode); 8994 operands[4] = gen_reg_rtx (CCFPmode); 8995 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 8996 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 8997 }) 8998 8999 9001 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector 9002 ;; register 9003 9004 (define_expand "ieee_128bit_negative_zero" 9005 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))] 9006 "TARGET_FLOAT128_TYPE" 9007 { 9008 rtvec v = rtvec_alloc (16); 9009 int i, high; 9010 9011 for (i = 0; i < 16; i++) 9012 RTVEC_ELT (v, i) = const0_rtx; 9013 9014 high = (BYTES_BIG_ENDIAN) ? 0 : 15; 9015 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode); 9016 9017 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v)); 9018 DONE; 9019 }) 9020 9021 ;; IEEE 128-bit negate 9022 9023 ;; We have 2 insns here for negate and absolute value. The first uses 9024 ;; match_scratch so that phases like combine can recognize neg/abs as generic 9025 ;; insns, and second insn after the first split pass loads up the bit to 9026 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of 9027 ;; neg/abs to create the constant just once. 9028 9029 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2" 9030 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 9031 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 9032 (clobber (match_scratch:V16QI 2 "=v"))] 9033 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 9034 "#" 9035 "&& 1" 9036 [(parallel [(set (match_dup 0) 9037 (neg:IEEE128 (match_dup 1))) 9038 (use (match_dup 2))])] 9039 { 9040 if (GET_CODE (operands[2]) == SCRATCH) 9041 operands[2] = gen_reg_rtx (V16QImode); 9042 9043 operands[3] = gen_reg_rtx (V16QImode); 9044 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 9045 } 9046 [(set_attr "length" "8") 9047 (set_attr "type" "vecsimple")]) 9048 9049 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal" 9050 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 9051 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 9052 (use (match_operand:V16QI 2 "register_operand" "v"))] 9053 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 9054 "xxlxor %x0,%x1,%x2" 9055 [(set_attr "type" "veclogical")]) 9056 9057 ;; IEEE 128-bit absolute value 9058 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2" 9059 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 9060 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 9061 (clobber (match_scratch:V16QI 2 "=v"))] 9062 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 9063 "#" 9064 "&& 1" 9065 [(parallel [(set (match_dup 0) 9066 (abs:IEEE128 (match_dup 1))) 9067 (use (match_dup 2))])] 9068 { 9069 if (GET_CODE (operands[2]) == SCRATCH) 9070 operands[2] = gen_reg_rtx (V16QImode); 9071 9072 operands[3] = gen_reg_rtx (V16QImode); 9073 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 9074 } 9075 [(set_attr "length" "8") 9076 (set_attr "type" "vecsimple")]) 9077 9078 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal" 9079 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 9080 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 9081 (use (match_operand:V16QI 2 "register_operand" "v"))] 9082 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 9083 "xxlandc %x0,%x1,%x2" 9084 [(set_attr "type" "veclogical")]) 9085 9086 ;; IEEE 128-bit negative absolute value 9087 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2" 9088 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 9089 (neg:IEEE128 9090 (abs:IEEE128 9091 (match_operand:IEEE128 1 "register_operand" "wa")))) 9092 (clobber (match_scratch:V16QI 2 "=v"))] 9093 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW 9094 && FLOAT128_IEEE_P (<MODE>mode)" 9095 "#" 9096 "&& 1" 9097 [(parallel [(set (match_dup 0) 9098 (neg:IEEE128 (abs:IEEE128 (match_dup 1)))) 9099 (use (match_dup 2))])] 9100 { 9101 if (GET_CODE (operands[2]) == SCRATCH) 9102 operands[2] = gen_reg_rtx (V16QImode); 9103 9104 operands[3] = gen_reg_rtx (V16QImode); 9105 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 9106 } 9107 [(set_attr "length" "8") 9108 (set_attr "type" "vecsimple")]) 9109 9110 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal" 9111 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 9112 (neg:IEEE128 9113 (abs:IEEE128 9114 (match_operand:IEEE128 1 "register_operand" "wa")))) 9115 (use (match_operand:V16QI 2 "register_operand" "v"))] 9116 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 9117 "xxlor %x0,%x1,%x2" 9118 [(set_attr "type" "veclogical")]) 9119 9120 ;; Float128 conversion functions. These expand to library function calls. 9121 ;; We use expand to convert from IBM double double to IEEE 128-bit 9122 ;; and trunc for the opposite. 9123 (define_expand "extendiftf2" 9124 [(set (match_operand:TF 0 "gpc_reg_operand") 9125 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))] 9126 "TARGET_FLOAT128_TYPE" 9127 { 9128 rs6000_expand_float128_convert (operands[0], operands[1], false); 9129 DONE; 9130 }) 9131 9132 (define_expand "extendifkf2" 9133 [(set (match_operand:KF 0 "gpc_reg_operand") 9134 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))] 9135 "TARGET_FLOAT128_TYPE" 9136 { 9137 rs6000_expand_float128_convert (operands[0], operands[1], false); 9138 DONE; 9139 }) 9140 9141 (define_expand "extendtfkf2" 9142 [(set (match_operand:KF 0 "gpc_reg_operand") 9143 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))] 9144 "TARGET_FLOAT128_TYPE" 9145 { 9146 rs6000_expand_float128_convert (operands[0], operands[1], false); 9147 DONE; 9148 }) 9149 9150 (define_expand "extendtfif2" 9151 [(set (match_operand:IF 0 "gpc_reg_operand") 9152 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))] 9153 "TARGET_FLOAT128_TYPE" 9154 { 9155 rs6000_expand_float128_convert (operands[0], operands[1], false); 9156 DONE; 9157 }) 9158 9159 (define_expand "trunciftf2" 9160 [(set (match_operand:TF 0 "gpc_reg_operand") 9161 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))] 9162 "TARGET_FLOAT128_TYPE" 9163 { 9164 rs6000_expand_float128_convert (operands[0], operands[1], false); 9165 DONE; 9166 }) 9167 9168 (define_expand "truncifkf2" 9169 [(set (match_operand:KF 0 "gpc_reg_operand") 9170 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))] 9171 "TARGET_FLOAT128_TYPE" 9172 { 9173 rs6000_expand_float128_convert (operands[0], operands[1], false); 9174 DONE; 9175 }) 9176 9177 (define_expand "trunckftf2" 9178 [(set (match_operand:TF 0 "gpc_reg_operand") 9179 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))] 9180 "TARGET_FLOAT128_TYPE" 9181 { 9182 rs6000_expand_float128_convert (operands[0], operands[1], false); 9183 DONE; 9184 }) 9185 9186 (define_expand "trunctfif2" 9187 [(set (match_operand:IF 0 "gpc_reg_operand") 9188 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))] 9189 "TARGET_FLOAT128_TYPE" 9190 { 9191 rs6000_expand_float128_convert (operands[0], operands[1], false); 9192 DONE; 9193 }) 9194 9195 (define_insn_and_split "*extend<mode>tf2_internal" 9196 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>") 9197 (float_extend:TF 9198 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))] 9199 "TARGET_FLOAT128_TYPE 9200 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)" 9201 "#" 9202 "&& reload_completed" 9203 [(set (match_dup 0) (match_dup 2))] 9204 { 9205 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1])); 9206 }) 9207 9208 (define_insn_and_split "*extendtf<mode>2_internal" 9209 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>") 9210 (float_extend:IFKF 9211 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))] 9212 "TARGET_FLOAT128_TYPE 9213 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)" 9214 "#" 9215 "&& reload_completed" 9216 [(set (match_dup 0) (match_dup 2))] 9217 { 9218 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1])); 9219 }) 9220 9221 9223 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all 9224 ;; must have 3 arguments, and scratch register constraint must be a single 9225 ;; constraint. 9226 9227 ;; Reload patterns to support gpr load/store with misaligned mem. 9228 ;; and multiple gpr load/store at offset >= 0xfffc 9229 (define_expand "reload_<mode>_store" 9230 [(parallel [(match_operand 0 "memory_operand" "=m") 9231 (match_operand 1 "gpc_reg_operand" "r") 9232 (match_operand:GPR 2 "register_operand" "=&b")])] 9233 "" 9234 { 9235 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true); 9236 DONE; 9237 }) 9238 9239 (define_expand "reload_<mode>_load" 9240 [(parallel [(match_operand 0 "gpc_reg_operand" "=r") 9241 (match_operand 1 "memory_operand" "m") 9242 (match_operand:GPR 2 "register_operand" "=b")])] 9243 "" 9244 { 9245 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false); 9246 DONE; 9247 }) 9248 9249 9251 ;; Reload patterns for various types using the vector registers. We may need 9252 ;; an additional base register to convert the reg+offset addressing to reg+reg 9253 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an 9254 ;; index register for gpr registers. 9255 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store" 9256 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m") 9257 (match_operand:RELOAD 1 "gpc_reg_operand" "wa") 9258 (match_operand:P 2 "register_operand" "=b")])] 9259 "<P:tptrsize>" 9260 { 9261 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true); 9262 DONE; 9263 }) 9264 9265 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load" 9266 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa") 9267 (match_operand:RELOAD 1 "memory_operand" "m") 9268 (match_operand:P 2 "register_operand" "=b")])] 9269 "<P:tptrsize>" 9270 { 9271 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false); 9272 DONE; 9273 }) 9274 9275 9276 ;; Reload sometimes tries to move the address to a GPR, and can generate 9277 ;; invalid RTL for addresses involving AND -16. Allow addresses involving 9278 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16. 9279 9280 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>" 9281 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9282 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 9283 (match_operand:P 2 "reg_or_cint_operand" "rI")) 9284 (const_int -16)))] 9285 "TARGET_ALTIVEC && reload_completed" 9286 "#" 9287 "&& reload_completed" 9288 [(set (match_dup 0) 9289 (plus:P (match_dup 1) 9290 (match_dup 2))) 9291 (set (match_dup 0) 9292 (and:P (match_dup 0) 9293 (const_int -16)))]) 9294 9296 ;; Power8 merge instructions to allow direct move to/from floating point 9297 ;; registers in 32-bit mode. We use TF mode to get two registers to move the 9298 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF 9299 ;; value, since it is allocated in reload and not all of the flow information 9300 ;; is setup for it. We have two patterns to do the two moves between gprs and 9301 ;; fprs. There isn't a dependancy between the two, but we could potentially 9302 ;; schedule other instructions between the two instructions. 9303 9304 (define_insn "p8_fmrgow_<mode>" 9305 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 9306 (unspec:FMOVE64X [ 9307 (match_operand:DF 1 "register_operand" "d") 9308 (match_operand:DF 2 "register_operand" "d")] 9309 UNSPEC_P8V_FMRGOW))] 9310 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9311 "fmrgow %0,%1,%2" 9312 [(set_attr "type" "fpsimple")]) 9313 9314 (define_insn "p8_mtvsrwz" 9315 [(set (match_operand:DF 0 "register_operand" "=d") 9316 (unspec:DF [(match_operand:SI 1 "register_operand" "r")] 9317 UNSPEC_P8V_MTVSRWZ))] 9318 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9319 "mtvsrwz %x0,%1" 9320 [(set_attr "type" "mtvsr")]) 9321 9322 (define_insn "p8_mtvsrwz_v16qisi2" 9323 [(set (match_operand:V16QI 0 "register_operand" "=wa") 9324 (unspec:V16QI [(match_operand:SI 1 "register_operand" "r")] 9325 UNSPEC_P8V_MTVSRWZ))] 9326 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9327 "mtvsrwz %x0,%1" 9328 [(set_attr "type" "mtvsr")]) 9329 9330 (define_insn "p8_mtvsrd_v16qidi2" 9331 [(set (match_operand:V16QI 0 "register_operand" "=wa") 9332 (unspec:V16QI [(match_operand:DI 1 "register_operand" "r")] 9333 UNSPEC_P8V_MTVSRD))] 9334 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9335 "mtvsrd %x0,%1" 9336 [(set_attr "type" "mtvsr")]) 9337 9338 (define_insn_and_split "reload_fpr_from_gpr<mode>" 9339 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 9340 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")] 9341 UNSPEC_P8V_RELOAD_FROM_GPR)) 9342 (clobber (match_operand:IF 2 "register_operand" "=d"))] 9343 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9344 "#" 9345 "&& reload_completed" 9346 [(const_int 0)] 9347 { 9348 rtx dest = operands[0]; 9349 rtx src = operands[1]; 9350 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 9351 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 9352 rtx gpr_hi_reg = gen_highpart (SImode, src); 9353 rtx gpr_lo_reg = gen_lowpart (SImode, src); 9354 9355 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg)); 9356 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg)); 9357 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo)); 9358 DONE; 9359 } 9360 [(set_attr "length" "12") 9361 (set_attr "type" "three")]) 9362 9363 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode 9364 (define_insn "p8_mtvsrd_df" 9365 [(set (match_operand:DF 0 "register_operand" "=wa") 9366 (unspec:DF [(match_operand:DI 1 "register_operand" "r")] 9367 UNSPEC_P8V_MTVSRD))] 9368 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9369 "mtvsrd %x0,%1" 9370 [(set_attr "type" "mtvsr")]) 9371 9372 (define_insn "p8_xxpermdi_<mode>" 9373 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 9374 (unspec:FMOVE128_GPR [ 9375 (match_operand:DF 1 "register_operand" "wa") 9376 (match_operand:DF 2 "register_operand" "wa")] 9377 UNSPEC_P8V_XXPERMDI))] 9378 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9379 "xxpermdi %x0,%x1,%x2,0" 9380 [(set_attr "type" "vecperm")]) 9381 9382 (define_insn_and_split "reload_vsx_from_gpr<mode>" 9383 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 9384 (unspec:FMOVE128_GPR 9385 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")] 9386 UNSPEC_P8V_RELOAD_FROM_GPR)) 9387 (clobber (match_operand:IF 2 "register_operand" "=wa"))] 9388 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9389 "#" 9390 "&& reload_completed" 9391 [(const_int 0)] 9392 { 9393 rtx dest = operands[0]; 9394 rtx src = operands[1]; 9395 /* You might think that we could use op0 as one temp and a DF clobber 9396 as op2, but you'd be wrong. Secondary reload move patterns don't 9397 check for overlap of the clobber and the destination. */ 9398 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 9399 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 9400 rtx gpr_hi_reg = gen_highpart (DImode, src); 9401 rtx gpr_lo_reg = gen_lowpart (DImode, src); 9402 9403 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg)); 9404 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg)); 9405 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo)); 9406 DONE; 9407 } 9408 [(set_attr "length" "12") 9409 (set_attr "type" "three")]) 9410 9411 (define_split 9412 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand") 9413 (match_operand:FMOVE128_GPR 1 "input_operand"))] 9414 "reload_completed 9415 && (int_reg_operand (operands[0], <MODE>mode) 9416 || int_reg_operand (operands[1], <MODE>mode)) 9417 && (!TARGET_DIRECT_MOVE_128 9418 || (!vsx_register_operand (operands[0], <MODE>mode) 9419 && !vsx_register_operand (operands[1], <MODE>mode)))" 9420 [(pc)] 9421 { 9422 rs6000_split_multireg_move (operands[0], operands[1]); 9423 DONE; 9424 }) 9425 9426 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point 9427 ;; type is stored internally as double precision in the VSX registers, we have 9428 ;; to convert it from the vector format. 9429 (define_insn "p8_mtvsrd_sf" 9430 [(set (match_operand:SF 0 "register_operand" "=wa") 9431 (unspec:SF [(match_operand:DI 1 "register_operand" "r")] 9432 UNSPEC_P8V_MTVSRD))] 9433 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9434 "mtvsrd %x0,%1" 9435 [(set_attr "type" "mtvsr")]) 9436 9437 (define_insn_and_split "reload_vsx_from_gprsf" 9438 [(set (match_operand:SF 0 "register_operand" "=wa") 9439 (unspec:SF [(match_operand:SF 1 "register_operand" "r")] 9440 UNSPEC_P8V_RELOAD_FROM_GPR)) 9441 (clobber (match_operand:DI 2 "register_operand" "=r"))] 9442 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9443 "#" 9444 "&& reload_completed" 9445 [(const_int 0)] 9446 { 9447 rtx op0 = operands[0]; 9448 rtx op1 = operands[1]; 9449 rtx op2 = operands[2]; 9450 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0); 9451 9452 /* Move SF value to upper 32-bits for xscvspdpn. */ 9453 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 9454 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 9455 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 9456 DONE; 9457 } 9458 [(set_attr "length" "8") 9459 (set_attr "type" "two")]) 9460 9461 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a 9462 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value, 9463 ;; and then doing a move of that. 9464 (define_insn "p8_mfvsrd_3_<mode>" 9465 [(set (match_operand:DF 0 "register_operand" "=r") 9466 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 9467 UNSPEC_P8V_RELOAD_FROM_VSX))] 9468 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9469 "mfvsrd %0,%x1" 9470 [(set_attr "type" "mfvsr")]) 9471 9472 (define_insn_and_split "reload_gpr_from_vsx<mode>" 9473 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r") 9474 (unspec:FMOVE128_GPR 9475 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 9476 UNSPEC_P8V_RELOAD_FROM_VSX)) 9477 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))] 9478 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9479 "#" 9480 "&& reload_completed" 9481 [(const_int 0)] 9482 { 9483 rtx dest = operands[0]; 9484 rtx src = operands[1]; 9485 rtx tmp = operands[2]; 9486 rtx gpr_hi_reg = gen_highpart (DFmode, dest); 9487 rtx gpr_lo_reg = gen_lowpart (DFmode, dest); 9488 9489 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src)); 9490 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3))); 9491 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp)); 9492 DONE; 9493 } 9494 [(set_attr "length" "12") 9495 (set_attr "type" "three")]) 9496 9497 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point 9498 ;; type is stored internally as double precision, we have to convert it to the 9499 ;; vector format. 9500 9501 (define_insn_and_split "reload_gpr_from_vsxsf" 9502 [(set (match_operand:SF 0 "register_operand" "=r") 9503 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")] 9504 UNSPEC_P8V_RELOAD_FROM_VSX)) 9505 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))] 9506 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 9507 "#" 9508 "&& reload_completed" 9509 [(const_int 0)] 9510 { 9511 rtx op0 = operands[0]; 9512 rtx op1 = operands[1]; 9513 rtx op2 = operands[2]; 9514 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0)); 9515 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 9516 9517 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 9518 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si)); 9519 DONE; 9520 } 9521 [(set_attr "length" "8") 9522 (set_attr "type" "two") 9523 (set_attr "isa" "p8v")]) 9524 9526 ;; Next come the multi-word integer load and store and the load and store 9527 ;; multiple insns. 9528 9529 ;; List r->r after r->Y, otherwise reload will try to reload a 9530 ;; non-offsettable address by using r->r which won't make progress. 9531 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload 9532 ;; a gpr into a fpr instead of reloading an invalid 'Y' address 9533 9534 ;; GPR store GPR load GPR move FPR store FPR load FPR move 9535 ;; GPR const AVX store AVX store AVX load AVX load VSX move 9536 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const 9537 ;; AVX const 9538 9539 (define_insn "*movdi_internal32" 9540 [(set (match_operand:DI 0 "nonimmediate_operand" 9541 "=Y, r, r, m, ^d, ^d, 9542 r, wY, Z, ^v, $v, ^wa, 9543 wa, wa, v, wa, *i, v, 9544 v") 9545 (match_operand:DI 1 "input_operand" 9546 "r, Y, r, ^d, m, ^d, 9547 IJKnF, ^v, $v, wY, Z, ^wa, 9548 Oj, wM, OjwM, Oj, wM, wS, 9549 wB"))] 9550 "! TARGET_POWERPC64 9551 && (gpc_reg_operand (operands[0], DImode) 9552 || gpc_reg_operand (operands[1], DImode))" 9553 "@ 9554 # 9555 # 9556 # 9557 stfd%U0%X0 %1,%0 9558 lfd%U1%X1 %0,%1 9559 fmr %0,%1 9560 # 9561 stxsd %1,%0 9562 stxsdx %x1,%y0 9563 lxsd %0,%1 9564 lxsdx %x0,%y1 9565 xxlor %x0,%x1,%x1 9566 xxspltib %x0,0 9567 xxspltib %x0,255 9568 vspltisw %0,%1 9569 xxlxor %x0,%x0,%x0 9570 xxlorc %x0,%x0,%x0 9571 # 9572 #" 9573 [(set_attr "type" 9574 "store, load, *, fpstore, fpload, fpsimple, 9575 *, fpstore, fpstore, fpload, fpload, veclogical, 9576 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple, 9577 vecsimple") 9578 (set_attr "size" "64") 9579 (set_attr "length" 9580 "8, 8, 8, *, *, *, 9581 16, *, *, *, *, *, 9582 *, *, *, *, *, 8, 9583 *") 9584 (set_attr "isa" 9585 "*, *, *, *, *, *, 9586 *, p9v, p7v, p9v, p7v, *, 9587 p9v, p9v, p7v, *, *, p7v, 9588 p7v")]) 9589 9590 (define_split 9591 [(set (match_operand:DI 0 "gpc_reg_operand") 9592 (match_operand:DI 1 "const_int_operand"))] 9593 "! TARGET_POWERPC64 && reload_completed 9594 && gpr_or_gpr_p (operands[0], operands[1]) 9595 && !direct_move_p (operands[0], operands[1])" 9596 [(set (match_dup 2) (match_dup 4)) 9597 (set (match_dup 3) (match_dup 1))] 9598 { 9599 HOST_WIDE_INT value = INTVAL (operands[1]); 9600 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 9601 DImode); 9602 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 9603 DImode); 9604 operands[4] = GEN_INT (value >> 32); 9605 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 9606 }) 9607 9608 (define_split 9609 [(set (match_operand:DIFD 0 "nonimmediate_operand") 9610 (match_operand:DIFD 1 "input_operand"))] 9611 "reload_completed && !TARGET_POWERPC64 9612 && gpr_or_gpr_p (operands[0], operands[1]) 9613 && !direct_move_p (operands[0], operands[1])" 9614 [(pc)] 9615 { 9616 rs6000_split_multireg_move (operands[0], operands[1]); 9617 DONE; 9618 }) 9619 9620 ;; GPR store GPR load GPR move 9621 ;; GPR li GPR lis GPR pli GPR # 9622 ;; FPR store FPR load FPR move 9623 ;; AVX store AVX store AVX load AVX load VSX move 9624 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 9625 ;; P9 const AVX const 9626 ;; From SPR To SPR SPR<->SPR 9627 ;; VSX->GPR GPR->VSX 9628 (define_insn "*movdi_internal64" 9629 [(set (match_operand:DI 0 "nonimmediate_operand" 9630 "=YZ, r, r, 9631 r, r, r, r, 9632 m, ^d, ^d, 9633 wY, Z, $v, $v, ^wa, 9634 wa, wa, v, wa, wa, 9635 v, v, 9636 r, *h, *h, 9637 ?r, ?wa") 9638 (match_operand:DI 1 "input_operand" 9639 "r, YZ, r, 9640 I, L, eI, nF, 9641 ^d, m, ^d, 9642 ^v, $v, wY, Z, ^wa, 9643 Oj, wM, OjwM, Oj, wM, 9644 wS, wB, 9645 *h, r, 0, 9646 wa, r"))] 9647 "TARGET_POWERPC64 9648 && (gpc_reg_operand (operands[0], DImode) 9649 || gpc_reg_operand (operands[1], DImode))" 9650 "@ 9651 std%U0%X0 %1,%0 9652 ld%U1%X1 %0,%1 9653 mr %0,%1 9654 li %0,%1 9655 lis %0,%v1 9656 li %0,%1 9657 # 9658 stfd%U0%X0 %1,%0 9659 lfd%U1%X1 %0,%1 9660 fmr %0,%1 9661 stxsd %1,%0 9662 stxsdx %x1,%y0 9663 lxsd %0,%1 9664 lxsdx %x0,%y1 9665 xxlor %x0,%x1,%x1 9666 xxspltib %x0,0 9667 xxspltib %x0,255 9668 # 9669 xxlxor %x0,%x0,%x0 9670 xxlorc %x0,%x0,%x0 9671 # 9672 # 9673 mf%1 %0 9674 mt%0 %1 9675 nop 9676 mfvsrd %0,%x1 9677 mtvsrd %x0,%1" 9678 [(set_attr "type" 9679 "store, load, *, 9680 *, *, *, *, 9681 fpstore, fpload, fpsimple, 9682 fpstore, fpstore, fpload, fpload, veclogical, 9683 vecsimple, vecsimple, vecsimple, veclogical, veclogical, 9684 vecsimple, vecsimple, 9685 mfjmpr, mtjmpr, *, 9686 mfvsr, mtvsr") 9687 (set_attr "size" "64") 9688 (set_attr "length" 9689 "*, *, *, 9690 *, *, *, 20, 9691 *, *, *, 9692 *, *, *, *, *, 9693 *, *, *, *, *, 9694 8, *, 9695 *, *, *, 9696 *, *") 9697 (set_attr "isa" 9698 "*, *, *, 9699 *, *, p10, *, 9700 *, *, *, 9701 p9v, p7v, p9v, p7v, *, 9702 p9v, p9v, p7v, *, *, 9703 p7v, p7v, 9704 *, *, *, 9705 p8v, p8v")]) 9706 9707 ; Some DImode loads are best done as a load of -1 followed by a mask 9708 ; instruction. 9709 (define_split 9710 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 9711 (match_operand:DI 1 "const_int_operand"))] 9712 "TARGET_POWERPC64 9713 && num_insns_constant (operands[1], DImode) > 1 9714 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff) 9715 && rs6000_is_valid_and_mask (operands[1], DImode)" 9716 [(set (match_dup 0) 9717 (const_int -1)) 9718 (set (match_dup 0) 9719 (and:DI (match_dup 0) 9720 (match_dup 1)))] 9721 "") 9722 9723 ;; Split a load of a large constant into the appropriate five-instruction 9724 ;; sequence. Handle anything in a constant number of insns. 9725 ;; When non-easy constants can go in the TOC, this should use 9726 ;; easy_fp_constant predicate. 9727 (define_split 9728 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 9729 (match_operand:DI 1 "const_int_operand"))] 9730 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 9731 [(set (match_dup 0) (match_dup 2)) 9732 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 9733 { 9734 if (rs6000_emit_set_const (operands[0], operands[1])) 9735 DONE; 9736 else 9737 FAIL; 9738 }) 9739 9740 (define_split 9741 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 9742 (match_operand:DI 1 "const_scalar_int_operand"))] 9743 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 9744 [(set (match_dup 0) (match_dup 2)) 9745 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 9746 { 9747 if (rs6000_emit_set_const (operands[0], operands[1])) 9748 DONE; 9749 else 9750 FAIL; 9751 }) 9752 9753 (define_split 9754 [(set (match_operand:DI 0 "altivec_register_operand") 9755 (match_operand:DI 1 "s5bit_cint_operand"))] 9756 "TARGET_VSX && reload_completed" 9757 [(const_int 0)] 9758 { 9759 rtx op0 = operands[0]; 9760 rtx op1 = operands[1]; 9761 int r = REGNO (op0); 9762 rtx op0_v4si = gen_rtx_REG (V4SImode, r); 9763 9764 emit_insn (gen_altivec_vspltisw (op0_v4si, op1)); 9765 if (op1 != const0_rtx && op1 != constm1_rtx) 9766 { 9767 rtx op0_v2di = gen_rtx_REG (V2DImode, r); 9768 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si)); 9769 } 9770 DONE; 9771 }) 9772 9773 ;; Split integer constants that can be loaded with XXSPLTIB and a 9774 ;; sign extend operation. 9775 (define_split 9776 [(set (match_operand:INT_ISA3 0 "altivec_register_operand") 9777 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))] 9778 "TARGET_P9_VECTOR && reload_completed" 9779 [(const_int 0)] 9780 { 9781 rtx op0 = operands[0]; 9782 rtx op1 = operands[1]; 9783 int r = REGNO (op0); 9784 rtx op0_v16qi = gen_rtx_REG (V16QImode, r); 9785 9786 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1)); 9787 if (<MODE>mode == DImode) 9788 emit_insn (gen_vsx_sign_extend_v16qi_di (operands[0], op0_v16qi)); 9789 else if (<MODE>mode == SImode) 9790 emit_insn (gen_vsx_sign_extend_v16qi_si (operands[0], op0_v16qi)); 9791 else if (<MODE>mode == HImode) 9792 { 9793 rtx op0_v8hi = gen_rtx_REG (V8HImode, r); 9794 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi)); 9795 } 9796 DONE; 9797 }) 9798 9799 9801 ;; TImode/PTImode is similar, except that we usually want to compute the 9802 ;; address into a register and use lsi/stsi (the exception is during reload). 9803 9804 (define_insn "*mov<mode>_string" 9805 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r") 9806 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))] 9807 "! TARGET_POWERPC64 9808 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode)) 9809 && (gpc_reg_operand (operands[0], <MODE>mode) 9810 || gpc_reg_operand (operands[1], <MODE>mode))" 9811 "#" 9812 [(set_attr "type" "store,store,load,load,*,*") 9813 (set_attr "update" "yes") 9814 (set_attr "indexed" "yes") 9815 (set_attr "cell_micro" "conditional")]) 9816 9817 (define_insn "*mov<mode>_ppc64" 9818 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r") 9819 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))] 9820 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode) 9821 && (gpc_reg_operand (operands[0], <MODE>mode) 9822 || gpc_reg_operand (operands[1], <MODE>mode)))" 9823 { 9824 return rs6000_output_move_128bit (operands); 9825 } 9826 [(set_attr "type" "store,store,load,load,*,*") 9827 (set_attr "length" "8") 9828 (set_attr "max_prefixed_insns" "2")]) 9829 9830 (define_split 9831 [(set (match_operand:TI2 0 "int_reg_operand") 9832 (match_operand:TI2 1 "const_scalar_int_operand"))] 9833 "TARGET_POWERPC64 9834 && (VECTOR_MEM_NONE_P (<MODE>mode) 9835 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))" 9836 [(set (match_dup 2) (match_dup 4)) 9837 (set (match_dup 3) (match_dup 5))] 9838 { 9839 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 9840 <MODE>mode); 9841 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 9842 <MODE>mode); 9843 if (CONST_WIDE_INT_P (operands[1])) 9844 { 9845 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1)); 9846 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0)); 9847 } 9848 else if (CONST_INT_P (operands[1])) 9849 { 9850 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); 9851 operands[5] = operands[1]; 9852 } 9853 else 9854 FAIL; 9855 }) 9856 9857 (define_split 9858 [(set (match_operand:TI2 0 "nonimmediate_operand") 9859 (match_operand:TI2 1 "input_operand"))] 9860 "reload_completed 9861 && gpr_or_gpr_p (operands[0], operands[1]) 9862 && !direct_move_p (operands[0], operands[1]) 9863 && !quad_load_store_p (operands[0], operands[1])" 9864 [(pc)] 9865 { 9866 rs6000_split_multireg_move (operands[0], operands[1]); 9867 DONE; 9868 }) 9869 9871 (define_expand "setmemsi" 9872 [(parallel [(set (match_operand:BLK 0 "") 9873 (match_operand 2 "const_int_operand")) 9874 (use (match_operand:SI 1 "")) 9875 (use (match_operand:SI 3 ""))])] 9876 "" 9877 { 9878 /* If value to set is not zero, use the library routine. */ 9879 if (operands[2] != const0_rtx) 9880 FAIL; 9881 9882 if (expand_block_clear (operands)) 9883 DONE; 9884 else 9885 FAIL; 9886 }) 9887 9888 ;; String compare N insn. 9889 ;; Argument 0 is the target (result) 9890 ;; Argument 1 is the destination 9891 ;; Argument 2 is the source 9892 ;; Argument 3 is the length 9893 ;; Argument 4 is the alignment 9894 9895 (define_expand "cmpstrnsi" 9896 [(parallel [(set (match_operand:SI 0) 9897 (compare:SI (match_operand:BLK 1) 9898 (match_operand:BLK 2))) 9899 (use (match_operand:SI 3)) 9900 (use (match_operand:SI 4))])] 9901 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)" 9902 { 9903 if (optimize_insn_for_size_p ()) 9904 FAIL; 9905 9906 if (expand_strn_compare (operands, 0)) 9907 DONE; 9908 else 9909 FAIL; 9910 }) 9911 9912 ;; String compare insn. 9913 ;; Argument 0 is the target (result) 9914 ;; Argument 1 is the destination 9915 ;; Argument 2 is the source 9916 ;; Argument 3 is the alignment 9917 9918 (define_expand "cmpstrsi" 9919 [(parallel [(set (match_operand:SI 0) 9920 (compare:SI (match_operand:BLK 1) 9921 (match_operand:BLK 2))) 9922 (use (match_operand:SI 3))])] 9923 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)" 9924 { 9925 if (optimize_insn_for_size_p ()) 9926 FAIL; 9927 9928 if (expand_strn_compare (operands, 1)) 9929 DONE; 9930 else 9931 FAIL; 9932 }) 9933 9934 ;; Block compare insn. 9935 ;; Argument 0 is the target (result) 9936 ;; Argument 1 is the destination 9937 ;; Argument 2 is the source 9938 ;; Argument 3 is the length 9939 ;; Argument 4 is the alignment 9940 9941 (define_expand "cmpmemsi" 9942 [(parallel [(set (match_operand:SI 0) 9943 (compare:SI (match_operand:BLK 1) 9944 (match_operand:BLK 2))) 9945 (use (match_operand:SI 3)) 9946 (use (match_operand:SI 4))])] 9947 "TARGET_POPCNTD" 9948 { 9949 if (expand_block_compare (operands)) 9950 DONE; 9951 else 9952 FAIL; 9953 }) 9954 9955 ;; String/block copy insn (source and destination must not overlap). 9956 ;; Argument 0 is the destination 9957 ;; Argument 1 is the source 9958 ;; Argument 2 is the length 9959 ;; Argument 3 is the alignment 9960 9961 (define_expand "cpymemsi" 9962 [(parallel [(set (match_operand:BLK 0 "") 9963 (match_operand:BLK 1 "")) 9964 (use (match_operand:SI 2 "")) 9965 (use (match_operand:SI 3 ""))])] 9966 "" 9967 { 9968 if (expand_block_move (operands, false)) 9969 DONE; 9970 else 9971 FAIL; 9972 }) 9973 9974 ;; String/block move insn (source and destination may overlap). 9975 ;; Argument 0 is the destination 9976 ;; Argument 1 is the source 9977 ;; Argument 2 is the length 9978 ;; Argument 3 is the alignment 9979 9980 (define_expand "movmemsi" 9981 [(parallel [(set (match_operand:BLK 0 "") 9982 (match_operand:BLK 1 "")) 9983 (use (match_operand:SI 2 "")) 9984 (use (match_operand:SI 3 ""))])] 9985 "" 9986 { 9987 if (expand_block_move (operands, true)) 9988 DONE; 9989 else 9990 FAIL; 9991 }) 9992 9993 9995 ;; Define insns that do load or store with update. Some of these we can 9996 ;; get by using pre-decrement or pre-increment, but the hardware can also 9997 ;; do cases where the increment is not the size of the object. 9998 ;; 9999 ;; In all these cases, we use operands 0 and 1 for the register being 10000 ;; incremented because those are the operands that local-alloc will 10001 ;; tie and these are the pair most likely to be tieable (and the ones 10002 ;; that will benefit the most). 10003 10004 (define_insn "*movdi_update1" 10005 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r") 10006 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10007 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))) 10008 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10009 (plus:P (match_dup 1) (match_dup 2)))] 10010 "TARGET_POWERPC64 && TARGET_UPDATE 10011 && (!avoiding_indexed_address_p (DImode) 10012 || !gpc_reg_operand (operands[2], Pmode))" 10013 "@ 10014 ldux %3,%0,%2 10015 ldu %3,%2(%0)" 10016 [(set_attr "type" "load") 10017 (set_attr "update" "yes") 10018 (set_attr "indexed" "yes,no")]) 10019 10020 (define_insn "movdi_<mode>_update" 10021 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10022 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) 10023 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 10024 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10025 (plus:P (match_dup 1) (match_dup 2)))] 10026 "TARGET_POWERPC64 && TARGET_UPDATE 10027 && (!avoiding_indexed_address_p (DImode) 10028 || !gpc_reg_operand (operands[2], Pmode) 10029 || (REG_P (operands[0]) 10030 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 10031 "@ 10032 stdux %3,%0,%2 10033 stdu %3,%2(%0)" 10034 [(set_attr "type" "store") 10035 (set_attr "update" "yes") 10036 (set_attr "indexed" "yes,no")]) 10037 10038 ;; This pattern is only conditional on TARGET_64BIT, as it is 10039 ;; needed for stack allocation, even if the user passes -mno-update. 10040 (define_insn "movdi_update_stack" 10041 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") 10042 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))) 10043 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 10044 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") 10045 (plus:DI (match_dup 1) (match_dup 2)))] 10046 "TARGET_64BIT" 10047 "@ 10048 stdux %3,%0,%2 10049 stdu %3,%2(%0)" 10050 [(set_attr "type" "store") 10051 (set_attr "update" "yes") 10052 (set_attr "indexed" "yes,no")]) 10053 10054 (define_insn "*movsi_update1" 10055 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 10056 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10057 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 10058 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10059 (plus:P (match_dup 1) (match_dup 2)))] 10060 "TARGET_UPDATE 10061 && (!avoiding_indexed_address_p (SImode) 10062 || !gpc_reg_operand (operands[2], Pmode))" 10063 "@ 10064 lwzux %3,%0,%2 10065 lwzu %3,%2(%0)" 10066 [(set_attr "type" "load") 10067 (set_attr "update" "yes") 10068 (set_attr "indexed" "yes,no")]) 10069 10070 (define_insn "*movsi_update2" 10071 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r") 10072 (sign_extend:EXTSI 10073 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0") 10074 (match_operand:P 2 "gpc_reg_operand" "r"))))) 10075 (set (match_operand:P 0 "gpc_reg_operand" "=b") 10076 (plus:P (match_dup 1) (match_dup 2)))] 10077 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)" 10078 "lwaux %3,%0,%2" 10079 [(set_attr "type" "load") 10080 (set_attr "sign_extend" "yes") 10081 (set_attr "update" "yes") 10082 (set_attr "indexed" "yes")]) 10083 10084 (define_insn "movsi_<mode>_update" 10085 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10086 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 10087 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 10088 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10089 (plus:P (match_dup 1) (match_dup 2)))] 10090 "TARGET_UPDATE 10091 && (!avoiding_indexed_address_p (SImode) 10092 || !gpc_reg_operand (operands[2], Pmode) 10093 || (REG_P (operands[0]) 10094 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 10095 "@ 10096 stwux %3,%0,%2 10097 stwu %3,%2(%0)" 10098 [(set_attr "type" "store") 10099 (set_attr "update" "yes") 10100 (set_attr "indexed" "yes,no")]) 10101 10102 ;; This is an unconditional pattern; needed for stack allocation, even 10103 ;; if the user passes -mno-update. 10104 (define_insn "movsi_update_stack" 10105 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 10106 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 10107 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 10108 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 10109 (plus:SI (match_dup 1) (match_dup 2)))] 10110 "TARGET_32BIT" 10111 "@ 10112 stwux %3,%0,%2 10113 stwu %3,%2(%0)" 10114 [(set_attr "type" "store") 10115 (set_attr "update" "yes") 10116 (set_attr "indexed" "yes,no")]) 10117 10118 (define_insn "*movhi_update1" 10119 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r") 10120 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10121 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 10122 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10123 (plus:P (match_dup 1) (match_dup 2)))] 10124 "TARGET_UPDATE 10125 && (!avoiding_indexed_address_p (HImode) 10126 || !gpc_reg_operand (operands[2], SImode))" 10127 "@ 10128 lhzux %3,%0,%2 10129 lhzu %3,%2(%0)" 10130 [(set_attr "type" "load") 10131 (set_attr "update" "yes") 10132 (set_attr "indexed" "yes,no")]) 10133 10134 (define_insn "*movhi_update2" 10135 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r") 10136 (zero_extend:EXTHI 10137 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10138 (match_operand:P 2 "reg_or_short_operand" "r,I"))))) 10139 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10140 (plus:P (match_dup 1) (match_dup 2)))] 10141 "TARGET_UPDATE 10142 && (!avoiding_indexed_address_p (HImode) 10143 || !gpc_reg_operand (operands[2], Pmode))" 10144 "@ 10145 lhzux %3,%0,%2 10146 lhzu %3,%2(%0)" 10147 [(set_attr "type" "load") 10148 (set_attr "update" "yes") 10149 (set_attr "indexed" "yes,no")]) 10150 10151 (define_insn "*movhi_update3" 10152 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r") 10153 (sign_extend:EXTHI 10154 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10155 (match_operand:P 2 "reg_or_short_operand" "r,I"))))) 10156 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10157 (plus:P (match_dup 1) (match_dup 2)))] 10158 "TARGET_UPDATE 10159 && !(avoiding_indexed_address_p (HImode) 10160 && gpc_reg_operand (operands[2], Pmode))" 10161 "@ 10162 lhaux %3,%0,%2 10163 lhau %3,%2(%0)" 10164 [(set_attr "type" "load") 10165 (set_attr "sign_extend" "yes") 10166 (set_attr "update" "yes") 10167 (set_attr "indexed" "yes,no")]) 10168 10169 (define_insn "*movhi_update4" 10170 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10171 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 10172 (match_operand:HI 3 "gpc_reg_operand" "r,r")) 10173 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10174 (plus:P (match_dup 1) (match_dup 2)))] 10175 "TARGET_UPDATE 10176 && (!avoiding_indexed_address_p (HImode) 10177 || !gpc_reg_operand (operands[2], Pmode))" 10178 "@ 10179 sthux %3,%0,%2 10180 sthu %3,%2(%0)" 10181 [(set_attr "type" "store") 10182 (set_attr "update" "yes") 10183 (set_attr "indexed" "yes,no")]) 10184 10185 (define_insn "*movqi_update1" 10186 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r") 10187 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10188 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 10189 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10190 (plus:P (match_dup 1) (match_dup 2)))] 10191 "TARGET_UPDATE 10192 && (!avoiding_indexed_address_p (QImode) 10193 || !gpc_reg_operand (operands[2], Pmode))" 10194 "@ 10195 lbzux %3,%0,%2 10196 lbzu %3,%2(%0)" 10197 [(set_attr "type" "load") 10198 (set_attr "update" "yes") 10199 (set_attr "indexed" "yes,no")]) 10200 10201 (define_insn "*movqi_update2" 10202 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r") 10203 (zero_extend:EXTQI 10204 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10205 (match_operand:P 2 "reg_or_short_operand" "r,I"))))) 10206 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10207 (plus:P (match_dup 1) (match_dup 2)))] 10208 "TARGET_UPDATE 10209 && (!avoiding_indexed_address_p (QImode) 10210 || !gpc_reg_operand (operands[2], Pmode))" 10211 "@ 10212 lbzux %3,%0,%2 10213 lbzu %3,%2(%0)" 10214 [(set_attr "type" "load") 10215 (set_attr "update" "yes") 10216 (set_attr "indexed" "yes,no")]) 10217 10218 (define_insn "*movqi_update3" 10219 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10220 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 10221 (match_operand:QI 3 "gpc_reg_operand" "r,r")) 10222 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10223 (plus:P (match_dup 1) (match_dup 2)))] 10224 "TARGET_UPDATE 10225 && (!avoiding_indexed_address_p (QImode) 10226 || !gpc_reg_operand (operands[2], Pmode))" 10227 "@ 10228 stbux %3,%0,%2 10229 stbu %3,%2(%0)" 10230 [(set_attr "type" "store") 10231 (set_attr "update" "yes") 10232 (set_attr "indexed" "yes,no")]) 10233 10234 (define_insn "*mov<SFDF:mode>_update1" 10235 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>") 10236 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10237 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 10238 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10239 (plus:P (match_dup 1) (match_dup 2)))] 10240 "TARGET_HARD_FLOAT && TARGET_UPDATE 10241 && (!avoiding_indexed_address_p (<SFDF:MODE>mode) 10242 || !gpc_reg_operand (operands[2], Pmode))" 10243 "@ 10244 lf<sd>ux %3,%0,%2 10245 lf<sd>u %3,%2(%0)" 10246 [(set_attr "type" "fpload") 10247 (set_attr "update" "yes") 10248 (set_attr "indexed" "yes,no") 10249 (set_attr "size" "<SFDF:bits>")]) 10250 10251 (define_insn "*mov<SFDF:mode>_update2" 10252 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10253 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 10254 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>")) 10255 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10256 (plus:P (match_dup 1) (match_dup 2)))] 10257 "TARGET_HARD_FLOAT && TARGET_UPDATE 10258 && (!avoiding_indexed_address_p (<SFDF:MODE>mode) 10259 || !gpc_reg_operand (operands[2], Pmode))" 10260 "@ 10261 stf<sd>ux %3,%0,%2 10262 stf<sd>u %3,%2(%0)" 10263 [(set_attr "type" "fpstore") 10264 (set_attr "update" "yes") 10265 (set_attr "indexed" "yes,no") 10266 (set_attr "size" "<SFDF:bits>")]) 10267 10268 (define_insn "*movsf_update3" 10269 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r") 10270 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10271 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 10272 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10273 (plus:P (match_dup 1) (match_dup 2)))] 10274 "TARGET_SOFT_FLOAT && TARGET_UPDATE 10275 && (!avoiding_indexed_address_p (SFmode) 10276 || !gpc_reg_operand (operands[2], Pmode))" 10277 "@ 10278 lwzux %3,%0,%2 10279 lwzu %3,%2(%0)" 10280 [(set_attr "type" "load") 10281 (set_attr "update" "yes") 10282 (set_attr "indexed" "yes,no")]) 10283 10284 (define_insn "*movsf_update4" 10285 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 10286 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 10287 (match_operand:SF 3 "gpc_reg_operand" "r,r")) 10288 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 10289 (plus:P (match_dup 1) (match_dup 2)))] 10290 "TARGET_SOFT_FLOAT && TARGET_UPDATE 10291 && (!avoiding_indexed_address_p (SFmode) 10292 || !gpc_reg_operand (operands[2], Pmode))" 10293 "@ 10294 stwux %3,%0,%2 10295 stwu %3,%2(%0)" 10296 [(set_attr "type" "store") 10297 (set_attr "update" "yes") 10298 (set_attr "indexed" "yes,no")]) 10299 10300 10301 ;; After inserting conditional returns we can sometimes have 10302 ;; unnecessary register moves. Unfortunately we cannot have a 10303 ;; modeless peephole here, because some single SImode sets have early 10304 ;; clobber outputs. Although those sets expand to multi-ppc-insn 10305 ;; sequences, using get_attr_length here will smash the operands 10306 ;; array. Neither is there an early_cobbler_p predicate. 10307 ;; Also this optimization interferes with scalars going into 10308 ;; altivec registers (the code does reloading through the FPRs). 10309 (define_peephole2 10310 [(set (match_operand:DF 0 "gpc_reg_operand") 10311 (match_operand:DF 1 "any_operand")) 10312 (set (match_operand:DF 2 "gpc_reg_operand") 10313 (match_dup 0))] 10314 "!TARGET_VSX 10315 && peep2_reg_dead_p (2, operands[0])" 10316 [(set (match_dup 2) (match_dup 1))]) 10317 10318 (define_peephole2 10319 [(set (match_operand:SF 0 "gpc_reg_operand") 10320 (match_operand:SF 1 "any_operand")) 10321 (set (match_operand:SF 2 "gpc_reg_operand") 10322 (match_dup 0))] 10323 "!TARGET_P8_VECTOR 10324 && peep2_reg_dead_p (2, operands[0])" 10325 [(set (match_dup 2) (match_dup 1))]) 10326 10327 10329 ;; TLS support. 10330 10331 (define_insn "*tls_gd_pcrel<bits>" 10332 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10333 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") 10334 (const_int 0)] 10335 UNSPEC_TLSGD))] 10336 "HAVE_AS_TLS && TARGET_ELF" 10337 "la %0,%1@got@tlsgd@pcrel" 10338 [(set_attr "prefixed" "yes")]) 10339 10340 (define_insn_and_split "*tls_gd<bits>" 10341 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10342 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") 10343 (match_operand:P 2 "gpc_reg_operand" "b")] 10344 UNSPEC_TLSGD))] 10345 "HAVE_AS_TLS && TARGET_ELF" 10346 "addi %0,%2,%1@got@tlsgd" 10347 "&& TARGET_CMODEL != CMODEL_SMALL" 10348 [(set (match_dup 3) 10349 (high:P 10350 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) 10351 (set (match_dup 0) 10352 (lo_sum:P (match_dup 3) 10353 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))] 10354 { 10355 operands[3] = gen_reg_rtx (<MODE>mode); 10356 } 10357 [(set (attr "length") 10358 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 10359 (const_int 8) 10360 (const_int 4)))]) 10361 10362 (define_insn "*tls_gd_high<bits>" 10363 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10364 (high:P 10365 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") 10366 (match_operand:P 2 "gpc_reg_operand" "b")] 10367 UNSPEC_TLSGD)))] 10368 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10369 "addis %0,%2,%1@got@tlsgd@ha") 10370 10371 (define_insn "*tls_gd_low<bits>" 10372 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10373 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 10374 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "") 10375 (match_operand:P 3 "gpc_reg_operand" "b")] 10376 UNSPEC_TLSGD)))] 10377 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10378 "addi %0,%1,%2@got@tlsgd@l") 10379 10380 (define_insn "*tls_ld_pcrel<bits>" 10381 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10382 (unspec:P [(const_int 0)] 10383 UNSPEC_TLSLD))] 10384 "HAVE_AS_TLS && TARGET_ELF" 10385 "la %0,%&@got@tlsld@pcrel" 10386 [(set_attr "prefixed" "yes")]) 10387 10388 (define_insn_and_split "*tls_ld<bits>" 10389 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10390 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] 10391 UNSPEC_TLSLD))] 10392 "HAVE_AS_TLS && TARGET_ELF" 10393 "addi %0,%1,%&@got@tlsld" 10394 "&& TARGET_CMODEL != CMODEL_SMALL" 10395 [(set (match_dup 2) 10396 (high:P 10397 (unspec:P [(match_dup 1)] UNSPEC_TLSLD))) 10398 (set (match_dup 0) 10399 (lo_sum:P (match_dup 2) 10400 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))] 10401 { 10402 operands[2] = gen_reg_rtx (<MODE>mode); 10403 } 10404 [(set (attr "length") 10405 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 10406 (const_int 8) 10407 (const_int 4)))]) 10408 10409 (define_insn "*tls_ld_high<bits>" 10410 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10411 (high:P 10412 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] 10413 UNSPEC_TLSLD)))] 10414 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10415 "addis %0,%1,%&@got@tlsld@ha") 10416 10417 (define_insn "*tls_ld_low<bits>" 10418 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10419 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 10420 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")] 10421 UNSPEC_TLSLD)))] 10422 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10423 "addi %0,%1,%&@got@tlsld@l") 10424 10425 (define_insn "tls_dtprel_<bits>" 10426 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10427 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10428 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10429 UNSPEC_TLSDTPREL))] 10430 "HAVE_AS_TLS" 10431 "addi %0,%1,%2@dtprel" 10432 [(set (attr "prefixed") 10433 (if_then_else (match_test "rs6000_tls_size == 16") 10434 (const_string "no") 10435 (const_string "yes")))]) 10436 10437 (define_insn "tls_dtprel_ha_<bits>" 10438 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10439 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10440 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10441 UNSPEC_TLSDTPRELHA))] 10442 "HAVE_AS_TLS" 10443 "addis %0,%1,%2@dtprel@ha") 10444 10445 (define_insn "tls_dtprel_lo_<bits>" 10446 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10447 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10448 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10449 UNSPEC_TLSDTPRELLO))] 10450 "HAVE_AS_TLS" 10451 "addi %0,%1,%2@dtprel@l") 10452 10453 (define_insn_and_split "tls_got_dtprel_<bits>" 10454 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10455 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10456 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10457 UNSPEC_TLSGOTDTPREL))] 10458 "HAVE_AS_TLS" 10459 "<ptrload> %0,%2@got@dtprel(%1)" 10460 "&& TARGET_CMODEL != CMODEL_SMALL" 10461 [(set (match_dup 3) 10462 (high:P 10463 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) 10464 (set (match_dup 0) 10465 (lo_sum:P (match_dup 3) 10466 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))] 10467 { 10468 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 10469 } 10470 [(set (attr "length") 10471 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 10472 (const_int 8) 10473 (const_int 4)))]) 10474 10475 (define_insn "*tls_got_dtprel_high<bits>" 10476 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10477 (high:P 10478 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10479 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10480 UNSPEC_TLSGOTDTPREL)))] 10481 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 10482 "addis %0,%1,%2@got@dtprel@ha") 10483 10484 (define_insn "*tls_got_dtprel_low<bits>" 10485 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10486 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 10487 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b") 10488 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10489 UNSPEC_TLSGOTDTPREL)))] 10490 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 10491 "<ptrload> %0,%2@got@dtprel@l(%1)") 10492 10493 (define_insn "tls_tprel_<bits>" 10494 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10495 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10496 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10497 UNSPEC_TLSTPREL))] 10498 "HAVE_AS_TLS" 10499 "addi %0,%1,%2@tprel" 10500 [(set (attr "prefixed") 10501 (if_then_else (match_test "rs6000_tls_size == 16") 10502 (const_string "no") 10503 (const_string "yes")))]) 10504 10505 (define_insn "tls_tprel_ha_<bits>" 10506 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10507 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10508 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10509 UNSPEC_TLSTPRELHA))] 10510 "HAVE_AS_TLS" 10511 "addis %0,%1,%2@tprel@ha") 10512 10513 (define_insn "tls_tprel_lo_<bits>" 10514 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10515 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10516 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10517 UNSPEC_TLSTPRELLO))] 10518 "HAVE_AS_TLS" 10519 "addi %0,%1,%2@tprel@l") 10520 10521 (define_insn "*tls_got_tprel_pcrel_<bits>" 10522 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10523 (unspec:P [(const_int 0) 10524 (match_operand:P 1 "rs6000_tls_symbol_ref" "")] 10525 UNSPEC_TLSGOTTPREL))] 10526 "HAVE_AS_TLS" 10527 "<ptrload> %0,%1@got@tprel@pcrel" 10528 [(set_attr "prefixed" "yes")]) 10529 10530 ;; "b" output constraint here and on tls_tls input to support linker tls 10531 ;; optimization. The linker may edit the instructions emitted by a 10532 ;; tls_got_tprel/tls_tls pair to addis,addi. 10533 (define_insn_and_split "tls_got_tprel_<bits>" 10534 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10535 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10536 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10537 UNSPEC_TLSGOTTPREL))] 10538 "HAVE_AS_TLS" 10539 "<ptrload> %0,%2@got@tprel(%1)" 10540 "&& TARGET_CMODEL != CMODEL_SMALL" 10541 [(set (match_dup 3) 10542 (high:P 10543 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) 10544 (set (match_dup 0) 10545 (lo_sum:P (match_dup 3) 10546 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))] 10547 { 10548 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 10549 } 10550 [(set (attr "length") 10551 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 10552 (const_int 8) 10553 (const_int 4)))]) 10554 10555 (define_insn "*tls_got_tprel_high<bits>" 10556 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10557 (high:P 10558 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10559 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10560 UNSPEC_TLSGOTTPREL)))] 10561 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 10562 "addis %0,%1,%2@got@tprel@ha") 10563 10564 (define_insn "*tls_got_tprel_low<bits>" 10565 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10566 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 10567 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b") 10568 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10569 UNSPEC_TLSGOTTPREL)))] 10570 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 10571 "<ptrload> %0,%2@got@tprel@l(%1)") 10572 10573 (define_insn "tls_tls_pcrel_<bits>" 10574 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10575 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10576 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10577 UNSPEC_TLSTLS_PCREL))] 10578 "TARGET_ELF && HAVE_AS_TLS" 10579 "add %0,%1,%2@tls@pcrel") 10580 10581 (define_insn "tls_tls_<bits>" 10582 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10583 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10584 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 10585 UNSPEC_TLSTLS))] 10586 "TARGET_ELF && HAVE_AS_TLS" 10587 "add %0,%1,%2@tls") 10588 10589 (define_expand "tls_get_tpointer" 10590 [(set (match_operand:SI 0 "gpc_reg_operand") 10591 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))] 10592 "TARGET_XCOFF && HAVE_AS_TLS" 10593 { 10594 emit_insn (gen_tls_get_tpointer_internal ()); 10595 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); 10596 DONE; 10597 }) 10598 10599 (define_insn "tls_get_tpointer_internal" 10600 [(set (reg:SI 3) 10601 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS)) 10602 (clobber (reg:SI LR_REGNO))] 10603 "TARGET_XCOFF && HAVE_AS_TLS" 10604 "bla .__get_tpointer") 10605 10606 (define_expand "tls_get_addr<mode>" 10607 [(set (match_operand:P 0 "gpc_reg_operand") 10608 (unspec:P [(match_operand:P 1 "gpc_reg_operand") 10609 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))] 10610 "TARGET_XCOFF && HAVE_AS_TLS" 10611 { 10612 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]); 10613 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]); 10614 emit_insn (gen_tls_get_addr_internal<mode> ()); 10615 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3)); 10616 DONE; 10617 }) 10618 10619 (define_insn "tls_get_addr_internal<mode>" 10620 [(set (reg:P 3) 10621 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS)) 10622 (clobber (reg:P 0)) 10623 (clobber (reg:P 4)) 10624 (clobber (reg:P 5)) 10625 (clobber (reg:P 11)) 10626 (clobber (reg:CC CR0_REGNO)) 10627 (clobber (reg:P LR_REGNO))] 10628 "TARGET_XCOFF && HAVE_AS_TLS" 10629 "bla .__tls_get_addr") 10630 10632 ;; Next come insns related to the calling sequence. 10633 ;; 10634 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). 10635 ;; We move the back-chain and decrement the stack pointer. 10636 ;; 10637 ;; Operand1 is more naturally reg_or_short_operand. However, for a large 10638 ;; constant alloca, using that predicate will force the generic code to put 10639 ;; the constant size into a register before calling the expander. 10640 ;; 10641 ;; As a result the expander would not have the constant size information 10642 ;; in those cases and would have to generate less efficient code. 10643 ;; 10644 ;; Thus we allow reg_or_cint_operand instead so that the expander can see 10645 ;; the constant size. The value is forced into a register if necessary. 10646 ;; 10647 (define_expand "allocate_stack" 10648 [(set (match_operand 0 "gpc_reg_operand") 10649 (minus (reg 1) (match_operand 1 "reg_or_cint_operand"))) 10650 (set (reg 1) 10651 (minus (reg 1) (match_dup 1)))] 10652 "" 10653 { 10654 rtx chain = gen_reg_rtx (Pmode); 10655 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); 10656 rtx neg_op0; 10657 rtx insn, par, set, mem; 10658 10659 /* By allowing reg_or_cint_operand as the predicate we can get 10660 better code for stack-clash-protection because we do not lose 10661 size information. But the rest of the code expects the operand 10662 to be reg_or_short_operand. If it isn't, then force it into 10663 a register. */ 10664 rtx orig_op1 = operands[1]; 10665 if (!reg_or_short_operand (operands[1], Pmode)) 10666 operands[1] = force_reg (Pmode, operands[1]); 10667 10668 emit_move_insn (chain, stack_bot); 10669 10670 /* Check stack bounds if necessary. */ 10671 if (crtl->limit_stack) 10672 { 10673 rtx available; 10674 available = expand_binop (Pmode, sub_optab, 10675 stack_pointer_rtx, stack_limit_rtx, 10676 NULL_RTX, 1, OPTAB_WIDEN); 10677 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx)); 10678 } 10679 10680 /* Allocate and probe if requested. 10681 This may look similar to the loop we use for prologue allocations, 10682 but it is critically different. For the former we know the loop 10683 will iterate, but do not know that generally here. The former 10684 uses that knowledge to rotate the loop. Combining them would be 10685 possible with some performance cost. */ 10686 if (flag_stack_clash_protection) 10687 { 10688 rtx rounded_size, last_addr, residual; 10689 HOST_WIDE_INT probe_interval; 10690 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr, 10691 &residual, &probe_interval, 10692 orig_op1); 10693 10694 /* We do occasionally get in here with constant sizes, we might 10695 as well do a reasonable job when we obviously can. */ 10696 if (rounded_size != const0_rtx) 10697 { 10698 rtx loop_lab, end_loop; 10699 bool rotated = CONST_INT_P (rounded_size); 10700 rtx update = GEN_INT (-probe_interval); 10701 if (probe_interval > 32768) 10702 update = force_reg (Pmode, update); 10703 10704 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop, 10705 last_addr, rotated); 10706 10707 if (TARGET_32BIT) 10708 emit_insn (gen_movsi_update_stack (stack_pointer_rtx, 10709 stack_pointer_rtx, 10710 update, chain)); 10711 else 10712 emit_insn (gen_movdi_update_stack (stack_pointer_rtx, 10713 stack_pointer_rtx, 10714 update, chain)); 10715 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop, 10716 last_addr, rotated); 10717 } 10718 10719 /* Now handle residuals. We just have to set operands[1] correctly 10720 and let the rest of the expander run. */ 10721 operands[1] = residual; 10722 } 10723 10724 if (!(CONST_INT_P (operands[1]) 10725 && IN_RANGE (INTVAL (operands[1]), -32767, 32768))) 10726 { 10727 operands[1] = force_reg (Pmode, operands[1]); 10728 neg_op0 = gen_reg_rtx (Pmode); 10729 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1])); 10730 } 10731 else 10732 neg_op0 = GEN_INT (-INTVAL (operands[1])); 10733 10734 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack 10735 : gen_movdi_update_stack)) 10736 (stack_pointer_rtx, stack_pointer_rtx, neg_op0, 10737 chain)); 10738 /* Since we didn't use gen_frame_mem to generate the MEM, grab 10739 it now and set the alias set/attributes. The above gen_*_update 10740 calls will generate a PARALLEL with the MEM set being the first 10741 operation. */ 10742 par = PATTERN (insn); 10743 gcc_assert (GET_CODE (par) == PARALLEL); 10744 set = XVECEXP (par, 0, 0); 10745 gcc_assert (GET_CODE (set) == SET); 10746 mem = SET_DEST (set); 10747 gcc_assert (MEM_P (mem)); 10748 MEM_NOTRAP_P (mem) = 1; 10749 set_mem_alias_set (mem, get_frame_alias_set ()); 10750 10751 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 10752 DONE; 10753 }) 10754 10755 ;; These patterns say how to save and restore the stack pointer. We need not 10756 ;; save the stack pointer at function level since we are careful to 10757 ;; preserve the backchain. At block level, we have to restore the backchain 10758 ;; when we restore the stack pointer. 10759 ;; 10760 ;; For nonlocal gotos, we must save both the stack pointer and its 10761 ;; backchain and restore both. Note that in the nonlocal case, the 10762 ;; save area is a memory location. 10763 10764 (define_expand "save_stack_function" 10765 [(match_operand 0 "any_operand") 10766 (match_operand 1 "any_operand")] 10767 "" 10768 "DONE;") 10769 10770 (define_expand "restore_stack_function" 10771 [(match_operand 0 "any_operand") 10772 (match_operand 1 "any_operand")] 10773 "" 10774 "DONE;") 10775 10776 ;; Adjust stack pointer (op0) to a new value (op1). 10777 ;; First copy old stack backchain to new location, and ensure that the 10778 ;; scheduler won't reorder the sp assignment before the backchain write. 10779 (define_expand "restore_stack_block" 10780 [(set (match_dup 2) (match_dup 3)) 10781 (set (match_dup 4) (match_dup 2)) 10782 (match_dup 5) 10783 (set (match_operand 0 "register_operand") 10784 (match_operand 1 "register_operand"))] 10785 "" 10786 { 10787 rtvec p; 10788 10789 operands[1] = force_reg (Pmode, operands[1]); 10790 operands[2] = gen_reg_rtx (Pmode); 10791 operands[3] = gen_frame_mem (Pmode, operands[0]); 10792 operands[4] = gen_frame_mem (Pmode, operands[1]); 10793 p = rtvec_alloc (1); 10794 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 10795 const0_rtx); 10796 operands[5] = gen_rtx_PARALLEL (VOIDmode, p); 10797 }) 10798 10799 (define_expand "save_stack_nonlocal" 10800 [(set (match_dup 3) (match_dup 4)) 10801 (set (match_operand 0 "memory_operand") (match_dup 3)) 10802 (set (match_dup 2) (match_operand 1 "register_operand"))] 10803 "" 10804 { 10805 int units_per_word = (TARGET_32BIT) ? 4 : 8; 10806 10807 /* Copy the backchain to the first word, sp to the second. */ 10808 operands[0] = adjust_address_nv (operands[0], Pmode, 0); 10809 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word); 10810 operands[3] = gen_reg_rtx (Pmode); 10811 operands[4] = gen_frame_mem (Pmode, operands[1]); 10812 }) 10813 10814 (define_expand "restore_stack_nonlocal" 10815 [(set (match_dup 2) (match_operand 1 "memory_operand")) 10816 (set (match_dup 3) (match_dup 4)) 10817 (set (match_dup 5) (match_dup 2)) 10818 (match_dup 6) 10819 (set (match_operand 0 "register_operand") (match_dup 3))] 10820 "" 10821 { 10822 int units_per_word = (TARGET_32BIT) ? 4 : 8; 10823 rtvec p; 10824 10825 /* Restore the backchain from the first word, sp from the second. */ 10826 operands[2] = gen_reg_rtx (Pmode); 10827 operands[3] = gen_reg_rtx (Pmode); 10828 operands[1] = adjust_address_nv (operands[1], Pmode, 0); 10829 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word); 10830 operands[5] = gen_frame_mem (Pmode, operands[3]); 10831 p = rtvec_alloc (1); 10832 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 10833 const0_rtx); 10834 operands[6] = gen_rtx_PARALLEL (VOIDmode, p); 10835 }) 10836 10838 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel 10839 ;; to the symbol or label. 10840 (define_insn "*pcrel_local_addr" 10841 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10842 (match_operand:DI 1 "pcrel_local_address"))] 10843 "TARGET_PCREL" 10844 "la %0,%a1" 10845 [(set_attr "prefixed" "yes")]) 10846 10847 ;; Load up a PC-relative address to an external symbol. If the symbol and the 10848 ;; program are both defined in the main program, the linker will optimize this 10849 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by 10850 ;; the dynamic linker and loaded up. Print_operand_address will append a 10851 ;; @got@pcrel to the symbol. 10852 (define_insn "*pcrel_extern_addr" 10853 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10854 (match_operand:DI 1 "pcrel_external_address"))] 10855 "TARGET_PCREL" 10856 "ld %0,%a1" 10857 [(set_attr "prefixed" "yes") 10858 (set_attr "type" "load") 10859 (set_attr "loads_external_address" "yes")]) 10860 10861 ;; TOC register handling. 10862 10863 ;; Code to initialize the TOC register... 10864 10865 (define_insn "load_toc_aix_si" 10866 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10867 (unspec:SI [(const_int 0)] UNSPEC_TOC)) 10868 (use (reg:SI 2))])] 10869 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT" 10870 { 10871 char buf[30]; 10872 extern int need_toc_init; 10873 need_toc_init = 1; 10874 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); 10875 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 10876 operands[2] = gen_rtx_REG (Pmode, 2); 10877 return "lwz %0,%1(%2)"; 10878 } 10879 [(set_attr "type" "load") 10880 (set_attr "update" "no") 10881 (set_attr "indexed" "no")]) 10882 10883 (define_insn "load_toc_aix_di" 10884 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10885 (unspec:DI [(const_int 0)] UNSPEC_TOC)) 10886 (use (reg:DI 2))])] 10887 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT" 10888 { 10889 char buf[30]; 10890 extern int need_toc_init; 10891 need_toc_init = 1; 10892 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 10893 !TARGET_ELF || !TARGET_MINIMAL_TOC); 10894 if (TARGET_ELF) 10895 strcat (buf, "@toc"); 10896 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 10897 operands[2] = gen_rtx_REG (Pmode, 2); 10898 return "ld %0,%1(%2)"; 10899 } 10900 [(set_attr "type" "load") 10901 (set_attr "update" "no") 10902 (set_attr "indexed" "no")]) 10903 10904 (define_insn "load_toc_v4_pic_si" 10905 [(set (reg:SI LR_REGNO) 10906 (unspec:SI [(const_int 0)] UNSPEC_TOC))] 10907 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT" 10908 "bl _GLOBAL_OFFSET_TABLE_@local-4" 10909 [(set_attr "type" "branch")]) 10910 10911 (define_expand "load_toc_v4_PIC_1" 10912 [(parallel [(set (reg:SI LR_REGNO) 10913 (match_operand:SI 0 "immediate_operand" "s")) 10914 (use (unspec [(match_dup 0)] UNSPEC_TOC))])] 10915 "TARGET_ELF && DEFAULT_ABI == ABI_V4 10916 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10917 "") 10918 10919 (define_insn "load_toc_v4_PIC_1_normal" 10920 [(set (reg:SI LR_REGNO) 10921 (match_operand:SI 0 "immediate_operand" "s")) 10922 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 10923 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 10924 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10925 "bcl 20,31,%0\n%0:" 10926 [(set_attr "type" "branch") 10927 (set_attr "cannot_copy" "yes")]) 10928 10929 (define_insn "load_toc_v4_PIC_1_476" 10930 [(set (reg:SI LR_REGNO) 10931 (match_operand:SI 0 "immediate_operand" "s")) 10932 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 10933 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 10934 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10935 { 10936 char name[32]; 10937 static char templ[32]; 10938 10939 get_ppc476_thunk_name (name); 10940 sprintf (templ, "bl %s\n%%0:", name); 10941 return templ; 10942 } 10943 [(set_attr "type" "branch") 10944 (set_attr "cannot_copy" "yes")]) 10945 10946 (define_expand "load_toc_v4_PIC_1b" 10947 [(parallel [(set (reg:SI LR_REGNO) 10948 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10949 (label_ref (match_operand 1 ""))] 10950 UNSPEC_TOCPTR)) 10951 (match_dup 1)])] 10952 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10953 "") 10954 10955 (define_insn "load_toc_v4_PIC_1b_normal" 10956 [(set (reg:SI LR_REGNO) 10957 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10958 (label_ref (match_operand 1 "" ""))] 10959 UNSPEC_TOCPTR)) 10960 (match_dup 1)] 10961 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10962 "bcl 20,31,$+8\;.long %0-$" 10963 [(set_attr "type" "branch") 10964 (set_attr "length" "8")]) 10965 10966 (define_insn "load_toc_v4_PIC_1b_476" 10967 [(set (reg:SI LR_REGNO) 10968 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10969 (label_ref (match_operand 1 "" ""))] 10970 UNSPEC_TOCPTR)) 10971 (match_dup 1)] 10972 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10973 { 10974 char name[32]; 10975 static char templ[32]; 10976 10977 get_ppc476_thunk_name (name); 10978 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name); 10979 return templ; 10980 } 10981 [(set_attr "type" "branch") 10982 (set_attr "length" "16")]) 10983 10984 (define_insn "load_toc_v4_PIC_2" 10985 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10986 (mem:SI (plus:SI 10987 (match_operand:SI 1 "gpc_reg_operand" "b") 10988 (const 10989 (minus:SI (match_operand:SI 2 "immediate_operand" "s") 10990 (match_operand:SI 3 "immediate_operand" "s"))))))] 10991 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10992 "lwz %0,%2-%3(%1)" 10993 [(set_attr "type" "load")]) 10994 10995 (define_insn "load_toc_v4_PIC_3b" 10996 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10997 (plus:SI 10998 (match_operand:SI 1 "gpc_reg_operand" "b") 10999 (high:SI 11000 (const 11001 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 11002 (match_operand:SI 3 "symbol_ref_operand" "s"))))))] 11003 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 11004 "addis %0,%1,%2-%3@ha") 11005 11006 (define_insn "load_toc_v4_PIC_3c" 11007 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 11008 (lo_sum:SI 11009 (match_operand:SI 1 "gpc_reg_operand" "b") 11010 (const 11011 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 11012 (match_operand:SI 3 "symbol_ref_operand" "s")))))] 11013 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 11014 "addi %0,%1,%2-%3@l") 11015 11016 ;; If the TOC is shared over a translation unit, as happens with all 11017 ;; the kinds of PIC that we support, we need to restore the TOC 11018 ;; pointer only when jumping over units of translation. 11019 ;; On Darwin, we need to reload the picbase. 11020 11021 (define_expand "builtin_setjmp_receiver" 11022 [(use (label_ref (match_operand 0 "")))] 11023 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1) 11024 || (TARGET_TOC && TARGET_MINIMAL_TOC) 11025 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)" 11026 { 11027 #if TARGET_MACHO 11028 if (DEFAULT_ABI == ABI_DARWIN) 11029 { 11030 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); 11031 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 11032 rtx tmplabrtx; 11033 char tmplab[20]; 11034 11035 crtl->uses_pic_offset_table = 1; 11036 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR", 11037 CODE_LABEL_NUMBER (operands[0])); 11038 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); 11039 11040 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx)); 11041 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); 11042 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg, 11043 picrtx, tmplabrtx)); 11044 } 11045 else 11046 #endif 11047 rs6000_emit_load_toc_table (FALSE); 11048 DONE; 11049 }) 11050 11051 ;; Largetoc support 11052 (define_insn "*largetoc_high" 11053 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 11054 (high:DI 11055 (unspec [(match_operand:DI 1 "" "") 11056 (match_operand:DI 2 "gpc_reg_operand" "b")] 11057 UNSPEC_TOCREL)))] 11058 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 11059 "addis %0,%2,%1@toc@ha") 11060 11061 (define_insn "*largetoc_high_aix<mode>" 11062 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 11063 (high:P 11064 (unspec [(match_operand:P 1 "" "") 11065 (match_operand:P 2 "gpc_reg_operand" "b")] 11066 UNSPEC_TOCREL)))] 11067 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 11068 "addis %0,%1@u(%2)") 11069 11070 (define_insn "*largetoc_high_plus" 11071 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 11072 (high:DI 11073 (plus:DI 11074 (unspec [(match_operand:DI 1 "" "") 11075 (match_operand:DI 2 "gpc_reg_operand" "b")] 11076 UNSPEC_TOCREL) 11077 (match_operand:DI 3 "add_cint_operand" "n"))))] 11078 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 11079 "addis %0,%2,%1+%3@toc@ha") 11080 11081 (define_insn "*largetoc_high_plus_aix<mode>" 11082 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 11083 (high:P 11084 (plus:P 11085 (unspec [(match_operand:P 1 "" "") 11086 (match_operand:P 2 "gpc_reg_operand" "b")] 11087 UNSPEC_TOCREL) 11088 (match_operand:P 3 "add_cint_operand" "n"))))] 11089 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 11090 "addis %0,%1+%3@u(%2)") 11091 11092 (define_insn "*largetoc_low" 11093 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 11094 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 11095 (match_operand:DI 2 "" "")))] 11096 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 11097 "addi %0,%1,%2@l") 11098 11099 (define_insn "*largetoc_low_aix<mode>" 11100 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11101 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 11102 (match_operand:P 2 "" "")))] 11103 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 11104 "la %0,%2@l(%1)") 11105 11106 (define_insn_and_split "*tocref<mode>" 11107 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 11108 (match_operand:P 1 "small_toc_ref" "R"))] 11109 "TARGET_TOC 11110 && legitimate_constant_pool_address_p (operands[1], QImode, false)" 11111 "la %0,%a1" 11112 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed" 11113 [(set (match_dup 0) (high:P (match_dup 1))) 11114 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))]) 11115 11116 ;; Elf specific ways of loading addresses for non-PIC code. 11117 ;; The output of this could be r0, but we make a very strong 11118 ;; preference for a base register because it will usually 11119 ;; be needed there. 11120 (define_insn "elf_high" 11121 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") 11122 (high:SI (match_operand 1 "" "")))] 11123 "TARGET_ELF && !TARGET_64BIT && !flag_pic" 11124 "lis %0,%1@ha") 11125 11126 (define_insn "elf_low" 11127 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 11128 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 11129 (match_operand 2 "" "")))] 11130 "TARGET_ELF && !TARGET_64BIT && !flag_pic" 11131 "la %0,%2@l(%1)") 11132 11133 (define_insn "*pltseq_tocsave_<mode>" 11134 [(set (match_operand:P 0 "memory_operand" "=m") 11135 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 11136 (match_operand:P 2 "symbol_ref_operand" "s") 11137 (match_operand:P 3 "" "")] 11138 UNSPEC_PLTSEQ))] 11139 "TARGET_PLTSEQ 11140 && DEFAULT_ABI == ABI_ELFv2" 11141 { 11142 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE); 11143 }) 11144 11145 (define_insn "*pltseq_plt16_ha_<mode>" 11146 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11147 (unspec:P [(match_operand:P 1 "" "") 11148 (match_operand:P 2 "symbol_ref_operand" "s") 11149 (match_operand:P 3 "" "")] 11150 UNSPEC_PLT16_HA))] 11151 "TARGET_PLTSEQ" 11152 { 11153 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA); 11154 }) 11155 11156 (define_insn "*pltseq_plt16_lo_<mode>" 11157 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11158 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b") 11159 (match_operand:P 2 "symbol_ref_operand" "s") 11160 (match_operand:P 3 "" "")] 11161 UNSPECV_PLT16_LO))] 11162 "TARGET_PLTSEQ" 11163 { 11164 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO); 11165 } 11166 [(set_attr "type" "load")]) 11167 11168 (define_insn "*pltseq_mtctr_<mode>" 11169 [(set (match_operand:P 0 "register_operand" "=c") 11170 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") 11171 (match_operand:P 2 "symbol_ref_operand" "s") 11172 (match_operand:P 3 "" "")] 11173 UNSPEC_PLTSEQ))] 11174 "TARGET_PLTSEQ" 11175 { 11176 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR); 11177 }) 11178 11179 (define_insn "*pltseq_plt_pcrel<mode>" 11180 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11181 (unspec_volatile:P [(match_operand:P 1 "" "") 11182 (match_operand:P 2 "symbol_ref_operand" "s") 11183 (match_operand:P 3 "" "")] 11184 UNSPECV_PLT_PCREL))] 11185 "HAVE_AS_PLTSEQ && TARGET_ELF 11186 && rs6000_pcrel_p ()" 11187 { 11188 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34); 11189 } 11190 [(set_attr "type" "load") 11191 (set_attr "length" "12")]) 11192 11194 ;; Call and call_value insns 11195 ;; For the purposes of expanding calls, Darwin is very similar to SYSV. 11196 (define_expand "call" 11197 [(parallel [(call (mem:SI (match_operand 0 "address_operand")) 11198 (match_operand 1 "")) 11199 (use (match_operand 2 "")) 11200 (clobber (reg:SI LR_REGNO))])] 11201 "" 11202 { 11203 #if TARGET_MACHO 11204 if (MACHOPIC_INDIRECT) 11205 operands[0] = machopic_indirect_call_target (operands[0]); 11206 #endif 11207 11208 gcc_assert (MEM_P (operands[0])); 11209 11210 operands[0] = XEXP (operands[0], 0); 11211 11212 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 11213 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]); 11214 else if (DEFAULT_ABI == ABI_V4) 11215 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]); 11216 else if (DEFAULT_ABI == ABI_DARWIN) 11217 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]); 11218 else 11219 gcc_unreachable (); 11220 11221 DONE; 11222 }) 11223 11224 (define_expand "call_value" 11225 [(parallel [(set (match_operand 0 "") 11226 (call (mem:SI (match_operand 1 "address_operand")) 11227 (match_operand 2 ""))) 11228 (use (match_operand 3 "")) 11229 (clobber (reg:SI LR_REGNO))])] 11230 "" 11231 { 11232 #if TARGET_MACHO 11233 if (MACHOPIC_INDIRECT) 11234 operands[1] = machopic_indirect_call_target (operands[1]); 11235 #endif 11236 11237 gcc_assert (MEM_P (operands[1])); 11238 11239 operands[1] = XEXP (operands[1], 0); 11240 11241 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 11242 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]); 11243 else if (DEFAULT_ABI == ABI_V4) 11244 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]); 11245 else if (DEFAULT_ABI == ABI_DARWIN) 11246 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]); 11247 else 11248 gcc_unreachable (); 11249 11250 DONE; 11251 }) 11252 11253 ;; Call to function in current module. No TOC pointer reload needed. 11254 ;; Operand2 is nonzero if we are using the V.4 calling sequence and 11255 ;; either the function was not prototyped, or it was prototyped as a 11256 ;; variable argument function. It is > 0 if FP registers were passed 11257 ;; and < 0 if they were not. 11258 11259 (define_insn "*call_local<mode>" 11260 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s")) 11261 (match_operand 1)) 11262 (use (match_operand:SI 2 "immediate_operand" "O,n")) 11263 (clobber (reg:P LR_REGNO))] 11264 "(INTVAL (operands[2]) & CALL_LONG) == 0" 11265 { 11266 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11267 output_asm_insn ("crxor 6,6,6", operands); 11268 11269 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11270 output_asm_insn ("creqv 6,6,6", operands); 11271 11272 if (rs6000_pcrel_p ()) 11273 return "bl %z0@notoc"; 11274 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0"; 11275 } 11276 [(set_attr "type" "branch") 11277 (set_attr "length" "4,8")]) 11278 11279 (define_insn "*call_value_local<mode>" 11280 [(set (match_operand 0 "" "") 11281 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s")) 11282 (match_operand 2))) 11283 (use (match_operand:SI 3 "immediate_operand" "O,n")) 11284 (clobber (reg:P LR_REGNO))] 11285 "(INTVAL (operands[3]) & CALL_LONG) == 0" 11286 { 11287 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11288 output_asm_insn ("crxor 6,6,6", operands); 11289 11290 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11291 output_asm_insn ("creqv 6,6,6", operands); 11292 11293 if (rs6000_pcrel_p ()) 11294 return "bl %z1@notoc"; 11295 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1"; 11296 } 11297 [(set_attr "type" "branch") 11298 (set_attr "length" "4,8")]) 11299 11300 11301 ;; A function pointer under System V is just a normal pointer 11302 ;; operands[0] is the function pointer 11303 ;; operands[1] is the tls call arg 11304 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument 11305 ;; which indicates how to set cr1 11306 11307 (define_insn "*call_indirect_nonlocal_sysv<mode>" 11308 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 11309 (match_operand 1)) 11310 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 11311 (clobber (reg:P LR_REGNO))] 11312 "DEFAULT_ABI == ABI_V4 11313 || DEFAULT_ABI == ABI_DARWIN" 11314 { 11315 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11316 output_asm_insn ("crxor 6,6,6", operands); 11317 11318 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11319 output_asm_insn ("creqv 6,6,6", operands); 11320 11321 return rs6000_indirect_call_template (operands, 0); 11322 } 11323 [(set_attr "type" "jmpreg") 11324 (set (attr "length") 11325 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") 11326 (match_test "which_alternative != 1")) 11327 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11328 (const_string "12") 11329 (ior (and (match_test "!rs6000_speculate_indirect_jumps") 11330 (match_test "which_alternative != 1")) 11331 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11332 (const_string "8")] 11333 (const_string "4")))]) 11334 11335 (define_insn "*call_nonlocal_sysv<mode>" 11336 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 11337 (match_operand 1)) 11338 (use (match_operand:SI 2 "immediate_operand" "O,n")) 11339 (clobber (reg:P LR_REGNO))] 11340 "(DEFAULT_ABI == ABI_DARWIN 11341 || (DEFAULT_ABI == ABI_V4 11342 && (INTVAL (operands[2]) & CALL_LONG) == 0))" 11343 { 11344 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11345 output_asm_insn ("crxor 6,6,6", operands); 11346 11347 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11348 output_asm_insn ("creqv 6,6,6", operands); 11349 11350 return rs6000_call_template (operands, 0); 11351 } 11352 [(set_attr "type" "branch,branch") 11353 (set_attr "length" "4,8")]) 11354 11355 (define_insn "*call_nonlocal_sysv_secure<mode>" 11356 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 11357 (match_operand 1)) 11358 (use (match_operand:SI 2 "immediate_operand" "O,n")) 11359 (use (match_operand:SI 3 "register_operand" "r,r")) 11360 (clobber (reg:P LR_REGNO))] 11361 "(DEFAULT_ABI == ABI_V4 11362 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) 11363 && (INTVAL (operands[2]) & CALL_LONG) == 0)" 11364 { 11365 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11366 output_asm_insn ("crxor 6,6,6", operands); 11367 11368 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11369 output_asm_insn ("creqv 6,6,6", operands); 11370 11371 return rs6000_call_template (operands, 0); 11372 } 11373 [(set_attr "type" "branch,branch") 11374 (set_attr "length" "4,8")]) 11375 11376 (define_insn "*call_value_indirect_nonlocal_sysv<mode>" 11377 [(set (match_operand 0 "" "") 11378 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 11379 (match_operand:P 2 "unspec_tls" ""))) 11380 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 11381 (clobber (reg:P LR_REGNO))] 11382 "DEFAULT_ABI == ABI_V4 11383 || DEFAULT_ABI == ABI_DARWIN" 11384 { 11385 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11386 output_asm_insn ("crxor 6,6,6", operands); 11387 11388 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11389 output_asm_insn ("creqv 6,6,6", operands); 11390 11391 return rs6000_indirect_call_template (operands, 1); 11392 } 11393 [(set_attr "type" "jmpreg") 11394 (set (attr "length") 11395 (plus 11396 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])") 11397 (const_int 4) 11398 (const_int 0)) 11399 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 11400 (match_test "which_alternative != 1")) 11401 (const_int 8) 11402 (const_int 4))))]) 11403 11404 (define_insn "*call_value_nonlocal_sysv<mode>" 11405 [(set (match_operand 0 "" "") 11406 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 11407 (match_operand:P 2 "unspec_tls" ""))) 11408 (use (match_operand:SI 3 "immediate_operand" "n")) 11409 (clobber (reg:P LR_REGNO))] 11410 "(DEFAULT_ABI == ABI_DARWIN 11411 || (DEFAULT_ABI == ABI_V4 11412 && (INTVAL (operands[3]) & CALL_LONG) == 0))" 11413 { 11414 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11415 output_asm_insn ("crxor 6,6,6", operands); 11416 11417 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11418 output_asm_insn ("creqv 6,6,6", operands); 11419 11420 return rs6000_call_template (operands, 1); 11421 } 11422 [(set_attr "type" "branch") 11423 (set (attr "length") 11424 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])") 11425 (const_int 8) 11426 (const_int 4)))]) 11427 11428 (define_insn "*call_value_nonlocal_sysv_secure<mode>" 11429 [(set (match_operand 0 "" "") 11430 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 11431 (match_operand:P 2 "unspec_tls" ""))) 11432 (use (match_operand:SI 3 "immediate_operand" "n")) 11433 (use (match_operand:SI 4 "register_operand" "r")) 11434 (clobber (reg:P LR_REGNO))] 11435 "(DEFAULT_ABI == ABI_V4 11436 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) 11437 && (INTVAL (operands[3]) & CALL_LONG) == 0)" 11438 { 11439 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11440 output_asm_insn ("crxor 6,6,6", operands); 11441 11442 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11443 output_asm_insn ("creqv 6,6,6", operands); 11444 11445 return rs6000_call_template (operands, 1); 11446 } 11447 [(set_attr "type" "branch") 11448 (set (attr "length") 11449 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])") 11450 (const_int 8) 11451 (const_int 4)))]) 11452 11453 ;; Call to AIX abi function which may be in another module. 11454 ;; Restore the TOC pointer (r2) after the call. 11455 11456 (define_insn "*call_nonlocal_aix<mode>" 11457 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s")) 11458 (match_operand 1)) 11459 (use (match_operand:SI 2 "immediate_operand" "n")) 11460 (clobber (reg:P LR_REGNO))] 11461 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 11462 && (INTVAL (operands[2]) & CALL_LONG) == 0" 11463 { 11464 return rs6000_call_template (operands, 0); 11465 } 11466 [(set_attr "type" "branch") 11467 (set (attr "length") 11468 (if_then_else (match_test "rs6000_pcrel_p ()") 11469 (const_int 4) 11470 (const_int 8)))]) 11471 11472 (define_insn "*call_value_nonlocal_aix<mode>" 11473 [(set (match_operand 0 "" "") 11474 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 11475 (match_operand:P 2 "unspec_tls" ""))) 11476 (use (match_operand:SI 3 "immediate_operand" "n")) 11477 (clobber (reg:P LR_REGNO))] 11478 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 11479 && (INTVAL (operands[3]) & CALL_LONG) == 0" 11480 { 11481 return rs6000_call_template (operands, 1); 11482 } 11483 [(set_attr "type" "branch") 11484 (set (attr "length") 11485 (if_then_else (match_test "rs6000_pcrel_p ()") 11486 (const_int 4) 11487 (const_int 8)))]) 11488 11489 ;; Call to indirect functions with the AIX abi using a 3 word descriptor. 11490 ;; Operand0 is the addresss of the function to call 11491 ;; Operand3 is the location in the function descriptor to load r2 from 11492 ;; Operand4 is the offset of the stack location holding the current TOC pointer 11493 11494 (define_insn "*call_indirect_aix<mode>" 11495 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 11496 (match_operand 1)) 11497 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 11498 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>")) 11499 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT)) 11500 (clobber (reg:P LR_REGNO))] 11501 "DEFAULT_ABI == ABI_AIX" 11502 { 11503 return rs6000_indirect_call_template (operands, 0); 11504 } 11505 [(set_attr "type" "jmpreg") 11506 (set (attr "length") 11507 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 11508 (match_test "which_alternative != 1")) 11509 (const_string "16") 11510 (const_string "12")))]) 11511 11512 (define_insn "*call_value_indirect_aix<mode>" 11513 [(set (match_operand 0 "" "") 11514 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 11515 (match_operand:P 2 "unspec_tls" ""))) 11516 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 11517 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>")) 11518 (set (reg:P TOC_REGNUM) 11519 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")] 11520 UNSPEC_TOCSLOT)) 11521 (clobber (reg:P LR_REGNO))] 11522 "DEFAULT_ABI == ABI_AIX" 11523 { 11524 return rs6000_indirect_call_template (operands, 1); 11525 } 11526 [(set_attr "type" "jmpreg") 11527 (set (attr "length") 11528 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 11529 (match_test "which_alternative != 1")) 11530 (const_string "16") 11531 (const_string "12")))]) 11532 11533 ;; Call to indirect functions with the ELFv2 ABI. 11534 ;; Operand0 is the addresss of the function to call 11535 ;; Operand3 is the offset of the stack location holding the current TOC pointer 11536 11537 (define_insn "*call_indirect_elfv2<mode>" 11538 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 11539 (match_operand 1)) 11540 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 11541 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT)) 11542 (clobber (reg:P LR_REGNO))] 11543 "DEFAULT_ABI == ABI_ELFv2" 11544 { 11545 return rs6000_indirect_call_template (operands, 0); 11546 } 11547 [(set_attr "type" "jmpreg") 11548 (set (attr "length") 11549 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 11550 (match_test "which_alternative != 1")) 11551 (const_string "12") 11552 (const_string "8")))]) 11553 11554 (define_insn "*call_indirect_pcrel<mode>" 11555 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 11556 (match_operand 1)) 11557 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 11558 (clobber (reg:P LR_REGNO))] 11559 "rs6000_pcrel_p ()" 11560 { 11561 return rs6000_indirect_call_template (operands, 0); 11562 } 11563 [(set_attr "type" "jmpreg") 11564 (set (attr "length") 11565 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 11566 (match_test "which_alternative != 1")) 11567 (const_string "8") 11568 (const_string "4")))]) 11569 11570 (define_insn "*call_value_indirect_elfv2<mode>" 11571 [(set (match_operand 0 "" "") 11572 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 11573 (match_operand:P 2 "unspec_tls" ""))) 11574 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 11575 (set (reg:P TOC_REGNUM) 11576 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] 11577 UNSPEC_TOCSLOT)) 11578 (clobber (reg:P LR_REGNO))] 11579 "DEFAULT_ABI == ABI_ELFv2" 11580 { 11581 return rs6000_indirect_call_template (operands, 1); 11582 } 11583 [(set_attr "type" "jmpreg") 11584 (set (attr "length") 11585 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 11586 (match_test "which_alternative != 1")) 11587 (const_string "12") 11588 (const_string "8")))]) 11589 11590 (define_insn "*call_value_indirect_pcrel<mode>" 11591 [(set (match_operand 0 "" "") 11592 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 11593 (match_operand:P 2 "unspec_tls" ""))) 11594 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 11595 (clobber (reg:P LR_REGNO))] 11596 "rs6000_pcrel_p ()" 11597 { 11598 return rs6000_indirect_call_template (operands, 1); 11599 } 11600 [(set_attr "type" "jmpreg") 11601 (set (attr "length") 11602 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 11603 (match_test "which_alternative != 1")) 11604 (const_string "8") 11605 (const_string "4")))]) 11606 11607 ;; Call subroutine returning any type. 11608 (define_expand "untyped_call" 11609 [(parallel [(call (match_operand 0 "") 11610 (const_int 0)) 11611 (match_operand 1 "") 11612 (match_operand 2 "")])] 11613 "" 11614 { 11615 int i; 11616 11617 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); 11618 11619 for (int i = 0; i < XVECLEN (operands[2], 0); i++) 11620 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i))); 11621 emit_insn (gen_blockage ()); 11622 11623 for (i = 0; i < XVECLEN (operands[2], 0); i++) 11624 { 11625 rtx set = XVECEXP (operands[2], 0, i); 11626 emit_move_insn (SET_DEST (set), SET_SRC (set)); 11627 } 11628 11629 /* The optimizer does not know that the call sets the function value 11630 registers we stored in the result block. We avoid problems by 11631 claiming that all hard registers are used and clobbered at this 11632 point. */ 11633 emit_insn (gen_blockage ()); 11634 11635 DONE; 11636 }) 11637 11638 ;; sibling call patterns 11639 (define_expand "sibcall" 11640 [(parallel [(call (mem:SI (match_operand 0 "address_operand")) 11641 (match_operand 1 "")) 11642 (use (match_operand 2 "")) 11643 (simple_return)])] 11644 "" 11645 { 11646 #if TARGET_MACHO 11647 if (MACHOPIC_INDIRECT) 11648 operands[0] = machopic_indirect_call_target (operands[0]); 11649 #endif 11650 11651 gcc_assert (MEM_P (operands[0])); 11652 gcc_assert (CONST_INT_P (operands[1])); 11653 11654 operands[0] = XEXP (operands[0], 0); 11655 11656 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 11657 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); 11658 else if (DEFAULT_ABI == ABI_V4) 11659 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]); 11660 else if (DEFAULT_ABI == ABI_DARWIN) 11661 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]); 11662 else 11663 gcc_unreachable (); 11664 11665 DONE; 11666 }) 11667 11668 (define_expand "sibcall_value" 11669 [(parallel [(set (match_operand 0 "register_operand") 11670 (call (mem:SI (match_operand 1 "address_operand")) 11671 (match_operand 2 ""))) 11672 (use (match_operand 3 "")) 11673 (simple_return)])] 11674 "" 11675 { 11676 #if TARGET_MACHO 11677 if (MACHOPIC_INDIRECT) 11678 operands[1] = machopic_indirect_call_target (operands[1]); 11679 #endif 11680 11681 gcc_assert (MEM_P (operands[1])); 11682 gcc_assert (CONST_INT_P (operands[2])); 11683 11684 operands[1] = XEXP (operands[1], 0); 11685 11686 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 11687 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]); 11688 else if (DEFAULT_ABI == ABI_V4) 11689 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]); 11690 else if (DEFAULT_ABI == ABI_DARWIN) 11691 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]); 11692 else 11693 gcc_unreachable (); 11694 11695 DONE; 11696 }) 11697 11698 (define_insn "*sibcall_local<mode>" 11699 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s")) 11700 (match_operand 1)) 11701 (use (match_operand:SI 2 "immediate_operand" "O,n")) 11702 (simple_return)] 11703 "(INTVAL (operands[2]) & CALL_LONG) == 0" 11704 { 11705 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11706 output_asm_insn ("crxor 6,6,6", operands); 11707 11708 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11709 output_asm_insn ("creqv 6,6,6", operands); 11710 11711 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0"; 11712 } 11713 [(set_attr "type" "branch") 11714 (set_attr "length" "4,8")]) 11715 11716 (define_insn "*sibcall_value_local<mode>" 11717 [(set (match_operand 0 "" "") 11718 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s")) 11719 (match_operand 2))) 11720 (use (match_operand:SI 3 "immediate_operand" "O,n")) 11721 (simple_return)] 11722 "(INTVAL (operands[3]) & CALL_LONG) == 0" 11723 { 11724 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11725 output_asm_insn ("crxor 6,6,6", operands); 11726 11727 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11728 output_asm_insn ("creqv 6,6,6", operands); 11729 11730 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1"; 11731 } 11732 [(set_attr "type" "branch") 11733 (set_attr "length" "4,8")]) 11734 11735 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>" 11736 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 11737 (match_operand 1)) 11738 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 11739 (simple_return)] 11740 "DEFAULT_ABI == ABI_V4 11741 || DEFAULT_ABI == ABI_DARWIN" 11742 { 11743 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11744 output_asm_insn ("crxor 6,6,6", operands); 11745 11746 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11747 output_asm_insn ("creqv 6,6,6", operands); 11748 11749 return rs6000_indirect_sibcall_template (operands, 0); 11750 } 11751 [(set_attr "type" "jmpreg") 11752 (set (attr "length") 11753 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") 11754 (match_test "which_alternative != 1")) 11755 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11756 (const_string "12") 11757 (ior (and (match_test "!rs6000_speculate_indirect_jumps") 11758 (match_test "which_alternative != 1")) 11759 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11760 (const_string "8")] 11761 (const_string "4")))]) 11762 11763 (define_insn "*sibcall_nonlocal_sysv<mode>" 11764 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 11765 (match_operand 1)) 11766 (use (match_operand 2 "immediate_operand" "O,n")) 11767 (simple_return)] 11768 "(DEFAULT_ABI == ABI_DARWIN 11769 || DEFAULT_ABI == ABI_V4) 11770 && (INTVAL (operands[2]) & CALL_LONG) == 0" 11771 { 11772 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11773 output_asm_insn ("crxor 6,6,6", operands); 11774 11775 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11776 output_asm_insn ("creqv 6,6,6", operands); 11777 11778 return rs6000_sibcall_template (operands, 0); 11779 } 11780 [(set_attr "type" "branch") 11781 (set_attr "length" "4,8")]) 11782 11783 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>" 11784 [(set (match_operand 0 "" "") 11785 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 11786 (match_operand 2))) 11787 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 11788 (simple_return)] 11789 "DEFAULT_ABI == ABI_V4 11790 || DEFAULT_ABI == ABI_DARWIN" 11791 { 11792 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11793 output_asm_insn ("crxor 6,6,6", operands); 11794 11795 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11796 output_asm_insn ("creqv 6,6,6", operands); 11797 11798 return rs6000_indirect_sibcall_template (operands, 1); 11799 } 11800 [(set_attr "type" "jmpreg") 11801 (set (attr "length") 11802 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") 11803 (match_test "which_alternative != 1")) 11804 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11805 (const_string "12") 11806 (ior (and (match_test "!rs6000_speculate_indirect_jumps") 11807 (match_test "which_alternative != 1")) 11808 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11809 (const_string "8")] 11810 (const_string "4")))]) 11811 11812 (define_insn "*sibcall_value_nonlocal_sysv<mode>" 11813 [(set (match_operand 0 "" "") 11814 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) 11815 (match_operand 2))) 11816 (use (match_operand:SI 3 "immediate_operand" "O,n")) 11817 (simple_return)] 11818 "(DEFAULT_ABI == ABI_DARWIN 11819 || DEFAULT_ABI == ABI_V4) 11820 && (INTVAL (operands[3]) & CALL_LONG) == 0" 11821 { 11822 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11823 output_asm_insn ("crxor 6,6,6", operands); 11824 11825 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11826 output_asm_insn ("creqv 6,6,6", operands); 11827 11828 return rs6000_sibcall_template (operands, 1); 11829 } 11830 [(set_attr "type" "branch") 11831 (set_attr "length" "4,8")]) 11832 11833 ;; AIX ABI sibling call patterns. 11834 11835 (define_insn "*sibcall_aix<mode>" 11836 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) 11837 (match_operand 1)) 11838 (simple_return)] 11839 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11840 { 11841 if (which_alternative == 0) 11842 return rs6000_sibcall_template (operands, 0); 11843 else 11844 return "b%T0"; 11845 } 11846 [(set_attr "type" "branch")]) 11847 11848 (define_insn "*sibcall_value_aix<mode>" 11849 [(set (match_operand 0 "" "") 11850 (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) 11851 (match_operand 2))) 11852 (simple_return)] 11853 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11854 { 11855 if (which_alternative == 0) 11856 return rs6000_sibcall_template (operands, 1); 11857 else 11858 return "b%T1"; 11859 } 11860 [(set_attr "type" "branch")]) 11861 11862 (define_expand "sibcall_epilogue" 11863 [(use (const_int 0))] 11864 "" 11865 { 11866 if (!TARGET_SCHED_PROLOG) 11867 emit_insn (gen_blockage ()); 11868 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL); 11869 DONE; 11870 }) 11871 11872 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 11873 ;; all of memory. This blocks insns from being moved across this point. 11874 11875 (define_insn "blockage" 11876 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] 11877 "" 11878 "" 11879 [(set_attr "length" "0")]) 11880 11881 (define_expand "probe_stack_address" 11882 [(use (match_operand 0 "address_operand"))] 11883 "" 11884 { 11885 operands[0] = gen_rtx_MEM (Pmode, operands[0]); 11886 MEM_VOLATILE_P (operands[0]) = 1; 11887 11888 if (TARGET_64BIT) 11889 emit_insn (gen_probe_stack_di (operands[0])); 11890 else 11891 emit_insn (gen_probe_stack_si (operands[0])); 11892 DONE; 11893 }) 11894 11895 (define_insn "probe_stack_<mode>" 11896 [(set (match_operand:P 0 "memory_operand" "=m") 11897 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))] 11898 "" 11899 { 11900 operands[1] = gen_rtx_REG (Pmode, 0); 11901 return "st<wd>%U0%X0 %1,%0"; 11902 } 11903 [(set_attr "type" "store") 11904 (set (attr "update") 11905 (if_then_else (match_operand 0 "update_address_mem") 11906 (const_string "yes") 11907 (const_string "no"))) 11908 (set (attr "indexed") 11909 (if_then_else (match_operand 0 "indexed_address_mem") 11910 (const_string "yes") 11911 (const_string "no")))]) 11912 11913 (define_insn "probe_stack_range<P:mode>" 11914 [(set (match_operand:P 0 "register_operand" "=&r") 11915 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 11916 (match_operand:P 2 "register_operand" "r") 11917 (match_operand:P 3 "register_operand" "r")] 11918 UNSPECV_PROBE_STACK_RANGE))] 11919 "" 11920 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);" 11921 [(set_attr "type" "three")]) 11922 11924 ;; Compare insns are next. Note that the RS/6000 has two types of compares, 11925 ;; signed & unsigned, and one type of branch. 11926 ;; 11927 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc 11928 ;; insns, and branches. 11929 11930 (define_expand "cbranch<mode>4" 11931 [(use (match_operator 0 "comparison_operator" 11932 [(match_operand:GPR 1 "gpc_reg_operand") 11933 (match_operand:GPR 2 "reg_or_short_operand")])) 11934 (use (match_operand 3))] 11935 "" 11936 { 11937 /* Take care of the possibility that operands[2] might be negative but 11938 this might be a logical operation. That insn doesn't exist. */ 11939 if (CONST_INT_P (operands[2]) 11940 && INTVAL (operands[2]) < 0) 11941 { 11942 operands[2] = force_reg (<MODE>mode, operands[2]); 11943 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]), 11944 GET_MODE (operands[0]), 11945 operands[1], operands[2]); 11946 } 11947 11948 rs6000_emit_cbranch (<MODE>mode, operands); 11949 DONE; 11950 }) 11951 11952 (define_expand "cbranch<mode>4" 11953 [(use (match_operator 0 "comparison_operator" 11954 [(match_operand:FP 1 "gpc_reg_operand") 11955 (match_operand:FP 2 "gpc_reg_operand")])) 11956 (use (match_operand 3))] 11957 "" 11958 { 11959 rs6000_emit_cbranch (<MODE>mode, operands); 11960 DONE; 11961 }) 11962 11963 (define_expand "cstore<mode>4_signed" 11964 [(use (match_operator 1 "signed_comparison_operator" 11965 [(match_operand:P 2 "gpc_reg_operand") 11966 (match_operand:P 3 "gpc_reg_operand")])) 11967 (clobber (match_operand:P 0 "gpc_reg_operand"))] 11968 "" 11969 { 11970 enum rtx_code cond_code = GET_CODE (operands[1]); 11971 11972 rtx op0 = operands[0]; 11973 rtx op1 = operands[2]; 11974 rtx op2 = operands[3]; 11975 11976 if (cond_code == GE || cond_code == LT) 11977 { 11978 cond_code = swap_condition (cond_code); 11979 std::swap (op1, op2); 11980 } 11981 11982 rtx tmp1 = gen_reg_rtx (<MODE>mode); 11983 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11984 rtx tmp3 = gen_reg_rtx (<MODE>mode); 11985 11986 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11987 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh))); 11988 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh))); 11989 11990 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2)); 11991 11992 if (cond_code == LE) 11993 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2)); 11994 else 11995 { 11996 rtx tmp4 = gen_reg_rtx (<MODE>mode); 11997 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2)); 11998 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx)); 11999 } 12000 12001 DONE; 12002 }) 12003 12004 (define_expand "cstore<mode>4_unsigned" 12005 [(use (match_operator 1 "unsigned_comparison_operator" 12006 [(match_operand:P 2 "gpc_reg_operand") 12007 (match_operand:P 3 "reg_or_short_operand")])) 12008 (clobber (match_operand:P 0 "gpc_reg_operand"))] 12009 "" 12010 { 12011 enum rtx_code cond_code = GET_CODE (operands[1]); 12012 12013 rtx op0 = operands[0]; 12014 rtx op1 = operands[2]; 12015 rtx op2 = operands[3]; 12016 12017 if (cond_code == GEU || cond_code == LTU) 12018 { 12019 cond_code = swap_condition (cond_code); 12020 std::swap (op1, op2); 12021 } 12022 12023 if (!gpc_reg_operand (op1, <MODE>mode)) 12024 op1 = force_reg (<MODE>mode, op1); 12025 if (!reg_or_short_operand (op2, <MODE>mode)) 12026 op2 = force_reg (<MODE>mode, op2); 12027 12028 rtx tmp = gen_reg_rtx (<MODE>mode); 12029 rtx tmp2 = gen_reg_rtx (<MODE>mode); 12030 12031 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2)); 12032 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2)); 12033 12034 if (cond_code == LEU) 12035 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx)); 12036 else 12037 emit_insn (gen_neg<mode>2 (op0, tmp2)); 12038 12039 DONE; 12040 }) 12041 12042 (define_expand "cstore_si_as_di" 12043 [(use (match_operator 1 "unsigned_comparison_operator" 12044 [(match_operand:SI 2 "gpc_reg_operand") 12045 (match_operand:SI 3 "reg_or_short_operand")])) 12046 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 12047 "" 12048 { 12049 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0; 12050 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1])); 12051 12052 operands[2] = force_reg (SImode, operands[2]); 12053 operands[3] = force_reg (SImode, operands[3]); 12054 rtx op1 = gen_reg_rtx (DImode); 12055 rtx op2 = gen_reg_rtx (DImode); 12056 convert_move (op1, operands[2], uns_flag); 12057 convert_move (op2, operands[3], uns_flag); 12058 12059 if (cond_code == GT || cond_code == LE) 12060 { 12061 cond_code = swap_condition (cond_code); 12062 std::swap (op1, op2); 12063 } 12064 12065 rtx tmp = gen_reg_rtx (DImode); 12066 rtx tmp2 = gen_reg_rtx (DImode); 12067 emit_insn (gen_subdi3 (tmp, op1, op2)); 12068 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63))); 12069 12070 rtx tmp3; 12071 switch (cond_code) 12072 { 12073 default: 12074 gcc_unreachable (); 12075 case LT: 12076 tmp3 = tmp2; 12077 break; 12078 case GE: 12079 tmp3 = gen_reg_rtx (DImode); 12080 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx)); 12081 break; 12082 } 12083 12084 convert_move (operands[0], tmp3, 1); 12085 12086 DONE; 12087 }) 12088 12089 (define_expand "cstore<mode>4_signed_imm" 12090 [(use (match_operator 1 "signed_comparison_operator" 12091 [(match_operand:GPR 2 "gpc_reg_operand") 12092 (match_operand:GPR 3 "immediate_operand")])) 12093 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 12094 "" 12095 { 12096 bool invert = false; 12097 12098 enum rtx_code cond_code = GET_CODE (operands[1]); 12099 12100 rtx op0 = operands[0]; 12101 rtx op1 = operands[2]; 12102 HOST_WIDE_INT val = INTVAL (operands[3]); 12103 12104 if (cond_code == GE || cond_code == GT) 12105 { 12106 cond_code = reverse_condition (cond_code); 12107 invert = true; 12108 } 12109 12110 if (cond_code == LE) 12111 val++; 12112 12113 rtx tmp = gen_reg_rtx (<MODE>mode); 12114 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 12115 rtx x = gen_reg_rtx (<MODE>mode); 12116 if (val < 0) 12117 emit_insn (gen_and<mode>3 (x, op1, tmp)); 12118 else 12119 emit_insn (gen_ior<mode>3 (x, op1, tmp)); 12120 12121 if (invert) 12122 { 12123 rtx tmp = gen_reg_rtx (<MODE>mode); 12124 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 12125 x = tmp; 12126 } 12127 12128 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 12129 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 12130 12131 DONE; 12132 }) 12133 12134 (define_expand "cstore<mode>4_unsigned_imm" 12135 [(use (match_operator 1 "unsigned_comparison_operator" 12136 [(match_operand:GPR 2 "gpc_reg_operand") 12137 (match_operand:GPR 3 "immediate_operand")])) 12138 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 12139 "" 12140 { 12141 bool invert = false; 12142 12143 enum rtx_code cond_code = GET_CODE (operands[1]); 12144 12145 rtx op0 = operands[0]; 12146 rtx op1 = operands[2]; 12147 HOST_WIDE_INT val = INTVAL (operands[3]); 12148 12149 if (cond_code == GEU || cond_code == GTU) 12150 { 12151 cond_code = reverse_condition (cond_code); 12152 invert = true; 12153 } 12154 12155 if (cond_code == LEU) 12156 val++; 12157 12158 rtx tmp = gen_reg_rtx (<MODE>mode); 12159 rtx tmp2 = gen_reg_rtx (<MODE>mode); 12160 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 12161 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1)); 12162 rtx x = gen_reg_rtx (<MODE>mode); 12163 if (val < 0) 12164 emit_insn (gen_ior<mode>3 (x, tmp, tmp2)); 12165 else 12166 emit_insn (gen_and<mode>3 (x, tmp, tmp2)); 12167 12168 if (invert) 12169 { 12170 rtx tmp = gen_reg_rtx (<MODE>mode); 12171 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 12172 x = tmp; 12173 } 12174 12175 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 12176 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 12177 12178 DONE; 12179 }) 12180 12181 (define_expand "cstore<mode>4" 12182 [(use (match_operator 1 "comparison_operator" 12183 [(match_operand:GPR 2 "gpc_reg_operand") 12184 (match_operand:GPR 3 "reg_or_short_operand")])) 12185 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 12186 "" 12187 { 12188 /* Everything is best done with setbc[r] if available. */ 12189 if (TARGET_POWER10 && TARGET_ISEL) 12190 { 12191 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx); 12192 DONE; 12193 } 12194 12195 /* Expanding EQ and NE directly to some machine instructions does not help 12196 but does hurt combine. So don't. */ 12197 if (GET_CODE (operands[1]) == EQ) 12198 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3])); 12199 else if (<MODE>mode == Pmode 12200 && GET_CODE (operands[1]) == NE) 12201 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3])); 12202 else if (GET_CODE (operands[1]) == NE) 12203 { 12204 rtx tmp = gen_reg_rtx (<MODE>mode); 12205 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3])); 12206 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); 12207 } 12208 12209 /* If ISEL is fast, expand to it. */ 12210 else if (TARGET_ISEL) 12211 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx); 12212 12213 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu 12214 etc. combinations magically work out just right. */ 12215 else if (<MODE>mode == Pmode 12216 && unsigned_comparison_operator (operands[1], VOIDmode)) 12217 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1], 12218 operands[2], operands[3])); 12219 12220 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */ 12221 else if (<MODE>mode == SImode && Pmode == DImode) 12222 emit_insn (gen_cstore_si_as_di (operands[0], operands[1], 12223 operands[2], operands[3])); 12224 12225 /* For signed comparisons against a constant, we can do some simple 12226 bit-twiddling. */ 12227 else if (signed_comparison_operator (operands[1], VOIDmode) 12228 && CONST_INT_P (operands[3])) 12229 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1], 12230 operands[2], operands[3])); 12231 12232 /* And similarly for unsigned comparisons. */ 12233 else if (unsigned_comparison_operator (operands[1], VOIDmode) 12234 && CONST_INT_P (operands[3])) 12235 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1], 12236 operands[2], operands[3])); 12237 12238 /* We also do not want to use mfcr for signed comparisons. */ 12239 else if (<MODE>mode == Pmode 12240 && signed_comparison_operator (operands[1], VOIDmode)) 12241 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1], 12242 operands[2], operands[3])); 12243 12244 /* Everything else, use the mfcr brute force. */ 12245 else 12246 rs6000_emit_sCOND (<MODE>mode, operands); 12247 12248 DONE; 12249 }) 12250 12251 (define_expand "cstore<mode>4" 12252 [(use (match_operator 1 "comparison_operator" 12253 [(match_operand:FP 2 "gpc_reg_operand") 12254 (match_operand:FP 3 "gpc_reg_operand")])) 12255 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 12256 "" 12257 { 12258 rs6000_emit_sCOND (<MODE>mode, operands); 12259 DONE; 12260 }) 12261 12262 12263 (define_expand "stack_protect_set" 12264 [(match_operand 0 "memory_operand") 12265 (match_operand 1 "memory_operand")] 12266 "" 12267 { 12268 if (rs6000_stack_protector_guard == SSP_TLS) 12269 { 12270 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg); 12271 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset); 12272 rtx addr = gen_rtx_PLUS (Pmode, reg, offset); 12273 operands[1] = gen_rtx_MEM (Pmode, addr); 12274 } 12275 12276 if (TARGET_64BIT) 12277 emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); 12278 else 12279 emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); 12280 12281 DONE; 12282 }) 12283 12284 ;; We can't use the prefixed attribute here because there are two memory 12285 ;; instructions. We can't split the insn due to the fact that this operation 12286 ;; needs to be done in one piece. 12287 (define_insn "stack_protect_set<mode>" 12288 [(set (match_operand:P 0 "memory_operand" "=YZ") 12289 (unspec:P [(match_operand:P 1 "memory_operand" "YZ")] UNSPEC_SP_SET)) 12290 (set (match_scratch:P 2 "=&r") (const_int 0))] 12291 "" 12292 { 12293 if (prefixed_memory (operands[1], <MODE>mode)) 12294 /* Prefixed load only supports D-form but no update and X-form. */ 12295 output_asm_insn ("p<ptrload> %2,%1", operands); 12296 else 12297 output_asm_insn ("<ptrload>%U1%X1 %2,%1", operands); 12298 12299 if (prefixed_memory (operands[0], <MODE>mode)) 12300 /* Prefixed store only supports D-form but no update and X-form. */ 12301 output_asm_insn ("pst<wd> %2,%0", operands); 12302 else 12303 output_asm_insn ("st<wd>%U0%X0 %2,%0", operands); 12304 12305 return "li %2,0"; 12306 } 12307 [(set_attr "type" "three") 12308 12309 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each 12310 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for 12311 ;; the LI 0 at the end. 12312 (set_attr "prefixed" "no") 12313 (set_attr "num_insns" "3") 12314 (set (attr "length") 12315 (cond [(and (match_operand 0 "prefixed_memory") 12316 (match_operand 1 "prefixed_memory")) 12317 (const_int 24) 12318 12319 (ior (match_operand 0 "prefixed_memory") 12320 (match_operand 1 "prefixed_memory")) 12321 (const_int 20)] 12322 12323 (const_int 12)))]) 12324 12325 (define_expand "stack_protect_test" 12326 [(match_operand 0 "memory_operand") 12327 (match_operand 1 "memory_operand") 12328 (match_operand 2 "")] 12329 "" 12330 { 12331 rtx guard = operands[1]; 12332 12333 if (rs6000_stack_protector_guard == SSP_TLS) 12334 { 12335 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg); 12336 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset); 12337 rtx addr = gen_rtx_PLUS (Pmode, reg, offset); 12338 guard = gen_rtx_MEM (Pmode, addr); 12339 } 12340 12341 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST); 12342 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]); 12343 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]); 12344 emit_jump_insn (jump); 12345 12346 DONE; 12347 }) 12348 12349 ;; We can't use the prefixed attribute here because there are two memory 12350 ;; instructions. We can't split the insn due to the fact that this operation 12351 ;; needs to be done in one piece. 12352 (define_insn "stack_protect_test<mode>" 12353 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 12354 (unspec:CCEQ [(match_operand:P 1 "memory_operand" "YZ,YZ") 12355 (match_operand:P 2 "memory_operand" "YZ,YZ")] 12356 UNSPEC_SP_TEST)) 12357 (set (match_scratch:P 4 "=r,r") (const_int 0)) 12358 (clobber (match_scratch:P 3 "=&r,&r"))] 12359 "" 12360 { 12361 if (prefixed_memory (operands[1], <MODE>mode)) 12362 /* Prefixed load only supports D-form but no update and X-form. */ 12363 output_asm_insn ("p<ptrload> %3,%1", operands); 12364 else 12365 output_asm_insn ("<ptrload>%U1%X1 %3,%1", operands); 12366 12367 if (prefixed_memory (operands[2], <MODE>mode)) 12368 output_asm_insn ("p<ptrload> %4,%2", operands); 12369 else 12370 output_asm_insn ("<ptrload>%U2%X2 %4,%2", operands); 12371 12372 if (which_alternative == 0) 12373 output_asm_insn ("xor. %3,%3,%4", operands); 12374 else 12375 output_asm_insn ("cmpl<wd> %0,%3,%4\;li %3,0", operands); 12376 12377 return "li %4,0"; 12378 } 12379 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each 12380 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or 12381 ;; 8 bytes to do the test. 12382 [(set_attr "prefixed" "no") 12383 (set_attr "num_insns" "4,5") 12384 (set (attr "length") 12385 (cond [(and (match_operand 1 "prefixed_memory") 12386 (match_operand 2 "prefixed_memory")) 12387 (if_then_else (eq_attr "alternative" "0") 12388 (const_int 28) 12389 (const_int 32)) 12390 12391 (ior (match_operand 1 "prefixed_memory") 12392 (match_operand 2 "prefixed_memory")) 12393 (if_then_else (eq_attr "alternative" "0") 12394 (const_int 20) 12395 (const_int 24))] 12396 12397 (if_then_else (eq_attr "alternative" "0") 12398 (const_int 16) 12399 (const_int 20))))]) 12400 12401 12403 ;; Here are the actual compare insns. 12404 (define_insn "*cmp<mode>_signed" 12405 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 12406 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r") 12407 (match_operand:GPR 2 "reg_or_short_operand" "rI")))] 12408 "" 12409 "cmp<wd>%I2 %0,%1,%2" 12410 [(set_attr "type" "cmp")]) 12411 12412 (define_insn "*cmp<mode>_unsigned" 12413 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") 12414 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r") 12415 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))] 12416 "" 12417 "cmpl<wd>%I2 %0,%1,%2" 12418 [(set_attr "type" "cmp")]) 12419 12420 ;; If we are comparing a register for equality with a large constant, 12421 ;; we can do this with an XOR followed by a compare. But this is profitable 12422 ;; only if the large constant is only used for the comparison (and in this 12423 ;; case we already have a register to reuse as scratch). 12424 ;; 12425 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear: 12426 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available. 12427 12428 (define_peephole2 12429 [(set (match_operand:SI 0 "register_operand") 12430 (match_operand:SI 1 "logical_const_operand")) 12431 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator" 12432 [(match_dup 0) 12433 (match_operand:SI 2 "logical_const_operand")])) 12434 (set (match_operand:CC 4 "cc_reg_operand") 12435 (compare:CC (match_operand:SI 5 "gpc_reg_operand") 12436 (match_dup 0))) 12437 (set (pc) 12438 (if_then_else (match_operator 6 "equality_operator" 12439 [(match_dup 4) (const_int 0)]) 12440 (match_operand 7 "") 12441 (match_operand 8 "")))] 12442 "peep2_reg_dead_p (3, operands[0]) 12443 && peep2_reg_dead_p (4, operands[4]) 12444 && REGNO (operands[0]) != REGNO (operands[5])" 12445 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9))) 12446 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10))) 12447 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))] 12448 12449 { 12450 /* Get the constant we are comparing against, and see what it looks like 12451 when sign-extended from 16 to 32 bits. Then see what constant we could 12452 XOR with SEXTC to get the sign-extended value. */ 12453 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]), 12454 SImode, 12455 operands[1], operands[2]); 12456 HOST_WIDE_INT c = INTVAL (cnst); 12457 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000; 12458 HOST_WIDE_INT xorv = c ^ sextc; 12459 12460 operands[9] = GEN_INT (xorv); 12461 operands[10] = GEN_INT (sextc); 12462 }) 12463 12464 ;; Only need to compare second words if first words equal 12465 (define_insn "*cmp<mode>_internal1" 12466 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 12467 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 12468 (match_operand:IBM128 2 "gpc_reg_operand" "d")))] 12469 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) 12470 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 12471 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" 12472 [(set_attr "type" "fpcompare") 12473 (set_attr "length" "12")]) 12474 12475 (define_insn_and_split "*cmp<IBM128:mode>_internal2" 12476 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 12477 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 12478 (match_operand:IBM128 2 "gpc_reg_operand" "d"))) 12479 (clobber (match_scratch:DF 3 "=d")) 12480 (clobber (match_scratch:DF 4 "=d")) 12481 (clobber (match_scratch:DF 5 "=d")) 12482 (clobber (match_scratch:DF 6 "=d")) 12483 (clobber (match_scratch:DF 7 "=d")) 12484 (clobber (match_scratch:DF 8 "=d")) 12485 (clobber (match_scratch:DF 9 "=d")) 12486 (clobber (match_scratch:DF 10 "=d")) 12487 (clobber (match_scratch:GPR 11 "=b"))] 12488 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode) 12489 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 12490 "#" 12491 "&& reload_completed" 12492 [(set (match_dup 3) (match_dup 14)) 12493 (set (match_dup 4) (match_dup 15)) 12494 (set (match_dup 9) (abs:DF (match_dup 5))) 12495 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) 12496 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) 12497 (label_ref (match_dup 12)) 12498 (pc))) 12499 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) 12500 (set (pc) (label_ref (match_dup 13))) 12501 (match_dup 12) 12502 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) 12503 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) 12504 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) 12505 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4))) 12506 (match_dup 13)] 12507 { 12508 REAL_VALUE_TYPE rv; 12509 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 12510 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 12511 12512 operands[5] = simplify_gen_subreg (DFmode, operands[1], 12513 <IBM128:MODE>mode, hi_word); 12514 operands[6] = simplify_gen_subreg (DFmode, operands[1], 12515 <IBM128:MODE>mode, lo_word); 12516 operands[7] = simplify_gen_subreg (DFmode, operands[2], 12517 <IBM128:MODE>mode, hi_word); 12518 operands[8] = simplify_gen_subreg (DFmode, operands[2], 12519 <IBM128:MODE>mode, lo_word); 12520 operands[12] = gen_label_rtx (); 12521 operands[13] = gen_label_rtx (); 12522 real_inf (&rv); 12523 operands[14] = force_const_mem (DFmode, 12524 const_double_from_real_value (rv, DFmode)); 12525 operands[15] = force_const_mem (DFmode, 12526 const_double_from_real_value (dconst0, 12527 DFmode)); 12528 if (TARGET_TOC) 12529 { 12530 rtx tocref; 12531 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]); 12532 operands[14] = gen_const_mem (DFmode, tocref); 12533 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]); 12534 operands[15] = gen_const_mem (DFmode, tocref); 12535 set_mem_alias_set (operands[14], get_TOC_alias_set ()); 12536 set_mem_alias_set (operands[15], get_TOC_alias_set ()); 12537 } 12538 }) 12539 12541 ;; Now we have the scc insns. We can do some combinations because of the 12542 ;; way the machine works. 12543 ;; 12544 ;; Note that this is probably faster if we can put an insn between the 12545 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most 12546 ;; cases the insns below which don't use an intermediate CR field will 12547 ;; be used instead. 12548 (define_insn "set<mode>_cc" 12549 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12550 (match_operator:GPR 1 "scc_comparison_operator" 12551 [(match_operand 2 "cc_reg_operand" "y") 12552 (const_int 0)]))] 12553 "" 12554 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" 12555 [(set (attr "type") 12556 (cond [(match_test "TARGET_MFCRF") 12557 (const_string "mfcrf") 12558 ] 12559 (const_string "mfcr"))) 12560 (set_attr "length" "8")]) 12561 12562 12563 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu]) 12564 (define_code_attr UNS [(eq "CC") 12565 (ne "CC") 12566 (lt "CC") (ltu "CCUNS") 12567 (gt "CC") (gtu "CCUNS") 12568 (le "CC") (leu "CCUNS") 12569 (ge "CC") (geu "CCUNS")]) 12570 (define_code_attr UNSu_ [(eq "") 12571 (ne "") 12572 (lt "") (ltu "u_") 12573 (gt "") (gtu "u_") 12574 (le "") (leu "u_") 12575 (ge "") (geu "u_")]) 12576 (define_code_attr UNSIK [(eq "I") 12577 (ne "I") 12578 (lt "I") (ltu "K") 12579 (gt "I") (gtu "K") 12580 (le "I") (leu "K") 12581 (ge "I") (geu "K")]) 12582 12583 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel" 12584 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12585 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r") 12586 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>"))) 12587 (clobber (match_scratch:GPR 3 "=r")) 12588 (clobber (match_scratch:GPR 4 "=r")) 12589 (clobber (match_scratch:<UNS> 5 "=y"))] 12590 "!TARGET_POWER10 && TARGET_ISEL 12591 && !(<CODE> == EQ && operands[2] == const0_rtx) 12592 && !(<CODE> == NE && operands[2] == const0_rtx 12593 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)" 12594 "#" 12595 "&& 1" 12596 [(pc)] 12597 { 12598 rtx_code code = <CODE>; 12599 if (CONST_INT_P (operands[2]) && code != EQ && code != NE) 12600 { 12601 HOST_WIDE_INT val = INTVAL (operands[2]); 12602 if (code == LT && val != -0x8000) 12603 { 12604 code = LE; 12605 val--; 12606 } 12607 if (code == GT && val != 0x7fff) 12608 { 12609 code = GE; 12610 val++; 12611 } 12612 if (code == LTU && val != 0) 12613 { 12614 code = LEU; 12615 val--; 12616 } 12617 if (code == GTU && val != 0xffff) 12618 { 12619 code = GEU; 12620 val++; 12621 } 12622 operands[2] = GEN_INT (val); 12623 } 12624 12625 if (code == NE || code == LE || code == GE || code == LEU || code == GEU) 12626 operands[3] = const0_rtx; 12627 else 12628 { 12629 if (GET_CODE (operands[3]) == SCRATCH) 12630 operands[3] = gen_reg_rtx (<GPR:MODE>mode); 12631 emit_move_insn (operands[3], const0_rtx); 12632 } 12633 12634 if (GET_CODE (operands[4]) == SCRATCH) 12635 operands[4] = gen_reg_rtx (<GPR:MODE>mode); 12636 emit_move_insn (operands[4], const1_rtx); 12637 12638 if (GET_CODE (operands[5]) == SCRATCH) 12639 operands[5] = gen_reg_rtx (<UNS>mode); 12640 12641 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]); 12642 emit_insn (gen_rtx_SET (operands[5], c1)); 12643 12644 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx); 12645 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]); 12646 emit_move_insn (operands[0], x); 12647 12648 DONE; 12649 } 12650 [(set (attr "cost") 12651 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ) 12652 || <CODE> == NE 12653 || <CODE> == LE || <CODE> == GE 12654 || <CODE> == LEU || <CODE> == GEU") 12655 (const_string "9") 12656 (const_string "10")))]) 12657 12658 (define_mode_attr scc_eq_op2 [(SI "rKLI") 12659 (DI "rKJI")]) 12660 12661 (define_expand "eq<mode>3" 12662 [(parallel [ 12663 (set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12664 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 12665 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 12666 (clobber (match_scratch:GPR 3 "=r")) 12667 (clobber (match_scratch:GPR 4 "=r"))])] 12668 "" 12669 { 12670 if (TARGET_POWER10) 12671 { 12672 rtx cc = gen_reg_rtx (CCmode); 12673 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]); 12674 emit_insn (gen_rtx_SET (cc, compare)); 12675 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx); 12676 emit_insn (gen_setbc_signed_<mode> (operands[0], eq, cc)); 12677 DONE; 12678 } 12679 12680 if (TARGET_ISEL && operands[2] != const0_rtx) 12681 { 12682 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1], 12683 operands[2])); 12684 DONE; 12685 } 12686 }) 12687 12688 (define_insn_and_split "*eq<mode>3" 12689 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12690 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 12691 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 12692 (clobber (match_scratch:GPR 3 "=r")) 12693 (clobber (match_scratch:GPR 4 "=r"))] 12694 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)" 12695 "#" 12696 "&& 1" 12697 [(set (match_dup 4) 12698 (clz:GPR (match_dup 3))) 12699 (set (match_dup 0) 12700 (lshiftrt:GPR (match_dup 4) 12701 (match_dup 5)))] 12702 { 12703 operands[3] = rs6000_emit_eqne (<MODE>mode, 12704 operands[1], operands[2], operands[3]); 12705 12706 if (GET_CODE (operands[4]) == SCRATCH) 12707 operands[4] = gen_reg_rtx (<MODE>mode); 12708 12709 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode))); 12710 } 12711 [(set (attr "length") 12712 (if_then_else (match_test "operands[2] == const0_rtx") 12713 (const_string "8") 12714 (const_string "12")))]) 12715 12716 (define_expand "ne<mode>3" 12717 [(parallel [ 12718 (set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12719 (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 12720 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 12721 (clobber (match_scratch:GPR 3 "=r")) 12722 (clobber (match_scratch:GPR 4 "=r")) 12723 (clobber (reg:GPR CA_REGNO))])] 12724 "" 12725 { 12726 if (TARGET_POWER10) 12727 { 12728 rtx cc = gen_reg_rtx (CCmode); 12729 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]); 12730 emit_insn (gen_rtx_SET (cc, compare)); 12731 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx); 12732 emit_insn (gen_setbc_signed_<mode> (operands[0], ne, cc)); 12733 DONE; 12734 } 12735 12736 if (<MODE>mode != Pmode) 12737 { 12738 rtx x = gen_reg_rtx (<MODE>mode); 12739 emit_insn (gen_eq<mode>3 (x, operands[1], operands[2])); 12740 emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx)); 12741 DONE; 12742 } 12743 12744 if (TARGET_ISEL && operands[2] != const0_rtx) 12745 { 12746 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1], 12747 operands[2])); 12748 DONE; 12749 } 12750 }) 12751 12752 (define_insn_and_split "*ne<mode>3" 12753 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12754 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12755 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) 12756 (clobber (match_scratch:P 3 "=r")) 12757 (clobber (match_scratch:P 4 "=r")) 12758 (clobber (reg:P CA_REGNO))] 12759 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)" 12760 "#" 12761 "&& 1" 12762 [(parallel [(set (match_dup 4) 12763 (plus:P (match_dup 3) 12764 (const_int -1))) 12765 (set (reg:P CA_REGNO) 12766 (ne:P (match_dup 3) 12767 (const_int 0)))]) 12768 (parallel [(set (match_dup 0) 12769 (plus:P (plus:P (not:P (match_dup 4)) 12770 (reg:P CA_REGNO)) 12771 (match_dup 3))) 12772 (clobber (reg:P CA_REGNO))])] 12773 { 12774 operands[3] = rs6000_emit_eqne (<MODE>mode, 12775 operands[1], operands[2], operands[3]); 12776 12777 if (GET_CODE (operands[4]) == SCRATCH) 12778 operands[4] = gen_reg_rtx (<MODE>mode); 12779 } 12780 [(set (attr "length") 12781 (if_then_else (match_test "operands[2] == const0_rtx") 12782 (const_string "8") 12783 (const_string "12")))]) 12784 12785 (define_insn_and_split "*neg_eq_<mode>" 12786 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12787 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12788 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12789 (clobber (match_scratch:P 3 "=r")) 12790 (clobber (match_scratch:P 4 "=r")) 12791 (clobber (reg:P CA_REGNO))] 12792 "!TARGET_POWER10" 12793 "#" 12794 "&& 1" 12795 [(parallel [(set (match_dup 4) 12796 (plus:P (match_dup 3) 12797 (const_int -1))) 12798 (set (reg:P CA_REGNO) 12799 (ne:P (match_dup 3) 12800 (const_int 0)))]) 12801 (parallel [(set (match_dup 0) 12802 (plus:P (reg:P CA_REGNO) 12803 (const_int -1))) 12804 (clobber (reg:P CA_REGNO))])] 12805 { 12806 operands[3] = rs6000_emit_eqne (<MODE>mode, 12807 operands[1], operands[2], operands[3]); 12808 12809 if (GET_CODE (operands[4]) == SCRATCH) 12810 operands[4] = gen_reg_rtx (<MODE>mode); 12811 } 12812 [(set (attr "length") 12813 (if_then_else (match_test "operands[2] == const0_rtx") 12814 (const_string "8") 12815 (const_string "12")))]) 12816 12817 (define_insn_and_split "*neg_ne_<mode>" 12818 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12819 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12820 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12821 (clobber (match_scratch:P 3 "=r")) 12822 (clobber (match_scratch:P 4 "=r")) 12823 (clobber (reg:P CA_REGNO))] 12824 "!TARGET_POWER10" 12825 "#" 12826 "&& 1" 12827 [(parallel [(set (match_dup 4) 12828 (neg:P (match_dup 3))) 12829 (set (reg:P CA_REGNO) 12830 (eq:P (match_dup 3) 12831 (const_int 0)))]) 12832 (parallel [(set (match_dup 0) 12833 (plus:P (reg:P CA_REGNO) 12834 (const_int -1))) 12835 (clobber (reg:P CA_REGNO))])] 12836 { 12837 operands[3] = rs6000_emit_eqne (<MODE>mode, 12838 operands[1], operands[2], operands[3]); 12839 12840 if (GET_CODE (operands[4]) == SCRATCH) 12841 operands[4] = gen_reg_rtx (<MODE>mode); 12842 } 12843 [(set (attr "length") 12844 (if_then_else (match_test "operands[2] == const0_rtx") 12845 (const_string "8") 12846 (const_string "12")))]) 12847 12848 (define_insn_and_split "*plus_eq_<mode>" 12849 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12850 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12851 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 12852 (match_operand:P 3 "gpc_reg_operand" "r"))) 12853 (clobber (match_scratch:P 4 "=r")) 12854 (clobber (match_scratch:P 5 "=r")) 12855 (clobber (reg:P CA_REGNO))] 12856 "" 12857 "#" 12858 "" 12859 [(parallel [(set (match_dup 5) 12860 (neg:P (match_dup 4))) 12861 (set (reg:P CA_REGNO) 12862 (eq:P (match_dup 4) 12863 (const_int 0)))]) 12864 (parallel [(set (match_dup 0) 12865 (plus:P (match_dup 3) 12866 (reg:P CA_REGNO))) 12867 (clobber (reg:P CA_REGNO))])] 12868 { 12869 operands[4] = rs6000_emit_eqne (<MODE>mode, 12870 operands[1], operands[2], operands[4]); 12871 12872 if (GET_CODE (operands[5]) == SCRATCH) 12873 operands[5] = gen_reg_rtx (<MODE>mode); 12874 } 12875 [(set (attr "length") 12876 (if_then_else (match_test "operands[2] == const0_rtx") 12877 (const_string "8") 12878 (const_string "12")))]) 12879 12880 (define_insn_and_split "*plus_ne_<mode>" 12881 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12882 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12883 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 12884 (match_operand:P 3 "gpc_reg_operand" "r"))) 12885 (clobber (match_scratch:P 4 "=r")) 12886 (clobber (match_scratch:P 5 "=r")) 12887 (clobber (reg:P CA_REGNO))] 12888 "" 12889 "#" 12890 "" 12891 [(parallel [(set (match_dup 5) 12892 (plus:P (match_dup 4) 12893 (const_int -1))) 12894 (set (reg:P CA_REGNO) 12895 (ne:P (match_dup 4) 12896 (const_int 0)))]) 12897 (parallel [(set (match_dup 0) 12898 (plus:P (match_dup 3) 12899 (reg:P CA_REGNO))) 12900 (clobber (reg:P CA_REGNO))])] 12901 { 12902 operands[4] = rs6000_emit_eqne (<MODE>mode, 12903 operands[1], operands[2], operands[4]); 12904 12905 if (GET_CODE (operands[5]) == SCRATCH) 12906 operands[5] = gen_reg_rtx (<MODE>mode); 12907 } 12908 [(set (attr "length") 12909 (if_then_else (match_test "operands[2] == const0_rtx") 12910 (const_string "8") 12911 (const_string "12")))]) 12912 12913 (define_insn_and_split "*minus_eq_<mode>" 12914 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12915 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 12916 (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12917 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12918 (clobber (match_scratch:P 4 "=r")) 12919 (clobber (match_scratch:P 5 "=r")) 12920 (clobber (reg:P CA_REGNO))] 12921 "" 12922 "#" 12923 "" 12924 [(parallel [(set (match_dup 5) 12925 (plus:P (match_dup 4) 12926 (const_int -1))) 12927 (set (reg:P CA_REGNO) 12928 (ne:P (match_dup 4) 12929 (const_int 0)))]) 12930 (parallel [(set (match_dup 0) 12931 (plus:P (plus:P (match_dup 3) 12932 (reg:P CA_REGNO)) 12933 (const_int -1))) 12934 (clobber (reg:P CA_REGNO))])] 12935 { 12936 operands[4] = rs6000_emit_eqne (<MODE>mode, 12937 operands[1], operands[2], operands[4]); 12938 12939 if (GET_CODE (operands[5]) == SCRATCH) 12940 operands[5] = gen_reg_rtx (<MODE>mode); 12941 } 12942 [(set (attr "length") 12943 (if_then_else (match_test "operands[2] == const0_rtx") 12944 (const_string "8") 12945 (const_string "12")))]) 12946 12947 (define_insn_and_split "*minus_ne_<mode>" 12948 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12949 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 12950 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12951 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12952 (clobber (match_scratch:P 4 "=r")) 12953 (clobber (match_scratch:P 5 "=r")) 12954 (clobber (reg:P CA_REGNO))] 12955 "" 12956 "#" 12957 "" 12958 [(parallel [(set (match_dup 5) 12959 (neg:P (match_dup 4))) 12960 (set (reg:P CA_REGNO) 12961 (eq:P (match_dup 4) 12962 (const_int 0)))]) 12963 (parallel [(set (match_dup 0) 12964 (plus:P (plus:P (match_dup 3) 12965 (reg:P CA_REGNO)) 12966 (const_int -1))) 12967 (clobber (reg:P CA_REGNO))])] 12968 { 12969 operands[4] = rs6000_emit_eqne (<MODE>mode, 12970 operands[1], operands[2], operands[4]); 12971 12972 if (GET_CODE (operands[5]) == SCRATCH) 12973 operands[5] = gen_reg_rtx (<MODE>mode); 12974 } 12975 [(set (attr "length") 12976 (if_then_else (match_test "operands[2] == const0_rtx") 12977 (const_string "8") 12978 (const_string "12")))]) 12979 12980 (define_insn_and_split "*eqsi3_ext<mode>" 12981 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 12982 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 12983 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 12984 (clobber (match_scratch:SI 3 "=r")) 12985 (clobber (match_scratch:SI 4 "=r"))] 12986 "!TARGET_POWER10" 12987 "#" 12988 "&& 1" 12989 [(set (match_dup 4) 12990 (clz:SI (match_dup 3))) 12991 (set (match_dup 0) 12992 (zero_extend:EXTSI 12993 (lshiftrt:SI (match_dup 4) 12994 (const_int 5))))] 12995 { 12996 operands[3] = rs6000_emit_eqne (SImode, 12997 operands[1], operands[2], operands[3]); 12998 12999 if (GET_CODE (operands[4]) == SCRATCH) 13000 operands[4] = gen_reg_rtx (SImode); 13001 } 13002 [(set (attr "length") 13003 (if_then_else (match_test "operands[2] == const0_rtx") 13004 (const_string "8") 13005 (const_string "12")))]) 13006 13007 (define_insn_and_split "*nesi3_ext<mode>" 13008 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 13009 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 13010 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 13011 (clobber (match_scratch:SI 3 "=r")) 13012 (clobber (match_scratch:SI 4 "=r")) 13013 (clobber (match_scratch:EXTSI 5 "=r"))] 13014 "!TARGET_ISEL" 13015 "#" 13016 "&& 1" 13017 [(set (match_dup 4) 13018 (clz:SI (match_dup 3))) 13019 (set (match_dup 5) 13020 (zero_extend:EXTSI 13021 (lshiftrt:SI (match_dup 4) 13022 (const_int 5)))) 13023 (set (match_dup 0) 13024 (xor:EXTSI (match_dup 5) 13025 (const_int 1)))] 13026 { 13027 operands[3] = rs6000_emit_eqne (SImode, 13028 operands[1], operands[2], operands[3]); 13029 13030 if (GET_CODE (operands[4]) == SCRATCH) 13031 operands[4] = gen_reg_rtx (SImode); 13032 if (GET_CODE (operands[5]) == SCRATCH) 13033 operands[5] = gen_reg_rtx (<MODE>mode); 13034 } 13035 [(set (attr "length") 13036 (if_then_else (match_test "operands[2] == const0_rtx") 13037 (const_string "12") 13038 (const_string "16")))]) 13039 13040 13041 (define_code_iterator fp_rev [ordered ne unle unge]) 13042 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq]) 13043 13044 (define_insn_and_split "*<code><mode>_cc" 13045 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 13046 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y") 13047 (const_int 0)))] 13048 "!flag_finite_math_only" 13049 "#" 13050 "&& 1" 13051 [(pc)] 13052 { 13053 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>); 13054 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx); 13055 rtx tmp = gen_reg_rtx (<MODE>mode); 13056 emit_move_insn (tmp, eq); 13057 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); 13058 DONE; 13059 } 13060 [(set_attr "length" "12")]) 13061 13062 (define_insn_and_split "*<code><mode>_cc" 13063 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 13064 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y") 13065 (const_int 0)))] 13066 "!flag_finite_math_only" 13067 "#" 13068 "&& 1" 13069 [(pc)] 13070 { 13071 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]); 13072 13073 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx)); 13074 DONE; 13075 } 13076 [(set_attr "length" "12")]) 13077 13079 ;; Conditional branches. 13080 ;; These either are a single bc insn, or a bc around a b. 13081 13082 (define_insn "*cbranch" 13083 [(set (pc) 13084 (if_then_else (match_operator 1 "branch_comparison_operator" 13085 [(match_operand 2 "cc_reg_operand" "y") 13086 (const_int 0)]) 13087 (label_ref (match_operand 0)) 13088 (pc)))] 13089 "" 13090 { 13091 return output_cbranch (operands[1], "%l0", 0, insn); 13092 } 13093 [(set_attr "type" "branch") 13094 (set (attr "length") 13095 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13096 (const_int -32768)) 13097 (lt (minus (match_dup 0) (pc)) 13098 (const_int 32764))) 13099 (const_int 4) 13100 (const_int 8)))]) 13101 13102 (define_insn_and_split "*cbranch_2insn" 13103 [(set (pc) 13104 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator" 13105 [(match_operand 2 "cc_reg_operand" "y") 13106 (const_int 0)]) 13107 (label_ref (match_operand 0)) 13108 (pc)))] 13109 "!flag_finite_math_only" 13110 "#" 13111 "&& 1" 13112 [(pc)] 13113 { 13114 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]); 13115 13116 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0); 13117 13118 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]); 13119 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx); 13120 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx); 13121 emit_jump_insn (gen_rtx_SET (pc_rtx, ite)); 13122 13123 if (note) 13124 { 13125 profile_probability prob 13126 = profile_probability::from_reg_br_prob_note (XINT (note, 0)); 13127 13128 add_reg_br_prob_note (get_last_insn (), prob); 13129 } 13130 13131 DONE; 13132 } 13133 [(set_attr "type" "branch") 13134 (set (attr "length") 13135 (if_then_else (and (ge (minus (match_dup 0) (pc)) 13136 (const_int -32764)) 13137 (lt (minus (match_dup 0) (pc)) 13138 (const_int 32760))) 13139 (const_int 8) 13140 (const_int 16)))]) 13141 13142 ;; Conditional return. 13143 (define_insn "*creturn" 13144 [(set (pc) 13145 (if_then_else (match_operator 0 "branch_comparison_operator" 13146 [(match_operand 1 "cc_reg_operand" "y") 13147 (const_int 0)]) 13148 (any_return) 13149 (pc)))] 13150 "<return_pred>" 13151 { 13152 return output_cbranch (operands[0], NULL, 0, insn); 13153 } 13154 [(set_attr "type" "jmpreg")]) 13155 13156 ;; Logic on condition register values. 13157 13158 ; This pattern matches things like 13159 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0)) 13160 ; (eq:SI (reg:CCFP 68) (const_int 0))) 13161 ; (const_int 1))) 13162 ; which are generated by the branch logic. 13163 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB) 13164 13165 (define_insn "@cceq_ior_compare_<mode>" 13166 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 13167 (compare:CCEQ (match_operator:GPR 1 "boolean_operator" 13168 [(match_operator:GPR 2 13169 "branch_positive_comparison_operator" 13170 [(match_operand 3 13171 "cc_reg_operand" "y,y") 13172 (const_int 0)]) 13173 (match_operator:GPR 4 13174 "branch_positive_comparison_operator" 13175 [(match_operand 5 13176 "cc_reg_operand" "0,y") 13177 (const_int 0)])]) 13178 (const_int 1)))] 13179 "" 13180 "cr%q1 %E0,%j2,%j4" 13181 [(set_attr "type" "cr_logical") 13182 (set_attr "cr_logical_3op" "no,yes")]) 13183 13184 ; Why is the constant -1 here, but 1 in the previous pattern? 13185 ; Because ~1 has all but the low bit set. 13186 (define_insn "cceq_ior_compare_complement" 13187 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 13188 (compare:CCEQ (match_operator:SI 1 "boolean_operator" 13189 [(not:SI (match_operator:SI 2 13190 "branch_positive_comparison_operator" 13191 [(match_operand 3 13192 "cc_reg_operand" "y,y") 13193 (const_int 0)])) 13194 (match_operator:SI 4 13195 "branch_positive_comparison_operator" 13196 [(match_operand 5 13197 "cc_reg_operand" "0,y") 13198 (const_int 0)])]) 13199 (const_int -1)))] 13200 "" 13201 "cr%q1 %E0,%j2,%j4" 13202 [(set_attr "type" "cr_logical") 13203 (set_attr "cr_logical_3op" "no,yes")]) 13204 13205 (define_insn "@cceq_rev_compare_<mode>" 13206 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 13207 (compare:CCEQ (match_operator:GPR 1 13208 "branch_positive_comparison_operator" 13209 [(match_operand 2 13210 "cc_reg_operand" "0,y") 13211 (const_int 0)]) 13212 (const_int 0)))] 13213 "" 13214 "crnot %E0,%j1" 13215 [(set_attr "type" "cr_logical") 13216 (set_attr "cr_logical_3op" "no,yes")]) 13217 13218 ;; If we are comparing the result of two comparisons, this can be done 13219 ;; using creqv or crxor. 13220 13221 (define_insn_and_split "" 13222 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y") 13223 (compare:CCEQ (match_operator 1 "branch_comparison_operator" 13224 [(match_operand 2 "cc_reg_operand" "y") 13225 (const_int 0)]) 13226 (match_operator 3 "branch_comparison_operator" 13227 [(match_operand 4 "cc_reg_operand" "y") 13228 (const_int 0)])))] 13229 "" 13230 "#" 13231 "" 13232 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3)) 13233 (match_dup 5)))] 13234 { 13235 int positive_1, positive_2; 13236 13237 positive_1 = branch_positive_comparison_operator (operands[1], 13238 GET_MODE (operands[1])); 13239 positive_2 = branch_positive_comparison_operator (operands[3], 13240 GET_MODE (operands[3])); 13241 13242 if (! positive_1) 13243 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]), 13244 GET_CODE (operands[1])), 13245 SImode, 13246 operands[2], const0_rtx); 13247 else if (GET_MODE (operands[1]) != SImode) 13248 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, 13249 operands[2], const0_rtx); 13250 13251 if (! positive_2) 13252 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]), 13253 GET_CODE (operands[3])), 13254 SImode, 13255 operands[4], const0_rtx); 13256 else if (GET_MODE (operands[3]) != SImode) 13257 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, 13258 operands[4], const0_rtx); 13259 13260 if (positive_1 == positive_2) 13261 { 13262 operands[1] = gen_rtx_NOT (SImode, operands[1]); 13263 operands[5] = constm1_rtx; 13264 } 13265 else 13266 { 13267 operands[5] = const1_rtx; 13268 } 13269 }) 13270 13271 ;; Unconditional branch and return. 13272 13273 (define_insn "jump" 13274 [(set (pc) 13275 (label_ref (match_operand 0)))] 13276 "" 13277 "b %l0" 13278 [(set_attr "type" "branch")]) 13279 13280 (define_insn "<return_str>return" 13281 [(any_return)] 13282 "<return_pred>" 13283 "blr" 13284 [(set_attr "type" "jmpreg")]) 13285 13286 (define_expand "indirect_jump" 13287 [(set (pc) (match_operand 0 "register_operand"))] 13288 "" 13289 { 13290 if (!rs6000_speculate_indirect_jumps) { 13291 rtx ccreg = gen_reg_rtx (CCmode); 13292 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg)); 13293 DONE; 13294 } 13295 }) 13296 13297 (define_insn "*indirect_jump<mode>" 13298 [(set (pc) 13299 (match_operand:P 0 "register_operand" "c,*l"))] 13300 "rs6000_speculate_indirect_jumps" 13301 "b%T0" 13302 [(set_attr "type" "jmpreg")]) 13303 13304 (define_insn "@indirect_jump<mode>_nospec" 13305 [(set (pc) (match_operand:P 0 "register_operand" "c,*l")) 13306 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))] 13307 "!rs6000_speculate_indirect_jumps" 13308 "crset %E1\;beq%T0- %1\;b $" 13309 [(set_attr "type" "jmpreg") 13310 (set_attr "length" "12")]) 13311 13312 ;; Table jump for switch statements: 13313 (define_expand "tablejump" 13314 [(use (match_operand 0)) 13315 (use (label_ref (match_operand 1)))] 13316 "" 13317 { 13318 if (rs6000_speculate_indirect_jumps) 13319 { 13320 if (rs6000_relative_jumptables) 13321 emit_jump_insn (gen_tablejump_normal (Pmode, operands[0], operands[1])); 13322 else 13323 emit_jump_insn (gen_tablejump_absolute (Pmode, operands[0], 13324 operands[1])); 13325 } 13326 else 13327 { 13328 rtx ccreg = gen_reg_rtx (CCmode); 13329 rtx jump; 13330 if (rs6000_relative_jumptables) 13331 jump = gen_tablejump_nospec (Pmode, operands[0], operands[1], ccreg); 13332 else 13333 jump = gen_tablejump_absolute_nospec (Pmode, operands[0], operands[1], 13334 ccreg); 13335 emit_jump_insn (jump); 13336 } 13337 DONE; 13338 }) 13339 13340 (define_expand "@tablejump<mode>_normal" 13341 [(use (match_operand:SI 0)) 13342 (use (match_operand:P 1))] 13343 "rs6000_speculate_indirect_jumps && rs6000_relative_jumptables" 13344 { 13345 rtx off = force_reg (SImode, operands[0]); 13346 if (<MODE>mode != SImode) 13347 { 13348 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off); 13349 off = gen_reg_rtx (Pmode); 13350 emit_move_insn (off, src); 13351 } 13352 13353 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1])); 13354 rtx addr = gen_reg_rtx (Pmode); 13355 13356 emit_insn (gen_add<mode>3 (addr, off, lab)); 13357 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1])); 13358 DONE; 13359 }) 13360 13361 (define_expand "@tablejump<mode>_absolute" 13362 [(use (match_operand:P 0)) 13363 (use (match_operand:P 1))] 13364 "rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables" 13365 { 13366 rtx addr = gen_reg_rtx (Pmode); 13367 emit_move_insn (addr, operands[0]); 13368 13369 emit_jump_insn (gen_tablejump_insn_normal (Pmode, addr, operands[1])); 13370 DONE; 13371 }) 13372 13373 (define_expand "@tablejump<mode>_nospec" 13374 [(use (match_operand:SI 0)) 13375 (use (match_operand:P 1)) 13376 (use (match_operand:CC 2))] 13377 "!rs6000_speculate_indirect_jumps && rs6000_relative_jumptables" 13378 { 13379 rtx off = force_reg (SImode, operands[0]); 13380 if (<MODE>mode != SImode) 13381 { 13382 rtx src = gen_rtx_fmt_e (SIGN_EXTEND, Pmode, off); 13383 off = gen_reg_rtx (Pmode); 13384 emit_move_insn (off, src); 13385 } 13386 13387 rtx lab = force_reg (Pmode, gen_rtx_LABEL_REF (Pmode, operands[1])); 13388 rtx addr = gen_reg_rtx (Pmode); 13389 13390 emit_insn (gen_add<mode>3 (addr, off, lab)); 13391 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1], 13392 operands[2])); 13393 DONE; 13394 }) 13395 13396 (define_expand "@tablejump<mode>_absolute_nospec" 13397 [(use (match_operand:P 0)) 13398 (use (match_operand:P 1)) 13399 (use (match_operand:CC 2))] 13400 "!rs6000_speculate_indirect_jumps && !rs6000_relative_jumptables" 13401 { 13402 rtx addr = gen_reg_rtx (Pmode); 13403 emit_move_insn (addr, operands[0]); 13404 13405 emit_jump_insn (gen_tablejump_insn_nospec (Pmode, addr, operands[1], 13406 operands[2])); 13407 DONE; 13408 }) 13409 13410 (define_insn "@tablejump<mode>_insn_normal" 13411 [(set (pc) 13412 (match_operand:P 0 "register_operand" "c,*l")) 13413 (use (label_ref (match_operand 1)))] 13414 "rs6000_speculate_indirect_jumps" 13415 "b%T0" 13416 [(set_attr "type" "jmpreg")]) 13417 13418 (define_insn "@tablejump<mode>_insn_nospec" 13419 [(set (pc) 13420 (match_operand:P 0 "register_operand" "c,*l")) 13421 (use (label_ref (match_operand 1))) 13422 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))] 13423 "!rs6000_speculate_indirect_jumps" 13424 "crset %E2\;beq%T0- %2\;b $" 13425 [(set_attr "type" "jmpreg") 13426 (set_attr "length" "12")]) 13427 13428 (define_insn "nop" 13429 [(unspec [(const_int 0)] UNSPEC_NOP)] 13430 "" 13431 "nop") 13432 13433 (define_insn "group_ending_nop" 13434 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)] 13435 "" 13436 { 13437 operands[0] = gen_rtx_REG (Pmode, 13438 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2); 13439 return "ori %0,%0,0"; 13440 }) 13441 13442 (define_insn "speculation_barrier" 13443 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)] 13444 "" 13445 { 13446 operands[0] = gen_rtx_REG (Pmode, 31); 13447 return "ori %0,%0,0"; 13448 }) 13449 13451 ;; Define the subtract-one-and-jump insns, starting with the template 13452 ;; so loop.c knows what to generate. 13453 13454 (define_expand "doloop_end" 13455 [(use (match_operand 0)) ; loop pseudo 13456 (use (match_operand 1))] ; label 13457 "" 13458 { 13459 if (GET_MODE (operands[0]) != Pmode) 13460 FAIL; 13461 13462 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1])); 13463 DONE; 13464 }) 13465 13466 (define_expand "@ctr<mode>" 13467 [(parallel [(set (pc) 13468 (if_then_else (ne (match_operand:P 0 "register_operand") 13469 (const_int 1)) 13470 (label_ref (match_operand 1)) 13471 (pc))) 13472 (set (match_dup 0) 13473 (plus:P (match_dup 0) 13474 (const_int -1))) 13475 (clobber (match_scratch:CC 2)) 13476 (clobber (match_scratch:P 3))])] 13477 "" 13478 "") 13479 13480 ;; We need to be able to do this for any operand, including MEM, or we 13481 ;; will cause reload to blow up since we don't allow output reloads on 13482 ;; JUMP_INSNs. 13483 ;; For the length attribute to be calculated correctly, the 13484 ;; label MUST be operand 0. 13485 ;; rs6000_legitimate_combined_insn prevents combine creating any of 13486 ;; the ctr<mode> insns. 13487 13488 (define_code_iterator eqne [eq ne]) 13489 (define_code_attr bd [(eq "bdz") (ne "bdnz")]) 13490 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")]) 13491 13492 (define_insn "<bd>_<mode>" 13493 [(set (pc) 13494 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 13495 (const_int 1)) 13496 (label_ref (match_operand 0)) 13497 (pc))) 13498 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l") 13499 (plus:P (match_dup 1) 13500 (const_int -1))) 13501 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 13502 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 13503 "" 13504 { 13505 if (which_alternative != 0) 13506 return "#"; 13507 else if (get_attr_length (insn) == 4) 13508 return "<bd> %l0"; 13509 else 13510 return "<bd_neg> $+8\;b %l0"; 13511 } 13512 [(set_attr "type" "branch") 13513 (set_attr_alternative "length" 13514 [(if_then_else (and (ge (minus (match_dup 0) (pc)) 13515 (const_int -32768)) 13516 (lt (minus (match_dup 0) (pc)) 13517 (const_int 32764))) 13518 (const_int 4) 13519 (const_int 8)) 13520 (const_string "16") 13521 (const_string "20") 13522 (const_string "20")])]) 13523 13524 ;; Now the splitter if we could not allocate the CTR register 13525 (define_split 13526 [(set (pc) 13527 (if_then_else (match_operator 2 "comparison_operator" 13528 [(match_operand:P 1 "gpc_reg_operand") 13529 (const_int 1)]) 13530 (match_operand 5) 13531 (match_operand 6))) 13532 (set (match_operand:P 0 "nonimmediate_operand") 13533 (plus:P (match_dup 1) 13534 (const_int -1))) 13535 (clobber (match_scratch:CC 3)) 13536 (clobber (match_scratch:P 4))] 13537 "reload_completed" 13538 [(set (pc) 13539 (if_then_else (match_dup 7) 13540 (match_dup 5) 13541 (match_dup 6)))] 13542 { 13543 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3], 13544 const0_rtx); 13545 emit_insn (gen_rtx_SET (operands[3], 13546 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx))); 13547 if (int_reg_operand (operands[0], <MODE>mode)) 13548 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx)); 13549 else 13550 { 13551 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx)); 13552 emit_move_insn (operands[0], operands[4]); 13553 } 13554 /* No DONE so branch comes from the pattern. */ 13555 }) 13556 13557 ;; patterns for bdnzt/bdnzf/bdzt/bdzf 13558 ;; Note that in the case of long branches we have to decompose this into 13559 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition 13560 ;; and the CR bit, which means there is no way to conveniently invert the 13561 ;; comparison as is done with plain bdnz/bdz. 13562 13563 (define_insn "<bd>tf_<mode>" 13564 [(set (pc) 13565 (if_then_else 13566 (and 13567 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 13568 (const_int 1)) 13569 (match_operator 3 "branch_comparison_operator" 13570 [(match_operand 4 "cc_reg_operand" "y,y,y,y") 13571 (const_int 0)])) 13572 (label_ref (match_operand 0)) 13573 (pc))) 13574 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l") 13575 (plus:P (match_dup 1) 13576 (const_int -1))) 13577 (clobber (match_scratch:P 5 "=X,X,&r,r")) 13578 (clobber (match_scratch:CC 6 "=X,&y,&y,&y")) 13579 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))] 13580 "" 13581 { 13582 if (which_alternative != 0) 13583 return "#"; 13584 else if (get_attr_length (insn) == 4) 13585 { 13586 if (branch_positive_comparison_operator (operands[3], 13587 GET_MODE (operands[3]))) 13588 return "<bd>t %j3,%l0"; 13589 else 13590 return "<bd>f %j3,%l0"; 13591 } 13592 else 13593 { 13594 static char seq[96]; 13595 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn); 13596 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs); 13597 return seq; 13598 } 13599 } 13600 [(set_attr "type" "branch") 13601 (set_attr_alternative "length" 13602 [(if_then_else (and (ge (minus (match_dup 0) (pc)) 13603 (const_int -32768)) 13604 (lt (minus (match_dup 0) (pc)) 13605 (const_int 32764))) 13606 (const_int 4) 13607 (const_int 8)) 13608 (const_string "16") 13609 (const_string "20") 13610 (const_string "20")])]) 13611 13612 ;; Now the splitter if we could not allocate the CTR register 13613 (define_split 13614 [(set (pc) 13615 (if_then_else 13616 (and 13617 (match_operator 1 "comparison_operator" 13618 [(match_operand:P 0 "gpc_reg_operand") 13619 (const_int 1)]) 13620 (match_operator 3 "branch_comparison_operator" 13621 [(match_operand 2 "cc_reg_operand") 13622 (const_int 0)])) 13623 (match_operand 4) 13624 (match_operand 5))) 13625 (set (match_operand:P 6 "nonimmediate_operand") 13626 (plus:P (match_dup 0) 13627 (const_int -1))) 13628 (clobber (match_scratch:P 7)) 13629 (clobber (match_scratch:CC 8)) 13630 (clobber (match_scratch:CCEQ 9))] 13631 "reload_completed" 13632 [(pc)] 13633 { 13634 rtx ctr = operands[0]; 13635 rtx ctrcmp = operands[1]; 13636 rtx ccin = operands[2]; 13637 rtx cccmp = operands[3]; 13638 rtx dst1 = operands[4]; 13639 rtx dst2 = operands[5]; 13640 rtx ctrout = operands[6]; 13641 rtx ctrtmp = operands[7]; 13642 enum rtx_code cmpcode = GET_CODE (ctrcmp); 13643 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp)); 13644 if (!ispos) 13645 cmpcode = reverse_condition (cmpcode); 13646 /* Generate crand/crandc here. */ 13647 emit_insn (gen_rtx_SET (operands[8], 13648 gen_rtx_COMPARE (CCmode, ctr, const1_rtx))); 13649 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx); 13650 13651 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp); 13652 if (ispos) 13653 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc, 13654 operands[8], cccmp, ccin)); 13655 else 13656 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc, 13657 operands[8], cccmp, ccin)); 13658 if (int_reg_operand (ctrout, <MODE>mode)) 13659 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx)); 13660 else 13661 { 13662 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx)); 13663 emit_move_insn (ctrout, ctrtmp); 13664 } 13665 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx); 13666 emit_jump_insn (gen_rtx_SET (pc_rtx, 13667 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp, 13668 dst1, dst2))); 13669 DONE; 13670 }) 13671 13672 13674 (define_insn "trap" 13675 [(trap_if (const_int 1) (const_int 0))] 13676 "" 13677 "trap" 13678 [(set_attr "type" "trap")]) 13679 13680 (define_expand "ctrap<mode>4" 13681 [(trap_if (match_operator 0 "ordered_comparison_operator" 13682 [(match_operand:GPR 1 "register_operand") 13683 (match_operand:GPR 2 "reg_or_short_operand")]) 13684 (match_operand 3 "zero_constant" ""))] 13685 "" 13686 "") 13687 13688 (define_insn "" 13689 [(trap_if (match_operator 0 "ordered_comparison_operator" 13690 [(match_operand:GPR 1 "register_operand" "r") 13691 (match_operand:GPR 2 "reg_or_short_operand" "rI")]) 13692 (const_int 0))] 13693 "" 13694 "t<wd>%V0%I2 %1,%2" 13695 [(set_attr "type" "trap")]) 13696 13698 ;; Insns related to generating the function prologue and epilogue. 13699 13700 (define_expand "prologue" 13701 [(use (const_int 0))] 13702 "" 13703 { 13704 rs6000_emit_prologue (); 13705 if (!TARGET_SCHED_PROLOG) 13706 emit_insn (gen_blockage ()); 13707 DONE; 13708 }) 13709 13710 (define_insn "*movesi_from_cr_one" 13711 [(match_parallel 0 "mfcr_operation" 13712 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 13713 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y") 13714 (match_operand 3 "immediate_operand" "n")] 13715 UNSPEC_MOVESI_FROM_CR))])] 13716 "TARGET_MFCRF" 13717 { 13718 int mask = 0; 13719 int i; 13720 for (i = 0; i < XVECLEN (operands[0], 0); i++) 13721 { 13722 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 13723 operands[4] = GEN_INT (mask); 13724 output_asm_insn ("mfcr %1,%4", operands); 13725 } 13726 return ""; 13727 } 13728 [(set_attr "type" "mfcrf")]) 13729 13730 ;; Don't include the volatile CRs since their values are not used wrt CR save 13731 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the 13732 ;; prologue past an insn (early exit test) that defines a register used in the 13733 ;; prologue. 13734 (define_insn "prologue_movesi_from_cr" 13735 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 13736 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO) 13737 (reg:CC CR4_REGNO)] 13738 UNSPEC_MOVESI_FROM_CR))] 13739 "" 13740 "mfcr %0" 13741 [(set_attr "type" "mfcr")]) 13742 13743 (define_insn "*crsave" 13744 [(match_parallel 0 "crsave_operation" 13745 [(set (match_operand:SI 1 "memory_operand" "=m") 13746 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 13747 "" 13748 "stw %2,%1" 13749 [(set_attr "type" "store")]) 13750 13751 (define_insn "*stmw" 13752 [(match_parallel 0 "stmw_operation" 13753 [(set (match_operand:SI 1 "memory_operand" "=m") 13754 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 13755 "TARGET_MULTIPLE" 13756 "stmw %2,%1" 13757 [(set_attr "type" "store") 13758 (set_attr "update" "yes") 13759 (set_attr "indexed" "yes")]) 13760 13761 ; The following comment applies to: 13762 ; save_gpregs_* 13763 ; save_fpregs_* 13764 ; restore_gpregs* 13765 ; return_and_restore_gpregs* 13766 ; return_and_restore_fpregs* 13767 ; return_and_restore_fpregs_aix* 13768 ; 13769 ; The out-of-line save / restore functions expects one input argument. 13770 ; Since those are not standard call_insn's, we must avoid using 13771 ; MATCH_OPERAND for that argument. That way the register rename 13772 ; optimization will not try to rename this register. 13773 ; Each pattern is repeated for each possible register number used in 13774 ; various ABIs (r11, r1, and for some functions r12) 13775 13776 (define_insn "*save_gpregs_<mode>_r11" 13777 [(match_parallel 0 "any_parallel_operand" 13778 [(clobber (reg:P LR_REGNO)) 13779 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13780 (use (reg:P 11)) 13781 (set (match_operand:P 2 "memory_operand" "=m") 13782 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13783 "" 13784 "bl %1" 13785 [(set_attr "type" "branch")]) 13786 13787 (define_insn "*save_gpregs_<mode>_r12" 13788 [(match_parallel 0 "any_parallel_operand" 13789 [(clobber (reg:P LR_REGNO)) 13790 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13791 (use (reg:P 12)) 13792 (set (match_operand:P 2 "memory_operand" "=m") 13793 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13794 "" 13795 "bl %1" 13796 [(set_attr "type" "branch")]) 13797 13798 (define_insn "*save_gpregs_<mode>_r1" 13799 [(match_parallel 0 "any_parallel_operand" 13800 [(clobber (reg:P LR_REGNO)) 13801 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13802 (use (reg:P 1)) 13803 (set (match_operand:P 2 "memory_operand" "=m") 13804 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13805 "" 13806 "bl %1" 13807 [(set_attr "type" "branch")]) 13808 13809 (define_insn "*save_fpregs_<mode>_r11" 13810 [(match_parallel 0 "any_parallel_operand" 13811 [(clobber (reg:P LR_REGNO)) 13812 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13813 (use (reg:P 11)) 13814 (set (match_operand:DF 2 "memory_operand" "=m") 13815 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13816 "" 13817 "bl %1" 13818 [(set_attr "type" "branch")]) 13819 13820 (define_insn "*save_fpregs_<mode>_r12" 13821 [(match_parallel 0 "any_parallel_operand" 13822 [(clobber (reg:P LR_REGNO)) 13823 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13824 (use (reg:P 12)) 13825 (set (match_operand:DF 2 "memory_operand" "=m") 13826 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13827 "" 13828 "bl %1" 13829 [(set_attr "type" "branch")]) 13830 13831 (define_insn "*save_fpregs_<mode>_r1" 13832 [(match_parallel 0 "any_parallel_operand" 13833 [(clobber (reg:P LR_REGNO)) 13834 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13835 (use (reg:P 1)) 13836 (set (match_operand:DF 2 "memory_operand" "=m") 13837 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13838 "" 13839 "bl %1" 13840 [(set_attr "type" "branch")]) 13841 13842 ; This is to explain that changes to the stack pointer should 13843 ; not be moved over loads from or stores to stack memory. 13844 (define_insn "stack_tie" 13845 [(match_parallel 0 "tie_operand" 13846 [(set (mem:BLK (reg 1)) (const_int 0))])] 13847 "" 13848 "" 13849 [(set_attr "length" "0")]) 13850 13851 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to 13852 ; stay behind all restores from the stack, it cannot be reordered to before 13853 ; one. See PR77687. This insn is an add or mr, and a memory clobber. 13854 (define_insn "stack_restore_tie" 13855 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 13856 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") 13857 (match_operand:SI 2 "reg_or_cint_operand" "O,rI"))) 13858 (set (mem:BLK (scratch)) (const_int 0))] 13859 "TARGET_32BIT" 13860 "@ 13861 mr %0,%1 13862 add%I2 %0,%1,%2" 13863 [(set_attr "type" "*,add")]) 13864 13865 (define_expand "epilogue" 13866 [(use (const_int 0))] 13867 "" 13868 { 13869 if (!TARGET_SCHED_PROLOG) 13870 emit_insn (gen_blockage ()); 13871 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL); 13872 DONE; 13873 }) 13874 13875 ; On some processors, doing the mtcrf one CC register at a time is 13876 ; faster (like on the 604e). On others, doing them all at once is 13877 ; faster; for instance, on the 601 and 750. 13878 13879 (define_expand "movsi_to_cr_one" 13880 [(set (match_operand:CC 0 "cc_reg_operand") 13881 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand") 13882 (match_dup 2)] UNSPEC_MOVESI_TO_CR))] 13883 "" 13884 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));") 13885 13886 (define_insn "*movsi_to_cr" 13887 [(match_parallel 0 "mtcrf_operation" 13888 [(set (match_operand:CC 1 "cc_reg_operand" "=y") 13889 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r") 13890 (match_operand 3 "immediate_operand" "n")] 13891 UNSPEC_MOVESI_TO_CR))])] 13892 "" 13893 { 13894 int mask = 0; 13895 int i; 13896 for (i = 0; i < XVECLEN (operands[0], 0); i++) 13897 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 13898 operands[4] = GEN_INT (mask); 13899 return "mtcrf %4,%2"; 13900 } 13901 [(set_attr "type" "mtcr")]) 13902 13903 (define_insn "*mtcrfsi" 13904 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 13905 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 13906 (match_operand 2 "immediate_operand" "n")] 13907 UNSPEC_MOVESI_TO_CR))] 13908 "REG_P (operands[0]) 13909 && CR_REGNO_P (REGNO (operands[0])) 13910 && CONST_INT_P (operands[2]) 13911 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))" 13912 "mtcrf %R0,%1" 13913 [(set_attr "type" "mtcr")]) 13914 13915 ; The load-multiple instructions have similar properties. 13916 ; Note that "load_multiple" is a name known to the machine-independent 13917 ; code that actually corresponds to the PowerPC load-string. 13918 13919 (define_insn "*lmw" 13920 [(match_parallel 0 "lmw_operation" 13921 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 13922 (match_operand:SI 2 "memory_operand" "m"))])] 13923 "TARGET_MULTIPLE" 13924 "lmw %1,%2" 13925 [(set_attr "type" "load") 13926 (set_attr "update" "yes") 13927 (set_attr "indexed" "yes") 13928 (set_attr "cell_micro" "always")]) 13929 13930 ; FIXME: "any_parallel_operand" is a bit flexible... 13931 13932 ; The following comment applies to: 13933 ; save_gpregs_* 13934 ; save_fpregs_* 13935 ; restore_gpregs* 13936 ; return_and_restore_gpregs* 13937 ; return_and_restore_fpregs* 13938 ; return_and_restore_fpregs_aix* 13939 ; 13940 ; The out-of-line save / restore functions expects one input argument. 13941 ; Since those are not standard call_insn's, we must avoid using 13942 ; MATCH_OPERAND for that argument. That way the register rename 13943 ; optimization will not try to rename this register. 13944 ; Each pattern is repeated for each possible register number used in 13945 ; various ABIs (r11, r1, and for some functions r12) 13946 13947 (define_insn "*restore_gpregs_<mode>_r11" 13948 [(match_parallel 0 "any_parallel_operand" 13949 [(clobber (reg:P LR_REGNO)) 13950 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13951 (use (reg:P 11)) 13952 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13953 (match_operand:P 3 "memory_operand" "m"))])] 13954 "" 13955 "bl %1" 13956 [(set_attr "type" "branch")]) 13957 13958 (define_insn "*restore_gpregs_<mode>_r12" 13959 [(match_parallel 0 "any_parallel_operand" 13960 [(clobber (reg:P LR_REGNO)) 13961 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13962 (use (reg:P 12)) 13963 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13964 (match_operand:P 3 "memory_operand" "m"))])] 13965 "" 13966 "bl %1" 13967 [(set_attr "type" "branch")]) 13968 13969 (define_insn "*restore_gpregs_<mode>_r1" 13970 [(match_parallel 0 "any_parallel_operand" 13971 [(clobber (reg:P LR_REGNO)) 13972 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13973 (use (reg:P 1)) 13974 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13975 (match_operand:P 3 "memory_operand" "m"))])] 13976 "" 13977 "bl %1" 13978 [(set_attr "type" "branch")]) 13979 13980 (define_insn "*return_and_restore_gpregs_<mode>_r11" 13981 [(match_parallel 0 "any_parallel_operand" 13982 [(return) 13983 (clobber (reg:P LR_REGNO)) 13984 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13985 (use (reg:P 11)) 13986 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13987 (match_operand:P 3 "memory_operand" "m"))])] 13988 "" 13989 "b %1" 13990 [(set_attr "type" "branch")]) 13991 13992 (define_insn "*return_and_restore_gpregs_<mode>_r12" 13993 [(match_parallel 0 "any_parallel_operand" 13994 [(return) 13995 (clobber (reg:P LR_REGNO)) 13996 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13997 (use (reg:P 12)) 13998 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13999 (match_operand:P 3 "memory_operand" "m"))])] 14000 "" 14001 "b %1" 14002 [(set_attr "type" "branch")]) 14003 14004 (define_insn "*return_and_restore_gpregs_<mode>_r1" 14005 [(match_parallel 0 "any_parallel_operand" 14006 [(return) 14007 (clobber (reg:P LR_REGNO)) 14008 (use (match_operand:P 1 "symbol_ref_operand" "s")) 14009 (use (reg:P 1)) 14010 (set (match_operand:P 2 "gpc_reg_operand" "=r") 14011 (match_operand:P 3 "memory_operand" "m"))])] 14012 "" 14013 "b %1" 14014 [(set_attr "type" "branch")]) 14015 14016 (define_insn "*return_and_restore_fpregs_<mode>_r11" 14017 [(match_parallel 0 "any_parallel_operand" 14018 [(return) 14019 (clobber (reg:P LR_REGNO)) 14020 (use (match_operand:P 1 "symbol_ref_operand" "s")) 14021 (use (reg:P 11)) 14022 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 14023 (match_operand:DF 3 "memory_operand" "m"))])] 14024 "" 14025 "b %1" 14026 [(set_attr "type" "branch")]) 14027 14028 (define_insn "*return_and_restore_fpregs_<mode>_r12" 14029 [(match_parallel 0 "any_parallel_operand" 14030 [(return) 14031 (clobber (reg:P LR_REGNO)) 14032 (use (match_operand:P 1 "symbol_ref_operand" "s")) 14033 (use (reg:P 12)) 14034 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 14035 (match_operand:DF 3 "memory_operand" "m"))])] 14036 "" 14037 "b %1" 14038 [(set_attr "type" "branch")]) 14039 14040 (define_insn "*return_and_restore_fpregs_<mode>_r1" 14041 [(match_parallel 0 "any_parallel_operand" 14042 [(return) 14043 (clobber (reg:P LR_REGNO)) 14044 (use (match_operand:P 1 "symbol_ref_operand" "s")) 14045 (use (reg:P 1)) 14046 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 14047 (match_operand:DF 3 "memory_operand" "m"))])] 14048 "" 14049 "b %1" 14050 [(set_attr "type" "branch")]) 14051 14052 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11" 14053 [(match_parallel 0 "any_parallel_operand" 14054 [(return) 14055 (use (match_operand:P 1 "symbol_ref_operand" "s")) 14056 (use (reg:P 11)) 14057 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 14058 (match_operand:DF 3 "memory_operand" "m"))])] 14059 "" 14060 "b %1" 14061 [(set_attr "type" "branch")]) 14062 14063 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1" 14064 [(match_parallel 0 "any_parallel_operand" 14065 [(return) 14066 (use (match_operand:P 1 "symbol_ref_operand" "s")) 14067 (use (reg:P 1)) 14068 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 14069 (match_operand:DF 3 "memory_operand" "m"))])] 14070 "" 14071 "b %1" 14072 [(set_attr "type" "branch")]) 14073 14074 ; This is used in compiling the unwind routines. 14075 (define_expand "eh_return" 14076 [(use (match_operand 0 "general_operand"))] 14077 "" 14078 { 14079 emit_insn (gen_eh_set_lr (Pmode, operands[0])); 14080 emit_jump_insn (gen_eh_return_internal ()); 14081 emit_barrier (); 14082 DONE; 14083 }) 14084 14085 ; We can't expand this before we know where the link register is stored. 14086 (define_insn_and_split "@eh_set_lr_<mode>" 14087 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR) 14088 (clobber (match_scratch:P 1 "=&b"))] 14089 "" 14090 "#" 14091 "reload_completed" 14092 [(const_int 0)] 14093 { 14094 rs6000_emit_eh_reg_restore (operands[0], operands[1]); 14095 DONE; 14096 }) 14097 14098 (define_insn_and_split "eh_return_internal" 14099 [(eh_return)] 14100 "" 14101 "#" 14102 "epilogue_completed" 14103 [(const_int 0)] 14104 { 14105 if (!TARGET_SCHED_PROLOG) 14106 emit_insn (gen_blockage ()); 14107 rs6000_emit_epilogue (EPILOGUE_TYPE_EH_RETURN); 14108 DONE; 14109 }) 14110 14111 (define_insn "prefetch" 14112 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a") 14113 (match_operand:SI 1 "const_int_operand" "n") 14114 (match_operand:SI 2 "const_int_operand" "n"))] 14115 "" 14116 { 14117 14118 14119 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7). 14120 AIX does not support the dcbtstt and dcbtt extended mnemonics. 14121 The AIX assembler does not support the three operand form of dcbt 14122 and dcbtst on Power 7 (-mpwr7). */ 14123 int inst_select = INTVAL (operands[2]) || !TARGET_POWER8; 14124 14125 if (REG_P (operands[0])) 14126 { 14127 if (INTVAL (operands[1]) == 0) 14128 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16"; 14129 else 14130 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16"; 14131 } 14132 else 14133 { 14134 if (INTVAL (operands[1]) == 0) 14135 return inst_select ? "dcbt %a0" : "dcbt %a0,16"; 14136 else 14137 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16"; 14138 } 14139 } 14140 [(set_attr "type" "load")]) 14141 14143 ;; Handle -fsplit-stack. 14144 14145 (define_expand "split_stack_prologue" 14146 [(const_int 0)] 14147 "" 14148 { 14149 rs6000_expand_split_stack_prologue (); 14150 DONE; 14151 }) 14152 14153 (define_expand "load_split_stack_limit" 14154 [(set (match_operand 0) 14155 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))] 14156 "" 14157 { 14158 emit_insn (gen_rtx_SET (operands[0], 14159 gen_rtx_UNSPEC (Pmode, 14160 gen_rtvec (1, const0_rtx), 14161 UNSPEC_STACK_CHECK))); 14162 DONE; 14163 }) 14164 14165 (define_insn "load_split_stack_limit_di" 14166 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 14167 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))] 14168 "TARGET_64BIT" 14169 "ld %0,-0x7040(13)" 14170 [(set_attr "type" "load") 14171 (set_attr "update" "no") 14172 (set_attr "indexed" "no")]) 14173 14174 (define_insn "load_split_stack_limit_si" 14175 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 14176 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))] 14177 "!TARGET_64BIT" 14178 "lwz %0,-0x7020(2)" 14179 [(set_attr "type" "load") 14180 (set_attr "update" "no") 14181 (set_attr "indexed" "no")]) 14182 14183 ;; A return instruction which the middle-end doesn't see. 14184 ;; Use r0 to stop regrename twiddling with lr restore insns emitted 14185 ;; after the call to __morestack. 14186 (define_insn "split_stack_return" 14187 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)] 14188 "" 14189 "blr" 14190 [(set_attr "type" "jmpreg")]) 14191 14192 ;; If there are operand 0 bytes available on the stack, jump to 14193 ;; operand 1. 14194 (define_expand "split_stack_space_check" 14195 [(set (match_dup 2) 14196 (unspec [(const_int 0)] UNSPEC_STACK_CHECK)) 14197 (set (match_dup 3) 14198 (minus (reg STACK_POINTER_REGNUM) 14199 (match_operand 0))) 14200 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2))) 14201 (set (pc) (if_then_else 14202 (geu (match_dup 4) (const_int 0)) 14203 (label_ref (match_operand 1)) 14204 (pc)))] 14205 "" 14206 { 14207 rs6000_split_stack_space_check (operands[0], operands[1]); 14208 DONE; 14209 }) 14210 14212 (define_insn "bpermd_<mode>" 14213 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 14214 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") 14215 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))] 14216 "TARGET_POPCNTD" 14217 "bpermd %0,%1,%2" 14218 [(set_attr "type" "popcnt")]) 14219 14220 14222 ;; Builtin fma support. Handle 14223 ;; Note that the conditions for expansion are in the FMA_F iterator. 14224 14225 (define_expand "fma<mode>4" 14226 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 14227 (fma:FMA_F 14228 (match_operand:FMA_F 1 "gpc_reg_operand") 14229 (match_operand:FMA_F 2 "gpc_reg_operand") 14230 (match_operand:FMA_F 3 "gpc_reg_operand")))] 14231 "" 14232 "") 14233 14234 (define_insn "*fma<mode>4_fpr" 14235 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 14236 (fma:SFDF 14237 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa") 14238 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 14239 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))] 14240 "TARGET_HARD_FLOAT" 14241 "@ 14242 fmadd<s> %0,%1,%2,%3 14243 xsmadda<sd>p %x0,%x1,%x2 14244 xsmaddm<sd>p %x0,%x1,%x3" 14245 [(set_attr "type" "fp") 14246 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 14247 14248 ; Altivec only has fma and nfms. 14249 (define_expand "fms<mode>4" 14250 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 14251 (fma:FMA_F 14252 (match_operand:FMA_F 1 "gpc_reg_operand") 14253 (match_operand:FMA_F 2 "gpc_reg_operand") 14254 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))] 14255 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 14256 "") 14257 14258 (define_insn "*fms<mode>4_fpr" 14259 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 14260 (fma:SFDF 14261 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa") 14262 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 14263 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))] 14264 "TARGET_HARD_FLOAT" 14265 "@ 14266 fmsub<s> %0,%1,%2,%3 14267 xsmsuba<sd>p %x0,%x1,%x2 14268 xsmsubm<sd>p %x0,%x1,%x3" 14269 [(set_attr "type" "fp") 14270 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 14271 14272 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c. 14273 (define_expand "fnma<mode>4" 14274 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 14275 (neg:FMA_F 14276 (fma:FMA_F 14277 (match_operand:FMA_F 1 "gpc_reg_operand") 14278 (match_operand:FMA_F 2 "gpc_reg_operand") 14279 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))] 14280 "!HONOR_SIGNED_ZEROS (<MODE>mode)" 14281 "") 14282 14283 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c. 14284 (define_expand "fnms<mode>4" 14285 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 14286 (neg:FMA_F 14287 (fma:FMA_F 14288 (match_operand:FMA_F 1 "gpc_reg_operand") 14289 (match_operand:FMA_F 2 "gpc_reg_operand") 14290 (match_operand:FMA_F 3 "gpc_reg_operand"))))] 14291 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 14292 "") 14293 14294 ; Not an official optab name, but used from builtins. 14295 (define_expand "nfma<mode>4" 14296 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 14297 (neg:FMA_F 14298 (fma:FMA_F 14299 (match_operand:FMA_F 1 "gpc_reg_operand") 14300 (match_operand:FMA_F 2 "gpc_reg_operand") 14301 (match_operand:FMA_F 3 "gpc_reg_operand"))))] 14302 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 14303 "") 14304 14305 (define_insn "*nfma<mode>4_fpr" 14306 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 14307 (neg:SFDF 14308 (fma:SFDF 14309 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa") 14310 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 14311 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))] 14312 "TARGET_HARD_FLOAT" 14313 "@ 14314 fnmadd<s> %0,%1,%2,%3 14315 xsnmadda<sd>p %x0,%x1,%x2 14316 xsnmaddm<sd>p %x0,%x1,%x3" 14317 [(set_attr "type" "fp") 14318 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 14319 14320 ; Not an official optab name, but used from builtins. 14321 (define_expand "nfms<mode>4" 14322 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 14323 (neg:FMA_F 14324 (fma:FMA_F 14325 (match_operand:FMA_F 1 "gpc_reg_operand") 14326 (match_operand:FMA_F 2 "gpc_reg_operand") 14327 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))] 14328 "" 14329 "") 14330 14331 (define_insn "*nfmssf4_fpr" 14332 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 14333 (neg:SFDF 14334 (fma:SFDF 14335 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa") 14336 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 14337 (neg:SFDF 14338 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))] 14339 "TARGET_HARD_FLOAT" 14340 "@ 14341 fnmsub<s> %0,%1,%2,%3 14342 xsnmsuba<sd>p %x0,%x1,%x2 14343 xsnmsubm<sd>p %x0,%x1,%x3" 14344 [(set_attr "type" "fp") 14345 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 14346 14348 (define_expand "rs6000_get_timebase" 14349 [(use (match_operand:DI 0 "gpc_reg_operand"))] 14350 "" 14351 { 14352 if (TARGET_POWERPC64) 14353 emit_insn (gen_rs6000_mftb_di (operands[0])); 14354 else 14355 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0])); 14356 DONE; 14357 }) 14358 14359 (define_insn "rs6000_get_timebase_ppc32" 14360 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 14361 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB)) 14362 (clobber (match_scratch:SI 1 "=r")) 14363 (clobber (match_scratch:CC 2 "=y"))] 14364 "!TARGET_POWERPC64" 14365 { 14366 if (WORDS_BIG_ENDIAN) 14367 if (TARGET_MFCRF) 14368 { 14369 return "mfspr %0,269\;" 14370 "mfspr %L0,268\;" 14371 "mfspr %1,269\;" 14372 "cmpw %2,%0,%1\;" 14373 "bne- %2,$-16"; 14374 } 14375 else 14376 { 14377 return "mftbu %0\;" 14378 "mftb %L0\;" 14379 "mftbu %1\;" 14380 "cmpw %2,%0,%1\;" 14381 "bne- %2,$-16"; 14382 } 14383 else 14384 if (TARGET_MFCRF) 14385 { 14386 return "mfspr %L0,269\;" 14387 "mfspr %0,268\;" 14388 "mfspr %1,269\;" 14389 "cmpw %2,%L0,%1\;" 14390 "bne- %2,$-16"; 14391 } 14392 else 14393 { 14394 return "mftbu %L0\;" 14395 "mftb %0\;" 14396 "mftbu %1\;" 14397 "cmpw %2,%L0,%1\;" 14398 "bne- %2,$-16"; 14399 } 14400 } 14401 [(set_attr "length" "20")]) 14402 14403 (define_insn "rs6000_mftb_<mode>" 14404 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 14405 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))] 14406 "" 14407 { 14408 if (TARGET_MFCRF) 14409 return "mfspr %0,268"; 14410 else 14411 return "mftb %0"; 14412 }) 14413 14414 14416 ;; The ISA 3.0 mffsl instruction is a lower latency instruction 14417 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR. 14418 (define_insn "rs6000_mffsl_hw" 14419 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 14420 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))] 14421 "TARGET_HARD_FLOAT" 14422 "mffsl %0") 14423 14424 (define_expand "rs6000_mffsl" 14425 [(set (match_operand:DF 0 "gpc_reg_operand") 14426 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))] 14427 "TARGET_HARD_FLOAT" 14428 { 14429 /* If the low latency mffsl instruction (ISA 3.0) is available use it, 14430 otherwise fall back to the older mffs instruction to emulate the mffsl 14431 instruction. */ 14432 14433 if (!TARGET_P9_MISC) 14434 { 14435 rtx tmp1 = gen_reg_rtx (DFmode); 14436 14437 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl 14438 instruction using the mffs instruction and masking the result. */ 14439 emit_insn (gen_rs6000_mffs (tmp1)); 14440 14441 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0); 14442 rtx tmp2 = gen_reg_rtx (DImode); 14443 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL))); 14444 14445 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0); 14446 emit_move_insn (operands[0], tmp2df); 14447 DONE; 14448 } 14449 14450 emit_insn (gen_rs6000_mffsl_hw (operands[0])); 14451 DONE; 14452 }) 14453 14454 (define_insn "rs6000_mffs" 14455 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 14456 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))] 14457 "TARGET_HARD_FLOAT" 14458 "mffs %0") 14459 14460 (define_insn "rs6000_mtfsf" 14461 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i") 14462 (match_operand:DF 1 "gpc_reg_operand" "d")] 14463 UNSPECV_MTFSF)] 14464 "TARGET_HARD_FLOAT" 14465 "mtfsf %0,%1") 14466 14467 (define_insn "rs6000_mtfsf_hi" 14468 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") 14469 (match_operand:DF 1 "gpc_reg_operand" "d")] 14470 UNSPECV_MTFSF_HI)] 14471 "TARGET_HARD_FLOAT" 14472 "mtfsf %0,%1,0,1") 14473 14474 14476 ;; Power8 fusion support for fusing an addis instruction with a D-form load of 14477 ;; a GPR. The addis instruction must be adjacent to the load, and use the same 14478 ;; register that is being loaded. The fused ops must be physically adjacent. 14479 14480 ;; On Power8 GPR loads, we try to use the register that is being load. The 14481 ;; peephole2 then gathers any other fused possibilities that it can find after 14482 ;; register allocation. If power9 fusion is selected, we also fuse floating 14483 ;; point loads/stores. 14484 14485 ;; Find cases where the addis that feeds into a load instruction is either used 14486 ;; once or is the same as the target register, and replace it with the fusion 14487 ;; insn 14488 14489 (define_peephole2 14490 [(set (match_operand:P 0 "base_reg_operand") 14491 (match_operand:P 1 "fusion_gpr_addis")) 14492 (set (match_operand:INT1 2 "base_reg_operand") 14493 (match_operand:INT1 3 "fusion_gpr_mem_load"))] 14494 "TARGET_P8_FUSION 14495 && fusion_gpr_load_p (operands[0], operands[1], operands[2], 14496 operands[3])" 14497 [(const_int 0)] 14498 { 14499 expand_fusion_gpr_load (operands); 14500 DONE; 14501 }) 14502 14503 ;; Fusion insn, created by the define_peephole2 above (and eventually by 14504 ;; reload) 14505 14506 (define_insn "*fusion_gpr_load_<mode>" 14507 [(set (match_operand:INT1 0 "base_reg_operand" "=b") 14508 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")] 14509 UNSPEC_FUSION_GPR))] 14510 "TARGET_P8_FUSION" 14511 { 14512 return emit_fusion_gpr_load (operands[0], operands[1]); 14513 } 14514 [(set_attr "type" "load") 14515 (set_attr "length" "8")]) 14516 14517 14519 ;; Optimize cases where we want to do a D-form load (register+offset) on 14520 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator 14521 ;; has generated: 14522 ;; LFD 0,32(3) 14523 ;; XXLOR 32,0,0 14524 ;; 14525 ;; and we change this to: 14526 ;; LI 0,32 14527 ;; LXSDX 32,3,9 14528 14529 (define_peephole2 14530 [(match_scratch:P 0 "b") 14531 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 14532 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand")) 14533 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand") 14534 (match_dup 1))] 14535 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])" 14536 [(set (match_dup 0) 14537 (match_dup 4)) 14538 (set (match_dup 3) 14539 (match_dup 5))] 14540 { 14541 rtx tmp_reg = operands[0]; 14542 rtx mem = operands[2]; 14543 rtx addr = XEXP (mem, 0); 14544 rtx add_op0, add_op1, new_addr; 14545 14546 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 14547 add_op0 = XEXP (addr, 0); 14548 add_op1 = XEXP (addr, 1); 14549 gcc_assert (REG_P (add_op0)); 14550 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); 14551 14552 operands[4] = add_op1; 14553 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr); 14554 }) 14555 14556 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an 14557 ;; Altivec register, and the register allocator has generated: 14558 ;; XXLOR 0,32,32 14559 ;; STFD 0,32(3) 14560 ;; 14561 ;; and we change this to: 14562 ;; LI 0,32 14563 ;; STXSDX 32,3,9 14564 14565 (define_peephole2 14566 [(match_scratch:P 0 "b") 14567 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 14568 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand")) 14569 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand") 14570 (match_dup 1))] 14571 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])" 14572 [(set (match_dup 0) 14573 (match_dup 4)) 14574 (set (match_dup 5) 14575 (match_dup 2))] 14576 { 14577 rtx tmp_reg = operands[0]; 14578 rtx mem = operands[3]; 14579 rtx addr = XEXP (mem, 0); 14580 rtx add_op0, add_op1, new_addr; 14581 14582 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 14583 add_op0 = XEXP (addr, 0); 14584 add_op1 = XEXP (addr, 1); 14585 gcc_assert (REG_P (add_op0)); 14586 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); 14587 14588 operands[4] = add_op1; 14589 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr); 14590 }) 14591 14592 14594 ;; Miscellaneous ISA 2.06 (power7) instructions 14595 (define_insn "addg6s" 14596 [(set (match_operand:SI 0 "register_operand" "=r") 14597 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 14598 (match_operand:SI 2 "register_operand" "r")] 14599 UNSPEC_ADDG6S))] 14600 "TARGET_POPCNTD" 14601 "addg6s %0,%1,%2" 14602 [(set_attr "type" "integer")]) 14603 14604 (define_insn "cdtbcd" 14605 [(set (match_operand:SI 0 "register_operand" "=r") 14606 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 14607 UNSPEC_CDTBCD))] 14608 "TARGET_POPCNTD" 14609 "cdtbcd %0,%1" 14610 [(set_attr "type" "integer")]) 14611 14612 (define_insn "cbcdtd" 14613 [(set (match_operand:SI 0 "register_operand" "=r") 14614 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 14615 UNSPEC_CBCDTD))] 14616 "TARGET_POPCNTD" 14617 "cbcdtd %0,%1" 14618 [(set_attr "type" "integer")]) 14619 14620 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE 14621 UNSPEC_DIVEU]) 14622 14623 (define_int_attr div_extend [(UNSPEC_DIVE "e") 14624 (UNSPEC_DIVEU "eu")]) 14625 14626 (define_insn "div<div_extend>_<mode>" 14627 [(set (match_operand:GPR 0 "register_operand" "=r") 14628 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r") 14629 (match_operand:GPR 2 "register_operand" "r")] 14630 UNSPEC_DIV_EXTEND))] 14631 "TARGET_POPCNTD" 14632 "div<wd><div_extend> %0,%1,%2" 14633 [(set_attr "type" "div") 14634 (set_attr "size" "<bits>")]) 14635 14636 14638 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers 14639 14640 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types 14641 (define_mode_attr FP128_64 [(TF "DF") 14642 (IF "DF") 14643 (TD "DI") 14644 (KF "DI")]) 14645 14646 (define_expand "unpack<mode>" 14647 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand") 14648 (unspec:<FP128_64> 14649 [(match_operand:FMOVE128 1 "register_operand") 14650 (match_operand:QI 2 "const_0_to_1_operand")] 14651 UNSPEC_UNPACK_128BIT))] 14652 "FLOAT128_2REG_P (<MODE>mode)" 14653 "") 14654 14655 (define_insn_and_split "unpack<mode>_dm" 14656 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m") 14657 (unspec:<FP128_64> 14658 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r") 14659 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")] 14660 UNSPEC_UNPACK_128BIT))] 14661 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)" 14662 "#" 14663 "&& reload_completed" 14664 [(set (match_dup 0) (match_dup 3))] 14665 { 14666 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 14667 14668 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 14669 { 14670 emit_note (NOTE_INSN_DELETED); 14671 DONE; 14672 } 14673 14674 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 14675 } 14676 [(set_attr "type" "fp,fpstore,mtvsr,mfvsr,store")]) 14677 14678 (define_insn_and_split "unpack<mode>_nodm" 14679 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,m") 14680 (unspec:<FP128_64> 14681 [(match_operand:FMOVE128 1 "register_operand" "d,d,r") 14682 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i")] 14683 UNSPEC_UNPACK_128BIT))] 14684 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)" 14685 "#" 14686 "&& reload_completed" 14687 [(set (match_dup 0) (match_dup 3))] 14688 { 14689 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 14690 14691 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 14692 { 14693 emit_note (NOTE_INSN_DELETED); 14694 DONE; 14695 } 14696 14697 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 14698 } 14699 [(set_attr "type" "fp,fpstore,store")]) 14700 14701 (define_expand "pack<mode>" 14702 [(use (match_operand:FMOVE128 0 "register_operand")) 14703 (use (match_operand:<FP128_64> 1 "register_operand")) 14704 (use (match_operand:<FP128_64> 2 "register_operand"))] 14705 "FLOAT128_2REG_P (<MODE>mode)" 14706 { 14707 if (TARGET_HARD_FLOAT) 14708 emit_insn (gen_pack<mode>_hard (operands[0], operands[1], operands[2])); 14709 else 14710 emit_insn (gen_pack<mode>_soft (operands[0], operands[1], operands[2])); 14711 DONE; 14712 }) 14713 14714 (define_insn_and_split "pack<mode>_hard" 14715 [(set (match_operand:FMOVE128 0 "register_operand" "=&d") 14716 (unspec:FMOVE128 14717 [(match_operand:<FP128_64> 1 "register_operand" "d") 14718 (match_operand:<FP128_64> 2 "register_operand" "d")] 14719 UNSPEC_PACK_128BIT))] 14720 "FLOAT128_2REG_P (<MODE>mode) && TARGET_HARD_FLOAT" 14721 "#" 14722 "&& reload_completed" 14723 [(set (match_dup 3) (match_dup 1)) 14724 (set (match_dup 4) (match_dup 2))] 14725 { 14726 unsigned dest_hi = REGNO (operands[0]); 14727 unsigned dest_lo = dest_hi + 1; 14728 14729 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo)); 14730 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); 14731 14732 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); 14733 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); 14734 } 14735 [(set_attr "type" "fp") 14736 (set_attr "length" "8")]) 14737 14738 (define_insn_and_split "pack<mode>_soft" 14739 [(set (match_operand:FMOVE128 0 "register_operand" "=&r") 14740 (unspec:FMOVE128 14741 [(match_operand:<FP128_64> 1 "register_operand" "r") 14742 (match_operand:<FP128_64> 2 "register_operand" "r")] 14743 UNSPEC_PACK_128BIT))] 14744 "FLOAT128_2REG_P (<MODE>mode) && TARGET_SOFT_FLOAT" 14745 "#" 14746 "&& reload_completed" 14747 [(set (match_dup 3) (match_dup 1)) 14748 (set (match_dup 4) (match_dup 2))] 14749 { 14750 unsigned dest_hi = REGNO (operands[0]); 14751 unsigned dest_lo = dest_hi + (TARGET_POWERPC64 ? 1 : 2); 14752 14753 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo)); 14754 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); 14755 14756 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); 14757 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); 14758 } 14759 [(set_attr "type" "integer") 14760 (set (attr "length") 14761 (if_then_else 14762 (match_test "TARGET_POWERPC64") 14763 (const_string "8") 14764 (const_string "16")))]) 14765 14766 (define_insn "unpack<mode>" 14767 [(set (match_operand:DI 0 "register_operand" "=wa,wa") 14768 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa") 14769 (match_operand:QI 2 "const_0_to_1_operand" "O,i")] 14770 UNSPEC_UNPACK_128BIT))] 14771 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 14772 { 14773 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0) 14774 return ASM_COMMENT_START " xxpermdi to same register"; 14775 14776 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3); 14777 return "xxpermdi %x0,%x1,%x1,%3"; 14778 } 14779 [(set_attr "type" "vecperm")]) 14780 14781 (define_insn "pack<mode>" 14782 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa") 14783 (unspec:FMOVE128_VSX 14784 [(match_operand:DI 1 "register_operand" "wa") 14785 (match_operand:DI 2 "register_operand" "wa")] 14786 UNSPEC_PACK_128BIT))] 14787 "TARGET_VSX" 14788 "xxpermdi %x0,%x1,%x2,0" 14789 [(set_attr "type" "vecperm")]) 14790 14791 14792 14794 ;; ISA 2.08 IEEE 128-bit floating point support. 14795 14796 (define_insn "add<mode>3" 14797 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14798 (plus:IEEE128 14799 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14800 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14801 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14802 "xsaddqp %0,%1,%2" 14803 [(set_attr "type" "vecfloat") 14804 (set_attr "size" "128")]) 14805 14806 (define_insn "sub<mode>3" 14807 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14808 (minus:IEEE128 14809 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14810 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14811 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14812 "xssubqp %0,%1,%2" 14813 [(set_attr "type" "vecfloat") 14814 (set_attr "size" "128")]) 14815 14816 (define_insn "mul<mode>3" 14817 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14818 (mult:IEEE128 14819 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14820 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14821 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14822 "xsmulqp %0,%1,%2" 14823 [(set_attr "type" "qmul") 14824 (set_attr "size" "128")]) 14825 14826 (define_insn "div<mode>3" 14827 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14828 (div:IEEE128 14829 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14830 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14831 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14832 "xsdivqp %0,%1,%2" 14833 [(set_attr "type" "vecdiv") 14834 (set_attr "size" "128")]) 14835 14836 (define_insn "sqrt<mode>2" 14837 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14838 (sqrt:IEEE128 14839 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14840 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14841 "xssqrtqp %0,%1" 14842 [(set_attr "type" "vecdiv") 14843 (set_attr "size" "128")]) 14844 14845 (define_expand "copysign<mode>3" 14846 [(use (match_operand:IEEE128 0 "altivec_register_operand")) 14847 (use (match_operand:IEEE128 1 "altivec_register_operand")) 14848 (use (match_operand:IEEE128 2 "altivec_register_operand"))] 14849 "FLOAT128_IEEE_P (<MODE>mode)" 14850 { 14851 if (TARGET_FLOAT128_HW) 14852 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1], 14853 operands[2])); 14854 else 14855 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1], 14856 operands[2])); 14857 DONE; 14858 }) 14859 14860 (define_insn "copysign<mode>3_hard" 14861 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14862 (unspec:IEEE128 14863 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14864 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14865 UNSPEC_COPYSIGN))] 14866 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14867 "xscpsgnqp %0,%2,%1" 14868 [(set_attr "type" "vecmove") 14869 (set_attr "size" "128")]) 14870 14871 (define_insn "copysign<mode>3_soft" 14872 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14873 (unspec:IEEE128 14874 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14875 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14876 UNSPEC_COPYSIGN)) 14877 (clobber (match_scratch:IEEE128 3 "=&v"))] 14878 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14879 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1" 14880 [(set_attr "type" "veccomplex") 14881 (set_attr "length" "8")]) 14882 14883 (define_insn "@neg<mode>2_hw" 14884 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14885 (neg:IEEE128 14886 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14887 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14888 "xsnegqp %0,%1" 14889 [(set_attr "type" "vecmove") 14890 (set_attr "size" "128")]) 14891 14892 14893 (define_insn "@abs<mode>2_hw" 14894 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14895 (abs:IEEE128 14896 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14897 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14898 "xsabsqp %0,%1" 14899 [(set_attr "type" "vecmove") 14900 (set_attr "size" "128")]) 14901 14902 14903 (define_insn "*nabs<mode>2_hw" 14904 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14905 (neg:IEEE128 14906 (abs:IEEE128 14907 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))] 14908 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14909 "xsnabsqp %0,%1" 14910 [(set_attr "type" "vecmove") 14911 (set_attr "size" "128")]) 14912 14913 ;; Initially don't worry about doing fusion 14914 (define_insn "fma<mode>4_hw" 14915 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14916 (fma:IEEE128 14917 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14918 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14919 (match_operand:IEEE128 3 "altivec_register_operand" "0")))] 14920 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14921 "xsmaddqp %0,%1,%2" 14922 [(set_attr "type" "qmul") 14923 (set_attr "size" "128")]) 14924 14925 (define_insn "*fms<mode>4_hw" 14926 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14927 (fma:IEEE128 14928 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14929 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14930 (neg:IEEE128 14931 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 14932 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14933 "xsmsubqp %0,%1,%2" 14934 [(set_attr "type" "qmul") 14935 (set_attr "size" "128")]) 14936 14937 (define_insn "*nfma<mode>4_hw" 14938 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14939 (neg:IEEE128 14940 (fma:IEEE128 14941 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14942 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14943 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 14944 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14945 "xsnmaddqp %0,%1,%2" 14946 [(set_attr "type" "qmul") 14947 (set_attr "size" "128")]) 14948 14949 (define_insn "*nfms<mode>4_hw" 14950 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14951 (neg:IEEE128 14952 (fma:IEEE128 14953 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14954 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14955 (neg:IEEE128 14956 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))] 14957 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14958 "xsnmsubqp %0,%1,%2" 14959 [(set_attr "type" "qmul") 14960 (set_attr "size" "128")]) 14961 14962 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw" 14963 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14964 (float_extend:IEEE128 14965 (match_operand:SFDF 1 "altivec_register_operand" "v")))] 14966 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14967 "xscvdpqp %0,%1" 14968 [(set_attr "type" "vecfloat") 14969 (set_attr "size" "128")]) 14970 14971 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating 14972 ;; point is a simple copy. 14973 (define_insn_and_split "extendkftf2" 14974 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa") 14975 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))] 14976 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD" 14977 "@ 14978 # 14979 xxlor %x0,%x1,%x1" 14980 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 14981 [(const_int 0)] 14982 { 14983 emit_note (NOTE_INSN_DELETED); 14984 DONE; 14985 } 14986 [(set_attr "type" "*,veclogical") 14987 (set_attr "length" "0,4")]) 14988 14989 (define_insn_and_split "trunctfkf2" 14990 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa") 14991 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))] 14992 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD" 14993 "@ 14994 # 14995 xxlor %x0,%x1,%x1" 14996 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 14997 [(const_int 0)] 14998 { 14999 emit_note (NOTE_INSN_DELETED); 15000 DONE; 15001 } 15002 [(set_attr "type" "*,veclogical") 15003 (set_attr "length" "0,4")]) 15004 15005 (define_insn "trunc<mode>df2_hw" 15006 [(set (match_operand:DF 0 "altivec_register_operand" "=v") 15007 (float_truncate:DF 15008 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 15009 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15010 "xscvqpdp %0,%1" 15011 [(set_attr "type" "vecfloat") 15012 (set_attr "size" "128")]) 15013 15014 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing 15015 ;; the KFmode -> DFmode conversion using round to odd rather than the normal 15016 ;; conversion 15017 (define_insn_and_split "trunc<mode>sf2_hw" 15018 [(set (match_operand:SF 0 "vsx_register_operand" "=wa") 15019 (float_truncate:SF 15020 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 15021 (clobber (match_scratch:DF 2 "=v"))] 15022 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15023 "#" 15024 "&& 1" 15025 [(set (match_dup 2) 15026 (unspec:DF [(match_dup 1)] 15027 UNSPEC_TRUNC_ROUND_TO_ODD)) 15028 (set (match_dup 0) 15029 (float_truncate:SF (match_dup 2)))] 15030 { 15031 if (GET_CODE (operands[2]) == SCRATCH) 15032 operands[2] = gen_reg_rtx (DFmode); 15033 } 15034 [(set_attr "type" "vecfloat") 15035 (set_attr "length" "8") 15036 (set_attr "isa" "p8v")]) 15037 15038 ;; Conversion between IEEE 128-bit and integer types 15039 15040 ;; The fix function for DImode and SImode was declared earlier as a 15041 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't 15042 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided 15043 ;; unless we have the IEEE 128-bit hardware. 15044 ;; 15045 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have 15046 ;; to provide a GPR target that used direct move and a conversion in the GPR 15047 ;; which works around QImode/HImode not being allowed in vector registers in 15048 ;; ISA 2.07 (power8). 15049 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw" 15050 [(set (match_operand:SDI 0 "altivec_register_operand" "=v") 15051 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 15052 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 15053 "xscvqp<su><wd>z %0,%1" 15054 [(set_attr "type" "vecfloat") 15055 (set_attr "size" "128")]) 15056 15057 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2" 15058 [(set (match_operand:QHI 0 "altivec_register_operand" "=v") 15059 (any_fix:QHI 15060 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 15061 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 15062 "xscvqp<su>wz %0,%1" 15063 [(set_attr "type" "vecfloat") 15064 (set_attr "size" "128")]) 15065 15066 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit 15067 ;; floating point value to 8/16/32-bit integer to GPR in order to save it. 15068 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem" 15069 [(set (match_operand:QHSI 0 "memory_operand" "=Z") 15070 (any_fix:QHSI 15071 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 15072 (clobber (match_scratch:QHSI 2 "=v"))] 15073 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 15074 "#" 15075 "&& reload_completed" 15076 [(set (match_dup 2) 15077 (any_fix:QHSI (match_dup 1))) 15078 (set (match_dup 0) 15079 (match_dup 2))]) 15080 15081 (define_insn "float_<mode>di2_hw" 15082 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15083 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))] 15084 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15085 "xscvsdqp %0,%1" 15086 [(set_attr "type" "vecfloat") 15087 (set_attr "size" "128")]) 15088 15089 (define_insn_and_split "float_<mode>si2_hw" 15090 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15091 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ"))) 15092 (clobber (match_scratch:DI 2 "=v"))] 15093 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15094 "#" 15095 "&& 1" 15096 [(set (match_dup 2) 15097 (sign_extend:DI (match_dup 1))) 15098 (set (match_dup 0) 15099 (float:IEEE128 (match_dup 2)))] 15100 { 15101 if (GET_CODE (operands[2]) == SCRATCH) 15102 operands[2] = gen_reg_rtx (DImode); 15103 15104 if (MEM_P (operands[1])) 15105 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 15106 }) 15107 15108 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2" 15109 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 15110 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) 15111 (clobber (match_scratch:DI 2 "=X,r,X"))] 15112 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 15113 "#" 15114 "&& reload_completed" 15115 [(const_int 0)] 15116 { 15117 rtx dest = operands[0]; 15118 rtx src = operands[1]; 15119 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest)); 15120 15121 if (altivec_register_operand (src, <QHI:MODE>mode)) 15122 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src)); 15123 else if (int_reg_operand (src, <QHI:MODE>mode)) 15124 { 15125 rtx ext_di = operands[2]; 15126 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src)); 15127 emit_move_insn (dest_di, ext_di); 15128 } 15129 else if (MEM_P (src)) 15130 { 15131 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest)); 15132 emit_move_insn (dest_qhi, src); 15133 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi)); 15134 } 15135 else 15136 gcc_unreachable (); 15137 15138 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di)); 15139 DONE; 15140 } 15141 [(set_attr "length" "8,12,12") 15142 (set_attr "type" "vecfloat") 15143 (set_attr "size" "128")]) 15144 15145 (define_insn "floatuns_<mode>di2_hw" 15146 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15147 (unsigned_float:IEEE128 15148 (match_operand:DI 1 "altivec_register_operand" "v")))] 15149 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15150 "xscvudqp %0,%1" 15151 [(set_attr "type" "vecfloat") 15152 (set_attr "size" "128")]) 15153 15154 (define_insn_and_split "floatuns_<mode>si2_hw" 15155 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15156 (unsigned_float:IEEE128 15157 (match_operand:SI 1 "nonimmediate_operand" "vrZ"))) 15158 (clobber (match_scratch:DI 2 "=v"))] 15159 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15160 "#" 15161 "&& 1" 15162 [(set (match_dup 2) 15163 (zero_extend:DI (match_dup 1))) 15164 (set (match_dup 0) 15165 (float:IEEE128 (match_dup 2)))] 15166 { 15167 if (GET_CODE (operands[2]) == SCRATCH) 15168 operands[2] = gen_reg_rtx (DImode); 15169 15170 if (MEM_P (operands[1])) 15171 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 15172 }) 15173 15174 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2" 15175 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 15176 (unsigned_float:IEEE128 15177 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) 15178 (clobber (match_scratch:DI 2 "=X,r,X"))] 15179 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 15180 "#" 15181 "&& reload_completed" 15182 [(const_int 0)] 15183 { 15184 rtx dest = operands[0]; 15185 rtx src = operands[1]; 15186 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest)); 15187 15188 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src)) 15189 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src)); 15190 else if (int_reg_operand (src, <QHI:MODE>mode)) 15191 { 15192 rtx ext_di = operands[2]; 15193 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src)); 15194 emit_move_insn (dest_di, ext_di); 15195 } 15196 else 15197 gcc_unreachable (); 15198 15199 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di)); 15200 DONE; 15201 } 15202 [(set_attr "length" "8,12,8") 15203 (set_attr "type" "vecfloat") 15204 (set_attr "size" "128")]) 15205 15206 ;; IEEE 128-bit round to integer built-in functions 15207 (define_insn "floor<mode>2" 15208 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15209 (unspec:IEEE128 15210 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 15211 UNSPEC_FRIM))] 15212 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15213 "xsrqpi 1,%0,%1,3" 15214 [(set_attr "type" "vecfloat") 15215 (set_attr "size" "128")]) 15216 15217 (define_insn "ceil<mode>2" 15218 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15219 (unspec:IEEE128 15220 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 15221 UNSPEC_FRIP))] 15222 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15223 "xsrqpi 1,%0,%1,2" 15224 [(set_attr "type" "vecfloat") 15225 (set_attr "size" "128")]) 15226 15227 (define_insn "btrunc<mode>2" 15228 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15229 (unspec:IEEE128 15230 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 15231 UNSPEC_FRIZ))] 15232 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15233 "xsrqpi 1,%0,%1,1" 15234 [(set_attr "type" "vecfloat") 15235 (set_attr "size" "128")]) 15236 15237 (define_insn "round<mode>2" 15238 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15239 (unspec:IEEE128 15240 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 15241 UNSPEC_FRIN))] 15242 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15243 "xsrqpi 0,%0,%1,0" 15244 [(set_attr "type" "vecfloat") 15245 (set_attr "size" "128")]) 15246 15247 ;; IEEE 128-bit instructions with round to odd semantics 15248 (define_insn "add<mode>3_odd" 15249 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15250 (unspec:IEEE128 15251 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 15252 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 15253 UNSPEC_ADD_ROUND_TO_ODD))] 15254 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15255 "xsaddqpo %0,%1,%2" 15256 [(set_attr "type" "vecfloat") 15257 (set_attr "size" "128")]) 15258 15259 (define_insn "sub<mode>3_odd" 15260 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15261 (unspec:IEEE128 15262 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 15263 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 15264 UNSPEC_SUB_ROUND_TO_ODD))] 15265 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15266 "xssubqpo %0,%1,%2" 15267 [(set_attr "type" "vecfloat") 15268 (set_attr "size" "128")]) 15269 15270 (define_insn "mul<mode>3_odd" 15271 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15272 (unspec:IEEE128 15273 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 15274 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 15275 UNSPEC_MUL_ROUND_TO_ODD))] 15276 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15277 "xsmulqpo %0,%1,%2" 15278 [(set_attr "type" "qmul") 15279 (set_attr "size" "128")]) 15280 15281 (define_insn "div<mode>3_odd" 15282 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15283 (unspec:IEEE128 15284 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 15285 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 15286 UNSPEC_DIV_ROUND_TO_ODD))] 15287 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15288 "xsdivqpo %0,%1,%2" 15289 [(set_attr "type" "vecdiv") 15290 (set_attr "size" "128")]) 15291 15292 (define_insn "sqrt<mode>2_odd" 15293 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15294 (unspec:IEEE128 15295 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 15296 UNSPEC_SQRT_ROUND_TO_ODD))] 15297 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15298 "xssqrtqpo %0,%1" 15299 [(set_attr "type" "vecdiv") 15300 (set_attr "size" "128")]) 15301 15302 (define_insn "fma<mode>4_odd" 15303 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15304 (unspec:IEEE128 15305 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 15306 (match_operand:IEEE128 2 "altivec_register_operand" "v") 15307 (match_operand:IEEE128 3 "altivec_register_operand" "0")] 15308 UNSPEC_FMA_ROUND_TO_ODD))] 15309 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15310 "xsmaddqpo %0,%1,%2" 15311 [(set_attr "type" "qmul") 15312 (set_attr "size" "128")]) 15313 15314 (define_insn "*fms<mode>4_odd" 15315 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15316 (unspec:IEEE128 15317 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 15318 (match_operand:IEEE128 2 "altivec_register_operand" "v") 15319 (neg:IEEE128 15320 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] 15321 UNSPEC_FMA_ROUND_TO_ODD))] 15322 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15323 "xsmsubqpo %0,%1,%2" 15324 [(set_attr "type" "qmul") 15325 (set_attr "size" "128")]) 15326 15327 (define_insn "*nfma<mode>4_odd" 15328 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15329 (neg:IEEE128 15330 (unspec:IEEE128 15331 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 15332 (match_operand:IEEE128 2 "altivec_register_operand" "v") 15333 (match_operand:IEEE128 3 "altivec_register_operand" "0")] 15334 UNSPEC_FMA_ROUND_TO_ODD)))] 15335 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15336 "xsnmaddqpo %0,%1,%2" 15337 [(set_attr "type" "qmul") 15338 (set_attr "size" "128")]) 15339 15340 (define_insn "*nfms<mode>4_odd" 15341 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 15342 (neg:IEEE128 15343 (unspec:IEEE128 15344 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 15345 (match_operand:IEEE128 2 "altivec_register_operand" "v") 15346 (neg:IEEE128 15347 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] 15348 UNSPEC_FMA_ROUND_TO_ODD)))] 15349 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15350 "xsnmsubqpo %0,%1,%2" 15351 [(set_attr "type" "qmul") 15352 (set_attr "size" "128")]) 15353 15354 (define_insn "trunc<mode>df2_odd" 15355 [(set (match_operand:DF 0 "vsx_register_operand" "=v") 15356 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 15357 UNSPEC_TRUNC_ROUND_TO_ODD))] 15358 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15359 "xscvqpdpo %0,%1" 15360 [(set_attr "type" "vecfloat") 15361 (set_attr "size" "128")]) 15362 15363 ;; IEEE 128-bit comparisons 15364 (define_insn "*cmp<mode>_hw" 15365 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 15366 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v") 15367 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 15368 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 15369 "xscmpuqp %0,%1,%2" 15370 [(set_attr "type" "veccmp") 15371 (set_attr "size" "128")]) 15372 15374 ;; Miscellaneous ISA 3.0 (power9) instructions 15375 15376 (define_expand "darn_32_<mode>" 15377 [(use (match_operand:GPR 0 "register_operand"))] 15378 "TARGET_P9_MISC" 15379 { 15380 emit_insn (gen_darn (<MODE>mode, operands[0], const0_rtx)); 15381 DONE; 15382 }) 15383 15384 (define_expand "darn_64_<mode>" 15385 [(use (match_operand:GPR 0 "register_operand"))] 15386 "TARGET_P9_MISC" 15387 { 15388 emit_insn (gen_darn (<MODE>mode, operands[0], const1_rtx)); 15389 DONE; 15390 }) 15391 15392 (define_expand "darn_raw_<mode>" 15393 [(use (match_operand:GPR 0 "register_operand"))] 15394 "TARGET_P9_MISC" 15395 { 15396 emit_insn (gen_darn (<MODE>mode, operands[0], const2_rtx)); 15397 DONE; 15398 }) 15399 15400 (define_insn "@darn<mode>" 15401 [(set (match_operand:GPR 0 "register_operand" "=r") 15402 (unspec_volatile:GPR [(match_operand 1 "const_int_operand" "n")] 15403 UNSPECV_DARN))] 15404 "TARGET_P9_MISC" 15405 "darn %0,%1" 15406 [(set_attr "type" "integer")]) 15407 15408 ;; Test byte within range. 15409 ;; 15410 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 15411 ;; represents a byte whose value is ignored in this context and 15412 ;; vv, the least significant byte, holds the byte value that is to 15413 ;; be tested for membership within the range specified by operand 2. 15414 ;; The bytes of operand 2 are organized as xx:xx:hi:lo. 15415 ;; 15416 ;; Return in target register operand 0 a value of 1 if lo <= vv and 15417 ;; vv <= hi. Otherwise, set register operand 0 to 0. 15418 ;; 15419 ;; Though the instructions to which this expansion maps operate on 15420 ;; 64-bit registers, the current implementation only operates on 15421 ;; SI-mode operands as the high-order bits provide no information 15422 ;; that is not already available in the low-order bits. To avoid the 15423 ;; costs of data widening operations, future enhancements might allow 15424 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 15425 (define_expand "cmprb" 15426 [(set (match_dup 3) 15427 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 15428 (match_operand:SI 2 "gpc_reg_operand" "r")] 15429 UNSPEC_CMPRB)) 15430 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 15431 (if_then_else:SI (lt (match_dup 3) 15432 (const_int 0)) 15433 (const_int -1) 15434 (if_then_else (gt (match_dup 3) 15435 (const_int 0)) 15436 (const_int 1) 15437 (const_int 0))))] 15438 "TARGET_P9_MISC" 15439 { 15440 operands[3] = gen_reg_rtx (CCmode); 15441 }) 15442 15443 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 15444 ;; represents a byte whose value is ignored in this context and 15445 ;; vv, the least significant byte, holds the byte value that is to 15446 ;; be tested for membership within the range specified by operand 2. 15447 ;; The bytes of operand 2 are organized as xx:xx:hi:lo. 15448 ;; 15449 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if 15450 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other 15451 ;; 3 bits of the target CR register are all set to 0. 15452 (define_insn "*cmprb_internal" 15453 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 15454 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 15455 (match_operand:SI 2 "gpc_reg_operand" "r")] 15456 UNSPEC_CMPRB))] 15457 "TARGET_P9_MISC" 15458 "cmprb %0,0,%1,%2" 15459 [(set_attr "type" "logical")]) 15460 15461 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition 15462 ;; register operand 1 is on. Otherwise, set operand 0 register to 1 15463 ;; if the GT bit (0x4) of condition register operand 1 is on. 15464 ;; Otherwise, set operand 0 to 0. Note that the result stored into 15465 ;; register operand 0 is non-zero iff either the LT or GT bits are on 15466 ;; within condition register operand 1. 15467 (define_insn "setb_signed" 15468 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 15469 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y") 15470 (const_int 0)) 15471 (const_int -1) 15472 (if_then_else (gt (match_dup 1) 15473 (const_int 0)) 15474 (const_int 1) 15475 (const_int 0))))] 15476 "TARGET_P9_MISC" 15477 "setb %0,%1" 15478 [(set_attr "type" "logical")]) 15479 15480 (define_insn "setb_unsigned" 15481 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 15482 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y") 15483 (const_int 0)) 15484 (const_int -1) 15485 (if_then_else (gtu (match_dup 1) 15486 (const_int 0)) 15487 (const_int 1) 15488 (const_int 0))))] 15489 "TARGET_P9_MISC" 15490 "setb %0,%1" 15491 [(set_attr "type" "logical")]) 15492 15493 ;; Test byte within two ranges. 15494 ;; 15495 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 15496 ;; represents a byte whose value is ignored in this context and 15497 ;; vv, the least significant byte, holds the byte value that is to 15498 ;; be tested for membership within the range specified by operand 2. 15499 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. 15500 ;; 15501 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and 15502 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register 15503 ;; operand 0 to 0. 15504 ;; 15505 ;; Though the instructions to which this expansion maps operate on 15506 ;; 64-bit registers, the current implementation only operates on 15507 ;; SI-mode operands as the high-order bits provide no information 15508 ;; that is not already available in the low-order bits. To avoid the 15509 ;; costs of data widening operations, future enhancements might allow 15510 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 15511 (define_expand "cmprb2" 15512 [(set (match_dup 3) 15513 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 15514 (match_operand:SI 2 "gpc_reg_operand" "r")] 15515 UNSPEC_CMPRB2)) 15516 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 15517 (if_then_else:SI (lt (match_dup 3) 15518 (const_int 0)) 15519 (const_int -1) 15520 (if_then_else (gt (match_dup 3) 15521 (const_int 0)) 15522 (const_int 1) 15523 (const_int 0))))] 15524 "TARGET_P9_MISC" 15525 { 15526 operands[3] = gen_reg_rtx (CCmode); 15527 }) 15528 15529 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 15530 ;; represents a byte whose value is ignored in this context and 15531 ;; vv, the least significant byte, holds the byte value that is to 15532 ;; be tested for membership within the ranges specified by operand 2. 15533 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. 15534 ;; 15535 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if 15536 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). 15537 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target 15538 ;; CR register are all set to 0. 15539 (define_insn "*cmprb2_internal" 15540 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 15541 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 15542 (match_operand:SI 2 "gpc_reg_operand" "r")] 15543 UNSPEC_CMPRB2))] 15544 "TARGET_P9_MISC" 15545 "cmprb %0,1,%1,%2" 15546 [(set_attr "type" "logical")]) 15547 15548 ;; Test byte membership within set of 8 bytes. 15549 ;; 15550 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 15551 ;; represents a byte whose value is ignored in this context and 15552 ;; vv, the least significant byte, holds the byte value that is to 15553 ;; be tested for membership within the set specified by operand 2. 15554 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. 15555 ;; 15556 ;; Return in target register operand 0 a value of 1 if vv equals one 15557 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set 15558 ;; register operand 0 to 0. Note that the 8 byte values held within 15559 ;; operand 2 need not be unique. 15560 ;; 15561 ;; Though the instructions to which this expansion maps operate on 15562 ;; 64-bit registers, the current implementation requires that operands 15563 ;; 0 and 1 have mode SI as the high-order bits provide no information 15564 ;; that is not already available in the low-order bits. To avoid the 15565 ;; costs of data widening operations, future enhancements might allow 15566 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 15567 (define_expand "cmpeqb" 15568 [(set (match_dup 3) 15569 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 15570 (match_operand:DI 2 "gpc_reg_operand" "r")] 15571 UNSPEC_CMPEQB)) 15572 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 15573 (if_then_else:SI (lt (match_dup 3) 15574 (const_int 0)) 15575 (const_int -1) 15576 (if_then_else (gt (match_dup 3) 15577 (const_int 0)) 15578 (const_int 1) 15579 (const_int 0))))] 15580 "TARGET_P9_MISC && TARGET_64BIT" 15581 { 15582 operands[3] = gen_reg_rtx (CCmode); 15583 }) 15584 15585 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 15586 ;; represents a byte whose value is ignored in this context and 15587 ;; vv, the least significant byte, holds the byte value that is to 15588 ;; be tested for membership within the set specified by operand 2. 15589 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. 15590 ;; 15591 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv 15592 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, 15593 ;; set the GT bit to zero. The other 3 bits of the target CR register 15594 ;; are all set to 0. 15595 (define_insn "*cmpeqb_internal" 15596 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 15597 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 15598 (match_operand:DI 2 "gpc_reg_operand" "r")] 15599 UNSPEC_CMPEQB))] 15600 "TARGET_P9_MISC && TARGET_64BIT" 15601 "cmpeqb %0,%1,%2" 15602 [(set_attr "type" "logical")]) 15603 15604 15605 ;; ROP mitigation instructions. 15606 15607 (define_insn "hashst" 15608 [(set (match_operand:DI 0 "simple_offsettable_mem_operand" "=m") 15609 (unspec_volatile:DI [(match_operand:DI 1 "int_reg_operand" "r")] 15610 UNSPEC_HASHST))] 15611 "rs6000_rop_protect" 15612 { 15613 static char templ[32]; 15614 const char *p = rs6000_privileged ? "p" : ""; 15615 sprintf (templ, "hashst%s %%1,%%0", p); 15616 return templ; 15617 } 15618 [(set_attr "type" "store")]) 15619 15620 (define_insn "hashchk" 15621 [(unspec_volatile [(match_operand:DI 0 "int_reg_operand" "r") 15622 (match_operand:DI 1 "simple_offsettable_mem_operand" "m")] 15623 UNSPEC_HASHCHK)] 15624 "rs6000_rop_protect" 15625 { 15626 static char templ[32]; 15627 const char *p = rs6000_privileged ? "p" : ""; 15628 sprintf (templ, "hashchk%s %%0,%%1", p); 15629 return templ; 15630 } 15631 [(set_attr "type" "load")]) 15632 15634 15635 (include "sync.md") 15636 (include "vector.md") 15637 (include "vsx.md") 15638 (include "altivec.md") 15639 (include "mma.md") 15640 (include "dfp.md") 15641 (include "crypto.md") 15642 (include "htm.md") 15643 (include "fusion.md") 15644 (include "pcrel-opt.md") 15645