1;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler 2;; Copyright (C) 1990-2020 Free Software Foundation, Inc. 3;; Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 4 5;; This file is part of GCC. 6 7;; GCC is free software; you can redistribute it and/or modify it 8;; under the terms of the GNU General Public License as published 9;; by the Free Software Foundation; either version 3, or (at your 10;; option) any later version. 11 12;; GCC is distributed in the hope that it will be useful, but WITHOUT 13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15;; License for more details. 16 17;; You should have received a copy of the GNU General Public License 18;; along with GCC; see the file COPYING3. If not see 19;; <http://www.gnu.org/licenses/>. 20 21;;- See file "rtl.def" for documentation on define_insn, match_*, et. al. 22 23;; 24;; REGNOS 25;; 26 27(define_constants 28 [(FIRST_GPR_REGNO 0) 29 (STACK_POINTER_REGNUM 1) 30 (TOC_REGNUM 2) 31 (STATIC_CHAIN_REGNUM 11) 32 (HARD_FRAME_POINTER_REGNUM 31) 33 (LAST_GPR_REGNO 31) 34 (FIRST_FPR_REGNO 32) 35 (LAST_FPR_REGNO 63) 36 (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_TLSDTPREL 81 UNSPEC_TLSDTPRELHA 82 UNSPEC_TLSDTPRELLO 83 UNSPEC_TLSGOTDTPREL 84 UNSPEC_TLSTPREL 85 UNSPEC_TLSTPRELHA 86 UNSPEC_TLSTPRELLO 87 UNSPEC_TLSGOTTPREL 88 UNSPEC_TLSTLS 89 UNSPEC_TLSTLS_PCREL 90 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero 91 UNSPEC_STFIWX 92 UNSPEC_POPCNTB 93 UNSPEC_FRES 94 UNSPEC_SP_SET 95 UNSPEC_SP_TEST 96 UNSPEC_SYNC 97 UNSPEC_LWSYNC 98 UNSPEC_SYNC_OP 99 UNSPEC_ATOMIC 100 UNSPEC_CMPXCHG 101 UNSPEC_XCHG 102 UNSPEC_AND 103 UNSPEC_DLMZB 104 UNSPEC_DLMZB_CR 105 UNSPEC_DLMZB_STRLEN 106 UNSPEC_RSQRT 107 UNSPEC_TOCREL 108 UNSPEC_MACHOPIC_OFFSET 109 UNSPEC_BPERM 110 UNSPEC_COPYSIGN 111 UNSPEC_PARITY 112 UNSPEC_CMPB 113 UNSPEC_FCTIW 114 UNSPEC_FCTID 115 UNSPEC_LFIWAX 116 UNSPEC_LFIWZX 117 UNSPEC_FCTIWUZ 118 UNSPEC_NOP 119 UNSPEC_GRP_END_NOP 120 UNSPEC_P8V_FMRGOW 121 UNSPEC_P8V_MTVSRWZ 122 UNSPEC_P8V_RELOAD_FROM_GPR 123 UNSPEC_P8V_MTVSRD 124 UNSPEC_P8V_XXPERMDI 125 UNSPEC_P8V_RELOAD_FROM_VSX 126 UNSPEC_ADDG6S 127 UNSPEC_CDTBCD 128 UNSPEC_CBCDTD 129 UNSPEC_DIVE 130 UNSPEC_DIVEU 131 UNSPEC_UNPACK_128BIT 132 UNSPEC_PACK_128BIT 133 UNSPEC_LSQ 134 UNSPEC_FUSION_GPR 135 UNSPEC_STACK_CHECK 136 UNSPEC_CMPRB 137 UNSPEC_CMPRB2 138 UNSPEC_CMPEQB 139 UNSPEC_ADD_ROUND_TO_ODD 140 UNSPEC_SUB_ROUND_TO_ODD 141 UNSPEC_MUL_ROUND_TO_ODD 142 UNSPEC_DIV_ROUND_TO_ODD 143 UNSPEC_FMA_ROUND_TO_ODD 144 UNSPEC_SQRT_ROUND_TO_ODD 145 UNSPEC_TRUNC_ROUND_TO_ODD 146 UNSPEC_SIGNBIT 147 UNSPEC_SF_FROM_SI 148 UNSPEC_SI_FROM_SF 149 UNSPEC_PLTSEQ 150 UNSPEC_PLT16_HA 151 ]) 152 153;; 154;; UNSPEC_VOLATILE usage 155;; 156 157(define_c_enum "unspecv" 158 [UNSPECV_BLOCK 159 UNSPECV_LL ; load-locked 160 UNSPECV_SC ; store-conditional 161 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses 162 UNSPECV_EH_RR ; eh_reg_restore 163 UNSPECV_ISYNC ; isync instruction 164 UNSPECV_MFTB ; move from time base 165 UNSPECV_DARN ; darn 1 (deliver a random number) 166 UNSPECV_DARN_32 ; darn 2 167 UNSPECV_DARN_RAW ; darn 0 168 UNSPECV_NLGR ; non-local goto receiver 169 UNSPECV_MFFS ; Move from FPSCR 170 UNSPECV_MFFSL ; Move from FPSCR light instruction version 171 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode 172 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode 173 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15 174 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7 175 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0 176 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1 177 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return 178 UNSPECV_SPEC_BARRIER ; Speculation barrier 179 UNSPECV_PLT16_LO 180 UNSPECV_PLT_PCREL 181 ]) 182 183; The three different kinds of epilogue. 184(define_enum "epilogue_type" [normal sibcall eh_return]) 185 186;; Define an insn type attribute. This is used in function unit delay 187;; computations. 188(define_attr "type" 189 "integer,two,three, 190 add,logical,shift,insert, 191 mul,halfmul,div, 192 exts,cntlz,popcnt,isel, 193 load,store,fpload,fpstore,vecload,vecstore, 194 cmp, 195 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c, 196 cr_logical,mfcr,mfcrf,mtcr, 197 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt, 198 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm, 199 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto, 200 veclogical,veccmpfx,vecexts,vecmove, 201 htm,htmsimple,dfp,mma" 202 (const_string "integer")) 203 204;; What data size does this instruction work on? 205;; This is used for insert, mul and others as necessary. 206(define_attr "size" "8,16,32,64,128" (const_string "32")) 207 208;; What is the insn_cost for this insn? The target hook can still override 209;; this. For optimizing for size the "length" attribute is used instead. 210(define_attr "cost" "" (const_int 0)) 211 212;; Is this instruction record form ("dot", signed compare to 0, writing CR0)? 213;; This is used for add, logical, shift, exts, mul. 214(define_attr "dot" "no,yes" (const_string "no")) 215 216;; Does this instruction sign-extend its result? 217;; This is used for load insns. 218(define_attr "sign_extend" "no,yes" (const_string "no")) 219 220;; Does this cr_logical instruction have three operands? That is, BT != BB. 221(define_attr "cr_logical_3op" "no,yes" (const_string "no")) 222 223;; Does this instruction use indexed (that is, reg+reg) addressing? 224;; This is used for load and store insns. If operand 0 or 1 is a MEM 225;; it is automatically set based on that. If a load or store instruction 226;; has fewer than two operands it needs to set this attribute manually 227;; or the compiler will crash. 228(define_attr "indexed" "no,yes" 229 (if_then_else (ior (match_operand 0 "indexed_address_mem") 230 (match_operand 1 "indexed_address_mem")) 231 (const_string "yes") 232 (const_string "no"))) 233 234;; Does this instruction use update addressing? 235;; This is used for load and store insns. See the comments for "indexed". 236(define_attr "update" "no,yes" 237 (if_then_else (ior (match_operand 0 "update_address_mem") 238 (match_operand 1 "update_address_mem")) 239 (const_string "yes") 240 (const_string "no"))) 241 242;; Is this instruction using operands[2] as shift amount, and can that be a 243;; register? 244;; This is used for shift insns. 245(define_attr "maybe_var_shift" "no,yes" (const_string "no")) 246 247;; Is this instruction using a shift amount from a register? 248;; This is used for shift insns. 249(define_attr "var_shift" "no,yes" 250 (if_then_else (and (eq_attr "type" "shift") 251 (eq_attr "maybe_var_shift" "yes")) 252 (if_then_else (match_operand 2 "gpc_reg_operand") 253 (const_string "yes") 254 (const_string "no")) 255 (const_string "no"))) 256 257;; Is copying of this instruction disallowed? 258(define_attr "cannot_copy" "no,yes" (const_string "no")) 259 260 261;; Whether an insn is a prefixed insn, and an initial 'p' should be printed 262;; before the instruction. A prefixed instruction has a prefix instruction 263;; word that extends the immediate value of the instructions from 12-16 bits to 264;; 34 bits. The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed 265;; insns. The default "length" attribute will also be adjusted by default to 266;; be 12 bytes. 267(define_attr "prefixed" "no,yes" 268 (cond [(ior (match_test "!TARGET_PREFIXED") 269 (match_test "!NONJUMP_INSN_P (insn)")) 270 (const_string "no") 271 272 (eq_attr "type" "load,fpload,vecload") 273 (if_then_else (match_test "prefixed_load_p (insn)") 274 (const_string "yes") 275 (const_string "no")) 276 277 (eq_attr "type" "store,fpstore,vecstore") 278 (if_then_else (match_test "prefixed_store_p (insn)") 279 (const_string "yes") 280 (const_string "no")) 281 282 (eq_attr "type" "integer,add") 283 (if_then_else (match_test "prefixed_paddi_p (insn)") 284 (const_string "yes") 285 (const_string "no"))] 286 287 (const_string "no"))) 288 289;; Return the number of real hardware instructions in a combined insn. If it 290;; is 0, just use the length / 4. 291(define_attr "num_insns" "" (const_int 0)) 292 293;; If an insn is prefixed, return the maximum number of prefixed instructions 294;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the 295;; insn length. 296(define_attr "max_prefixed_insns" "" (const_int 1)) 297 298;; Length of the instruction (in bytes). This length does not consider the 299;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust 300;; the length if there are prefixed instructions. 301;; 302;; While it might be tempting to use num_insns to calculate the length, it can 303;; be problematical unless all insn lengths are adjusted to use num_insns 304;; (i.e. if num_insns is 0, it will get the length, which in turn will get 305;; num_insns and recurse). 306(define_attr "length" "" (const_int 4)) 307 308;; Processor type -- this attribute must exactly match the processor_type 309;; enumeration in rs6000-opts.h. 310(define_attr "cpu" 311 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630, 312 ppc750,ppc7400,ppc7450, 313 ppc403,ppc405,ppc440,ppc476, 314 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500, 315 power4,power5,power6,power7,power8,power9,power10, 316 rs64a,mpccore,cell,ppca2,titan" 317 (const (symbol_ref "(enum attr_cpu) rs6000_tune"))) 318 319;; The ISA we implement. 320(define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,p10" 321 (const_string "any")) 322 323;; Is this alternative enabled for the current CPU/ISA/etc.? 324(define_attr "enabled" "" 325 (cond 326 [(eq_attr "isa" "any") 327 (const_int 1) 328 329 (and (eq_attr "isa" "p5") 330 (match_test "TARGET_POPCNTB")) 331 (const_int 1) 332 333 (and (eq_attr "isa" "p6") 334 (match_test "TARGET_CMPB")) 335 (const_int 1) 336 337 (and (eq_attr "isa" "p7") 338 (match_test "TARGET_POPCNTD")) 339 (const_int 1) 340 341 (and (eq_attr "isa" "p7v") 342 (match_test "TARGET_VSX")) 343 (const_int 1) 344 345 (and (eq_attr "isa" "p8v") 346 (match_test "TARGET_P8_VECTOR")) 347 (const_int 1) 348 349 (and (eq_attr "isa" "p9v") 350 (match_test "TARGET_P9_VECTOR")) 351 (const_int 1) 352 353 (and (eq_attr "isa" "p9kf") 354 (match_test "TARGET_FLOAT128_TYPE")) 355 (const_int 1) 356 357 (and (eq_attr "isa" "p9tf") 358 (match_test "FLOAT128_VECTOR_P (TFmode)")) 359 (const_int 1) 360 361 (and (eq_attr "isa" "p10") 362 (match_test "TARGET_POWER10")) 363 (const_int 1) 364 ] (const_int 0))) 365 366;; If this instruction is microcoded on the CELL processor 367; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded 368(define_attr "cell_micro" "not,conditional,always" 369 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul") 370 (eq_attr "dot" "yes")) 371 (and (eq_attr "type" "load") 372 (eq_attr "sign_extend" "yes")) 373 (and (eq_attr "type" "shift") 374 (eq_attr "var_shift" "yes"))) 375 (const_string "always") 376 (const_string "not"))) 377 378(automata_option "ndfa") 379 380(include "rs64.md") 381(include "mpc.md") 382(include "40x.md") 383(include "440.md") 384(include "476.md") 385(include "601.md") 386(include "603.md") 387(include "6xx.md") 388(include "7xx.md") 389(include "7450.md") 390(include "8540.md") 391(include "e300c2c3.md") 392(include "e500mc.md") 393(include "e500mc64.md") 394(include "e5500.md") 395(include "e6500.md") 396(include "power4.md") 397(include "power5.md") 398(include "power6.md") 399(include "power7.md") 400(include "power8.md") 401(include "power9.md") 402(include "power10.md") 403(include "cell.md") 404(include "a2.md") 405(include "titan.md") 406 407(include "predicates.md") 408(include "constraints.md") 409 410 411;; Mode iterators 412 413; This mode iterator allows :GPR to be used to indicate the allowable size 414; of whole values in GPRs. 415(define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")]) 416 417; And again, for patterns that need two (potentially) different integer modes. 418(define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")]) 419 420; Any supported integer mode. 421(define_mode_iterator INT [QI HI SI DI TI PTI]) 422 423; Any supported integer mode that fits in one register. 424(define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")]) 425 426; Integer modes supported in VSX registers with ISA 3.0 instructions 427(define_mode_iterator INT_ISA3 [QI HI SI DI]) 428 429; Everything we can extend QImode to. 430(define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")]) 431 432; Everything we can extend HImode to. 433(define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")]) 434 435; Everything we can extend SImode to. 436(define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")]) 437 438; QImode or HImode for small integer moves and small atomic ops 439(define_mode_iterator QHI [QI HI]) 440 441; QImode, HImode, SImode for fused ops only for GPR loads 442(define_mode_iterator QHSI [QI HI SI]) 443 444; HImode or SImode for sign extended fusion ops 445(define_mode_iterator HSI [HI SI]) 446 447; SImode or DImode, even if DImode doesn't fit in GPRs. 448(define_mode_iterator SDI [SI DI]) 449 450; The size of a pointer. Also, the size of the value that a record-condition 451; (one with a '.') will compare; and the size used for arithmetic carries. 452(define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")]) 453 454; Iterator to add PTImode along with TImode (TImode can go in VSX registers, 455; PTImode is GPR only) 456(define_mode_iterator TI2 [TI PTI]) 457 458; Any hardware-supported floating-point mode 459(define_mode_iterator FP [ 460 (SF "TARGET_HARD_FLOAT") 461 (DF "TARGET_HARD_FLOAT") 462 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128") 463 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128") 464 (KF "TARGET_FLOAT128_TYPE") 465 (DD "TARGET_DFP") 466 (TD "TARGET_DFP")]) 467 468; Any fma capable floating-point mode. 469(define_mode_iterator FMA_F [ 470 (SF "TARGET_HARD_FLOAT") 471 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)") 472 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)") 473 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)") 474 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)") 475 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)") 476 ]) 477 478; Floating point move iterators to combine binary and decimal moves 479(define_mode_iterator FMOVE32 [SF SD]) 480(define_mode_iterator FMOVE64 [DF DD]) 481(define_mode_iterator FMOVE64X [DI DF DD]) 482(define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128") 483 (IF "FLOAT128_IBM_P (IFmode)") 484 (TD "TARGET_HARD_FLOAT")]) 485 486(define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)") 487 (IF "FLOAT128_2REG_P (IFmode)") 488 (TD "TARGET_HARD_FLOAT")]) 489 490; Iterators for 128 bit types for direct move 491(define_mode_iterator FMOVE128_GPR [TI 492 V16QI 493 V8HI 494 V4SI 495 V4SF 496 V2DI 497 V2DF 498 V1TI 499 (KF "FLOAT128_VECTOR_P (KFmode)") 500 (TF "FLOAT128_VECTOR_P (TFmode)")]) 501 502; Iterator for 128-bit VSX types for pack/unpack 503(define_mode_iterator FMOVE128_VSX [V1TI KF]) 504 505; Iterators for converting to/from TFmode 506(define_mode_iterator IFKF [IF KF]) 507 508; Constraints for moving IF/KFmode. 509(define_mode_attr IFKF_reg [(IF "d") (KF "wa")]) 510 511; Whether a floating point move is ok, don't allow SD without hardware FP 512(define_mode_attr fmove_ok [(SF "") 513 (DF "") 514 (SD "TARGET_HARD_FLOAT") 515 (DD "")]) 516 517; Convert REAL_VALUE to the appropriate bits 518(define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE") 519 (DF "REAL_VALUE_TO_TARGET_DOUBLE") 520 (SD "REAL_VALUE_TO_TARGET_DECIMAL32") 521 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")]) 522 523; Whether 0.0 has an all-zero bit pattern 524(define_mode_attr zero_fp [(SF "j") 525 (DF "j") 526 (TF "j") 527 (IF "j") 528 (KF "j") 529 (SD "wn") 530 (DD "wn") 531 (TD "wn")]) 532 533; Definitions for 64-bit VSX 534(define_mode_attr f64_vsx [(DF "wa") (DD "wn")]) 535 536; Definitions for 64-bit direct move 537(define_mode_attr f64_dm [(DF "wa") (DD "d")]) 538 539; Definitions for 64-bit use of altivec registers 540(define_mode_attr f64_av [(DF "v") (DD "wn")]) 541 542; Definitions for 64-bit access to ISA 3.0 (power9) vector 543(define_mode_attr f64_p9 [(DF "v") (DD "wn")]) 544 545; These modes do not fit in integer registers in 32-bit mode. 546(define_mode_iterator DIFD [DI DF DD]) 547 548; Iterator for reciprocal estimate instructions 549(define_mode_iterator RECIPF [SF DF V4SF V2DF]) 550 551; SFmode or DFmode. 552(define_mode_iterator SFDF [SF DF]) 553 554; And again, for when we need two FP modes in a pattern. 555(define_mode_iterator SFDF2 [SF DF]) 556 557; A generic s/d attribute, for sp/dp for example. 558(define_mode_attr sd [(SF "s") (DF "d") 559 (V4SF "s") (V2DF "d")]) 560 561; "s" or nothing, for fmuls/fmul for example. 562(define_mode_attr s [(SF "s") (DF "")]) 563 564; Iterator for 128-bit floating point that uses the IBM double-double format 565(define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)") 566 (TF "FLOAT128_IBM_P (TFmode)")]) 567 568; Iterator for 128-bit floating point that uses IEEE 128-bit float 569(define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)") 570 (TF "FLOAT128_IEEE_P (TFmode)")]) 571 572; Iterator for 128-bit floating point 573(define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE") 574 (IF "TARGET_FLOAT128_TYPE") 575 (TF "TARGET_LONG_DOUBLE_128")]) 576 577; Iterator for signbit on 64-bit machines with direct move 578(define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)") 579 (TF "FLOAT128_VECTOR_P (TFmode)")]) 580 581; Iterator for ISA 3.0 supported floating point types 582(define_mode_iterator FP_ISA3 [SF DF]) 583 584; SF/DF constraint for arithmetic on traditional floating point registers 585(define_mode_attr Ff [(SF "f") (DF "d") (DI "d")]) 586 587; SF/DF constraint for arithmetic on VSX registers using instructions added in 588; ISA 2.06 (power7). This includes instructions that normally target DF mode, 589; but are used on SFmode, since internally SFmode values are kept in the DFmode 590; format. 591(define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")]) 592 593; Which isa is needed for those float instructions? 594(define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")]) 595 596; FRE/FRES support 597(define_mode_attr FFRE [(SF "FRES") (DF "FRE")]) 598 599; Conditional returns. 600(define_code_iterator any_return [return simple_return]) 601(define_code_attr return_pred [(return "direct_return ()") 602 (simple_return "1")]) 603(define_code_attr return_str [(return "") (simple_return "simple_")]) 604 605; Logical operators. 606(define_code_iterator iorxor [ior xor]) 607(define_code_iterator and_ior_xor [and ior xor]) 608 609; Signed/unsigned variants of ops. 610(define_code_iterator any_extend [sign_extend zero_extend]) 611(define_code_iterator any_fix [fix unsigned_fix]) 612(define_code_iterator any_float [float unsigned_float]) 613 614(define_code_attr u [(sign_extend "") 615 (zero_extend "u") 616 (fix "") 617 (unsigned_fix "u")]) 618 619(define_code_attr su [(sign_extend "s") 620 (zero_extend "u") 621 (fix "s") 622 (unsigned_fix "u") 623 (float "s") 624 (unsigned_float "u")]) 625 626(define_code_attr az [(sign_extend "a") 627 (zero_extend "z") 628 (fix "a") 629 (unsigned_fix "z") 630 (float "a") 631 (unsigned_float "z")]) 632 633(define_code_attr uns [(fix "") 634 (unsigned_fix "uns") 635 (float "") 636 (unsigned_float "uns")]) 637 638; Various instructions that come in SI and DI forms. 639; A generic w/d attribute, for things like cmpw/cmpd. 640(define_mode_attr wd [(QI "b") 641 (HI "h") 642 (SI "w") 643 (DI "d") 644 (V16QI "b") 645 (V8HI "h") 646 (V4SI "w") 647 (V2DI "d") 648 (V1TI "q") 649 (TI "q")]) 650 651;; How many bits in this mode? 652(define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64") 653 (SF "32") (DF "64")]) 654 655; DImode bits 656(define_mode_attr dbits [(QI "56") (HI "48") (SI "32")]) 657 658;; Bitmask for shift instructions 659(define_mode_attr hH [(SI "h") (DI "H")]) 660 661;; A mode twice the size of the given mode 662(define_mode_attr dmode [(SI "di") (DI "ti")]) 663(define_mode_attr DMODE [(SI "DI") (DI "TI")]) 664 665;; Suffix for reload patterns 666(define_mode_attr ptrsize [(SI "32bit") 667 (DI "64bit")]) 668 669(define_mode_attr tptrsize [(SI "TARGET_32BIT") 670 (DI "TARGET_64BIT")]) 671 672(define_mode_attr mptrsize [(SI "si") 673 (DI "di")]) 674 675(define_mode_attr ptrload [(SI "lwz") 676 (DI "ld")]) 677 678(define_mode_attr ptrm [(SI "m") 679 (DI "Y")]) 680 681(define_mode_attr rreg [(SF "f") 682 (DF "wa") 683 (TF "f") 684 (TD "f") 685 (V4SF "wa") 686 (V2DF "wa")]) 687 688(define_mode_attr rreg2 [(SF "f") 689 (DF "d")]) 690 691(define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS") 692 (DF "TARGET_FCFID")]) 693 694;; Mode iterator for logical operations on 128-bit types 695(define_mode_iterator BOOL_128 [TI 696 PTI 697 (V16QI "TARGET_ALTIVEC") 698 (V8HI "TARGET_ALTIVEC") 699 (V4SI "TARGET_ALTIVEC") 700 (V4SF "TARGET_ALTIVEC") 701 (V2DI "TARGET_ALTIVEC") 702 (V2DF "TARGET_ALTIVEC") 703 (V1TI "TARGET_ALTIVEC")]) 704 705;; For the GPRs we use 3 constraints for register outputs, two that are the 706;; same as the output register, and a third where the output register is an 707;; early clobber, so we don't have to deal with register overlaps. For the 708;; vector types, we prefer to use the vector registers. For TI mode, allow 709;; either. 710 711;; Mode attribute for boolean operation register constraints for output 712(define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v") 713 (PTI "&r,r,r") 714 (V16QI "wa,v,&?r,?r,?r") 715 (V8HI "wa,v,&?r,?r,?r") 716 (V4SI "wa,v,&?r,?r,?r") 717 (V4SF "wa,v,&?r,?r,?r") 718 (V2DI "wa,v,&?r,?r,?r") 719 (V2DF "wa,v,&?r,?r,?r") 720 (V1TI "wa,v,&?r,?r,?r")]) 721 722;; Mode attribute for boolean operation register constraints for operand1 723(define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v") 724 (PTI "r,0,r") 725 (V16QI "wa,v,r,0,r") 726 (V8HI "wa,v,r,0,r") 727 (V4SI "wa,v,r,0,r") 728 (V4SF "wa,v,r,0,r") 729 (V2DI "wa,v,r,0,r") 730 (V2DF "wa,v,r,0,r") 731 (V1TI "wa,v,r,0,r")]) 732 733;; Mode attribute for boolean operation register constraints for operand2 734(define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v") 735 (PTI "r,r,0") 736 (V16QI "wa,v,r,r,0") 737 (V8HI "wa,v,r,r,0") 738 (V4SI "wa,v,r,r,0") 739 (V4SF "wa,v,r,r,0") 740 (V2DI "wa,v,r,r,0") 741 (V2DF "wa,v,r,r,0") 742 (V1TI "wa,v,r,r,0")]) 743 744;; Mode attribute for boolean operation register constraints for operand1 745;; for one_cmpl. To simplify things, we repeat the constraint where 0 746;; is used for operand1 or operand2 747(define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v") 748 (PTI "r,0,0") 749 (V16QI "wa,v,r,0,0") 750 (V8HI "wa,v,r,0,0") 751 (V4SI "wa,v,r,0,0") 752 (V4SF "wa,v,r,0,0") 753 (V2DI "wa,v,r,0,0") 754 (V2DF "wa,v,r,0,0") 755 (V1TI "wa,v,r,0,0")]) 756 757;; Reload iterator for creating the function to allocate a base register to 758;; supplement addressing modes. 759(define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI 760 SF SD SI DF DD DI TI PTI KF IF TF 761 POI PXI]) 762 763;; Iterate over smin, smax 764(define_code_iterator fp_minmax [smin smax]) 765 766(define_code_attr minmax [(smin "min") 767 (smax "max")]) 768 769(define_code_attr SMINMAX [(smin "SMIN") 770 (smax "SMAX")]) 771 772;; Iterator to optimize the following cases: 773;; D-form load to FPR register & move to Altivec register 774;; Move Altivec register to FPR register and store 775(define_mode_iterator ALTIVEC_DFORM [DF 776 (SF "TARGET_P8_VECTOR") 777 (DI "TARGET_POWERPC64")]) 778 779(include "darwin.md") 780 781;; Start with fixed-point load and store insns. Here we put only the more 782;; complex forms. Basic data transfer is done later. 783 784(define_insn "zero_extendqi<mode>2" 785 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,wa,^v") 786 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,?Z,v")))] 787 "" 788 "@ 789 lbz%U1%X1 %0,%1 790 rlwinm %0,%1,0,0xff 791 lxsibzx %x0,%y1 792 vextractub %0,%1,7" 793 [(set_attr "type" "load,shift,fpload,vecperm") 794 (set_attr "isa" "*,*,p9v,p9v")]) 795 796(define_insn_and_split "*zero_extendqi<mode>2_dot" 797 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 798 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 799 (const_int 0))) 800 (clobber (match_scratch:EXTQI 0 "=r,r"))] 801 "" 802 "@ 803 andi. %0,%1,0xff 804 #" 805 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 806 [(set (match_dup 0) 807 (zero_extend:EXTQI (match_dup 1))) 808 (set (match_dup 2) 809 (compare:CC (match_dup 0) 810 (const_int 0)))] 811 "" 812 [(set_attr "type" "logical") 813 (set_attr "dot" "yes") 814 (set_attr "length" "4,8")]) 815 816(define_insn_and_split "*zero_extendqi<mode>2_dot2" 817 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 818 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 819 (const_int 0))) 820 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 821 (zero_extend:EXTQI (match_dup 1)))] 822 "" 823 "@ 824 andi. %0,%1,0xff 825 #" 826 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 827 [(set (match_dup 0) 828 (zero_extend:EXTQI (match_dup 1))) 829 (set (match_dup 2) 830 (compare:CC (match_dup 0) 831 (const_int 0)))] 832 "" 833 [(set_attr "type" "logical") 834 (set_attr "dot" "yes") 835 (set_attr "length" "4,8")]) 836 837 838(define_insn "zero_extendhi<mode>2" 839 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,wa,^v") 840 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,?Z,v")))] 841 "" 842 "@ 843 lhz%U1%X1 %0,%1 844 rlwinm %0,%1,0,0xffff 845 lxsihzx %x0,%y1 846 vextractuh %0,%1,6" 847 [(set_attr "type" "load,shift,fpload,vecperm") 848 (set_attr "isa" "*,*,p9v,p9v")]) 849 850(define_insn_and_split "*zero_extendhi<mode>2_dot" 851 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 852 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 853 (const_int 0))) 854 (clobber (match_scratch:EXTHI 0 "=r,r"))] 855 "" 856 "@ 857 andi. %0,%1,0xffff 858 #" 859 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 860 [(set (match_dup 0) 861 (zero_extend:EXTHI (match_dup 1))) 862 (set (match_dup 2) 863 (compare:CC (match_dup 0) 864 (const_int 0)))] 865 "" 866 [(set_attr "type" "logical") 867 (set_attr "dot" "yes") 868 (set_attr "length" "4,8")]) 869 870(define_insn_and_split "*zero_extendhi<mode>2_dot2" 871 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 872 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 873 (const_int 0))) 874 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 875 (zero_extend:EXTHI (match_dup 1)))] 876 "" 877 "@ 878 andi. %0,%1,0xffff 879 #" 880 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 881 [(set (match_dup 0) 882 (zero_extend:EXTHI (match_dup 1))) 883 (set (match_dup 2) 884 (compare:CC (match_dup 0) 885 (const_int 0)))] 886 "" 887 [(set_attr "type" "logical") 888 (set_attr "dot" "yes") 889 (set_attr "length" "4,8")]) 890 891 892(define_insn "zero_extendsi<mode>2" 893 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa") 894 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,?Z,?Z,r,wa,wa")))] 895 "" 896 "@ 897 lwz%U1%X1 %0,%1 898 rldicl %0,%1,0,32 899 lfiwzx %0,%y1 900 lxsiwzx %x0,%y1 901 mtvsrwz %x0,%1 902 mfvsrwz %0,%x1 903 xxextractuw %x0,%x1,4" 904 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts") 905 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")]) 906 907(define_insn_and_split "*zero_extendsi<mode>2_dot" 908 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 909 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 910 (const_int 0))) 911 (clobber (match_scratch:EXTSI 0 "=r,r"))] 912 "" 913 "@ 914 rldicl. %0,%1,0,32 915 #" 916 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 917 [(set (match_dup 0) 918 (zero_extend:DI (match_dup 1))) 919 (set (match_dup 2) 920 (compare:CC (match_dup 0) 921 (const_int 0)))] 922 "" 923 [(set_attr "type" "shift") 924 (set_attr "dot" "yes") 925 (set_attr "length" "4,8")]) 926 927(define_insn_and_split "*zero_extendsi<mode>2_dot2" 928 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 929 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 930 (const_int 0))) 931 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") 932 (zero_extend:EXTSI (match_dup 1)))] 933 "" 934 "@ 935 rldicl. %0,%1,0,32 936 #" 937 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 938 [(set (match_dup 0) 939 (zero_extend:EXTSI (match_dup 1))) 940 (set (match_dup 2) 941 (compare:CC (match_dup 0) 942 (const_int 0)))] 943 "" 944 [(set_attr "type" "shift") 945 (set_attr "dot" "yes") 946 (set_attr "length" "4,8")]) 947 948 949(define_insn "extendqi<mode>2" 950 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v") 951 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))] 952 "" 953 "@ 954 extsb %0,%1 955 vextsb2d %0,%1" 956 [(set_attr "type" "exts,vecperm") 957 (set_attr "isa" "*,p9v")]) 958 959(define_insn_and_split "*extendqi<mode>2_dot" 960 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 961 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 962 (const_int 0))) 963 (clobber (match_scratch:EXTQI 0 "=r,r"))] 964 "" 965 "@ 966 extsb. %0,%1 967 #" 968 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 969 [(set (match_dup 0) 970 (sign_extend:EXTQI (match_dup 1))) 971 (set (match_dup 2) 972 (compare:CC (match_dup 0) 973 (const_int 0)))] 974 "" 975 [(set_attr "type" "exts") 976 (set_attr "dot" "yes") 977 (set_attr "length" "4,8")]) 978 979(define_insn_and_split "*extendqi<mode>2_dot2" 980 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 981 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r")) 982 (const_int 0))) 983 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r") 984 (sign_extend:EXTQI (match_dup 1)))] 985 "" 986 "@ 987 extsb. %0,%1 988 #" 989 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 990 [(set (match_dup 0) 991 (sign_extend:EXTQI (match_dup 1))) 992 (set (match_dup 2) 993 (compare:CC (match_dup 0) 994 (const_int 0)))] 995 "" 996 [(set_attr "type" "exts") 997 (set_attr "dot" "yes") 998 (set_attr "length" "4,8")]) 999 1000 1001(define_expand "extendhi<mode>2" 1002 [(set (match_operand:EXTHI 0 "gpc_reg_operand") 1003 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))] 1004 "" 1005 "") 1006 1007(define_insn "*extendhi<mode>2" 1008 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v") 1009 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))] 1010 "" 1011 "@ 1012 lha%U1%X1 %0,%1 1013 extsh %0,%1 1014 # 1015 vextsh2d %0,%1" 1016 [(set_attr "type" "load,exts,fpload,vecperm") 1017 (set_attr "sign_extend" "yes") 1018 (set_attr "length" "*,*,8,*") 1019 (set_attr "isa" "*,*,p9v,p9v")]) 1020 1021(define_split 1022 [(set (match_operand:EXTHI 0 "altivec_register_operand") 1023 (sign_extend:EXTHI 1024 (match_operand:HI 1 "indexed_or_indirect_operand")))] 1025 "TARGET_P9_VECTOR && reload_completed" 1026 [(set (match_dup 2) 1027 (match_dup 1)) 1028 (set (match_dup 0) 1029 (sign_extend:EXTHI (match_dup 2)))] 1030{ 1031 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0])); 1032}) 1033 1034(define_insn_and_split "*extendhi<mode>2_dot" 1035 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1036 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 1037 (const_int 0))) 1038 (clobber (match_scratch:EXTHI 0 "=r,r"))] 1039 "" 1040 "@ 1041 extsh. %0,%1 1042 #" 1043 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1044 [(set (match_dup 0) 1045 (sign_extend:EXTHI (match_dup 1))) 1046 (set (match_dup 2) 1047 (compare:CC (match_dup 0) 1048 (const_int 0)))] 1049 "" 1050 [(set_attr "type" "exts") 1051 (set_attr "dot" "yes") 1052 (set_attr "length" "4,8")]) 1053 1054(define_insn_and_split "*extendhi<mode>2_dot2" 1055 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1056 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r")) 1057 (const_int 0))) 1058 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r") 1059 (sign_extend:EXTHI (match_dup 1)))] 1060 "" 1061 "@ 1062 extsh. %0,%1 1063 #" 1064 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1065 [(set (match_dup 0) 1066 (sign_extend:EXTHI (match_dup 1))) 1067 (set (match_dup 2) 1068 (compare:CC (match_dup 0) 1069 (const_int 0)))] 1070 "" 1071 [(set_attr "type" "exts") 1072 (set_attr "dot" "yes") 1073 (set_attr "length" "4,8")]) 1074 1075 1076(define_insn "extendsi<mode>2" 1077 [(set (match_operand:EXTSI 0 "gpc_reg_operand" 1078 "=r, r, d, wa, wa, v, v, wr") 1079 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand" 1080 "YZ, r, Z, Z, r, v, v, ?wa")))] 1081 "" 1082 "@ 1083 lwa%U1%X1 %0,%1 1084 extsw %0,%1 1085 lfiwax %0,%y1 1086 lxsiwax %x0,%y1 1087 mtvsrwa %x0,%1 1088 vextsw2d %0,%1 1089 # 1090 #" 1091 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr") 1092 (set_attr "sign_extend" "yes") 1093 (set_attr "length" "*,*,*,*,*,*,8,8") 1094 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")]) 1095 1096(define_split 1097 [(set (match_operand:EXTSI 0 "int_reg_operand") 1098 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))] 1099 "TARGET_DIRECT_MOVE_64BIT && reload_completed" 1100 [(set (match_dup 2) 1101 (match_dup 1)) 1102 (set (match_dup 0) 1103 (sign_extend:DI (match_dup 2)))] 1104{ 1105 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0])); 1106}) 1107 1108(define_split 1109 [(set (match_operand:DI 0 "altivec_register_operand") 1110 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))] 1111 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed" 1112 [(const_int 0)] 1113{ 1114 rtx dest = operands[0]; 1115 rtx src = operands[1]; 1116 int dest_regno = REGNO (dest); 1117 int src_regno = REGNO (src); 1118 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno); 1119 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno); 1120 1121 if (BYTES_BIG_ENDIAN) 1122 { 1123 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si)); 1124 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx)); 1125 } 1126 else 1127 { 1128 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si)); 1129 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx)); 1130 } 1131 DONE; 1132}) 1133 1134(define_insn_and_split "*extendsi<mode>2_dot" 1135 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1136 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 1137 (const_int 0))) 1138 (clobber (match_scratch:EXTSI 0 "=r,r"))] 1139 "" 1140 "@ 1141 extsw. %0,%1 1142 #" 1143 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1144 [(set (match_dup 0) 1145 (sign_extend:EXTSI (match_dup 1))) 1146 (set (match_dup 2) 1147 (compare:CC (match_dup 0) 1148 (const_int 0)))] 1149 "" 1150 [(set_attr "type" "exts") 1151 (set_attr "dot" "yes") 1152 (set_attr "length" "4,8")]) 1153 1154(define_insn_and_split "*extendsi<mode>2_dot2" 1155 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 1156 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r")) 1157 (const_int 0))) 1158 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r") 1159 (sign_extend:EXTSI (match_dup 1)))] 1160 "" 1161 "@ 1162 extsw. %0,%1 1163 #" 1164 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 1165 [(set (match_dup 0) 1166 (sign_extend:EXTSI (match_dup 1))) 1167 (set (match_dup 2) 1168 (compare:CC (match_dup 0) 1169 (const_int 0)))] 1170 "" 1171 [(set_attr "type" "exts") 1172 (set_attr "dot" "yes") 1173 (set_attr "length" "4,8")]) 1174 1175;; IBM 405, 440, 464 and 476 half-word multiplication operations. 1176 1177(define_insn "*macchwc" 1178 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1179 (compare:CC (plus:SI (mult:SI (ashiftrt:SI 1180 (match_operand:SI 2 "gpc_reg_operand" "r") 1181 (const_int 16)) 1182 (sign_extend:SI 1183 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1184 (match_operand:SI 4 "gpc_reg_operand" "0")) 1185 (const_int 0))) 1186 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1187 (plus:SI (mult:SI (ashiftrt:SI 1188 (match_dup 2) 1189 (const_int 16)) 1190 (sign_extend:SI 1191 (match_dup 1))) 1192 (match_dup 4)))] 1193 "TARGET_MULHW" 1194 "macchw. %0,%1,%2" 1195 [(set_attr "type" "halfmul")]) 1196 1197(define_insn "*macchw" 1198 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1199 (plus:SI (mult:SI (ashiftrt:SI 1200 (match_operand:SI 2 "gpc_reg_operand" "r") 1201 (const_int 16)) 1202 (sign_extend:SI 1203 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1204 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1205 "TARGET_MULHW" 1206 "macchw %0,%1,%2" 1207 [(set_attr "type" "halfmul")]) 1208 1209(define_insn "*macchwuc" 1210 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1211 (compare:CC (plus:SI (mult:SI (lshiftrt:SI 1212 (match_operand:SI 2 "gpc_reg_operand" "r") 1213 (const_int 16)) 1214 (zero_extend:SI 1215 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1216 (match_operand:SI 4 "gpc_reg_operand" "0")) 1217 (const_int 0))) 1218 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1219 (plus:SI (mult:SI (lshiftrt:SI 1220 (match_dup 2) 1221 (const_int 16)) 1222 (zero_extend:SI 1223 (match_dup 1))) 1224 (match_dup 4)))] 1225 "TARGET_MULHW" 1226 "macchwu. %0,%1,%2" 1227 [(set_attr "type" "halfmul")]) 1228 1229(define_insn "*macchwu" 1230 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1231 (plus:SI (mult:SI (lshiftrt:SI 1232 (match_operand:SI 2 "gpc_reg_operand" "r") 1233 (const_int 16)) 1234 (zero_extend:SI 1235 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1236 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1237 "TARGET_MULHW" 1238 "macchwu %0,%1,%2" 1239 [(set_attr "type" "halfmul")]) 1240 1241(define_insn "*machhwc" 1242 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1243 (compare:CC (plus:SI (mult:SI (ashiftrt:SI 1244 (match_operand:SI 1 "gpc_reg_operand" "%r") 1245 (const_int 16)) 1246 (ashiftrt:SI 1247 (match_operand:SI 2 "gpc_reg_operand" "r") 1248 (const_int 16))) 1249 (match_operand:SI 4 "gpc_reg_operand" "0")) 1250 (const_int 0))) 1251 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1252 (plus:SI (mult:SI (ashiftrt:SI 1253 (match_dup 1) 1254 (const_int 16)) 1255 (ashiftrt:SI 1256 (match_dup 2) 1257 (const_int 16))) 1258 (match_dup 4)))] 1259 "TARGET_MULHW" 1260 "machhw. %0,%1,%2" 1261 [(set_attr "type" "halfmul")]) 1262 1263(define_insn "*machhw" 1264 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1265 (plus:SI (mult:SI (ashiftrt:SI 1266 (match_operand:SI 1 "gpc_reg_operand" "%r") 1267 (const_int 16)) 1268 (ashiftrt:SI 1269 (match_operand:SI 2 "gpc_reg_operand" "r") 1270 (const_int 16))) 1271 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1272 "TARGET_MULHW" 1273 "machhw %0,%1,%2" 1274 [(set_attr "type" "halfmul")]) 1275 1276(define_insn "*machhwuc" 1277 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1278 (compare:CC (plus:SI (mult:SI (lshiftrt:SI 1279 (match_operand:SI 1 "gpc_reg_operand" "%r") 1280 (const_int 16)) 1281 (lshiftrt:SI 1282 (match_operand:SI 2 "gpc_reg_operand" "r") 1283 (const_int 16))) 1284 (match_operand:SI 4 "gpc_reg_operand" "0")) 1285 (const_int 0))) 1286 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1287 (plus:SI (mult:SI (lshiftrt:SI 1288 (match_dup 1) 1289 (const_int 16)) 1290 (lshiftrt:SI 1291 (match_dup 2) 1292 (const_int 16))) 1293 (match_dup 4)))] 1294 "TARGET_MULHW" 1295 "machhwu. %0,%1,%2" 1296 [(set_attr "type" "halfmul")]) 1297 1298(define_insn "*machhwu" 1299 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1300 (plus:SI (mult:SI (lshiftrt:SI 1301 (match_operand:SI 1 "gpc_reg_operand" "%r") 1302 (const_int 16)) 1303 (lshiftrt:SI 1304 (match_operand:SI 2 "gpc_reg_operand" "r") 1305 (const_int 16))) 1306 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1307 "TARGET_MULHW" 1308 "machhwu %0,%1,%2" 1309 [(set_attr "type" "halfmul")]) 1310 1311(define_insn "*maclhwc" 1312 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1313 (compare:CC (plus:SI (mult:SI (sign_extend:SI 1314 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1315 (sign_extend:SI 1316 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1317 (match_operand:SI 4 "gpc_reg_operand" "0")) 1318 (const_int 0))) 1319 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1320 (plus:SI (mult:SI (sign_extend:SI 1321 (match_dup 1)) 1322 (sign_extend:SI 1323 (match_dup 2))) 1324 (match_dup 4)))] 1325 "TARGET_MULHW" 1326 "maclhw. %0,%1,%2" 1327 [(set_attr "type" "halfmul")]) 1328 1329(define_insn "*maclhw" 1330 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1331 (plus:SI (mult:SI (sign_extend:SI 1332 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1333 (sign_extend:SI 1334 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1335 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1336 "TARGET_MULHW" 1337 "maclhw %0,%1,%2" 1338 [(set_attr "type" "halfmul")]) 1339 1340(define_insn "*maclhwuc" 1341 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1342 (compare:CC (plus:SI (mult:SI (zero_extend:SI 1343 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1344 (zero_extend:SI 1345 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1346 (match_operand:SI 4 "gpc_reg_operand" "0")) 1347 (const_int 0))) 1348 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1349 (plus:SI (mult:SI (zero_extend:SI 1350 (match_dup 1)) 1351 (zero_extend:SI 1352 (match_dup 2))) 1353 (match_dup 4)))] 1354 "TARGET_MULHW" 1355 "maclhwu. %0,%1,%2" 1356 [(set_attr "type" "halfmul")]) 1357 1358(define_insn "*maclhwu" 1359 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1360 (plus:SI (mult:SI (zero_extend:SI 1361 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1362 (zero_extend:SI 1363 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1364 (match_operand:SI 3 "gpc_reg_operand" "0")))] 1365 "TARGET_MULHW" 1366 "maclhwu %0,%1,%2" 1367 [(set_attr "type" "halfmul")]) 1368 1369(define_insn "*nmacchwc" 1370 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1371 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1372 (mult:SI (ashiftrt:SI 1373 (match_operand:SI 2 "gpc_reg_operand" "r") 1374 (const_int 16)) 1375 (sign_extend:SI 1376 (match_operand:HI 1 "gpc_reg_operand" "r")))) 1377 (const_int 0))) 1378 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1379 (minus:SI (match_dup 4) 1380 (mult:SI (ashiftrt:SI 1381 (match_dup 2) 1382 (const_int 16)) 1383 (sign_extend:SI 1384 (match_dup 1)))))] 1385 "TARGET_MULHW" 1386 "nmacchw. %0,%1,%2" 1387 [(set_attr "type" "halfmul")]) 1388 1389(define_insn "*nmacchw" 1390 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1391 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1392 (mult:SI (ashiftrt:SI 1393 (match_operand:SI 2 "gpc_reg_operand" "r") 1394 (const_int 16)) 1395 (sign_extend:SI 1396 (match_operand:HI 1 "gpc_reg_operand" "r")))))] 1397 "TARGET_MULHW" 1398 "nmacchw %0,%1,%2" 1399 [(set_attr "type" "halfmul")]) 1400 1401(define_insn "*nmachhwc" 1402 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1403 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1404 (mult:SI (ashiftrt:SI 1405 (match_operand:SI 1 "gpc_reg_operand" "%r") 1406 (const_int 16)) 1407 (ashiftrt:SI 1408 (match_operand:SI 2 "gpc_reg_operand" "r") 1409 (const_int 16)))) 1410 (const_int 0))) 1411 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1412 (minus:SI (match_dup 4) 1413 (mult:SI (ashiftrt:SI 1414 (match_dup 1) 1415 (const_int 16)) 1416 (ashiftrt:SI 1417 (match_dup 2) 1418 (const_int 16)))))] 1419 "TARGET_MULHW" 1420 "nmachhw. %0,%1,%2" 1421 [(set_attr "type" "halfmul")]) 1422 1423(define_insn "*nmachhw" 1424 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1425 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1426 (mult:SI (ashiftrt:SI 1427 (match_operand:SI 1 "gpc_reg_operand" "%r") 1428 (const_int 16)) 1429 (ashiftrt:SI 1430 (match_operand:SI 2 "gpc_reg_operand" "r") 1431 (const_int 16)))))] 1432 "TARGET_MULHW" 1433 "nmachhw %0,%1,%2" 1434 [(set_attr "type" "halfmul")]) 1435 1436(define_insn "*nmaclhwc" 1437 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1438 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0") 1439 (mult:SI (sign_extend:SI 1440 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1441 (sign_extend:SI 1442 (match_operand:HI 2 "gpc_reg_operand" "r")))) 1443 (const_int 0))) 1444 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1445 (minus:SI (match_dup 4) 1446 (mult:SI (sign_extend:SI 1447 (match_dup 1)) 1448 (sign_extend:SI 1449 (match_dup 2)))))] 1450 "TARGET_MULHW" 1451 "nmaclhw. %0,%1,%2" 1452 [(set_attr "type" "halfmul")]) 1453 1454(define_insn "*nmaclhw" 1455 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1456 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0") 1457 (mult:SI (sign_extend:SI 1458 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1459 (sign_extend:SI 1460 (match_operand:HI 2 "gpc_reg_operand" "r")))))] 1461 "TARGET_MULHW" 1462 "nmaclhw %0,%1,%2" 1463 [(set_attr "type" "halfmul")]) 1464 1465(define_insn "*mulchwc" 1466 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1467 (compare:CC (mult:SI (ashiftrt:SI 1468 (match_operand:SI 2 "gpc_reg_operand" "r") 1469 (const_int 16)) 1470 (sign_extend:SI 1471 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1472 (const_int 0))) 1473 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1474 (mult:SI (ashiftrt:SI 1475 (match_dup 2) 1476 (const_int 16)) 1477 (sign_extend:SI 1478 (match_dup 1))))] 1479 "TARGET_MULHW" 1480 "mulchw. %0,%1,%2" 1481 [(set_attr "type" "halfmul")]) 1482 1483(define_insn "*mulchw" 1484 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1485 (mult:SI (ashiftrt:SI 1486 (match_operand:SI 2 "gpc_reg_operand" "r") 1487 (const_int 16)) 1488 (sign_extend:SI 1489 (match_operand:HI 1 "gpc_reg_operand" "r"))))] 1490 "TARGET_MULHW" 1491 "mulchw %0,%1,%2" 1492 [(set_attr "type" "halfmul")]) 1493 1494(define_insn "*mulchwuc" 1495 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1496 (compare:CC (mult:SI (lshiftrt:SI 1497 (match_operand:SI 2 "gpc_reg_operand" "r") 1498 (const_int 16)) 1499 (zero_extend:SI 1500 (match_operand:HI 1 "gpc_reg_operand" "r"))) 1501 (const_int 0))) 1502 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1503 (mult:SI (lshiftrt:SI 1504 (match_dup 2) 1505 (const_int 16)) 1506 (zero_extend:SI 1507 (match_dup 1))))] 1508 "TARGET_MULHW" 1509 "mulchwu. %0,%1,%2" 1510 [(set_attr "type" "halfmul")]) 1511 1512(define_insn "*mulchwu" 1513 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1514 (mult:SI (lshiftrt:SI 1515 (match_operand:SI 2 "gpc_reg_operand" "r") 1516 (const_int 16)) 1517 (zero_extend:SI 1518 (match_operand:HI 1 "gpc_reg_operand" "r"))))] 1519 "TARGET_MULHW" 1520 "mulchwu %0,%1,%2" 1521 [(set_attr "type" "halfmul")]) 1522 1523(define_insn "*mulhhwc" 1524 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1525 (compare:CC (mult:SI (ashiftrt:SI 1526 (match_operand:SI 1 "gpc_reg_operand" "%r") 1527 (const_int 16)) 1528 (ashiftrt:SI 1529 (match_operand:SI 2 "gpc_reg_operand" "r") 1530 (const_int 16))) 1531 (const_int 0))) 1532 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1533 (mult:SI (ashiftrt:SI 1534 (match_dup 1) 1535 (const_int 16)) 1536 (ashiftrt:SI 1537 (match_dup 2) 1538 (const_int 16))))] 1539 "TARGET_MULHW" 1540 "mulhhw. %0,%1,%2" 1541 [(set_attr "type" "halfmul")]) 1542 1543(define_insn "*mulhhw" 1544 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1545 (mult:SI (ashiftrt:SI 1546 (match_operand:SI 1 "gpc_reg_operand" "%r") 1547 (const_int 16)) 1548 (ashiftrt:SI 1549 (match_operand:SI 2 "gpc_reg_operand" "r") 1550 (const_int 16))))] 1551 "TARGET_MULHW" 1552 "mulhhw %0,%1,%2" 1553 [(set_attr "type" "halfmul")]) 1554 1555(define_insn "*mulhhwuc" 1556 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1557 (compare:CC (mult:SI (lshiftrt:SI 1558 (match_operand:SI 1 "gpc_reg_operand" "%r") 1559 (const_int 16)) 1560 (lshiftrt:SI 1561 (match_operand:SI 2 "gpc_reg_operand" "r") 1562 (const_int 16))) 1563 (const_int 0))) 1564 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1565 (mult:SI (lshiftrt:SI 1566 (match_dup 1) 1567 (const_int 16)) 1568 (lshiftrt:SI 1569 (match_dup 2) 1570 (const_int 16))))] 1571 "TARGET_MULHW" 1572 "mulhhwu. %0,%1,%2" 1573 [(set_attr "type" "halfmul")]) 1574 1575(define_insn "*mulhhwu" 1576 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1577 (mult:SI (lshiftrt:SI 1578 (match_operand:SI 1 "gpc_reg_operand" "%r") 1579 (const_int 16)) 1580 (lshiftrt:SI 1581 (match_operand:SI 2 "gpc_reg_operand" "r") 1582 (const_int 16))))] 1583 "TARGET_MULHW" 1584 "mulhhwu %0,%1,%2" 1585 [(set_attr "type" "halfmul")]) 1586 1587(define_insn "*mullhwc" 1588 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1589 (compare:CC (mult:SI (sign_extend:SI 1590 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1591 (sign_extend:SI 1592 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1593 (const_int 0))) 1594 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1595 (mult:SI (sign_extend:SI 1596 (match_dup 1)) 1597 (sign_extend:SI 1598 (match_dup 2))))] 1599 "TARGET_MULHW" 1600 "mullhw. %0,%1,%2" 1601 [(set_attr "type" "halfmul")]) 1602 1603(define_insn "*mullhw" 1604 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1605 (mult:SI (sign_extend:SI 1606 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1607 (sign_extend:SI 1608 (match_operand:HI 2 "gpc_reg_operand" "r"))))] 1609 "TARGET_MULHW" 1610 "mullhw %0,%1,%2" 1611 [(set_attr "type" "halfmul")]) 1612 1613(define_insn "*mullhwuc" 1614 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1615 (compare:CC (mult:SI (zero_extend:SI 1616 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1617 (zero_extend:SI 1618 (match_operand:HI 2 "gpc_reg_operand" "r"))) 1619 (const_int 0))) 1620 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1621 (mult:SI (zero_extend:SI 1622 (match_dup 1)) 1623 (zero_extend:SI 1624 (match_dup 2))))] 1625 "TARGET_MULHW" 1626 "mullhwu. %0,%1,%2" 1627 [(set_attr "type" "halfmul")]) 1628 1629(define_insn "*mullhwu" 1630 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 1631 (mult:SI (zero_extend:SI 1632 (match_operand:HI 1 "gpc_reg_operand" "%r")) 1633 (zero_extend:SI 1634 (match_operand:HI 2 "gpc_reg_operand" "r"))))] 1635 "TARGET_MULHW" 1636 "mullhwu %0,%1,%2" 1637 [(set_attr "type" "halfmul")]) 1638 1639;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support. 1640(define_insn "dlmzb" 1641 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 1642 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 1643 (match_operand:SI 2 "gpc_reg_operand" "r")] 1644 UNSPEC_DLMZB_CR)) 1645 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 1646 (unspec:SI [(match_dup 1) 1647 (match_dup 2)] 1648 UNSPEC_DLMZB))] 1649 "TARGET_DLMZB" 1650 "dlmzb. %0,%1,%2") 1651 1652(define_expand "strlensi" 1653 [(set (match_operand:SI 0 "gpc_reg_operand") 1654 (unspec:SI [(match_operand:BLK 1 "general_operand") 1655 (match_operand:QI 2 "const_int_operand") 1656 (match_operand 3 "const_int_operand")] 1657 UNSPEC_DLMZB_STRLEN)) 1658 (clobber (match_scratch:CC 4))] 1659 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size" 1660{ 1661 rtx result = operands[0]; 1662 rtx src = operands[1]; 1663 rtx search_char = operands[2]; 1664 rtx align = operands[3]; 1665 rtx addr, scratch_string, word1, word2, scratch_dlmzb; 1666 rtx loop_label, end_label, mem, cr0, cond; 1667 if (search_char != const0_rtx 1668 || !CONST_INT_P (align) 1669 || INTVAL (align) < 8) 1670 FAIL; 1671 word1 = gen_reg_rtx (SImode); 1672 word2 = gen_reg_rtx (SImode); 1673 scratch_dlmzb = gen_reg_rtx (SImode); 1674 scratch_string = gen_reg_rtx (Pmode); 1675 loop_label = gen_label_rtx (); 1676 end_label = gen_label_rtx (); 1677 addr = force_reg (Pmode, XEXP (src, 0)); 1678 emit_move_insn (scratch_string, addr); 1679 emit_label (loop_label); 1680 mem = change_address (src, SImode, scratch_string); 1681 emit_move_insn (word1, mem); 1682 emit_move_insn (word2, adjust_address (mem, SImode, 4)); 1683 cr0 = gen_rtx_REG (CCmode, CR0_REGNO); 1684 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0)); 1685 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx); 1686 emit_jump_insn (gen_rtx_SET (pc_rtx, 1687 gen_rtx_IF_THEN_ELSE (VOIDmode, 1688 cond, 1689 gen_rtx_LABEL_REF 1690 (VOIDmode, 1691 end_label), 1692 pc_rtx))); 1693 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8))); 1694 emit_jump_insn (gen_rtx_SET (pc_rtx, 1695 gen_rtx_LABEL_REF (VOIDmode, loop_label))); 1696 emit_barrier (); 1697 emit_label (end_label); 1698 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb)); 1699 emit_insn (gen_subsi3 (result, scratch_string, addr)); 1700 emit_insn (gen_addsi3 (result, result, constm1_rtx)); 1701 DONE; 1702}) 1703 1704;; Fixed-point arithmetic insns. 1705 1706(define_expand "add<mode>3" 1707 [(set (match_operand:SDI 0 "gpc_reg_operand") 1708 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand") 1709 (match_operand:SDI 2 "reg_or_add_cint_operand")))] 1710 "" 1711{ 1712 if (<MODE>mode == DImode && !TARGET_POWERPC64) 1713 { 1714 rtx lo0 = gen_lowpart (SImode, operands[0]); 1715 rtx lo1 = gen_lowpart (SImode, operands[1]); 1716 rtx lo2 = gen_lowpart (SImode, operands[2]); 1717 rtx hi0 = gen_highpart (SImode, operands[0]); 1718 rtx hi1 = gen_highpart (SImode, operands[1]); 1719 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]); 1720 1721 if (!reg_or_short_operand (lo2, SImode)) 1722 lo2 = force_reg (SImode, lo2); 1723 if (!adde_operand (hi2, SImode)) 1724 hi2 = force_reg (SImode, hi2); 1725 1726 emit_insn (gen_addsi3_carry (lo0, lo1, lo2)); 1727 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2)); 1728 DONE; 1729 } 1730 1731 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode)) 1732 { 1733 rtx tmp = ((!can_create_pseudo_p () 1734 || rtx_equal_p (operands[0], operands[1])) 1735 ? operands[0] : gen_reg_rtx (<MODE>mode)); 1736 1737 /* Adding a constant to r0 is not a valid insn, so use a different 1738 strategy in that case. */ 1739 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0) 1740 { 1741 if (operands[0] == operands[1]) 1742 FAIL; 1743 rs6000_emit_move (operands[0], operands[2], <MODE>mode); 1744 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0])); 1745 DONE; 1746 } 1747 1748 HOST_WIDE_INT val = INTVAL (operands[2]); 1749 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1750 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); 1751 1752 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest))) 1753 FAIL; 1754 1755 /* The ordering here is important for the prolog expander. 1756 When space is allocated from the stack, adding 'low' first may 1757 produce a temporary deallocation (which would be bad). */ 1758 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest))); 1759 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low))); 1760 DONE; 1761 } 1762}) 1763 1764(define_insn "*add<mode>3" 1765 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r") 1766 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b") 1767 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))] 1768 "" 1769 "@ 1770 add %0,%1,%2 1771 addi %0,%1,%2 1772 addis %0,%1,%v2 1773 addi %0,%1,%2" 1774 [(set_attr "type" "add") 1775 (set_attr "isa" "*,*,*,p10")]) 1776 1777(define_insn "*addsi3_high" 1778 [(set (match_operand:SI 0 "gpc_reg_operand" "=b") 1779 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b") 1780 (high:SI (match_operand 2 "" ""))))] 1781 "TARGET_MACHO && !TARGET_64BIT" 1782 "addis %0,%1,ha16(%2)" 1783 [(set_attr "type" "add")]) 1784 1785(define_insn_and_split "*add<mode>3_dot" 1786 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1787 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 1788 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 1789 (const_int 0))) 1790 (clobber (match_scratch:GPR 0 "=r,r"))] 1791 "<MODE>mode == Pmode" 1792 "@ 1793 add. %0,%1,%2 1794 #" 1795 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1796 [(set (match_dup 0) 1797 (plus:GPR (match_dup 1) 1798 (match_dup 2))) 1799 (set (match_dup 3) 1800 (compare:CC (match_dup 0) 1801 (const_int 0)))] 1802 "" 1803 [(set_attr "type" "add") 1804 (set_attr "dot" "yes") 1805 (set_attr "length" "4,8")]) 1806 1807(define_insn_and_split "*add<mode>3_dot2" 1808 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1809 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 1810 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 1811 (const_int 0))) 1812 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1813 (plus:GPR (match_dup 1) 1814 (match_dup 2)))] 1815 "<MODE>mode == Pmode" 1816 "@ 1817 add. %0,%1,%2 1818 #" 1819 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1820 [(set (match_dup 0) 1821 (plus:GPR (match_dup 1) 1822 (match_dup 2))) 1823 (set (match_dup 3) 1824 (compare:CC (match_dup 0) 1825 (const_int 0)))] 1826 "" 1827 [(set_attr "type" "add") 1828 (set_attr "dot" "yes") 1829 (set_attr "length" "4,8")]) 1830 1831(define_insn_and_split "*add<mode>3_imm_dot" 1832 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1833 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b") 1834 (match_operand:GPR 2 "short_cint_operand" "I,I")) 1835 (const_int 0))) 1836 (clobber (match_scratch:GPR 0 "=r,r")) 1837 (clobber (reg:GPR CA_REGNO))] 1838 "<MODE>mode == Pmode" 1839 "@ 1840 addic. %0,%1,%2 1841 #" 1842 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1843 [(set (match_dup 0) 1844 (plus:GPR (match_dup 1) 1845 (match_dup 2))) 1846 (set (match_dup 3) 1847 (compare:CC (match_dup 0) 1848 (const_int 0)))] 1849 "" 1850 [(set_attr "type" "add") 1851 (set_attr "dot" "yes") 1852 (set_attr "length" "4,8")]) 1853 1854(define_insn_and_split "*add<mode>3_imm_dot2" 1855 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 1856 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b") 1857 (match_operand:GPR 2 "short_cint_operand" "I,I")) 1858 (const_int 0))) 1859 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 1860 (plus:GPR (match_dup 1) 1861 (match_dup 2))) 1862 (clobber (reg:GPR CA_REGNO))] 1863 "<MODE>mode == Pmode" 1864 "@ 1865 addic. %0,%1,%2 1866 #" 1867 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 1868 [(set (match_dup 0) 1869 (plus:GPR (match_dup 1) 1870 (match_dup 2))) 1871 (set (match_dup 3) 1872 (compare:CC (match_dup 0) 1873 (const_int 0)))] 1874 "" 1875 [(set_attr "type" "add") 1876 (set_attr "dot" "yes") 1877 (set_attr "length" "4,8")]) 1878 1879;; Split an add that we can't do in one insn into two insns, each of which 1880;; does one 16-bit part. This is used by combine. Note that the low-order 1881;; add should be last in case the result gets used in an address. 1882 1883(define_split 1884 [(set (match_operand:GPR 0 "gpc_reg_operand") 1885 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand") 1886 (match_operand:GPR 2 "non_add_cint_operand")))] 1887 "" 1888 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3))) 1889 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))] 1890{ 1891 HOST_WIDE_INT val = INTVAL (operands[2]); 1892 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000; 1893 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode); 1894 1895 operands[4] = GEN_INT (low); 1896 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest))) 1897 operands[3] = GEN_INT (rest); 1898 else if (can_create_pseudo_p ()) 1899 { 1900 operands[3] = gen_reg_rtx (DImode); 1901 emit_move_insn (operands[3], operands[2]); 1902 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3])); 1903 DONE; 1904 } 1905 else 1906 FAIL; 1907}) 1908 1909 1910(define_insn "add<mode>3_carry" 1911 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1912 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1913 (match_operand:P 2 "reg_or_short_operand" "rI"))) 1914 (set (reg:P CA_REGNO) 1915 (ltu:P (plus:P (match_dup 1) 1916 (match_dup 2)) 1917 (match_dup 1)))] 1918 "" 1919 "add%I2c %0,%1,%2" 1920 [(set_attr "type" "add")]) 1921 1922(define_insn "*add<mode>3_imm_carry_pos" 1923 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1924 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1925 (match_operand:P 2 "short_cint_operand" "n"))) 1926 (set (reg:P CA_REGNO) 1927 (geu:P (match_dup 1) 1928 (match_operand:P 3 "const_int_operand" "n")))] 1929 "INTVAL (operands[2]) > 0 1930 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0" 1931 "addic %0,%1,%2" 1932 [(set_attr "type" "add")]) 1933 1934(define_insn "*add<mode>3_imm_carry_0" 1935 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1936 (match_operand:P 1 "gpc_reg_operand" "r")) 1937 (set (reg:P CA_REGNO) 1938 (const_int 0))] 1939 "" 1940 "addic %0,%1,0" 1941 [(set_attr "type" "add")]) 1942 1943(define_insn "*add<mode>3_imm_carry_m1" 1944 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1945 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1946 (const_int -1))) 1947 (set (reg:P CA_REGNO) 1948 (ne:P (match_dup 1) 1949 (const_int 0)))] 1950 "" 1951 "addic %0,%1,-1" 1952 [(set_attr "type" "add")]) 1953 1954(define_insn "*add<mode>3_imm_carry_neg" 1955 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 1956 (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 1957 (match_operand:P 2 "short_cint_operand" "n"))) 1958 (set (reg:P CA_REGNO) 1959 (gtu:P (match_dup 1) 1960 (match_operand:P 3 "const_int_operand" "n")))] 1961 "INTVAL (operands[2]) < 0 1962 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1" 1963 "addic %0,%1,%2" 1964 [(set_attr "type" "add")]) 1965 1966 1967(define_expand "add<mode>3_carry_in" 1968 [(parallel [ 1969 (set (match_operand:GPR 0 "gpc_reg_operand") 1970 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand") 1971 (match_operand:GPR 2 "adde_operand")) 1972 (reg:GPR CA_REGNO))) 1973 (clobber (reg:GPR CA_REGNO))])] 1974 "" 1975{ 1976 if (operands[2] == const0_rtx) 1977 { 1978 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1])); 1979 DONE; 1980 } 1981 if (operands[2] == constm1_rtx) 1982 { 1983 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1])); 1984 DONE; 1985 } 1986}) 1987 1988(define_insn "*add<mode>3_carry_in_internal" 1989 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 1990 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 1991 (match_operand:GPR 2 "gpc_reg_operand" "r")) 1992 (reg:GPR CA_REGNO))) 1993 (clobber (reg:GPR CA_REGNO))] 1994 "" 1995 "adde %0,%1,%2" 1996 [(set_attr "type" "add")]) 1997 1998(define_insn "*add<mode>3_carry_in_internal2" 1999 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2000 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 2001 (reg:GPR CA_REGNO)) 2002 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 2003 (clobber (reg:GPR CA_REGNO))] 2004 "" 2005 "adde %0,%1,%2" 2006 [(set_attr "type" "add")]) 2007 2008(define_insn "add<mode>3_carry_in_0" 2009 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2010 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 2011 (reg:GPR CA_REGNO))) 2012 (clobber (reg:GPR CA_REGNO))] 2013 "" 2014 "addze %0,%1" 2015 [(set_attr "type" "add")]) 2016 2017(define_insn "add<mode>3_carry_in_m1" 2018 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2019 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 2020 (reg:GPR CA_REGNO)) 2021 (const_int -1))) 2022 (clobber (reg:GPR CA_REGNO))] 2023 "" 2024 "addme %0,%1" 2025 [(set_attr "type" "add")]) 2026 2027 2028(define_expand "one_cmpl<mode>2" 2029 [(set (match_operand:SDI 0 "gpc_reg_operand") 2030 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))] 2031 "" 2032{ 2033 if (<MODE>mode == DImode && !TARGET_POWERPC64) 2034 { 2035 rs6000_split_logical (operands, NOT, false, false, false); 2036 DONE; 2037 } 2038}) 2039 2040(define_insn "*one_cmpl<mode>2" 2041 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2042 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2043 "" 2044 "not %0,%1") 2045 2046(define_insn_and_split "*one_cmpl<mode>2_dot" 2047 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2048 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2049 (const_int 0))) 2050 (clobber (match_scratch:GPR 0 "=r,r"))] 2051 "<MODE>mode == Pmode" 2052 "@ 2053 not. %0,%1 2054 #" 2055 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2056 [(set (match_dup 0) 2057 (not:GPR (match_dup 1))) 2058 (set (match_dup 2) 2059 (compare:CC (match_dup 0) 2060 (const_int 0)))] 2061 "" 2062 [(set_attr "type" "logical") 2063 (set_attr "dot" "yes") 2064 (set_attr "length" "4,8")]) 2065 2066(define_insn_and_split "*one_cmpl<mode>2_dot2" 2067 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2068 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2069 (const_int 0))) 2070 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2071 (not:GPR (match_dup 1)))] 2072 "<MODE>mode == Pmode" 2073 "@ 2074 not. %0,%1 2075 #" 2076 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2077 [(set (match_dup 0) 2078 (not:GPR (match_dup 1))) 2079 (set (match_dup 2) 2080 (compare:CC (match_dup 0) 2081 (const_int 0)))] 2082 "" 2083 [(set_attr "type" "logical") 2084 (set_attr "dot" "yes") 2085 (set_attr "length" "4,8")]) 2086 2087 2088(define_expand "sub<mode>3" 2089 [(set (match_operand:SDI 0 "gpc_reg_operand") 2090 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand") 2091 (match_operand:SDI 2 "gpc_reg_operand")))] 2092 "" 2093{ 2094 if (<MODE>mode == DImode && !TARGET_POWERPC64) 2095 { 2096 rtx lo0 = gen_lowpart (SImode, operands[0]); 2097 rtx lo1 = gen_lowpart (SImode, operands[1]); 2098 rtx lo2 = gen_lowpart (SImode, operands[2]); 2099 rtx hi0 = gen_highpart (SImode, operands[0]); 2100 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]); 2101 rtx hi2 = gen_highpart (SImode, operands[2]); 2102 2103 if (!reg_or_short_operand (lo1, SImode)) 2104 lo1 = force_reg (SImode, lo1); 2105 if (!adde_operand (hi1, SImode)) 2106 hi1 = force_reg (SImode, hi1); 2107 2108 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1)); 2109 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1)); 2110 DONE; 2111 } 2112 2113 if (short_cint_operand (operands[1], <MODE>mode)) 2114 { 2115 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1])); 2116 DONE; 2117 } 2118}) 2119 2120(define_insn "*subf<mode>3" 2121 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2122 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r") 2123 (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2124 "" 2125 "subf %0,%1,%2" 2126 [(set_attr "type" "add")]) 2127 2128(define_insn_and_split "*subf<mode>3_dot" 2129 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2130 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r") 2131 (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2132 (const_int 0))) 2133 (clobber (match_scratch:GPR 0 "=r,r"))] 2134 "<MODE>mode == Pmode" 2135 "@ 2136 subf. %0,%1,%2 2137 #" 2138 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2139 [(set (match_dup 0) 2140 (minus:GPR (match_dup 2) 2141 (match_dup 1))) 2142 (set (match_dup 3) 2143 (compare:CC (match_dup 0) 2144 (const_int 0)))] 2145 "" 2146 [(set_attr "type" "add") 2147 (set_attr "dot" "yes") 2148 (set_attr "length" "4,8")]) 2149 2150(define_insn_and_split "*subf<mode>3_dot2" 2151 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2152 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r") 2153 (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2154 (const_int 0))) 2155 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2156 (minus:GPR (match_dup 2) 2157 (match_dup 1)))] 2158 "<MODE>mode == Pmode" 2159 "@ 2160 subf. %0,%1,%2 2161 #" 2162 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2163 [(set (match_dup 0) 2164 (minus:GPR (match_dup 2) 2165 (match_dup 1))) 2166 (set (match_dup 3) 2167 (compare:CC (match_dup 0) 2168 (const_int 0)))] 2169 "" 2170 [(set_attr "type" "add") 2171 (set_attr "dot" "yes") 2172 (set_attr "length" "4,8")]) 2173 2174(define_insn "subf<mode>3_imm" 2175 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2176 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I") 2177 (match_operand:GPR 1 "gpc_reg_operand" "r"))) 2178 (clobber (reg:GPR CA_REGNO))] 2179 "" 2180 "subfic %0,%1,%2" 2181 [(set_attr "type" "add")]) 2182 2183(define_insn_and_split "subf<mode>3_carry_dot2" 2184 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2185 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r") 2186 (match_operand:P 1 "gpc_reg_operand" "r,r")) 2187 (const_int 0))) 2188 (set (match_operand:P 0 "gpc_reg_operand" "=r,r") 2189 (minus:P (match_dup 2) 2190 (match_dup 1))) 2191 (set (reg:P CA_REGNO) 2192 (leu:P (match_dup 1) 2193 (match_dup 2)))] 2194 "<MODE>mode == Pmode" 2195 "@ 2196 subfc. %0,%1,%2 2197 #" 2198 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2199 [(parallel [(set (match_dup 0) 2200 (minus:P (match_dup 2) 2201 (match_dup 1))) 2202 (set (reg:P CA_REGNO) 2203 (leu:P (match_dup 1) 2204 (match_dup 2)))]) 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 "subf<mode>3_carry" 2214 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2215 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI") 2216 (match_operand:P 1 "gpc_reg_operand" "r"))) 2217 (set (reg:P CA_REGNO) 2218 (leu:P (match_dup 1) 2219 (match_dup 2)))] 2220 "" 2221 "subf%I2c %0,%1,%2" 2222 [(set_attr "type" "add")]) 2223 2224(define_insn "*subf<mode>3_imm_carry_0" 2225 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2226 (neg:P (match_operand:P 1 "gpc_reg_operand" "r"))) 2227 (set (reg:P CA_REGNO) 2228 (eq:P (match_dup 1) 2229 (const_int 0)))] 2230 "" 2231 "subfic %0,%1,0" 2232 [(set_attr "type" "add")]) 2233 2234(define_insn "*subf<mode>3_imm_carry_m1" 2235 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 2236 (not:P (match_operand:P 1 "gpc_reg_operand" "r"))) 2237 (set (reg:P CA_REGNO) 2238 (const_int 1))] 2239 "" 2240 "subfic %0,%1,-1" 2241 [(set_attr "type" "add")]) 2242 2243 2244(define_expand "subf<mode>3_carry_in" 2245 [(parallel [ 2246 (set (match_operand:GPR 0 "gpc_reg_operand") 2247 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand")) 2248 (reg:GPR CA_REGNO)) 2249 (match_operand:GPR 2 "adde_operand"))) 2250 (clobber (reg:GPR CA_REGNO))])] 2251 "" 2252{ 2253 if (operands[2] == const0_rtx) 2254 { 2255 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1])); 2256 DONE; 2257 } 2258 if (operands[2] == constm1_rtx) 2259 { 2260 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1])); 2261 DONE; 2262 } 2263}) 2264 2265(define_insn "*subf<mode>3_carry_in_internal" 2266 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2267 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 2268 (reg:GPR CA_REGNO)) 2269 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 2270 (clobber (reg:GPR CA_REGNO))] 2271 "" 2272 "subfe %0,%1,%2" 2273 [(set_attr "type" "add")]) 2274 2275(define_insn "subf<mode>3_carry_in_0" 2276 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2277 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 2278 (reg:GPR CA_REGNO))) 2279 (clobber (reg:GPR CA_REGNO))] 2280 "" 2281 "subfze %0,%1" 2282 [(set_attr "type" "add")]) 2283 2284(define_insn "subf<mode>3_carry_in_m1" 2285 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2286 (plus:GPR (minus:GPR (reg:GPR CA_REGNO) 2287 (match_operand:GPR 1 "gpc_reg_operand" "r")) 2288 (const_int -2))) 2289 (clobber (reg:GPR CA_REGNO))] 2290 "" 2291 "subfme %0,%1" 2292 [(set_attr "type" "add")]) 2293 2294(define_insn "subf<mode>3_carry_in_xx" 2295 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2296 (plus:GPR (reg:GPR CA_REGNO) 2297 (const_int -1))) 2298 (clobber (reg:GPR CA_REGNO))] 2299 "" 2300 "subfe %0,%0,%0" 2301 [(set_attr "type" "add")]) 2302 2303 2304(define_insn "@neg<mode>2" 2305 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2306 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2307 "" 2308 "neg %0,%1" 2309 [(set_attr "type" "add")]) 2310 2311(define_insn_and_split "*neg<mode>2_dot" 2312 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2313 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2314 (const_int 0))) 2315 (clobber (match_scratch:GPR 0 "=r,r"))] 2316 "<MODE>mode == Pmode" 2317 "@ 2318 neg. %0,%1 2319 #" 2320 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2321 [(set (match_dup 0) 2322 (neg:GPR (match_dup 1))) 2323 (set (match_dup 2) 2324 (compare:CC (match_dup 0) 2325 (const_int 0)))] 2326 "" 2327 [(set_attr "type" "add") 2328 (set_attr "dot" "yes") 2329 (set_attr "length" "4,8")]) 2330 2331(define_insn_and_split "*neg<mode>2_dot2" 2332 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y") 2333 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 2334 (const_int 0))) 2335 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2336 (neg:GPR (match_dup 1)))] 2337 "<MODE>mode == Pmode" 2338 "@ 2339 neg. %0,%1 2340 #" 2341 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)" 2342 [(set (match_dup 0) 2343 (neg:GPR (match_dup 1))) 2344 (set (match_dup 2) 2345 (compare:CC (match_dup 0) 2346 (const_int 0)))] 2347 "" 2348 [(set_attr "type" "add") 2349 (set_attr "dot" "yes") 2350 (set_attr "length" "4,8")]) 2351 2352 2353(define_insn "clz<mode>2" 2354 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2355 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2356 "" 2357 "cntlz<wd> %0,%1" 2358 [(set_attr "type" "cntlz")]) 2359 2360(define_expand "ctz<mode>2" 2361 [(set (match_operand:GPR 0 "gpc_reg_operand") 2362 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2363 "" 2364{ 2365 if (TARGET_CTZ) 2366 { 2367 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1])); 2368 DONE; 2369 } 2370 2371 rtx tmp1 = gen_reg_rtx (<MODE>mode); 2372 rtx tmp2 = gen_reg_rtx (<MODE>mode); 2373 rtx tmp3 = gen_reg_rtx (<MODE>mode); 2374 2375 if (TARGET_POPCNTD) 2376 { 2377 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx)); 2378 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1])); 2379 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2)); 2380 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3)); 2381 } 2382 else 2383 { 2384 emit_insn (gen_neg<mode>2 (tmp1, operands[1])); 2385 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1)); 2386 emit_insn (gen_clz<mode>2 (tmp3, tmp2)); 2387 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3)); 2388 } 2389 2390 DONE; 2391}) 2392 2393(define_insn "ctz<mode>2_hw" 2394 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2395 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2396 "TARGET_CTZ" 2397 "cnttz<wd> %0,%1" 2398 [(set_attr "type" "cntlz")]) 2399 2400(define_expand "ffs<mode>2" 2401 [(set (match_operand:GPR 0 "gpc_reg_operand") 2402 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2403 "" 2404{ 2405 rtx tmp1 = gen_reg_rtx (<MODE>mode); 2406 rtx tmp2 = gen_reg_rtx (<MODE>mode); 2407 rtx tmp3 = gen_reg_rtx (<MODE>mode); 2408 emit_insn (gen_neg<mode>2 (tmp1, operands[1])); 2409 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1)); 2410 emit_insn (gen_clz<mode>2 (tmp3, tmp2)); 2411 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3)); 2412 DONE; 2413}) 2414 2415 2416(define_expand "popcount<mode>2" 2417 [(set (match_operand:GPR 0 "gpc_reg_operand") 2418 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2419 "TARGET_POPCNTB || TARGET_POPCNTD" 2420{ 2421 rs6000_emit_popcount (operands[0], operands[1]); 2422 DONE; 2423}) 2424 2425(define_insn "popcntb<mode>2" 2426 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2427 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] 2428 UNSPEC_POPCNTB))] 2429 "TARGET_POPCNTB" 2430 "popcntb %0,%1" 2431 [(set_attr "type" "popcnt")]) 2432 2433(define_insn "popcntd<mode>2" 2434 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2435 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))] 2436 "TARGET_POPCNTD" 2437 "popcnt<wd> %0,%1" 2438 [(set_attr "type" "popcnt")]) 2439 2440 2441(define_expand "parity<mode>2" 2442 [(set (match_operand:GPR 0 "gpc_reg_operand") 2443 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))] 2444 "TARGET_POPCNTB" 2445{ 2446 rs6000_emit_parity (operands[0], operands[1]); 2447 DONE; 2448}) 2449 2450(define_insn "parity<mode>2_cmpb" 2451 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2452 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))] 2453 "TARGET_CMPB && TARGET_POPCNTB" 2454 "prty<wd> %0,%1" 2455 [(set_attr "type" "popcnt")]) 2456 2457(define_insn "cmpb<mode>3" 2458 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 2459 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r") 2460 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))] 2461 "TARGET_CMPB" 2462 "cmpb %0,%1,%2" 2463 [(set_attr "type" "cmp")]) 2464 2465;; Since the hardware zeros the upper part of the register, save generating the 2466;; AND immediate if we are converting to unsigned 2467(define_insn "*bswap<mode>2_extenddi" 2468 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2469 (zero_extend:DI 2470 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))] 2471 "TARGET_POWERPC64" 2472 "l<wd>brx %0,%y1" 2473 [(set_attr "type" "load")]) 2474 2475(define_insn "*bswaphi2_extendsi" 2476 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 2477 (zero_extend:SI 2478 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))] 2479 "" 2480 "lhbrx %0,%y1" 2481 [(set_attr "type" "load")]) 2482 2483;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents 2484;; the register allocator from converting a gpr<-gpr swap into a store and then 2485;; load with byte swap, which can be slower than doing it in the registers. It 2486;; also prevents certain failures with the RELOAD register allocator. 2487 2488(define_expand "bswap<mode>2" 2489 [(use (match_operand:HSI 0 "reg_or_mem_operand")) 2490 (use (match_operand:HSI 1 "reg_or_mem_operand"))] 2491 "" 2492{ 2493 rtx dest = operands[0]; 2494 rtx src = operands[1]; 2495 2496 if (!REG_P (dest) && !REG_P (src)) 2497 src = force_reg (<MODE>mode, src); 2498 2499 if (MEM_P (src)) 2500 { 2501 src = rs6000_force_indexed_or_indirect_mem (src); 2502 emit_insn (gen_bswap<mode>2_load (dest, src)); 2503 } 2504 else if (MEM_P (dest)) 2505 { 2506 dest = rs6000_force_indexed_or_indirect_mem (dest); 2507 emit_insn (gen_bswap<mode>2_store (dest, src)); 2508 } 2509 else 2510 emit_insn (gen_bswap<mode>2_reg (dest, src)); 2511 DONE; 2512}) 2513 2514(define_insn "bswap<mode>2_load" 2515 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r") 2516 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))] 2517 "" 2518 "l<wd>brx %0,%y1" 2519 [(set_attr "type" "load")]) 2520 2521(define_insn "bswap<mode>2_store" 2522 [(set (match_operand:HSI 0 "memory_operand" "=Z") 2523 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))] 2524 "" 2525 "st<wd>brx %1,%y0" 2526 [(set_attr "type" "store")]) 2527 2528(define_insn_and_split "bswaphi2_reg" 2529 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa") 2530 (bswap:HI 2531 (match_operand:HI 1 "gpc_reg_operand" "r,wa"))) 2532 (clobber (match_scratch:SI 2 "=&r,X"))] 2533 "" 2534 "@ 2535 # 2536 xxbrh %x0,%x1" 2537 "reload_completed && int_reg_operand (operands[0], HImode)" 2538 [(set (match_dup 3) 2539 (and:SI (lshiftrt:SI (match_dup 4) 2540 (const_int 8)) 2541 (const_int 255))) 2542 (set (match_dup 2) 2543 (and:SI (ashift:SI (match_dup 4) 2544 (const_int 8)) 2545 (const_int 65280))) ;; 0xff00 2546 (set (match_dup 3) 2547 (ior:SI (match_dup 3) 2548 (match_dup 2)))] 2549{ 2550 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0); 2551 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0); 2552} 2553 [(set_attr "length" "12,4") 2554 (set_attr "type" "*,vecperm") 2555 (set_attr "isa" "*,p9v")]) 2556 2557;; We are always BITS_BIG_ENDIAN, so the bit positions below in 2558;; zero_extract insns do not change for -mlittle. 2559(define_insn_and_split "bswapsi2_reg" 2560 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa") 2561 (bswap:SI 2562 (match_operand:SI 1 "gpc_reg_operand" "r,wa")))] 2563 "" 2564 "@ 2565 # 2566 xxbrw %x0,%x1" 2567 "reload_completed && int_reg_operand (operands[0], SImode)" 2568 [(set (match_dup 0) ; DABC 2569 (rotate:SI (match_dup 1) 2570 (const_int 24))) 2571 (set (match_dup 0) ; DCBC 2572 (ior:SI (and:SI (ashift:SI (match_dup 1) 2573 (const_int 8)) 2574 (const_int 16711680)) 2575 (and:SI (match_dup 0) 2576 (const_int -16711681)))) 2577 (set (match_dup 0) ; DCBA 2578 (ior:SI (and:SI (lshiftrt:SI (match_dup 1) 2579 (const_int 24)) 2580 (const_int 255)) 2581 (and:SI (match_dup 0) 2582 (const_int -256))))] 2583 "" 2584 [(set_attr "length" "12,4") 2585 (set_attr "type" "*,vecperm") 2586 (set_attr "isa" "*,p9v")]) 2587 2588;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like 2589;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more 2590;; complex code. 2591 2592(define_expand "bswapdi2" 2593 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand") 2594 (bswap:DI 2595 (match_operand:DI 1 "reg_or_mem_operand"))) 2596 (clobber (match_scratch:DI 2)) 2597 (clobber (match_scratch:DI 3))])] 2598 "" 2599{ 2600 rtx dest = operands[0]; 2601 rtx src = operands[1]; 2602 2603 if (!REG_P (dest) && !REG_P (src)) 2604 operands[1] = src = force_reg (DImode, src); 2605 2606 if (TARGET_POWERPC64 && TARGET_LDBRX) 2607 { 2608 if (MEM_P (src)) 2609 { 2610 src = rs6000_force_indexed_or_indirect_mem (src); 2611 emit_insn (gen_bswapdi2_load (dest, src)); 2612 } 2613 else if (MEM_P (dest)) 2614 { 2615 dest = rs6000_force_indexed_or_indirect_mem (dest); 2616 emit_insn (gen_bswapdi2_store (dest, src)); 2617 } 2618 else if (TARGET_P9_VECTOR) 2619 emit_insn (gen_bswapdi2_xxbrd (dest, src)); 2620 else 2621 emit_insn (gen_bswapdi2_reg (dest, src)); 2622 DONE; 2623 } 2624 2625 if (!TARGET_POWERPC64) 2626 { 2627 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode 2628 that uses 64-bit registers needs the same scratch registers as 64-bit 2629 mode. */ 2630 emit_insn (gen_bswapdi2_32bit (dest, src)); 2631 DONE; 2632 } 2633}) 2634 2635;; Power7/cell has ldbrx/stdbrx, so use it directly 2636(define_insn "bswapdi2_load" 2637 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 2638 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))] 2639 "TARGET_POWERPC64 && TARGET_LDBRX" 2640 "ldbrx %0,%y1" 2641 [(set_attr "type" "load")]) 2642 2643(define_insn "bswapdi2_store" 2644 [(set (match_operand:DI 0 "memory_operand" "=Z") 2645 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))] 2646 "TARGET_POWERPC64 && TARGET_LDBRX" 2647 "stdbrx %1,%y0" 2648 [(set_attr "type" "store")]) 2649 2650(define_insn "bswapdi2_xxbrd" 2651 [(set (match_operand:DI 0 "gpc_reg_operand" "=wa") 2652 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))] 2653 "TARGET_P9_VECTOR" 2654 "xxbrd %x0,%x1" 2655 [(set_attr "type" "vecperm") 2656 (set_attr "isa" "p9v")]) 2657 2658(define_insn "bswapdi2_reg" 2659 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r") 2660 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r"))) 2661 (clobber (match_scratch:DI 2 "=&r")) 2662 (clobber (match_scratch:DI 3 "=&r"))] 2663 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR" 2664 "#" 2665 [(set_attr "length" "36")]) 2666 2667;; Non-power7/cell, fall back to use lwbrx/stwbrx 2668(define_insn "*bswapdi2_64bit" 2669 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r") 2670 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) 2671 (clobber (match_scratch:DI 2 "=&b,&b,&r")) 2672 (clobber (match_scratch:DI 3 "=&r,&r,&r"))] 2673 "TARGET_POWERPC64 && !TARGET_LDBRX 2674 && (REG_P (operands[0]) || REG_P (operands[1])) 2675 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0])) 2676 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))" 2677 "#" 2678 [(set_attr "length" "16,12,36")]) 2679 2680(define_split 2681 [(set (match_operand:DI 0 "gpc_reg_operand") 2682 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand"))) 2683 (clobber (match_operand:DI 2 "gpc_reg_operand")) 2684 (clobber (match_operand:DI 3 "gpc_reg_operand"))] 2685 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" 2686 [(const_int 0)] 2687{ 2688 rtx dest = operands[0]; 2689 rtx src = operands[1]; 2690 rtx op2 = operands[2]; 2691 rtx op3 = operands[3]; 2692 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode, 2693 BYTES_BIG_ENDIAN ? 4 : 0); 2694 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode, 2695 BYTES_BIG_ENDIAN ? 4 : 0); 2696 rtx addr1; 2697 rtx addr2; 2698 rtx word1; 2699 rtx word2; 2700 2701 addr1 = XEXP (src, 0); 2702 if (GET_CODE (addr1) == PLUS) 2703 { 2704 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2705 if (TARGET_AVOID_XFORM) 2706 { 2707 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2708 addr2 = op2; 2709 } 2710 else 2711 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); 2712 } 2713 else if (TARGET_AVOID_XFORM) 2714 { 2715 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2716 addr2 = op2; 2717 } 2718 else 2719 { 2720 emit_move_insn (op2, GEN_INT (4)); 2721 addr2 = gen_rtx_PLUS (Pmode, op2, addr1); 2722 } 2723 2724 word1 = change_address (src, SImode, addr1); 2725 word2 = change_address (src, SImode, addr2); 2726 2727 if (BYTES_BIG_ENDIAN) 2728 { 2729 emit_insn (gen_bswapsi2 (op3_32, word2)); 2730 emit_insn (gen_bswapsi2 (dest_32, word1)); 2731 } 2732 else 2733 { 2734 emit_insn (gen_bswapsi2 (op3_32, word1)); 2735 emit_insn (gen_bswapsi2 (dest_32, word2)); 2736 } 2737 2738 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32))); 2739 emit_insn (gen_iordi3 (dest, dest, op3)); 2740 DONE; 2741}) 2742 2743(define_split 2744 [(set (match_operand:DI 0 "indexed_or_indirect_operand") 2745 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 2746 (clobber (match_operand:DI 2 "gpc_reg_operand")) 2747 (clobber (match_operand:DI 3 "gpc_reg_operand"))] 2748 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed" 2749 [(const_int 0)] 2750{ 2751 rtx dest = operands[0]; 2752 rtx src = operands[1]; 2753 rtx op2 = operands[2]; 2754 rtx op3 = operands[3]; 2755 rtx src_si = simplify_gen_subreg (SImode, src, DImode, 2756 BYTES_BIG_ENDIAN ? 4 : 0); 2757 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, 2758 BYTES_BIG_ENDIAN ? 4 : 0); 2759 rtx addr1; 2760 rtx addr2; 2761 rtx word1; 2762 rtx word2; 2763 2764 addr1 = XEXP (dest, 0); 2765 if (GET_CODE (addr1) == PLUS) 2766 { 2767 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2768 if (TARGET_AVOID_XFORM) 2769 { 2770 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2771 addr2 = op2; 2772 } 2773 else 2774 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1)); 2775 } 2776 else if (TARGET_AVOID_XFORM) 2777 { 2778 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2779 addr2 = op2; 2780 } 2781 else 2782 { 2783 emit_move_insn (op2, GEN_INT (4)); 2784 addr2 = gen_rtx_PLUS (Pmode, op2, addr1); 2785 } 2786 2787 word1 = change_address (dest, SImode, addr1); 2788 word2 = change_address (dest, SImode, addr2); 2789 2790 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32))); 2791 2792 if (BYTES_BIG_ENDIAN) 2793 { 2794 emit_insn (gen_bswapsi2 (word1, src_si)); 2795 emit_insn (gen_bswapsi2 (word2, op3_si)); 2796 } 2797 else 2798 { 2799 emit_insn (gen_bswapsi2 (word2, src_si)); 2800 emit_insn (gen_bswapsi2 (word1, op3_si)); 2801 } 2802 DONE; 2803}) 2804 2805(define_split 2806 [(set (match_operand:DI 0 "gpc_reg_operand") 2807 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 2808 (clobber (match_operand:DI 2 "gpc_reg_operand")) 2809 (clobber (match_operand:DI 3 "gpc_reg_operand"))] 2810 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed" 2811 [(const_int 0)] 2812{ 2813 rtx dest = operands[0]; 2814 rtx src = operands[1]; 2815 rtx op2 = operands[2]; 2816 rtx op3 = operands[3]; 2817 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0; 2818 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off); 2819 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off); 2820 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off); 2821 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off); 2822 2823 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32))); 2824 emit_insn (gen_bswapsi2 (dest_si, src_si)); 2825 emit_insn (gen_bswapsi2 (op3_si, op2_si)); 2826 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32))); 2827 emit_insn (gen_iordi3 (dest, dest, op3)); 2828 DONE; 2829}) 2830 2831(define_insn "bswapdi2_32bit" 2832 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r") 2833 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r"))) 2834 (clobber (match_scratch:SI 2 "=&b,&b,X"))] 2835 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))" 2836 "#" 2837 [(set_attr "length" "16,12,36")]) 2838 2839(define_split 2840 [(set (match_operand:DI 0 "gpc_reg_operand") 2841 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand"))) 2842 (clobber (match_operand:SI 2 "gpc_reg_operand"))] 2843 "!TARGET_POWERPC64 && reload_completed" 2844 [(const_int 0)] 2845{ 2846 rtx dest = operands[0]; 2847 rtx src = operands[1]; 2848 rtx op2 = operands[2]; 2849 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); 2850 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); 2851 rtx addr1; 2852 rtx addr2; 2853 rtx word1; 2854 rtx word2; 2855 2856 addr1 = XEXP (src, 0); 2857 if (GET_CODE (addr1) == PLUS) 2858 { 2859 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2860 if (TARGET_AVOID_XFORM 2861 || REGNO (XEXP (addr1, 1)) == REGNO (dest2)) 2862 { 2863 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2864 addr2 = op2; 2865 } 2866 else 2867 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); 2868 } 2869 else if (TARGET_AVOID_XFORM 2870 || REGNO (addr1) == REGNO (dest2)) 2871 { 2872 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2873 addr2 = op2; 2874 } 2875 else 2876 { 2877 emit_move_insn (op2, GEN_INT (4)); 2878 addr2 = gen_rtx_PLUS (SImode, op2, addr1); 2879 } 2880 2881 word1 = change_address (src, SImode, addr1); 2882 word2 = change_address (src, SImode, addr2); 2883 2884 emit_insn (gen_bswapsi2 (dest2, word1)); 2885 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed, 2886 thus allowing us to omit an early clobber on the output. */ 2887 emit_insn (gen_bswapsi2 (dest1, word2)); 2888 DONE; 2889}) 2890 2891(define_split 2892 [(set (match_operand:DI 0 "indexed_or_indirect_operand") 2893 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 2894 (clobber (match_operand:SI 2 "gpc_reg_operand"))] 2895 "!TARGET_POWERPC64 && reload_completed" 2896 [(const_int 0)] 2897{ 2898 rtx dest = operands[0]; 2899 rtx src = operands[1]; 2900 rtx op2 = operands[2]; 2901 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); 2902 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); 2903 rtx addr1; 2904 rtx addr2; 2905 rtx word1; 2906 rtx word2; 2907 2908 addr1 = XEXP (dest, 0); 2909 if (GET_CODE (addr1) == PLUS) 2910 { 2911 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4))); 2912 if (TARGET_AVOID_XFORM) 2913 { 2914 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2)); 2915 addr2 = op2; 2916 } 2917 else 2918 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1)); 2919 } 2920 else if (TARGET_AVOID_XFORM) 2921 { 2922 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4))); 2923 addr2 = op2; 2924 } 2925 else 2926 { 2927 emit_move_insn (op2, GEN_INT (4)); 2928 addr2 = gen_rtx_PLUS (SImode, op2, addr1); 2929 } 2930 2931 word1 = change_address (dest, SImode, addr1); 2932 word2 = change_address (dest, SImode, addr2); 2933 2934 emit_insn (gen_bswapsi2 (word2, src1)); 2935 emit_insn (gen_bswapsi2 (word1, src2)); 2936 DONE; 2937}) 2938 2939(define_split 2940 [(set (match_operand:DI 0 "gpc_reg_operand") 2941 (bswap:DI (match_operand:DI 1 "gpc_reg_operand"))) 2942 (clobber (match_operand:SI 2 ""))] 2943 "!TARGET_POWERPC64 && reload_completed" 2944 [(const_int 0)] 2945{ 2946 rtx dest = operands[0]; 2947 rtx src = operands[1]; 2948 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0); 2949 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4); 2950 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0); 2951 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4); 2952 2953 emit_insn (gen_bswapsi2 (dest1, src2)); 2954 emit_insn (gen_bswapsi2 (dest2, src1)); 2955 DONE; 2956}) 2957 2958 2959(define_insn "mul<mode>3" 2960 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 2961 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 2962 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))] 2963 "" 2964 "@ 2965 mull<wd> %0,%1,%2 2966 mulli %0,%1,%2" 2967 [(set_attr "type" "mul") 2968 (set (attr "size") 2969 (cond [(match_operand:GPR 2 "s8bit_cint_operand") 2970 (const_string "8") 2971 (match_operand:GPR 2 "short_cint_operand") 2972 (const_string "16")] 2973 (const_string "<bits>")))]) 2974 2975(define_insn_and_split "*mul<mode>3_dot" 2976 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 2977 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 2978 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 2979 (const_int 0))) 2980 (clobber (match_scratch:GPR 0 "=r,r"))] 2981 "<MODE>mode == Pmode" 2982 "@ 2983 mull<wd>. %0,%1,%2 2984 #" 2985 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 2986 [(set (match_dup 0) 2987 (mult:GPR (match_dup 1) 2988 (match_dup 2))) 2989 (set (match_dup 3) 2990 (compare:CC (match_dup 0) 2991 (const_int 0)))] 2992 "" 2993 [(set_attr "type" "mul") 2994 (set_attr "size" "<bits>") 2995 (set_attr "dot" "yes") 2996 (set_attr "length" "4,8")]) 2997 2998(define_insn_and_split "*mul<mode>3_dot2" 2999 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3000 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3001 (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3002 (const_int 0))) 3003 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3004 (mult:GPR (match_dup 1) 3005 (match_dup 2)))] 3006 "<MODE>mode == Pmode" 3007 "@ 3008 mull<wd>. %0,%1,%2 3009 #" 3010 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3011 [(set (match_dup 0) 3012 (mult:GPR (match_dup 1) 3013 (match_dup 2))) 3014 (set (match_dup 3) 3015 (compare:CC (match_dup 0) 3016 (const_int 0)))] 3017 "" 3018 [(set_attr "type" "mul") 3019 (set_attr "size" "<bits>") 3020 (set_attr "dot" "yes") 3021 (set_attr "length" "4,8")]) 3022 3023 3024(define_expand "<su>mul<mode>3_highpart" 3025 [(set (match_operand:GPR 0 "gpc_reg_operand") 3026 (subreg:GPR 3027 (mult:<DMODE> (any_extend:<DMODE> 3028 (match_operand:GPR 1 "gpc_reg_operand")) 3029 (any_extend:<DMODE> 3030 (match_operand:GPR 2 "gpc_reg_operand"))) 3031 0))] 3032 "" 3033{ 3034 if (<MODE>mode == SImode && TARGET_POWERPC64) 3035 { 3036 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1], 3037 operands[2])); 3038 DONE; 3039 } 3040 3041 if (!WORDS_BIG_ENDIAN) 3042 { 3043 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1], 3044 operands[2])); 3045 DONE; 3046 } 3047}) 3048 3049(define_insn "*<su>mul<mode>3_highpart" 3050 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3051 (subreg:GPR 3052 (mult:<DMODE> (any_extend:<DMODE> 3053 (match_operand:GPR 1 "gpc_reg_operand" "r")) 3054 (any_extend:<DMODE> 3055 (match_operand:GPR 2 "gpc_reg_operand" "r"))) 3056 0))] 3057 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)" 3058 "mulh<wd><u> %0,%1,%2" 3059 [(set_attr "type" "mul") 3060 (set_attr "size" "<bits>")]) 3061 3062(define_insn "<su>mulsi3_highpart_le" 3063 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 3064 (subreg:SI 3065 (mult:DI (any_extend:DI 3066 (match_operand:SI 1 "gpc_reg_operand" "r")) 3067 (any_extend:DI 3068 (match_operand:SI 2 "gpc_reg_operand" "r"))) 3069 4))] 3070 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64" 3071 "mulhw<u> %0,%1,%2" 3072 [(set_attr "type" "mul")]) 3073 3074(define_insn "<su>muldi3_highpart_le" 3075 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 3076 (subreg:DI 3077 (mult:TI (any_extend:TI 3078 (match_operand:DI 1 "gpc_reg_operand" "r")) 3079 (any_extend:TI 3080 (match_operand:DI 2 "gpc_reg_operand" "r"))) 3081 8))] 3082 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64" 3083 "mulhd<u> %0,%1,%2" 3084 [(set_attr "type" "mul") 3085 (set_attr "size" "64")]) 3086 3087(define_insn "<su>mulsi3_highpart_64" 3088 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 3089 (truncate:SI 3090 (lshiftrt:DI 3091 (mult:DI (any_extend:DI 3092 (match_operand:SI 1 "gpc_reg_operand" "r")) 3093 (any_extend:DI 3094 (match_operand:SI 2 "gpc_reg_operand" "r"))) 3095 (const_int 32))))] 3096 "TARGET_POWERPC64" 3097 "mulhw<u> %0,%1,%2" 3098 [(set_attr "type" "mul")]) 3099 3100(define_expand "<u>mul<mode><dmode>3" 3101 [(set (match_operand:<DMODE> 0 "gpc_reg_operand") 3102 (mult:<DMODE> (any_extend:<DMODE> 3103 (match_operand:GPR 1 "gpc_reg_operand")) 3104 (any_extend:<DMODE> 3105 (match_operand:GPR 2 "gpc_reg_operand"))))] 3106 "!(<MODE>mode == SImode && TARGET_POWERPC64)" 3107{ 3108 rtx l = gen_reg_rtx (<MODE>mode); 3109 rtx h = gen_reg_rtx (<MODE>mode); 3110 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2])); 3111 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2])); 3112 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l); 3113 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h); 3114 DONE; 3115}) 3116 3117(define_insn "*maddld<mode>4" 3118 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3119 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3120 (match_operand:GPR 2 "gpc_reg_operand" "r")) 3121 (match_operand:GPR 3 "gpc_reg_operand" "r")))] 3122 "TARGET_MADDLD" 3123 "maddld %0,%1,%2,%3" 3124 [(set_attr "type" "mul")]) 3125 3126(define_insn "udiv<mode>3" 3127 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3128 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3129 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3130 "" 3131 "div<wd>u %0,%1,%2" 3132 [(set_attr "type" "div") 3133 (set_attr "size" "<bits>")]) 3134 3135 3136;; For powers of two we can do sra[wd]i/addze for divide and then adjust for 3137;; modulus. If it isn't a power of two, force operands into register and do 3138;; a normal divide. 3139(define_expand "div<mode>3" 3140 [(set (match_operand:GPR 0 "gpc_reg_operand") 3141 (div:GPR (match_operand:GPR 1 "gpc_reg_operand") 3142 (match_operand:GPR 2 "reg_or_cint_operand")))] 3143 "" 3144{ 3145 if (CONST_INT_P (operands[2]) 3146 && INTVAL (operands[2]) > 0 3147 && exact_log2 (INTVAL (operands[2])) >= 0) 3148 { 3149 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2])); 3150 DONE; 3151 } 3152 3153 operands[2] = force_reg (<MODE>mode, operands[2]); 3154}) 3155 3156(define_insn "*div<mode>3" 3157 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3158 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3159 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3160 "" 3161 "div<wd> %0,%1,%2" 3162 [(set_attr "type" "div") 3163 (set_attr "size" "<bits>")]) 3164 3165(define_insn "div<mode>3_sra" 3166 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3167 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3168 (match_operand:GPR 2 "exact_log2_cint_operand" "N"))) 3169 (clobber (reg:GPR CA_REGNO))] 3170 "" 3171 "sra<wd>i %0,%1,%p2\;addze %0,%0" 3172 [(set_attr "type" "two") 3173 (set_attr "length" "8")]) 3174 3175(define_insn_and_split "*div<mode>3_sra_dot" 3176 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3177 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3178 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")) 3179 (const_int 0))) 3180 (clobber (match_scratch:GPR 0 "=r,r")) 3181 (clobber (reg:GPR CA_REGNO))] 3182 "<MODE>mode == Pmode" 3183 "@ 3184 sra<wd>i %0,%1,%p2\;addze. %0,%0 3185 #" 3186 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3187 [(parallel [(set (match_dup 0) 3188 (div:GPR (match_dup 1) 3189 (match_dup 2))) 3190 (clobber (reg:GPR CA_REGNO))]) 3191 (set (match_dup 3) 3192 (compare:CC (match_dup 0) 3193 (const_int 0)))] 3194 "" 3195 [(set_attr "type" "two") 3196 (set_attr "length" "8,12") 3197 (set_attr "cell_micro" "not")]) 3198 3199(define_insn_and_split "*div<mode>3_sra_dot2" 3200 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3201 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 3202 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N")) 3203 (const_int 0))) 3204 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3205 (div:GPR (match_dup 1) 3206 (match_dup 2))) 3207 (clobber (reg:GPR CA_REGNO))] 3208 "<MODE>mode == Pmode" 3209 "@ 3210 sra<wd>i %0,%1,%p2\;addze. %0,%0 3211 #" 3212 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3213 [(parallel [(set (match_dup 0) 3214 (div:GPR (match_dup 1) 3215 (match_dup 2))) 3216 (clobber (reg:GPR CA_REGNO))]) 3217 (set (match_dup 3) 3218 (compare:CC (match_dup 0) 3219 (const_int 0)))] 3220 "" 3221 [(set_attr "type" "two") 3222 (set_attr "length" "8,12") 3223 (set_attr "cell_micro" "not")]) 3224 3225(define_expand "mod<mode>3" 3226 [(set (match_operand:GPR 0 "gpc_reg_operand") 3227 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand") 3228 (match_operand:GPR 2 "reg_or_cint_operand")))] 3229 "" 3230{ 3231 int i; 3232 rtx temp1; 3233 rtx temp2; 3234 3235 if (!CONST_INT_P (operands[2]) 3236 || INTVAL (operands[2]) <= 0 3237 || (i = exact_log2 (INTVAL (operands[2]))) < 0) 3238 { 3239 if (!TARGET_MODULO) 3240 FAIL; 3241 3242 operands[2] = force_reg (<MODE>mode, operands[2]); 3243 } 3244 else 3245 { 3246 temp1 = gen_reg_rtx (<MODE>mode); 3247 temp2 = gen_reg_rtx (<MODE>mode); 3248 3249 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2])); 3250 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i))); 3251 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2)); 3252 DONE; 3253 } 3254}) 3255 3256;; In order to enable using a peephole2 for combining div/mod to eliminate the 3257;; mod, prefer putting the result of mod into a different register 3258(define_insn "*mod<mode>3" 3259 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 3260 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3261 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3262 "TARGET_MODULO" 3263 "mods<wd> %0,%1,%2" 3264 [(set_attr "type" "div") 3265 (set_attr "size" "<bits>")]) 3266 3267 3268(define_insn "umod<mode>3" 3269 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r") 3270 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3271 (match_operand:GPR 2 "gpc_reg_operand" "r")))] 3272 "TARGET_MODULO" 3273 "modu<wd> %0,%1,%2" 3274 [(set_attr "type" "div") 3275 (set_attr "size" "<bits>")]) 3276 3277;; On machines with modulo support, do a combined div/mod the old fashioned 3278;; method, since the multiply/subtract is faster than doing the mod instruction 3279;; after a divide. 3280 3281(define_peephole2 3282 [(set (match_operand:GPR 0 "gpc_reg_operand") 3283 (div:GPR (match_operand:GPR 1 "gpc_reg_operand") 3284 (match_operand:GPR 2 "gpc_reg_operand"))) 3285 (set (match_operand:GPR 3 "gpc_reg_operand") 3286 (mod:GPR (match_dup 1) 3287 (match_dup 2)))] 3288 "TARGET_MODULO 3289 && ! reg_mentioned_p (operands[0], operands[1]) 3290 && ! reg_mentioned_p (operands[0], operands[2]) 3291 && ! reg_mentioned_p (operands[3], operands[1]) 3292 && ! reg_mentioned_p (operands[3], operands[2])" 3293 [(set (match_dup 0) 3294 (div:GPR (match_dup 1) 3295 (match_dup 2))) 3296 (set (match_dup 3) 3297 (mult:GPR (match_dup 0) 3298 (match_dup 2))) 3299 (set (match_dup 3) 3300 (minus:GPR (match_dup 1) 3301 (match_dup 3)))]) 3302 3303(define_peephole2 3304 [(set (match_operand:GPR 0 "gpc_reg_operand") 3305 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand") 3306 (match_operand:GPR 2 "gpc_reg_operand"))) 3307 (set (match_operand:GPR 3 "gpc_reg_operand") 3308 (umod:GPR (match_dup 1) 3309 (match_dup 2)))] 3310 "TARGET_MODULO 3311 && ! reg_mentioned_p (operands[0], operands[1]) 3312 && ! reg_mentioned_p (operands[0], operands[2]) 3313 && ! reg_mentioned_p (operands[3], operands[1]) 3314 && ! reg_mentioned_p (operands[3], operands[2])" 3315 [(set (match_dup 0) 3316 (udiv:GPR (match_dup 1) 3317 (match_dup 2))) 3318 (set (match_dup 3) 3319 (mult:GPR (match_dup 0) 3320 (match_dup 2))) 3321 (set (match_dup 3) 3322 (minus:GPR (match_dup 1) 3323 (match_dup 3)))]) 3324 3325 3326;; Logical instructions 3327;; The logical instructions are mostly combined by using match_operator, 3328;; but the plain AND insns are somewhat different because there is no 3329;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all 3330;; those rotate-and-mask operations. Thus, the AND insns come first. 3331 3332(define_expand "and<mode>3" 3333 [(set (match_operand:SDI 0 "gpc_reg_operand") 3334 (and:SDI (match_operand:SDI 1 "gpc_reg_operand") 3335 (match_operand:SDI 2 "reg_or_cint_operand")))] 3336 "" 3337{ 3338 if (<MODE>mode == DImode && !TARGET_POWERPC64) 3339 { 3340 rs6000_split_logical (operands, AND, false, false, false); 3341 DONE; 3342 } 3343 3344 if (CONST_INT_P (operands[2])) 3345 { 3346 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode)) 3347 { 3348 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2])); 3349 DONE; 3350 } 3351 3352 if (logical_const_operand (operands[2], <MODE>mode)) 3353 { 3354 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2])); 3355 DONE; 3356 } 3357 3358 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode)) 3359 { 3360 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0); 3361 DONE; 3362 } 3363 3364 operands[2] = force_reg (<MODE>mode, operands[2]); 3365 } 3366}) 3367 3368 3369(define_insn "and<mode>3_imm" 3370 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3371 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3372 (match_operand:GPR 2 "logical_const_operand" "n"))) 3373 (clobber (match_scratch:CC 3 "=x"))] 3374 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3375 "andi%e2. %0,%1,%u2" 3376 [(set_attr "type" "logical") 3377 (set_attr "dot" "yes")]) 3378 3379(define_insn_and_split "*and<mode>3_imm_dot" 3380 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3381 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3382 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3383 (const_int 0))) 3384 (clobber (match_scratch:GPR 0 "=r,r")) 3385 (clobber (match_scratch:CC 4 "=X,x"))] 3386 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3387 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3388 "@ 3389 andi%e2. %0,%1,%u2 3390 #" 3391 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3392 [(parallel [(set (match_dup 0) 3393 (and:GPR (match_dup 1) 3394 (match_dup 2))) 3395 (clobber (match_dup 4))]) 3396 (set (match_dup 3) 3397 (compare:CC (match_dup 0) 3398 (const_int 0)))] 3399 "" 3400 [(set_attr "type" "logical") 3401 (set_attr "dot" "yes") 3402 (set_attr "length" "4,8")]) 3403 3404(define_insn_and_split "*and<mode>3_imm_dot2" 3405 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3406 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3407 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3408 (const_int 0))) 3409 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3410 (and:GPR (match_dup 1) 3411 (match_dup 2))) 3412 (clobber (match_scratch:CC 4 "=X,x"))] 3413 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3414 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3415 "@ 3416 andi%e2. %0,%1,%u2 3417 #" 3418 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3419 [(parallel [(set (match_dup 0) 3420 (and:GPR (match_dup 1) 3421 (match_dup 2))) 3422 (clobber (match_dup 4))]) 3423 (set (match_dup 3) 3424 (compare:CC (match_dup 0) 3425 (const_int 0)))] 3426 "" 3427 [(set_attr "type" "logical") 3428 (set_attr "dot" "yes") 3429 (set_attr "length" "4,8")]) 3430 3431(define_insn_and_split "*and<mode>3_imm_mask_dot" 3432 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3433 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3434 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3435 (const_int 0))) 3436 (clobber (match_scratch:GPR 0 "=r,r"))] 3437 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3438 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3439 "@ 3440 andi%e2. %0,%1,%u2 3441 #" 3442 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3443 [(set (match_dup 0) 3444 (and:GPR (match_dup 1) 3445 (match_dup 2))) 3446 (set (match_dup 3) 3447 (compare:CC (match_dup 0) 3448 (const_int 0)))] 3449 "" 3450 [(set_attr "type" "logical") 3451 (set_attr "dot" "yes") 3452 (set_attr "length" "4,8")]) 3453 3454(define_insn_and_split "*and<mode>3_imm_mask_dot2" 3455 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y") 3456 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3457 (match_operand:GPR 2 "logical_const_operand" "n,n")) 3458 (const_int 0))) 3459 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3460 (and:GPR (match_dup 1) 3461 (match_dup 2)))] 3462 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3463 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3464 "@ 3465 andi%e2. %0,%1,%u2 3466 #" 3467 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3468 [(set (match_dup 0) 3469 (and:GPR (match_dup 1) 3470 (match_dup 2))) 3471 (set (match_dup 3) 3472 (compare:CC (match_dup 0) 3473 (const_int 0)))] 3474 "" 3475 [(set_attr "type" "logical") 3476 (set_attr "dot" "yes") 3477 (set_attr "length" "4,8")]) 3478 3479(define_insn "*and<mode>3_imm_dot_shifted" 3480 [(set (match_operand:CC 3 "cc_reg_operand" "=x") 3481 (compare:CC 3482 (and:GPR 3483 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3484 (match_operand:SI 4 "const_int_operand" "n")) 3485 (match_operand:GPR 2 "const_int_operand" "n")) 3486 (const_int 0))) 3487 (clobber (match_scratch:GPR 0 "=r"))] 3488 "logical_const_operand (GEN_INT (UINTVAL (operands[2]) 3489 << INTVAL (operands[4])), 3490 DImode) 3491 && (<MODE>mode == Pmode 3492 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)" 3493{ 3494 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4])); 3495 return "andi%e2. %0,%1,%u2"; 3496} 3497 [(set_attr "type" "logical") 3498 (set_attr "dot" "yes")]) 3499 3500 3501(define_insn "and<mode>3_mask" 3502 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3503 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3504 (match_operand:GPR 2 "const_int_operand" "n")))] 3505 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3506{ 3507 return rs6000_insn_for_and_mask (<MODE>mode, operands, false); 3508} 3509 [(set_attr "type" "shift")]) 3510 3511(define_insn_and_split "*and<mode>3_mask_dot" 3512 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3513 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3514 (match_operand:GPR 2 "const_int_operand" "n,n")) 3515 (const_int 0))) 3516 (clobber (match_scratch:GPR 0 "=r,r"))] 3517 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3518 && !logical_const_operand (operands[2], <MODE>mode) 3519 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3520{ 3521 if (which_alternative == 0) 3522 return rs6000_insn_for_and_mask (<MODE>mode, operands, true); 3523 else 3524 return "#"; 3525} 3526 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3527 [(set (match_dup 0) 3528 (and:GPR (match_dup 1) 3529 (match_dup 2))) 3530 (set (match_dup 3) 3531 (compare:CC (match_dup 0) 3532 (const_int 0)))] 3533 "" 3534 [(set_attr "type" "shift") 3535 (set_attr "dot" "yes") 3536 (set_attr "length" "4,8")]) 3537 3538(define_insn_and_split "*and<mode>3_mask_dot2" 3539 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3540 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3541 (match_operand:GPR 2 "const_int_operand" "n,n")) 3542 (const_int 0))) 3543 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3544 (and:GPR (match_dup 1) 3545 (match_dup 2)))] 3546 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3547 && !logical_const_operand (operands[2], <MODE>mode) 3548 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)" 3549{ 3550 if (which_alternative == 0) 3551 return rs6000_insn_for_and_mask (<MODE>mode, operands, true); 3552 else 3553 return "#"; 3554} 3555 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 3556 [(set (match_dup 0) 3557 (and:GPR (match_dup 1) 3558 (match_dup 2))) 3559 (set (match_dup 3) 3560 (compare:CC (match_dup 0) 3561 (const_int 0)))] 3562 "" 3563 [(set_attr "type" "shift") 3564 (set_attr "dot" "yes") 3565 (set_attr "length" "4,8")]) 3566 3567 3568(define_insn_and_split "*and<mode>3_2insn" 3569 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3570 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r") 3571 (match_operand:GPR 2 "const_int_operand" "n")))] 3572 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3573 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3574 || logical_const_operand (operands[2], <MODE>mode))" 3575 "#" 3576 "&& 1" 3577 [(pc)] 3578{ 3579 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0); 3580 DONE; 3581} 3582 [(set_attr "type" "shift") 3583 (set_attr "length" "8")]) 3584 3585(define_insn_and_split "*and<mode>3_2insn_dot" 3586 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3587 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3588 (match_operand:GPR 2 "const_int_operand" "n,n")) 3589 (const_int 0))) 3590 (clobber (match_scratch:GPR 0 "=r,r"))] 3591 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3592 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3593 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3594 || logical_const_operand (operands[2], <MODE>mode))" 3595 "#" 3596 "&& reload_completed" 3597 [(pc)] 3598{ 3599 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1); 3600 DONE; 3601} 3602 [(set_attr "type" "shift") 3603 (set_attr "dot" "yes") 3604 (set_attr "length" "8,12")]) 3605 3606(define_insn_and_split "*and<mode>3_2insn_dot2" 3607 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 3608 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r") 3609 (match_operand:GPR 2 "const_int_operand" "n,n")) 3610 (const_int 0))) 3611 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3612 (and:GPR (match_dup 1) 3613 (match_dup 2)))] 3614 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff) 3615 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode) 3616 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode) 3617 || logical_const_operand (operands[2], <MODE>mode))" 3618 "#" 3619 "&& reload_completed" 3620 [(pc)] 3621{ 3622 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2); 3623 DONE; 3624} 3625 [(set_attr "type" "shift") 3626 (set_attr "dot" "yes") 3627 (set_attr "length" "8,12")]) 3628 3629 3630(define_expand "<code><mode>3" 3631 [(set (match_operand:SDI 0 "gpc_reg_operand") 3632 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand") 3633 (match_operand:SDI 2 "reg_or_cint_operand")))] 3634 "" 3635{ 3636 if (<MODE>mode == DImode && !TARGET_POWERPC64) 3637 { 3638 rs6000_split_logical (operands, <CODE>, false, false, false); 3639 DONE; 3640 } 3641 3642 if (non_logical_cint_operand (operands[2], <MODE>mode)) 3643 { 3644 rtx tmp = ((!can_create_pseudo_p () 3645 || rtx_equal_p (operands[0], operands[1])) 3646 ? operands[0] : gen_reg_rtx (<MODE>mode)); 3647 3648 HOST_WIDE_INT value = INTVAL (operands[2]); 3649 HOST_WIDE_INT lo = value & 0xffff; 3650 HOST_WIDE_INT hi = value - lo; 3651 3652 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi))); 3653 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo))); 3654 DONE; 3655 } 3656 3657 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode)) 3658 operands[2] = force_reg (<MODE>mode, operands[2]); 3659}) 3660 3661(define_split 3662 [(set (match_operand:GPR 0 "gpc_reg_operand") 3663 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand") 3664 (match_operand:GPR 2 "non_logical_cint_operand")))] 3665 "" 3666 [(set (match_dup 3) 3667 (iorxor:GPR (match_dup 1) 3668 (match_dup 4))) 3669 (set (match_dup 0) 3670 (iorxor:GPR (match_dup 3) 3671 (match_dup 5)))] 3672{ 3673 operands[3] = ((!can_create_pseudo_p () 3674 || rtx_equal_p (operands[0], operands[1])) 3675 ? operands[0] : gen_reg_rtx (<MODE>mode)); 3676 3677 HOST_WIDE_INT value = INTVAL (operands[2]); 3678 HOST_WIDE_INT lo = value & 0xffff; 3679 HOST_WIDE_INT hi = value - lo; 3680 3681 operands[4] = GEN_INT (hi); 3682 operands[5] = GEN_INT (lo); 3683}) 3684 3685(define_insn "*bool<mode>3_imm" 3686 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3687 (match_operator:GPR 3 "boolean_or_operator" 3688 [(match_operand:GPR 1 "gpc_reg_operand" "%r") 3689 (match_operand:GPR 2 "logical_const_operand" "n")]))] 3690 "" 3691 "%q3i%e2 %0,%1,%u2" 3692 [(set_attr "type" "logical")]) 3693 3694(define_insn "*bool<mode>3" 3695 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3696 (match_operator:GPR 3 "boolean_operator" 3697 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3698 (match_operand:GPR 2 "gpc_reg_operand" "r")]))] 3699 "" 3700 "%q3 %0,%1,%2" 3701 [(set_attr "type" "logical")]) 3702 3703(define_insn_and_split "*bool<mode>3_dot" 3704 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3705 (compare:CC (match_operator:GPR 3 "boolean_operator" 3706 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3707 (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) 3708 (const_int 0))) 3709 (clobber (match_scratch:GPR 0 "=r,r"))] 3710 "<MODE>mode == Pmode" 3711 "@ 3712 %q3. %0,%1,%2 3713 #" 3714 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3715 [(set (match_dup 0) 3716 (match_dup 3)) 3717 (set (match_dup 4) 3718 (compare:CC (match_dup 0) 3719 (const_int 0)))] 3720 "" 3721 [(set_attr "type" "logical") 3722 (set_attr "dot" "yes") 3723 (set_attr "length" "4,8")]) 3724 3725(define_insn_and_split "*bool<mode>3_dot2" 3726 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3727 (compare:CC (match_operator:GPR 3 "boolean_operator" 3728 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3729 (match_operand:GPR 2 "gpc_reg_operand" "r,r")]) 3730 (const_int 0))) 3731 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3732 (match_dup 3))] 3733 "<MODE>mode == Pmode" 3734 "@ 3735 %q3. %0,%1,%2 3736 #" 3737 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3738 [(set (match_dup 0) 3739 (match_dup 3)) 3740 (set (match_dup 4) 3741 (compare:CC (match_dup 0) 3742 (const_int 0)))] 3743 "" 3744 [(set_attr "type" "logical") 3745 (set_attr "dot" "yes") 3746 (set_attr "length" "4,8")]) 3747 3748 3749(define_insn "*boolc<mode>3" 3750 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3751 (match_operator:GPR 3 "boolean_operator" 3752 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")) 3753 (match_operand:GPR 1 "gpc_reg_operand" "r")]))] 3754 "" 3755 "%q3 %0,%1,%2" 3756 [(set_attr "type" "logical")]) 3757 3758(define_insn_and_split "*boolc<mode>3_dot" 3759 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3760 (compare:CC (match_operator:GPR 3 "boolean_operator" 3761 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3762 (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) 3763 (const_int 0))) 3764 (clobber (match_scratch:GPR 0 "=r,r"))] 3765 "<MODE>mode == Pmode" 3766 "@ 3767 %q3. %0,%1,%2 3768 #" 3769 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3770 [(set (match_dup 0) 3771 (match_dup 3)) 3772 (set (match_dup 4) 3773 (compare:CC (match_dup 0) 3774 (const_int 0)))] 3775 "" 3776 [(set_attr "type" "logical") 3777 (set_attr "dot" "yes") 3778 (set_attr "length" "4,8")]) 3779 3780(define_insn_and_split "*boolc<mode>3_dot2" 3781 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3782 (compare:CC (match_operator:GPR 3 "boolean_operator" 3783 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")) 3784 (match_operand:GPR 1 "gpc_reg_operand" "r,r")]) 3785 (const_int 0))) 3786 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3787 (match_dup 3))] 3788 "<MODE>mode == Pmode" 3789 "@ 3790 %q3. %0,%1,%2 3791 #" 3792 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3793 [(set (match_dup 0) 3794 (match_dup 3)) 3795 (set (match_dup 4) 3796 (compare:CC (match_dup 0) 3797 (const_int 0)))] 3798 "" 3799 [(set_attr "type" "logical") 3800 (set_attr "dot" "yes") 3801 (set_attr "length" "4,8")]) 3802 3803 3804(define_insn "*boolcc<mode>3" 3805 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3806 (match_operator:GPR 3 "boolean_operator" 3807 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")) 3808 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))] 3809 "" 3810 "%q3 %0,%1,%2" 3811 [(set_attr "type" "logical")]) 3812 3813(define_insn_and_split "*boolcc<mode>3_dot" 3814 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3815 (compare:CC (match_operator:GPR 3 "boolean_operator" 3816 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 3817 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) 3818 (const_int 0))) 3819 (clobber (match_scratch:GPR 0 "=r,r"))] 3820 "<MODE>mode == Pmode" 3821 "@ 3822 %q3. %0,%1,%2 3823 #" 3824 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3825 [(set (match_dup 0) 3826 (match_dup 3)) 3827 (set (match_dup 4) 3828 (compare:CC (match_dup 0) 3829 (const_int 0)))] 3830 "" 3831 [(set_attr "type" "logical") 3832 (set_attr "dot" "yes") 3833 (set_attr "length" "4,8")]) 3834 3835(define_insn_and_split "*boolcc<mode>3_dot2" 3836 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y") 3837 (compare:CC (match_operator:GPR 3 "boolean_operator" 3838 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")) 3839 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))]) 3840 (const_int 0))) 3841 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3842 (match_dup 3))] 3843 "<MODE>mode == Pmode" 3844 "@ 3845 %q3. %0,%1,%2 3846 #" 3847 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)" 3848 [(set (match_dup 0) 3849 (match_dup 3)) 3850 (set (match_dup 4) 3851 (compare:CC (match_dup 0) 3852 (const_int 0)))] 3853 "" 3854 [(set_attr "type" "logical") 3855 (set_attr "dot" "yes") 3856 (set_attr "length" "4,8")]) 3857 3858 3859;; TODO: Should have dots of this as well. 3860(define_insn "*eqv<mode>3" 3861 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3862 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 3863 (match_operand:GPR 2 "gpc_reg_operand" "r"))))] 3864 "" 3865 "eqv %0,%1,%2" 3866 [(set_attr "type" "logical")]) 3867 3868;; Rotate-and-mask and insert. 3869 3870(define_insn "*rotl<mode>3_mask" 3871 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3872 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3873 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3874 (match_operand:SI 2 "reg_or_cint_operand" "rn")]) 3875 (match_operand:GPR 3 "const_int_operand" "n")))] 3876 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3877{ 3878 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false); 3879} 3880 [(set_attr "type" "shift") 3881 (set_attr "maybe_var_shift" "yes")]) 3882 3883(define_insn_and_split "*rotl<mode>3_mask_dot" 3884 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") 3885 (compare:CC 3886 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3887 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3888 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")]) 3889 (match_operand:GPR 3 "const_int_operand" "n,n")) 3890 (const_int 0))) 3891 (clobber (match_scratch:GPR 0 "=r,r"))] 3892 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff) 3893 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3894{ 3895 if (which_alternative == 0) 3896 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true); 3897 else 3898 return "#"; 3899} 3900 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)" 3901 [(set (match_dup 0) 3902 (and:GPR (match_dup 4) 3903 (match_dup 3))) 3904 (set (match_dup 5) 3905 (compare:CC (match_dup 0) 3906 (const_int 0)))] 3907 "" 3908 [(set_attr "type" "shift") 3909 (set_attr "maybe_var_shift" "yes") 3910 (set_attr "dot" "yes") 3911 (set_attr "length" "4,8")]) 3912 3913(define_insn_and_split "*rotl<mode>3_mask_dot2" 3914 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y") 3915 (compare:CC 3916 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3917 [(match_operand:GPR 1 "gpc_reg_operand" "r,r") 3918 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")]) 3919 (match_operand:GPR 3 "const_int_operand" "n,n")) 3920 (const_int 0))) 3921 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 3922 (and:GPR (match_dup 4) 3923 (match_dup 3)))] 3924 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff) 3925 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)" 3926{ 3927 if (which_alternative == 0) 3928 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true); 3929 else 3930 return "#"; 3931} 3932 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)" 3933 [(set (match_dup 0) 3934 (and:GPR (match_dup 4) 3935 (match_dup 3))) 3936 (set (match_dup 5) 3937 (compare:CC (match_dup 0) 3938 (const_int 0)))] 3939 "" 3940 [(set_attr "type" "shift") 3941 (set_attr "maybe_var_shift" "yes") 3942 (set_attr "dot" "yes") 3943 (set_attr "length" "4,8")]) 3944 3945; Special case for less-than-0. We can do it with just one machine 3946; instruction, but the generic optimizers do not realise it is cheap. 3947(define_insn "*lt0_<mode>di" 3948 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3949 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r") 3950 (const_int 0)))] 3951 "TARGET_POWERPC64" 3952 "srdi %0,%1,63" 3953 [(set_attr "type" "shift")]) 3954 3955(define_insn "*lt0_<mode>si" 3956 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3957 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r") 3958 (const_int 0)))] 3959 "" 3960 "rlwinm %0,%1,1,31,31" 3961 [(set_attr "type" "shift")]) 3962 3963 3964 3965; Two forms for insert (the two arms of the IOR are not canonicalized, 3966; both are an AND so are the same precedence). 3967(define_insn "*rotl<mode>3_insert" 3968 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3969 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3970 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3971 (match_operand:SI 2 "const_int_operand" "n")]) 3972 (match_operand:GPR 3 "const_int_operand" "n")) 3973 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0") 3974 (match_operand:GPR 6 "const_int_operand" "n"))))] 3975 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode) 3976 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0" 3977{ 3978 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false); 3979} 3980 [(set_attr "type" "insert")]) 3981; FIXME: this needs an attr "size", so that the scheduler can see the 3982; difference between rlwimi and rldimi. We also might want dot forms, 3983; but not for rlwimi on POWER4 and similar processors. 3984 3985(define_insn "*rotl<mode>3_insert_2" 3986 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 3987 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0") 3988 (match_operand:GPR 6 "const_int_operand" "n")) 3989 (and:GPR (match_operator:GPR 4 "rotate_mask_operator" 3990 [(match_operand:GPR 1 "gpc_reg_operand" "r") 3991 (match_operand:SI 2 "const_int_operand" "n")]) 3992 (match_operand:GPR 3 "const_int_operand" "n"))))] 3993 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode) 3994 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0" 3995{ 3996 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false); 3997} 3998 [(set_attr "type" "insert")]) 3999 4000; There are also some forms without one of the ANDs. 4001(define_insn "*rotl<mode>3_insert_3" 4002 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4003 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 4004 (match_operand:GPR 4 "const_int_operand" "n")) 4005 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4006 (match_operand:SI 2 "const_int_operand" "n"))))] 4007 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)" 4008{ 4009 if (<MODE>mode == SImode) 4010 return "rlwimi %0,%1,%h2,0,31-%h2"; 4011 else 4012 return "rldimi %0,%1,%H2,0"; 4013} 4014 [(set_attr "type" "insert")]) 4015 4016(define_insn "*rotl<mode>3_insert_4" 4017 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4018 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0") 4019 (match_operand:GPR 4 "const_int_operand" "n")) 4020 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4021 (match_operand:SI 2 "const_int_operand" "n"))))] 4022 "<MODE>mode == SImode && 4023 GET_MODE_PRECISION (<MODE>mode) 4024 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))" 4025{ 4026 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode) 4027 - INTVAL (operands[2])); 4028 if (<MODE>mode == SImode) 4029 return "rlwimi %0,%1,%h2,32-%h2,31"; 4030 else 4031 return "rldimi %0,%1,%H2,64-%H2"; 4032} 4033 [(set_attr "type" "insert")]) 4034 4035(define_insn "*rotlsi3_insert_5" 4036 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 4037 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r") 4038 (match_operand:SI 2 "const_int_operand" "n,n")) 4039 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0") 4040 (match_operand:SI 4 "const_int_operand" "n,n"))))] 4041 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode) 4042 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0 4043 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 4044 "@ 4045 rlwimi %0,%3,0,%4 4046 rlwimi %0,%1,0,%2" 4047 [(set_attr "type" "insert")]) 4048 4049(define_insn "*rotldi3_insert_6" 4050 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4051 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0") 4052 (match_operand:DI 2 "const_int_operand" "n")) 4053 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r") 4054 (match_operand:DI 4 "const_int_operand" "n"))))] 4055 "exact_log2 (-UINTVAL (operands[2])) > 0 4056 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 4057{ 4058 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2]))); 4059 return "rldimi %0,%3,0,%5"; 4060} 4061 [(set_attr "type" "insert") 4062 (set_attr "size" "64")]) 4063 4064(define_insn "*rotldi3_insert_7" 4065 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4066 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r") 4067 (match_operand:DI 4 "const_int_operand" "n")) 4068 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0") 4069 (match_operand:DI 2 "const_int_operand" "n"))))] 4070 "exact_log2 (-UINTVAL (operands[2])) > 0 4071 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0" 4072{ 4073 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2]))); 4074 return "rldimi %0,%3,0,%5"; 4075} 4076 [(set_attr "type" "insert") 4077 (set_attr "size" "64")]) 4078 4079 4080; This handles the important case of multiple-precision shifts. There is 4081; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns. 4082(define_split 4083 [(set (match_operand:GPR 0 "gpc_reg_operand") 4084 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 4085 (match_operand:SI 3 "const_int_operand")) 4086 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand") 4087 (match_operand:SI 4 "const_int_operand"))))] 4088 "can_create_pseudo_p () 4089 && INTVAL (operands[3]) + INTVAL (operands[4]) 4090 >= GET_MODE_PRECISION (<MODE>mode)" 4091 [(set (match_dup 5) 4092 (lshiftrt:GPR (match_dup 2) 4093 (match_dup 4))) 4094 (set (match_dup 0) 4095 (ior:GPR (and:GPR (match_dup 5) 4096 (match_dup 6)) 4097 (ashift:GPR (match_dup 1) 4098 (match_dup 3))))] 4099{ 4100 unsigned HOST_WIDE_INT mask = 1; 4101 mask = (mask << INTVAL (operands[3])) - 1; 4102 operands[5] = gen_reg_rtx (<MODE>mode); 4103 operands[6] = GEN_INT (mask); 4104}) 4105 4106(define_split 4107 [(set (match_operand:GPR 0 "gpc_reg_operand") 4108 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand") 4109 (match_operand:SI 4 "const_int_operand")) 4110 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand") 4111 (match_operand:SI 3 "const_int_operand"))))] 4112 "can_create_pseudo_p () 4113 && INTVAL (operands[3]) + INTVAL (operands[4]) 4114 >= GET_MODE_PRECISION (<MODE>mode)" 4115 [(set (match_dup 5) 4116 (lshiftrt:GPR (match_dup 2) 4117 (match_dup 4))) 4118 (set (match_dup 0) 4119 (ior:GPR (and:GPR (match_dup 5) 4120 (match_dup 6)) 4121 (ashift:GPR (match_dup 1) 4122 (match_dup 3))))] 4123{ 4124 unsigned HOST_WIDE_INT mask = 1; 4125 mask = (mask << INTVAL (operands[3])) - 1; 4126 operands[5] = gen_reg_rtx (<MODE>mode); 4127 operands[6] = GEN_INT (mask); 4128}) 4129 4130 4131; Another important case is setting some bits to 1; we can do that with 4132; an insert instruction, in many cases. 4133(define_insn_and_split "*ior<mode>_mask" 4134 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4135 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0") 4136 (match_operand:GPR 2 "const_int_operand" "n"))) 4137 (clobber (match_scratch:GPR 3 "=r"))] 4138 "!logical_const_operand (operands[2], <MODE>mode) 4139 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)" 4140 "#" 4141 "&& 1" 4142 [(set (match_dup 3) 4143 (const_int -1)) 4144 (set (match_dup 0) 4145 (ior:GPR (and:GPR (rotate:GPR (match_dup 3) 4146 (match_dup 4)) 4147 (match_dup 2)) 4148 (and:GPR (match_dup 1) 4149 (match_dup 5))))] 4150{ 4151 int nb, ne; 4152 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode); 4153 if (GET_CODE (operands[3]) == SCRATCH) 4154 operands[3] = gen_reg_rtx (<MODE>mode); 4155 operands[4] = GEN_INT (ne); 4156 operands[5] = GEN_INT (~UINTVAL (operands[2])); 4157} 4158 [(set_attr "type" "two") 4159 (set_attr "length" "8")]) 4160 4161 4162; Yet another case is an rldimi with the second value coming from memory. 4163; The zero_extend that should become part of the rldimi is merged into the 4164; load from memory instead. Split things properly again. 4165(define_split 4166 [(set (match_operand:DI 0 "gpc_reg_operand") 4167 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand") 4168 (match_operand:SI 2 "const_int_operand")) 4169 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))] 4170 "INTVAL (operands[2]) == <bits>" 4171 [(set (match_dup 4) 4172 (zero_extend:DI (match_dup 3))) 4173 (set (match_dup 0) 4174 (ior:DI (and:DI (match_dup 4) 4175 (match_dup 5)) 4176 (ashift:DI (match_dup 1) 4177 (match_dup 2))))] 4178{ 4179 operands[4] = gen_reg_rtx (DImode); 4180 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1); 4181}) 4182 4183; rlwimi, too. 4184(define_split 4185 [(set (match_operand:SI 0 "gpc_reg_operand") 4186 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand") 4187 (match_operand:SI 2 "const_int_operand")) 4188 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))] 4189 "INTVAL (operands[2]) == <bits>" 4190 [(set (match_dup 4) 4191 (zero_extend:SI (match_dup 3))) 4192 (set (match_dup 0) 4193 (ior:SI (and:SI (match_dup 4) 4194 (match_dup 5)) 4195 (ashift:SI (match_dup 1) 4196 (match_dup 2))))] 4197{ 4198 operands[4] = gen_reg_rtx (SImode); 4199 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1); 4200}) 4201 4202 4203;; Now the simple shifts. 4204 4205(define_insn "rotl<mode>3" 4206 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4207 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4208 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4209 "" 4210 "rotl<wd>%I2 %0,%1,%<hH>2" 4211 [(set_attr "type" "shift") 4212 (set_attr "maybe_var_shift" "yes")]) 4213 4214(define_insn "*rotlsi3_64" 4215 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4216 (zero_extend:DI 4217 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4218 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4219 "TARGET_POWERPC64" 4220 "rotlw%I2 %0,%1,%h2" 4221 [(set_attr "type" "shift") 4222 (set_attr "maybe_var_shift" "yes")]) 4223 4224(define_insn_and_split "*rotl<mode>3_dot" 4225 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4226 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4227 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4228 (const_int 0))) 4229 (clobber (match_scratch:GPR 0 "=r,r"))] 4230 "<MODE>mode == Pmode" 4231 "@ 4232 rotl<wd>%I2. %0,%1,%<hH>2 4233 #" 4234 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4235 [(set (match_dup 0) 4236 (rotate:GPR (match_dup 1) 4237 (match_dup 2))) 4238 (set (match_dup 3) 4239 (compare:CC (match_dup 0) 4240 (const_int 0)))] 4241 "" 4242 [(set_attr "type" "shift") 4243 (set_attr "maybe_var_shift" "yes") 4244 (set_attr "dot" "yes") 4245 (set_attr "length" "4,8")]) 4246 4247(define_insn_and_split "*rotl<mode>3_dot2" 4248 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4249 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4250 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4251 (const_int 0))) 4252 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4253 (rotate:GPR (match_dup 1) 4254 (match_dup 2)))] 4255 "<MODE>mode == Pmode" 4256 "@ 4257 rotl<wd>%I2. %0,%1,%<hH>2 4258 #" 4259 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4260 [(set (match_dup 0) 4261 (rotate:GPR (match_dup 1) 4262 (match_dup 2))) 4263 (set (match_dup 3) 4264 (compare:CC (match_dup 0) 4265 (const_int 0)))] 4266 "" 4267 [(set_attr "type" "shift") 4268 (set_attr "maybe_var_shift" "yes") 4269 (set_attr "dot" "yes") 4270 (set_attr "length" "4,8")]) 4271 4272 4273(define_insn "ashl<mode>3" 4274 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4275 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4276 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4277 "" 4278 "sl<wd>%I2 %0,%1,%<hH>2" 4279 [(set_attr "type" "shift") 4280 (set_attr "maybe_var_shift" "yes")]) 4281 4282(define_insn "*ashlsi3_64" 4283 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4284 (zero_extend:DI 4285 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4286 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4287 "TARGET_POWERPC64" 4288 "slw%I2 %0,%1,%h2" 4289 [(set_attr "type" "shift") 4290 (set_attr "maybe_var_shift" "yes")]) 4291 4292(define_insn_and_split "*ashl<mode>3_dot" 4293 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4294 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4295 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4296 (const_int 0))) 4297 (clobber (match_scratch:GPR 0 "=r,r"))] 4298 "<MODE>mode == Pmode" 4299 "@ 4300 sl<wd>%I2. %0,%1,%<hH>2 4301 #" 4302 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4303 [(set (match_dup 0) 4304 (ashift:GPR (match_dup 1) 4305 (match_dup 2))) 4306 (set (match_dup 3) 4307 (compare:CC (match_dup 0) 4308 (const_int 0)))] 4309 "" 4310 [(set_attr "type" "shift") 4311 (set_attr "maybe_var_shift" "yes") 4312 (set_attr "dot" "yes") 4313 (set_attr "length" "4,8")]) 4314 4315(define_insn_and_split "*ashl<mode>3_dot2" 4316 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4317 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4318 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4319 (const_int 0))) 4320 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4321 (ashift:GPR (match_dup 1) 4322 (match_dup 2)))] 4323 "<MODE>mode == Pmode" 4324 "@ 4325 sl<wd>%I2. %0,%1,%<hH>2 4326 #" 4327 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4328 [(set (match_dup 0) 4329 (ashift:GPR (match_dup 1) 4330 (match_dup 2))) 4331 (set (match_dup 3) 4332 (compare:CC (match_dup 0) 4333 (const_int 0)))] 4334 "" 4335 [(set_attr "type" "shift") 4336 (set_attr "maybe_var_shift" "yes") 4337 (set_attr "dot" "yes") 4338 (set_attr "length" "4,8")]) 4339 4340;; Pretend we have a memory form of extswsli until register allocation is done 4341;; so that we use LWZ to load the value from memory, instead of LWA. 4342(define_insn_and_split "ashdi3_extswsli" 4343 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 4344 (ashift:DI 4345 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m")) 4346 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))] 4347 "TARGET_EXTSWSLI" 4348 "@ 4349 extswsli %0,%1,%2 4350 #" 4351 "&& reload_completed && MEM_P (operands[1])" 4352 [(set (match_dup 3) 4353 (match_dup 1)) 4354 (set (match_dup 0) 4355 (ashift:DI (sign_extend:DI (match_dup 3)) 4356 (match_dup 2)))] 4357{ 4358 operands[3] = gen_lowpart (SImode, operands[0]); 4359} 4360 [(set_attr "type" "shift") 4361 (set_attr "maybe_var_shift" "no")]) 4362 4363 4364(define_insn_and_split "ashdi3_extswsli_dot" 4365 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y") 4366 (compare:CC 4367 (ashift:DI 4368 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m")) 4369 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n")) 4370 (const_int 0))) 4371 (clobber (match_scratch:DI 0 "=r,r,r,r"))] 4372 "TARGET_EXTSWSLI" 4373 "@ 4374 extswsli. %0,%1,%2 4375 # 4376 # 4377 #" 4378 "&& reload_completed 4379 && (cc_reg_not_cr0_operand (operands[3], CCmode) 4380 || memory_operand (operands[1], SImode))" 4381 [(pc)] 4382{ 4383 rtx dest = operands[0]; 4384 rtx src = operands[1]; 4385 rtx shift = operands[2]; 4386 rtx cr = operands[3]; 4387 rtx src2; 4388 4389 if (!MEM_P (src)) 4390 src2 = src; 4391 else 4392 { 4393 src2 = gen_lowpart (SImode, dest); 4394 emit_move_insn (src2, src); 4395 } 4396 4397 if (REGNO (cr) == CR0_REGNO) 4398 { 4399 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr)); 4400 DONE; 4401 } 4402 4403 emit_insn (gen_ashdi3_extswsli (dest, src2, shift)); 4404 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx))); 4405 DONE; 4406} 4407 [(set_attr "type" "shift") 4408 (set_attr "maybe_var_shift" "no") 4409 (set_attr "dot" "yes") 4410 (set_attr "length" "4,8,8,12")]) 4411 4412(define_insn_and_split "ashdi3_extswsli_dot2" 4413 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y") 4414 (compare:CC 4415 (ashift:DI 4416 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m")) 4417 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n")) 4418 (const_int 0))) 4419 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r") 4420 (ashift:DI (sign_extend:DI (match_dup 1)) 4421 (match_dup 2)))] 4422 "TARGET_EXTSWSLI" 4423 "@ 4424 extswsli. %0,%1,%2 4425 # 4426 # 4427 #" 4428 "&& reload_completed 4429 && (cc_reg_not_cr0_operand (operands[3], CCmode) 4430 || memory_operand (operands[1], SImode))" 4431 [(pc)] 4432{ 4433 rtx dest = operands[0]; 4434 rtx src = operands[1]; 4435 rtx shift = operands[2]; 4436 rtx cr = operands[3]; 4437 rtx src2; 4438 4439 if (!MEM_P (src)) 4440 src2 = src; 4441 else 4442 { 4443 src2 = gen_lowpart (SImode, dest); 4444 emit_move_insn (src2, src); 4445 } 4446 4447 if (REGNO (cr) == CR0_REGNO) 4448 { 4449 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr)); 4450 DONE; 4451 } 4452 4453 emit_insn (gen_ashdi3_extswsli (dest, src2, shift)); 4454 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx))); 4455 DONE; 4456} 4457 [(set_attr "type" "shift") 4458 (set_attr "maybe_var_shift" "no") 4459 (set_attr "dot" "yes") 4460 (set_attr "length" "4,8,8,12")]) 4461 4462(define_insn "lshr<mode>3" 4463 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4464 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4465 (match_operand:SI 2 "reg_or_cint_operand" "rn")))] 4466 "" 4467 "sr<wd>%I2 %0,%1,%<hH>2" 4468 [(set_attr "type" "shift") 4469 (set_attr "maybe_var_shift" "yes")]) 4470 4471(define_insn "*lshrsi3_64" 4472 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4473 (zero_extend:DI 4474 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4475 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))] 4476 "TARGET_POWERPC64" 4477 "srw%I2 %0,%1,%h2" 4478 [(set_attr "type" "shift") 4479 (set_attr "maybe_var_shift" "yes")]) 4480 4481(define_insn_and_split "*lshr<mode>3_dot" 4482 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4483 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4484 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4485 (const_int 0))) 4486 (clobber (match_scratch:GPR 0 "=r,r"))] 4487 "<MODE>mode == Pmode" 4488 "@ 4489 sr<wd>%I2. %0,%1,%<hH>2 4490 #" 4491 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4492 [(set (match_dup 0) 4493 (lshiftrt:GPR (match_dup 1) 4494 (match_dup 2))) 4495 (set (match_dup 3) 4496 (compare:CC (match_dup 0) 4497 (const_int 0)))] 4498 "" 4499 [(set_attr "type" "shift") 4500 (set_attr "maybe_var_shift" "yes") 4501 (set_attr "dot" "yes") 4502 (set_attr "length" "4,8")]) 4503 4504(define_insn_and_split "*lshr<mode>3_dot2" 4505 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4506 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4507 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4508 (const_int 0))) 4509 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4510 (lshiftrt:GPR (match_dup 1) 4511 (match_dup 2)))] 4512 "<MODE>mode == Pmode" 4513 "@ 4514 sr<wd>%I2. %0,%1,%<hH>2 4515 #" 4516 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4517 [(set (match_dup 0) 4518 (lshiftrt:GPR (match_dup 1) 4519 (match_dup 2))) 4520 (set (match_dup 3) 4521 (compare:CC (match_dup 0) 4522 (const_int 0)))] 4523 "" 4524 [(set_attr "type" "shift") 4525 (set_attr "maybe_var_shift" "yes") 4526 (set_attr "dot" "yes") 4527 (set_attr "length" "4,8")]) 4528 4529 4530(define_insn "ashr<mode>3" 4531 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 4532 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 4533 (match_operand:SI 2 "reg_or_cint_operand" "rn"))) 4534 (clobber (reg:GPR CA_REGNO))] 4535 "" 4536 "sra<wd>%I2 %0,%1,%<hH>2" 4537 [(set_attr "type" "shift") 4538 (set_attr "maybe_var_shift" "yes")]) 4539 4540(define_insn "*ashrsi3_64" 4541 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 4542 (sign_extend:DI 4543 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r") 4544 (match_operand:SI 2 "reg_or_cint_operand" "rn")))) 4545 (clobber (reg:SI CA_REGNO))] 4546 "TARGET_POWERPC64" 4547 "sraw%I2 %0,%1,%h2" 4548 [(set_attr "type" "shift") 4549 (set_attr "maybe_var_shift" "yes")]) 4550 4551(define_insn_and_split "*ashr<mode>3_dot" 4552 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4553 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4554 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4555 (const_int 0))) 4556 (clobber (match_scratch:GPR 0 "=r,r")) 4557 (clobber (reg:GPR CA_REGNO))] 4558 "<MODE>mode == Pmode" 4559 "@ 4560 sra<wd>%I2. %0,%1,%<hH>2 4561 #" 4562 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4563 [(parallel [(set (match_dup 0) 4564 (ashiftrt:GPR (match_dup 1) 4565 (match_dup 2))) 4566 (clobber (reg:GPR CA_REGNO))]) 4567 (set (match_dup 3) 4568 (compare:CC (match_dup 0) 4569 (const_int 0)))] 4570 "" 4571 [(set_attr "type" "shift") 4572 (set_attr "maybe_var_shift" "yes") 4573 (set_attr "dot" "yes") 4574 (set_attr "length" "4,8")]) 4575 4576(define_insn_and_split "*ashr<mode>3_dot2" 4577 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y") 4578 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r") 4579 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")) 4580 (const_int 0))) 4581 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 4582 (ashiftrt:GPR (match_dup 1) 4583 (match_dup 2))) 4584 (clobber (reg:GPR CA_REGNO))] 4585 "<MODE>mode == Pmode" 4586 "@ 4587 sra<wd>%I2. %0,%1,%<hH>2 4588 #" 4589 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)" 4590 [(parallel [(set (match_dup 0) 4591 (ashiftrt:GPR (match_dup 1) 4592 (match_dup 2))) 4593 (clobber (reg:GPR CA_REGNO))]) 4594 (set (match_dup 3) 4595 (compare:CC (match_dup 0) 4596 (const_int 0)))] 4597 "" 4598 [(set_attr "type" "shift") 4599 (set_attr "maybe_var_shift" "yes") 4600 (set_attr "dot" "yes") 4601 (set_attr "length" "4,8")]) 4602 4603;; Builtins to replace a division to generate FRE reciprocal estimate 4604;; instructions and the necessary fixup instructions 4605(define_expand "recip<mode>3" 4606 [(match_operand:RECIPF 0 "gpc_reg_operand") 4607 (match_operand:RECIPF 1 "gpc_reg_operand") 4608 (match_operand:RECIPF 2 "gpc_reg_operand")] 4609 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)" 4610{ 4611 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false); 4612 DONE; 4613}) 4614 4615;; Split to create division from FRE/FRES/etc. and fixup instead of the normal 4616;; hardware division. This is only done before register allocation and with 4617;; -ffast-math. This must appear before the divsf3/divdf3 insns. 4618;; We used to also check optimize_insn_for_speed_p () but problems with guessed 4619;; frequencies (pr68212/pr77536) yields that unreliable so it was removed. 4620(define_split 4621 [(set (match_operand:RECIPF 0 "gpc_reg_operand") 4622 (div:RECIPF (match_operand 1 "gpc_reg_operand") 4623 (match_operand 2 "gpc_reg_operand")))] 4624 "RS6000_RECIP_AUTO_RE_P (<MODE>mode) 4625 && can_create_pseudo_p () && flag_finite_math_only 4626 && !flag_trapping_math && flag_reciprocal_math" 4627 [(const_int 0)] 4628{ 4629 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); 4630 DONE; 4631}) 4632 4633;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the 4634;; appropriate fixup. 4635(define_expand "rsqrt<mode>2" 4636 [(match_operand:RECIPF 0 "gpc_reg_operand") 4637 (match_operand:RECIPF 1 "gpc_reg_operand")] 4638 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 4639{ 4640 rs6000_emit_swsqrt (operands[0], operands[1], 1); 4641 DONE; 4642}) 4643 4644;; Floating-point insns, excluding normal data motion. We combine the SF/DF 4645;; modes here, and also add in conditional vsx/power8-vector support to access 4646;; values in the traditional Altivec registers if the appropriate 4647;; -mupper-regs-{df,sf} option is enabled. 4648 4649(define_expand "abs<mode>2" 4650 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4651 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] 4652 "TARGET_HARD_FLOAT" 4653 "") 4654 4655(define_insn "*abs<mode>2_fpr" 4656 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4657 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 4658 "TARGET_HARD_FLOAT" 4659 "@ 4660 fabs %0,%1 4661 xsabsdp %x0,%x1" 4662 [(set_attr "type" "fpsimple")]) 4663 4664(define_insn "*nabs<mode>2_fpr" 4665 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4666 (neg:SFDF 4667 (abs:SFDF 4668 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))] 4669 "TARGET_HARD_FLOAT" 4670 "@ 4671 fnabs %0,%1 4672 xsnabsdp %x0,%x1" 4673 [(set_attr "type" "fpsimple")]) 4674 4675(define_expand "neg<mode>2" 4676 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4677 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] 4678 "TARGET_HARD_FLOAT" 4679 "") 4680 4681(define_insn "*neg<mode>2_fpr" 4682 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 4683 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 4684 "TARGET_HARD_FLOAT" 4685 "@ 4686 fneg %0,%1 4687 xsnegdp %x0,%x1" 4688 [(set_attr "type" "fpsimple")]) 4689 4690(define_expand "add<mode>3" 4691 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4692 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4693 (match_operand:SFDF 2 "gpc_reg_operand")))] 4694 "TARGET_HARD_FLOAT" 4695 "") 4696 4697(define_insn "*add<mode>3_fpr" 4698 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 4699 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa") 4700 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 4701 "TARGET_HARD_FLOAT" 4702 "@ 4703 fadd<s> %0,%1,%2 4704 xsadd<sd>p %x0,%x1,%x2" 4705 [(set_attr "type" "fp") 4706 (set_attr "isa" "*,<Fisa>")]) 4707 4708(define_expand "sub<mode>3" 4709 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4710 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4711 (match_operand:SFDF 2 "gpc_reg_operand")))] 4712 "TARGET_HARD_FLOAT" 4713 "") 4714 4715(define_insn "*sub<mode>3_fpr" 4716 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 4717 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa") 4718 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 4719 "TARGET_HARD_FLOAT" 4720 "@ 4721 fsub<s> %0,%1,%2 4722 xssub<sd>p %x0,%x1,%x2" 4723 [(set_attr "type" "fp") 4724 (set_attr "isa" "*,<Fisa>")]) 4725 4726(define_expand "mul<mode>3" 4727 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4728 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4729 (match_operand:SFDF 2 "gpc_reg_operand")))] 4730 "TARGET_HARD_FLOAT" 4731 "") 4732 4733(define_insn "*mul<mode>3_fpr" 4734 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 4735 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa") 4736 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 4737 "TARGET_HARD_FLOAT" 4738 "@ 4739 fmul<s> %0,%1,%2 4740 xsmul<sd>p %x0,%x1,%x2" 4741 [(set_attr "type" "dmul") 4742 (set_attr "isa" "*,<Fisa>")]) 4743 4744(define_expand "div<mode>3" 4745 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4746 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 4747 (match_operand:SFDF 2 "gpc_reg_operand")))] 4748 "TARGET_HARD_FLOAT" 4749{ 4750 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode) 4751 && can_create_pseudo_p () && flag_finite_math_only 4752 && !flag_trapping_math && flag_reciprocal_math) 4753 { 4754 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true); 4755 DONE; 4756 } 4757}) 4758 4759(define_insn "*div<mode>3_fpr" 4760 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 4761 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa") 4762 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 4763 "TARGET_HARD_FLOAT" 4764 "@ 4765 fdiv<s> %0,%1,%2 4766 xsdiv<sd>p %x0,%x1,%x2" 4767 [(set_attr "type" "<sd>div") 4768 (set_attr "isa" "*,<Fisa>")]) 4769 4770(define_insn "*sqrt<mode>2_internal" 4771 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 4772 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))] 4773 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT" 4774 "@ 4775 fsqrt<s> %0,%1 4776 xssqrt<sd>p %x0,%x1" 4777 [(set_attr "type" "<sd>sqrt") 4778 (set_attr "isa" "*,<Fisa>")]) 4779 4780(define_expand "sqrt<mode>2" 4781 [(set (match_operand:SFDF 0 "gpc_reg_operand") 4782 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))] 4783 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT" 4784{ 4785 if (<MODE>mode == SFmode 4786 && TARGET_RECIP_PRECISION 4787 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode) 4788 && !optimize_function_for_size_p (cfun) 4789 && flag_finite_math_only && !flag_trapping_math 4790 && flag_unsafe_math_optimizations) 4791 { 4792 rs6000_emit_swsqrt (operands[0], operands[1], 0); 4793 DONE; 4794 } 4795}) 4796 4797;; Floating point reciprocal approximation 4798(define_insn "fre<sd>" 4799 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 4800 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")] 4801 UNSPEC_FRES))] 4802 "TARGET_<FFRE>" 4803 "@ 4804 fre<s> %0,%1 4805 xsre<sd>p %x0,%x1" 4806 [(set_attr "type" "fp") 4807 (set_attr "isa" "*,<Fisa>")]) 4808 4809(define_expand "fmod<mode>3" 4810 [(use (match_operand:SFDF 0 "gpc_reg_operand")) 4811 (use (match_operand:SFDF 1 "gpc_reg_operand")) 4812 (use (match_operand:SFDF 2 "gpc_reg_operand"))] 4813 "TARGET_HARD_FLOAT 4814 && TARGET_FPRND 4815 && flag_unsafe_math_optimizations" 4816{ 4817 rtx div = gen_reg_rtx (<MODE>mode); 4818 emit_insn (gen_div<mode>3 (div, operands[1], operands[2])); 4819 4820 rtx friz = gen_reg_rtx (<MODE>mode); 4821 emit_insn (gen_btrunc<mode>2 (friz, div)); 4822 4823 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], friz, operands[1])); 4824 DONE; 4825 }) 4826 4827(define_expand "remainder<mode>3" 4828 [(use (match_operand:SFDF 0 "gpc_reg_operand")) 4829 (use (match_operand:SFDF 1 "gpc_reg_operand")) 4830 (use (match_operand:SFDF 2 "gpc_reg_operand"))] 4831 "TARGET_HARD_FLOAT 4832 && TARGET_FPRND 4833 && flag_unsafe_math_optimizations" 4834{ 4835 rtx div = gen_reg_rtx (<MODE>mode); 4836 emit_insn (gen_div<mode>3 (div, operands[1], operands[2])); 4837 4838 rtx frin = gen_reg_rtx (<MODE>mode); 4839 emit_insn (gen_round<mode>2 (frin, div)); 4840 4841 emit_insn (gen_nfms<mode>4 (operands[0], operands[2], frin, operands[1])); 4842 DONE; 4843 }) 4844 4845(define_insn "*rsqrt<mode>2" 4846 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 4847 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")] 4848 UNSPEC_RSQRT))] 4849 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 4850 "@ 4851 frsqrte<s> %0,%1 4852 xsrsqrte<sd>p %x0,%x1" 4853 [(set_attr "type" "fp") 4854 (set_attr "isa" "*,<Fisa>")]) 4855 4856;; Floating point comparisons 4857(define_insn "*cmp<mode>_fpr" 4858 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y") 4859 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa") 4860 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 4861 "TARGET_HARD_FLOAT" 4862 "@ 4863 fcmpu %0,%1,%2 4864 xscmpudp %0,%x1,%x2" 4865 [(set_attr "type" "fpcompare") 4866 (set_attr "isa" "*,<Fisa>")]) 4867 4868;; Floating point conversions 4869(define_expand "extendsfdf2" 4870 [(set (match_operand:DF 0 "gpc_reg_operand") 4871 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))] 4872 "TARGET_HARD_FLOAT" 4873{ 4874 if (HONOR_SNANS (SFmode)) 4875 operands[1] = force_reg (SFmode, operands[1]); 4876}) 4877 4878(define_insn_and_split "*extendsfdf2_fpr" 4879 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v") 4880 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))] 4881 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)" 4882 "@ 4883 # 4884 fmr %0,%1 4885 lfs%U1%X1 %0,%1 4886 # 4887 xscpsgndp %x0,%x1,%x1 4888 lxsspx %x0,%y1 4889 lxssp %0,%1" 4890 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])" 4891 [(const_int 0)] 4892{ 4893 emit_note (NOTE_INSN_DELETED); 4894 DONE; 4895} 4896 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload") 4897 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")]) 4898 4899(define_insn "*extendsfdf2_snan" 4900 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 4901 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))] 4902 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)" 4903 "@ 4904 frsp %0,%1 4905 xsrsp %x0,%x1" 4906 [(set_attr "type" "fp") 4907 (set_attr "isa" "*,p8v")]) 4908 4909(define_expand "truncdfsf2" 4910 [(set (match_operand:SF 0 "gpc_reg_operand") 4911 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))] 4912 "TARGET_HARD_FLOAT" 4913 "") 4914 4915(define_insn "*truncdfsf2_fpr" 4916 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa") 4917 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))] 4918 "TARGET_HARD_FLOAT" 4919 "@ 4920 frsp %0,%1 4921 xsrsp %x0,%x1" 4922 [(set_attr "type" "fp") 4923 (set_attr "isa" "*,p8v")]) 4924 4925;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in 4926;; builtins.c and optabs.c that are not correct for IBM long double 4927;; when little-endian. 4928(define_expand "signbit<mode>2" 4929 [(set (match_dup 2) 4930 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand"))) 4931 (set (match_dup 3) 4932 (subreg:DI (match_dup 2) 0)) 4933 (set (match_dup 4) 4934 (match_dup 5)) 4935 (set (match_operand:SI 0 "gpc_reg_operand") 4936 (match_dup 6))] 4937 "TARGET_HARD_FLOAT 4938 && (!FLOAT128_IEEE_P (<MODE>mode) 4939 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))" 4940{ 4941 if (FLOAT128_IEEE_P (<MODE>mode)) 4942 { 4943 rtx dest = operands[0]; 4944 rtx src = operands[1]; 4945 rtx tmp = gen_reg_rtx (DImode); 4946 rtx dest_di = gen_lowpart (DImode, dest); 4947 4948 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src)); 4949 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63))); 4950 DONE; 4951 } 4952 operands[2] = gen_reg_rtx (DFmode); 4953 operands[3] = gen_reg_rtx (DImode); 4954 if (TARGET_POWERPC64) 4955 { 4956 operands[4] = gen_reg_rtx (DImode); 4957 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63)); 4958 operands[6] = gen_rtx_SUBREG (SImode, operands[4], 4959 WORDS_BIG_ENDIAN ? 4 : 0); 4960 } 4961 else 4962 { 4963 operands[4] = gen_reg_rtx (SImode); 4964 operands[5] = gen_rtx_SUBREG (SImode, operands[3], 4965 WORDS_BIG_ENDIAN ? 0 : 4); 4966 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31)); 4967 } 4968}) 4969 4970;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid 4971;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the 4972;; register allocator would typically move the entire _Float128 item to GPRs (2 4973;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07). 4974;; 4975;; After register allocation, if the _Float128 had originally been in GPRs, the 4976;; split allows the post reload phases to eliminate the move, and do the shift 4977;; directly with the register that contains the signbit. 4978(define_insn_and_split "@signbit<mode>2_dm" 4979 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 4980 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")] 4981 UNSPEC_SIGNBIT))] 4982 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 4983 "@ 4984 mfvsrd %0,%x1 4985 #" 4986 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)" 4987 [(set (match_dup 0) 4988 (match_dup 2))] 4989{ 4990 operands[2] = gen_highpart (DImode, operands[1]); 4991} 4992 [(set_attr "type" "mftgpr,*")]) 4993 4994;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector 4995;; register and then doing a direct move if the value comes from memory. On 4996;; little endian, we have to load the 2nd double-word to get the sign bit. 4997(define_insn_and_split "*signbit<mode>2_dm_mem" 4998 [(set (match_operand:DI 0 "gpc_reg_operand" "=b") 4999 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")] 5000 UNSPEC_SIGNBIT))] 5001 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 5002 "#" 5003 "&& 1" 5004 [(set (match_dup 0) 5005 (match_dup 2))] 5006{ 5007 rtx dest = operands[0]; 5008 rtx src = operands[1]; 5009 rtx addr = XEXP (src, 0); 5010 5011 if (WORDS_BIG_ENDIAN) 5012 operands[2] = adjust_address (src, DImode, 0); 5013 5014 else if (REG_P (addr) || SUBREG_P (addr)) 5015 operands[2] = adjust_address (src, DImode, 8); 5016 5017 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0)) 5018 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode)) 5019 operands[2] = adjust_address (src, DImode, 8); 5020 5021 else 5022 { 5023 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest; 5024 emit_insn (gen_rtx_SET (tmp, addr)); 5025 operands[2] = change_address (src, DImode, 5026 gen_rtx_PLUS (DImode, tmp, GEN_INT (8))); 5027 } 5028}) 5029 5030(define_expand "copysign<mode>3" 5031 [(set (match_dup 3) 5032 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand"))) 5033 (set (match_dup 4) 5034 (neg:SFDF (abs:SFDF (match_dup 1)))) 5035 (set (match_operand:SFDF 0 "gpc_reg_operand") 5036 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand") 5037 (match_dup 5)) 5038 (match_dup 3) 5039 (match_dup 4)))] 5040 "TARGET_HARD_FLOAT 5041 && ((TARGET_PPC_GFXOPT 5042 && !HONOR_NANS (<MODE>mode) 5043 && !HONOR_SIGNED_ZEROS (<MODE>mode)) 5044 || TARGET_CMPB 5045 || VECTOR_UNIT_VSX_P (<MODE>mode))" 5046{ 5047 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode)) 5048 { 5049 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1], 5050 operands[2])); 5051 DONE; 5052 } 5053 5054 operands[3] = gen_reg_rtx (<MODE>mode); 5055 operands[4] = gen_reg_rtx (<MODE>mode); 5056 operands[5] = CONST0_RTX (<MODE>mode); 5057 }) 5058 5059;; Use an unspec rather providing an if-then-else in RTL, to prevent the 5060;; compiler from optimizing -0.0 5061(define_insn "copysign<mode>3_fcpsgn" 5062 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5063 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") 5064 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")] 5065 UNSPEC_COPYSIGN))] 5066 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))" 5067 "@ 5068 fcpsgn %0,%2,%1 5069 xscpsgndp %x0,%x2,%x1" 5070 [(set_attr "type" "fpsimple")]) 5071 5072;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a 5073;; fsel instruction and some auxiliary computations. Then we just have a 5074;; single DEFINE_INSN for fsel and the define_splits to make them if made by 5075;; combine. 5076;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we 5077;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary 5078;; computations. Then we just have a single DEFINE_INSN for fsel and the 5079;; define_splits to make them if made by combine. On VSX machines we have the 5080;; min/max instructions. 5081;; 5082;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector 5083;; to allow either DF/SF to use only traditional registers. 5084 5085(define_expand "s<minmax><mode>3" 5086 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5087 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 5088 (match_operand:SFDF 2 "gpc_reg_operand")))] 5089 "TARGET_MINMAX" 5090{ 5091 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 5092 DONE; 5093}) 5094 5095(define_insn "*s<minmax><mode>3_vsx" 5096 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 5097 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>") 5098 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))] 5099 "TARGET_VSX && TARGET_HARD_FLOAT" 5100{ 5101 return (TARGET_P9_MINMAX 5102 ? "xs<minmax>cdp %x0,%x1,%x2" 5103 : "xs<minmax>dp %x0,%x1,%x2"); 5104} 5105 [(set_attr "type" "fp")]) 5106 5107;; The conditional move instructions allow us to perform max and min operations 5108;; even when we don't have the appropriate max/min instruction using the FSEL 5109;; instruction. 5110 5111(define_insn_and_split "*s<minmax><mode>3_fpr" 5112 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5113 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 5114 (match_operand:SFDF 2 "gpc_reg_operand")))] 5115 "!TARGET_VSX && TARGET_MINMAX" 5116 "#" 5117 "&& 1" 5118 [(const_int 0)] 5119{ 5120 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 5121 DONE; 5122}) 5123 5124(define_expand "mov<mode>cc" 5125 [(set (match_operand:GPR 0 "gpc_reg_operand") 5126 (if_then_else:GPR (match_operand 1 "comparison_operator") 5127 (match_operand:GPR 2 "gpc_reg_operand") 5128 (match_operand:GPR 3 "gpc_reg_operand")))] 5129 "TARGET_ISEL" 5130{ 5131 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 5132 DONE; 5133 else 5134 FAIL; 5135}) 5136 5137;; We use the BASE_REGS for the isel input operands because, if rA is 5138;; 0, the value of 0 is placed in rD upon truth. Similarly for rB 5139;; because we may switch the operands and rB may end up being rA. 5140;; 5141;; We need 2 patterns: an unsigned and a signed pattern. We could 5142;; leave out the mode in operand 4 and use one pattern, but reload can 5143;; change the mode underneath our feet and then gets confused trying 5144;; to reload the value. 5145(define_mode_iterator CCEITHER [CC CCUNS]) 5146(define_mode_attr un [(CC "") (CCUNS "un")]) 5147(define_insn "isel_<un>signed_<GPR:mode>" 5148 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 5149 (if_then_else:GPR 5150 (match_operator 1 "scc_comparison_operator" 5151 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y") 5152 (const_int 0)]) 5153 (match_operand:GPR 2 "reg_or_zero_operand" "O,b") 5154 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] 5155 "TARGET_ISEL" 5156 "isel %0,%2,%3,%j1" 5157 [(set_attr "type" "isel")]) 5158 5159;; These patterns can be useful for combine; they let combine know that 5160;; isel can handle reversed comparisons so long as the operands are 5161;; registers. 5162 5163(define_insn "*isel_reversed_<un>signed_<GPR:mode>" 5164 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 5165 (if_then_else:GPR 5166 (match_operator 1 "scc_rev_comparison_operator" 5167 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y") 5168 (const_int 0)]) 5169 (match_operand:GPR 2 "gpc_reg_operand" "r,r") 5170 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))] 5171 "TARGET_ISEL" 5172{ 5173 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1]))); 5174 return "isel %0,%3,%2,%j1"; 5175} 5176 [(set_attr "type" "isel")]) 5177 5178;; Floating point conditional move 5179(define_expand "mov<mode>cc" 5180 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5181 (if_then_else:SFDF (match_operand 1 "comparison_operator") 5182 (match_operand:SFDF 2 "gpc_reg_operand") 5183 (match_operand:SFDF 3 "gpc_reg_operand")))] 5184 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT" 5185{ 5186 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 5187 DONE; 5188 else 5189 FAIL; 5190}) 5191 5192(define_insn "*fsel<SFDF:mode><SFDF2:mode>4" 5193 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>") 5194 (if_then_else:SFDF 5195 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>") 5196 (match_operand:SFDF2 4 "zero_fp_constant" "F")) 5197 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>") 5198 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))] 5199 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT" 5200 "fsel %0,%1,%2,%3" 5201 [(set_attr "type" "fp")]) 5202 5203(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9" 5204 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 5205 (if_then_else:SFDF 5206 (match_operator:CCFP 1 "fpmask_comparison_operator" 5207 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 5208 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 5209 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 5210 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5211 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 5212 "TARGET_P9_MINMAX" 5213 "#" 5214 "" 5215 [(set (match_dup 6) 5216 (if_then_else:V2DI (match_dup 1) 5217 (match_dup 7) 5218 (match_dup 8))) 5219 (set (match_dup 0) 5220 (if_then_else:SFDF (ne (match_dup 6) 5221 (match_dup 8)) 5222 (match_dup 4) 5223 (match_dup 5)))] 5224{ 5225 if (GET_CODE (operands[6]) == SCRATCH) 5226 operands[6] = gen_reg_rtx (V2DImode); 5227 5228 operands[7] = CONSTM1_RTX (V2DImode); 5229 operands[8] = CONST0_RTX (V2DImode); 5230} 5231 [(set_attr "length" "8") 5232 (set_attr "type" "vecperm")]) 5233 5234;; Handle inverting the fpmask comparisons. 5235(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9" 5236 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 5237 (if_then_else:SFDF 5238 (match_operator:CCFP 1 "invert_fpmask_comparison_operator" 5239 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 5240 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 5241 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 5242 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5243 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 5244 "TARGET_P9_MINMAX" 5245 "#" 5246 "&& 1" 5247 [(set (match_dup 6) 5248 (if_then_else:V2DI (match_dup 9) 5249 (match_dup 7) 5250 (match_dup 8))) 5251 (set (match_dup 0) 5252 (if_then_else:SFDF (ne (match_dup 6) 5253 (match_dup 8)) 5254 (match_dup 5) 5255 (match_dup 4)))] 5256{ 5257 rtx op1 = operands[1]; 5258 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1)); 5259 5260 if (GET_CODE (operands[6]) == SCRATCH) 5261 operands[6] = gen_reg_rtx (V2DImode); 5262 5263 operands[7] = CONSTM1_RTX (V2DImode); 5264 operands[8] = CONST0_RTX (V2DImode); 5265 5266 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]); 5267} 5268 [(set_attr "length" "8") 5269 (set_attr "type" "vecperm")]) 5270 5271(define_insn "*fpmask<mode>" 5272 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa") 5273 (if_then_else:V2DI 5274 (match_operator:CCFP 1 "fpmask_comparison_operator" 5275 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>") 5276 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")]) 5277 (match_operand:V2DI 4 "all_ones_constant" "") 5278 (match_operand:V2DI 5 "zero_constant" "")))] 5279 "TARGET_P9_MINMAX" 5280 "xscmp%V1dp %x0,%x2,%x3" 5281 [(set_attr "type" "fpcompare")]) 5282 5283(define_insn "*xxsel<mode>" 5284 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 5285 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa") 5286 (match_operand:V2DI 2 "zero_constant" "")) 5287 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>") 5288 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))] 5289 "TARGET_P9_MINMAX" 5290 "xxsel %x0,%x4,%x3,%x1" 5291 [(set_attr "type" "vecmove")]) 5292 5293 5294;; Conversions to and from floating-point. 5295 5296; We don't define lfiwax/lfiwzx with the normal definition, because we 5297; don't want to support putting SImode in FPR registers. 5298(define_insn "lfiwax" 5299 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v") 5300 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")] 5301 UNSPEC_LFIWAX))] 5302 "TARGET_HARD_FLOAT && TARGET_LFIWAX" 5303 "@ 5304 lfiwax %0,%y1 5305 lxsiwax %x0,%y1 5306 mtvsrwa %x0,%1 5307 vextsw2d %0,%1" 5308 [(set_attr "type" "fpload,fpload,mffgpr,vecexts") 5309 (set_attr "isa" "*,p8v,p8v,p9v")]) 5310 5311; This split must be run before register allocation because it allocates the 5312; memory slot that is needed to move values to/from the FPR. We don't allocate 5313; it earlier to allow for the combiner to merge insns together where it might 5314; not be needed and also in case the insns are deleted as dead code. 5315 5316(define_insn_and_split "floatsi<mode>2_lfiwax" 5317 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5318 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r"))) 5319 (clobber (match_scratch:DI 2 "=d,wa"))] 5320 "TARGET_HARD_FLOAT && TARGET_LFIWAX 5321 && <SI_CONVERT_FP> && can_create_pseudo_p ()" 5322 "#" 5323 "" 5324 [(pc)] 5325{ 5326 rtx dest = operands[0]; 5327 rtx src = operands[1]; 5328 rtx tmp; 5329 5330 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE) 5331 tmp = convert_to_mode (DImode, src, false); 5332 else 5333 { 5334 tmp = operands[2]; 5335 if (GET_CODE (tmp) == SCRATCH) 5336 tmp = gen_reg_rtx (DImode); 5337 if (MEM_P (src)) 5338 { 5339 src = rs6000_force_indexed_or_indirect_mem (src); 5340 emit_insn (gen_lfiwax (tmp, src)); 5341 } 5342 else 5343 { 5344 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5345 emit_move_insn (stack, src); 5346 emit_insn (gen_lfiwax (tmp, stack)); 5347 } 5348 } 5349 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5350 DONE; 5351} 5352 [(set_attr "length" "12") 5353 (set_attr "type" "fpload")]) 5354 5355(define_insn_and_split "floatsi<mode>2_lfiwax_mem" 5356 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5357 (float:SFDF 5358 (sign_extend:DI 5359 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z")))) 5360 (clobber (match_scratch:DI 2 "=d,wa"))] 5361 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>" 5362 "#" 5363 "" 5364 [(pc)] 5365{ 5366 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 5367 if (GET_CODE (operands[2]) == SCRATCH) 5368 operands[2] = gen_reg_rtx (DImode); 5369 if (TARGET_P8_VECTOR) 5370 emit_insn (gen_extendsidi2 (operands[2], operands[1])); 5371 else 5372 emit_insn (gen_lfiwax (operands[2], operands[1])); 5373 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5374 DONE; 5375} 5376 [(set_attr "length" "8") 5377 (set_attr "type" "fpload")]) 5378 5379(define_insn "lfiwzx" 5380 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa") 5381 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")] 5382 UNSPEC_LFIWZX))] 5383 "TARGET_HARD_FLOAT && TARGET_LFIWZX" 5384 "@ 5385 lfiwzx %0,%y1 5386 lxsiwzx %x0,%y1 5387 mtvsrwz %x0,%1 5388 xxextractuw %x0,%x1,4" 5389 [(set_attr "type" "fpload,fpload,mftgpr,vecexts") 5390 (set_attr "isa" "*,p8v,p8v,p9v")]) 5391 5392(define_insn_and_split "floatunssi<mode>2_lfiwzx" 5393 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5394 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r"))) 5395 (clobber (match_scratch:DI 2 "=d,wa"))] 5396 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" 5397 "#" 5398 "" 5399 [(pc)] 5400{ 5401 rtx dest = operands[0]; 5402 rtx src = operands[1]; 5403 rtx tmp; 5404 5405 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE) 5406 tmp = convert_to_mode (DImode, src, true); 5407 else 5408 { 5409 tmp = operands[2]; 5410 if (GET_CODE (tmp) == SCRATCH) 5411 tmp = gen_reg_rtx (DImode); 5412 if (MEM_P (src)) 5413 { 5414 src = rs6000_force_indexed_or_indirect_mem (src); 5415 emit_insn (gen_lfiwzx (tmp, src)); 5416 } 5417 else 5418 { 5419 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5420 emit_move_insn (stack, src); 5421 emit_insn (gen_lfiwzx (tmp, stack)); 5422 } 5423 } 5424 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5425 DONE; 5426} 5427 [(set_attr "length" "12") 5428 (set_attr "type" "fpload")]) 5429 5430(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem" 5431 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5432 (unsigned_float:SFDF 5433 (zero_extend:DI 5434 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z")))) 5435 (clobber (match_scratch:DI 2 "=d,wa"))] 5436 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" 5437 "#" 5438 "" 5439 [(pc)] 5440{ 5441 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 5442 if (GET_CODE (operands[2]) == SCRATCH) 5443 operands[2] = gen_reg_rtx (DImode); 5444 if (TARGET_P8_VECTOR) 5445 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1])); 5446 else 5447 emit_insn (gen_lfiwzx (operands[2], operands[1])); 5448 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5449 DONE; 5450} 5451 [(set_attr "length" "8") 5452 (set_attr "type" "fpload")]) 5453 5454; For each of these conversions, there is a define_expand, a define_insn 5455; with a '#' template, and a define_split (with C code). The idea is 5456; to allow constant folding with the template of the define_insn, 5457; then to have the insns split later (between sched1 and final). 5458 5459(define_expand "floatsidf2" 5460 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand") 5461 (float:DF (match_operand:SI 1 "nonimmediate_operand"))) 5462 (use (match_dup 2)) 5463 (use (match_dup 3)) 5464 (clobber (match_dup 4)) 5465 (clobber (match_dup 5)) 5466 (clobber (match_dup 6))])] 5467 "TARGET_HARD_FLOAT" 5468{ 5469 if (TARGET_LFIWAX && TARGET_FCFID) 5470 { 5471 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1])); 5472 DONE; 5473 } 5474 else if (TARGET_FCFID) 5475 { 5476 rtx dreg = operands[1]; 5477 if (!REG_P (dreg)) 5478 dreg = force_reg (SImode, dreg); 5479 dreg = convert_to_mode (DImode, dreg, false); 5480 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5481 DONE; 5482 } 5483 5484 if (!REG_P (operands[1])) 5485 operands[1] = force_reg (SImode, operands[1]); 5486 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5487 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); 5488 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5489 operands[5] = gen_reg_rtx (DFmode); 5490 operands[6] = gen_reg_rtx (SImode); 5491}) 5492 5493(define_insn_and_split "*floatsidf2_internal" 5494 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5495 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5496 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5497 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5498 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5499 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) 5500 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] 5501 "!TARGET_FCFID && TARGET_HARD_FLOAT" 5502 "#" 5503 "" 5504 [(pc)] 5505{ 5506 rtx lowword, highword; 5507 gcc_assert (MEM_P (operands[4])); 5508 highword = adjust_address (operands[4], SImode, 0); 5509 lowword = adjust_address (operands[4], SImode, 4); 5510 if (! WORDS_BIG_ENDIAN) 5511 std::swap (lowword, highword); 5512 5513 emit_insn (gen_xorsi3 (operands[6], operands[1], 5514 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff))); 5515 emit_move_insn (lowword, operands[6]); 5516 emit_move_insn (highword, operands[2]); 5517 emit_move_insn (operands[5], operands[4]); 5518 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5519 DONE; 5520} 5521 [(set_attr "length" "24") 5522 (set_attr "type" "fp")]) 5523 5524;; If we don't have a direct conversion to single precision, don't enable this 5525;; conversion for 32-bit without fast math, because we don't have the insn to 5526;; generate the fixup swizzle to avoid double rounding problems. 5527(define_expand "floatunssisf2" 5528 [(set (match_operand:SF 0 "gpc_reg_operand") 5529 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))] 5530 "TARGET_HARD_FLOAT 5531 && ((TARGET_FCFIDUS && TARGET_LFIWZX) 5532 || (TARGET_FCFID 5533 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" 5534{ 5535 if (TARGET_LFIWZX && TARGET_FCFIDUS) 5536 { 5537 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1])); 5538 DONE; 5539 } 5540 else 5541 { 5542 rtx dreg = operands[1]; 5543 if (!REG_P (dreg)) 5544 dreg = force_reg (SImode, dreg); 5545 dreg = convert_to_mode (DImode, dreg, true); 5546 emit_insn (gen_floatdisf2 (operands[0], dreg)); 5547 DONE; 5548 } 5549}) 5550 5551(define_expand "floatunssidf2" 5552 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand") 5553 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand"))) 5554 (use (match_dup 2)) 5555 (use (match_dup 3)) 5556 (clobber (match_dup 4)) 5557 (clobber (match_dup 5))])] 5558 "TARGET_HARD_FLOAT" 5559{ 5560 if (TARGET_LFIWZX && TARGET_FCFID) 5561 { 5562 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1])); 5563 DONE; 5564 } 5565 else if (TARGET_FCFID) 5566 { 5567 rtx dreg = operands[1]; 5568 if (!REG_P (dreg)) 5569 dreg = force_reg (SImode, dreg); 5570 dreg = convert_to_mode (DImode, dreg, true); 5571 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5572 DONE; 5573 } 5574 5575 if (!REG_P (operands[1])) 5576 operands[1] = force_reg (SImode, operands[1]); 5577 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5578 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); 5579 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5580 operands[5] = gen_reg_rtx (DFmode); 5581}) 5582 5583(define_insn_and_split "*floatunssidf2_internal" 5584 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5585 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5586 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5587 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5588 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5589 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] 5590 "!TARGET_FCFIDU && TARGET_HARD_FLOAT 5591 && !(TARGET_FCFID && TARGET_POWERPC64)" 5592 "#" 5593 "" 5594 [(pc)] 5595{ 5596 rtx lowword, highword; 5597 gcc_assert (MEM_P (operands[4])); 5598 highword = adjust_address (operands[4], SImode, 0); 5599 lowword = adjust_address (operands[4], SImode, 4); 5600 if (! WORDS_BIG_ENDIAN) 5601 std::swap (lowword, highword); 5602 5603 emit_move_insn (lowword, operands[1]); 5604 emit_move_insn (highword, operands[2]); 5605 emit_move_insn (operands[5], operands[4]); 5606 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5607 DONE; 5608} 5609 [(set_attr "length" "20") 5610 (set_attr "type" "fp")]) 5611 5612;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to 5613;; vector registers. These insns favor doing the sign/zero extension in 5614;; the vector registers, rather then loading up a GPR, doing a sign/zero 5615;; extension and then a direct move. 5616 5617(define_expand "float<QHI:mode><FP_ISA3:mode>2" 5618 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") 5619 (float:FP_ISA3 5620 (match_operand:QHI 1 "input_operand"))) 5621 (clobber (match_scratch:DI 2)) 5622 (clobber (match_scratch:DI 3)) 5623 (clobber (match_scratch:<QHI:MODE> 4))])] 5624 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5625{ 5626 if (MEM_P (operands[1])) 5627 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 5628}) 5629 5630(define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal" 5631 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>") 5632 (float:FP_ISA3 5633 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z"))) 5634 (clobber (match_scratch:DI 2 "=v,wa,v")) 5635 (clobber (match_scratch:DI 3 "=X,r,X")) 5636 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))] 5637 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5638 "#" 5639 "&& reload_completed" 5640 [(const_int 0)] 5641{ 5642 rtx result = operands[0]; 5643 rtx input = operands[1]; 5644 rtx di = operands[2]; 5645 5646 if (!MEM_P (input)) 5647 { 5648 rtx tmp = operands[3]; 5649 if (altivec_register_operand (input, <QHI:MODE>mode)) 5650 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5651 else if (GET_CODE (tmp) == SCRATCH) 5652 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5653 else 5654 { 5655 emit_insn (gen_extend<QHI:mode>di2 (tmp, input)); 5656 emit_move_insn (di, tmp); 5657 } 5658 } 5659 else 5660 { 5661 rtx tmp = operands[4]; 5662 emit_move_insn (tmp, input); 5663 emit_insn (gen_extend<QHI:mode>di2 (di, tmp)); 5664 } 5665 5666 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); 5667 DONE; 5668} 5669 [(set_attr "isa" "p9v,*,p9v")]) 5670 5671(define_expand "floatuns<QHI:mode><FP_ISA3:mode>2" 5672 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") 5673 (unsigned_float:FP_ISA3 5674 (match_operand:QHI 1 "input_operand"))) 5675 (clobber (match_scratch:DI 2)) 5676 (clobber (match_scratch:DI 3))])] 5677 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5678{ 5679 if (MEM_P (operands[1])) 5680 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 5681}) 5682 5683(define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal" 5684 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>") 5685 (unsigned_float:FP_ISA3 5686 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z"))) 5687 (clobber (match_scratch:DI 2 "=v,wa,wa")) 5688 (clobber (match_scratch:DI 3 "=X,r,X"))] 5689 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5690 "#" 5691 "&& reload_completed" 5692 [(const_int 0)] 5693{ 5694 rtx result = operands[0]; 5695 rtx input = operands[1]; 5696 rtx di = operands[2]; 5697 5698 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode)) 5699 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input)); 5700 else 5701 { 5702 rtx tmp = operands[3]; 5703 if (GET_CODE (tmp) == SCRATCH) 5704 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5705 else 5706 { 5707 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input)); 5708 emit_move_insn (di, tmp); 5709 } 5710 } 5711 5712 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); 5713 DONE; 5714} 5715 [(set_attr "isa" "p9v,*,p9v")]) 5716 5717(define_expand "fix_trunc<mode>si2" 5718 [(set (match_operand:SI 0 "gpc_reg_operand") 5719 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))] 5720 "TARGET_HARD_FLOAT" 5721{ 5722 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)) 5723 { 5724 rtx src = force_reg (<MODE>mode, operands[1]); 5725 5726 if (TARGET_STFIWX) 5727 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src)); 5728 else 5729 { 5730 rtx tmp = gen_reg_rtx (DImode); 5731 rtx stack = rs6000_allocate_stack_temp (DImode, true, false); 5732 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src, 5733 tmp, stack)); 5734 } 5735 DONE; 5736 } 5737}) 5738 5739; Like the convert to float patterns, this insn must be split before 5740; register allocation so that it can allocate the memory slot if it 5741; needed 5742(define_insn_and_split "fix_trunc<mode>si2_stfiwx" 5743 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5744 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 5745 (clobber (match_scratch:DI 2 "=d"))] 5746 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p () 5747 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" 5748 "#" 5749 "" 5750 [(pc)] 5751{ 5752 rtx dest = operands[0]; 5753 rtx src = operands[1]; 5754 rtx tmp = operands[2]; 5755 5756 if (GET_CODE (tmp) == SCRATCH) 5757 tmp = gen_reg_rtx (DImode); 5758 5759 emit_insn (gen_fctiwz_<mode> (tmp, src)); 5760 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32)) 5761 { 5762 dest = rs6000_force_indexed_or_indirect_mem (dest); 5763 emit_insn (gen_stfiwx (dest, tmp)); 5764 DONE; 5765 } 5766 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest)) 5767 { 5768 dest = gen_lowpart (DImode, dest); 5769 emit_move_insn (dest, tmp); 5770 DONE; 5771 } 5772 else 5773 { 5774 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5775 emit_insn (gen_stfiwx (stack, tmp)); 5776 emit_move_insn (dest, stack); 5777 DONE; 5778 } 5779} 5780 [(set_attr "length" "12") 5781 (set_attr "type" "fp")]) 5782 5783(define_insn_and_split "fix_trunc<mode>si2_internal" 5784 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r") 5785 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>"))) 5786 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d")) 5787 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))] 5788 "TARGET_HARD_FLOAT 5789 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" 5790 "#" 5791 "" 5792 [(pc)] 5793{ 5794 rtx lowword; 5795 gcc_assert (MEM_P (operands[3])); 5796 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 5797 5798 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1])); 5799 emit_move_insn (operands[3], operands[2]); 5800 emit_move_insn (operands[0], lowword); 5801 DONE; 5802} 5803 [(set_attr "length" "16") 5804 (set_attr "type" "fp")]) 5805 5806(define_expand "fix_trunc<mode>di2" 5807 [(set (match_operand:DI 0 "gpc_reg_operand") 5808 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))] 5809 "TARGET_HARD_FLOAT && TARGET_FCFID" 5810 "") 5811 5812(define_insn "*fix_trunc<mode>di2_fctidz" 5813 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 5814 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 5815 "TARGET_HARD_FLOAT && TARGET_FCFID" 5816 "@ 5817 fctidz %0,%1 5818 xscvdpsxds %x0,%x1" 5819 [(set_attr "type" "fp")]) 5820 5821;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR 5822;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the 5823;; vector registers, so we need to do direct moves to the GPRs, but SImode 5824;; values can go in VSX registers. Keeping the direct move part through 5825;; register allocation prevents the register allocator from doing a direct move 5826;; of the SImode value to a GPR, and then a store/load. 5827(define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2" 5828 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r") 5829 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa"))) 5830 (clobber (match_scratch:SI 2 "=X,X,wa"))] 5831 "TARGET_DIRECT_MOVE" 5832 "@ 5833 fctiw<u>z %0,%1 5834 xscvdp<su>xws %x0,%x1 5835 #" 5836 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)" 5837 [(set (match_dup 2) 5838 (any_fix:SI (match_dup 1))) 5839 (set (match_dup 3) 5840 (match_dup 2))] 5841{ 5842 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0])); 5843} 5844 [(set_attr "type" "fp") 5845 (set_attr "length" "4,4,8") 5846 (set_attr "isa" "p9v,p9v,*")]) 5847 5848(define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8" 5849 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa") 5850 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))] 5851 "TARGET_DIRECT_MOVE" 5852 "@ 5853 fctiw<u>z %0,%1 5854 xscvdp<su>xws %x0,%x1" 5855 [(set_attr "type" "fp")]) 5856 5857;; Keep the convert and store together through register allocation to prevent 5858;; the register allocator from getting clever and doing a direct move to a GPR 5859;; and then store for reg+offset stores. 5860(define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem" 5861 [(set (match_operand:QHSI 0 "memory_operand" "=Z") 5862 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa"))) 5863 (clobber (match_scratch:SI 2 "=wa"))] 5864 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR" 5865 "#" 5866 "&& reload_completed" 5867 [(set (match_dup 2) 5868 (any_fix:SI (match_dup 1))) 5869 (set (match_dup 0) 5870 (match_dup 3))] 5871{ 5872 operands[3] = (<QHSI:MODE>mode == SImode 5873 ? operands[2] 5874 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2]))); 5875}) 5876 5877(define_expand "fixuns_trunc<mode>si2" 5878 [(set (match_operand:SI 0 "gpc_reg_operand") 5879 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))] 5880 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX" 5881{ 5882 if (!TARGET_P8_VECTOR) 5883 { 5884 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1])); 5885 DONE; 5886 } 5887}) 5888 5889(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx" 5890 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5891 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 5892 (clobber (match_scratch:DI 2 "=d"))] 5893 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ 5894 && TARGET_STFIWX && can_create_pseudo_p () 5895 && !TARGET_P8_VECTOR" 5896 "#" 5897 "" 5898 [(pc)] 5899{ 5900 rtx dest = operands[0]; 5901 rtx src = operands[1]; 5902 rtx tmp = operands[2]; 5903 5904 if (GET_CODE (tmp) == SCRATCH) 5905 tmp = gen_reg_rtx (DImode); 5906 5907 emit_insn (gen_fctiwuz_<mode> (tmp, src)); 5908 if (MEM_P (dest)) 5909 { 5910 dest = rs6000_force_indexed_or_indirect_mem (dest); 5911 emit_insn (gen_stfiwx (dest, tmp)); 5912 DONE; 5913 } 5914 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE) 5915 { 5916 dest = gen_lowpart (DImode, dest); 5917 emit_move_insn (dest, tmp); 5918 DONE; 5919 } 5920 else 5921 { 5922 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5923 emit_insn (gen_stfiwx (stack, tmp)); 5924 emit_move_insn (dest, stack); 5925 DONE; 5926 } 5927} 5928 [(set_attr "length" "12") 5929 (set_attr "type" "fp")]) 5930 5931(define_insn "fixuns_trunc<mode>di2" 5932 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 5933 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 5934 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ" 5935 "@ 5936 fctiduz %0,%1 5937 xscvdpuxds %x0,%x1" 5938 [(set_attr "type" "fp")]) 5939 5940(define_insn "rs6000_mtfsb0" 5941 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")] 5942 UNSPECV_MTFSB0)] 5943 "TARGET_HARD_FLOAT" 5944 "mtfsb0 %0" 5945 [(set_attr "type" "fp")]) 5946 5947(define_insn "rs6000_mtfsb1" 5948 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")] 5949 UNSPECV_MTFSB1)] 5950 "TARGET_HARD_FLOAT" 5951 "mtfsb1 %0" 5952 [(set_attr "type" "fp")]) 5953 5954(define_insn "rs6000_mffscrn" 5955 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 5956 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] 5957 UNSPECV_MFFSCRN))] 5958 "TARGET_P9_MISC" 5959 "mffscrn %0,%1" 5960 [(set_attr "type" "fp")]) 5961 5962(define_insn "rs6000_mffscdrn" 5963 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 5964 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN)) 5965 (use (match_operand:DF 1 "gpc_reg_operand" "d"))] 5966 "TARGET_P9_MISC" 5967 "mffscdrn %0,%1" 5968 [(set_attr "type" "fp")]) 5969 5970(define_expand "rs6000_set_fpscr_rn" 5971 [(match_operand:DI 0 "reg_or_cint_operand")] 5972 "TARGET_HARD_FLOAT" 5973{ 5974 rtx tmp_df = gen_reg_rtx (DFmode); 5975 5976 /* The floating point rounding control bits are FPSCR[62:63]. Put the 5977 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */ 5978 if (TARGET_P9_MISC) 5979 { 5980 rtx src_df = force_reg (DImode, operands[0]); 5981 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0); 5982 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df)); 5983 DONE; 5984 } 5985 5986 if (CONST_INT_P (operands[0])) 5987 { 5988 if ((INTVAL (operands[0]) & 0x1) == 0x1) 5989 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31))); 5990 else 5991 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31))); 5992 5993 if ((INTVAL (operands[0]) & 0x2) == 0x2) 5994 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30))); 5995 else 5996 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30))); 5997 } 5998 else 5999 { 6000 rtx tmp_rn = gen_reg_rtx (DImode); 6001 rtx tmp_di = gen_reg_rtx (DImode); 6002 6003 /* Extract new RN mode from operand. */ 6004 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3))); 6005 6006 /* Insert new RN mode into FSCPR. */ 6007 emit_insn (gen_rs6000_mffs (tmp_df)); 6008 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); 6009 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4))); 6010 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn)); 6011 6012 /* Need to write to field k=15. The fields are [0:15]. Hence with 6013 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an 6014 8-bit field[0:7]. Need to set the bit that corresponds to the 6015 value of i that you want [0:7]. */ 6016 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); 6017 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df)); 6018 } 6019 DONE; 6020}) 6021 6022(define_expand "rs6000_set_fpscr_drn" 6023 [(match_operand:DI 0 "gpc_reg_operand")] 6024 "TARGET_HARD_FLOAT" 6025{ 6026 rtx tmp_df = gen_reg_rtx (DFmode); 6027 6028 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the 6029 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */ 6030 if (TARGET_P9_MISC) 6031 { 6032 rtx src_df = gen_reg_rtx (DFmode); 6033 6034 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32))); 6035 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0); 6036 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df)); 6037 } 6038 else 6039 { 6040 rtx tmp_rn = gen_reg_rtx (DImode); 6041 rtx tmp_di = gen_reg_rtx (DImode); 6042 6043 /* Extract new DRN mode from operand. */ 6044 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7))); 6045 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32))); 6046 6047 /* Insert new RN mode into FSCPR. */ 6048 emit_insn (gen_rs6000_mffs (tmp_df)); 6049 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); 6050 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL))); 6051 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn)); 6052 6053 /* Need to write to field 7. The fields are [0:15]. The equation to 6054 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set 6055 i to 0x1 to get field 7 where i selects the field. */ 6056 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); 6057 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df)); 6058 } 6059 DONE; 6060}) 6061 6062;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) 6063;; rather than (set (subreg:SI (reg)) (fix:SI ...)) 6064;; because the first makes it clear that operand 0 is not live 6065;; before the instruction. 6066(define_insn "fctiwz_<mode>" 6067 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 6068 (unspec:DI [(fix:SI 6069 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 6070 UNSPEC_FCTIWZ))] 6071 "TARGET_HARD_FLOAT" 6072 "@ 6073 fctiwz %0,%1 6074 xscvdpsxws %x0,%x1" 6075 [(set_attr "type" "fp")]) 6076 6077(define_insn "fctiwuz_<mode>" 6078 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 6079 (unspec:DI [(unsigned_fix:SI 6080 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 6081 UNSPEC_FCTIWUZ))] 6082 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ" 6083 "@ 6084 fctiwuz %0,%1 6085 xscvdpuxws %x0,%x1" 6086 [(set_attr "type" "fp")]) 6087 6088;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since 6089;; since the friz instruction does not truncate the value if the floating 6090;; point value is < LONG_MIN or > LONG_MAX. 6091(define_insn "*friz" 6092 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6093 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))] 6094 "TARGET_HARD_FLOAT && TARGET_FPRND 6095 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ" 6096 "@ 6097 friz %0,%1 6098 xsrdpiz %x0,%x1" 6099 [(set_attr "type" "fp")]) 6100 6101;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This 6102;; optimization prevents on ISA 2.06 systems and earlier having to store the 6103;; value from the FPR/vector unit to the stack, load the value into a GPR, sign 6104;; extend it, store it back on the stack from the GPR, load it back into the 6105;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07), 6106;; disable using store and load to sign/zero extend the value. 6107(define_insn_and_split "*round32<mode>2_fprs" 6108 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 6109 (float:SFDF 6110 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 6111 (clobber (match_scratch:DI 2 "=d")) 6112 (clobber (match_scratch:DI 3 "=d"))] 6113 "TARGET_HARD_FLOAT 6114 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID 6115 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()" 6116 "#" 6117 "" 6118 [(pc)] 6119{ 6120 rtx dest = operands[0]; 6121 rtx src = operands[1]; 6122 rtx tmp1 = operands[2]; 6123 rtx tmp2 = operands[3]; 6124 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 6125 6126 if (GET_CODE (tmp1) == SCRATCH) 6127 tmp1 = gen_reg_rtx (DImode); 6128 if (GET_CODE (tmp2) == SCRATCH) 6129 tmp2 = gen_reg_rtx (DImode); 6130 6131 emit_insn (gen_fctiwz_<mode> (tmp1, src)); 6132 emit_insn (gen_stfiwx (stack, tmp1)); 6133 emit_insn (gen_lfiwax (tmp2, stack)); 6134 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 6135 DONE; 6136} 6137 [(set_attr "type" "fpload") 6138 (set_attr "length" "16")]) 6139 6140(define_insn_and_split "*roundu32<mode>2_fprs" 6141 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 6142 (unsigned_float:SFDF 6143 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 6144 (clobber (match_scratch:DI 2 "=d")) 6145 (clobber (match_scratch:DI 3 "=d"))] 6146 "TARGET_HARD_FLOAT 6147 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE 6148 && can_create_pseudo_p ()" 6149 "#" 6150 "" 6151 [(pc)] 6152{ 6153 rtx dest = operands[0]; 6154 rtx src = operands[1]; 6155 rtx tmp1 = operands[2]; 6156 rtx tmp2 = operands[3]; 6157 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 6158 6159 if (GET_CODE (tmp1) == SCRATCH) 6160 tmp1 = gen_reg_rtx (DImode); 6161 if (GET_CODE (tmp2) == SCRATCH) 6162 tmp2 = gen_reg_rtx (DImode); 6163 6164 emit_insn (gen_fctiwuz_<mode> (tmp1, src)); 6165 emit_insn (gen_stfiwx (stack, tmp1)); 6166 emit_insn (gen_lfiwzx (tmp2, stack)); 6167 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 6168 DONE; 6169} 6170 [(set_attr "type" "fpload") 6171 (set_attr "length" "16")]) 6172 6173;; No VSX equivalent to fctid 6174(define_insn "lrint<mode>di2" 6175 [(set (match_operand:DI 0 "gpc_reg_operand" "=d") 6176 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 6177 UNSPEC_FCTID))] 6178 "TARGET_HARD_FLOAT && TARGET_FPRND" 6179 "fctid %0,%1" 6180 [(set_attr "type" "fp")]) 6181 6182(define_insn "btrunc<mode>2" 6183 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 6184 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 6185 UNSPEC_FRIZ))] 6186 "TARGET_HARD_FLOAT && TARGET_FPRND" 6187 "@ 6188 friz %0,%1 6189 xsrdpiz %x0,%x1" 6190 [(set_attr "type" "fp")]) 6191 6192(define_insn "ceil<mode>2" 6193 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 6194 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 6195 UNSPEC_FRIP))] 6196 "TARGET_HARD_FLOAT && TARGET_FPRND" 6197 "@ 6198 frip %0,%1 6199 xsrdpip %x0,%x1" 6200 [(set_attr "type" "fp")]) 6201 6202(define_insn "floor<mode>2" 6203 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 6204 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 6205 UNSPEC_FRIM))] 6206 "TARGET_HARD_FLOAT && TARGET_FPRND" 6207 "@ 6208 frim %0,%1 6209 xsrdpim %x0,%x1" 6210 [(set_attr "type" "fp")]) 6211 6212;; No VSX equivalent to frin 6213(define_insn "round<mode>2" 6214 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") 6215 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 6216 UNSPEC_FRIN))] 6217 "TARGET_HARD_FLOAT && TARGET_FPRND" 6218 "frin %0,%1" 6219 [(set_attr "type" "fp")]) 6220 6221(define_insn "*xsrdpi<mode>2" 6222 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 6223 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")] 6224 UNSPEC_XSRDPI))] 6225 "TARGET_HARD_FLOAT && TARGET_VSX" 6226 "xsrdpi %x0,%x1" 6227 [(set_attr "type" "fp")]) 6228 6229(define_expand "lround<mode>di2" 6230 [(set (match_dup 2) 6231 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")] 6232 UNSPEC_XSRDPI)) 6233 (set (match_operand:DI 0 "gpc_reg_operand") 6234 (unspec:DI [(match_dup 2)] 6235 UNSPEC_FCTID))] 6236 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND" 6237{ 6238 operands[2] = gen_reg_rtx (<MODE>mode); 6239}) 6240 6241; An UNSPEC is used so we don't have to support SImode in FP registers. 6242(define_insn "stfiwx" 6243 [(set (match_operand:SI 0 "memory_operand" "=Z,Z") 6244 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")] 6245 UNSPEC_STFIWX))] 6246 "TARGET_PPC_GFXOPT" 6247 "@ 6248 stfiwx %1,%y0 6249 stxsiwx %x1,%y0" 6250 [(set_attr "type" "fpstore") 6251 (set_attr "isa" "*,p8v")]) 6252 6253;; If we don't have a direct conversion to single precision, don't enable this 6254;; conversion for 32-bit without fast math, because we don't have the insn to 6255;; generate the fixup swizzle to avoid double rounding problems. 6256(define_expand "floatsisf2" 6257 [(set (match_operand:SF 0 "gpc_reg_operand") 6258 (float:SF (match_operand:SI 1 "nonimmediate_operand")))] 6259 "TARGET_HARD_FLOAT 6260 && ((TARGET_FCFIDS && TARGET_LFIWAX) 6261 || (TARGET_FCFID 6262 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" 6263{ 6264 if (TARGET_FCFIDS && TARGET_LFIWAX) 6265 { 6266 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1])); 6267 DONE; 6268 } 6269 else if (TARGET_FCFID && TARGET_LFIWAX) 6270 { 6271 rtx dfreg = gen_reg_rtx (DFmode); 6272 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1])); 6273 emit_insn (gen_truncdfsf2 (operands[0], dfreg)); 6274 DONE; 6275 } 6276 else 6277 { 6278 rtx dreg = operands[1]; 6279 if (!REG_P (dreg)) 6280 dreg = force_reg (SImode, dreg); 6281 dreg = convert_to_mode (DImode, dreg, false); 6282 emit_insn (gen_floatdisf2 (operands[0], dreg)); 6283 DONE; 6284 } 6285}) 6286 6287(define_insn "floatdidf2" 6288 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6289 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6290 "TARGET_FCFID && TARGET_HARD_FLOAT" 6291 "@ 6292 fcfid %0,%1 6293 xscvsxddp %x0,%x1" 6294 [(set_attr "type" "fp")]) 6295 6296; Allow the combiner to merge source memory operands to the conversion so that 6297; the optimizer/register allocator doesn't try to load the value too early in a 6298; GPR and then use store/load to move it to a FPR and suffer from a store-load 6299; hit. We will split after reload to avoid the trip through the GPRs 6300 6301(define_insn_and_split "*floatdidf2_mem" 6302 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6303 (float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 6304 (clobber (match_scratch:DI 2 "=d,wa"))] 6305 "TARGET_HARD_FLOAT && TARGET_FCFID" 6306 "#" 6307 "&& reload_completed" 6308 [(set (match_dup 2) (match_dup 1)) 6309 (set (match_dup 0) (float:DF (match_dup 2)))] 6310 "" 6311 [(set_attr "length" "8") 6312 (set_attr "type" "fpload")]) 6313 6314(define_expand "floatunsdidf2" 6315 [(set (match_operand:DF 0 "gpc_reg_operand") 6316 (unsigned_float:DF 6317 (match_operand:DI 1 "gpc_reg_operand")))] 6318 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 6319 "") 6320 6321(define_insn "*floatunsdidf2_fcfidu" 6322 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6323 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6324 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 6325 "@ 6326 fcfidu %0,%1 6327 xscvuxddp %x0,%x1" 6328 [(set_attr "type" "fp")]) 6329 6330(define_insn_and_split "*floatunsdidf2_mem" 6331 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6332 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 6333 (clobber (match_scratch:DI 2 "=d,wa"))] 6334 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))" 6335 "#" 6336 "&& reload_completed" 6337 [(set (match_dup 2) (match_dup 1)) 6338 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))] 6339 "" 6340 [(set_attr "length" "8") 6341 (set_attr "type" "fpload")]) 6342 6343(define_expand "floatdisf2" 6344 [(set (match_operand:SF 0 "gpc_reg_operand") 6345 (float:SF (match_operand:DI 1 "gpc_reg_operand")))] 6346 "TARGET_FCFID && TARGET_HARD_FLOAT 6347 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)" 6348{ 6349 if (!TARGET_FCFIDS) 6350 { 6351 rtx val = operands[1]; 6352 if (!flag_unsafe_math_optimizations) 6353 { 6354 rtx label = gen_label_rtx (); 6355 val = gen_reg_rtx (DImode); 6356 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label)); 6357 emit_label (label); 6358 } 6359 emit_insn (gen_floatdisf2_internal1 (operands[0], val)); 6360 DONE; 6361 } 6362}) 6363 6364(define_insn "floatdisf2_fcfids" 6365 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa") 6366 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6367 "TARGET_HARD_FLOAT && TARGET_FCFIDS" 6368 "@ 6369 fcfids %0,%1 6370 xscvsxdsp %x0,%x1" 6371 [(set_attr "type" "fp") 6372 (set_attr "isa" "*,p8v")]) 6373 6374(define_insn_and_split "*floatdisf2_mem" 6375 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa") 6376 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 6377 (clobber (match_scratch:DI 2 "=d,d,wa"))] 6378 "TARGET_HARD_FLOAT && TARGET_FCFIDS" 6379 "#" 6380 "&& reload_completed" 6381 [(pc)] 6382{ 6383 emit_move_insn (operands[2], operands[1]); 6384 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2])); 6385 DONE; 6386} 6387 [(set_attr "length" "8") 6388 (set_attr "isa" "*,p8v,p8v")]) 6389 6390;; This is not IEEE compliant if rounding mode is "round to nearest". 6391;; If the DI->DF conversion is inexact, then it's possible to suffer 6392;; from double rounding. 6393;; Instead of creating a new cpu type for two FP operations, just use fp 6394(define_insn_and_split "floatdisf2_internal1" 6395 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 6396 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d"))) 6397 (clobber (match_scratch:DF 2 "=d"))] 6398 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS" 6399 "#" 6400 "&& reload_completed" 6401 [(set (match_dup 2) 6402 (float:DF (match_dup 1))) 6403 (set (match_dup 0) 6404 (float_truncate:SF (match_dup 2)))] 6405 "" 6406 [(set_attr "length" "8") 6407 (set_attr "type" "fp")]) 6408 6409;; Twiddles bits to avoid double rounding. 6410;; Bits that might be truncated when converting to DFmode are replaced 6411;; by a bit that won't be lost at that stage, but is below the SFmode 6412;; rounding position. 6413(define_expand "floatdisf2_internal2" 6414 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "") 6415 (const_int 53))) 6416 (clobber (reg:DI CA_REGNO))]) 6417 (set (match_operand:DI 0 "") (and:DI (match_dup 1) 6418 (const_int 2047))) 6419 (set (match_dup 3) (plus:DI (match_dup 3) 6420 (const_int 1))) 6421 (set (match_dup 0) (plus:DI (match_dup 0) 6422 (const_int 2047))) 6423 (set (match_dup 4) (compare:CCUNS (match_dup 3) 6424 (const_int 2))) 6425 (set (match_dup 0) (ior:DI (match_dup 0) 6426 (match_dup 1))) 6427 (set (match_dup 0) (and:DI (match_dup 0) 6428 (const_int -2048))) 6429 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) 6430 (label_ref (match_operand:DI 2 "")) 6431 (pc))) 6432 (set (match_dup 0) (match_dup 1))] 6433 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS" 6434{ 6435 operands[3] = gen_reg_rtx (DImode); 6436 operands[4] = gen_reg_rtx (CCUNSmode); 6437}) 6438 6439(define_expand "floatunsdisf2" 6440 [(set (match_operand:SF 0 "gpc_reg_operand") 6441 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))] 6442 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" 6443 "") 6444 6445(define_insn "floatunsdisf2_fcfidus" 6446 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa") 6447 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6448 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" 6449 "@ 6450 fcfidus %0,%1 6451 xscvuxdsp %x0,%x1" 6452 [(set_attr "type" "fp") 6453 (set_attr "isa" "*,p8v")]) 6454 6455(define_insn_and_split "*floatunsdisf2_mem" 6456 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa") 6457 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 6458 (clobber (match_scratch:DI 2 "=d,d,wa"))] 6459 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" 6460 "#" 6461 "&& reload_completed" 6462 [(pc)] 6463{ 6464 emit_move_insn (operands[2], operands[1]); 6465 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2])); 6466 DONE; 6467} 6468 [(set_attr "type" "fpload") 6469 (set_attr "length" "8") 6470 (set_attr "isa" "*,p8v,p8v")]) 6471 6472;; Define the TImode operations that can be done in a small number 6473;; of instructions. The & constraints are to prevent the register 6474;; allocator from allocating registers that overlap with the inputs 6475;; (for example, having an input in 7,8 and an output in 6,7). We 6476;; also allow for the output being the same as one of the inputs. 6477 6478(define_expand "addti3" 6479 [(set (match_operand:TI 0 "gpc_reg_operand") 6480 (plus:TI (match_operand:TI 1 "gpc_reg_operand") 6481 (match_operand:TI 2 "reg_or_short_operand")))] 6482 "TARGET_64BIT" 6483{ 6484 rtx lo0 = gen_lowpart (DImode, operands[0]); 6485 rtx lo1 = gen_lowpart (DImode, operands[1]); 6486 rtx lo2 = gen_lowpart (DImode, operands[2]); 6487 rtx hi0 = gen_highpart (DImode, operands[0]); 6488 rtx hi1 = gen_highpart (DImode, operands[1]); 6489 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]); 6490 6491 if (!reg_or_short_operand (lo2, DImode)) 6492 lo2 = force_reg (DImode, lo2); 6493 if (!adde_operand (hi2, DImode)) 6494 hi2 = force_reg (DImode, hi2); 6495 6496 emit_insn (gen_adddi3_carry (lo0, lo1, lo2)); 6497 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2)); 6498 DONE; 6499}) 6500 6501(define_expand "subti3" 6502 [(set (match_operand:TI 0 "gpc_reg_operand") 6503 (minus:TI (match_operand:TI 1 "reg_or_short_operand") 6504 (match_operand:TI 2 "gpc_reg_operand")))] 6505 "TARGET_64BIT" 6506{ 6507 rtx lo0 = gen_lowpart (DImode, operands[0]); 6508 rtx lo1 = gen_lowpart (DImode, operands[1]); 6509 rtx lo2 = gen_lowpart (DImode, operands[2]); 6510 rtx hi0 = gen_highpart (DImode, operands[0]); 6511 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]); 6512 rtx hi2 = gen_highpart (DImode, operands[2]); 6513 6514 if (!reg_or_short_operand (lo1, DImode)) 6515 lo1 = force_reg (DImode, lo1); 6516 if (!adde_operand (hi1, DImode)) 6517 hi1 = force_reg (DImode, hi1); 6518 6519 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1)); 6520 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1)); 6521 DONE; 6522}) 6523 6524;; 128-bit logical operations expanders 6525 6526(define_expand "and<mode>3" 6527 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6528 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6529 (match_operand:BOOL_128 2 "vlogical_operand")))] 6530 "" 6531 "") 6532 6533(define_expand "ior<mode>3" 6534 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6535 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6536 (match_operand:BOOL_128 2 "vlogical_operand")))] 6537 "" 6538 "") 6539 6540(define_expand "xor<mode>3" 6541 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6542 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6543 (match_operand:BOOL_128 2 "vlogical_operand")))] 6544 "" 6545 "") 6546 6547(define_expand "nor<mode>3" 6548 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6549 (and:BOOL_128 6550 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")) 6551 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))] 6552 "" 6553 "") 6554 6555(define_expand "andc<mode>3" 6556 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6557 (and:BOOL_128 6558 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand")) 6559 (match_operand:BOOL_128 1 "vlogical_operand")))] 6560 "" 6561 "") 6562 6563;; Power8 vector logical instructions. 6564(define_expand "eqv<mode>3" 6565 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6566 (not:BOOL_128 6567 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6568 (match_operand:BOOL_128 2 "vlogical_operand"))))] 6569 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6570 "") 6571 6572;; Rewrite nand into canonical form 6573(define_expand "nand<mode>3" 6574 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6575 (ior:BOOL_128 6576 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")) 6577 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))] 6578 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6579 "") 6580 6581;; The canonical form is to have the negated element first, so we need to 6582;; reverse arguments. 6583(define_expand "orc<mode>3" 6584 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6585 (ior:BOOL_128 6586 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand")) 6587 (match_operand:BOOL_128 1 "vlogical_operand")))] 6588 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6589 "") 6590 6591;; 128-bit logical operations insns and split operations 6592(define_insn_and_split "*and<mode>3_internal" 6593 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6594 (and:BOOL_128 6595 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 6596 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))] 6597 "" 6598{ 6599 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6600 return "xxland %x0,%x1,%x2"; 6601 6602 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6603 return "vand %0,%1,%2"; 6604 6605 return "#"; 6606} 6607 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6608 [(const_int 0)] 6609{ 6610 rs6000_split_logical (operands, AND, false, false, false); 6611 DONE; 6612} 6613 [(set (attr "type") 6614 (if_then_else 6615 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6616 (const_string "veclogical") 6617 (const_string "integer"))) 6618 (set (attr "length") 6619 (if_then_else 6620 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6621 (const_string "4") 6622 (if_then_else 6623 (match_test "TARGET_POWERPC64") 6624 (const_string "8") 6625 (const_string "16"))))]) 6626 6627;; 128-bit IOR/XOR 6628(define_insn_and_split "*bool<mode>3_internal" 6629 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6630 (match_operator:BOOL_128 3 "boolean_or_operator" 6631 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 6632 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))] 6633 "" 6634{ 6635 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6636 return "xxl%q3 %x0,%x1,%x2"; 6637 6638 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6639 return "v%q3 %0,%1,%2"; 6640 6641 return "#"; 6642} 6643 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6644 [(const_int 0)] 6645{ 6646 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false); 6647 DONE; 6648} 6649 [(set (attr "type") 6650 (if_then_else 6651 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6652 (const_string "veclogical") 6653 (const_string "integer"))) 6654 (set (attr "length") 6655 (if_then_else 6656 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6657 (const_string "4") 6658 (if_then_else 6659 (match_test "TARGET_POWERPC64") 6660 (const_string "8") 6661 (const_string "16"))))]) 6662 6663;; 128-bit ANDC/ORC 6664(define_insn_and_split "*boolc<mode>3_internal1" 6665 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6666 (match_operator:BOOL_128 3 "boolean_operator" 6667 [(not:BOOL_128 6668 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")) 6669 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))] 6670 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 6671{ 6672 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6673 return "xxl%q3 %x0,%x1,%x2"; 6674 6675 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6676 return "v%q3 %0,%1,%2"; 6677 6678 return "#"; 6679} 6680 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 6681 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6682 [(const_int 0)] 6683{ 6684 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 6685 DONE; 6686} 6687 [(set (attr "type") 6688 (if_then_else 6689 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6690 (const_string "veclogical") 6691 (const_string "integer"))) 6692 (set (attr "length") 6693 (if_then_else 6694 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6695 (const_string "4") 6696 (if_then_else 6697 (match_test "TARGET_POWERPC64") 6698 (const_string "8") 6699 (const_string "16"))))]) 6700 6701(define_insn_and_split "*boolc<mode>3_internal2" 6702 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6703 (match_operator:TI2 3 "boolean_operator" 6704 [(not:TI2 6705 (match_operand:TI2 2 "int_reg_operand" "r,0,r")) 6706 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))] 6707 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6708 "#" 6709 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6710 [(const_int 0)] 6711{ 6712 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 6713 DONE; 6714} 6715 [(set_attr "type" "integer") 6716 (set (attr "length") 6717 (if_then_else 6718 (match_test "TARGET_POWERPC64") 6719 (const_string "8") 6720 (const_string "16")))]) 6721 6722;; 128-bit NAND/NOR 6723(define_insn_and_split "*boolcc<mode>3_internal1" 6724 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6725 (match_operator:BOOL_128 3 "boolean_operator" 6726 [(not:BOOL_128 6727 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")) 6728 (not:BOOL_128 6729 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))] 6730 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 6731{ 6732 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6733 return "xxl%q3 %x0,%x1,%x2"; 6734 6735 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6736 return "v%q3 %0,%1,%2"; 6737 6738 return "#"; 6739} 6740 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 6741 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6742 [(const_int 0)] 6743{ 6744 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 6745 DONE; 6746} 6747 [(set (attr "type") 6748 (if_then_else 6749 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6750 (const_string "veclogical") 6751 (const_string "integer"))) 6752 (set (attr "length") 6753 (if_then_else 6754 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6755 (const_string "4") 6756 (if_then_else 6757 (match_test "TARGET_POWERPC64") 6758 (const_string "8") 6759 (const_string "16"))))]) 6760 6761(define_insn_and_split "*boolcc<mode>3_internal2" 6762 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6763 (match_operator:TI2 3 "boolean_operator" 6764 [(not:TI2 6765 (match_operand:TI2 1 "int_reg_operand" "r,0,r")) 6766 (not:TI2 6767 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))] 6768 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6769 "#" 6770 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6771 [(const_int 0)] 6772{ 6773 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 6774 DONE; 6775} 6776 [(set_attr "type" "integer") 6777 (set (attr "length") 6778 (if_then_else 6779 (match_test "TARGET_POWERPC64") 6780 (const_string "8") 6781 (const_string "16")))]) 6782 6783 6784;; 128-bit EQV 6785(define_insn_and_split "*eqv<mode>3_internal1" 6786 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6787 (not:BOOL_128 6788 (xor:BOOL_128 6789 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>") 6790 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))] 6791 "TARGET_P8_VECTOR" 6792{ 6793 if (vsx_register_operand (operands[0], <MODE>mode)) 6794 return "xxleqv %x0,%x1,%x2"; 6795 6796 return "#"; 6797} 6798 "TARGET_P8_VECTOR && reload_completed 6799 && int_reg_operand (operands[0], <MODE>mode)" 6800 [(const_int 0)] 6801{ 6802 rs6000_split_logical (operands, XOR, true, false, false); 6803 DONE; 6804} 6805 [(set (attr "type") 6806 (if_then_else 6807 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6808 (const_string "veclogical") 6809 (const_string "integer"))) 6810 (set (attr "length") 6811 (if_then_else 6812 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6813 (const_string "4") 6814 (if_then_else 6815 (match_test "TARGET_POWERPC64") 6816 (const_string "8") 6817 (const_string "16"))))]) 6818 6819(define_insn_and_split "*eqv<mode>3_internal2" 6820 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6821 (not:TI2 6822 (xor:TI2 6823 (match_operand:TI2 1 "int_reg_operand" "r,0,r") 6824 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))] 6825 "!TARGET_P8_VECTOR" 6826 "#" 6827 "reload_completed && !TARGET_P8_VECTOR" 6828 [(const_int 0)] 6829{ 6830 rs6000_split_logical (operands, XOR, true, false, false); 6831 DONE; 6832} 6833 [(set_attr "type" "integer") 6834 (set (attr "length") 6835 (if_then_else 6836 (match_test "TARGET_POWERPC64") 6837 (const_string "8") 6838 (const_string "16")))]) 6839 6840;; 128-bit one's complement 6841(define_insn_and_split "one_cmpl<mode>2" 6842 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6843 (not:BOOL_128 6844 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))] 6845 "" 6846{ 6847 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6848 return "xxlnor %x0,%x1,%x1"; 6849 6850 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6851 return "vnor %0,%1,%1"; 6852 6853 return "#"; 6854} 6855 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6856 [(const_int 0)] 6857{ 6858 rs6000_split_logical (operands, NOT, false, false, false); 6859 DONE; 6860} 6861 [(set (attr "type") 6862 (if_then_else 6863 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6864 (const_string "veclogical") 6865 (const_string "integer"))) 6866 (set (attr "length") 6867 (if_then_else 6868 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6869 (const_string "4") 6870 (if_then_else 6871 (match_test "TARGET_POWERPC64") 6872 (const_string "8") 6873 (const_string "16"))))]) 6874 6875 6876;; Now define ways of moving data around. 6877 6878;; Set up a register with a value from the GOT table 6879 6880(define_expand "movsi_got" 6881 [(set (match_operand:SI 0 "gpc_reg_operand") 6882 (unspec:SI [(match_operand:SI 1 "got_operand") 6883 (match_dup 2)] UNSPEC_MOVSI_GOT))] 6884 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 6885{ 6886 if (GET_CODE (operands[1]) == CONST) 6887 { 6888 rtx offset = const0_rtx; 6889 HOST_WIDE_INT value; 6890 6891 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset); 6892 value = INTVAL (offset); 6893 if (value != 0) 6894 { 6895 rtx tmp = (!can_create_pseudo_p () 6896 ? operands[0] 6897 : gen_reg_rtx (Pmode)); 6898 emit_insn (gen_movsi_got (tmp, operands[1])); 6899 emit_insn (gen_addsi3 (operands[0], tmp, offset)); 6900 DONE; 6901 } 6902 } 6903 6904 operands[2] = rs6000_got_register (operands[1]); 6905}) 6906 6907(define_insn "*movsi_got_internal" 6908 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 6909 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") 6910 (match_operand:SI 2 "gpc_reg_operand" "b")] 6911 UNSPEC_MOVSI_GOT))] 6912 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 6913 "lwz %0,%a1@got(%2)" 6914 [(set_attr "type" "load")]) 6915 6916;; Used by sched, shorten_branches and final when the GOT pseudo reg 6917;; didn't get allocated to a hard register. 6918(define_split 6919 [(set (match_operand:SI 0 "gpc_reg_operand") 6920 (unspec:SI [(match_operand:SI 1 "got_no_const_operand") 6921 (match_operand:SI 2 "memory_operand")] 6922 UNSPEC_MOVSI_GOT))] 6923 "DEFAULT_ABI == ABI_V4 6924 && flag_pic == 1 6925 && reload_completed" 6926 [(set (match_dup 0) (match_dup 2)) 6927 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 6928 UNSPEC_MOVSI_GOT))] 6929 "") 6930 6931;; MR LA 6932;; LWZ LFIWZX LXSIWZX 6933;; STW STFIWX STXSIWX 6934;; LI LIS PLI # 6935;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW 6936;; XXLXOR 0 XXLORC -1 P9 const 6937;; MTVSRWZ MFVSRWZ 6938;; MF%1 MT%0 NOP 6939 6940(define_insn "*movsi_internal1" 6941 [(set (match_operand:SI 0 "nonimmediate_operand" 6942 "=r, r, 6943 r, d, v, 6944 m, ?Z, ?Z, 6945 r, r, r, r, 6946 wa, wa, wa, v, 6947 wa, v, v, 6948 wa, r, 6949 r, *h, *h") 6950 (match_operand:SI 1 "input_operand" 6951 "r, U, 6952 m, ?Z, ?Z, 6953 r, d, v, 6954 I, L, eI, n, 6955 wa, O, wM, wB, 6956 O, wM, wS, 6957 r, wa, 6958 *h, r, 0"))] 6959 "gpc_reg_operand (operands[0], SImode) 6960 || gpc_reg_operand (operands[1], SImode)" 6961 "@ 6962 mr %0,%1 6963 la %0,%a1 6964 lwz%U1%X1 %0,%1 6965 lfiwzx %0,%y1 6966 lxsiwzx %x0,%y1 6967 stw%U0%X0 %1,%0 6968 stfiwx %1,%y0 6969 stxsiwx %x1,%y0 6970 li %0,%1 6971 lis %0,%v1 6972 li %0,%1 6973 # 6974 xxlor %x0,%x1,%x1 6975 xxspltib %x0,0 6976 xxspltib %x0,255 6977 vspltisw %0,%1 6978 xxlxor %x0,%x0,%x0 6979 xxlorc %x0,%x0,%x0 6980 # 6981 mtvsrwz %x0,%1 6982 mfvsrwz %0,%x1 6983 mf%1 %0 6984 mt%0 %1 6985 nop" 6986 [(set_attr "type" 6987 "*, *, 6988 load, fpload, fpload, 6989 store, fpstore, fpstore, 6990 *, *, *, *, 6991 veclogical, vecsimple, vecsimple, vecsimple, 6992 veclogical, veclogical, vecsimple, 6993 mffgpr, mftgpr, 6994 *, *, *") 6995 (set_attr "length" 6996 "*, *, 6997 *, *, *, 6998 *, *, *, 6999 *, *, *, 8, 7000 *, *, *, *, 7001 *, *, 8, 7002 *, *, 7003 *, *, *") 7004 (set_attr "isa" 7005 "*, *, 7006 *, p8v, p8v, 7007 *, p8v, p8v, 7008 *, *, p10, *, 7009 p8v, p9v, p9v, p8v, 7010 p9v, p8v, p9v, 7011 p8v, p8v, 7012 *, *, *")]) 7013 7014;; Like movsi, but adjust a SF value to be used in a SI context, i.e. 7015;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0)) 7016;; 7017;; Because SF values are actually stored as DF values within the vector 7018;; registers, we need to convert the value to the vector SF format when 7019;; we need to use the bits in a union or similar cases. We only need 7020;; to do this transformation when the value is a vector register. Loads, 7021;; stores, and transfers within GPRs are assumed to be safe. 7022;; 7023;; This is a more general case of reload_gpr_from_vsxsf. That insn must have 7024;; no alternatives, because the call is created as part of secondary_reload, 7025;; and operand #2's register class is used to allocate the temporary register. 7026;; This function is called before reload, and it creates the temporary as 7027;; needed. 7028 7029;; MR LWZ LFIWZX LXSIWZX STW 7030;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX 7031;; MTVSRWZ 7032 7033(define_insn_and_split "movsi_from_sf" 7034 [(set (match_operand:SI 0 "nonimmediate_operand" 7035 "=r, r, ?*d, ?*v, m, 7036 m, wY, Z, r, ?*wa, 7037 wa") 7038 (unspec:SI [(match_operand:SF 1 "input_operand" 7039 "r, m, Z, Z, r, 7040 f, v, wa, wa, wa, 7041 r")] 7042 UNSPEC_SI_FROM_SF)) 7043 (clobber (match_scratch:V4SF 2 7044 "=X, X, X, X, X, 7045 X, X, X, wa, X, 7046 X"))] 7047 "TARGET_NO_SF_SUBREG 7048 && (register_operand (operands[0], SImode) 7049 || register_operand (operands[1], SFmode))" 7050 "@ 7051 mr %0,%1 7052 lwz%U1%X1 %0,%1 7053 lfiwzx %0,%y1 7054 lxsiwzx %x0,%y1 7055 stw%U0%X0 %1,%0 7056 stfs%U0%X0 %1,%0 7057 stxssp %1,%0 7058 stxsspx %x1,%y0 7059 # 7060 xscvdpspn %x0,%x1 7061 mtvsrwz %x0,%1" 7062 "&& reload_completed 7063 && int_reg_operand (operands[0], SImode) 7064 && vsx_reg_sfsubreg_ok (operands[1], SFmode)" 7065 [(const_int 0)] 7066{ 7067 rtx op0 = operands[0]; 7068 rtx op1 = operands[1]; 7069 rtx op2 = operands[2]; 7070 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0)); 7071 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 7072 7073 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 7074 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si)); 7075 DONE; 7076} 7077 [(set_attr "type" 7078 "*, load, fpload, fpload, store, 7079 fpstore, fpstore, fpstore, mftgpr, fp, 7080 mffgpr") 7081 (set_attr "length" 7082 "*, *, *, *, *, 7083 *, *, *, 8, *, 7084 *") 7085 (set_attr "isa" 7086 "*, *, p8v, p8v, *, 7087 *, p9v, p8v, p8v, p8v, 7088 p8v")]) 7089 7090;; movsi_from_sf with zero extension 7091;; 7092;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR 7093;; VSX->VSX MTVSRWZ 7094 7095(define_insn_and_split "*movdi_from_sf_zero_ext" 7096 [(set (match_operand:DI 0 "gpc_reg_operand" 7097 "=r, r, ?*d, ?*v, r, 7098 ?v, wa") 7099 (zero_extend:DI 7100 (unspec:SI [(match_operand:SF 1 "input_operand" 7101 "r, m, Z, Z, wa, 7102 wa, r")] 7103 UNSPEC_SI_FROM_SF))) 7104 (clobber (match_scratch:V4SF 2 7105 "=X, X, X, X, wa, 7106 wa, X"))] 7107 "TARGET_DIRECT_MOVE_64BIT 7108 && (register_operand (operands[0], DImode) 7109 || register_operand (operands[1], SImode))" 7110 "@ 7111 rldicl %0,%1,0,32 7112 lwz%U1%X1 %0,%1 7113 lfiwzx %0,%y1 7114 lxsiwzx %x0,%y1 7115 # 7116 # 7117 mtvsrwz %x0,%1" 7118 "&& reload_completed 7119 && register_operand (operands[0], DImode) 7120 && vsx_reg_sfsubreg_ok (operands[1], SFmode)" 7121 [(const_int 0)] 7122{ 7123 rtx op0 = operands[0]; 7124 rtx op1 = operands[1]; 7125 rtx op2 = operands[2]; 7126 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 7127 7128 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 7129 emit_insn (gen_zero_extendsidi2 (op0, op2_si)); 7130 DONE; 7131} 7132 [(set_attr "type" 7133 "*, load, fpload, fpload, two, 7134 two, mffgpr") 7135 (set_attr "length" 7136 "*, *, *, *, 8, 7137 8, *") 7138 (set_attr "isa" 7139 "*, *, p8v, p8v, p8v, 7140 p9v, p8v")]) 7141 7142;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before 7143;; moving it to SImode. We cannot do a SFmode store without having to do the 7144;; conversion explicitly since that doesn't work in most cases if the input 7145;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the 7146;; former handles cases where the input will not fit in a SFmode, and the 7147;; latter assumes the value has already been rounded. 7148(define_insn "*movsi_from_df" 7149 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa") 7150 (unspec:SI [(float_truncate:SF 7151 (match_operand:DF 1 "gpc_reg_operand" "wa"))] 7152 UNSPEC_SI_FROM_SF))] 7153 "TARGET_NO_SF_SUBREG" 7154 "xscvdpsp %x0,%x1" 7155 [(set_attr "type" "fp")]) 7156 7157;; Split a load of a large constant into the appropriate two-insn 7158;; sequence. 7159 7160(define_split 7161 [(set (match_operand:SI 0 "gpc_reg_operand") 7162 (match_operand:SI 1 "const_int_operand"))] 7163 "num_insns_constant (operands[1], SImode) > 1" 7164 [(set (match_dup 0) 7165 (match_dup 2)) 7166 (set (match_dup 0) 7167 (ior:SI (match_dup 0) 7168 (match_dup 3)))] 7169{ 7170 if (rs6000_emit_set_const (operands[0], operands[1])) 7171 DONE; 7172 else 7173 FAIL; 7174}) 7175 7176;; Split loading -128..127 to use XXSPLITB and VEXTSW2D 7177(define_split 7178 [(set (match_operand:DI 0 "altivec_register_operand") 7179 (match_operand:DI 1 "xxspltib_constant_split"))] 7180 "TARGET_P9_VECTOR && reload_completed" 7181 [(const_int 0)] 7182{ 7183 rtx op0 = operands[0]; 7184 rtx op1 = operands[1]; 7185 int r = REGNO (op0); 7186 rtx op0_v16qi = gen_rtx_REG (V16QImode, r); 7187 7188 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1)); 7189 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi)); 7190 DONE; 7191}) 7192 7193(define_insn "*mov<mode>_internal2" 7194 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y") 7195 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r") 7196 (const_int 0))) 7197 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))] 7198 "" 7199 "@ 7200 cmp<wd>i %2,%0,0 7201 mr. %0,%1 7202 #" 7203 [(set_attr "type" "cmp,logical,cmp") 7204 (set_attr "dot" "yes") 7205 (set_attr "length" "4,4,8")]) 7206 7207(define_split 7208 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand") 7209 (compare:CC (match_operand:P 1 "gpc_reg_operand") 7210 (const_int 0))) 7211 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))] 7212 "reload_completed" 7213 [(set (match_dup 0) (match_dup 1)) 7214 (set (match_dup 2) 7215 (compare:CC (match_dup 0) 7216 (const_int 0)))] 7217 "") 7218 7219(define_expand "mov<mode>" 7220 [(set (match_operand:INT 0 "general_operand") 7221 (match_operand:INT 1 "any_operand"))] 7222 "" 7223{ 7224 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7225 DONE; 7226}) 7227 7228;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI 7229;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ 7230;; MTVSRWZ MF%1 MT%1 NOP 7231(define_insn "*mov<mode>_internal" 7232 [(set (match_operand:QHI 0 "nonimmediate_operand" 7233 "=r, r, wa, m, ?Z, r, 7234 wa, wa, wa, v, ?v, r, 7235 wa, r, *c*l, *h") 7236 (match_operand:QHI 1 "input_operand" 7237 "r, m, ?Z, r, wa, i, 7238 wa, O, wM, wB, wS, wa, 7239 r, *h, r, 0"))] 7240 "gpc_reg_operand (operands[0], <MODE>mode) 7241 || gpc_reg_operand (operands[1], <MODE>mode)" 7242 "@ 7243 mr %0,%1 7244 l<wd>z%U1%X1 %0,%1 7245 lxsi<wd>zx %x0,%y1 7246 st<wd>%U0%X0 %1,%0 7247 stxsi<wd>x %x1,%y0 7248 li %0,%1 7249 xxlor %x0,%x1,%x1 7250 xxspltib %x0,0 7251 xxspltib %x0,255 7252 vspltis<wd> %0,%1 7253 # 7254 mfvsrwz %0,%x1 7255 mtvsrwz %x0,%1 7256 mf%1 %0 7257 mt%0 %1 7258 nop" 7259 [(set_attr "type" 7260 "*, load, fpload, store, fpstore, *, 7261 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr, 7262 mffgpr, mfjmpr, mtjmpr, *") 7263 (set_attr "length" 7264 "*, *, *, *, *, *, 7265 *, *, *, *, 8, *, 7266 *, *, *, *") 7267 (set_attr "isa" 7268 "*, *, p9v, *, p9v, *, 7269 p9v, p9v, p9v, p9v, p9v, p9v, 7270 p9v, *, *, *")]) 7271 7272 7273;; Here is how to move condition codes around. When we store CC data in 7274;; an integer register or memory, we store just the high-order 4 bits. 7275;; This lets us not shift in the most common case of CR0. 7276(define_expand "movcc" 7277 [(set (match_operand:CC 0 "nonimmediate_operand") 7278 (match_operand:CC 1 "nonimmediate_operand"))] 7279 "" 7280 "") 7281 7282(define_mode_iterator CC_any [CC CCUNS CCEQ CCFP]) 7283 7284(define_insn "*movcc_<mode>" 7285 [(set (match_operand:CC_any 0 "nonimmediate_operand" 7286 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m") 7287 (match_operand:CC_any 1 "general_operand" 7288 " y,r, r,O,x,y,r,I,*h, r,m,r"))] 7289 "register_operand (operands[0], <MODE>mode) 7290 || register_operand (operands[1], <MODE>mode)" 7291 "@ 7292 mcrf %0,%1 7293 mtcrf 128,%1 7294 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff 7295 crxor %0,%0,%0 7296 mfcr %0%Q1 7297 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000 7298 mr %0,%1 7299 li %0,%1 7300 mf%1 %0 7301 mt%0 %1 7302 lwz%U1%X1 %0,%1 7303 stw%U0%X0 %1,%0" 7304 [(set_attr_alternative "type" 7305 [(const_string "cr_logical") 7306 (const_string "mtcr") 7307 (const_string "mtcr") 7308 (const_string "cr_logical") 7309 (if_then_else (match_test "TARGET_MFCRF") 7310 (const_string "mfcrf") (const_string "mfcr")) 7311 (if_then_else (match_test "TARGET_MFCRF") 7312 (const_string "mfcrf") (const_string "mfcr")) 7313 (const_string "integer") 7314 (const_string "integer") 7315 (const_string "mfjmpr") 7316 (const_string "mtjmpr") 7317 (const_string "load") 7318 (const_string "store")]) 7319 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")]) 7320 7321;; For floating-point, we normally deal with the floating-point registers 7322;; unless -msoft-float is used. The sole exception is that parameter passing 7323;; can produce floating-point values in fixed-point registers. Unless the 7324;; value is a simple constant or already in memory, we deal with this by 7325;; allocating memory and copying the value explicitly via that memory location. 7326 7327;; Move 32-bit binary/decimal floating point 7328(define_expand "mov<mode>" 7329 [(set (match_operand:FMOVE32 0 "nonimmediate_operand") 7330 (match_operand:FMOVE32 1 "any_operand"))] 7331 "<fmove_ok>" 7332{ 7333 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7334 DONE; 7335}) 7336 7337(define_split 7338 [(set (match_operand:FMOVE32 0 "gpc_reg_operand") 7339 (match_operand:FMOVE32 1 "const_double_operand"))] 7340 "reload_completed 7341 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 7342 || (SUBREG_P (operands[0]) 7343 && REG_P (SUBREG_REG (operands[0])) 7344 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7345 [(set (match_dup 2) (match_dup 3))] 7346{ 7347 long l; 7348 7349 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7350 7351 if (! TARGET_POWERPC64) 7352 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); 7353 else 7354 operands[2] = gen_lowpart (SImode, operands[0]); 7355 7356 operands[3] = gen_int_mode (l, SImode); 7357}) 7358 7359;; Originally, we tried to keep movsf and movsd common, but the differences 7360;; addressing was making it rather difficult to hide with mode attributes. In 7361;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store 7362;; before the VSX stores meant that the register allocator would tend to do a 7363;; direct move to the GPR (which involves conversion from scalar to 7364;; vector/memory formats) to save values in the traditional Altivec registers, 7365;; while SDmode had problems on power6 if the GPR store was not first due to 7366;; the power6 not having an integer store operation. 7367;; 7368;; LWZ LFS LXSSP LXSSPX STFS STXSSP 7369;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP 7370;; MR MT<x> MF<x> NOP 7371 7372(define_insn "movsf_hardfloat" 7373 [(set (match_operand:SF 0 "nonimmediate_operand" 7374 "=!r, f, v, wa, m, wY, 7375 Z, m, wa, !r, f, wa, 7376 !r, *c*l, !r, *h") 7377 (match_operand:SF 1 "input_operand" 7378 "m, m, wY, Z, f, v, 7379 wa, r, j, j, f, wa, 7380 r, r, *h, 0"))] 7381 "(register_operand (operands[0], SFmode) 7382 || register_operand (operands[1], SFmode)) 7383 && TARGET_HARD_FLOAT 7384 && (TARGET_ALLOW_SF_SUBREG 7385 || valid_sf_si_move (operands[0], operands[1], SFmode))" 7386 "@ 7387 lwz%U1%X1 %0,%1 7388 lfs%U1%X1 %0,%1 7389 lxssp %0,%1 7390 lxsspx %x0,%y1 7391 stfs%U0%X0 %1,%0 7392 stxssp %1,%0 7393 stxsspx %x1,%y0 7394 stw%U0%X0 %1,%0 7395 xxlxor %x0,%x0,%x0 7396 li %0,0 7397 fmr %0,%1 7398 xscpsgndp %x0,%x1,%x1 7399 mr %0,%1 7400 mt%0 %1 7401 mf%1 %0 7402 nop" 7403 [(set_attr "type" 7404 "load, fpload, fpload, fpload, fpstore, fpstore, 7405 fpstore, store, veclogical, integer, fpsimple, fpsimple, 7406 *, mtjmpr, mfjmpr, *") 7407 (set_attr "isa" 7408 "*, *, p9v, p8v, *, p9v, 7409 p8v, *, *, *, *, *, 7410 *, *, *, *")]) 7411 7412;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ 7413;; FMR MR MT%0 MF%1 NOP 7414(define_insn "movsd_hardfloat" 7415 [(set (match_operand:SD 0 "nonimmediate_operand" 7416 "=!r, d, m, ?Z, ?d, ?r, 7417 f, !r, *c*l, !r, *h") 7418 (match_operand:SD 1 "input_operand" 7419 "m, ?Z, r, wx, r, d, 7420 f, r, r, *h, 0"))] 7421 "(register_operand (operands[0], SDmode) 7422 || register_operand (operands[1], SDmode)) 7423 && TARGET_HARD_FLOAT" 7424 "@ 7425 lwz%U1%X1 %0,%1 7426 lfiwzx %0,%y1 7427 stw%U0%X0 %1,%0 7428 stfiwx %1,%y0 7429 mtvsrwz %x0,%1 7430 mfvsrwz %0,%x1 7431 fmr %0,%1 7432 mr %0,%1 7433 mt%0 %1 7434 mf%1 %0 7435 nop" 7436 [(set_attr "type" 7437 "load, fpload, store, fpstore, mffgpr, mftgpr, 7438 fpsimple, *, mtjmpr, mfjmpr, *") 7439 (set_attr "isa" 7440 "*, p7, *, *, p8v, p8v, 7441 *, *, *, *, *")]) 7442 7443;; MR MT%0 MF%0 LWZ STW LI 7444;; LIS G-const. F/n-const NOP 7445(define_insn "*mov<mode>_softfloat" 7446 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" 7447 "=r, *c*l, r, r, m, r, 7448 r, r, r, *h") 7449 7450 (match_operand:FMOVE32 1 "input_operand" 7451 "r, r, *h, m, r, I, 7452 L, G, Fn, 0"))] 7453 7454 "(gpc_reg_operand (operands[0], <MODE>mode) 7455 || gpc_reg_operand (operands[1], <MODE>mode)) 7456 && TARGET_SOFT_FLOAT" 7457 "@ 7458 mr %0,%1 7459 mt%0 %1 7460 mf%1 %0 7461 lwz%U1%X1 %0,%1 7462 stw%U0%X0 %1,%0 7463 li %0,%1 7464 lis %0,%v1 7465 # 7466 # 7467 nop" 7468 [(set_attr "type" 7469 "*, mtjmpr, mfjmpr, load, store, *, 7470 *, *, *, *") 7471 7472 (set_attr "length" 7473 "*, *, *, *, *, *, 7474 *, *, 8, *")]) 7475 7476;; Like movsf, but adjust a SI value to be used in a SF context, i.e. 7477;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0)) 7478;; 7479;; Because SF values are actually stored as DF values within the vector 7480;; registers, we need to convert the value to the vector SF format when 7481;; we need to use the bits in a union or similar cases. We only need 7482;; to do this transformation when the value is a vector register. Loads, 7483;; stores, and transfers within GPRs are assumed to be safe. 7484;; 7485;; This is a more general case of reload_vsx_from_gprsf. That insn must have 7486;; no alternatives, because the call is created as part of secondary_reload, 7487;; and operand #2's register class is used to allocate the temporary register. 7488;; This function is called before reload, and it creates the temporary as 7489;; needed. 7490 7491;; LWZ LFS LXSSP LXSSPX STW STFIWX 7492;; STXSIWX GPR->VSX VSX->GPR GPR->GPR 7493(define_insn_and_split "movsf_from_si" 7494 [(set (match_operand:SF 0 "nonimmediate_operand" 7495 "=!r, f, v, wa, m, Z, 7496 Z, wa, ?r, !r") 7497 (unspec:SF [(match_operand:SI 1 "input_operand" 7498 "m, m, wY, Z, r, f, 7499 wa, r, wa, r")] 7500 UNSPEC_SF_FROM_SI)) 7501 (clobber (match_scratch:DI 2 7502 "=X, X, X, X, X, X, 7503 X, r, X, X"))] 7504 "TARGET_NO_SF_SUBREG 7505 && (register_operand (operands[0], SFmode) 7506 || register_operand (operands[1], SImode))" 7507 "@ 7508 lwz%U1%X1 %0,%1 7509 lfs%U1%X1 %0,%1 7510 lxssp %0,%1 7511 lxsspx %x0,%y1 7512 stw%U0%X0 %1,%0 7513 stfiwx %1,%y0 7514 stxsiwx %x1,%y0 7515 # 7516 mfvsrwz %0,%x1 7517 mr %0,%1" 7518 7519 "&& reload_completed 7520 && vsx_reg_sfsubreg_ok (operands[0], SFmode) 7521 && int_reg_operand_not_pseudo (operands[1], SImode)" 7522 [(const_int 0)] 7523{ 7524 rtx op0 = operands[0]; 7525 rtx op1 = operands[1]; 7526 rtx op2 = operands[2]; 7527 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1)); 7528 7529 /* Move SF value to upper 32-bits for xscvspdpn. */ 7530 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 7531 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 7532 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 7533 DONE; 7534} 7535 [(set_attr "length" 7536 "*, *, *, *, *, *, 7537 *, 12, *, *") 7538 (set_attr "type" 7539 "load, fpload, fpload, fpload, store, fpstore, 7540 fpstore, vecfloat, mffgpr, *") 7541 (set_attr "isa" 7542 "*, *, p9v, p8v, *, *, 7543 p8v, p8v, p8v, *")]) 7544 7545 7546;; Move 64-bit binary/decimal floating point 7547(define_expand "mov<mode>" 7548 [(set (match_operand:FMOVE64 0 "nonimmediate_operand") 7549 (match_operand:FMOVE64 1 "any_operand"))] 7550 "" 7551{ 7552 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7553 DONE; 7554}) 7555 7556(define_split 7557 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 7558 (match_operand:FMOVE64 1 "const_int_operand"))] 7559 "! TARGET_POWERPC64 && reload_completed 7560 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 7561 || (SUBREG_P (operands[0]) 7562 && REG_P (SUBREG_REG (operands[0])) 7563 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7564 [(set (match_dup 2) (match_dup 4)) 7565 (set (match_dup 3) (match_dup 1))] 7566{ 7567 int endian = (WORDS_BIG_ENDIAN == 0); 7568 HOST_WIDE_INT value = INTVAL (operands[1]); 7569 7570 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 7571 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 7572 operands[4] = GEN_INT (value >> 32); 7573 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 7574}) 7575 7576(define_split 7577 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 7578 (match_operand:FMOVE64 1 "const_double_operand"))] 7579 "! TARGET_POWERPC64 && reload_completed 7580 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 7581 || (SUBREG_P (operands[0]) 7582 && REG_P (SUBREG_REG (operands[0])) 7583 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7584 [(set (match_dup 2) (match_dup 4)) 7585 (set (match_dup 3) (match_dup 5))] 7586{ 7587 int endian = (WORDS_BIG_ENDIAN == 0); 7588 long l[2]; 7589 7590 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7591 7592 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 7593 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 7594 operands[4] = gen_int_mode (l[endian], SImode); 7595 operands[5] = gen_int_mode (l[1 - endian], SImode); 7596}) 7597 7598(define_split 7599 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 7600 (match_operand:FMOVE64 1 "const_double_operand"))] 7601 "TARGET_POWERPC64 && reload_completed 7602 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 7603 || (SUBREG_P (operands[0]) 7604 && REG_P (SUBREG_REG (operands[0])) 7605 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7606 [(set (match_dup 2) (match_dup 3))] 7607{ 7608 int endian = (WORDS_BIG_ENDIAN == 0); 7609 long l[2]; 7610 HOST_WIDE_INT val; 7611 7612 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7613 7614 operands[2] = gen_lowpart (DImode, operands[0]); 7615 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ 7616 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 7617 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); 7618 7619 operands[3] = gen_int_mode (val, DImode); 7620}) 7621 7622;; Don't have reload use general registers to load a constant. It is 7623;; less efficient than loading the constant into an FP register, since 7624;; it will probably be used there. 7625 7626;; The move constraints are ordered to prefer floating point registers before 7627;; general purpose registers to avoid doing a store and a load to get the value 7628;; into a floating point register when it is needed for a floating point 7629;; operation. Prefer traditional floating point registers over VSX registers, 7630;; since the D-form version of the memory instructions does not need a GPR for 7631;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec 7632;; registers. 7633 7634;; If we have FPR registers, rs6000_emit_move has moved all constants to memory, 7635;; except for 0.0 which can be created on VSX with an xor instruction. 7636 7637;; STFD LFD FMR LXSD STXSD 7638;; LXSD STXSD XXLOR XXLXOR GPR<-0 7639;; LWZ STW MR 7640 7641 7642(define_insn "*mov<mode>_hardfloat32" 7643 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 7644 "=m, d, d, <f64_p9>, wY, 7645 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r, 7646 Y, r, !r") 7647 (match_operand:FMOVE64 1 "input_operand" 7648 "d, m, d, wY, <f64_p9>, 7649 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>, 7650 r, Y, r"))] 7651 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT 7652 && (gpc_reg_operand (operands[0], <MODE>mode) 7653 || gpc_reg_operand (operands[1], <MODE>mode))" 7654 "@ 7655 stfd%U0%X0 %1,%0 7656 lfd%U1%X1 %0,%1 7657 fmr %0,%1 7658 lxsd %0,%1 7659 stxsd %1,%0 7660 lxsdx %x0,%y1 7661 stxsdx %x1,%y0 7662 xxlor %x0,%x1,%x1 7663 xxlxor %x0,%x0,%x0 7664 # 7665 # 7666 # 7667 #" 7668 [(set_attr "type" 7669 "fpstore, fpload, fpsimple, fpload, fpstore, 7670 fpload, fpstore, veclogical, veclogical, two, 7671 store, load, two") 7672 (set_attr "size" "64") 7673 (set_attr "length" 7674 "*, *, *, *, *, 7675 *, *, *, *, 8, 7676 8, 8, 8") 7677 (set_attr "isa" 7678 "*, *, *, p9v, p9v, 7679 p7v, p7v, *, *, *, 7680 *, *, *")]) 7681 7682;; STW LWZ MR G-const H-const F-const 7683 7684(define_insn "*mov<mode>_softfloat32" 7685 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 7686 "=Y, r, r, r, r, r") 7687 7688 (match_operand:FMOVE64 1 "input_operand" 7689 "r, Y, r, G, H, F"))] 7690 7691 "!TARGET_POWERPC64 7692 && (gpc_reg_operand (operands[0], <MODE>mode) 7693 || gpc_reg_operand (operands[1], <MODE>mode))" 7694 "#" 7695 [(set_attr "type" 7696 "store, load, two, *, *, *") 7697 7698 (set_attr "length" 7699 "8, 8, 8, 8, 12, 16")]) 7700 7701; ld/std require word-aligned displacements -> 'Y' constraint. 7702; List Y->r and r->Y before r->r for reload. 7703 7704;; STFD LFD FMR LXSD STXSD 7705;; LXSDX STXSDX XXLOR XXLXOR LI 0 7706;; STD LD MR MT{CTR,LR} MF{CTR,LR} 7707;; NOP MFVSRD MTVSRD 7708 7709(define_insn "*mov<mode>_hardfloat64" 7710 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 7711 "=m, d, d, <f64_p9>, wY, 7712 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r, 7713 YZ, r, !r, *c*l, !r, 7714 *h, r, <f64_dm>") 7715 (match_operand:FMOVE64 1 "input_operand" 7716 "d, m, d, wY, <f64_p9>, 7717 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>, 7718 r, YZ, r, r, *h, 7719 0, <f64_dm>, r"))] 7720 "TARGET_POWERPC64 && TARGET_HARD_FLOAT 7721 && (gpc_reg_operand (operands[0], <MODE>mode) 7722 || gpc_reg_operand (operands[1], <MODE>mode))" 7723 "@ 7724 stfd%U0%X0 %1,%0 7725 lfd%U1%X1 %0,%1 7726 fmr %0,%1 7727 lxsd %0,%1 7728 stxsd %1,%0 7729 lxsdx %x0,%y1 7730 stxsdx %x1,%y0 7731 xxlor %x0,%x1,%x1 7732 xxlxor %x0,%x0,%x0 7733 li %0,0 7734 std%U0%X0 %1,%0 7735 ld%U1%X1 %0,%1 7736 mr %0,%1 7737 mt%0 %1 7738 mf%1 %0 7739 nop 7740 mfvsrd %0,%x1 7741 mtvsrd %x0,%1" 7742 [(set_attr "type" 7743 "fpstore, fpload, fpsimple, fpload, fpstore, 7744 fpload, fpstore, veclogical, veclogical, integer, 7745 store, load, *, mtjmpr, mfjmpr, 7746 *, mftgpr, mffgpr") 7747 (set_attr "size" "64") 7748 (set_attr "isa" 7749 "*, *, *, p9v, p9v, 7750 p7v, p7v, *, *, *, 7751 *, *, *, *, *, 7752 *, p8v, p8v")]) 7753 7754;; STD LD MR MT<SPR> MF<SPR> G-const 7755;; H-const F-const Special 7756 7757(define_insn "*mov<mode>_softfloat64" 7758 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 7759 "=Y, r, r, *c*l, r, r, 7760 r, r, *h") 7761 7762 (match_operand:FMOVE64 1 "input_operand" 7763 "r, Y, r, r, *h, G, 7764 H, F, 0"))] 7765 7766 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT 7767 && (gpc_reg_operand (operands[0], <MODE>mode) 7768 || gpc_reg_operand (operands[1], <MODE>mode))" 7769 "@ 7770 std%U0%X0 %1,%0 7771 ld%U1%X1 %0,%1 7772 mr %0,%1 7773 mt%0 %1 7774 mf%1 %0 7775 # 7776 # 7777 # 7778 nop" 7779 [(set_attr "type" 7780 "store, load, *, mtjmpr, mfjmpr, *, 7781 *, *, *") 7782 7783 (set_attr "length" 7784 "*, *, *, *, *, 8, 7785 12, 16, *")]) 7786 7787(define_expand "mov<mode>" 7788 [(set (match_operand:FMOVE128 0 "general_operand") 7789 (match_operand:FMOVE128 1 "any_operand"))] 7790 "" 7791{ 7792 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7793 DONE; 7794}) 7795 7796;; It's important to list Y->r and r->Y before r->r because otherwise 7797;; reload, given m->r, will try to pick r->r and reload it, which 7798;; doesn't make progress. 7799 7800;; We can't split little endian direct moves of TDmode, because the words are 7801;; not swapped like they are for TImode or TFmode. Subregs therefore are 7802;; problematical. Don't allow direct move for this case. 7803 7804;; FPR load FPR store FPR move FPR zero GPR load 7805;; GPR zero GPR store GPR move MFVSRD MTVSRD 7806 7807(define_insn_and_split "*mov<mode>_64bit_dm" 7808 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" 7809 "=m, d, d, d, Y, 7810 r, r, r, r, d") 7811 7812 (match_operand:FMOVE128_FPR 1 "input_operand" 7813 "d, m, d, <zero_fp>, r, 7814 <zero_fp>, Y, r, d, r"))] 7815 7816 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode) 7817 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN) 7818 && (gpc_reg_operand (operands[0], <MODE>mode) 7819 || gpc_reg_operand (operands[1], <MODE>mode))" 7820 "#" 7821 "&& reload_completed" 7822 [(pc)] 7823{ 7824 rs6000_split_multireg_move (operands[0], operands[1]); 7825 DONE; 7826} 7827 [(set_attr "length" "8") 7828 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v") 7829 (set_attr "max_prefixed_insns" "2") 7830 (set_attr "num_insns" "2")]) 7831 7832(define_insn_and_split "*movtd_64bit_nodm" 7833 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r") 7834 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))] 7835 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN 7836 && (gpc_reg_operand (operands[0], TDmode) 7837 || gpc_reg_operand (operands[1], TDmode))" 7838 "#" 7839 "&& reload_completed" 7840 [(pc)] 7841{ 7842 rs6000_split_multireg_move (operands[0], operands[1]); 7843 DONE; 7844} 7845 [(set_attr "length" "8,8,8,12,12,8") 7846 (set_attr "max_prefixed_insns" "2") 7847 (set_attr "num_insns" "2,2,2,3,3,2")]) 7848 7849(define_insn_and_split "*mov<mode>_32bit" 7850 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r") 7851 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))] 7852 "TARGET_HARD_FLOAT && !TARGET_POWERPC64 7853 && (FLOAT128_2REG_P (<MODE>mode) 7854 || int_reg_operand_not_pseudo (operands[0], <MODE>mode) 7855 || int_reg_operand_not_pseudo (operands[1], <MODE>mode)) 7856 && (gpc_reg_operand (operands[0], <MODE>mode) 7857 || gpc_reg_operand (operands[1], <MODE>mode))" 7858 "#" 7859 "&& reload_completed" 7860 [(pc)] 7861{ 7862 rs6000_split_multireg_move (operands[0], operands[1]); 7863 DONE; 7864} 7865 [(set_attr "length" "8,8,8,8,20,20,16")]) 7866 7867(define_insn_and_split "*mov<mode>_softfloat" 7868 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r") 7869 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))] 7870 "TARGET_SOFT_FLOAT 7871 && (gpc_reg_operand (operands[0], <MODE>mode) 7872 || gpc_reg_operand (operands[1], <MODE>mode))" 7873 "#" 7874 "&& reload_completed" 7875 [(pc)] 7876{ 7877 rs6000_split_multireg_move (operands[0], operands[1]); 7878 DONE; 7879} 7880 [(set_attr_alternative "length" 7881 [(if_then_else (match_test "TARGET_POWERPC64") 7882 (const_string "8") 7883 (const_string "16")) 7884 (if_then_else (match_test "TARGET_POWERPC64") 7885 (const_string "8") 7886 (const_string "16")) 7887 (if_then_else (match_test "TARGET_POWERPC64") 7888 (const_string "16") 7889 (const_string "32")) 7890 (if_then_else (match_test "TARGET_POWERPC64") 7891 (const_string "8") 7892 (const_string "16"))])]) 7893 7894(define_expand "@extenddf<mode>2" 7895 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7896 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))] 7897 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7898{ 7899 if (FLOAT128_IEEE_P (<MODE>mode)) 7900 rs6000_expand_float128_convert (operands[0], operands[1], false); 7901 else if (TARGET_VSX) 7902 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1])); 7903 else 7904 { 7905 rtx zero = gen_reg_rtx (DFmode); 7906 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode); 7907 7908 emit_insn (gen_extenddf2_fprs (<MODE>mode, 7909 operands[0], operands[1], zero)); 7910 } 7911 DONE; 7912}) 7913 7914;; Allow memory operands for the source to be created by the combiner. 7915(define_insn_and_split "@extenddf<mode>2_fprs" 7916 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d") 7917 (float_extend:IBM128 7918 (match_operand:DF 1 "nonimmediate_operand" "d,m,d"))) 7919 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))] 7920 "!TARGET_VSX && TARGET_HARD_FLOAT 7921 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" 7922 "#" 7923 "&& reload_completed" 7924 [(set (match_dup 3) (match_dup 1)) 7925 (set (match_dup 4) (match_dup 2))] 7926{ 7927 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 7928 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 7929 7930 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 7931 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 7932}) 7933 7934(define_insn_and_split "@extenddf<mode>2_vsx" 7935 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d") 7936 (float_extend:IBM128 7937 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))] 7938 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)" 7939 "#" 7940 "&& reload_completed" 7941 [(set (match_dup 2) (match_dup 1)) 7942 (set (match_dup 3) (match_dup 4))] 7943{ 7944 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 7945 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 7946 7947 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 7948 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 7949 operands[4] = CONST0_RTX (DFmode); 7950}) 7951 7952(define_expand "extendsf<mode>2" 7953 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7954 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))] 7955 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7956{ 7957 if (FLOAT128_IEEE_P (<MODE>mode)) 7958 rs6000_expand_float128_convert (operands[0], operands[1], false); 7959 else 7960 { 7961 rtx tmp = gen_reg_rtx (DFmode); 7962 emit_insn (gen_extendsfdf2 (tmp, operands[1])); 7963 emit_insn (gen_extenddf<mode>2 (operands[0], tmp)); 7964 } 7965 DONE; 7966}) 7967 7968(define_expand "trunc<mode>df2" 7969 [(set (match_operand:DF 0 "gpc_reg_operand") 7970 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))] 7971 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7972{ 7973 if (FLOAT128_IEEE_P (<MODE>mode)) 7974 { 7975 rs6000_expand_float128_convert (operands[0], operands[1], false); 7976 DONE; 7977 } 7978}) 7979 7980(define_insn_and_split "trunc<mode>df2_internal1" 7981 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d") 7982 (float_truncate:DF 7983 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))] 7984 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT 7985 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7986 "@ 7987 # 7988 fmr %0,%1" 7989 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 7990 [(const_int 0)] 7991{ 7992 emit_note (NOTE_INSN_DELETED); 7993 DONE; 7994} 7995 [(set_attr "type" "fpsimple")]) 7996 7997(define_insn "trunc<mode>df2_internal2" 7998 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7999 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 8000 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT 8001 && TARGET_LONG_DOUBLE_128" 8002 "fadd %0,%1,%L1" 8003 [(set_attr "type" "fp")]) 8004 8005(define_expand "trunc<mode>sf2" 8006 [(set (match_operand:SF 0 "gpc_reg_operand") 8007 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8008 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8009{ 8010 if (FLOAT128_IEEE_P (<MODE>mode)) 8011 rs6000_expand_float128_convert (operands[0], operands[1], false); 8012 else 8013 { 8014 rtx tmp = gen_reg_rtx (DFmode); 8015 emit_insn (gen_trunc<mode>df2 (tmp, operands[1])); 8016 emit_insn (gen_truncdfsf2 (operands[0], tmp)); 8017 } 8018 DONE; 8019}) 8020 8021(define_expand "floatsi<mode>2" 8022 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 8023 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand"))) 8024 (clobber (match_scratch:DI 2))])] 8025 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8026{ 8027 rtx op0 = operands[0]; 8028 rtx op1 = operands[1]; 8029 8030 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)) 8031 ; 8032 else if (FLOAT128_IEEE_P (<MODE>mode)) 8033 { 8034 rs6000_expand_float128_convert (op0, op1, false); 8035 DONE; 8036 } 8037 else 8038 { 8039 rtx tmp = gen_reg_rtx (DFmode); 8040 expand_float (tmp, op1, false); 8041 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp)); 8042 DONE; 8043 } 8044}) 8045 8046; fadd, but rounding towards zero. 8047; This is probably not the optimal code sequence. 8048(define_insn "fix_trunc_helper<mode>" 8049 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 8050 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")] 8051 UNSPEC_FIX_TRUNC_TF)) 8052 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))] 8053 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)" 8054 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" 8055 [(set_attr "type" "fp") 8056 (set_attr "length" "20")]) 8057 8058(define_expand "fix_trunc<mode>si2" 8059 [(set (match_operand:SI 0 "gpc_reg_operand") 8060 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8061 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8062{ 8063 rtx op0 = operands[0]; 8064 rtx op1 = operands[1]; 8065 8066 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)) 8067 ; 8068 else 8069 { 8070 if (FLOAT128_IEEE_P (<MODE>mode)) 8071 rs6000_expand_float128_convert (op0, op1, false); 8072 else 8073 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1)); 8074 DONE; 8075 } 8076}) 8077 8078(define_expand "@fix_trunc<mode>si2_fprs" 8079 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand") 8080 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand"))) 8081 (clobber (match_dup 2)) 8082 (clobber (match_dup 3)) 8083 (clobber (match_dup 4)) 8084 (clobber (match_dup 5))])] 8085 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8086{ 8087 operands[2] = gen_reg_rtx (DFmode); 8088 operands[3] = gen_reg_rtx (DFmode); 8089 operands[4] = gen_reg_rtx (DImode); 8090 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode)); 8091}) 8092 8093(define_insn_and_split "*fix_trunc<mode>si2_internal" 8094 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 8095 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d"))) 8096 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d")) 8097 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d")) 8098 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d")) 8099 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))] 8100 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8101 "#" 8102 "" 8103 [(pc)] 8104{ 8105 rtx lowword; 8106 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1], 8107 operands[3])); 8108 8109 gcc_assert (MEM_P (operands[5])); 8110 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 8111 8112 emit_insn (gen_fctiwz_df (operands[4], operands[2])); 8113 emit_move_insn (operands[5], operands[4]); 8114 emit_move_insn (operands[0], lowword); 8115 DONE; 8116}) 8117 8118(define_expand "fix_trunc<mode>di2" 8119 [(set (match_operand:DI 0 "gpc_reg_operand") 8120 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))] 8121 "TARGET_FLOAT128_TYPE" 8122{ 8123 if (!TARGET_FLOAT128_HW) 8124 { 8125 rs6000_expand_float128_convert (operands[0], operands[1], false); 8126 DONE; 8127 } 8128}) 8129 8130(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2" 8131 [(set (match_operand:SDI 0 "gpc_reg_operand") 8132 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))] 8133 "TARGET_FLOAT128_TYPE" 8134{ 8135 rs6000_expand_float128_convert (operands[0], operands[1], true); 8136 DONE; 8137}) 8138 8139(define_expand "floatdi<mode>2" 8140 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 8141 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))] 8142 "TARGET_FLOAT128_TYPE" 8143{ 8144 if (!TARGET_FLOAT128_HW) 8145 { 8146 rs6000_expand_float128_convert (operands[0], operands[1], false); 8147 DONE; 8148 } 8149}) 8150 8151(define_expand "floatunsdi<IEEE128:mode>2" 8152 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 8153 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))] 8154 "TARGET_FLOAT128_TYPE" 8155{ 8156 if (!TARGET_FLOAT128_HW) 8157 { 8158 rs6000_expand_float128_convert (operands[0], operands[1], true); 8159 DONE; 8160 } 8161}) 8162 8163(define_expand "floatuns<IEEE128:mode>2" 8164 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 8165 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))] 8166 "TARGET_FLOAT128_TYPE" 8167{ 8168 rtx op0 = operands[0]; 8169 rtx op1 = operands[1]; 8170 8171 if (TARGET_FLOAT128_HW) 8172 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1)); 8173 else 8174 rs6000_expand_float128_convert (op0, op1, true); 8175 DONE; 8176}) 8177 8178(define_expand "neg<mode>2" 8179 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 8180 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8181 "FLOAT128_IEEE_P (<MODE>mode) 8182 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" 8183{ 8184 if (FLOAT128_IEEE_P (<MODE>mode)) 8185 { 8186 if (TARGET_FLOAT128_HW) 8187 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1])); 8188 else if (TARGET_FLOAT128_TYPE) 8189 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode, 8190 operands[0], operands[1])); 8191 else 8192 { 8193 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode); 8194 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST, 8195 <MODE>mode, 8196 operands[1], <MODE>mode); 8197 8198 if (target && !rtx_equal_p (target, operands[0])) 8199 emit_move_insn (operands[0], target); 8200 } 8201 DONE; 8202 } 8203}) 8204 8205(define_insn "neg<mode>2_internal" 8206 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d") 8207 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 8208 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)" 8209{ 8210 if (REGNO (operands[0]) == REGNO (operands[1]) + 1) 8211 return "fneg %L0,%L1\;fneg %0,%1"; 8212 else 8213 return "fneg %0,%1\;fneg %L0,%L1"; 8214} 8215 [(set_attr "type" "fpsimple") 8216 (set_attr "length" "8")]) 8217 8218(define_expand "abs<mode>2" 8219 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 8220 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8221 "FLOAT128_IEEE_P (<MODE>mode) 8222 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" 8223{ 8224 rtx label; 8225 8226 if (FLOAT128_IEEE_P (<MODE>mode)) 8227 { 8228 if (TARGET_FLOAT128_HW) 8229 { 8230 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1])); 8231 DONE; 8232 } 8233 else if (TARGET_FLOAT128_TYPE) 8234 { 8235 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode, 8236 operands[0], operands[1])); 8237 DONE; 8238 } 8239 else 8240 FAIL; 8241 } 8242 8243 label = gen_label_rtx (); 8244 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label)); 8245 emit_label (label); 8246 DONE; 8247}) 8248 8249(define_expand "@abs<mode>2_internal" 8250 [(set (match_operand:IBM128 0 "gpc_reg_operand") 8251 (match_operand:IBM128 1 "gpc_reg_operand")) 8252 (set (match_dup 3) (match_dup 5)) 8253 (set (match_dup 5) (abs:DF (match_dup 5))) 8254 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5))) 8255 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0)) 8256 (label_ref (match_operand 2 "")) 8257 (pc))) 8258 (set (match_dup 6) (neg:DF (match_dup 6)))] 8259 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8260{ 8261 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 8262 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 8263 operands[3] = gen_reg_rtx (DFmode); 8264 operands[4] = gen_reg_rtx (CCFPmode); 8265 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 8266 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 8267}) 8268 8269 8270;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector 8271;; register 8272 8273(define_expand "ieee_128bit_negative_zero" 8274 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))] 8275 "TARGET_FLOAT128_TYPE" 8276{ 8277 rtvec v = rtvec_alloc (16); 8278 int i, high; 8279 8280 for (i = 0; i < 16; i++) 8281 RTVEC_ELT (v, i) = const0_rtx; 8282 8283 high = (BYTES_BIG_ENDIAN) ? 0 : 15; 8284 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode); 8285 8286 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v)); 8287 DONE; 8288}) 8289 8290;; IEEE 128-bit negate 8291 8292;; We have 2 insns here for negate and absolute value. The first uses 8293;; match_scratch so that phases like combine can recognize neg/abs as generic 8294;; insns, and second insn after the first split pass loads up the bit to 8295;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of 8296;; neg/abs to create the constant just once. 8297 8298(define_insn_and_split "@ieee_128bit_vsx_neg<mode>2" 8299 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8300 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8301 (clobber (match_scratch:V16QI 2 "=v"))] 8302 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8303 "#" 8304 "&& 1" 8305 [(parallel [(set (match_dup 0) 8306 (neg:IEEE128 (match_dup 1))) 8307 (use (match_dup 2))])] 8308{ 8309 if (GET_CODE (operands[2]) == SCRATCH) 8310 operands[2] = gen_reg_rtx (V16QImode); 8311 8312 operands[3] = gen_reg_rtx (V16QImode); 8313 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8314} 8315 [(set_attr "length" "8") 8316 (set_attr "type" "vecsimple")]) 8317 8318(define_insn "*ieee_128bit_vsx_neg<mode>2_internal" 8319 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8320 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8321 (use (match_operand:V16QI 2 "register_operand" "v"))] 8322 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8323 "xxlxor %x0,%x1,%x2" 8324 [(set_attr "type" "veclogical")]) 8325 8326;; IEEE 128-bit absolute value 8327(define_insn_and_split "@ieee_128bit_vsx_abs<mode>2" 8328 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8329 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8330 (clobber (match_scratch:V16QI 2 "=v"))] 8331 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 8332 "#" 8333 "&& 1" 8334 [(parallel [(set (match_dup 0) 8335 (abs:IEEE128 (match_dup 1))) 8336 (use (match_dup 2))])] 8337{ 8338 if (GET_CODE (operands[2]) == SCRATCH) 8339 operands[2] = gen_reg_rtx (V16QImode); 8340 8341 operands[3] = gen_reg_rtx (V16QImode); 8342 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8343} 8344 [(set_attr "length" "8") 8345 (set_attr "type" "vecsimple")]) 8346 8347(define_insn "*ieee_128bit_vsx_abs<mode>2_internal" 8348 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8349 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8350 (use (match_operand:V16QI 2 "register_operand" "v"))] 8351 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8352 "xxlandc %x0,%x1,%x2" 8353 [(set_attr "type" "veclogical")]) 8354 8355;; IEEE 128-bit negative absolute value 8356(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2" 8357 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8358 (neg:IEEE128 8359 (abs:IEEE128 8360 (match_operand:IEEE128 1 "register_operand" "wa")))) 8361 (clobber (match_scratch:V16QI 2 "=v"))] 8362 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW 8363 && FLOAT128_IEEE_P (<MODE>mode)" 8364 "#" 8365 "&& 1" 8366 [(parallel [(set (match_dup 0) 8367 (neg:IEEE128 (abs:IEEE128 (match_dup 1)))) 8368 (use (match_dup 2))])] 8369{ 8370 if (GET_CODE (operands[2]) == SCRATCH) 8371 operands[2] = gen_reg_rtx (V16QImode); 8372 8373 operands[3] = gen_reg_rtx (V16QImode); 8374 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8375} 8376 [(set_attr "length" "8") 8377 (set_attr "type" "vecsimple")]) 8378 8379(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal" 8380 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8381 (neg:IEEE128 8382 (abs:IEEE128 8383 (match_operand:IEEE128 1 "register_operand" "wa")))) 8384 (use (match_operand:V16QI 2 "register_operand" "v"))] 8385 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8386 "xxlor %x0,%x1,%x2" 8387 [(set_attr "type" "veclogical")]) 8388 8389;; Float128 conversion functions. These expand to library function calls. 8390;; We use expand to convert from IBM double double to IEEE 128-bit 8391;; and trunc for the opposite. 8392(define_expand "extendiftf2" 8393 [(set (match_operand:TF 0 "gpc_reg_operand") 8394 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))] 8395 "TARGET_FLOAT128_TYPE" 8396{ 8397 rs6000_expand_float128_convert (operands[0], operands[1], false); 8398 DONE; 8399}) 8400 8401(define_expand "extendifkf2" 8402 [(set (match_operand:KF 0 "gpc_reg_operand") 8403 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))] 8404 "TARGET_FLOAT128_TYPE" 8405{ 8406 rs6000_expand_float128_convert (operands[0], operands[1], false); 8407 DONE; 8408}) 8409 8410(define_expand "extendtfkf2" 8411 [(set (match_operand:KF 0 "gpc_reg_operand") 8412 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))] 8413 "TARGET_FLOAT128_TYPE" 8414{ 8415 rs6000_expand_float128_convert (operands[0], operands[1], false); 8416 DONE; 8417}) 8418 8419(define_expand "extendtfif2" 8420 [(set (match_operand:IF 0 "gpc_reg_operand") 8421 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))] 8422 "TARGET_FLOAT128_TYPE" 8423{ 8424 rs6000_expand_float128_convert (operands[0], operands[1], false); 8425 DONE; 8426}) 8427 8428(define_expand "trunciftf2" 8429 [(set (match_operand:TF 0 "gpc_reg_operand") 8430 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))] 8431 "TARGET_FLOAT128_TYPE" 8432{ 8433 rs6000_expand_float128_convert (operands[0], operands[1], false); 8434 DONE; 8435}) 8436 8437(define_expand "truncifkf2" 8438 [(set (match_operand:KF 0 "gpc_reg_operand") 8439 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))] 8440 "TARGET_FLOAT128_TYPE" 8441{ 8442 rs6000_expand_float128_convert (operands[0], operands[1], false); 8443 DONE; 8444}) 8445 8446(define_expand "trunckftf2" 8447 [(set (match_operand:TF 0 "gpc_reg_operand") 8448 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))] 8449 "TARGET_FLOAT128_TYPE" 8450{ 8451 rs6000_expand_float128_convert (operands[0], operands[1], false); 8452 DONE; 8453}) 8454 8455(define_expand "trunctfif2" 8456 [(set (match_operand:IF 0 "gpc_reg_operand") 8457 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))] 8458 "TARGET_FLOAT128_TYPE" 8459{ 8460 rs6000_expand_float128_convert (operands[0], operands[1], false); 8461 DONE; 8462}) 8463 8464(define_insn_and_split "*extend<mode>tf2_internal" 8465 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>") 8466 (float_extend:TF 8467 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))] 8468 "TARGET_FLOAT128_TYPE 8469 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)" 8470 "#" 8471 "&& reload_completed" 8472 [(set (match_dup 0) (match_dup 2))] 8473{ 8474 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1])); 8475}) 8476 8477(define_insn_and_split "*extendtf<mode>2_internal" 8478 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>") 8479 (float_extend:IFKF 8480 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))] 8481 "TARGET_FLOAT128_TYPE 8482 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)" 8483 "#" 8484 "&& reload_completed" 8485 [(set (match_dup 0) (match_dup 2))] 8486{ 8487 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1])); 8488}) 8489 8490 8491;; Reload helper functions used by rs6000_secondary_reload. The patterns all 8492;; must have 3 arguments, and scratch register constraint must be a single 8493;; constraint. 8494 8495;; Reload patterns to support gpr load/store with misaligned mem. 8496;; and multiple gpr load/store at offset >= 0xfffc 8497(define_expand "reload_<mode>_store" 8498 [(parallel [(match_operand 0 "memory_operand" "=m") 8499 (match_operand 1 "gpc_reg_operand" "r") 8500 (match_operand:GPR 2 "register_operand" "=&b")])] 8501 "" 8502{ 8503 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true); 8504 DONE; 8505}) 8506 8507(define_expand "reload_<mode>_load" 8508 [(parallel [(match_operand 0 "gpc_reg_operand" "=r") 8509 (match_operand 1 "memory_operand" "m") 8510 (match_operand:GPR 2 "register_operand" "=b")])] 8511 "" 8512{ 8513 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false); 8514 DONE; 8515}) 8516 8517 8518;; Reload patterns for various types using the vector registers. We may need 8519;; an additional base register to convert the reg+offset addressing to reg+reg 8520;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an 8521;; index register for gpr registers. 8522(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store" 8523 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m") 8524 (match_operand:RELOAD 1 "gpc_reg_operand" "wa") 8525 (match_operand:P 2 "register_operand" "=b")])] 8526 "<P:tptrsize>" 8527{ 8528 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true); 8529 DONE; 8530}) 8531 8532(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load" 8533 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa") 8534 (match_operand:RELOAD 1 "memory_operand" "m") 8535 (match_operand:P 2 "register_operand" "=b")])] 8536 "<P:tptrsize>" 8537{ 8538 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false); 8539 DONE; 8540}) 8541 8542 8543;; Reload sometimes tries to move the address to a GPR, and can generate 8544;; invalid RTL for addresses involving AND -16. Allow addresses involving 8545;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16. 8546 8547(define_insn_and_split "*vec_reload_and_plus_<mptrsize>" 8548 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 8549 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 8550 (match_operand:P 2 "reg_or_cint_operand" "rI")) 8551 (const_int -16)))] 8552 "TARGET_ALTIVEC && reload_completed" 8553 "#" 8554 "&& reload_completed" 8555 [(set (match_dup 0) 8556 (plus:P (match_dup 1) 8557 (match_dup 2))) 8558 (set (match_dup 0) 8559 (and:P (match_dup 0) 8560 (const_int -16)))]) 8561 8562;; Power8 merge instructions to allow direct move to/from floating point 8563;; registers in 32-bit mode. We use TF mode to get two registers to move the 8564;; individual 32-bit parts across. Subreg doesn't work too well on the TF 8565;; value, since it is allocated in reload and not all of the flow information 8566;; is setup for it. We have two patterns to do the two moves between gprs and 8567;; fprs. There isn't a dependancy between the two, but we could potentially 8568;; schedule other instructions between the two instructions. 8569 8570(define_insn "p8_fmrgow_<mode>" 8571 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 8572 (unspec:FMOVE64X [ 8573 (match_operand:DF 1 "register_operand" "d") 8574 (match_operand:DF 2 "register_operand" "d")] 8575 UNSPEC_P8V_FMRGOW))] 8576 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8577 "fmrgow %0,%1,%2" 8578 [(set_attr "type" "fpsimple")]) 8579 8580(define_insn "p8_mtvsrwz" 8581 [(set (match_operand:DF 0 "register_operand" "=d") 8582 (unspec:DF [(match_operand:SI 1 "register_operand" "r")] 8583 UNSPEC_P8V_MTVSRWZ))] 8584 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8585 "mtvsrwz %x0,%1" 8586 [(set_attr "type" "mftgpr")]) 8587 8588(define_insn_and_split "reload_fpr_from_gpr<mode>" 8589 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 8590 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")] 8591 UNSPEC_P8V_RELOAD_FROM_GPR)) 8592 (clobber (match_operand:IF 2 "register_operand" "=d"))] 8593 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8594 "#" 8595 "&& reload_completed" 8596 [(const_int 0)] 8597{ 8598 rtx dest = operands[0]; 8599 rtx src = operands[1]; 8600 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 8601 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 8602 rtx gpr_hi_reg = gen_highpart (SImode, src); 8603 rtx gpr_lo_reg = gen_lowpart (SImode, src); 8604 8605 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg)); 8606 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg)); 8607 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo)); 8608 DONE; 8609} 8610 [(set_attr "length" "12") 8611 (set_attr "type" "three")]) 8612 8613;; Move 128 bit values from GPRs to VSX registers in 64-bit mode 8614(define_insn "p8_mtvsrd_df" 8615 [(set (match_operand:DF 0 "register_operand" "=wa") 8616 (unspec:DF [(match_operand:DI 1 "register_operand" "r")] 8617 UNSPEC_P8V_MTVSRD))] 8618 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8619 "mtvsrd %x0,%1" 8620 [(set_attr "type" "mftgpr")]) 8621 8622(define_insn "p8_xxpermdi_<mode>" 8623 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 8624 (unspec:FMOVE128_GPR [ 8625 (match_operand:DF 1 "register_operand" "wa") 8626 (match_operand:DF 2 "register_operand" "wa")] 8627 UNSPEC_P8V_XXPERMDI))] 8628 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8629 "xxpermdi %x0,%x1,%x2,0" 8630 [(set_attr "type" "vecperm")]) 8631 8632(define_insn_and_split "reload_vsx_from_gpr<mode>" 8633 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 8634 (unspec:FMOVE128_GPR 8635 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")] 8636 UNSPEC_P8V_RELOAD_FROM_GPR)) 8637 (clobber (match_operand:IF 2 "register_operand" "=wa"))] 8638 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8639 "#" 8640 "&& reload_completed" 8641 [(const_int 0)] 8642{ 8643 rtx dest = operands[0]; 8644 rtx src = operands[1]; 8645 /* You might think that we could use op0 as one temp and a DF clobber 8646 as op2, but you'd be wrong. Secondary reload move patterns don't 8647 check for overlap of the clobber and the destination. */ 8648 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 8649 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 8650 rtx gpr_hi_reg = gen_highpart (DImode, src); 8651 rtx gpr_lo_reg = gen_lowpart (DImode, src); 8652 8653 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg)); 8654 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg)); 8655 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo)); 8656 DONE; 8657} 8658 [(set_attr "length" "12") 8659 (set_attr "type" "three")]) 8660 8661(define_split 8662 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand") 8663 (match_operand:FMOVE128_GPR 1 "input_operand"))] 8664 "reload_completed 8665 && (int_reg_operand (operands[0], <MODE>mode) 8666 || int_reg_operand (operands[1], <MODE>mode)) 8667 && (!TARGET_DIRECT_MOVE_128 8668 || (!vsx_register_operand (operands[0], <MODE>mode) 8669 && !vsx_register_operand (operands[1], <MODE>mode)))" 8670 [(pc)] 8671{ 8672 rs6000_split_multireg_move (operands[0], operands[1]); 8673 DONE; 8674}) 8675 8676;; Move SFmode to a VSX from a GPR register. Because scalar floating point 8677;; type is stored internally as double precision in the VSX registers, we have 8678;; to convert it from the vector format. 8679(define_insn "p8_mtvsrd_sf" 8680 [(set (match_operand:SF 0 "register_operand" "=wa") 8681 (unspec:SF [(match_operand:DI 1 "register_operand" "r")] 8682 UNSPEC_P8V_MTVSRD))] 8683 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8684 "mtvsrd %x0,%1" 8685 [(set_attr "type" "mftgpr")]) 8686 8687(define_insn_and_split "reload_vsx_from_gprsf" 8688 [(set (match_operand:SF 0 "register_operand" "=wa") 8689 (unspec:SF [(match_operand:SF 1 "register_operand" "r")] 8690 UNSPEC_P8V_RELOAD_FROM_GPR)) 8691 (clobber (match_operand:DI 2 "register_operand" "=r"))] 8692 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8693 "#" 8694 "&& reload_completed" 8695 [(const_int 0)] 8696{ 8697 rtx op0 = operands[0]; 8698 rtx op1 = operands[1]; 8699 rtx op2 = operands[2]; 8700 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0); 8701 8702 /* Move SF value to upper 32-bits for xscvspdpn. */ 8703 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 8704 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 8705 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 8706 DONE; 8707} 8708 [(set_attr "length" "8") 8709 (set_attr "type" "two")]) 8710 8711;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a 8712;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value, 8713;; and then doing a move of that. 8714(define_insn "p8_mfvsrd_3_<mode>" 8715 [(set (match_operand:DF 0 "register_operand" "=r") 8716 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 8717 UNSPEC_P8V_RELOAD_FROM_VSX))] 8718 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8719 "mfvsrd %0,%x1" 8720 [(set_attr "type" "mftgpr")]) 8721 8722(define_insn_and_split "reload_gpr_from_vsx<mode>" 8723 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r") 8724 (unspec:FMOVE128_GPR 8725 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 8726 UNSPEC_P8V_RELOAD_FROM_VSX)) 8727 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))] 8728 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8729 "#" 8730 "&& reload_completed" 8731 [(const_int 0)] 8732{ 8733 rtx dest = operands[0]; 8734 rtx src = operands[1]; 8735 rtx tmp = operands[2]; 8736 rtx gpr_hi_reg = gen_highpart (DFmode, dest); 8737 rtx gpr_lo_reg = gen_lowpart (DFmode, dest); 8738 8739 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src)); 8740 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3))); 8741 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp)); 8742 DONE; 8743} 8744 [(set_attr "length" "12") 8745 (set_attr "type" "three")]) 8746 8747;; Move SFmode to a GPR from a VSX register. Because scalar floating point 8748;; type is stored internally as double precision, we have to convert it to the 8749;; vector format. 8750 8751(define_insn_and_split "reload_gpr_from_vsxsf" 8752 [(set (match_operand:SF 0 "register_operand" "=r") 8753 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")] 8754 UNSPEC_P8V_RELOAD_FROM_VSX)) 8755 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))] 8756 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8757 "#" 8758 "&& reload_completed" 8759 [(const_int 0)] 8760{ 8761 rtx op0 = operands[0]; 8762 rtx op1 = operands[1]; 8763 rtx op2 = operands[2]; 8764 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0)); 8765 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 8766 8767 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 8768 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si)); 8769 DONE; 8770} 8771 [(set_attr "length" "8") 8772 (set_attr "type" "two") 8773 (set_attr "isa" "p8v")]) 8774 8775;; Next come the multi-word integer load and store and the load and store 8776;; multiple insns. 8777 8778;; List r->r after r->Y, otherwise reload will try to reload a 8779;; non-offsettable address by using r->r which won't make progress. 8780;; Use of fprs is disparaged slightly otherwise reload prefers to reload 8781;; a gpr into a fpr instead of reloading an invalid 'Y' address 8782 8783;; GPR store GPR load GPR move FPR store FPR load FPR move 8784;; GPR const AVX store AVX store AVX load AVX load VSX move 8785;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const 8786;; AVX const 8787 8788(define_insn "*movdi_internal32" 8789 [(set (match_operand:DI 0 "nonimmediate_operand" 8790 "=Y, r, r, m, ^d, ^d, 8791 r, wY, Z, ^v, $v, ^wa, 8792 wa, wa, v, wa, *i, v, 8793 v") 8794 (match_operand:DI 1 "input_operand" 8795 "r, Y, r, ^d, m, ^d, 8796 IJKnF, ^v, $v, wY, Z, ^wa, 8797 Oj, wM, OjwM, Oj, wM, wS, 8798 wB"))] 8799 "! TARGET_POWERPC64 8800 && (gpc_reg_operand (operands[0], DImode) 8801 || gpc_reg_operand (operands[1], DImode))" 8802 "@ 8803 # 8804 # 8805 # 8806 stfd%U0%X0 %1,%0 8807 lfd%U1%X1 %0,%1 8808 fmr %0,%1 8809 # 8810 stxsd %1,%0 8811 stxsdx %x1,%y0 8812 lxsd %0,%1 8813 lxsdx %x0,%y1 8814 xxlor %x0,%x1,%x1 8815 xxspltib %x0,0 8816 xxspltib %x0,255 8817 vspltisw %0,%1 8818 xxlxor %x0,%x0,%x0 8819 xxlorc %x0,%x0,%x0 8820 # 8821 #" 8822 [(set_attr "type" 8823 "store, load, *, fpstore, fpload, fpsimple, 8824 *, fpstore, fpstore, fpload, fpload, veclogical, 8825 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple, 8826 vecsimple") 8827 (set_attr "size" "64") 8828 (set_attr "length" 8829 "8, 8, 8, *, *, *, 8830 16, *, *, *, *, *, 8831 *, *, *, *, *, 8, 8832 *") 8833 (set_attr "isa" 8834 "*, *, *, *, *, *, 8835 *, p9v, p7v, p9v, p7v, *, 8836 p9v, p9v, p7v, *, *, p7v, 8837 p7v")]) 8838 8839(define_split 8840 [(set (match_operand:DI 0 "gpc_reg_operand") 8841 (match_operand:DI 1 "const_int_operand"))] 8842 "! TARGET_POWERPC64 && reload_completed 8843 && gpr_or_gpr_p (operands[0], operands[1]) 8844 && !direct_move_p (operands[0], operands[1])" 8845 [(set (match_dup 2) (match_dup 4)) 8846 (set (match_dup 3) (match_dup 1))] 8847{ 8848 HOST_WIDE_INT value = INTVAL (operands[1]); 8849 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 8850 DImode); 8851 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 8852 DImode); 8853 operands[4] = GEN_INT (value >> 32); 8854 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 8855}) 8856 8857(define_split 8858 [(set (match_operand:DIFD 0 "nonimmediate_operand") 8859 (match_operand:DIFD 1 "input_operand"))] 8860 "reload_completed && !TARGET_POWERPC64 8861 && gpr_or_gpr_p (operands[0], operands[1]) 8862 && !direct_move_p (operands[0], operands[1])" 8863 [(pc)] 8864{ 8865 rs6000_split_multireg_move (operands[0], operands[1]); 8866 DONE; 8867}) 8868 8869;; GPR store GPR load GPR move 8870;; GPR li GPR lis GPR pli GPR # 8871;; FPR store FPR load FPR move 8872;; AVX store AVX store AVX load AVX load VSX move 8873;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 8874;; P9 const AVX const 8875;; From SPR To SPR SPR<->SPR 8876;; VSX->GPR GPR->VSX 8877(define_insn "*movdi_internal64" 8878 [(set (match_operand:DI 0 "nonimmediate_operand" 8879 "=YZ, r, r, 8880 r, r, r, r, 8881 m, ^d, ^d, 8882 wY, Z, $v, $v, ^wa, 8883 wa, wa, v, wa, wa, 8884 v, v, 8885 r, *h, *h, 8886 ?r, ?wa") 8887 (match_operand:DI 1 "input_operand" 8888 "r, YZ, r, 8889 I, L, eI, nF, 8890 ^d, m, ^d, 8891 ^v, $v, wY, Z, ^wa, 8892 Oj, wM, OjwM, Oj, wM, 8893 wS, wB, 8894 *h, r, 0, 8895 wa, r"))] 8896 "TARGET_POWERPC64 8897 && (gpc_reg_operand (operands[0], DImode) 8898 || gpc_reg_operand (operands[1], DImode))" 8899 "@ 8900 std%U0%X0 %1,%0 8901 ld%U1%X1 %0,%1 8902 mr %0,%1 8903 li %0,%1 8904 lis %0,%v1 8905 li %0,%1 8906 # 8907 stfd%U0%X0 %1,%0 8908 lfd%U1%X1 %0,%1 8909 fmr %0,%1 8910 stxsd %1,%0 8911 stxsdx %x1,%y0 8912 lxsd %0,%1 8913 lxsdx %x0,%y1 8914 xxlor %x0,%x1,%x1 8915 xxspltib %x0,0 8916 xxspltib %x0,255 8917 # 8918 xxlxor %x0,%x0,%x0 8919 xxlorc %x0,%x0,%x0 8920 # 8921 # 8922 mf%1 %0 8923 mt%0 %1 8924 nop 8925 mfvsrd %0,%x1 8926 mtvsrd %x0,%1" 8927 [(set_attr "type" 8928 "store, load, *, 8929 *, *, *, *, 8930 fpstore, fpload, fpsimple, 8931 fpstore, fpstore, fpload, fpload, veclogical, 8932 vecsimple, vecsimple, vecsimple, veclogical, veclogical, 8933 vecsimple, vecsimple, 8934 mfjmpr, mtjmpr, *, 8935 mftgpr, mffgpr") 8936 (set_attr "size" "64") 8937 (set_attr "length" 8938 "*, *, *, 8939 *, *, *, 20, 8940 *, *, *, 8941 *, *, *, *, *, 8942 *, *, *, *, *, 8943 8, *, 8944 *, *, *, 8945 *, *") 8946 (set_attr "isa" 8947 "*, *, *, 8948 *, *, p10, *, 8949 *, *, *, 8950 p9v, p7v, p9v, p7v, *, 8951 p9v, p9v, p7v, *, *, 8952 p7v, p7v, 8953 *, *, *, 8954 p8v, p8v")]) 8955 8956; Some DImode loads are best done as a load of -1 followed by a mask 8957; instruction. 8958(define_split 8959 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 8960 (match_operand:DI 1 "const_int_operand"))] 8961 "TARGET_POWERPC64 8962 && num_insns_constant (operands[1], DImode) > 1 8963 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff) 8964 && rs6000_is_valid_and_mask (operands[1], DImode)" 8965 [(set (match_dup 0) 8966 (const_int -1)) 8967 (set (match_dup 0) 8968 (and:DI (match_dup 0) 8969 (match_dup 1)))] 8970 "") 8971 8972;; Split a load of a large constant into the appropriate five-instruction 8973;; sequence. Handle anything in a constant number of insns. 8974;; When non-easy constants can go in the TOC, this should use 8975;; easy_fp_constant predicate. 8976(define_split 8977 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 8978 (match_operand:DI 1 "const_int_operand"))] 8979 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 8980 [(set (match_dup 0) (match_dup 2)) 8981 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 8982{ 8983 if (rs6000_emit_set_const (operands[0], operands[1])) 8984 DONE; 8985 else 8986 FAIL; 8987}) 8988 8989(define_split 8990 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 8991 (match_operand:DI 1 "const_scalar_int_operand"))] 8992 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 8993 [(set (match_dup 0) (match_dup 2)) 8994 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 8995{ 8996 if (rs6000_emit_set_const (operands[0], operands[1])) 8997 DONE; 8998 else 8999 FAIL; 9000}) 9001 9002(define_split 9003 [(set (match_operand:DI 0 "altivec_register_operand") 9004 (match_operand:DI 1 "s5bit_cint_operand"))] 9005 "TARGET_VSX && reload_completed" 9006 [(const_int 0)] 9007{ 9008 rtx op0 = operands[0]; 9009 rtx op1 = operands[1]; 9010 int r = REGNO (op0); 9011 rtx op0_v4si = gen_rtx_REG (V4SImode, r); 9012 9013 emit_insn (gen_altivec_vspltisw (op0_v4si, op1)); 9014 if (op1 != const0_rtx && op1 != constm1_rtx) 9015 { 9016 rtx op0_v2di = gen_rtx_REG (V2DImode, r); 9017 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si)); 9018 } 9019 DONE; 9020}) 9021 9022;; Split integer constants that can be loaded with XXSPLTIB and a 9023;; sign extend operation. 9024(define_split 9025 [(set (match_operand:INT_ISA3 0 "altivec_register_operand") 9026 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))] 9027 "TARGET_P9_VECTOR && reload_completed" 9028 [(const_int 0)] 9029{ 9030 rtx op0 = operands[0]; 9031 rtx op1 = operands[1]; 9032 int r = REGNO (op0); 9033 rtx op0_v16qi = gen_rtx_REG (V16QImode, r); 9034 9035 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1)); 9036 if (<MODE>mode == DImode) 9037 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi)); 9038 else if (<MODE>mode == SImode) 9039 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi)); 9040 else if (<MODE>mode == HImode) 9041 { 9042 rtx op0_v8hi = gen_rtx_REG (V8HImode, r); 9043 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi)); 9044 } 9045 DONE; 9046}) 9047 9048 9049;; TImode/PTImode is similar, except that we usually want to compute the 9050;; address into a register and use lsi/stsi (the exception is during reload). 9051 9052(define_insn "*mov<mode>_string" 9053 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r") 9054 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))] 9055 "! TARGET_POWERPC64 9056 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode)) 9057 && (gpc_reg_operand (operands[0], <MODE>mode) 9058 || gpc_reg_operand (operands[1], <MODE>mode))" 9059 "#" 9060 [(set_attr "type" "store,store,load,load,*,*") 9061 (set_attr "update" "yes") 9062 (set_attr "indexed" "yes") 9063 (set_attr "cell_micro" "conditional")]) 9064 9065(define_insn "*mov<mode>_ppc64" 9066 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r") 9067 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))] 9068 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode) 9069 && (gpc_reg_operand (operands[0], <MODE>mode) 9070 || gpc_reg_operand (operands[1], <MODE>mode)))" 9071{ 9072 return rs6000_output_move_128bit (operands); 9073} 9074 [(set_attr "type" "store,store,load,load,*,*") 9075 (set_attr "length" "8") 9076 (set_attr "max_prefixed_insns" "2")]) 9077 9078(define_split 9079 [(set (match_operand:TI2 0 "int_reg_operand") 9080 (match_operand:TI2 1 "const_scalar_int_operand"))] 9081 "TARGET_POWERPC64 9082 && (VECTOR_MEM_NONE_P (<MODE>mode) 9083 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))" 9084 [(set (match_dup 2) (match_dup 4)) 9085 (set (match_dup 3) (match_dup 5))] 9086{ 9087 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 9088 <MODE>mode); 9089 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 9090 <MODE>mode); 9091 if (CONST_WIDE_INT_P (operands[1])) 9092 { 9093 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1)); 9094 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0)); 9095 } 9096 else if (CONST_INT_P (operands[1])) 9097 { 9098 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); 9099 operands[5] = operands[1]; 9100 } 9101 else 9102 FAIL; 9103}) 9104 9105(define_split 9106 [(set (match_operand:TI2 0 "nonimmediate_operand") 9107 (match_operand:TI2 1 "input_operand"))] 9108 "reload_completed 9109 && gpr_or_gpr_p (operands[0], operands[1]) 9110 && !direct_move_p (operands[0], operands[1]) 9111 && !quad_load_store_p (operands[0], operands[1])" 9112 [(pc)] 9113{ 9114 rs6000_split_multireg_move (operands[0], operands[1]); 9115 DONE; 9116}) 9117 9118(define_expand "setmemsi" 9119 [(parallel [(set (match_operand:BLK 0 "") 9120 (match_operand 2 "const_int_operand")) 9121 (use (match_operand:SI 1 "")) 9122 (use (match_operand:SI 3 ""))])] 9123 "" 9124{ 9125 /* If value to set is not zero, use the library routine. */ 9126 if (operands[2] != const0_rtx) 9127 FAIL; 9128 9129 if (expand_block_clear (operands)) 9130 DONE; 9131 else 9132 FAIL; 9133}) 9134 9135;; String compare N insn. 9136;; Argument 0 is the target (result) 9137;; Argument 1 is the destination 9138;; Argument 2 is the source 9139;; Argument 3 is the length 9140;; Argument 4 is the alignment 9141 9142(define_expand "cmpstrnsi" 9143 [(parallel [(set (match_operand:SI 0) 9144 (compare:SI (match_operand:BLK 1) 9145 (match_operand:BLK 2))) 9146 (use (match_operand:SI 3)) 9147 (use (match_operand:SI 4))])] 9148 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)" 9149{ 9150 if (optimize_insn_for_size_p ()) 9151 FAIL; 9152 9153 if (expand_strn_compare (operands, 0)) 9154 DONE; 9155 else 9156 FAIL; 9157}) 9158 9159;; String compare insn. 9160;; Argument 0 is the target (result) 9161;; Argument 1 is the destination 9162;; Argument 2 is the source 9163;; Argument 3 is the alignment 9164 9165(define_expand "cmpstrsi" 9166 [(parallel [(set (match_operand:SI 0) 9167 (compare:SI (match_operand:BLK 1) 9168 (match_operand:BLK 2))) 9169 (use (match_operand:SI 3))])] 9170 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)" 9171{ 9172 if (optimize_insn_for_size_p ()) 9173 FAIL; 9174 9175 if (expand_strn_compare (operands, 1)) 9176 DONE; 9177 else 9178 FAIL; 9179}) 9180 9181;; Block compare insn. 9182;; Argument 0 is the target (result) 9183;; Argument 1 is the destination 9184;; Argument 2 is the source 9185;; Argument 3 is the length 9186;; Argument 4 is the alignment 9187 9188(define_expand "cmpmemsi" 9189 [(parallel [(set (match_operand:SI 0) 9190 (compare:SI (match_operand:BLK 1) 9191 (match_operand:BLK 2))) 9192 (use (match_operand:SI 3)) 9193 (use (match_operand:SI 4))])] 9194 "TARGET_POPCNTD" 9195{ 9196 if (expand_block_compare (operands)) 9197 DONE; 9198 else 9199 FAIL; 9200}) 9201 9202;; String/block copy insn (source and destination must not overlap). 9203;; Argument 0 is the destination 9204;; Argument 1 is the source 9205;; Argument 2 is the length 9206;; Argument 3 is the alignment 9207 9208(define_expand "cpymemsi" 9209 [(parallel [(set (match_operand:BLK 0 "") 9210 (match_operand:BLK 1 "")) 9211 (use (match_operand:SI 2 "")) 9212 (use (match_operand:SI 3 ""))])] 9213 "" 9214{ 9215 if (expand_block_move (operands, false)) 9216 DONE; 9217 else 9218 FAIL; 9219}) 9220 9221;; String/block move insn (source and destination may overlap). 9222;; Argument 0 is the destination 9223;; Argument 1 is the source 9224;; Argument 2 is the length 9225;; Argument 3 is the alignment 9226 9227(define_expand "movmemsi" 9228 [(parallel [(set (match_operand:BLK 0 "") 9229 (match_operand:BLK 1 "")) 9230 (use (match_operand:SI 2 "")) 9231 (use (match_operand:SI 3 ""))])] 9232 "" 9233{ 9234 if (expand_block_move (operands, true)) 9235 DONE; 9236 else 9237 FAIL; 9238}) 9239 9240 9241;; Define insns that do load or store with update. Some of these we can 9242;; get by using pre-decrement or pre-increment, but the hardware can also 9243;; do cases where the increment is not the size of the object. 9244;; 9245;; In all these cases, we use operands 0 and 1 for the register being 9246;; incremented because those are the operands that local-alloc will 9247;; tie and these are the pair most likely to be tieable (and the ones 9248;; that will benefit the most). 9249 9250(define_insn "*movdi_update1" 9251 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r") 9252 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9253 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))) 9254 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9255 (plus:P (match_dup 1) (match_dup 2)))] 9256 "TARGET_POWERPC64 && TARGET_UPDATE 9257 && (!avoiding_indexed_address_p (DImode) 9258 || !gpc_reg_operand (operands[2], Pmode))" 9259 "@ 9260 ldux %3,%0,%2 9261 ldu %3,%2(%0)" 9262 [(set_attr "type" "load") 9263 (set_attr "update" "yes") 9264 (set_attr "indexed" "yes,no")]) 9265 9266(define_insn "movdi_<mode>_update" 9267 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9268 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) 9269 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 9270 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9271 (plus:P (match_dup 1) (match_dup 2)))] 9272 "TARGET_POWERPC64 && TARGET_UPDATE 9273 && (!avoiding_indexed_address_p (DImode) 9274 || !gpc_reg_operand (operands[2], Pmode) 9275 || (REG_P (operands[0]) 9276 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 9277 "@ 9278 stdux %3,%0,%2 9279 stdu %3,%2(%0)" 9280 [(set_attr "type" "store") 9281 (set_attr "update" "yes") 9282 (set_attr "indexed" "yes,no")]) 9283 9284;; This pattern is only conditional on TARGET_64BIT, as it is 9285;; needed for stack allocation, even if the user passes -mno-update. 9286(define_insn "movdi_update_stack" 9287 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") 9288 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))) 9289 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 9290 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") 9291 (plus:DI (match_dup 1) (match_dup 2)))] 9292 "TARGET_64BIT" 9293 "@ 9294 stdux %3,%0,%2 9295 stdu %3,%2(%0)" 9296 [(set_attr "type" "store") 9297 (set_attr "update" "yes") 9298 (set_attr "indexed" "yes,no")]) 9299 9300(define_insn "*movsi_update1" 9301 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 9302 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9303 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 9304 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9305 (plus:P (match_dup 1) (match_dup 2)))] 9306 "TARGET_UPDATE 9307 && (!avoiding_indexed_address_p (SImode) 9308 || !gpc_reg_operand (operands[2], Pmode))" 9309 "@ 9310 lwzux %3,%0,%2 9311 lwzu %3,%2(%0)" 9312 [(set_attr "type" "load") 9313 (set_attr "update" "yes") 9314 (set_attr "indexed" "yes,no")]) 9315 9316(define_insn "*movsi_update2" 9317 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r") 9318 (sign_extend:EXTSI 9319 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0") 9320 (match_operand:P 2 "gpc_reg_operand" "r"))))) 9321 (set (match_operand:P 0 "gpc_reg_operand" "=b") 9322 (plus:P (match_dup 1) (match_dup 2)))] 9323 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)" 9324 "lwaux %3,%0,%2" 9325 [(set_attr "type" "load") 9326 (set_attr "sign_extend" "yes") 9327 (set_attr "update" "yes") 9328 (set_attr "indexed" "yes")]) 9329 9330(define_insn "movsi_<mode>_update" 9331 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9332 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 9333 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 9334 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9335 (plus:P (match_dup 1) (match_dup 2)))] 9336 "TARGET_UPDATE 9337 && (!avoiding_indexed_address_p (SImode) 9338 || !gpc_reg_operand (operands[2], Pmode) 9339 || (REG_P (operands[0]) 9340 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 9341 "@ 9342 stwux %3,%0,%2 9343 stwu %3,%2(%0)" 9344 [(set_attr "type" "store") 9345 (set_attr "update" "yes") 9346 (set_attr "indexed" "yes,no")]) 9347 9348;; This is an unconditional pattern; needed for stack allocation, even 9349;; if the user passes -mno-update. 9350(define_insn "movsi_update_stack" 9351 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9352 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9353 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 9354 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9355 (plus:SI (match_dup 1) (match_dup 2)))] 9356 "TARGET_32BIT" 9357 "@ 9358 stwux %3,%0,%2 9359 stwu %3,%2(%0)" 9360 [(set_attr "type" "store") 9361 (set_attr "update" "yes") 9362 (set_attr "indexed" "yes,no")]) 9363 9364(define_insn "*movhi_update1" 9365 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r") 9366 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9367 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 9368 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9369 (plus:P (match_dup 1) (match_dup 2)))] 9370 "TARGET_UPDATE 9371 && (!avoiding_indexed_address_p (HImode) 9372 || !gpc_reg_operand (operands[2], SImode))" 9373 "@ 9374 lhzux %3,%0,%2 9375 lhzu %3,%2(%0)" 9376 [(set_attr "type" "load") 9377 (set_attr "update" "yes") 9378 (set_attr "indexed" "yes,no")]) 9379 9380(define_insn "*movhi_update2" 9381 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r") 9382 (zero_extend:EXTHI 9383 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9384 (match_operand:P 2 "reg_or_short_operand" "r,I"))))) 9385 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9386 (plus:P (match_dup 1) (match_dup 2)))] 9387 "TARGET_UPDATE 9388 && (!avoiding_indexed_address_p (HImode) 9389 || !gpc_reg_operand (operands[2], Pmode))" 9390 "@ 9391 lhzux %3,%0,%2 9392 lhzu %3,%2(%0)" 9393 [(set_attr "type" "load") 9394 (set_attr "update" "yes") 9395 (set_attr "indexed" "yes,no")]) 9396 9397(define_insn "*movhi_update3" 9398 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r") 9399 (sign_extend:EXTHI 9400 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9401 (match_operand:P 2 "reg_or_short_operand" "r,I"))))) 9402 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9403 (plus:P (match_dup 1) (match_dup 2)))] 9404 "TARGET_UPDATE 9405 && !(avoiding_indexed_address_p (HImode) 9406 && gpc_reg_operand (operands[2], Pmode))" 9407 "@ 9408 lhaux %3,%0,%2 9409 lhau %3,%2(%0)" 9410 [(set_attr "type" "load") 9411 (set_attr "sign_extend" "yes") 9412 (set_attr "update" "yes") 9413 (set_attr "indexed" "yes,no")]) 9414 9415(define_insn "*movhi_update4" 9416 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9417 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 9418 (match_operand:HI 3 "gpc_reg_operand" "r,r")) 9419 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9420 (plus:P (match_dup 1) (match_dup 2)))] 9421 "TARGET_UPDATE 9422 && (!avoiding_indexed_address_p (HImode) 9423 || !gpc_reg_operand (operands[2], Pmode))" 9424 "@ 9425 sthux %3,%0,%2 9426 sthu %3,%2(%0)" 9427 [(set_attr "type" "store") 9428 (set_attr "update" "yes") 9429 (set_attr "indexed" "yes,no")]) 9430 9431(define_insn "*movqi_update1" 9432 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r") 9433 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9434 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 9435 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9436 (plus:P (match_dup 1) (match_dup 2)))] 9437 "TARGET_UPDATE 9438 && (!avoiding_indexed_address_p (QImode) 9439 || !gpc_reg_operand (operands[2], Pmode))" 9440 "@ 9441 lbzux %3,%0,%2 9442 lbzu %3,%2(%0)" 9443 [(set_attr "type" "load") 9444 (set_attr "update" "yes") 9445 (set_attr "indexed" "yes,no")]) 9446 9447(define_insn "*movqi_update2" 9448 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r") 9449 (zero_extend:EXTQI 9450 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9451 (match_operand:P 2 "reg_or_short_operand" "r,I"))))) 9452 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9453 (plus:P (match_dup 1) (match_dup 2)))] 9454 "TARGET_UPDATE 9455 && (!avoiding_indexed_address_p (QImode) 9456 || !gpc_reg_operand (operands[2], Pmode))" 9457 "@ 9458 lbzux %3,%0,%2 9459 lbzu %3,%2(%0)" 9460 [(set_attr "type" "load") 9461 (set_attr "update" "yes") 9462 (set_attr "indexed" "yes,no")]) 9463 9464(define_insn "*movqi_update3" 9465 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9466 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 9467 (match_operand:QI 3 "gpc_reg_operand" "r,r")) 9468 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9469 (plus:P (match_dup 1) (match_dup 2)))] 9470 "TARGET_UPDATE 9471 && (!avoiding_indexed_address_p (QImode) 9472 || !gpc_reg_operand (operands[2], Pmode))" 9473 "@ 9474 stbux %3,%0,%2 9475 stbu %3,%2(%0)" 9476 [(set_attr "type" "store") 9477 (set_attr "update" "yes") 9478 (set_attr "indexed" "yes,no")]) 9479 9480(define_insn "*mov<SFDF:mode>_update1" 9481 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>") 9482 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9483 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 9484 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9485 (plus:P (match_dup 1) (match_dup 2)))] 9486 "TARGET_HARD_FLOAT && TARGET_UPDATE 9487 && (!avoiding_indexed_address_p (<SFDF:MODE>mode) 9488 || !gpc_reg_operand (operands[2], Pmode))" 9489 "@ 9490 lf<sd>ux %3,%0,%2 9491 lf<sd>u %3,%2(%0)" 9492 [(set_attr "type" "fpload") 9493 (set_attr "update" "yes") 9494 (set_attr "indexed" "yes,no") 9495 (set_attr "size" "<SFDF:bits>")]) 9496 9497(define_insn "*mov<SFDF:mode>_update2" 9498 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9499 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 9500 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>")) 9501 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9502 (plus:P (match_dup 1) (match_dup 2)))] 9503 "TARGET_HARD_FLOAT && TARGET_UPDATE 9504 && (!avoiding_indexed_address_p (<SFDF:MODE>mode) 9505 || !gpc_reg_operand (operands[2], Pmode))" 9506 "@ 9507 stf<sd>ux %3,%0,%2 9508 stf<sd>u %3,%2(%0)" 9509 [(set_attr "type" "fpstore") 9510 (set_attr "update" "yes") 9511 (set_attr "indexed" "yes,no") 9512 (set_attr "size" "<SFDF:bits>")]) 9513 9514(define_insn "*movsf_update3" 9515 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r") 9516 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9517 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 9518 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9519 (plus:P (match_dup 1) (match_dup 2)))] 9520 "TARGET_SOFT_FLOAT && TARGET_UPDATE 9521 && (!avoiding_indexed_address_p (SFmode) 9522 || !gpc_reg_operand (operands[2], Pmode))" 9523 "@ 9524 lwzux %3,%0,%2 9525 lwzu %3,%2(%0)" 9526 [(set_attr "type" "load") 9527 (set_attr "update" "yes") 9528 (set_attr "indexed" "yes,no")]) 9529 9530(define_insn "*movsf_update4" 9531 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9532 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 9533 (match_operand:SF 3 "gpc_reg_operand" "r,r")) 9534 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9535 (plus:P (match_dup 1) (match_dup 2)))] 9536 "TARGET_SOFT_FLOAT && TARGET_UPDATE 9537 && (!avoiding_indexed_address_p (SFmode) 9538 || !gpc_reg_operand (operands[2], Pmode))" 9539 "@ 9540 stwux %3,%0,%2 9541 stwu %3,%2(%0)" 9542 [(set_attr "type" "store") 9543 (set_attr "update" "yes") 9544 (set_attr "indexed" "yes,no")]) 9545 9546 9547;; After inserting conditional returns we can sometimes have 9548;; unnecessary register moves. Unfortunately we cannot have a 9549;; modeless peephole here, because some single SImode sets have early 9550;; clobber outputs. Although those sets expand to multi-ppc-insn 9551;; sequences, using get_attr_length here will smash the operands 9552;; array. Neither is there an early_cobbler_p predicate. 9553;; Also this optimization interferes with scalars going into 9554;; altivec registers (the code does reloading through the FPRs). 9555(define_peephole2 9556 [(set (match_operand:DF 0 "gpc_reg_operand") 9557 (match_operand:DF 1 "any_operand")) 9558 (set (match_operand:DF 2 "gpc_reg_operand") 9559 (match_dup 0))] 9560 "!TARGET_VSX 9561 && peep2_reg_dead_p (2, operands[0])" 9562 [(set (match_dup 2) (match_dup 1))]) 9563 9564(define_peephole2 9565 [(set (match_operand:SF 0 "gpc_reg_operand") 9566 (match_operand:SF 1 "any_operand")) 9567 (set (match_operand:SF 2 "gpc_reg_operand") 9568 (match_dup 0))] 9569 "!TARGET_P8_VECTOR 9570 && peep2_reg_dead_p (2, operands[0])" 9571 [(set (match_dup 2) (match_dup 1))]) 9572 9573 9574;; TLS support. 9575 9576(define_insn "*tls_gd_pcrel<bits>" 9577 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9578 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") 9579 (const_int 0)] 9580 UNSPEC_TLSGD))] 9581 "HAVE_AS_TLS && TARGET_ELF" 9582 "la %0,%1@got@tlsgd@pcrel" 9583 [(set_attr "prefixed" "yes")]) 9584 9585(define_insn_and_split "*tls_gd<bits>" 9586 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9587 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") 9588 (match_operand:P 2 "gpc_reg_operand" "b")] 9589 UNSPEC_TLSGD))] 9590 "HAVE_AS_TLS && TARGET_ELF" 9591 "addi %0,%2,%1@got@tlsgd" 9592 "&& TARGET_CMODEL != CMODEL_SMALL" 9593 [(set (match_dup 3) 9594 (high:P 9595 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) 9596 (set (match_dup 0) 9597 (lo_sum:P (match_dup 3) 9598 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))] 9599{ 9600 operands[3] = gen_reg_rtx (<MODE>mode); 9601} 9602 [(set (attr "length") 9603 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9604 (const_int 8) 9605 (const_int 4)))]) 9606 9607(define_insn "*tls_gd_high<bits>" 9608 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9609 (high:P 9610 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") 9611 (match_operand:P 2 "gpc_reg_operand" "b")] 9612 UNSPEC_TLSGD)))] 9613 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9614 "addis %0,%2,%1@got@tlsgd@ha") 9615 9616(define_insn "*tls_gd_low<bits>" 9617 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9618 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 9619 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "") 9620 (match_operand:P 3 "gpc_reg_operand" "b")] 9621 UNSPEC_TLSGD)))] 9622 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9623 "addi %0,%1,%2@got@tlsgd@l") 9624 9625(define_insn "*tls_ld_pcrel<bits>" 9626 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9627 (unspec:P [(const_int 0)] 9628 UNSPEC_TLSLD))] 9629 "HAVE_AS_TLS && TARGET_ELF" 9630 "la %0,%&@got@tlsld@pcrel" 9631 [(set_attr "prefixed" "yes")]) 9632 9633(define_insn_and_split "*tls_ld<bits>" 9634 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9635 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] 9636 UNSPEC_TLSLD))] 9637 "HAVE_AS_TLS && TARGET_ELF" 9638 "addi %0,%1,%&@got@tlsld" 9639 "&& TARGET_CMODEL != CMODEL_SMALL" 9640 [(set (match_dup 2) 9641 (high:P 9642 (unspec:P [(match_dup 1)] UNSPEC_TLSLD))) 9643 (set (match_dup 0) 9644 (lo_sum:P (match_dup 2) 9645 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))] 9646{ 9647 operands[2] = gen_reg_rtx (<MODE>mode); 9648} 9649 [(set (attr "length") 9650 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9651 (const_int 8) 9652 (const_int 4)))]) 9653 9654(define_insn "*tls_ld_high<bits>" 9655 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9656 (high:P 9657 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] 9658 UNSPEC_TLSLD)))] 9659 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9660 "addis %0,%1,%&@got@tlsld@ha") 9661 9662(define_insn "*tls_ld_low<bits>" 9663 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9664 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 9665 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")] 9666 UNSPEC_TLSLD)))] 9667 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9668 "addi %0,%1,%&@got@tlsld@l") 9669 9670(define_insn "tls_dtprel_<bits>" 9671 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9672 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9673 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9674 UNSPEC_TLSDTPREL))] 9675 "HAVE_AS_TLS" 9676 "addi %0,%1,%2@dtprel" 9677 [(set (attr "prefixed") 9678 (if_then_else (match_test "rs6000_tls_size == 16") 9679 (const_string "no") 9680 (const_string "yes")))]) 9681 9682(define_insn "tls_dtprel_ha_<bits>" 9683 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9684 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9685 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9686 UNSPEC_TLSDTPRELHA))] 9687 "HAVE_AS_TLS" 9688 "addis %0,%1,%2@dtprel@ha") 9689 9690(define_insn "tls_dtprel_lo_<bits>" 9691 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9692 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9693 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9694 UNSPEC_TLSDTPRELLO))] 9695 "HAVE_AS_TLS" 9696 "addi %0,%1,%2@dtprel@l") 9697 9698(define_insn_and_split "tls_got_dtprel_<bits>" 9699 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9700 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9701 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9702 UNSPEC_TLSGOTDTPREL))] 9703 "HAVE_AS_TLS" 9704 "<ptrload> %0,%2@got@dtprel(%1)" 9705 "&& TARGET_CMODEL != CMODEL_SMALL" 9706 [(set (match_dup 3) 9707 (high:P 9708 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) 9709 (set (match_dup 0) 9710 (lo_sum:P (match_dup 3) 9711 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))] 9712{ 9713 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9714} 9715 [(set (attr "length") 9716 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9717 (const_int 8) 9718 (const_int 4)))]) 9719 9720(define_insn "*tls_got_dtprel_high<bits>" 9721 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9722 (high:P 9723 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9724 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9725 UNSPEC_TLSGOTDTPREL)))] 9726 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9727 "addis %0,%1,%2@got@dtprel@ha") 9728 9729(define_insn "*tls_got_dtprel_low<bits>" 9730 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9731 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 9732 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b") 9733 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9734 UNSPEC_TLSGOTDTPREL)))] 9735 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9736 "<ptrload> %0,%2@got@dtprel@l(%1)") 9737 9738(define_insn "tls_tprel_<bits>" 9739 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9740 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9741 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9742 UNSPEC_TLSTPREL))] 9743 "HAVE_AS_TLS" 9744 "addi %0,%1,%2@tprel" 9745 [(set (attr "prefixed") 9746 (if_then_else (match_test "rs6000_tls_size == 16") 9747 (const_string "no") 9748 (const_string "yes")))]) 9749 9750(define_insn "tls_tprel_ha_<bits>" 9751 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9752 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9753 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9754 UNSPEC_TLSTPRELHA))] 9755 "HAVE_AS_TLS" 9756 "addis %0,%1,%2@tprel@ha") 9757 9758(define_insn "tls_tprel_lo_<bits>" 9759 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9760 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9761 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9762 UNSPEC_TLSTPRELLO))] 9763 "HAVE_AS_TLS" 9764 "addi %0,%1,%2@tprel@l") 9765 9766(define_insn "*tls_got_tprel_pcrel_<bits>" 9767 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9768 (unspec:P [(const_int 0) 9769 (match_operand:P 1 "rs6000_tls_symbol_ref" "")] 9770 UNSPEC_TLSGOTTPREL))] 9771 "HAVE_AS_TLS" 9772 "<ptrload> %0,%1@got@tprel@pcrel" 9773 [(set_attr "prefixed" "yes")]) 9774 9775;; "b" output constraint here and on tls_tls input to support linker tls 9776;; optimization. The linker may edit the instructions emitted by a 9777;; tls_got_tprel/tls_tls pair to addis,addi. 9778(define_insn_and_split "tls_got_tprel_<bits>" 9779 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9780 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9781 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9782 UNSPEC_TLSGOTTPREL))] 9783 "HAVE_AS_TLS" 9784 "<ptrload> %0,%2@got@tprel(%1)" 9785 "&& TARGET_CMODEL != CMODEL_SMALL" 9786 [(set (match_dup 3) 9787 (high:P 9788 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) 9789 (set (match_dup 0) 9790 (lo_sum:P (match_dup 3) 9791 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))] 9792{ 9793 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9794} 9795 [(set (attr "length") 9796 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9797 (const_int 8) 9798 (const_int 4)))]) 9799 9800(define_insn "*tls_got_tprel_high<bits>" 9801 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9802 (high:P 9803 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9804 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9805 UNSPEC_TLSGOTTPREL)))] 9806 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9807 "addis %0,%1,%2@got@tprel@ha") 9808 9809(define_insn "*tls_got_tprel_low<bits>" 9810 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9811 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 9812 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b") 9813 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9814 UNSPEC_TLSGOTTPREL)))] 9815 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9816 "<ptrload> %0,%2@got@tprel@l(%1)") 9817 9818(define_insn "tls_tls_pcrel_<bits>" 9819 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9820 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9821 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9822 UNSPEC_TLSTLS_PCREL))] 9823 "TARGET_ELF && HAVE_AS_TLS" 9824 "add %0,%1,%2@tls@pcrel") 9825 9826(define_insn "tls_tls_<bits>" 9827 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9828 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9829 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9830 UNSPEC_TLSTLS))] 9831 "TARGET_ELF && HAVE_AS_TLS" 9832 "add %0,%1,%2@tls") 9833 9834(define_expand "tls_get_tpointer" 9835 [(set (match_operand:SI 0 "gpc_reg_operand") 9836 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))] 9837 "TARGET_XCOFF && HAVE_AS_TLS" 9838{ 9839 emit_insn (gen_tls_get_tpointer_internal ()); 9840 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); 9841 DONE; 9842}) 9843 9844(define_insn "tls_get_tpointer_internal" 9845 [(set (reg:SI 3) 9846 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS)) 9847 (clobber (reg:SI LR_REGNO))] 9848 "TARGET_XCOFF && HAVE_AS_TLS" 9849 "bla __get_tpointer") 9850 9851(define_expand "tls_get_addr<mode>" 9852 [(set (match_operand:P 0 "gpc_reg_operand") 9853 (unspec:P [(match_operand:P 1 "gpc_reg_operand") 9854 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))] 9855 "TARGET_XCOFF && HAVE_AS_TLS" 9856{ 9857 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]); 9858 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]); 9859 emit_insn (gen_tls_get_addr_internal<mode> ()); 9860 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3)); 9861 DONE; 9862}) 9863 9864(define_insn "tls_get_addr_internal<mode>" 9865 [(set (reg:P 3) 9866 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS)) 9867 (clobber (reg:P 0)) 9868 (clobber (reg:P 4)) 9869 (clobber (reg:P 5)) 9870 (clobber (reg:P 11)) 9871 (clobber (reg:CC CR0_REGNO)) 9872 (clobber (reg:P LR_REGNO))] 9873 "TARGET_XCOFF && HAVE_AS_TLS" 9874 "bla __tls_get_addr") 9875 9876;; Next come insns related to the calling sequence. 9877;; 9878;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). 9879;; We move the back-chain and decrement the stack pointer. 9880;; 9881;; Operand1 is more naturally reg_or_short_operand. However, for a large 9882;; constant alloca, using that predicate will force the generic code to put 9883;; the constant size into a register before calling the expander. 9884;; 9885;; As a result the expander would not have the constant size information 9886;; in those cases and would have to generate less efficient code. 9887;; 9888;; Thus we allow reg_or_cint_operand instead so that the expander can see 9889;; the constant size. The value is forced into a register if necessary. 9890;; 9891(define_expand "allocate_stack" 9892 [(set (match_operand 0 "gpc_reg_operand") 9893 (minus (reg 1) (match_operand 1 "reg_or_cint_operand"))) 9894 (set (reg 1) 9895 (minus (reg 1) (match_dup 1)))] 9896 "" 9897{ 9898 rtx chain = gen_reg_rtx (Pmode); 9899 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); 9900 rtx neg_op0; 9901 rtx insn, par, set, mem; 9902 9903 /* By allowing reg_or_cint_operand as the predicate we can get 9904 better code for stack-clash-protection because we do not lose 9905 size information. But the rest of the code expects the operand 9906 to be reg_or_short_operand. If it isn't, then force it into 9907 a register. */ 9908 rtx orig_op1 = operands[1]; 9909 if (!reg_or_short_operand (operands[1], Pmode)) 9910 operands[1] = force_reg (Pmode, operands[1]); 9911 9912 emit_move_insn (chain, stack_bot); 9913 9914 /* Check stack bounds if necessary. */ 9915 if (crtl->limit_stack) 9916 { 9917 rtx available; 9918 available = expand_binop (Pmode, sub_optab, 9919 stack_pointer_rtx, stack_limit_rtx, 9920 NULL_RTX, 1, OPTAB_WIDEN); 9921 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx)); 9922 } 9923 9924 /* Allocate and probe if requested. 9925 This may look similar to the loop we use for prologue allocations, 9926 but it is critically different. For the former we know the loop 9927 will iterate, but do not know that generally here. The former 9928 uses that knowledge to rotate the loop. Combining them would be 9929 possible with some performance cost. */ 9930 if (flag_stack_clash_protection) 9931 { 9932 rtx rounded_size, last_addr, residual; 9933 HOST_WIDE_INT probe_interval; 9934 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr, 9935 &residual, &probe_interval, 9936 orig_op1); 9937 9938 /* We do occasionally get in here with constant sizes, we might 9939 as well do a reasonable job when we obviously can. */ 9940 if (rounded_size != const0_rtx) 9941 { 9942 rtx loop_lab, end_loop; 9943 bool rotated = CONST_INT_P (rounded_size); 9944 rtx update = GEN_INT (-probe_interval); 9945 if (probe_interval > 32768) 9946 update = force_reg (Pmode, update); 9947 9948 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop, 9949 last_addr, rotated); 9950 9951 if (TARGET_32BIT) 9952 emit_insn (gen_movsi_update_stack (stack_pointer_rtx, 9953 stack_pointer_rtx, 9954 update, chain)); 9955 else 9956 emit_insn (gen_movdi_update_stack (stack_pointer_rtx, 9957 stack_pointer_rtx, 9958 update, chain)); 9959 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop, 9960 last_addr, rotated); 9961 } 9962 9963 /* Now handle residuals. We just have to set operands[1] correctly 9964 and let the rest of the expander run. */ 9965 operands[1] = residual; 9966 } 9967 9968 if (!(CONST_INT_P (operands[1]) 9969 && IN_RANGE (INTVAL (operands[1]), -32767, 32768))) 9970 { 9971 operands[1] = force_reg (Pmode, operands[1]); 9972 neg_op0 = gen_reg_rtx (Pmode); 9973 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1])); 9974 } 9975 else 9976 neg_op0 = GEN_INT (-INTVAL (operands[1])); 9977 9978 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack 9979 : gen_movdi_update_stack)) 9980 (stack_pointer_rtx, stack_pointer_rtx, neg_op0, 9981 chain)); 9982 /* Since we didn't use gen_frame_mem to generate the MEM, grab 9983 it now and set the alias set/attributes. The above gen_*_update 9984 calls will generate a PARALLEL with the MEM set being the first 9985 operation. */ 9986 par = PATTERN (insn); 9987 gcc_assert (GET_CODE (par) == PARALLEL); 9988 set = XVECEXP (par, 0, 0); 9989 gcc_assert (GET_CODE (set) == SET); 9990 mem = SET_DEST (set); 9991 gcc_assert (MEM_P (mem)); 9992 MEM_NOTRAP_P (mem) = 1; 9993 set_mem_alias_set (mem, get_frame_alias_set ()); 9994 9995 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 9996 DONE; 9997}) 9998 9999;; These patterns say how to save and restore the stack pointer. We need not 10000;; save the stack pointer at function level since we are careful to 10001;; preserve the backchain. At block level, we have to restore the backchain 10002;; when we restore the stack pointer. 10003;; 10004;; For nonlocal gotos, we must save both the stack pointer and its 10005;; backchain and restore both. Note that in the nonlocal case, the 10006;; save area is a memory location. 10007 10008(define_expand "save_stack_function" 10009 [(match_operand 0 "any_operand") 10010 (match_operand 1 "any_operand")] 10011 "" 10012 "DONE;") 10013 10014(define_expand "restore_stack_function" 10015 [(match_operand 0 "any_operand") 10016 (match_operand 1 "any_operand")] 10017 "" 10018 "DONE;") 10019 10020;; Adjust stack pointer (op0) to a new value (op1). 10021;; First copy old stack backchain to new location, and ensure that the 10022;; scheduler won't reorder the sp assignment before the backchain write. 10023(define_expand "restore_stack_block" 10024 [(set (match_dup 2) (match_dup 3)) 10025 (set (match_dup 4) (match_dup 2)) 10026 (match_dup 5) 10027 (set (match_operand 0 "register_operand") 10028 (match_operand 1 "register_operand"))] 10029 "" 10030{ 10031 rtvec p; 10032 10033 operands[1] = force_reg (Pmode, operands[1]); 10034 operands[2] = gen_reg_rtx (Pmode); 10035 operands[3] = gen_frame_mem (Pmode, operands[0]); 10036 operands[4] = gen_frame_mem (Pmode, operands[1]); 10037 p = rtvec_alloc (1); 10038 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 10039 const0_rtx); 10040 operands[5] = gen_rtx_PARALLEL (VOIDmode, p); 10041}) 10042 10043(define_expand "save_stack_nonlocal" 10044 [(set (match_dup 3) (match_dup 4)) 10045 (set (match_operand 0 "memory_operand") (match_dup 3)) 10046 (set (match_dup 2) (match_operand 1 "register_operand"))] 10047 "" 10048{ 10049 int units_per_word = (TARGET_32BIT) ? 4 : 8; 10050 10051 /* Copy the backchain to the first word, sp to the second. */ 10052 operands[0] = adjust_address_nv (operands[0], Pmode, 0); 10053 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word); 10054 operands[3] = gen_reg_rtx (Pmode); 10055 operands[4] = gen_frame_mem (Pmode, operands[1]); 10056}) 10057 10058(define_expand "restore_stack_nonlocal" 10059 [(set (match_dup 2) (match_operand 1 "memory_operand")) 10060 (set (match_dup 3) (match_dup 4)) 10061 (set (match_dup 5) (match_dup 2)) 10062 (match_dup 6) 10063 (set (match_operand 0 "register_operand") (match_dup 3))] 10064 "" 10065{ 10066 int units_per_word = (TARGET_32BIT) ? 4 : 8; 10067 rtvec p; 10068 10069 /* Restore the backchain from the first word, sp from the second. */ 10070 operands[2] = gen_reg_rtx (Pmode); 10071 operands[3] = gen_reg_rtx (Pmode); 10072 operands[1] = adjust_address_nv (operands[1], Pmode, 0); 10073 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word); 10074 operands[5] = gen_frame_mem (Pmode, operands[3]); 10075 p = rtvec_alloc (1); 10076 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 10077 const0_rtx); 10078 operands[6] = gen_rtx_PARALLEL (VOIDmode, p); 10079}) 10080 10081;; Load up a PC-relative address. Print_operand_address will append a @pcrel 10082;; to the symbol or label. 10083(define_insn "*pcrel_local_addr" 10084 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10085 (match_operand:DI 1 "pcrel_local_address"))] 10086 "TARGET_PCREL" 10087 "la %0,%a1" 10088 [(set_attr "prefixed" "yes")]) 10089 10090;; Load up a PC-relative address to an external symbol. If the symbol and the 10091;; program are both defined in the main program, the linker will optimize this 10092;; to a PADDI. Otherwise, it will create a GOT address that is relocated by 10093;; the dynamic linker and loaded up. Print_operand_address will append a 10094;; @got@pcrel to the symbol. 10095(define_insn "*pcrel_extern_addr" 10096 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10097 (match_operand:DI 1 "pcrel_external_address"))] 10098 "TARGET_PCREL" 10099 "ld %0,%a1" 10100 [(set_attr "prefixed" "yes") 10101 (set_attr "type" "load")]) 10102 10103;; TOC register handling. 10104 10105;; Code to initialize the TOC register... 10106 10107(define_insn "load_toc_aix_si" 10108 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10109 (unspec:SI [(const_int 0)] UNSPEC_TOC)) 10110 (use (reg:SI 2))])] 10111 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT" 10112{ 10113 char buf[30]; 10114 extern int need_toc_init; 10115 need_toc_init = 1; 10116 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); 10117 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 10118 operands[2] = gen_rtx_REG (Pmode, 2); 10119 return "lwz %0,%1(%2)"; 10120} 10121 [(set_attr "type" "load") 10122 (set_attr "update" "no") 10123 (set_attr "indexed" "no")]) 10124 10125(define_insn "load_toc_aix_di" 10126 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10127 (unspec:DI [(const_int 0)] UNSPEC_TOC)) 10128 (use (reg:DI 2))])] 10129 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT" 10130{ 10131 char buf[30]; 10132 extern int need_toc_init; 10133 need_toc_init = 1; 10134 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 10135 !TARGET_ELF || !TARGET_MINIMAL_TOC); 10136 if (TARGET_ELF) 10137 strcat (buf, "@toc"); 10138 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 10139 operands[2] = gen_rtx_REG (Pmode, 2); 10140 return "ld %0,%1(%2)"; 10141} 10142 [(set_attr "type" "load") 10143 (set_attr "update" "no") 10144 (set_attr "indexed" "no")]) 10145 10146(define_insn "load_toc_v4_pic_si" 10147 [(set (reg:SI LR_REGNO) 10148 (unspec:SI [(const_int 0)] UNSPEC_TOC))] 10149 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT" 10150 "bl _GLOBAL_OFFSET_TABLE_@local-4" 10151 [(set_attr "type" "branch")]) 10152 10153(define_expand "load_toc_v4_PIC_1" 10154 [(parallel [(set (reg:SI LR_REGNO) 10155 (match_operand:SI 0 "immediate_operand" "s")) 10156 (use (unspec [(match_dup 0)] UNSPEC_TOC))])] 10157 "TARGET_ELF && DEFAULT_ABI == ABI_V4 10158 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10159 "") 10160 10161(define_insn "load_toc_v4_PIC_1_normal" 10162 [(set (reg:SI LR_REGNO) 10163 (match_operand:SI 0 "immediate_operand" "s")) 10164 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 10165 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 10166 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10167 "bcl 20,31,%0\n%0:" 10168 [(set_attr "type" "branch") 10169 (set_attr "cannot_copy" "yes")]) 10170 10171(define_insn "load_toc_v4_PIC_1_476" 10172 [(set (reg:SI LR_REGNO) 10173 (match_operand:SI 0 "immediate_operand" "s")) 10174 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 10175 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 10176 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10177{ 10178 char name[32]; 10179 static char templ[32]; 10180 10181 get_ppc476_thunk_name (name); 10182 sprintf (templ, "bl %s\n%%0:", name); 10183 return templ; 10184} 10185 [(set_attr "type" "branch") 10186 (set_attr "cannot_copy" "yes")]) 10187 10188(define_expand "load_toc_v4_PIC_1b" 10189 [(parallel [(set (reg:SI LR_REGNO) 10190 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10191 (label_ref (match_operand 1 ""))] 10192 UNSPEC_TOCPTR)) 10193 (match_dup 1)])] 10194 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10195 "") 10196 10197(define_insn "load_toc_v4_PIC_1b_normal" 10198 [(set (reg:SI LR_REGNO) 10199 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10200 (label_ref (match_operand 1 "" ""))] 10201 UNSPEC_TOCPTR)) 10202 (match_dup 1)] 10203 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10204 "bcl 20,31,$+8\;.long %0-$" 10205 [(set_attr "type" "branch") 10206 (set_attr "length" "8")]) 10207 10208(define_insn "load_toc_v4_PIC_1b_476" 10209 [(set (reg:SI LR_REGNO) 10210 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10211 (label_ref (match_operand 1 "" ""))] 10212 UNSPEC_TOCPTR)) 10213 (match_dup 1)] 10214 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10215{ 10216 char name[32]; 10217 static char templ[32]; 10218 10219 get_ppc476_thunk_name (name); 10220 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name); 10221 return templ; 10222} 10223 [(set_attr "type" "branch") 10224 (set_attr "length" "16")]) 10225 10226(define_insn "load_toc_v4_PIC_2" 10227 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10228 (mem:SI (plus:SI 10229 (match_operand:SI 1 "gpc_reg_operand" "b") 10230 (const 10231 (minus:SI (match_operand:SI 2 "immediate_operand" "s") 10232 (match_operand:SI 3 "immediate_operand" "s"))))))] 10233 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10234 "lwz %0,%2-%3(%1)" 10235 [(set_attr "type" "load")]) 10236 10237(define_insn "load_toc_v4_PIC_3b" 10238 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10239 (plus:SI 10240 (match_operand:SI 1 "gpc_reg_operand" "b") 10241 (high:SI 10242 (const 10243 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 10244 (match_operand:SI 3 "symbol_ref_operand" "s"))))))] 10245 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 10246 "addis %0,%1,%2-%3@ha") 10247 10248(define_insn "load_toc_v4_PIC_3c" 10249 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10250 (lo_sum:SI 10251 (match_operand:SI 1 "gpc_reg_operand" "b") 10252 (const 10253 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 10254 (match_operand:SI 3 "symbol_ref_operand" "s")))))] 10255 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 10256 "addi %0,%1,%2-%3@l") 10257 10258;; If the TOC is shared over a translation unit, as happens with all 10259;; the kinds of PIC that we support, we need to restore the TOC 10260;; pointer only when jumping over units of translation. 10261;; On Darwin, we need to reload the picbase. 10262 10263(define_expand "builtin_setjmp_receiver" 10264 [(use (label_ref (match_operand 0 "")))] 10265 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1) 10266 || (TARGET_TOC && TARGET_MINIMAL_TOC) 10267 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)" 10268{ 10269#if TARGET_MACHO 10270 if (DEFAULT_ABI == ABI_DARWIN) 10271 { 10272 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); 10273 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 10274 rtx tmplabrtx; 10275 char tmplab[20]; 10276 10277 crtl->uses_pic_offset_table = 1; 10278 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR", 10279 CODE_LABEL_NUMBER (operands[0])); 10280 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); 10281 10282 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx)); 10283 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); 10284 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg, 10285 picrtx, tmplabrtx)); 10286 } 10287 else 10288#endif 10289 rs6000_emit_load_toc_table (FALSE); 10290 DONE; 10291}) 10292 10293;; Largetoc support 10294(define_insn "*largetoc_high" 10295 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 10296 (high:DI 10297 (unspec [(match_operand:DI 1 "" "") 10298 (match_operand:DI 2 "gpc_reg_operand" "b")] 10299 UNSPEC_TOCREL)))] 10300 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10301 "addis %0,%2,%1@toc@ha") 10302 10303(define_insn "*largetoc_high_aix<mode>" 10304 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 10305 (high:P 10306 (unspec [(match_operand:P 1 "" "") 10307 (match_operand:P 2 "gpc_reg_operand" "b")] 10308 UNSPEC_TOCREL)))] 10309 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10310 "addis %0,%1@u(%2)") 10311 10312(define_insn "*largetoc_high_plus" 10313 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 10314 (high:DI 10315 (plus:DI 10316 (unspec [(match_operand:DI 1 "" "") 10317 (match_operand:DI 2 "gpc_reg_operand" "b")] 10318 UNSPEC_TOCREL) 10319 (match_operand:DI 3 "add_cint_operand" "n"))))] 10320 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10321 "addis %0,%2,%1+%3@toc@ha") 10322 10323(define_insn "*largetoc_high_plus_aix<mode>" 10324 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 10325 (high:P 10326 (plus:P 10327 (unspec [(match_operand:P 1 "" "") 10328 (match_operand:P 2 "gpc_reg_operand" "b")] 10329 UNSPEC_TOCREL) 10330 (match_operand:P 3 "add_cint_operand" "n"))))] 10331 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10332 "addis %0,%1+%3@u(%2)") 10333 10334(define_insn "*largetoc_low" 10335 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10336 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 10337 (match_operand:DI 2 "" "")))] 10338 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10339 "addi %0,%1,%2@l") 10340 10341(define_insn "*largetoc_low_aix<mode>" 10342 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10343 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 10344 (match_operand:P 2 "" "")))] 10345 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10346 "la %0,%2@l(%1)") 10347 10348(define_insn_and_split "*tocref<mode>" 10349 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10350 (match_operand:P 1 "small_toc_ref" "R"))] 10351 "TARGET_TOC 10352 && legitimate_constant_pool_address_p (operands[1], QImode, false)" 10353 "la %0,%a1" 10354 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed" 10355 [(set (match_dup 0) (high:P (match_dup 1))) 10356 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))]) 10357 10358;; Elf specific ways of loading addresses for non-PIC code. 10359;; The output of this could be r0, but we make a very strong 10360;; preference for a base register because it will usually 10361;; be needed there. 10362(define_insn "elf_high" 10363 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") 10364 (high:SI (match_operand 1 "" "")))] 10365 "TARGET_ELF && !TARGET_64BIT && !flag_pic" 10366 "lis %0,%1@ha") 10367 10368(define_insn "elf_low" 10369 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10370 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 10371 (match_operand 2 "" "")))] 10372 "TARGET_ELF && !TARGET_64BIT && !flag_pic" 10373 "la %0,%2@l(%1)") 10374 10375(define_insn "*pltseq_tocsave_<mode>" 10376 [(set (match_operand:P 0 "memory_operand" "=m") 10377 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10378 (match_operand:P 2 "symbol_ref_operand" "s") 10379 (match_operand:P 3 "" "")] 10380 UNSPEC_PLTSEQ))] 10381 "TARGET_PLTSEQ 10382 && DEFAULT_ABI == ABI_ELFv2" 10383{ 10384 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE); 10385}) 10386 10387(define_insn "*pltseq_plt16_ha_<mode>" 10388 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10389 (unspec:P [(match_operand:P 1 "" "") 10390 (match_operand:P 2 "symbol_ref_operand" "s") 10391 (match_operand:P 3 "" "")] 10392 UNSPEC_PLT16_HA))] 10393 "TARGET_PLTSEQ" 10394{ 10395 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA); 10396}) 10397 10398(define_insn "*pltseq_plt16_lo_<mode>" 10399 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10400 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b") 10401 (match_operand:P 2 "symbol_ref_operand" "s") 10402 (match_operand:P 3 "" "")] 10403 UNSPECV_PLT16_LO))] 10404 "TARGET_PLTSEQ" 10405{ 10406 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO); 10407} 10408 [(set_attr "type" "load")]) 10409 10410(define_insn "*pltseq_mtctr_<mode>" 10411 [(set (match_operand:P 0 "register_operand" "=c") 10412 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") 10413 (match_operand:P 2 "symbol_ref_operand" "s") 10414 (match_operand:P 3 "" "")] 10415 UNSPEC_PLTSEQ))] 10416 "TARGET_PLTSEQ" 10417{ 10418 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR); 10419}) 10420 10421(define_insn "*pltseq_plt_pcrel<mode>" 10422 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10423 (unspec_volatile:P [(match_operand:P 1 "" "") 10424 (match_operand:P 2 "symbol_ref_operand" "s") 10425 (match_operand:P 3 "" "")] 10426 UNSPECV_PLT_PCREL))] 10427 "HAVE_AS_PLTSEQ && TARGET_ELF 10428 && rs6000_pcrel_p (cfun)" 10429{ 10430 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34); 10431} 10432 [(set_attr "type" "load") 10433 (set_attr "length" "12")]) 10434 10435;; Call and call_value insns 10436;; For the purposes of expanding calls, Darwin is very similar to SYSV. 10437(define_expand "call" 10438 [(parallel [(call (mem:SI (match_operand 0 "address_operand")) 10439 (match_operand 1 "")) 10440 (use (match_operand 2 "")) 10441 (clobber (reg:SI LR_REGNO))])] 10442 "" 10443{ 10444#if TARGET_MACHO 10445 if (MACHOPIC_INDIRECT) 10446 operands[0] = machopic_indirect_call_target (operands[0]); 10447#endif 10448 10449 gcc_assert (MEM_P (operands[0])); 10450 10451 operands[0] = XEXP (operands[0], 0); 10452 10453 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10454 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]); 10455 else if (DEFAULT_ABI == ABI_V4) 10456 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]); 10457 else if (DEFAULT_ABI == ABI_DARWIN) 10458 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]); 10459 else 10460 gcc_unreachable (); 10461 10462 DONE; 10463}) 10464 10465(define_expand "call_value" 10466 [(parallel [(set (match_operand 0 "") 10467 (call (mem:SI (match_operand 1 "address_operand")) 10468 (match_operand 2 ""))) 10469 (use (match_operand 3 "")) 10470 (clobber (reg:SI LR_REGNO))])] 10471 "" 10472{ 10473#if TARGET_MACHO 10474 if (MACHOPIC_INDIRECT) 10475 operands[1] = machopic_indirect_call_target (operands[1]); 10476#endif 10477 10478 gcc_assert (MEM_P (operands[1])); 10479 10480 operands[1] = XEXP (operands[1], 0); 10481 10482 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10483 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]); 10484 else if (DEFAULT_ABI == ABI_V4) 10485 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]); 10486 else if (DEFAULT_ABI == ABI_DARWIN) 10487 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]); 10488 else 10489 gcc_unreachable (); 10490 10491 DONE; 10492}) 10493 10494;; Call to function in current module. No TOC pointer reload needed. 10495;; Operand2 is nonzero if we are using the V.4 calling sequence and 10496;; either the function was not prototyped, or it was prototyped as a 10497;; variable argument function. It is > 0 if FP registers were passed 10498;; and < 0 if they were not. 10499 10500(define_insn "*call_local<mode>" 10501 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s")) 10502 (match_operand 1)) 10503 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10504 (clobber (reg:P LR_REGNO))] 10505 "(INTVAL (operands[2]) & CALL_LONG) == 0" 10506{ 10507 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10508 output_asm_insn ("crxor 6,6,6", operands); 10509 10510 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10511 output_asm_insn ("creqv 6,6,6", operands); 10512 10513 if (rs6000_pcrel_p (cfun)) 10514 return "bl %z0@notoc"; 10515 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0"; 10516} 10517 [(set_attr "type" "branch") 10518 (set_attr "length" "4,8")]) 10519 10520(define_insn "*call_value_local<mode>" 10521 [(set (match_operand 0 "" "") 10522 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s")) 10523 (match_operand 2))) 10524 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10525 (clobber (reg:P LR_REGNO))] 10526 "(INTVAL (operands[3]) & CALL_LONG) == 0" 10527{ 10528 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10529 output_asm_insn ("crxor 6,6,6", operands); 10530 10531 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10532 output_asm_insn ("creqv 6,6,6", operands); 10533 10534 if (rs6000_pcrel_p (cfun)) 10535 return "bl %z1@notoc"; 10536 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1"; 10537} 10538 [(set_attr "type" "branch") 10539 (set_attr "length" "4,8")]) 10540 10541 10542;; A function pointer under System V is just a normal pointer 10543;; operands[0] is the function pointer 10544;; operands[1] is the tls call arg 10545;; operands[2] is the value FUNCTION_ARG returns for the VOID argument 10546;; which indicates how to set cr1 10547 10548(define_insn "*call_indirect_nonlocal_sysv<mode>" 10549 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 10550 (match_operand 1)) 10551 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 10552 (clobber (reg:P LR_REGNO))] 10553 "DEFAULT_ABI == ABI_V4 10554 || DEFAULT_ABI == ABI_DARWIN" 10555{ 10556 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10557 output_asm_insn ("crxor 6,6,6", operands); 10558 10559 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10560 output_asm_insn ("creqv 6,6,6", operands); 10561 10562 return rs6000_indirect_call_template (operands, 0); 10563} 10564 [(set_attr "type" "jmpreg") 10565 (set (attr "length") 10566 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") 10567 (match_test "which_alternative != 1")) 10568 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 10569 (const_string "12") 10570 (ior (and (match_test "!rs6000_speculate_indirect_jumps") 10571 (match_test "which_alternative != 1")) 10572 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 10573 (const_string "8")] 10574 (const_string "4")))]) 10575 10576(define_insn "*call_nonlocal_sysv<mode>" 10577 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 10578 (match_operand 1)) 10579 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10580 (clobber (reg:P LR_REGNO))] 10581 "(DEFAULT_ABI == ABI_DARWIN 10582 || (DEFAULT_ABI == ABI_V4 10583 && (INTVAL (operands[2]) & CALL_LONG) == 0))" 10584{ 10585 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10586 output_asm_insn ("crxor 6,6,6", operands); 10587 10588 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10589 output_asm_insn ("creqv 6,6,6", operands); 10590 10591 return rs6000_call_template (operands, 0); 10592} 10593 [(set_attr "type" "branch,branch") 10594 (set_attr "length" "4,8")]) 10595 10596(define_insn "*call_nonlocal_sysv_secure<mode>" 10597 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 10598 (match_operand 1)) 10599 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10600 (use (match_operand:SI 3 "register_operand" "r,r")) 10601 (clobber (reg:P LR_REGNO))] 10602 "(DEFAULT_ABI == ABI_V4 10603 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) 10604 && (INTVAL (operands[2]) & CALL_LONG) == 0)" 10605{ 10606 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10607 output_asm_insn ("crxor 6,6,6", operands); 10608 10609 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10610 output_asm_insn ("creqv 6,6,6", operands); 10611 10612 return rs6000_call_template (operands, 0); 10613} 10614 [(set_attr "type" "branch,branch") 10615 (set_attr "length" "4,8")]) 10616 10617(define_insn "*call_value_indirect_nonlocal_sysv<mode>" 10618 [(set (match_operand 0 "" "") 10619 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 10620 (match_operand:P 2 "unspec_tls" ""))) 10621 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 10622 (clobber (reg:P LR_REGNO))] 10623 "DEFAULT_ABI == ABI_V4 10624 || DEFAULT_ABI == ABI_DARWIN" 10625{ 10626 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10627 output_asm_insn ("crxor 6,6,6", operands); 10628 10629 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10630 output_asm_insn ("creqv 6,6,6", operands); 10631 10632 return rs6000_indirect_call_template (operands, 1); 10633} 10634 [(set_attr "type" "jmpreg") 10635 (set (attr "length") 10636 (plus 10637 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])") 10638 (const_int 4) 10639 (const_int 0)) 10640 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10641 (match_test "which_alternative != 1")) 10642 (const_int 8) 10643 (const_int 4))))]) 10644 10645(define_insn "*call_value_nonlocal_sysv<mode>" 10646 [(set (match_operand 0 "" "") 10647 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 10648 (match_operand:P 2 "unspec_tls" ""))) 10649 (use (match_operand:SI 3 "immediate_operand" "n")) 10650 (clobber (reg:P LR_REGNO))] 10651 "(DEFAULT_ABI == ABI_DARWIN 10652 || (DEFAULT_ABI == ABI_V4 10653 && (INTVAL (operands[3]) & CALL_LONG) == 0))" 10654{ 10655 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10656 output_asm_insn ("crxor 6,6,6", operands); 10657 10658 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10659 output_asm_insn ("creqv 6,6,6", operands); 10660 10661 return rs6000_call_template (operands, 1); 10662} 10663 [(set_attr "type" "branch") 10664 (set (attr "length") 10665 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])") 10666 (const_int 8) 10667 (const_int 4)))]) 10668 10669(define_insn "*call_value_nonlocal_sysv_secure<mode>" 10670 [(set (match_operand 0 "" "") 10671 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 10672 (match_operand:P 2 "unspec_tls" ""))) 10673 (use (match_operand:SI 3 "immediate_operand" "n")) 10674 (use (match_operand:SI 4 "register_operand" "r")) 10675 (clobber (reg:P LR_REGNO))] 10676 "(DEFAULT_ABI == ABI_V4 10677 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) 10678 && (INTVAL (operands[3]) & CALL_LONG) == 0)" 10679{ 10680 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10681 output_asm_insn ("crxor 6,6,6", operands); 10682 10683 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10684 output_asm_insn ("creqv 6,6,6", operands); 10685 10686 return rs6000_call_template (operands, 1); 10687} 10688 [(set_attr "type" "branch") 10689 (set (attr "length") 10690 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])") 10691 (const_int 8) 10692 (const_int 4)))]) 10693 10694;; Call to AIX abi function which may be in another module. 10695;; Restore the TOC pointer (r2) after the call. 10696 10697(define_insn "*call_nonlocal_aix<mode>" 10698 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s")) 10699 (match_operand 1)) 10700 (use (match_operand:SI 2 "immediate_operand" "n")) 10701 (clobber (reg:P LR_REGNO))] 10702 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10703 && (INTVAL (operands[2]) & CALL_LONG) == 0" 10704{ 10705 return rs6000_call_template (operands, 0); 10706} 10707 [(set_attr "type" "branch") 10708 (set (attr "length") 10709 (if_then_else (match_test "rs6000_pcrel_p (cfun)") 10710 (const_int 4) 10711 (const_int 8)))]) 10712 10713(define_insn "*call_value_nonlocal_aix<mode>" 10714 [(set (match_operand 0 "" "") 10715 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 10716 (match_operand:P 2 "unspec_tls" ""))) 10717 (use (match_operand:SI 3 "immediate_operand" "n")) 10718 (clobber (reg:P LR_REGNO))] 10719 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10720 && (INTVAL (operands[3]) & CALL_LONG) == 0" 10721{ 10722 return rs6000_call_template (operands, 1); 10723} 10724 [(set_attr "type" "branch") 10725 (set (attr "length") 10726 (if_then_else (match_test "rs6000_pcrel_p (cfun)") 10727 (const_int 4) 10728 (const_int 8)))]) 10729 10730;; Call to indirect functions with the AIX abi using a 3 word descriptor. 10731;; Operand0 is the addresss of the function to call 10732;; Operand3 is the location in the function descriptor to load r2 from 10733;; Operand4 is the offset of the stack location holding the current TOC pointer 10734 10735(define_insn "*call_indirect_aix<mode>" 10736 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 10737 (match_operand 1)) 10738 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 10739 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>")) 10740 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT)) 10741 (clobber (reg:P LR_REGNO))] 10742 "DEFAULT_ABI == ABI_AIX" 10743{ 10744 return rs6000_indirect_call_template (operands, 0); 10745} 10746 [(set_attr "type" "jmpreg") 10747 (set (attr "length") 10748 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10749 (match_test "which_alternative != 1")) 10750 (const_string "16") 10751 (const_string "12")))]) 10752 10753(define_insn "*call_value_indirect_aix<mode>" 10754 [(set (match_operand 0 "" "") 10755 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 10756 (match_operand:P 2 "unspec_tls" ""))) 10757 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 10758 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>")) 10759 (set (reg:P TOC_REGNUM) 10760 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")] 10761 UNSPEC_TOCSLOT)) 10762 (clobber (reg:P LR_REGNO))] 10763 "DEFAULT_ABI == ABI_AIX" 10764{ 10765 return rs6000_indirect_call_template (operands, 1); 10766} 10767 [(set_attr "type" "jmpreg") 10768 (set (attr "length") 10769 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10770 (match_test "which_alternative != 1")) 10771 (const_string "16") 10772 (const_string "12")))]) 10773 10774;; Call to indirect functions with the ELFv2 ABI. 10775;; Operand0 is the addresss of the function to call 10776;; Operand3 is the offset of the stack location holding the current TOC pointer 10777 10778(define_insn "*call_indirect_elfv2<mode>" 10779 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 10780 (match_operand 1)) 10781 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 10782 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT)) 10783 (clobber (reg:P LR_REGNO))] 10784 "DEFAULT_ABI == ABI_ELFv2" 10785{ 10786 return rs6000_indirect_call_template (operands, 0); 10787} 10788 [(set_attr "type" "jmpreg") 10789 (set (attr "length") 10790 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10791 (match_test "which_alternative != 1")) 10792 (const_string "12") 10793 (const_string "8")))]) 10794 10795(define_insn "*call_indirect_pcrel<mode>" 10796 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 10797 (match_operand 1)) 10798 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 10799 (clobber (reg:P LR_REGNO))] 10800 "rs6000_pcrel_p (cfun)" 10801{ 10802 return rs6000_indirect_call_template (operands, 0); 10803} 10804 [(set_attr "type" "jmpreg") 10805 (set (attr "length") 10806 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10807 (match_test "which_alternative != 1")) 10808 (const_string "8") 10809 (const_string "4")))]) 10810 10811(define_insn "*call_value_indirect_elfv2<mode>" 10812 [(set (match_operand 0 "" "") 10813 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 10814 (match_operand:P 2 "unspec_tls" ""))) 10815 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 10816 (set (reg:P TOC_REGNUM) 10817 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] 10818 UNSPEC_TOCSLOT)) 10819 (clobber (reg:P LR_REGNO))] 10820 "DEFAULT_ABI == ABI_ELFv2" 10821{ 10822 return rs6000_indirect_call_template (operands, 1); 10823} 10824 [(set_attr "type" "jmpreg") 10825 (set (attr "length") 10826 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10827 (match_test "which_alternative != 1")) 10828 (const_string "12") 10829 (const_string "8")))]) 10830 10831(define_insn "*call_value_indirect_pcrel<mode>" 10832 [(set (match_operand 0 "" "") 10833 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 10834 (match_operand:P 2 "unspec_tls" ""))) 10835 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 10836 (clobber (reg:P LR_REGNO))] 10837 "rs6000_pcrel_p (cfun)" 10838{ 10839 return rs6000_indirect_call_template (operands, 1); 10840} 10841 [(set_attr "type" "jmpreg") 10842 (set (attr "length") 10843 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10844 (match_test "which_alternative != 1")) 10845 (const_string "8") 10846 (const_string "4")))]) 10847 10848;; Call subroutine returning any type. 10849(define_expand "untyped_call" 10850 [(parallel [(call (match_operand 0 "") 10851 (const_int 0)) 10852 (match_operand 1 "") 10853 (match_operand 2 "")])] 10854 "" 10855{ 10856 int i; 10857 10858 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); 10859 10860 for (int i = 0; i < XVECLEN (operands[2], 0); i++) 10861 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i))); 10862 emit_insn (gen_blockage ()); 10863 10864 for (i = 0; i < XVECLEN (operands[2], 0); i++) 10865 { 10866 rtx set = XVECEXP (operands[2], 0, i); 10867 emit_move_insn (SET_DEST (set), SET_SRC (set)); 10868 } 10869 10870 /* The optimizer does not know that the call sets the function value 10871 registers we stored in the result block. We avoid problems by 10872 claiming that all hard registers are used and clobbered at this 10873 point. */ 10874 emit_insn (gen_blockage ()); 10875 10876 DONE; 10877}) 10878 10879;; sibling call patterns 10880(define_expand "sibcall" 10881 [(parallel [(call (mem:SI (match_operand 0 "address_operand")) 10882 (match_operand 1 "")) 10883 (use (match_operand 2 "")) 10884 (simple_return)])] 10885 "" 10886{ 10887#if TARGET_MACHO 10888 if (MACHOPIC_INDIRECT) 10889 operands[0] = machopic_indirect_call_target (operands[0]); 10890#endif 10891 10892 gcc_assert (MEM_P (operands[0])); 10893 gcc_assert (CONST_INT_P (operands[1])); 10894 10895 operands[0] = XEXP (operands[0], 0); 10896 10897 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10898 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); 10899 else if (DEFAULT_ABI == ABI_V4) 10900 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]); 10901 else if (DEFAULT_ABI == ABI_DARWIN) 10902 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]); 10903 else 10904 gcc_unreachable (); 10905 10906 DONE; 10907}) 10908 10909(define_expand "sibcall_value" 10910 [(parallel [(set (match_operand 0 "register_operand") 10911 (call (mem:SI (match_operand 1 "address_operand")) 10912 (match_operand 2 ""))) 10913 (use (match_operand 3 "")) 10914 (simple_return)])] 10915 "" 10916{ 10917#if TARGET_MACHO 10918 if (MACHOPIC_INDIRECT) 10919 operands[1] = machopic_indirect_call_target (operands[1]); 10920#endif 10921 10922 gcc_assert (MEM_P (operands[1])); 10923 gcc_assert (CONST_INT_P (operands[2])); 10924 10925 operands[1] = XEXP (operands[1], 0); 10926 10927 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10928 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]); 10929 else if (DEFAULT_ABI == ABI_V4) 10930 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]); 10931 else if (DEFAULT_ABI == ABI_DARWIN) 10932 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]); 10933 else 10934 gcc_unreachable (); 10935 10936 DONE; 10937}) 10938 10939(define_insn "*sibcall_local32" 10940 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) 10941 (match_operand 1)) 10942 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10943 (simple_return)] 10944 "(INTVAL (operands[2]) & CALL_LONG) == 0" 10945{ 10946 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10947 output_asm_insn ("crxor 6,6,6", operands); 10948 10949 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10950 output_asm_insn ("creqv 6,6,6", operands); 10951 10952 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0"; 10953} 10954 [(set_attr "type" "branch") 10955 (set_attr "length" "4,8")]) 10956 10957(define_insn "*sibcall_local64" 10958 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) 10959 (match_operand 1)) 10960 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10961 (simple_return)] 10962 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" 10963{ 10964 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10965 output_asm_insn ("crxor 6,6,6", operands); 10966 10967 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10968 output_asm_insn ("creqv 6,6,6", operands); 10969 10970 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0"; 10971} 10972 [(set_attr "type" "branch") 10973 (set_attr "length" "4,8")]) 10974 10975(define_insn "*sibcall_value_local32" 10976 [(set (match_operand 0 "" "") 10977 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) 10978 (match_operand 2))) 10979 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10980 (simple_return)] 10981 "(INTVAL (operands[3]) & CALL_LONG) == 0" 10982{ 10983 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10984 output_asm_insn ("crxor 6,6,6", operands); 10985 10986 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10987 output_asm_insn ("creqv 6,6,6", operands); 10988 10989 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1"; 10990} 10991 [(set_attr "type" "branch") 10992 (set_attr "length" "4,8")]) 10993 10994(define_insn "*sibcall_value_local64" 10995 [(set (match_operand 0 "" "") 10996 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) 10997 (match_operand 2))) 10998 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10999 (simple_return)] 11000 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" 11001{ 11002 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11003 output_asm_insn ("crxor 6,6,6", operands); 11004 11005 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11006 output_asm_insn ("creqv 6,6,6", operands); 11007 11008 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1"; 11009} 11010 [(set_attr "type" "branch") 11011 (set_attr "length" "4,8")]) 11012 11013(define_insn "*sibcall_indirect_nonlocal_sysv<mode>" 11014 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 11015 (match_operand 1)) 11016 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 11017 (simple_return)] 11018 "DEFAULT_ABI == ABI_V4 11019 || DEFAULT_ABI == ABI_DARWIN" 11020{ 11021 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11022 output_asm_insn ("crxor 6,6,6", operands); 11023 11024 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11025 output_asm_insn ("creqv 6,6,6", operands); 11026 11027 return rs6000_indirect_sibcall_template (operands, 0); 11028} 11029 [(set_attr "type" "jmpreg") 11030 (set (attr "length") 11031 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") 11032 (match_test "which_alternative != 1")) 11033 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11034 (const_string "12") 11035 (ior (and (match_test "!rs6000_speculate_indirect_jumps") 11036 (match_test "which_alternative != 1")) 11037 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11038 (const_string "8")] 11039 (const_string "4")))]) 11040 11041(define_insn "*sibcall_nonlocal_sysv<mode>" 11042 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 11043 (match_operand 1)) 11044 (use (match_operand 2 "immediate_operand" "O,n")) 11045 (simple_return)] 11046 "(DEFAULT_ABI == ABI_DARWIN 11047 || DEFAULT_ABI == ABI_V4) 11048 && (INTVAL (operands[2]) & CALL_LONG) == 0" 11049{ 11050 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11051 output_asm_insn ("crxor 6,6,6", operands); 11052 11053 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11054 output_asm_insn ("creqv 6,6,6", operands); 11055 11056 return rs6000_sibcall_template (operands, 0); 11057} 11058 [(set_attr "type" "branch") 11059 (set_attr "length" "4,8")]) 11060 11061(define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>" 11062 [(set (match_operand 0 "" "") 11063 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 11064 (match_operand 2))) 11065 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 11066 (simple_return)] 11067 "DEFAULT_ABI == ABI_V4 11068 || DEFAULT_ABI == ABI_DARWIN" 11069{ 11070 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11071 output_asm_insn ("crxor 6,6,6", operands); 11072 11073 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11074 output_asm_insn ("creqv 6,6,6", operands); 11075 11076 return rs6000_indirect_sibcall_template (operands, 1); 11077} 11078 [(set_attr "type" "jmpreg") 11079 (set (attr "length") 11080 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") 11081 (match_test "which_alternative != 1")) 11082 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11083 (const_string "12") 11084 (ior (and (match_test "!rs6000_speculate_indirect_jumps") 11085 (match_test "which_alternative != 1")) 11086 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11087 (const_string "8")] 11088 (const_string "4")))]) 11089 11090(define_insn "*sibcall_value_nonlocal_sysv<mode>" 11091 [(set (match_operand 0 "" "") 11092 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) 11093 (match_operand 2))) 11094 (use (match_operand:SI 3 "immediate_operand" "O,n")) 11095 (simple_return)] 11096 "(DEFAULT_ABI == ABI_DARWIN 11097 || DEFAULT_ABI == ABI_V4) 11098 && (INTVAL (operands[3]) & CALL_LONG) == 0" 11099{ 11100 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11101 output_asm_insn ("crxor 6,6,6", operands); 11102 11103 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11104 output_asm_insn ("creqv 6,6,6", operands); 11105 11106 return rs6000_sibcall_template (operands, 1); 11107} 11108 [(set_attr "type" "branch") 11109 (set_attr "length" "4,8")]) 11110 11111;; AIX ABI sibling call patterns. 11112 11113(define_insn "*sibcall_aix<mode>" 11114 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) 11115 (match_operand 1)) 11116 (simple_return)] 11117 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11118{ 11119 if (which_alternative == 0) 11120 return rs6000_sibcall_template (operands, 0); 11121 else 11122 return "b%T0"; 11123} 11124 [(set_attr "type" "branch")]) 11125 11126(define_insn "*sibcall_value_aix<mode>" 11127 [(set (match_operand 0 "" "") 11128 (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) 11129 (match_operand 2))) 11130 (simple_return)] 11131 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11132{ 11133 if (which_alternative == 0) 11134 return rs6000_sibcall_template (operands, 1); 11135 else 11136 return "b%T1"; 11137} 11138 [(set_attr "type" "branch")]) 11139 11140(define_expand "sibcall_epilogue" 11141 [(use (const_int 0))] 11142 "" 11143{ 11144 if (!TARGET_SCHED_PROLOG) 11145 emit_insn (gen_blockage ()); 11146 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL); 11147 DONE; 11148}) 11149 11150;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 11151;; all of memory. This blocks insns from being moved across this point. 11152 11153(define_insn "blockage" 11154 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] 11155 "" 11156 "" 11157 [(set_attr "length" "0")]) 11158 11159(define_expand "probe_stack_address" 11160 [(use (match_operand 0 "address_operand"))] 11161 "" 11162{ 11163 operands[0] = gen_rtx_MEM (Pmode, operands[0]); 11164 MEM_VOLATILE_P (operands[0]) = 1; 11165 11166 if (TARGET_64BIT) 11167 emit_insn (gen_probe_stack_di (operands[0])); 11168 else 11169 emit_insn (gen_probe_stack_si (operands[0])); 11170 DONE; 11171}) 11172 11173(define_insn "probe_stack_<mode>" 11174 [(set (match_operand:P 0 "memory_operand" "=m") 11175 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))] 11176 "" 11177{ 11178 operands[1] = gen_rtx_REG (Pmode, 0); 11179 return "st<wd>%U0%X0 %1,%0"; 11180} 11181 [(set_attr "type" "store") 11182 (set (attr "update") 11183 (if_then_else (match_operand 0 "update_address_mem") 11184 (const_string "yes") 11185 (const_string "no"))) 11186 (set (attr "indexed") 11187 (if_then_else (match_operand 0 "indexed_address_mem") 11188 (const_string "yes") 11189 (const_string "no")))]) 11190 11191(define_insn "probe_stack_range<P:mode>" 11192 [(set (match_operand:P 0 "register_operand" "=&r") 11193 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 11194 (match_operand:P 2 "register_operand" "r") 11195 (match_operand:P 3 "register_operand" "r")] 11196 UNSPECV_PROBE_STACK_RANGE))] 11197 "" 11198 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);" 11199 [(set_attr "type" "three")]) 11200 11201;; Compare insns are next. Note that the RS/6000 has two types of compares, 11202;; signed & unsigned, and one type of branch. 11203;; 11204;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc 11205;; insns, and branches. 11206 11207(define_expand "cbranch<mode>4" 11208 [(use (match_operator 0 "comparison_operator" 11209 [(match_operand:GPR 1 "gpc_reg_operand") 11210 (match_operand:GPR 2 "reg_or_short_operand")])) 11211 (use (match_operand 3))] 11212 "" 11213{ 11214 /* Take care of the possibility that operands[2] might be negative but 11215 this might be a logical operation. That insn doesn't exist. */ 11216 if (CONST_INT_P (operands[2]) 11217 && INTVAL (operands[2]) < 0) 11218 { 11219 operands[2] = force_reg (<MODE>mode, operands[2]); 11220 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]), 11221 GET_MODE (operands[0]), 11222 operands[1], operands[2]); 11223 } 11224 11225 rs6000_emit_cbranch (<MODE>mode, operands); 11226 DONE; 11227}) 11228 11229(define_expand "cbranch<mode>4" 11230 [(use (match_operator 0 "comparison_operator" 11231 [(match_operand:FP 1 "gpc_reg_operand") 11232 (match_operand:FP 2 "gpc_reg_operand")])) 11233 (use (match_operand 3))] 11234 "" 11235{ 11236 rs6000_emit_cbranch (<MODE>mode, operands); 11237 DONE; 11238}) 11239 11240(define_expand "cstore<mode>4_signed" 11241 [(use (match_operator 1 "signed_comparison_operator" 11242 [(match_operand:P 2 "gpc_reg_operand") 11243 (match_operand:P 3 "gpc_reg_operand")])) 11244 (clobber (match_operand:P 0 "gpc_reg_operand"))] 11245 "" 11246{ 11247 enum rtx_code cond_code = GET_CODE (operands[1]); 11248 11249 rtx op0 = operands[0]; 11250 rtx op1 = operands[2]; 11251 rtx op2 = operands[3]; 11252 11253 if (cond_code == GE || cond_code == LT) 11254 { 11255 cond_code = swap_condition (cond_code); 11256 std::swap (op1, op2); 11257 } 11258 11259 rtx tmp1 = gen_reg_rtx (<MODE>mode); 11260 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11261 rtx tmp3 = gen_reg_rtx (<MODE>mode); 11262 11263 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11264 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh))); 11265 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh))); 11266 11267 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2)); 11268 11269 if (cond_code == LE) 11270 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2)); 11271 else 11272 { 11273 rtx tmp4 = gen_reg_rtx (<MODE>mode); 11274 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2)); 11275 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx)); 11276 } 11277 11278 DONE; 11279}) 11280 11281(define_expand "cstore<mode>4_unsigned" 11282 [(use (match_operator 1 "unsigned_comparison_operator" 11283 [(match_operand:P 2 "gpc_reg_operand") 11284 (match_operand:P 3 "reg_or_short_operand")])) 11285 (clobber (match_operand:P 0 "gpc_reg_operand"))] 11286 "" 11287{ 11288 enum rtx_code cond_code = GET_CODE (operands[1]); 11289 11290 rtx op0 = operands[0]; 11291 rtx op1 = operands[2]; 11292 rtx op2 = operands[3]; 11293 11294 if (cond_code == GEU || cond_code == LTU) 11295 { 11296 cond_code = swap_condition (cond_code); 11297 std::swap (op1, op2); 11298 } 11299 11300 if (!gpc_reg_operand (op1, <MODE>mode)) 11301 op1 = force_reg (<MODE>mode, op1); 11302 if (!reg_or_short_operand (op2, <MODE>mode)) 11303 op2 = force_reg (<MODE>mode, op2); 11304 11305 rtx tmp = gen_reg_rtx (<MODE>mode); 11306 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11307 11308 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2)); 11309 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2)); 11310 11311 if (cond_code == LEU) 11312 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx)); 11313 else 11314 emit_insn (gen_neg<mode>2 (op0, tmp2)); 11315 11316 DONE; 11317}) 11318 11319(define_expand "cstore_si_as_di" 11320 [(use (match_operator 1 "unsigned_comparison_operator" 11321 [(match_operand:SI 2 "gpc_reg_operand") 11322 (match_operand:SI 3 "reg_or_short_operand")])) 11323 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 11324 "" 11325{ 11326 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0; 11327 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1])); 11328 11329 operands[2] = force_reg (SImode, operands[2]); 11330 operands[3] = force_reg (SImode, operands[3]); 11331 rtx op1 = gen_reg_rtx (DImode); 11332 rtx op2 = gen_reg_rtx (DImode); 11333 convert_move (op1, operands[2], uns_flag); 11334 convert_move (op2, operands[3], uns_flag); 11335 11336 if (cond_code == GT || cond_code == LE) 11337 { 11338 cond_code = swap_condition (cond_code); 11339 std::swap (op1, op2); 11340 } 11341 11342 rtx tmp = gen_reg_rtx (DImode); 11343 rtx tmp2 = gen_reg_rtx (DImode); 11344 emit_insn (gen_subdi3 (tmp, op1, op2)); 11345 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63))); 11346 11347 rtx tmp3; 11348 switch (cond_code) 11349 { 11350 default: 11351 gcc_unreachable (); 11352 case LT: 11353 tmp3 = tmp2; 11354 break; 11355 case GE: 11356 tmp3 = gen_reg_rtx (DImode); 11357 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx)); 11358 break; 11359 } 11360 11361 convert_move (operands[0], tmp3, 1); 11362 11363 DONE; 11364}) 11365 11366(define_expand "cstore<mode>4_signed_imm" 11367 [(use (match_operator 1 "signed_comparison_operator" 11368 [(match_operand:GPR 2 "gpc_reg_operand") 11369 (match_operand:GPR 3 "immediate_operand")])) 11370 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11371 "" 11372{ 11373 bool invert = false; 11374 11375 enum rtx_code cond_code = GET_CODE (operands[1]); 11376 11377 rtx op0 = operands[0]; 11378 rtx op1 = operands[2]; 11379 HOST_WIDE_INT val = INTVAL (operands[3]); 11380 11381 if (cond_code == GE || cond_code == GT) 11382 { 11383 cond_code = reverse_condition (cond_code); 11384 invert = true; 11385 } 11386 11387 if (cond_code == LE) 11388 val++; 11389 11390 rtx tmp = gen_reg_rtx (<MODE>mode); 11391 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 11392 rtx x = gen_reg_rtx (<MODE>mode); 11393 if (val < 0) 11394 emit_insn (gen_and<mode>3 (x, op1, tmp)); 11395 else 11396 emit_insn (gen_ior<mode>3 (x, op1, tmp)); 11397 11398 if (invert) 11399 { 11400 rtx tmp = gen_reg_rtx (<MODE>mode); 11401 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 11402 x = tmp; 11403 } 11404 11405 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11406 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 11407 11408 DONE; 11409}) 11410 11411(define_expand "cstore<mode>4_unsigned_imm" 11412 [(use (match_operator 1 "unsigned_comparison_operator" 11413 [(match_operand:GPR 2 "gpc_reg_operand") 11414 (match_operand:GPR 3 "immediate_operand")])) 11415 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11416 "" 11417{ 11418 bool invert = false; 11419 11420 enum rtx_code cond_code = GET_CODE (operands[1]); 11421 11422 rtx op0 = operands[0]; 11423 rtx op1 = operands[2]; 11424 HOST_WIDE_INT val = INTVAL (operands[3]); 11425 11426 if (cond_code == GEU || cond_code == GTU) 11427 { 11428 cond_code = reverse_condition (cond_code); 11429 invert = true; 11430 } 11431 11432 if (cond_code == LEU) 11433 val++; 11434 11435 rtx tmp = gen_reg_rtx (<MODE>mode); 11436 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11437 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 11438 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1)); 11439 rtx x = gen_reg_rtx (<MODE>mode); 11440 if (val < 0) 11441 emit_insn (gen_ior<mode>3 (x, tmp, tmp2)); 11442 else 11443 emit_insn (gen_and<mode>3 (x, tmp, tmp2)); 11444 11445 if (invert) 11446 { 11447 rtx tmp = gen_reg_rtx (<MODE>mode); 11448 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 11449 x = tmp; 11450 } 11451 11452 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11453 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 11454 11455 DONE; 11456}) 11457 11458(define_expand "cstore<mode>4" 11459 [(use (match_operator 1 "comparison_operator" 11460 [(match_operand:GPR 2 "gpc_reg_operand") 11461 (match_operand:GPR 3 "reg_or_short_operand")])) 11462 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11463 "" 11464{ 11465 /* Expanding EQ and NE directly to some machine instructions does not help 11466 but does hurt combine. So don't. */ 11467 if (GET_CODE (operands[1]) == EQ) 11468 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3])); 11469 else if (<MODE>mode == Pmode 11470 && GET_CODE (operands[1]) == NE) 11471 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3])); 11472 else if (GET_CODE (operands[1]) == NE) 11473 { 11474 rtx tmp = gen_reg_rtx (<MODE>mode); 11475 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3])); 11476 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); 11477 } 11478 11479 /* If ISEL is fast, expand to it. */ 11480 else if (TARGET_ISEL) 11481 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx); 11482 11483 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu 11484 etc. combinations magically work out just right. */ 11485 else if (<MODE>mode == Pmode 11486 && unsigned_comparison_operator (operands[1], VOIDmode)) 11487 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1], 11488 operands[2], operands[3])); 11489 11490 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */ 11491 else if (<MODE>mode == SImode && Pmode == DImode) 11492 emit_insn (gen_cstore_si_as_di (operands[0], operands[1], 11493 operands[2], operands[3])); 11494 11495 /* For signed comparisons against a constant, we can do some simple 11496 bit-twiddling. */ 11497 else if (signed_comparison_operator (operands[1], VOIDmode) 11498 && CONST_INT_P (operands[3])) 11499 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1], 11500 operands[2], operands[3])); 11501 11502 /* And similarly for unsigned comparisons. */ 11503 else if (unsigned_comparison_operator (operands[1], VOIDmode) 11504 && CONST_INT_P (operands[3])) 11505 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1], 11506 operands[2], operands[3])); 11507 11508 /* We also do not want to use mfcr for signed comparisons. */ 11509 else if (<MODE>mode == Pmode 11510 && signed_comparison_operator (operands[1], VOIDmode)) 11511 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1], 11512 operands[2], operands[3])); 11513 11514 /* Everything else, use the mfcr brute force. */ 11515 else 11516 rs6000_emit_sCOND (<MODE>mode, operands); 11517 11518 DONE; 11519}) 11520 11521(define_expand "cstore<mode>4" 11522 [(use (match_operator 1 "comparison_operator" 11523 [(match_operand:FP 2 "gpc_reg_operand") 11524 (match_operand:FP 3 "gpc_reg_operand")])) 11525 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 11526 "" 11527{ 11528 rs6000_emit_sCOND (<MODE>mode, operands); 11529 DONE; 11530}) 11531 11532 11533(define_expand "stack_protect_set" 11534 [(match_operand 0 "memory_operand") 11535 (match_operand 1 "memory_operand")] 11536 "" 11537{ 11538 if (rs6000_stack_protector_guard == SSP_TLS) 11539 { 11540 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg); 11541 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset); 11542 rtx addr = gen_rtx_PLUS (Pmode, reg, offset); 11543 operands[1] = gen_rtx_MEM (Pmode, addr); 11544 } 11545 11546 if (TARGET_64BIT) 11547 emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); 11548 else 11549 emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); 11550 11551 DONE; 11552}) 11553 11554(define_insn "stack_protect_setsi" 11555 [(set (match_operand:SI 0 "memory_operand" "=m") 11556 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 11557 (set (match_scratch:SI 2 "=&r") (const_int 0))] 11558 "TARGET_32BIT" 11559 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0" 11560 [(set_attr "type" "three") 11561 (set_attr "length" "12")]) 11562 11563;; We can't use the prefixed attribute here because there are two memory 11564;; instructions. We can't split the insn due to the fact that this operation 11565;; needs to be done in one piece. 11566(define_insn "stack_protect_setdi" 11567 [(set (match_operand:DI 0 "memory_operand" "=Y") 11568 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET)) 11569 (set (match_scratch:DI 2 "=&r") (const_int 0))] 11570 "TARGET_64BIT" 11571{ 11572 if (prefixed_memory (operands[1], DImode)) 11573 output_asm_insn ("pld %2,%1", operands); 11574 else 11575 output_asm_insn ("ld%U1%X1 %2,%1", operands); 11576 11577 if (prefixed_memory (operands[0], DImode)) 11578 output_asm_insn ("pstd %2,%0", operands); 11579 else 11580 output_asm_insn ("std%U0%X0 %2,%0", operands); 11581 11582 return "li %2,0"; 11583} 11584 [(set_attr "type" "three") 11585 11586 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each 11587 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for 11588 ;; the LI 0 at the end. 11589 (set_attr "prefixed" "no") 11590 (set_attr "num_insns" "3") 11591 (set (attr "length") 11592 (cond [(and (match_operand 0 "prefixed_memory") 11593 (match_operand 1 "prefixed_memory")) 11594 (const_int 24) 11595 11596 (ior (match_operand 0 "prefixed_memory") 11597 (match_operand 1 "prefixed_memory")) 11598 (const_int 20)] 11599 11600 (const_int 12)))]) 11601 11602(define_expand "stack_protect_test" 11603 [(match_operand 0 "memory_operand") 11604 (match_operand 1 "memory_operand") 11605 (match_operand 2 "")] 11606 "" 11607{ 11608 rtx guard = operands[1]; 11609 11610 if (rs6000_stack_protector_guard == SSP_TLS) 11611 { 11612 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg); 11613 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset); 11614 rtx addr = gen_rtx_PLUS (Pmode, reg, offset); 11615 guard = gen_rtx_MEM (Pmode, addr); 11616 } 11617 11618 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST); 11619 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]); 11620 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]); 11621 emit_jump_insn (jump); 11622 11623 DONE; 11624}) 11625 11626(define_insn "stack_protect_testsi" 11627 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 11628 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m") 11629 (match_operand:SI 2 "memory_operand" "m,m")] 11630 UNSPEC_SP_TEST)) 11631 (set (match_scratch:SI 4 "=r,r") (const_int 0)) 11632 (clobber (match_scratch:SI 3 "=&r,&r"))] 11633 "TARGET_32BIT" 11634 "@ 11635 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 11636 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0" 11637 [(set_attr "length" "16,20")]) 11638 11639;; We can't use the prefixed attribute here because there are two memory 11640;; instructions. We can't split the insn due to the fact that this operation 11641;; needs to be done in one piece. 11642(define_insn "stack_protect_testdi" 11643 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 11644 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y") 11645 (match_operand:DI 2 "memory_operand" "Y,Y")] 11646 UNSPEC_SP_TEST)) 11647 (set (match_scratch:DI 4 "=r,r") (const_int 0)) 11648 (clobber (match_scratch:DI 3 "=&r,&r"))] 11649 "TARGET_64BIT" 11650{ 11651 if (prefixed_memory (operands[1], DImode)) 11652 output_asm_insn ("pld %3,%1", operands); 11653 else 11654 output_asm_insn ("ld%U1%X1 %3,%1", operands); 11655 11656 if (prefixed_memory (operands[2], DImode)) 11657 output_asm_insn ("pld %4,%2", operands); 11658 else 11659 output_asm_insn ("ld%U2%X2 %4,%2", operands); 11660 11661 if (which_alternative == 0) 11662 output_asm_insn ("xor. %3,%3,%4", operands); 11663 else 11664 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands); 11665 11666 return "li %4,0"; 11667} 11668 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each 11669 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or 11670 ;; 8 bytes to do the test. 11671 [(set_attr "prefixed" "no") 11672 (set_attr "num_insns" "4,5") 11673 (set (attr "length") 11674 (cond [(and (match_operand 1 "prefixed_memory") 11675 (match_operand 2 "prefixed_memory")) 11676 (if_then_else (eq_attr "alternative" "0") 11677 (const_int 28) 11678 (const_int 32)) 11679 11680 (ior (match_operand 1 "prefixed_memory") 11681 (match_operand 2 "prefixed_memory")) 11682 (if_then_else (eq_attr "alternative" "0") 11683 (const_int 20) 11684 (const_int 24))] 11685 11686 (if_then_else (eq_attr "alternative" "0") 11687 (const_int 16) 11688 (const_int 20))))]) 11689 11690 11691;; Here are the actual compare insns. 11692(define_insn "*cmp<mode>_signed" 11693 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 11694 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r") 11695 (match_operand:GPR 2 "reg_or_short_operand" "rI")))] 11696 "" 11697 "cmp<wd>%I2 %0,%1,%2" 11698 [(set_attr "type" "cmp")]) 11699 11700(define_insn "*cmp<mode>_unsigned" 11701 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") 11702 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r") 11703 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))] 11704 "" 11705 "cmpl<wd>%I2 %0,%1,%2" 11706 [(set_attr "type" "cmp")]) 11707 11708;; If we are comparing a register for equality with a large constant, 11709;; we can do this with an XOR followed by a compare. But this is profitable 11710;; only if the large constant is only used for the comparison (and in this 11711;; case we already have a register to reuse as scratch). 11712;; 11713;; For 64-bit registers, we could only do so if the constant's bit 15 is clear: 11714;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available. 11715 11716(define_peephole2 11717 [(set (match_operand:SI 0 "register_operand") 11718 (match_operand:SI 1 "logical_const_operand")) 11719 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator" 11720 [(match_dup 0) 11721 (match_operand:SI 2 "logical_const_operand")])) 11722 (set (match_operand:CC 4 "cc_reg_operand") 11723 (compare:CC (match_operand:SI 5 "gpc_reg_operand") 11724 (match_dup 0))) 11725 (set (pc) 11726 (if_then_else (match_operator 6 "equality_operator" 11727 [(match_dup 4) (const_int 0)]) 11728 (match_operand 7 "") 11729 (match_operand 8 "")))] 11730 "peep2_reg_dead_p (3, operands[0]) 11731 && peep2_reg_dead_p (4, operands[4]) 11732 && REGNO (operands[0]) != REGNO (operands[5])" 11733 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9))) 11734 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10))) 11735 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))] 11736 11737{ 11738 /* Get the constant we are comparing against, and see what it looks like 11739 when sign-extended from 16 to 32 bits. Then see what constant we could 11740 XOR with SEXTC to get the sign-extended value. */ 11741 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]), 11742 SImode, 11743 operands[1], operands[2]); 11744 HOST_WIDE_INT c = INTVAL (cnst); 11745 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000; 11746 HOST_WIDE_INT xorv = c ^ sextc; 11747 11748 operands[9] = GEN_INT (xorv); 11749 operands[10] = GEN_INT (sextc); 11750}) 11751 11752;; Only need to compare second words if first words equal 11753(define_insn "*cmp<mode>_internal1" 11754 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 11755 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 11756 (match_operand:IBM128 2 "gpc_reg_operand" "d")))] 11757 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) 11758 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 11759 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" 11760 [(set_attr "type" "fpcompare") 11761 (set_attr "length" "12")]) 11762 11763(define_insn_and_split "*cmp<IBM128:mode>_internal2" 11764 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 11765 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 11766 (match_operand:IBM128 2 "gpc_reg_operand" "d"))) 11767 (clobber (match_scratch:DF 3 "=d")) 11768 (clobber (match_scratch:DF 4 "=d")) 11769 (clobber (match_scratch:DF 5 "=d")) 11770 (clobber (match_scratch:DF 6 "=d")) 11771 (clobber (match_scratch:DF 7 "=d")) 11772 (clobber (match_scratch:DF 8 "=d")) 11773 (clobber (match_scratch:DF 9 "=d")) 11774 (clobber (match_scratch:DF 10 "=d")) 11775 (clobber (match_scratch:GPR 11 "=b"))] 11776 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode) 11777 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 11778 "#" 11779 "&& reload_completed" 11780 [(set (match_dup 3) (match_dup 14)) 11781 (set (match_dup 4) (match_dup 15)) 11782 (set (match_dup 9) (abs:DF (match_dup 5))) 11783 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) 11784 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) 11785 (label_ref (match_dup 12)) 11786 (pc))) 11787 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) 11788 (set (pc) (label_ref (match_dup 13))) 11789 (match_dup 12) 11790 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) 11791 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) 11792 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) 11793 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4))) 11794 (match_dup 13)] 11795{ 11796 REAL_VALUE_TYPE rv; 11797 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 11798 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 11799 11800 operands[5] = simplify_gen_subreg (DFmode, operands[1], 11801 <IBM128:MODE>mode, hi_word); 11802 operands[6] = simplify_gen_subreg (DFmode, operands[1], 11803 <IBM128:MODE>mode, lo_word); 11804 operands[7] = simplify_gen_subreg (DFmode, operands[2], 11805 <IBM128:MODE>mode, hi_word); 11806 operands[8] = simplify_gen_subreg (DFmode, operands[2], 11807 <IBM128:MODE>mode, lo_word); 11808 operands[12] = gen_label_rtx (); 11809 operands[13] = gen_label_rtx (); 11810 real_inf (&rv); 11811 operands[14] = force_const_mem (DFmode, 11812 const_double_from_real_value (rv, DFmode)); 11813 operands[15] = force_const_mem (DFmode, 11814 const_double_from_real_value (dconst0, 11815 DFmode)); 11816 if (TARGET_TOC) 11817 { 11818 rtx tocref; 11819 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]); 11820 operands[14] = gen_const_mem (DFmode, tocref); 11821 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]); 11822 operands[15] = gen_const_mem (DFmode, tocref); 11823 set_mem_alias_set (operands[14], get_TOC_alias_set ()); 11824 set_mem_alias_set (operands[15], get_TOC_alias_set ()); 11825 } 11826}) 11827 11828;; Now we have the scc insns. We can do some combinations because of the 11829;; way the machine works. 11830;; 11831;; Note that this is probably faster if we can put an insn between the 11832;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most 11833;; cases the insns below which don't use an intermediate CR field will 11834;; be used instead. 11835(define_insn "set<mode>_cc" 11836 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11837 (match_operator:GPR 1 "scc_comparison_operator" 11838 [(match_operand 2 "cc_reg_operand" "y") 11839 (const_int 0)]))] 11840 "" 11841 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" 11842 [(set (attr "type") 11843 (cond [(match_test "TARGET_MFCRF") 11844 (const_string "mfcrf") 11845 ] 11846 (const_string "mfcr"))) 11847 (set_attr "length" "8")]) 11848 11849 11850(define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu]) 11851(define_code_attr UNS [(eq "CC") 11852 (ne "CC") 11853 (lt "CC") (ltu "CCUNS") 11854 (gt "CC") (gtu "CCUNS") 11855 (le "CC") (leu "CCUNS") 11856 (ge "CC") (geu "CCUNS")]) 11857(define_code_attr UNSu_ [(eq "") 11858 (ne "") 11859 (lt "") (ltu "u_") 11860 (gt "") (gtu "u_") 11861 (le "") (leu "u_") 11862 (ge "") (geu "u_")]) 11863(define_code_attr UNSIK [(eq "I") 11864 (ne "I") 11865 (lt "I") (ltu "K") 11866 (gt "I") (gtu "K") 11867 (le "I") (leu "K") 11868 (ge "I") (geu "K")]) 11869 11870(define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel" 11871 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11872 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r") 11873 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>"))) 11874 (clobber (match_scratch:GPR 3 "=r")) 11875 (clobber (match_scratch:GPR 4 "=r")) 11876 (clobber (match_scratch:<UNS> 5 "=y"))] 11877 "TARGET_ISEL 11878 && !(<CODE> == EQ && operands[2] == const0_rtx) 11879 && !(<CODE> == NE && operands[2] == const0_rtx 11880 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)" 11881 "#" 11882 "&& 1" 11883 [(pc)] 11884{ 11885 rtx_code code = <CODE>; 11886 if (CONST_INT_P (operands[2]) && code != EQ && code != NE) 11887 { 11888 HOST_WIDE_INT val = INTVAL (operands[2]); 11889 if (code == LT && val != -0x8000) 11890 { 11891 code = LE; 11892 val--; 11893 } 11894 if (code == GT && val != 0x7fff) 11895 { 11896 code = GE; 11897 val++; 11898 } 11899 if (code == LTU && val != 0) 11900 { 11901 code = LEU; 11902 val--; 11903 } 11904 if (code == GTU && val != 0xffff) 11905 { 11906 code = GEU; 11907 val++; 11908 } 11909 operands[2] = GEN_INT (val); 11910 } 11911 11912 if (code == NE || code == LE || code == GE || code == LEU || code == GEU) 11913 operands[3] = const0_rtx; 11914 else 11915 { 11916 if (GET_CODE (operands[3]) == SCRATCH) 11917 operands[3] = gen_reg_rtx (<GPR:MODE>mode); 11918 emit_move_insn (operands[3], const0_rtx); 11919 } 11920 11921 if (GET_CODE (operands[4]) == SCRATCH) 11922 operands[4] = gen_reg_rtx (<GPR:MODE>mode); 11923 emit_move_insn (operands[4], const1_rtx); 11924 11925 if (GET_CODE (operands[5]) == SCRATCH) 11926 operands[5] = gen_reg_rtx (<UNS>mode); 11927 11928 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]); 11929 emit_insn (gen_rtx_SET (operands[5], c1)); 11930 11931 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx); 11932 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]); 11933 emit_move_insn (operands[0], x); 11934 11935 DONE; 11936} 11937 [(set (attr "cost") 11938 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ) 11939 || <CODE> == NE 11940 || <CODE> == LE || <CODE> == GE 11941 || <CODE> == LEU || <CODE> == GEU") 11942 (const_string "9") 11943 (const_string "10")))]) 11944 11945(define_mode_attr scc_eq_op2 [(SI "rKLI") 11946 (DI "rKJI")]) 11947 11948(define_expand "eq<mode>3" 11949 [(parallel [ 11950 (set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11951 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 11952 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 11953 (clobber (match_scratch:GPR 3 "=r")) 11954 (clobber (match_scratch:GPR 4 "=r"))])] 11955 "" 11956{ 11957 if (TARGET_ISEL && operands[2] != const0_rtx) 11958 { 11959 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1], 11960 operands[2])); 11961 DONE; 11962 } 11963}) 11964 11965(define_insn_and_split "*eq<mode>3" 11966 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11967 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 11968 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 11969 (clobber (match_scratch:GPR 3 "=r")) 11970 (clobber (match_scratch:GPR 4 "=r"))] 11971 "!(TARGET_ISEL && operands[2] != const0_rtx)" 11972 "#" 11973 "&& 1" 11974 [(set (match_dup 4) 11975 (clz:GPR (match_dup 3))) 11976 (set (match_dup 0) 11977 (lshiftrt:GPR (match_dup 4) 11978 (match_dup 5)))] 11979{ 11980 operands[3] = rs6000_emit_eqne (<MODE>mode, 11981 operands[1], operands[2], operands[3]); 11982 11983 if (GET_CODE (operands[4]) == SCRATCH) 11984 operands[4] = gen_reg_rtx (<MODE>mode); 11985 11986 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode))); 11987} 11988 [(set (attr "length") 11989 (if_then_else (match_test "operands[2] == const0_rtx") 11990 (const_string "8") 11991 (const_string "12")))]) 11992 11993(define_expand "ne<mode>3" 11994 [(parallel [ 11995 (set (match_operand:P 0 "gpc_reg_operand" "=r") 11996 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 11997 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) 11998 (clobber (match_scratch:P 3 "=r")) 11999 (clobber (match_scratch:P 4 "=r")) 12000 (clobber (reg:P CA_REGNO))])] 12001 "" 12002{ 12003 if (TARGET_ISEL && operands[2] != const0_rtx) 12004 { 12005 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1], 12006 operands[2])); 12007 DONE; 12008 } 12009}) 12010 12011(define_insn_and_split "*ne<mode>3" 12012 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12013 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12014 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) 12015 (clobber (match_scratch:P 3 "=r")) 12016 (clobber (match_scratch:P 4 "=r")) 12017 (clobber (reg:P CA_REGNO))] 12018 "!(TARGET_ISEL && operands[2] != const0_rtx)" 12019 "#" 12020 "&& 1" 12021 [(parallel [(set (match_dup 4) 12022 (plus:P (match_dup 3) 12023 (const_int -1))) 12024 (set (reg:P CA_REGNO) 12025 (ne:P (match_dup 3) 12026 (const_int 0)))]) 12027 (parallel [(set (match_dup 0) 12028 (plus:P (plus:P (not:P (match_dup 4)) 12029 (reg:P CA_REGNO)) 12030 (match_dup 3))) 12031 (clobber (reg:P CA_REGNO))])] 12032{ 12033 operands[3] = rs6000_emit_eqne (<MODE>mode, 12034 operands[1], operands[2], operands[3]); 12035 12036 if (GET_CODE (operands[4]) == SCRATCH) 12037 operands[4] = gen_reg_rtx (<MODE>mode); 12038} 12039 [(set (attr "length") 12040 (if_then_else (match_test "operands[2] == const0_rtx") 12041 (const_string "8") 12042 (const_string "12")))]) 12043 12044(define_insn_and_split "*neg_eq_<mode>" 12045 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12046 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12047 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12048 (clobber (match_scratch:P 3 "=r")) 12049 (clobber (match_scratch:P 4 "=r")) 12050 (clobber (reg:P CA_REGNO))] 12051 "" 12052 "#" 12053 "" 12054 [(parallel [(set (match_dup 4) 12055 (plus:P (match_dup 3) 12056 (const_int -1))) 12057 (set (reg:P CA_REGNO) 12058 (ne:P (match_dup 3) 12059 (const_int 0)))]) 12060 (parallel [(set (match_dup 0) 12061 (plus:P (reg:P CA_REGNO) 12062 (const_int -1))) 12063 (clobber (reg:P CA_REGNO))])] 12064{ 12065 operands[3] = rs6000_emit_eqne (<MODE>mode, 12066 operands[1], operands[2], operands[3]); 12067 12068 if (GET_CODE (operands[4]) == SCRATCH) 12069 operands[4] = gen_reg_rtx (<MODE>mode); 12070} 12071 [(set (attr "length") 12072 (if_then_else (match_test "operands[2] == const0_rtx") 12073 (const_string "8") 12074 (const_string "12")))]) 12075 12076(define_insn_and_split "*neg_ne_<mode>" 12077 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12078 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12079 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12080 (clobber (match_scratch:P 3 "=r")) 12081 (clobber (match_scratch:P 4 "=r")) 12082 (clobber (reg:P CA_REGNO))] 12083 "" 12084 "#" 12085 "" 12086 [(parallel [(set (match_dup 4) 12087 (neg:P (match_dup 3))) 12088 (set (reg:P CA_REGNO) 12089 (eq:P (match_dup 3) 12090 (const_int 0)))]) 12091 (parallel [(set (match_dup 0) 12092 (plus:P (reg:P CA_REGNO) 12093 (const_int -1))) 12094 (clobber (reg:P CA_REGNO))])] 12095{ 12096 operands[3] = rs6000_emit_eqne (<MODE>mode, 12097 operands[1], operands[2], operands[3]); 12098 12099 if (GET_CODE (operands[4]) == SCRATCH) 12100 operands[4] = gen_reg_rtx (<MODE>mode); 12101} 12102 [(set (attr "length") 12103 (if_then_else (match_test "operands[2] == const0_rtx") 12104 (const_string "8") 12105 (const_string "12")))]) 12106 12107(define_insn_and_split "*plus_eq_<mode>" 12108 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12109 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12110 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 12111 (match_operand:P 3 "gpc_reg_operand" "r"))) 12112 (clobber (match_scratch:P 4 "=r")) 12113 (clobber (match_scratch:P 5 "=r")) 12114 (clobber (reg:P CA_REGNO))] 12115 "" 12116 "#" 12117 "" 12118 [(parallel [(set (match_dup 5) 12119 (neg:P (match_dup 4))) 12120 (set (reg:P CA_REGNO) 12121 (eq:P (match_dup 4) 12122 (const_int 0)))]) 12123 (parallel [(set (match_dup 0) 12124 (plus:P (match_dup 3) 12125 (reg:P CA_REGNO))) 12126 (clobber (reg:P CA_REGNO))])] 12127{ 12128 operands[4] = rs6000_emit_eqne (<MODE>mode, 12129 operands[1], operands[2], operands[4]); 12130 12131 if (GET_CODE (operands[5]) == SCRATCH) 12132 operands[5] = gen_reg_rtx (<MODE>mode); 12133} 12134 [(set (attr "length") 12135 (if_then_else (match_test "operands[2] == const0_rtx") 12136 (const_string "8") 12137 (const_string "12")))]) 12138 12139(define_insn_and_split "*plus_ne_<mode>" 12140 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12141 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12142 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 12143 (match_operand:P 3 "gpc_reg_operand" "r"))) 12144 (clobber (match_scratch:P 4 "=r")) 12145 (clobber (match_scratch:P 5 "=r")) 12146 (clobber (reg:P CA_REGNO))] 12147 "" 12148 "#" 12149 "" 12150 [(parallel [(set (match_dup 5) 12151 (plus:P (match_dup 4) 12152 (const_int -1))) 12153 (set (reg:P CA_REGNO) 12154 (ne:P (match_dup 4) 12155 (const_int 0)))]) 12156 (parallel [(set (match_dup 0) 12157 (plus:P (match_dup 3) 12158 (reg:P CA_REGNO))) 12159 (clobber (reg:P CA_REGNO))])] 12160{ 12161 operands[4] = rs6000_emit_eqne (<MODE>mode, 12162 operands[1], operands[2], operands[4]); 12163 12164 if (GET_CODE (operands[5]) == SCRATCH) 12165 operands[5] = gen_reg_rtx (<MODE>mode); 12166} 12167 [(set (attr "length") 12168 (if_then_else (match_test "operands[2] == const0_rtx") 12169 (const_string "8") 12170 (const_string "12")))]) 12171 12172(define_insn_and_split "*minus_eq_<mode>" 12173 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12174 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 12175 (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12176 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12177 (clobber (match_scratch:P 4 "=r")) 12178 (clobber (match_scratch:P 5 "=r")) 12179 (clobber (reg:P CA_REGNO))] 12180 "" 12181 "#" 12182 "" 12183 [(parallel [(set (match_dup 5) 12184 (plus:P (match_dup 4) 12185 (const_int -1))) 12186 (set (reg:P CA_REGNO) 12187 (ne:P (match_dup 4) 12188 (const_int 0)))]) 12189 (parallel [(set (match_dup 0) 12190 (plus:P (plus:P (match_dup 3) 12191 (reg:P CA_REGNO)) 12192 (const_int -1))) 12193 (clobber (reg:P CA_REGNO))])] 12194{ 12195 operands[4] = rs6000_emit_eqne (<MODE>mode, 12196 operands[1], operands[2], operands[4]); 12197 12198 if (GET_CODE (operands[5]) == SCRATCH) 12199 operands[5] = gen_reg_rtx (<MODE>mode); 12200} 12201 [(set (attr "length") 12202 (if_then_else (match_test "operands[2] == const0_rtx") 12203 (const_string "8") 12204 (const_string "12")))]) 12205 12206(define_insn_and_split "*minus_ne_<mode>" 12207 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12208 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 12209 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12210 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12211 (clobber (match_scratch:P 4 "=r")) 12212 (clobber (match_scratch:P 5 "=r")) 12213 (clobber (reg:P CA_REGNO))] 12214 "" 12215 "#" 12216 "" 12217 [(parallel [(set (match_dup 5) 12218 (neg:P (match_dup 4))) 12219 (set (reg:P CA_REGNO) 12220 (eq:P (match_dup 4) 12221 (const_int 0)))]) 12222 (parallel [(set (match_dup 0) 12223 (plus:P (plus:P (match_dup 3) 12224 (reg:P CA_REGNO)) 12225 (const_int -1))) 12226 (clobber (reg:P CA_REGNO))])] 12227{ 12228 operands[4] = rs6000_emit_eqne (<MODE>mode, 12229 operands[1], operands[2], operands[4]); 12230 12231 if (GET_CODE (operands[5]) == SCRATCH) 12232 operands[5] = gen_reg_rtx (<MODE>mode); 12233} 12234 [(set (attr "length") 12235 (if_then_else (match_test "operands[2] == const0_rtx") 12236 (const_string "8") 12237 (const_string "12")))]) 12238 12239(define_insn_and_split "*eqsi3_ext<mode>" 12240 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 12241 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 12242 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 12243 (clobber (match_scratch:SI 3 "=r")) 12244 (clobber (match_scratch:SI 4 "=r"))] 12245 "" 12246 "#" 12247 "" 12248 [(set (match_dup 4) 12249 (clz:SI (match_dup 3))) 12250 (set (match_dup 0) 12251 (zero_extend:EXTSI 12252 (lshiftrt:SI (match_dup 4) 12253 (const_int 5))))] 12254{ 12255 operands[3] = rs6000_emit_eqne (SImode, 12256 operands[1], operands[2], operands[3]); 12257 12258 if (GET_CODE (operands[4]) == SCRATCH) 12259 operands[4] = gen_reg_rtx (SImode); 12260} 12261 [(set (attr "length") 12262 (if_then_else (match_test "operands[2] == const0_rtx") 12263 (const_string "8") 12264 (const_string "12")))]) 12265 12266(define_insn_and_split "*nesi3_ext<mode>" 12267 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 12268 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 12269 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 12270 (clobber (match_scratch:SI 3 "=r")) 12271 (clobber (match_scratch:SI 4 "=r")) 12272 (clobber (match_scratch:EXTSI 5 "=r"))] 12273 "!TARGET_ISEL" 12274 "#" 12275 "&& 1" 12276 [(set (match_dup 4) 12277 (clz:SI (match_dup 3))) 12278 (set (match_dup 5) 12279 (zero_extend:EXTSI 12280 (lshiftrt:SI (match_dup 4) 12281 (const_int 5)))) 12282 (set (match_dup 0) 12283 (xor:EXTSI (match_dup 5) 12284 (const_int 1)))] 12285{ 12286 operands[3] = rs6000_emit_eqne (SImode, 12287 operands[1], operands[2], operands[3]); 12288 12289 if (GET_CODE (operands[4]) == SCRATCH) 12290 operands[4] = gen_reg_rtx (SImode); 12291 if (GET_CODE (operands[5]) == SCRATCH) 12292 operands[5] = gen_reg_rtx (<MODE>mode); 12293} 12294 [(set (attr "length") 12295 (if_then_else (match_test "operands[2] == const0_rtx") 12296 (const_string "12") 12297 (const_string "16")))]) 12298 12299 12300(define_code_iterator fp_rev [ordered ne unle unge]) 12301(define_code_iterator fp_two [ltgt le ge unlt ungt uneq]) 12302 12303(define_insn_and_split "*<code><mode>_cc" 12304 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12305 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y") 12306 (const_int 0)))] 12307 "!flag_finite_math_only" 12308 "#" 12309 "&& 1" 12310 [(pc)] 12311{ 12312 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>); 12313 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx); 12314 rtx tmp = gen_reg_rtx (<MODE>mode); 12315 emit_move_insn (tmp, eq); 12316 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); 12317 DONE; 12318} 12319 [(set_attr "length" "12")]) 12320 12321(define_insn_and_split "*<code><mode>_cc" 12322 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12323 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y") 12324 (const_int 0)))] 12325 "!flag_finite_math_only" 12326 "#" 12327 "&& 1" 12328 [(pc)] 12329{ 12330 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]); 12331 12332 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx)); 12333 DONE; 12334} 12335 [(set_attr "length" "12")]) 12336 12337;; Conditional branches. 12338;; These either are a single bc insn, or a bc around a b. 12339 12340(define_insn "*cbranch" 12341 [(set (pc) 12342 (if_then_else (match_operator 1 "branch_comparison_operator" 12343 [(match_operand 2 "cc_reg_operand" "y") 12344 (const_int 0)]) 12345 (label_ref (match_operand 0)) 12346 (pc)))] 12347 "" 12348{ 12349 return output_cbranch (operands[1], "%l0", 0, insn); 12350} 12351 [(set_attr "type" "branch") 12352 (set (attr "length") 12353 (if_then_else (and (ge (minus (match_dup 0) (pc)) 12354 (const_int -32768)) 12355 (lt (minus (match_dup 0) (pc)) 12356 (const_int 32764))) 12357 (const_int 4) 12358 (const_int 8)))]) 12359 12360(define_insn_and_split "*cbranch_2insn" 12361 [(set (pc) 12362 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator" 12363 [(match_operand 2 "cc_reg_operand" "y") 12364 (const_int 0)]) 12365 (label_ref (match_operand 0)) 12366 (pc)))] 12367 "!flag_finite_math_only" 12368 "#" 12369 "&& 1" 12370 [(pc)] 12371{ 12372 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]); 12373 12374 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0); 12375 12376 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]); 12377 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx); 12378 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx); 12379 emit_jump_insn (gen_rtx_SET (pc_rtx, ite)); 12380 12381 if (note) 12382 { 12383 profile_probability prob 12384 = profile_probability::from_reg_br_prob_note (XINT (note, 0)); 12385 12386 add_reg_br_prob_note (get_last_insn (), prob); 12387 } 12388 12389 DONE; 12390} 12391 [(set_attr "type" "branch") 12392 (set (attr "length") 12393 (if_then_else (and (ge (minus (match_dup 0) (pc)) 12394 (const_int -32764)) 12395 (lt (minus (match_dup 0) (pc)) 12396 (const_int 32760))) 12397 (const_int 8) 12398 (const_int 16)))]) 12399 12400;; Conditional return. 12401(define_insn "*creturn" 12402 [(set (pc) 12403 (if_then_else (match_operator 0 "branch_comparison_operator" 12404 [(match_operand 1 "cc_reg_operand" "y") 12405 (const_int 0)]) 12406 (any_return) 12407 (pc)))] 12408 "<return_pred>" 12409{ 12410 return output_cbranch (operands[0], NULL, 0, insn); 12411} 12412 [(set_attr "type" "jmpreg")]) 12413 12414;; Logic on condition register values. 12415 12416; This pattern matches things like 12417; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0)) 12418; (eq:SI (reg:CCFP 68) (const_int 0))) 12419; (const_int 1))) 12420; which are generated by the branch logic. 12421; Prefer destructive operations where BT = BB (for crXX BT,BA,BB) 12422 12423(define_insn "@cceq_ior_compare_<mode>" 12424 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12425 (compare:CCEQ (match_operator:GPR 1 "boolean_operator" 12426 [(match_operator:GPR 2 12427 "branch_positive_comparison_operator" 12428 [(match_operand 3 12429 "cc_reg_operand" "y,y") 12430 (const_int 0)]) 12431 (match_operator:GPR 4 12432 "branch_positive_comparison_operator" 12433 [(match_operand 5 12434 "cc_reg_operand" "0,y") 12435 (const_int 0)])]) 12436 (const_int 1)))] 12437 "" 12438 "cr%q1 %E0,%j2,%j4" 12439 [(set_attr "type" "cr_logical") 12440 (set_attr "cr_logical_3op" "no,yes")]) 12441 12442; Why is the constant -1 here, but 1 in the previous pattern? 12443; Because ~1 has all but the low bit set. 12444(define_insn "cceq_ior_compare_complement" 12445 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12446 (compare:CCEQ (match_operator:SI 1 "boolean_operator" 12447 [(not:SI (match_operator:SI 2 12448 "branch_positive_comparison_operator" 12449 [(match_operand 3 12450 "cc_reg_operand" "y,y") 12451 (const_int 0)])) 12452 (match_operator:SI 4 12453 "branch_positive_comparison_operator" 12454 [(match_operand 5 12455 "cc_reg_operand" "0,y") 12456 (const_int 0)])]) 12457 (const_int -1)))] 12458 "" 12459 "cr%q1 %E0,%j2,%j4" 12460 [(set_attr "type" "cr_logical") 12461 (set_attr "cr_logical_3op" "no,yes")]) 12462 12463(define_insn "@cceq_rev_compare_<mode>" 12464 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12465 (compare:CCEQ (match_operator:GPR 1 12466 "branch_positive_comparison_operator" 12467 [(match_operand 2 12468 "cc_reg_operand" "0,y") 12469 (const_int 0)]) 12470 (const_int 0)))] 12471 "" 12472 "crnot %E0,%j1" 12473 [(set_attr "type" "cr_logical") 12474 (set_attr "cr_logical_3op" "no,yes")]) 12475 12476;; If we are comparing the result of two comparisons, this can be done 12477;; using creqv or crxor. 12478 12479(define_insn_and_split "" 12480 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y") 12481 (compare:CCEQ (match_operator 1 "branch_comparison_operator" 12482 [(match_operand 2 "cc_reg_operand" "y") 12483 (const_int 0)]) 12484 (match_operator 3 "branch_comparison_operator" 12485 [(match_operand 4 "cc_reg_operand" "y") 12486 (const_int 0)])))] 12487 "" 12488 "#" 12489 "" 12490 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3)) 12491 (match_dup 5)))] 12492{ 12493 int positive_1, positive_2; 12494 12495 positive_1 = branch_positive_comparison_operator (operands[1], 12496 GET_MODE (operands[1])); 12497 positive_2 = branch_positive_comparison_operator (operands[3], 12498 GET_MODE (operands[3])); 12499 12500 if (! positive_1) 12501 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]), 12502 GET_CODE (operands[1])), 12503 SImode, 12504 operands[2], const0_rtx); 12505 else if (GET_MODE (operands[1]) != SImode) 12506 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, 12507 operands[2], const0_rtx); 12508 12509 if (! positive_2) 12510 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]), 12511 GET_CODE (operands[3])), 12512 SImode, 12513 operands[4], const0_rtx); 12514 else if (GET_MODE (operands[3]) != SImode) 12515 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, 12516 operands[4], const0_rtx); 12517 12518 if (positive_1 == positive_2) 12519 { 12520 operands[1] = gen_rtx_NOT (SImode, operands[1]); 12521 operands[5] = constm1_rtx; 12522 } 12523 else 12524 { 12525 operands[5] = const1_rtx; 12526 } 12527}) 12528 12529;; Unconditional branch and return. 12530 12531(define_insn "jump" 12532 [(set (pc) 12533 (label_ref (match_operand 0)))] 12534 "" 12535 "b %l0" 12536 [(set_attr "type" "branch")]) 12537 12538(define_insn "<return_str>return" 12539 [(any_return)] 12540 "<return_pred>" 12541 "blr" 12542 [(set_attr "type" "jmpreg")]) 12543 12544(define_expand "indirect_jump" 12545 [(set (pc) (match_operand 0 "register_operand"))] 12546 "" 12547{ 12548 if (!rs6000_speculate_indirect_jumps) { 12549 rtx ccreg = gen_reg_rtx (CCmode); 12550 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg)); 12551 DONE; 12552 } 12553}) 12554 12555(define_insn "*indirect_jump<mode>" 12556 [(set (pc) 12557 (match_operand:P 0 "register_operand" "c,*l"))] 12558 "rs6000_speculate_indirect_jumps" 12559 "b%T0" 12560 [(set_attr "type" "jmpreg")]) 12561 12562(define_insn "@indirect_jump<mode>_nospec" 12563 [(set (pc) (match_operand:P 0 "register_operand" "c,*l")) 12564 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))] 12565 "!rs6000_speculate_indirect_jumps" 12566 "crset %E1\;beq%T0- %1\;b $" 12567 [(set_attr "type" "jmpreg") 12568 (set_attr "length" "12")]) 12569 12570;; Table jump for switch statements: 12571(define_expand "tablejump" 12572 [(use (match_operand 0)) 12573 (use (label_ref (match_operand 1)))] 12574 "" 12575{ 12576 if (rs6000_speculate_indirect_jumps) 12577 { 12578 if (TARGET_32BIT) 12579 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); 12580 else 12581 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); 12582 } 12583 else 12584 { 12585 rtx ccreg = gen_reg_rtx (CCmode); 12586 rtx jump; 12587 if (TARGET_32BIT) 12588 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg); 12589 else 12590 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg); 12591 emit_jump_insn (jump); 12592 } 12593 DONE; 12594}) 12595 12596(define_expand "tablejumpsi" 12597 [(set (match_dup 3) 12598 (plus:SI (match_operand:SI 0) 12599 (match_dup 2))) 12600 (parallel [(set (pc) 12601 (match_dup 3)) 12602 (use (label_ref (match_operand 1)))])] 12603 "TARGET_32BIT && rs6000_speculate_indirect_jumps" 12604{ 12605 operands[0] = force_reg (SImode, operands[0]); 12606 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); 12607 operands[3] = gen_reg_rtx (SImode); 12608}) 12609 12610(define_expand "tablejumpsi_nospec" 12611 [(set (match_dup 4) 12612 (plus:SI (match_operand:SI 0) 12613 (match_dup 3))) 12614 (parallel [(set (pc) 12615 (match_dup 4)) 12616 (use (label_ref (match_operand 1))) 12617 (clobber (match_operand 2))])] 12618 "TARGET_32BIT && !rs6000_speculate_indirect_jumps" 12619{ 12620 operands[0] = force_reg (SImode, operands[0]); 12621 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); 12622 operands[4] = gen_reg_rtx (SImode); 12623}) 12624 12625(define_expand "tablejumpdi" 12626 [(set (match_dup 4) 12627 (sign_extend:DI (match_operand:SI 0 "lwa_operand"))) 12628 (set (match_dup 3) 12629 (plus:DI (match_dup 4) 12630 (match_dup 2))) 12631 (parallel [(set (pc) 12632 (match_dup 3)) 12633 (use (label_ref (match_operand 1)))])] 12634 "TARGET_64BIT && rs6000_speculate_indirect_jumps" 12635{ 12636 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); 12637 operands[3] = gen_reg_rtx (DImode); 12638 operands[4] = gen_reg_rtx (DImode); 12639}) 12640 12641(define_expand "tablejumpdi_nospec" 12642 [(set (match_dup 5) 12643 (sign_extend:DI (match_operand:SI 0 "lwa_operand"))) 12644 (set (match_dup 4) 12645 (plus:DI (match_dup 5) 12646 (match_dup 3))) 12647 (parallel [(set (pc) 12648 (match_dup 4)) 12649 (use (label_ref (match_operand 1))) 12650 (clobber (match_operand 2))])] 12651 "TARGET_64BIT && !rs6000_speculate_indirect_jumps" 12652{ 12653 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); 12654 operands[4] = gen_reg_rtx (DImode); 12655 operands[5] = gen_reg_rtx (DImode); 12656}) 12657 12658(define_insn "*tablejump<mode>_internal1" 12659 [(set (pc) 12660 (match_operand:P 0 "register_operand" "c,*l")) 12661 (use (label_ref (match_operand 1)))] 12662 "rs6000_speculate_indirect_jumps" 12663 "b%T0" 12664 [(set_attr "type" "jmpreg")]) 12665 12666(define_insn "*tablejump<mode>_internal1_nospec" 12667 [(set (pc) 12668 (match_operand:P 0 "register_operand" "c,*l")) 12669 (use (label_ref (match_operand 1))) 12670 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))] 12671 "!rs6000_speculate_indirect_jumps" 12672 "crset %E2\;beq%T0- %2\;b $" 12673 [(set_attr "type" "jmpreg") 12674 (set_attr "length" "12")]) 12675 12676(define_insn "nop" 12677 [(unspec [(const_int 0)] UNSPEC_NOP)] 12678 "" 12679 "nop") 12680 12681(define_insn "group_ending_nop" 12682 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)] 12683 "" 12684{ 12685 operands[0] = gen_rtx_REG (Pmode, 12686 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2); 12687 return "ori %0,%0,0"; 12688}) 12689 12690(define_insn "speculation_barrier" 12691 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)] 12692 "" 12693{ 12694 operands[0] = gen_rtx_REG (Pmode, 31); 12695 return "ori %0,%0,0"; 12696}) 12697 12698;; Define the subtract-one-and-jump insns, starting with the template 12699;; so loop.c knows what to generate. 12700 12701(define_expand "doloop_end" 12702 [(use (match_operand 0)) ; loop pseudo 12703 (use (match_operand 1))] ; label 12704 "" 12705{ 12706 if (GET_MODE (operands[0]) != Pmode) 12707 FAIL; 12708 12709 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1])); 12710 DONE; 12711}) 12712 12713(define_expand "@ctr<mode>" 12714 [(parallel [(set (pc) 12715 (if_then_else (ne (match_operand:P 0 "register_operand") 12716 (const_int 1)) 12717 (label_ref (match_operand 1)) 12718 (pc))) 12719 (set (match_dup 0) 12720 (plus:P (match_dup 0) 12721 (const_int -1))) 12722 (clobber (match_scratch:CC 2)) 12723 (clobber (match_scratch:P 3))])] 12724 "" 12725 "") 12726 12727;; We need to be able to do this for any operand, including MEM, or we 12728;; will cause reload to blow up since we don't allow output reloads on 12729;; JUMP_INSNs. 12730;; For the length attribute to be calculated correctly, the 12731;; label MUST be operand 0. 12732;; rs6000_legitimate_combined_insn prevents combine creating any of 12733;; the ctr<mode> insns. 12734 12735(define_code_iterator eqne [eq ne]) 12736(define_code_attr bd [(eq "bdz") (ne "bdnz")]) 12737(define_code_attr bd_neg [(eq "bdnz") (ne "bdz")]) 12738 12739(define_insn "<bd>_<mode>" 12740 [(set (pc) 12741 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12742 (const_int 1)) 12743 (label_ref (match_operand 0)) 12744 (pc))) 12745 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l") 12746 (plus:P (match_dup 1) 12747 (const_int -1))) 12748 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 12749 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 12750 "" 12751{ 12752 if (which_alternative != 0) 12753 return "#"; 12754 else if (get_attr_length (insn) == 4) 12755 return "<bd> %l0"; 12756 else 12757 return "<bd_neg> $+8\;b %l0"; 12758} 12759 [(set_attr "type" "branch") 12760 (set_attr_alternative "length" 12761 [(if_then_else (and (ge (minus (match_dup 0) (pc)) 12762 (const_int -32768)) 12763 (lt (minus (match_dup 0) (pc)) 12764 (const_int 32764))) 12765 (const_int 4) 12766 (const_int 8)) 12767 (const_string "16") 12768 (const_string "20") 12769 (const_string "20")])]) 12770 12771;; Now the splitter if we could not allocate the CTR register 12772(define_split 12773 [(set (pc) 12774 (if_then_else (match_operator 2 "comparison_operator" 12775 [(match_operand:P 1 "gpc_reg_operand") 12776 (const_int 1)]) 12777 (match_operand 5) 12778 (match_operand 6))) 12779 (set (match_operand:P 0 "nonimmediate_operand") 12780 (plus:P (match_dup 1) 12781 (const_int -1))) 12782 (clobber (match_scratch:CC 3)) 12783 (clobber (match_scratch:P 4))] 12784 "reload_completed" 12785 [(set (pc) 12786 (if_then_else (match_dup 7) 12787 (match_dup 5) 12788 (match_dup 6)))] 12789{ 12790 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3], 12791 const0_rtx); 12792 emit_insn (gen_rtx_SET (operands[3], 12793 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx))); 12794 if (int_reg_operand (operands[0], <MODE>mode)) 12795 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx)); 12796 else 12797 { 12798 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx)); 12799 emit_move_insn (operands[0], operands[4]); 12800 } 12801 /* No DONE so branch comes from the pattern. */ 12802}) 12803 12804;; patterns for bdnzt/bdnzf/bdzt/bdzf 12805;; Note that in the case of long branches we have to decompose this into 12806;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition 12807;; and the CR bit, which means there is no way to conveniently invert the 12808;; comparison as is done with plain bdnz/bdz. 12809 12810(define_insn "<bd>tf_<mode>" 12811 [(set (pc) 12812 (if_then_else 12813 (and 12814 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12815 (const_int 1)) 12816 (match_operator 3 "branch_comparison_operator" 12817 [(match_operand 4 "cc_reg_operand" "y,y,y,y") 12818 (const_int 0)])) 12819 (label_ref (match_operand 0)) 12820 (pc))) 12821 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l") 12822 (plus:P (match_dup 1) 12823 (const_int -1))) 12824 (clobber (match_scratch:P 5 "=X,X,&r,r")) 12825 (clobber (match_scratch:CC 6 "=X,&y,&y,&y")) 12826 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))] 12827 "" 12828{ 12829 if (which_alternative != 0) 12830 return "#"; 12831 else if (get_attr_length (insn) == 4) 12832 { 12833 if (branch_positive_comparison_operator (operands[3], 12834 GET_MODE (operands[3]))) 12835 return "<bd>t %j3,%l0"; 12836 else 12837 return "<bd>f %j3,%l0"; 12838 } 12839 else 12840 { 12841 static char seq[96]; 12842 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn); 12843 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs); 12844 return seq; 12845 } 12846} 12847 [(set_attr "type" "branch") 12848 (set_attr_alternative "length" 12849 [(if_then_else (and (ge (minus (match_dup 0) (pc)) 12850 (const_int -32768)) 12851 (lt (minus (match_dup 0) (pc)) 12852 (const_int 32764))) 12853 (const_int 4) 12854 (const_int 8)) 12855 (const_string "16") 12856 (const_string "20") 12857 (const_string "20")])]) 12858 12859;; Now the splitter if we could not allocate the CTR register 12860(define_split 12861 [(set (pc) 12862 (if_then_else 12863 (and 12864 (match_operator 1 "comparison_operator" 12865 [(match_operand:P 0 "gpc_reg_operand") 12866 (const_int 1)]) 12867 (match_operator 3 "branch_comparison_operator" 12868 [(match_operand 2 "cc_reg_operand") 12869 (const_int 0)])) 12870 (match_operand 4) 12871 (match_operand 5))) 12872 (set (match_operand:P 6 "nonimmediate_operand") 12873 (plus:P (match_dup 0) 12874 (const_int -1))) 12875 (clobber (match_scratch:P 7)) 12876 (clobber (match_scratch:CC 8)) 12877 (clobber (match_scratch:CCEQ 9))] 12878 "reload_completed" 12879[(pc)] 12880{ 12881 rtx ctr = operands[0]; 12882 rtx ctrcmp = operands[1]; 12883 rtx ccin = operands[2]; 12884 rtx cccmp = operands[3]; 12885 rtx dst1 = operands[4]; 12886 rtx dst2 = operands[5]; 12887 rtx ctrout = operands[6]; 12888 rtx ctrtmp = operands[7]; 12889 enum rtx_code cmpcode = GET_CODE (ctrcmp); 12890 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp)); 12891 if (!ispos) 12892 cmpcode = reverse_condition (cmpcode); 12893 /* Generate crand/crandc here. */ 12894 emit_insn (gen_rtx_SET (operands[8], 12895 gen_rtx_COMPARE (CCmode, ctr, const1_rtx))); 12896 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx); 12897 12898 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp); 12899 if (ispos) 12900 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc, 12901 operands[8], cccmp, ccin)); 12902 else 12903 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc, 12904 operands[8], cccmp, ccin)); 12905 if (int_reg_operand (ctrout, <MODE>mode)) 12906 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx)); 12907 else 12908 { 12909 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx)); 12910 emit_move_insn (ctrout, ctrtmp); 12911 } 12912 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx); 12913 emit_jump_insn (gen_rtx_SET (pc_rtx, 12914 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp, 12915 dst1, dst2))); 12916 DONE; 12917}) 12918 12919 12920(define_insn "trap" 12921 [(trap_if (const_int 1) (const_int 0))] 12922 "" 12923 "trap" 12924 [(set_attr "type" "trap")]) 12925 12926(define_expand "ctrap<mode>4" 12927 [(trap_if (match_operator 0 "ordered_comparison_operator" 12928 [(match_operand:GPR 1 "register_operand") 12929 (match_operand:GPR 2 "reg_or_short_operand")]) 12930 (match_operand 3 "zero_constant" ""))] 12931 "" 12932 "") 12933 12934(define_insn "" 12935 [(trap_if (match_operator 0 "ordered_comparison_operator" 12936 [(match_operand:GPR 1 "register_operand" "r") 12937 (match_operand:GPR 2 "reg_or_short_operand" "rI")]) 12938 (const_int 0))] 12939 "" 12940 "t<wd>%V0%I2 %1,%2" 12941 [(set_attr "type" "trap")]) 12942 12943;; Insns related to generating the function prologue and epilogue. 12944 12945(define_expand "prologue" 12946 [(use (const_int 0))] 12947 "" 12948{ 12949 rs6000_emit_prologue (); 12950 if (!TARGET_SCHED_PROLOG) 12951 emit_insn (gen_blockage ()); 12952 DONE; 12953}) 12954 12955(define_insn "*movesi_from_cr_one" 12956 [(match_parallel 0 "mfcr_operation" 12957 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 12958 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y") 12959 (match_operand 3 "immediate_operand" "n")] 12960 UNSPEC_MOVESI_FROM_CR))])] 12961 "TARGET_MFCRF" 12962{ 12963 int mask = 0; 12964 int i; 12965 for (i = 0; i < XVECLEN (operands[0], 0); i++) 12966 { 12967 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 12968 operands[4] = GEN_INT (mask); 12969 output_asm_insn ("mfcr %1,%4", operands); 12970 } 12971 return ""; 12972} 12973 [(set_attr "type" "mfcrf")]) 12974 12975;; Don't include the volatile CRs since their values are not used wrt CR save 12976;; in the prologue and doing so prevents shrink-wrapping because we can't move the 12977;; prologue past an insn (early exit test) that defines a register used in the 12978;; prologue. 12979(define_insn "prologue_movesi_from_cr" 12980 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 12981 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO) 12982 (reg:CC CR4_REGNO)] 12983 UNSPEC_MOVESI_FROM_CR))] 12984 "" 12985 "mfcr %0" 12986 [(set_attr "type" "mfcr")]) 12987 12988(define_insn "*crsave" 12989 [(match_parallel 0 "crsave_operation" 12990 [(set (match_operand:SI 1 "memory_operand" "=m") 12991 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 12992 "" 12993 "stw %2,%1" 12994 [(set_attr "type" "store")]) 12995 12996(define_insn "*stmw" 12997 [(match_parallel 0 "stmw_operation" 12998 [(set (match_operand:SI 1 "memory_operand" "=m") 12999 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 13000 "TARGET_MULTIPLE" 13001 "stmw %2,%1" 13002 [(set_attr "type" "store") 13003 (set_attr "update" "yes") 13004 (set_attr "indexed" "yes")]) 13005 13006; The following comment applies to: 13007; save_gpregs_* 13008; save_fpregs_* 13009; restore_gpregs* 13010; return_and_restore_gpregs* 13011; return_and_restore_fpregs* 13012; return_and_restore_fpregs_aix* 13013; 13014; The out-of-line save / restore functions expects one input argument. 13015; Since those are not standard call_insn's, we must avoid using 13016; MATCH_OPERAND for that argument. That way the register rename 13017; optimization will not try to rename this register. 13018; Each pattern is repeated for each possible register number used in 13019; various ABIs (r11, r1, and for some functions r12) 13020 13021(define_insn "*save_gpregs_<mode>_r11" 13022 [(match_parallel 0 "any_parallel_operand" 13023 [(clobber (reg:P LR_REGNO)) 13024 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13025 (use (reg:P 11)) 13026 (set (match_operand:P 2 "memory_operand" "=m") 13027 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13028 "" 13029 "bl %1" 13030 [(set_attr "type" "branch")]) 13031 13032(define_insn "*save_gpregs_<mode>_r12" 13033 [(match_parallel 0 "any_parallel_operand" 13034 [(clobber (reg:P LR_REGNO)) 13035 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13036 (use (reg:P 12)) 13037 (set (match_operand:P 2 "memory_operand" "=m") 13038 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13039 "" 13040 "bl %1" 13041 [(set_attr "type" "branch")]) 13042 13043(define_insn "*save_gpregs_<mode>_r1" 13044 [(match_parallel 0 "any_parallel_operand" 13045 [(clobber (reg:P LR_REGNO)) 13046 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13047 (use (reg:P 1)) 13048 (set (match_operand:P 2 "memory_operand" "=m") 13049 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13050 "" 13051 "bl %1" 13052 [(set_attr "type" "branch")]) 13053 13054(define_insn "*save_fpregs_<mode>_r11" 13055 [(match_parallel 0 "any_parallel_operand" 13056 [(clobber (reg:P LR_REGNO)) 13057 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13058 (use (reg:P 11)) 13059 (set (match_operand:DF 2 "memory_operand" "=m") 13060 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13061 "" 13062 "bl %1" 13063 [(set_attr "type" "branch")]) 13064 13065(define_insn "*save_fpregs_<mode>_r12" 13066 [(match_parallel 0 "any_parallel_operand" 13067 [(clobber (reg:P LR_REGNO)) 13068 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13069 (use (reg:P 12)) 13070 (set (match_operand:DF 2 "memory_operand" "=m") 13071 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13072 "" 13073 "bl %1" 13074 [(set_attr "type" "branch")]) 13075 13076(define_insn "*save_fpregs_<mode>_r1" 13077 [(match_parallel 0 "any_parallel_operand" 13078 [(clobber (reg:P LR_REGNO)) 13079 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13080 (use (reg:P 1)) 13081 (set (match_operand:DF 2 "memory_operand" "=m") 13082 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13083 "" 13084 "bl %1" 13085 [(set_attr "type" "branch")]) 13086 13087; This is to explain that changes to the stack pointer should 13088; not be moved over loads from or stores to stack memory. 13089(define_insn "stack_tie" 13090 [(match_parallel 0 "tie_operand" 13091 [(set (mem:BLK (reg 1)) (const_int 0))])] 13092 "" 13093 "" 13094 [(set_attr "length" "0")]) 13095 13096; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to 13097; stay behind all restores from the stack, it cannot be reordered to before 13098; one. See PR77687. This insn is an add or mr, and a memory clobber. 13099(define_insn "stack_restore_tie" 13100 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 13101 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") 13102 (match_operand:SI 2 "reg_or_cint_operand" "O,rI"))) 13103 (set (mem:BLK (scratch)) (const_int 0))] 13104 "TARGET_32BIT" 13105 "@ 13106 mr %0,%1 13107 add%I2 %0,%1,%2" 13108 [(set_attr "type" "*,add")]) 13109 13110(define_expand "epilogue" 13111 [(use (const_int 0))] 13112 "" 13113{ 13114 if (!TARGET_SCHED_PROLOG) 13115 emit_insn (gen_blockage ()); 13116 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL); 13117 DONE; 13118}) 13119 13120; On some processors, doing the mtcrf one CC register at a time is 13121; faster (like on the 604e). On others, doing them all at once is 13122; faster; for instance, on the 601 and 750. 13123 13124(define_expand "movsi_to_cr_one" 13125 [(set (match_operand:CC 0 "cc_reg_operand") 13126 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand") 13127 (match_dup 2)] UNSPEC_MOVESI_TO_CR))] 13128 "" 13129 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));") 13130 13131(define_insn "*movsi_to_cr" 13132 [(match_parallel 0 "mtcrf_operation" 13133 [(set (match_operand:CC 1 "cc_reg_operand" "=y") 13134 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r") 13135 (match_operand 3 "immediate_operand" "n")] 13136 UNSPEC_MOVESI_TO_CR))])] 13137 "" 13138{ 13139 int mask = 0; 13140 int i; 13141 for (i = 0; i < XVECLEN (operands[0], 0); i++) 13142 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 13143 operands[4] = GEN_INT (mask); 13144 return "mtcrf %4,%2"; 13145} 13146 [(set_attr "type" "mtcr")]) 13147 13148(define_insn "*mtcrfsi" 13149 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 13150 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 13151 (match_operand 2 "immediate_operand" "n")] 13152 UNSPEC_MOVESI_TO_CR))] 13153 "REG_P (operands[0]) 13154 && CR_REGNO_P (REGNO (operands[0])) 13155 && CONST_INT_P (operands[2]) 13156 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))" 13157 "mtcrf %R0,%1" 13158 [(set_attr "type" "mtcr")]) 13159 13160; The load-multiple instructions have similar properties. 13161; Note that "load_multiple" is a name known to the machine-independent 13162; code that actually corresponds to the PowerPC load-string. 13163 13164(define_insn "*lmw" 13165 [(match_parallel 0 "lmw_operation" 13166 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 13167 (match_operand:SI 2 "memory_operand" "m"))])] 13168 "TARGET_MULTIPLE" 13169 "lmw %1,%2" 13170 [(set_attr "type" "load") 13171 (set_attr "update" "yes") 13172 (set_attr "indexed" "yes") 13173 (set_attr "cell_micro" "always")]) 13174 13175; FIXME: "any_parallel_operand" is a bit flexible... 13176 13177; The following comment applies to: 13178; save_gpregs_* 13179; save_fpregs_* 13180; restore_gpregs* 13181; return_and_restore_gpregs* 13182; return_and_restore_fpregs* 13183; return_and_restore_fpregs_aix* 13184; 13185; The out-of-line save / restore functions expects one input argument. 13186; Since those are not standard call_insn's, we must avoid using 13187; MATCH_OPERAND for that argument. That way the register rename 13188; optimization will not try to rename this register. 13189; Each pattern is repeated for each possible register number used in 13190; various ABIs (r11, r1, and for some functions r12) 13191 13192(define_insn "*restore_gpregs_<mode>_r11" 13193 [(match_parallel 0 "any_parallel_operand" 13194 [(clobber (reg:P LR_REGNO)) 13195 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13196 (use (reg:P 11)) 13197 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13198 (match_operand:P 3 "memory_operand" "m"))])] 13199 "" 13200 "bl %1" 13201 [(set_attr "type" "branch")]) 13202 13203(define_insn "*restore_gpregs_<mode>_r12" 13204 [(match_parallel 0 "any_parallel_operand" 13205 [(clobber (reg:P LR_REGNO)) 13206 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13207 (use (reg:P 12)) 13208 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13209 (match_operand:P 3 "memory_operand" "m"))])] 13210 "" 13211 "bl %1" 13212 [(set_attr "type" "branch")]) 13213 13214(define_insn "*restore_gpregs_<mode>_r1" 13215 [(match_parallel 0 "any_parallel_operand" 13216 [(clobber (reg:P LR_REGNO)) 13217 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13218 (use (reg:P 1)) 13219 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13220 (match_operand:P 3 "memory_operand" "m"))])] 13221 "" 13222 "bl %1" 13223 [(set_attr "type" "branch")]) 13224 13225(define_insn "*return_and_restore_gpregs_<mode>_r11" 13226 [(match_parallel 0 "any_parallel_operand" 13227 [(return) 13228 (clobber (reg:P LR_REGNO)) 13229 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13230 (use (reg:P 11)) 13231 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13232 (match_operand:P 3 "memory_operand" "m"))])] 13233 "" 13234 "b %1" 13235 [(set_attr "type" "branch")]) 13236 13237(define_insn "*return_and_restore_gpregs_<mode>_r12" 13238 [(match_parallel 0 "any_parallel_operand" 13239 [(return) 13240 (clobber (reg:P LR_REGNO)) 13241 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13242 (use (reg:P 12)) 13243 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13244 (match_operand:P 3 "memory_operand" "m"))])] 13245 "" 13246 "b %1" 13247 [(set_attr "type" "branch")]) 13248 13249(define_insn "*return_and_restore_gpregs_<mode>_r1" 13250 [(match_parallel 0 "any_parallel_operand" 13251 [(return) 13252 (clobber (reg:P LR_REGNO)) 13253 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13254 (use (reg:P 1)) 13255 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13256 (match_operand:P 3 "memory_operand" "m"))])] 13257 "" 13258 "b %1" 13259 [(set_attr "type" "branch")]) 13260 13261(define_insn "*return_and_restore_fpregs_<mode>_r11" 13262 [(match_parallel 0 "any_parallel_operand" 13263 [(return) 13264 (clobber (reg:P LR_REGNO)) 13265 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13266 (use (reg:P 11)) 13267 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13268 (match_operand:DF 3 "memory_operand" "m"))])] 13269 "" 13270 "b %1" 13271 [(set_attr "type" "branch")]) 13272 13273(define_insn "*return_and_restore_fpregs_<mode>_r12" 13274 [(match_parallel 0 "any_parallel_operand" 13275 [(return) 13276 (clobber (reg:P LR_REGNO)) 13277 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13278 (use (reg:P 12)) 13279 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13280 (match_operand:DF 3 "memory_operand" "m"))])] 13281 "" 13282 "b %1" 13283 [(set_attr "type" "branch")]) 13284 13285(define_insn "*return_and_restore_fpregs_<mode>_r1" 13286 [(match_parallel 0 "any_parallel_operand" 13287 [(return) 13288 (clobber (reg:P LR_REGNO)) 13289 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13290 (use (reg:P 1)) 13291 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13292 (match_operand:DF 3 "memory_operand" "m"))])] 13293 "" 13294 "b %1" 13295 [(set_attr "type" "branch")]) 13296 13297(define_insn "*return_and_restore_fpregs_aix_<mode>_r11" 13298 [(match_parallel 0 "any_parallel_operand" 13299 [(return) 13300 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13301 (use (reg:P 11)) 13302 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13303 (match_operand:DF 3 "memory_operand" "m"))])] 13304 "" 13305 "b %1" 13306 [(set_attr "type" "branch")]) 13307 13308(define_insn "*return_and_restore_fpregs_aix_<mode>_r1" 13309 [(match_parallel 0 "any_parallel_operand" 13310 [(return) 13311 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13312 (use (reg:P 1)) 13313 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13314 (match_operand:DF 3 "memory_operand" "m"))])] 13315 "" 13316 "b %1" 13317 [(set_attr "type" "branch")]) 13318 13319; This is used in compiling the unwind routines. 13320(define_expand "eh_return" 13321 [(use (match_operand 0 "general_operand"))] 13322 "" 13323{ 13324 emit_insn (gen_eh_set_lr (Pmode, operands[0])); 13325 DONE; 13326}) 13327 13328; We can't expand this before we know where the link register is stored. 13329(define_insn_and_split "@eh_set_lr_<mode>" 13330 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR) 13331 (clobber (match_scratch:P 1 "=&b"))] 13332 "" 13333 "#" 13334 "reload_completed" 13335 [(const_int 0)] 13336{ 13337 rs6000_emit_eh_reg_restore (operands[0], operands[1]); 13338 DONE; 13339}) 13340 13341(define_insn "prefetch" 13342 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a") 13343 (match_operand:SI 1 "const_int_operand" "n") 13344 (match_operand:SI 2 "const_int_operand" "n"))] 13345 "" 13346{ 13347 13348 13349 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7). 13350 AIX does not support the dcbtstt and dcbtt extended mnemonics. 13351 The AIX assembler does not support the three operand form of dcbt 13352 and dcbtst on Power 7 (-mpwr7). */ 13353 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE; 13354 13355 if (REG_P (operands[0])) 13356 { 13357 if (INTVAL (operands[1]) == 0) 13358 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16"; 13359 else 13360 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16"; 13361 } 13362 else 13363 { 13364 if (INTVAL (operands[1]) == 0) 13365 return inst_select ? "dcbt %a0" : "dcbt %a0,16"; 13366 else 13367 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16"; 13368 } 13369} 13370 [(set_attr "type" "load")]) 13371 13372;; Handle -fsplit-stack. 13373 13374(define_expand "split_stack_prologue" 13375 [(const_int 0)] 13376 "" 13377{ 13378 rs6000_expand_split_stack_prologue (); 13379 DONE; 13380}) 13381 13382(define_expand "load_split_stack_limit" 13383 [(set (match_operand 0) 13384 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))] 13385 "" 13386{ 13387 emit_insn (gen_rtx_SET (operands[0], 13388 gen_rtx_UNSPEC (Pmode, 13389 gen_rtvec (1, const0_rtx), 13390 UNSPEC_STACK_CHECK))); 13391 DONE; 13392}) 13393 13394(define_insn "load_split_stack_limit_di" 13395 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 13396 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))] 13397 "TARGET_64BIT" 13398 "ld %0,-0x7040(13)" 13399 [(set_attr "type" "load") 13400 (set_attr "update" "no") 13401 (set_attr "indexed" "no")]) 13402 13403(define_insn "load_split_stack_limit_si" 13404 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 13405 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))] 13406 "!TARGET_64BIT" 13407 "lwz %0,-0x7020(2)" 13408 [(set_attr "type" "load") 13409 (set_attr "update" "no") 13410 (set_attr "indexed" "no")]) 13411 13412;; A return instruction which the middle-end doesn't see. 13413;; Use r0 to stop regrename twiddling with lr restore insns emitted 13414;; after the call to __morestack. 13415(define_insn "split_stack_return" 13416 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)] 13417 "" 13418 "blr" 13419 [(set_attr "type" "jmpreg")]) 13420 13421;; If there are operand 0 bytes available on the stack, jump to 13422;; operand 1. 13423(define_expand "split_stack_space_check" 13424 [(set (match_dup 2) 13425 (unspec [(const_int 0)] UNSPEC_STACK_CHECK)) 13426 (set (match_dup 3) 13427 (minus (reg STACK_POINTER_REGNUM) 13428 (match_operand 0))) 13429 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2))) 13430 (set (pc) (if_then_else 13431 (geu (match_dup 4) (const_int 0)) 13432 (label_ref (match_operand 1)) 13433 (pc)))] 13434 "" 13435{ 13436 rs6000_split_stack_space_check (operands[0], operands[1]); 13437 DONE; 13438}) 13439 13440(define_insn "bpermd_<mode>" 13441 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 13442 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") 13443 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))] 13444 "TARGET_POPCNTD" 13445 "bpermd %0,%1,%2" 13446 [(set_attr "type" "popcnt")]) 13447 13448 13449;; Builtin fma support. Handle 13450;; Note that the conditions for expansion are in the FMA_F iterator. 13451 13452(define_expand "fma<mode>4" 13453 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13454 (fma:FMA_F 13455 (match_operand:FMA_F 1 "gpc_reg_operand") 13456 (match_operand:FMA_F 2 "gpc_reg_operand") 13457 (match_operand:FMA_F 3 "gpc_reg_operand")))] 13458 "" 13459 "") 13460 13461(define_insn "*fma<mode>4_fpr" 13462 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 13463 (fma:SFDF 13464 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa") 13465 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 13466 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))] 13467 "TARGET_HARD_FLOAT" 13468 "@ 13469 fmadd<s> %0,%1,%2,%3 13470 xsmadda<sd>p %x0,%x1,%x2 13471 xsmaddm<sd>p %x0,%x1,%x3" 13472 [(set_attr "type" "fp") 13473 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 13474 13475; Altivec only has fma and nfms. 13476(define_expand "fms<mode>4" 13477 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13478 (fma:FMA_F 13479 (match_operand:FMA_F 1 "gpc_reg_operand") 13480 (match_operand:FMA_F 2 "gpc_reg_operand") 13481 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))] 13482 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13483 "") 13484 13485(define_insn "*fms<mode>4_fpr" 13486 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 13487 (fma:SFDF 13488 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa") 13489 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 13490 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))] 13491 "TARGET_HARD_FLOAT" 13492 "@ 13493 fmsub<s> %0,%1,%2,%3 13494 xsmsuba<sd>p %x0,%x1,%x2 13495 xsmsubm<sd>p %x0,%x1,%x3" 13496 [(set_attr "type" "fp") 13497 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 13498 13499;; If signed zeros are ignored, -(a * b - c) = -a * b + c. 13500(define_expand "fnma<mode>4" 13501 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13502 (neg:FMA_F 13503 (fma:FMA_F 13504 (match_operand:FMA_F 1 "gpc_reg_operand") 13505 (match_operand:FMA_F 2 "gpc_reg_operand") 13506 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))] 13507 "!HONOR_SIGNED_ZEROS (<MODE>mode)" 13508 "") 13509 13510;; If signed zeros are ignored, -(a * b + c) = -a * b - c. 13511(define_expand "fnms<mode>4" 13512 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13513 (neg:FMA_F 13514 (fma:FMA_F 13515 (match_operand:FMA_F 1 "gpc_reg_operand") 13516 (match_operand:FMA_F 2 "gpc_reg_operand") 13517 (match_operand:FMA_F 3 "gpc_reg_operand"))))] 13518 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13519 "") 13520 13521; Not an official optab name, but used from builtins. 13522(define_expand "nfma<mode>4" 13523 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13524 (neg:FMA_F 13525 (fma:FMA_F 13526 (match_operand:FMA_F 1 "gpc_reg_operand") 13527 (match_operand:FMA_F 2 "gpc_reg_operand") 13528 (match_operand:FMA_F 3 "gpc_reg_operand"))))] 13529 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13530 "") 13531 13532(define_insn "*nfma<mode>4_fpr" 13533 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 13534 (neg:SFDF 13535 (fma:SFDF 13536 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa") 13537 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 13538 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))] 13539 "TARGET_HARD_FLOAT" 13540 "@ 13541 fnmadd<s> %0,%1,%2,%3 13542 xsnmadda<sd>p %x0,%x1,%x2 13543 xsnmaddm<sd>p %x0,%x1,%x3" 13544 [(set_attr "type" "fp") 13545 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 13546 13547; Not an official optab name, but used from builtins. 13548(define_expand "nfms<mode>4" 13549 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13550 (neg:FMA_F 13551 (fma:FMA_F 13552 (match_operand:FMA_F 1 "gpc_reg_operand") 13553 (match_operand:FMA_F 2 "gpc_reg_operand") 13554 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))] 13555 "" 13556 "") 13557 13558(define_insn "*nfmssf4_fpr" 13559 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 13560 (neg:SFDF 13561 (fma:SFDF 13562 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa") 13563 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 13564 (neg:SFDF 13565 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))] 13566 "TARGET_HARD_FLOAT" 13567 "@ 13568 fnmsub<s> %0,%1,%2,%3 13569 xsnmsuba<sd>p %x0,%x1,%x2 13570 xsnmsubm<sd>p %x0,%x1,%x3" 13571 [(set_attr "type" "fp") 13572 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 13573 13574(define_expand "rs6000_get_timebase" 13575 [(use (match_operand:DI 0 "gpc_reg_operand"))] 13576 "" 13577{ 13578 if (TARGET_POWERPC64) 13579 emit_insn (gen_rs6000_mftb_di (operands[0])); 13580 else 13581 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0])); 13582 DONE; 13583}) 13584 13585(define_insn "rs6000_get_timebase_ppc32" 13586 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 13587 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB)) 13588 (clobber (match_scratch:SI 1 "=r")) 13589 (clobber (match_scratch:CC 2 "=y"))] 13590 "!TARGET_POWERPC64" 13591{ 13592 if (WORDS_BIG_ENDIAN) 13593 if (TARGET_MFCRF) 13594 { 13595 return "mfspr %0,269\;" 13596 "mfspr %L0,268\;" 13597 "mfspr %1,269\;" 13598 "cmpw %2,%0,%1\;" 13599 "bne- %2,$-16"; 13600 } 13601 else 13602 { 13603 return "mftbu %0\;" 13604 "mftb %L0\;" 13605 "mftbu %1\;" 13606 "cmpw %2,%0,%1\;" 13607 "bne- %2,$-16"; 13608 } 13609 else 13610 if (TARGET_MFCRF) 13611 { 13612 return "mfspr %L0,269\;" 13613 "mfspr %0,268\;" 13614 "mfspr %1,269\;" 13615 "cmpw %2,%L0,%1\;" 13616 "bne- %2,$-16"; 13617 } 13618 else 13619 { 13620 return "mftbu %L0\;" 13621 "mftb %0\;" 13622 "mftbu %1\;" 13623 "cmpw %2,%L0,%1\;" 13624 "bne- %2,$-16"; 13625 } 13626} 13627 [(set_attr "length" "20")]) 13628 13629(define_insn "rs6000_mftb_<mode>" 13630 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 13631 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))] 13632 "" 13633{ 13634 if (TARGET_MFCRF) 13635 return "mfspr %0,268"; 13636 else 13637 return "mftb %0"; 13638}) 13639 13640 13641;; The ISA 3.0 mffsl instruction is a lower latency instruction 13642;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR. 13643(define_insn "rs6000_mffsl_hw" 13644 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 13645 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))] 13646 "TARGET_HARD_FLOAT" 13647 "mffsl %0") 13648 13649(define_expand "rs6000_mffsl" 13650 [(set (match_operand:DF 0 "gpc_reg_operand") 13651 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))] 13652 "TARGET_HARD_FLOAT" 13653{ 13654 /* If the low latency mffsl instruction (ISA 3.0) is available use it, 13655 otherwise fall back to the older mffs instruction to emulate the mffsl 13656 instruction. */ 13657 13658 if (!TARGET_P9_MISC) 13659 { 13660 rtx tmp1 = gen_reg_rtx (DFmode); 13661 13662 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl 13663 instruction using the mffs instruction and masking the result. */ 13664 emit_insn (gen_rs6000_mffs (tmp1)); 13665 13666 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0); 13667 rtx tmp2 = gen_reg_rtx (DImode); 13668 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL))); 13669 13670 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0); 13671 emit_move_insn (operands[0], tmp2df); 13672 DONE; 13673 } 13674 13675 emit_insn (gen_rs6000_mffsl_hw (operands[0])); 13676 DONE; 13677}) 13678 13679(define_insn "rs6000_mffs" 13680 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 13681 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))] 13682 "TARGET_HARD_FLOAT" 13683 "mffs %0") 13684 13685(define_insn "rs6000_mtfsf" 13686 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i") 13687 (match_operand:DF 1 "gpc_reg_operand" "d")] 13688 UNSPECV_MTFSF)] 13689 "TARGET_HARD_FLOAT" 13690 "mtfsf %0,%1") 13691 13692(define_insn "rs6000_mtfsf_hi" 13693 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") 13694 (match_operand:DF 1 "gpc_reg_operand" "d")] 13695 UNSPECV_MTFSF_HI)] 13696 "TARGET_HARD_FLOAT" 13697 "mtfsf %0,%1,0,1") 13698 13699 13700;; Power8 fusion support for fusing an addis instruction with a D-form load of 13701;; a GPR. The addis instruction must be adjacent to the load, and use the same 13702;; register that is being loaded. The fused ops must be physically adjacent. 13703 13704;; On Power8 GPR loads, we try to use the register that is being load. The 13705;; peephole2 then gathers any other fused possibilities that it can find after 13706;; register allocation. If power9 fusion is selected, we also fuse floating 13707;; point loads/stores. 13708 13709;; Find cases where the addis that feeds into a load instruction is either used 13710;; once or is the same as the target register, and replace it with the fusion 13711;; insn 13712 13713(define_peephole2 13714 [(set (match_operand:P 0 "base_reg_operand") 13715 (match_operand:P 1 "fusion_gpr_addis")) 13716 (set (match_operand:INT1 2 "base_reg_operand") 13717 (match_operand:INT1 3 "fusion_gpr_mem_load"))] 13718 "TARGET_P8_FUSION 13719 && fusion_gpr_load_p (operands[0], operands[1], operands[2], 13720 operands[3])" 13721 [(const_int 0)] 13722{ 13723 expand_fusion_gpr_load (operands); 13724 DONE; 13725}) 13726 13727;; Fusion insn, created by the define_peephole2 above (and eventually by 13728;; reload) 13729 13730(define_insn "*fusion_gpr_load_<mode>" 13731 [(set (match_operand:INT1 0 "base_reg_operand" "=b") 13732 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")] 13733 UNSPEC_FUSION_GPR))] 13734 "TARGET_P8_FUSION" 13735{ 13736 return emit_fusion_gpr_load (operands[0], operands[1]); 13737} 13738 [(set_attr "type" "load") 13739 (set_attr "length" "8")]) 13740 13741 13742;; Optimize cases where we want to do a D-form load (register+offset) on 13743;; ISA 2.06/2.07 to an Altivec register, and the register allocator 13744;; has generated: 13745;; LFD 0,32(3) 13746;; XXLOR 32,0,0 13747;; 13748;; and we change this to: 13749;; LI 0,32 13750;; LXSDX 32,3,9 13751 13752(define_peephole2 13753 [(match_scratch:P 0 "b") 13754 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 13755 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand")) 13756 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand") 13757 (match_dup 1))] 13758 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])" 13759 [(set (match_dup 0) 13760 (match_dup 4)) 13761 (set (match_dup 3) 13762 (match_dup 5))] 13763{ 13764 rtx tmp_reg = operands[0]; 13765 rtx mem = operands[2]; 13766 rtx addr = XEXP (mem, 0); 13767 rtx add_op0, add_op1, new_addr; 13768 13769 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 13770 add_op0 = XEXP (addr, 0); 13771 add_op1 = XEXP (addr, 1); 13772 gcc_assert (REG_P (add_op0)); 13773 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); 13774 13775 operands[4] = add_op1; 13776 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr); 13777}) 13778 13779;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an 13780;; Altivec register, and the register allocator has generated: 13781;; XXLOR 0,32,32 13782;; STFD 0,32(3) 13783;; 13784;; and we change this to: 13785;; LI 0,32 13786;; STXSDX 32,3,9 13787 13788(define_peephole2 13789 [(match_scratch:P 0 "b") 13790 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 13791 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand")) 13792 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand") 13793 (match_dup 1))] 13794 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])" 13795 [(set (match_dup 0) 13796 (match_dup 4)) 13797 (set (match_dup 5) 13798 (match_dup 2))] 13799{ 13800 rtx tmp_reg = operands[0]; 13801 rtx mem = operands[3]; 13802 rtx addr = XEXP (mem, 0); 13803 rtx add_op0, add_op1, new_addr; 13804 13805 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 13806 add_op0 = XEXP (addr, 0); 13807 add_op1 = XEXP (addr, 1); 13808 gcc_assert (REG_P (add_op0)); 13809 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); 13810 13811 operands[4] = add_op1; 13812 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr); 13813}) 13814 13815 13816;; Miscellaneous ISA 2.06 (power7) instructions 13817(define_insn "addg6s" 13818 [(set (match_operand:SI 0 "register_operand" "=r") 13819 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 13820 (match_operand:SI 2 "register_operand" "r")] 13821 UNSPEC_ADDG6S))] 13822 "TARGET_POPCNTD" 13823 "addg6s %0,%1,%2" 13824 [(set_attr "type" "integer")]) 13825 13826(define_insn "cdtbcd" 13827 [(set (match_operand:SI 0 "register_operand" "=r") 13828 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 13829 UNSPEC_CDTBCD))] 13830 "TARGET_POPCNTD" 13831 "cdtbcd %0,%1" 13832 [(set_attr "type" "integer")]) 13833 13834(define_insn "cbcdtd" 13835 [(set (match_operand:SI 0 "register_operand" "=r") 13836 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 13837 UNSPEC_CBCDTD))] 13838 "TARGET_POPCNTD" 13839 "cbcdtd %0,%1" 13840 [(set_attr "type" "integer")]) 13841 13842(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE 13843 UNSPEC_DIVEU]) 13844 13845(define_int_attr div_extend [(UNSPEC_DIVE "e") 13846 (UNSPEC_DIVEU "eu")]) 13847 13848(define_insn "div<div_extend>_<mode>" 13849 [(set (match_operand:GPR 0 "register_operand" "=r") 13850 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r") 13851 (match_operand:GPR 2 "register_operand" "r")] 13852 UNSPEC_DIV_EXTEND))] 13853 "TARGET_POPCNTD" 13854 "div<wd><div_extend> %0,%1,%2" 13855 [(set_attr "type" "div") 13856 (set_attr "size" "<bits>")]) 13857 13858 13859;; Pack/unpack 128-bit floating point types that take 2 scalar registers 13860 13861; Type of the 64-bit part when packing/unpacking 128-bit floating point types 13862(define_mode_attr FP128_64 [(TF "DF") 13863 (IF "DF") 13864 (TD "DI") 13865 (KF "DI")]) 13866 13867(define_expand "unpack<mode>" 13868 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand") 13869 (unspec:<FP128_64> 13870 [(match_operand:FMOVE128 1 "register_operand") 13871 (match_operand:QI 2 "const_0_to_1_operand")] 13872 UNSPEC_UNPACK_128BIT))] 13873 "FLOAT128_2REG_P (<MODE>mode)" 13874 "") 13875 13876(define_insn_and_split "unpack<mode>_dm" 13877 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m") 13878 (unspec:<FP128_64> 13879 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r") 13880 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")] 13881 UNSPEC_UNPACK_128BIT))] 13882 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)" 13883 "#" 13884 "&& reload_completed" 13885 [(set (match_dup 0) (match_dup 3))] 13886{ 13887 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 13888 13889 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 13890 { 13891 emit_note (NOTE_INSN_DELETED); 13892 DONE; 13893 } 13894 13895 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 13896} 13897 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")]) 13898 13899(define_insn_and_split "unpack<mode>_nodm" 13900 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m") 13901 (unspec:<FP128_64> 13902 [(match_operand:FMOVE128 1 "register_operand" "d,d") 13903 (match_operand:QI 2 "const_0_to_1_operand" "i,i")] 13904 UNSPEC_UNPACK_128BIT))] 13905 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)" 13906 "#" 13907 "&& reload_completed" 13908 [(set (match_dup 0) (match_dup 3))] 13909{ 13910 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 13911 13912 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 13913 { 13914 emit_note (NOTE_INSN_DELETED); 13915 DONE; 13916 } 13917 13918 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 13919} 13920 [(set_attr "type" "fp,fpstore")]) 13921 13922(define_insn_and_split "pack<mode>" 13923 [(set (match_operand:FMOVE128 0 "register_operand" "=&d") 13924 (unspec:FMOVE128 13925 [(match_operand:<FP128_64> 1 "register_operand" "d") 13926 (match_operand:<FP128_64> 2 "register_operand" "d")] 13927 UNSPEC_PACK_128BIT))] 13928 "FLOAT128_2REG_P (<MODE>mode)" 13929 "#" 13930 "&& reload_completed" 13931 [(set (match_dup 3) (match_dup 1)) 13932 (set (match_dup 4) (match_dup 2))] 13933{ 13934 unsigned dest_hi = REGNO (operands[0]); 13935 unsigned dest_lo = dest_hi + 1; 13936 13937 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo)); 13938 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); 13939 13940 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); 13941 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); 13942} 13943 [(set_attr "type" "fp") 13944 (set_attr "length" "8")]) 13945 13946(define_insn "unpack<mode>" 13947 [(set (match_operand:DI 0 "register_operand" "=wa,wa") 13948 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa") 13949 (match_operand:QI 2 "const_0_to_1_operand" "O,i")] 13950 UNSPEC_UNPACK_128BIT))] 13951 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 13952{ 13953 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0) 13954 return ASM_COMMENT_START " xxpermdi to same register"; 13955 13956 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3); 13957 return "xxpermdi %x0,%x1,%x1,%3"; 13958} 13959 [(set_attr "type" "vecperm")]) 13960 13961(define_insn "pack<mode>" 13962 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa") 13963 (unspec:FMOVE128_VSX 13964 [(match_operand:DI 1 "register_operand" "wa") 13965 (match_operand:DI 2 "register_operand" "wa")] 13966 UNSPEC_PACK_128BIT))] 13967 "TARGET_VSX" 13968 "xxpermdi %x0,%x1,%x2,0" 13969 [(set_attr "type" "vecperm")]) 13970 13971 13972 13973;; ISA 2.08 IEEE 128-bit floating point support. 13974 13975(define_insn "add<mode>3" 13976 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13977 (plus:IEEE128 13978 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13979 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13980 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13981 "xsaddqp %0,%1,%2" 13982 [(set_attr "type" "vecfloat") 13983 (set_attr "size" "128")]) 13984 13985(define_insn "sub<mode>3" 13986 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13987 (minus:IEEE128 13988 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13989 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13990 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13991 "xssubqp %0,%1,%2" 13992 [(set_attr "type" "vecfloat") 13993 (set_attr "size" "128")]) 13994 13995(define_insn "mul<mode>3" 13996 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13997 (mult:IEEE128 13998 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13999 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14000 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14001 "xsmulqp %0,%1,%2" 14002 [(set_attr "type" "qmul") 14003 (set_attr "size" "128")]) 14004 14005(define_insn "div<mode>3" 14006 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14007 (div:IEEE128 14008 (match_operand:IEEE128 1 "altivec_register_operand" "v") 14009 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14010 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14011 "xsdivqp %0,%1,%2" 14012 [(set_attr "type" "vecdiv") 14013 (set_attr "size" "128")]) 14014 14015(define_insn "sqrt<mode>2" 14016 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14017 (sqrt:IEEE128 14018 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14019 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14020 "xssqrtqp %0,%1" 14021 [(set_attr "type" "vecdiv") 14022 (set_attr "size" "128")]) 14023 14024(define_expand "copysign<mode>3" 14025 [(use (match_operand:IEEE128 0 "altivec_register_operand")) 14026 (use (match_operand:IEEE128 1 "altivec_register_operand")) 14027 (use (match_operand:IEEE128 2 "altivec_register_operand"))] 14028 "FLOAT128_IEEE_P (<MODE>mode)" 14029{ 14030 if (TARGET_FLOAT128_HW) 14031 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1], 14032 operands[2])); 14033 else 14034 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1], 14035 operands[2])); 14036 DONE; 14037}) 14038 14039(define_insn "copysign<mode>3_hard" 14040 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14041 (unspec:IEEE128 14042 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14043 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14044 UNSPEC_COPYSIGN))] 14045 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14046 "xscpsgnqp %0,%2,%1" 14047 [(set_attr "type" "vecmove") 14048 (set_attr "size" "128")]) 14049 14050(define_insn "copysign<mode>3_soft" 14051 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14052 (unspec:IEEE128 14053 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14054 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14055 UNSPEC_COPYSIGN)) 14056 (clobber (match_scratch:IEEE128 3 "=&v"))] 14057 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14058 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1" 14059 [(set_attr "type" "veccomplex") 14060 (set_attr "length" "8")]) 14061 14062(define_insn "@neg<mode>2_hw" 14063 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14064 (neg:IEEE128 14065 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14066 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14067 "xsnegqp %0,%1" 14068 [(set_attr "type" "vecmove") 14069 (set_attr "size" "128")]) 14070 14071 14072(define_insn "@abs<mode>2_hw" 14073 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14074 (abs:IEEE128 14075 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14076 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14077 "xsabsqp %0,%1" 14078 [(set_attr "type" "vecmove") 14079 (set_attr "size" "128")]) 14080 14081 14082(define_insn "*nabs<mode>2_hw" 14083 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14084 (neg:IEEE128 14085 (abs:IEEE128 14086 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))] 14087 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14088 "xsnabsqp %0,%1" 14089 [(set_attr "type" "vecmove") 14090 (set_attr "size" "128")]) 14091 14092;; Initially don't worry about doing fusion 14093(define_insn "fma<mode>4_hw" 14094 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14095 (fma:IEEE128 14096 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14097 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14098 (match_operand:IEEE128 3 "altivec_register_operand" "0")))] 14099 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14100 "xsmaddqp %0,%1,%2" 14101 [(set_attr "type" "qmul") 14102 (set_attr "size" "128")]) 14103 14104(define_insn "*fms<mode>4_hw" 14105 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14106 (fma:IEEE128 14107 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14108 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14109 (neg:IEEE128 14110 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 14111 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14112 "xsmsubqp %0,%1,%2" 14113 [(set_attr "type" "qmul") 14114 (set_attr "size" "128")]) 14115 14116(define_insn "*nfma<mode>4_hw" 14117 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14118 (neg:IEEE128 14119 (fma:IEEE128 14120 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14121 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14122 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 14123 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14124 "xsnmaddqp %0,%1,%2" 14125 [(set_attr "type" "qmul") 14126 (set_attr "size" "128")]) 14127 14128(define_insn "*nfms<mode>4_hw" 14129 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14130 (neg:IEEE128 14131 (fma:IEEE128 14132 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14133 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14134 (neg:IEEE128 14135 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))] 14136 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14137 "xsnmsubqp %0,%1,%2" 14138 [(set_attr "type" "qmul") 14139 (set_attr "size" "128")]) 14140 14141(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw" 14142 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14143 (float_extend:IEEE128 14144 (match_operand:SFDF 1 "altivec_register_operand" "v")))] 14145 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14146 "xscvdpqp %0,%1" 14147 [(set_attr "type" "vecfloat") 14148 (set_attr "size" "128")]) 14149 14150;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating 14151;; point is a simple copy. 14152(define_insn_and_split "extendkftf2" 14153 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa") 14154 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))] 14155 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD" 14156 "@ 14157 # 14158 xxlor %x0,%x1,%x1" 14159 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 14160 [(const_int 0)] 14161{ 14162 emit_note (NOTE_INSN_DELETED); 14163 DONE; 14164} 14165 [(set_attr "type" "*,veclogical") 14166 (set_attr "length" "0,4")]) 14167 14168(define_insn_and_split "trunctfkf2" 14169 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa") 14170 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))] 14171 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD" 14172 "@ 14173 # 14174 xxlor %x0,%x1,%x1" 14175 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 14176 [(const_int 0)] 14177{ 14178 emit_note (NOTE_INSN_DELETED); 14179 DONE; 14180} 14181 [(set_attr "type" "*,veclogical") 14182 (set_attr "length" "0,4")]) 14183 14184(define_insn "trunc<mode>df2_hw" 14185 [(set (match_operand:DF 0 "altivec_register_operand" "=v") 14186 (float_truncate:DF 14187 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14188 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14189 "xscvqpdp %0,%1" 14190 [(set_attr "type" "vecfloat") 14191 (set_attr "size" "128")]) 14192 14193;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing 14194;; the KFmode -> DFmode conversion using round to odd rather than the normal 14195;; conversion 14196(define_insn_and_split "trunc<mode>sf2_hw" 14197 [(set (match_operand:SF 0 "vsx_register_operand" "=wa") 14198 (float_truncate:SF 14199 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 14200 (clobber (match_scratch:DF 2 "=v"))] 14201 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14202 "#" 14203 "&& 1" 14204 [(set (match_dup 2) 14205 (unspec:DF [(match_dup 1)] 14206 UNSPEC_TRUNC_ROUND_TO_ODD)) 14207 (set (match_dup 0) 14208 (float_truncate:SF (match_dup 2)))] 14209{ 14210 if (GET_CODE (operands[2]) == SCRATCH) 14211 operands[2] = gen_reg_rtx (DFmode); 14212} 14213 [(set_attr "type" "vecfloat") 14214 (set_attr "length" "8") 14215 (set_attr "isa" "p8v")]) 14216 14217;; Conversion between IEEE 128-bit and integer types 14218 14219;; The fix function for DImode and SImode was declared earlier as a 14220;; define_expand. It calls into rs6000_expand_float128_convert if we don't 14221;; have IEEE 128-bit hardware support. QImode and HImode are not provided 14222;; unless we have the IEEE 128-bit hardware. 14223;; 14224;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have 14225;; to provide a GPR target that used direct move and a conversion in the GPR 14226;; which works around QImode/HImode not being allowed in vector registers in 14227;; ISA 2.07 (power8). 14228(define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw" 14229 [(set (match_operand:SDI 0 "altivec_register_operand" "=v") 14230 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14231 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14232 "xscvqp<su><wd>z %0,%1" 14233 [(set_attr "type" "vecfloat") 14234 (set_attr "size" "128")]) 14235 14236(define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2" 14237 [(set (match_operand:QHI 0 "altivec_register_operand" "=v") 14238 (any_fix:QHI 14239 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14240 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14241 "xscvqp<su>wz %0,%1" 14242 [(set_attr "type" "vecfloat") 14243 (set_attr "size" "128")]) 14244 14245;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit 14246;; floating point value to 8/16/32-bit integer to GPR in order to save it. 14247(define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem" 14248 [(set (match_operand:QHSI 0 "memory_operand" "=Z") 14249 (any_fix:QHSI 14250 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 14251 (clobber (match_scratch:QHSI 2 "=v"))] 14252 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14253 "#" 14254 "&& reload_completed" 14255 [(set (match_dup 2) 14256 (any_fix:QHSI (match_dup 1))) 14257 (set (match_dup 0) 14258 (match_dup 2))]) 14259 14260(define_insn "float_<mode>di2_hw" 14261 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14262 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))] 14263 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14264 "xscvsdqp %0,%1" 14265 [(set_attr "type" "vecfloat") 14266 (set_attr "size" "128")]) 14267 14268(define_insn_and_split "float_<mode>si2_hw" 14269 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14270 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ"))) 14271 (clobber (match_scratch:DI 2 "=v"))] 14272 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14273 "#" 14274 "&& 1" 14275 [(set (match_dup 2) 14276 (sign_extend:DI (match_dup 1))) 14277 (set (match_dup 0) 14278 (float:IEEE128 (match_dup 2)))] 14279{ 14280 if (GET_CODE (operands[2]) == SCRATCH) 14281 operands[2] = gen_reg_rtx (DImode); 14282 14283 if (MEM_P (operands[1])) 14284 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 14285}) 14286 14287(define_insn_and_split "float<QHI:mode><IEEE128:mode>2" 14288 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 14289 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) 14290 (clobber (match_scratch:DI 2 "=X,r,X"))] 14291 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14292 "#" 14293 "&& reload_completed" 14294 [(const_int 0)] 14295{ 14296 rtx dest = operands[0]; 14297 rtx src = operands[1]; 14298 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest)); 14299 14300 if (altivec_register_operand (src, <QHI:MODE>mode)) 14301 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src)); 14302 else if (int_reg_operand (src, <QHI:MODE>mode)) 14303 { 14304 rtx ext_di = operands[2]; 14305 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src)); 14306 emit_move_insn (dest_di, ext_di); 14307 } 14308 else if (MEM_P (src)) 14309 { 14310 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest)); 14311 emit_move_insn (dest_qhi, src); 14312 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi)); 14313 } 14314 else 14315 gcc_unreachable (); 14316 14317 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di)); 14318 DONE; 14319} 14320 [(set_attr "length" "8,12,12") 14321 (set_attr "type" "vecfloat") 14322 (set_attr "size" "128")]) 14323 14324(define_insn "floatuns_<mode>di2_hw" 14325 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14326 (unsigned_float:IEEE128 14327 (match_operand:DI 1 "altivec_register_operand" "v")))] 14328 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14329 "xscvudqp %0,%1" 14330 [(set_attr "type" "vecfloat") 14331 (set_attr "size" "128")]) 14332 14333(define_insn_and_split "floatuns_<mode>si2_hw" 14334 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14335 (unsigned_float:IEEE128 14336 (match_operand:SI 1 "nonimmediate_operand" "vrZ"))) 14337 (clobber (match_scratch:DI 2 "=v"))] 14338 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14339 "#" 14340 "&& 1" 14341 [(set (match_dup 2) 14342 (zero_extend:DI (match_dup 1))) 14343 (set (match_dup 0) 14344 (float:IEEE128 (match_dup 2)))] 14345{ 14346 if (GET_CODE (operands[2]) == SCRATCH) 14347 operands[2] = gen_reg_rtx (DImode); 14348 14349 if (MEM_P (operands[1])) 14350 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 14351}) 14352 14353(define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2" 14354 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 14355 (unsigned_float:IEEE128 14356 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) 14357 (clobber (match_scratch:DI 2 "=X,r,X"))] 14358 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14359 "#" 14360 "&& reload_completed" 14361 [(const_int 0)] 14362{ 14363 rtx dest = operands[0]; 14364 rtx src = operands[1]; 14365 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest)); 14366 14367 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src)) 14368 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src)); 14369 else if (int_reg_operand (src, <QHI:MODE>mode)) 14370 { 14371 rtx ext_di = operands[2]; 14372 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src)); 14373 emit_move_insn (dest_di, ext_di); 14374 } 14375 else 14376 gcc_unreachable (); 14377 14378 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di)); 14379 DONE; 14380} 14381 [(set_attr "length" "8,12,8") 14382 (set_attr "type" "vecfloat") 14383 (set_attr "size" "128")]) 14384 14385;; IEEE 128-bit round to integer built-in functions 14386(define_insn "floor<mode>2" 14387 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14388 (unspec:IEEE128 14389 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14390 UNSPEC_FRIM))] 14391 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14392 "xsrqpi 1,%0,%1,3" 14393 [(set_attr "type" "vecfloat") 14394 (set_attr "size" "128")]) 14395 14396(define_insn "ceil<mode>2" 14397 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14398 (unspec:IEEE128 14399 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14400 UNSPEC_FRIP))] 14401 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14402 "xsrqpi 1,%0,%1,2" 14403 [(set_attr "type" "vecfloat") 14404 (set_attr "size" "128")]) 14405 14406(define_insn "btrunc<mode>2" 14407 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14408 (unspec:IEEE128 14409 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14410 UNSPEC_FRIZ))] 14411 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14412 "xsrqpi 1,%0,%1,1" 14413 [(set_attr "type" "vecfloat") 14414 (set_attr "size" "128")]) 14415 14416(define_insn "round<mode>2" 14417 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14418 (unspec:IEEE128 14419 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14420 UNSPEC_FRIN))] 14421 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14422 "xsrqpi 0,%0,%1,0" 14423 [(set_attr "type" "vecfloat") 14424 (set_attr "size" "128")]) 14425 14426;; IEEE 128-bit instructions with round to odd semantics 14427(define_insn "add<mode>3_odd" 14428 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14429 (unspec:IEEE128 14430 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14431 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14432 UNSPEC_ADD_ROUND_TO_ODD))] 14433 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14434 "xsaddqpo %0,%1,%2" 14435 [(set_attr "type" "vecfloat") 14436 (set_attr "size" "128")]) 14437 14438(define_insn "sub<mode>3_odd" 14439 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14440 (unspec:IEEE128 14441 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14442 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14443 UNSPEC_SUB_ROUND_TO_ODD))] 14444 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14445 "xssubqpo %0,%1,%2" 14446 [(set_attr "type" "vecfloat") 14447 (set_attr "size" "128")]) 14448 14449(define_insn "mul<mode>3_odd" 14450 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14451 (unspec:IEEE128 14452 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14453 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14454 UNSPEC_MUL_ROUND_TO_ODD))] 14455 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14456 "xsmulqpo %0,%1,%2" 14457 [(set_attr "type" "qmul") 14458 (set_attr "size" "128")]) 14459 14460(define_insn "div<mode>3_odd" 14461 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14462 (unspec:IEEE128 14463 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14464 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14465 UNSPEC_DIV_ROUND_TO_ODD))] 14466 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14467 "xsdivqpo %0,%1,%2" 14468 [(set_attr "type" "vecdiv") 14469 (set_attr "size" "128")]) 14470 14471(define_insn "sqrt<mode>2_odd" 14472 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14473 (unspec:IEEE128 14474 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14475 UNSPEC_SQRT_ROUND_TO_ODD))] 14476 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14477 "xssqrtqpo %0,%1" 14478 [(set_attr "type" "vecdiv") 14479 (set_attr "size" "128")]) 14480 14481(define_insn "fma<mode>4_odd" 14482 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14483 (unspec:IEEE128 14484 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14485 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14486 (match_operand:IEEE128 3 "altivec_register_operand" "0")] 14487 UNSPEC_FMA_ROUND_TO_ODD))] 14488 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14489 "xsmaddqpo %0,%1,%2" 14490 [(set_attr "type" "qmul") 14491 (set_attr "size" "128")]) 14492 14493(define_insn "*fms<mode>4_odd" 14494 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14495 (unspec:IEEE128 14496 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 14497 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14498 (neg:IEEE128 14499 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] 14500 UNSPEC_FMA_ROUND_TO_ODD))] 14501 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14502 "xsmsubqpo %0,%1,%2" 14503 [(set_attr "type" "qmul") 14504 (set_attr "size" "128")]) 14505 14506(define_insn "*nfma<mode>4_odd" 14507 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14508 (neg:IEEE128 14509 (unspec:IEEE128 14510 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 14511 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14512 (match_operand:IEEE128 3 "altivec_register_operand" "0")] 14513 UNSPEC_FMA_ROUND_TO_ODD)))] 14514 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14515 "xsnmaddqpo %0,%1,%2" 14516 [(set_attr "type" "qmul") 14517 (set_attr "size" "128")]) 14518 14519(define_insn "*nfms<mode>4_odd" 14520 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14521 (neg:IEEE128 14522 (unspec:IEEE128 14523 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 14524 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14525 (neg:IEEE128 14526 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] 14527 UNSPEC_FMA_ROUND_TO_ODD)))] 14528 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14529 "xsnmsubqpo %0,%1,%2" 14530 [(set_attr "type" "qmul") 14531 (set_attr "size" "128")]) 14532 14533(define_insn "trunc<mode>df2_odd" 14534 [(set (match_operand:DF 0 "vsx_register_operand" "=v") 14535 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14536 UNSPEC_TRUNC_ROUND_TO_ODD))] 14537 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14538 "xscvqpdpo %0,%1" 14539 [(set_attr "type" "vecfloat") 14540 (set_attr "size" "128")]) 14541 14542;; IEEE 128-bit comparisons 14543(define_insn "*cmp<mode>_hw" 14544 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 14545 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v") 14546 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14547 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14548 "xscmpuqp %0,%1,%2" 14549 [(set_attr "type" "veccmp") 14550 (set_attr "size" "128")]) 14551 14552;; Miscellaneous ISA 3.0 (power9) instructions 14553 14554(define_insn "darn_32" 14555 [(set (match_operand:SI 0 "register_operand" "=r") 14556 (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))] 14557 "TARGET_P9_MISC" 14558 "darn %0,0" 14559 [(set_attr "type" "integer")]) 14560 14561(define_insn "darn_raw" 14562 [(set (match_operand:DI 0 "register_operand" "=r") 14563 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))] 14564 "TARGET_P9_MISC && TARGET_64BIT" 14565 "darn %0,2" 14566 [(set_attr "type" "integer")]) 14567 14568(define_insn "darn" 14569 [(set (match_operand:DI 0 "register_operand" "=r") 14570 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))] 14571 "TARGET_P9_MISC && TARGET_64BIT" 14572 "darn %0,1" 14573 [(set_attr "type" "integer")]) 14574 14575;; Test byte within range. 14576;; 14577;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14578;; represents a byte whose value is ignored in this context and 14579;; vv, the least significant byte, holds the byte value that is to 14580;; be tested for membership within the range specified by operand 2. 14581;; The bytes of operand 2 are organized as xx:xx:hi:lo. 14582;; 14583;; Return in target register operand 0 a value of 1 if lo <= vv and 14584;; vv <= hi. Otherwise, set register operand 0 to 0. 14585;; 14586;; Though the instructions to which this expansion maps operate on 14587;; 64-bit registers, the current implementation only operates on 14588;; SI-mode operands as the high-order bits provide no information 14589;; that is not already available in the low-order bits. To avoid the 14590;; costs of data widening operations, future enhancements might allow 14591;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 14592(define_expand "cmprb" 14593 [(set (match_dup 3) 14594 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14595 (match_operand:SI 2 "gpc_reg_operand" "r")] 14596 UNSPEC_CMPRB)) 14597 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 14598 (if_then_else:SI (lt (match_dup 3) 14599 (const_int 0)) 14600 (const_int -1) 14601 (if_then_else (gt (match_dup 3) 14602 (const_int 0)) 14603 (const_int 1) 14604 (const_int 0))))] 14605 "TARGET_P9_MISC" 14606{ 14607 operands[3] = gen_reg_rtx (CCmode); 14608}) 14609 14610;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14611;; represents a byte whose value is ignored in this context and 14612;; vv, the least significant byte, holds the byte value that is to 14613;; be tested for membership within the range specified by operand 2. 14614;; The bytes of operand 2 are organized as xx:xx:hi:lo. 14615;; 14616;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if 14617;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other 14618;; 3 bits of the target CR register are all set to 0. 14619(define_insn "*cmprb_internal" 14620 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 14621 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14622 (match_operand:SI 2 "gpc_reg_operand" "r")] 14623 UNSPEC_CMPRB))] 14624 "TARGET_P9_MISC" 14625 "cmprb %0,0,%1,%2" 14626 [(set_attr "type" "logical")]) 14627 14628;; Set operand 0 register to -1 if the LT bit (0x8) of condition 14629;; register operand 1 is on. Otherwise, set operand 0 register to 1 14630;; if the GT bit (0x4) of condition register operand 1 is on. 14631;; Otherwise, set operand 0 to 0. Note that the result stored into 14632;; register operand 0 is non-zero iff either the LT or GT bits are on 14633;; within condition register operand 1. 14634(define_insn "setb_signed" 14635 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 14636 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y") 14637 (const_int 0)) 14638 (const_int -1) 14639 (if_then_else (gt (match_dup 1) 14640 (const_int 0)) 14641 (const_int 1) 14642 (const_int 0))))] 14643 "TARGET_P9_MISC" 14644 "setb %0,%1" 14645 [(set_attr "type" "logical")]) 14646 14647(define_insn "setb_unsigned" 14648 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 14649 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y") 14650 (const_int 0)) 14651 (const_int -1) 14652 (if_then_else (gtu (match_dup 1) 14653 (const_int 0)) 14654 (const_int 1) 14655 (const_int 0))))] 14656 "TARGET_P9_MISC" 14657 "setb %0,%1" 14658 [(set_attr "type" "logical")]) 14659 14660;; Test byte within two ranges. 14661;; 14662;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14663;; represents a byte whose value is ignored in this context and 14664;; vv, the least significant byte, holds the byte value that is to 14665;; be tested for membership within the range specified by operand 2. 14666;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. 14667;; 14668;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and 14669;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register 14670;; operand 0 to 0. 14671;; 14672;; Though the instructions to which this expansion maps operate on 14673;; 64-bit registers, the current implementation only operates on 14674;; SI-mode operands as the high-order bits provide no information 14675;; that is not already available in the low-order bits. To avoid the 14676;; costs of data widening operations, future enhancements might allow 14677;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 14678(define_expand "cmprb2" 14679 [(set (match_dup 3) 14680 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14681 (match_operand:SI 2 "gpc_reg_operand" "r")] 14682 UNSPEC_CMPRB2)) 14683 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 14684 (if_then_else:SI (lt (match_dup 3) 14685 (const_int 0)) 14686 (const_int -1) 14687 (if_then_else (gt (match_dup 3) 14688 (const_int 0)) 14689 (const_int 1) 14690 (const_int 0))))] 14691 "TARGET_P9_MISC" 14692{ 14693 operands[3] = gen_reg_rtx (CCmode); 14694}) 14695 14696;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14697;; represents a byte whose value is ignored in this context and 14698;; vv, the least significant byte, holds the byte value that is to 14699;; be tested for membership within the ranges specified by operand 2. 14700;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. 14701;; 14702;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if 14703;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). 14704;; Otherwise, set the GT bit to 0. The other 3 bits of the target 14705;; CR register are all set to 0. 14706(define_insn "*cmprb2_internal" 14707 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 14708 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14709 (match_operand:SI 2 "gpc_reg_operand" "r")] 14710 UNSPEC_CMPRB2))] 14711 "TARGET_P9_MISC" 14712 "cmprb %0,1,%1,%2" 14713 [(set_attr "type" "logical")]) 14714 14715;; Test byte membership within set of 8 bytes. 14716;; 14717;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14718;; represents a byte whose value is ignored in this context and 14719;; vv, the least significant byte, holds the byte value that is to 14720;; be tested for membership within the set specified by operand 2. 14721;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. 14722;; 14723;; Return in target register operand 0 a value of 1 if vv equals one 14724;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set 14725;; register operand 0 to 0. Note that the 8 byte values held within 14726;; operand 2 need not be unique. 14727;; 14728;; Though the instructions to which this expansion maps operate on 14729;; 64-bit registers, the current implementation requires that operands 14730;; 0 and 1 have mode SI as the high-order bits provide no information 14731;; that is not already available in the low-order bits. To avoid the 14732;; costs of data widening operations, future enhancements might allow 14733;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 14734(define_expand "cmpeqb" 14735 [(set (match_dup 3) 14736 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14737 (match_operand:DI 2 "gpc_reg_operand" "r")] 14738 UNSPEC_CMPEQB)) 14739 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 14740 (if_then_else:SI (lt (match_dup 3) 14741 (const_int 0)) 14742 (const_int -1) 14743 (if_then_else (gt (match_dup 3) 14744 (const_int 0)) 14745 (const_int 1) 14746 (const_int 0))))] 14747 "TARGET_P9_MISC && TARGET_64BIT" 14748{ 14749 operands[3] = gen_reg_rtx (CCmode); 14750}) 14751 14752;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14753;; represents a byte whose value is ignored in this context and 14754;; vv, the least significant byte, holds the byte value that is to 14755;; be tested for membership within the set specified by operand 2. 14756;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. 14757;; 14758;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv 14759;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, 14760;; set the GT bit to zero. The other 3 bits of the target CR register 14761;; are all set to 0. 14762(define_insn "*cmpeqb_internal" 14763 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 14764 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14765 (match_operand:DI 2 "gpc_reg_operand" "r")] 14766 UNSPEC_CMPEQB))] 14767 "TARGET_P9_MISC && TARGET_64BIT" 14768 "cmpeqb %0,%1,%2" 14769 [(set_attr "type" "logical")]) 14770 14771 14772(include "sync.md") 14773(include "vector.md") 14774(include "vsx.md") 14775(include "altivec.md") 14776(include "mma.md") 14777(include "dfp.md") 14778(include "crypto.md") 14779(include "htm.md") 14780