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_insn "*rsqrt<mode>2" 4810 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa") 4811 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")] 4812 UNSPEC_RSQRT))] 4813 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)" 4814 "@ 4815 frsqrte<s> %0,%1 4816 xsrsqrte<sd>p %x0,%x1" 4817 [(set_attr "type" "fp") 4818 (set_attr "isa" "*,<Fisa>")]) 4819 4820;; Floating point comparisons 4821(define_insn "*cmp<mode>_fpr" 4822 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y") 4823 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa") 4824 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))] 4825 "TARGET_HARD_FLOAT" 4826 "@ 4827 fcmpu %0,%1,%2 4828 xscmpudp %0,%x1,%x2" 4829 [(set_attr "type" "fpcompare") 4830 (set_attr "isa" "*,<Fisa>")]) 4831 4832;; Floating point conversions 4833(define_expand "extendsfdf2" 4834 [(set (match_operand:DF 0 "gpc_reg_operand") 4835 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))] 4836 "TARGET_HARD_FLOAT" 4837{ 4838 if (HONOR_SNANS (SFmode)) 4839 operands[1] = force_reg (SFmode, operands[1]); 4840}) 4841 4842(define_insn_and_split "*extendsfdf2_fpr" 4843 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v") 4844 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))] 4845 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)" 4846 "@ 4847 # 4848 fmr %0,%1 4849 lfs%U1%X1 %0,%1 4850 # 4851 xscpsgndp %x0,%x1,%x1 4852 lxsspx %x0,%y1 4853 lxssp %0,%1" 4854 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])" 4855 [(const_int 0)] 4856{ 4857 emit_note (NOTE_INSN_DELETED); 4858 DONE; 4859} 4860 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload") 4861 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")]) 4862 4863(define_insn "*extendsfdf2_snan" 4864 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 4865 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))] 4866 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)" 4867 "@ 4868 frsp %0,%1 4869 xsrsp %x0,%x1" 4870 [(set_attr "type" "fp") 4871 (set_attr "isa" "*,p8v")]) 4872 4873(define_expand "truncdfsf2" 4874 [(set (match_operand:SF 0 "gpc_reg_operand") 4875 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))] 4876 "TARGET_HARD_FLOAT" 4877 "") 4878 4879(define_insn "*truncdfsf2_fpr" 4880 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa") 4881 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))] 4882 "TARGET_HARD_FLOAT" 4883 "@ 4884 frsp %0,%1 4885 xsrsp %x0,%x1" 4886 [(set_attr "type" "fp") 4887 (set_attr "isa" "*,p8v")]) 4888 4889;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in 4890;; builtins.c and optabs.c that are not correct for IBM long double 4891;; when little-endian. 4892(define_expand "signbit<mode>2" 4893 [(set (match_dup 2) 4894 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand"))) 4895 (set (match_dup 3) 4896 (subreg:DI (match_dup 2) 0)) 4897 (set (match_dup 4) 4898 (match_dup 5)) 4899 (set (match_operand:SI 0 "gpc_reg_operand") 4900 (match_dup 6))] 4901 "TARGET_HARD_FLOAT 4902 && (!FLOAT128_IEEE_P (<MODE>mode) 4903 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))" 4904{ 4905 if (FLOAT128_IEEE_P (<MODE>mode)) 4906 { 4907 rtx dest = operands[0]; 4908 rtx src = operands[1]; 4909 rtx tmp = gen_reg_rtx (DImode); 4910 rtx dest_di = gen_lowpart (DImode, dest); 4911 4912 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src)); 4913 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63))); 4914 DONE; 4915 } 4916 operands[2] = gen_reg_rtx (DFmode); 4917 operands[3] = gen_reg_rtx (DImode); 4918 if (TARGET_POWERPC64) 4919 { 4920 operands[4] = gen_reg_rtx (DImode); 4921 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63)); 4922 operands[6] = gen_rtx_SUBREG (SImode, operands[4], 4923 WORDS_BIG_ENDIAN ? 4 : 0); 4924 } 4925 else 4926 { 4927 operands[4] = gen_reg_rtx (SImode); 4928 operands[5] = gen_rtx_SUBREG (SImode, operands[3], 4929 WORDS_BIG_ENDIAN ? 0 : 4); 4930 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31)); 4931 } 4932}) 4933 4934;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid 4935;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the 4936;; register allocator would typically move the entire _Float128 item to GPRs (2 4937;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07). 4938;; 4939;; After register allocation, if the _Float128 had originally been in GPRs, the 4940;; split allows the post reload phases to eliminate the move, and do the shift 4941;; directly with the register that contains the signbit. 4942(define_insn_and_split "@signbit<mode>2_dm" 4943 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r") 4944 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")] 4945 UNSPEC_SIGNBIT))] 4946 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 4947 "@ 4948 mfvsrd %0,%x1 4949 #" 4950 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)" 4951 [(set (match_dup 0) 4952 (match_dup 2))] 4953{ 4954 operands[2] = gen_highpart (DImode, operands[1]); 4955} 4956 [(set_attr "type" "mftgpr,*")]) 4957 4958;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector 4959;; register and then doing a direct move if the value comes from memory. On 4960;; little endian, we have to load the 2nd double-word to get the sign bit. 4961(define_insn_and_split "*signbit<mode>2_dm_mem" 4962 [(set (match_operand:DI 0 "gpc_reg_operand" "=b") 4963 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")] 4964 UNSPEC_SIGNBIT))] 4965 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 4966 "#" 4967 "&& 1" 4968 [(set (match_dup 0) 4969 (match_dup 2))] 4970{ 4971 rtx dest = operands[0]; 4972 rtx src = operands[1]; 4973 rtx addr = XEXP (src, 0); 4974 4975 if (WORDS_BIG_ENDIAN) 4976 operands[2] = adjust_address (src, DImode, 0); 4977 4978 else if (REG_P (addr) || SUBREG_P (addr)) 4979 operands[2] = adjust_address (src, DImode, 8); 4980 4981 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0)) 4982 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode)) 4983 operands[2] = adjust_address (src, DImode, 8); 4984 4985 else 4986 { 4987 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest; 4988 emit_insn (gen_rtx_SET (tmp, addr)); 4989 operands[2] = change_address (src, DImode, 4990 gen_rtx_PLUS (DImode, tmp, GEN_INT (8))); 4991 } 4992}) 4993 4994(define_expand "copysign<mode>3" 4995 [(set (match_dup 3) 4996 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand"))) 4997 (set (match_dup 4) 4998 (neg:SFDF (abs:SFDF (match_dup 1)))) 4999 (set (match_operand:SFDF 0 "gpc_reg_operand") 5000 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand") 5001 (match_dup 5)) 5002 (match_dup 3) 5003 (match_dup 4)))] 5004 "TARGET_HARD_FLOAT 5005 && ((TARGET_PPC_GFXOPT 5006 && !HONOR_NANS (<MODE>mode) 5007 && !HONOR_SIGNED_ZEROS (<MODE>mode)) 5008 || TARGET_CMPB 5009 || VECTOR_UNIT_VSX_P (<MODE>mode))" 5010{ 5011 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode)) 5012 { 5013 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1], 5014 operands[2])); 5015 DONE; 5016 } 5017 5018 operands[3] = gen_reg_rtx (<MODE>mode); 5019 operands[4] = gen_reg_rtx (<MODE>mode); 5020 operands[5] = CONST0_RTX (<MODE>mode); 5021 }) 5022 5023;; Use an unspec rather providing an if-then-else in RTL, to prevent the 5024;; compiler from optimizing -0.0 5025(define_insn "copysign<mode>3_fcpsgn" 5026 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 5027 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>") 5028 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")] 5029 UNSPEC_COPYSIGN))] 5030 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))" 5031 "@ 5032 fcpsgn %0,%2,%1 5033 xscpsgndp %x0,%x2,%x1" 5034 [(set_attr "type" "fpsimple")]) 5035 5036;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a 5037;; fsel instruction and some auxiliary computations. Then we just have a 5038;; single DEFINE_INSN for fsel and the define_splits to make them if made by 5039;; combine. 5040;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we 5041;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary 5042;; computations. Then we just have a single DEFINE_INSN for fsel and the 5043;; define_splits to make them if made by combine. On VSX machines we have the 5044;; min/max instructions. 5045;; 5046;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector 5047;; to allow either DF/SF to use only traditional registers. 5048 5049(define_expand "s<minmax><mode>3" 5050 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5051 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 5052 (match_operand:SFDF 2 "gpc_reg_operand")))] 5053 "TARGET_MINMAX" 5054{ 5055 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 5056 DONE; 5057}) 5058 5059(define_insn "*s<minmax><mode>3_vsx" 5060 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 5061 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>") 5062 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))] 5063 "TARGET_VSX && TARGET_HARD_FLOAT" 5064{ 5065 return (TARGET_P9_MINMAX 5066 ? "xs<minmax>cdp %x0,%x1,%x2" 5067 : "xs<minmax>dp %x0,%x1,%x2"); 5068} 5069 [(set_attr "type" "fp")]) 5070 5071;; The conditional move instructions allow us to perform max and min operations 5072;; even when we don't have the appropriate max/min instruction using the FSEL 5073;; instruction. 5074 5075(define_insn_and_split "*s<minmax><mode>3_fpr" 5076 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5077 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand") 5078 (match_operand:SFDF 2 "gpc_reg_operand")))] 5079 "!TARGET_VSX && TARGET_MINMAX" 5080 "#" 5081 "&& 1" 5082 [(const_int 0)] 5083{ 5084 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]); 5085 DONE; 5086}) 5087 5088(define_expand "mov<mode>cc" 5089 [(set (match_operand:GPR 0 "gpc_reg_operand") 5090 (if_then_else:GPR (match_operand 1 "comparison_operator") 5091 (match_operand:GPR 2 "gpc_reg_operand") 5092 (match_operand:GPR 3 "gpc_reg_operand")))] 5093 "TARGET_ISEL" 5094{ 5095 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 5096 DONE; 5097 else 5098 FAIL; 5099}) 5100 5101;; We use the BASE_REGS for the isel input operands because, if rA is 5102;; 0, the value of 0 is placed in rD upon truth. Similarly for rB 5103;; because we may switch the operands and rB may end up being rA. 5104;; 5105;; We need 2 patterns: an unsigned and a signed pattern. We could 5106;; leave out the mode in operand 4 and use one pattern, but reload can 5107;; change the mode underneath our feet and then gets confused trying 5108;; to reload the value. 5109(define_mode_iterator CCEITHER [CC CCUNS]) 5110(define_mode_attr un [(CC "") (CCUNS "un")]) 5111(define_insn "isel_<un>signed_<GPR:mode>" 5112 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 5113 (if_then_else:GPR 5114 (match_operator 1 "scc_comparison_operator" 5115 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y") 5116 (const_int 0)]) 5117 (match_operand:GPR 2 "reg_or_zero_operand" "O,b") 5118 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))] 5119 "TARGET_ISEL" 5120 "isel %0,%2,%3,%j1" 5121 [(set_attr "type" "isel")]) 5122 5123;; These patterns can be useful for combine; they let combine know that 5124;; isel can handle reversed comparisons so long as the operands are 5125;; registers. 5126 5127(define_insn "*isel_reversed_<un>signed_<GPR:mode>" 5128 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r") 5129 (if_then_else:GPR 5130 (match_operator 1 "scc_rev_comparison_operator" 5131 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y") 5132 (const_int 0)]) 5133 (match_operand:GPR 2 "gpc_reg_operand" "r,r") 5134 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))] 5135 "TARGET_ISEL" 5136{ 5137 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1]))); 5138 return "isel %0,%3,%2,%j1"; 5139} 5140 [(set_attr "type" "isel")]) 5141 5142;; Floating point conditional move 5143(define_expand "mov<mode>cc" 5144 [(set (match_operand:SFDF 0 "gpc_reg_operand") 5145 (if_then_else:SFDF (match_operand 1 "comparison_operator") 5146 (match_operand:SFDF 2 "gpc_reg_operand") 5147 (match_operand:SFDF 3 "gpc_reg_operand")))] 5148 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT" 5149{ 5150 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3])) 5151 DONE; 5152 else 5153 FAIL; 5154}) 5155 5156(define_insn "*fsel<SFDF:mode><SFDF2:mode>4" 5157 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>") 5158 (if_then_else:SFDF 5159 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>") 5160 (match_operand:SFDF2 4 "zero_fp_constant" "F")) 5161 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>") 5162 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))] 5163 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT" 5164 "fsel %0,%1,%2,%3" 5165 [(set_attr "type" "fp")]) 5166 5167(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9" 5168 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 5169 (if_then_else:SFDF 5170 (match_operator:CCFP 1 "fpmask_comparison_operator" 5171 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 5172 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 5173 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 5174 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5175 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 5176 "TARGET_P9_MINMAX" 5177 "#" 5178 "" 5179 [(set (match_dup 6) 5180 (if_then_else:V2DI (match_dup 1) 5181 (match_dup 7) 5182 (match_dup 8))) 5183 (set (match_dup 0) 5184 (if_then_else:SFDF (ne (match_dup 6) 5185 (match_dup 8)) 5186 (match_dup 4) 5187 (match_dup 5)))] 5188{ 5189 if (GET_CODE (operands[6]) == SCRATCH) 5190 operands[6] = gen_reg_rtx (V2DImode); 5191 5192 operands[7] = CONSTM1_RTX (V2DImode); 5193 operands[8] = CONST0_RTX (V2DImode); 5194} 5195 [(set_attr "length" "8") 5196 (set_attr "type" "vecperm")]) 5197 5198;; Handle inverting the fpmask comparisons. 5199(define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9" 5200 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>") 5201 (if_then_else:SFDF 5202 (match_operator:CCFP 1 "invert_fpmask_comparison_operator" 5203 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>") 5204 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")]) 5205 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>") 5206 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>"))) 5207 (clobber (match_scratch:V2DI 6 "=0,&wa"))] 5208 "TARGET_P9_MINMAX" 5209 "#" 5210 "&& 1" 5211 [(set (match_dup 6) 5212 (if_then_else:V2DI (match_dup 9) 5213 (match_dup 7) 5214 (match_dup 8))) 5215 (set (match_dup 0) 5216 (if_then_else:SFDF (ne (match_dup 6) 5217 (match_dup 8)) 5218 (match_dup 5) 5219 (match_dup 4)))] 5220{ 5221 rtx op1 = operands[1]; 5222 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1)); 5223 5224 if (GET_CODE (operands[6]) == SCRATCH) 5225 operands[6] = gen_reg_rtx (V2DImode); 5226 5227 operands[7] = CONSTM1_RTX (V2DImode); 5228 operands[8] = CONST0_RTX (V2DImode); 5229 5230 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]); 5231} 5232 [(set_attr "length" "8") 5233 (set_attr "type" "vecperm")]) 5234 5235(define_insn "*fpmask<mode>" 5236 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa") 5237 (if_then_else:V2DI 5238 (match_operator:CCFP 1 "fpmask_comparison_operator" 5239 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>") 5240 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")]) 5241 (match_operand:V2DI 4 "all_ones_constant" "") 5242 (match_operand:V2DI 5 "zero_constant" "")))] 5243 "TARGET_P9_MINMAX" 5244 "xscmp%V1dp %x0,%x2,%x3" 5245 [(set_attr "type" "fpcompare")]) 5246 5247(define_insn "*xxsel<mode>" 5248 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>") 5249 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa") 5250 (match_operand:V2DI 2 "zero_constant" "")) 5251 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>") 5252 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))] 5253 "TARGET_P9_MINMAX" 5254 "xxsel %x0,%x4,%x3,%x1" 5255 [(set_attr "type" "vecmove")]) 5256 5257 5258;; Conversions to and from floating-point. 5259 5260; We don't define lfiwax/lfiwzx with the normal definition, because we 5261; don't want to support putting SImode in FPR registers. 5262(define_insn "lfiwax" 5263 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v") 5264 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")] 5265 UNSPEC_LFIWAX))] 5266 "TARGET_HARD_FLOAT && TARGET_LFIWAX" 5267 "@ 5268 lfiwax %0,%y1 5269 lxsiwax %x0,%y1 5270 mtvsrwa %x0,%1 5271 vextsw2d %0,%1" 5272 [(set_attr "type" "fpload,fpload,mffgpr,vecexts") 5273 (set_attr "isa" "*,p8v,p8v,p9v")]) 5274 5275; This split must be run before register allocation because it allocates the 5276; memory slot that is needed to move values to/from the FPR. We don't allocate 5277; it earlier to allow for the combiner to merge insns together where it might 5278; not be needed and also in case the insns are deleted as dead code. 5279 5280(define_insn_and_split "floatsi<mode>2_lfiwax" 5281 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5282 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r"))) 5283 (clobber (match_scratch:DI 2 "=d,wa"))] 5284 "TARGET_HARD_FLOAT && TARGET_LFIWAX 5285 && <SI_CONVERT_FP> && can_create_pseudo_p ()" 5286 "#" 5287 "" 5288 [(pc)] 5289{ 5290 rtx dest = operands[0]; 5291 rtx src = operands[1]; 5292 rtx tmp; 5293 5294 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE) 5295 tmp = convert_to_mode (DImode, src, false); 5296 else 5297 { 5298 tmp = operands[2]; 5299 if (GET_CODE (tmp) == SCRATCH) 5300 tmp = gen_reg_rtx (DImode); 5301 if (MEM_P (src)) 5302 { 5303 src = rs6000_force_indexed_or_indirect_mem (src); 5304 emit_insn (gen_lfiwax (tmp, src)); 5305 } 5306 else 5307 { 5308 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5309 emit_move_insn (stack, src); 5310 emit_insn (gen_lfiwax (tmp, stack)); 5311 } 5312 } 5313 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5314 DONE; 5315} 5316 [(set_attr "length" "12") 5317 (set_attr "type" "fpload")]) 5318 5319(define_insn_and_split "floatsi<mode>2_lfiwax_mem" 5320 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5321 (float:SFDF 5322 (sign_extend:DI 5323 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z")))) 5324 (clobber (match_scratch:DI 2 "=d,wa"))] 5325 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>" 5326 "#" 5327 "" 5328 [(pc)] 5329{ 5330 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 5331 if (GET_CODE (operands[2]) == SCRATCH) 5332 operands[2] = gen_reg_rtx (DImode); 5333 if (TARGET_P8_VECTOR) 5334 emit_insn (gen_extendsidi2 (operands[2], operands[1])); 5335 else 5336 emit_insn (gen_lfiwax (operands[2], operands[1])); 5337 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5338 DONE; 5339} 5340 [(set_attr "length" "8") 5341 (set_attr "type" "fpload")]) 5342 5343(define_insn "lfiwzx" 5344 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa") 5345 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")] 5346 UNSPEC_LFIWZX))] 5347 "TARGET_HARD_FLOAT && TARGET_LFIWZX" 5348 "@ 5349 lfiwzx %0,%y1 5350 lxsiwzx %x0,%y1 5351 mtvsrwz %x0,%1 5352 xxextractuw %x0,%x1,4" 5353 [(set_attr "type" "fpload,fpload,mftgpr,vecexts") 5354 (set_attr "isa" "*,p8v,p8v,p9v")]) 5355 5356(define_insn_and_split "floatunssi<mode>2_lfiwzx" 5357 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5358 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r"))) 5359 (clobber (match_scratch:DI 2 "=d,wa"))] 5360 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" 5361 "#" 5362 "" 5363 [(pc)] 5364{ 5365 rtx dest = operands[0]; 5366 rtx src = operands[1]; 5367 rtx tmp; 5368 5369 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE) 5370 tmp = convert_to_mode (DImode, src, true); 5371 else 5372 { 5373 tmp = operands[2]; 5374 if (GET_CODE (tmp) == SCRATCH) 5375 tmp = gen_reg_rtx (DImode); 5376 if (MEM_P (src)) 5377 { 5378 src = rs6000_force_indexed_or_indirect_mem (src); 5379 emit_insn (gen_lfiwzx (tmp, src)); 5380 } 5381 else 5382 { 5383 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5384 emit_move_insn (stack, src); 5385 emit_insn (gen_lfiwzx (tmp, stack)); 5386 } 5387 } 5388 emit_insn (gen_floatdi<mode>2 (dest, tmp)); 5389 DONE; 5390} 5391 [(set_attr "length" "12") 5392 (set_attr "type" "fpload")]) 5393 5394(define_insn_and_split "floatunssi<mode>2_lfiwzx_mem" 5395 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>") 5396 (unsigned_float:SFDF 5397 (zero_extend:DI 5398 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z")))) 5399 (clobber (match_scratch:DI 2 "=d,wa"))] 5400 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>" 5401 "#" 5402 "" 5403 [(pc)] 5404{ 5405 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 5406 if (GET_CODE (operands[2]) == SCRATCH) 5407 operands[2] = gen_reg_rtx (DImode); 5408 if (TARGET_P8_VECTOR) 5409 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1])); 5410 else 5411 emit_insn (gen_lfiwzx (operands[2], operands[1])); 5412 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2])); 5413 DONE; 5414} 5415 [(set_attr "length" "8") 5416 (set_attr "type" "fpload")]) 5417 5418; For each of these conversions, there is a define_expand, a define_insn 5419; with a '#' template, and a define_split (with C code). The idea is 5420; to allow constant folding with the template of the define_insn, 5421; then to have the insns split later (between sched1 and final). 5422 5423(define_expand "floatsidf2" 5424 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand") 5425 (float:DF (match_operand:SI 1 "nonimmediate_operand"))) 5426 (use (match_dup 2)) 5427 (use (match_dup 3)) 5428 (clobber (match_dup 4)) 5429 (clobber (match_dup 5)) 5430 (clobber (match_dup 6))])] 5431 "TARGET_HARD_FLOAT" 5432{ 5433 if (TARGET_LFIWAX && TARGET_FCFID) 5434 { 5435 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1])); 5436 DONE; 5437 } 5438 else if (TARGET_FCFID) 5439 { 5440 rtx dreg = operands[1]; 5441 if (!REG_P (dreg)) 5442 dreg = force_reg (SImode, dreg); 5443 dreg = convert_to_mode (DImode, dreg, false); 5444 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5445 DONE; 5446 } 5447 5448 if (!REG_P (operands[1])) 5449 operands[1] = force_reg (SImode, operands[1]); 5450 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5451 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode)); 5452 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5453 operands[5] = gen_reg_rtx (DFmode); 5454 operands[6] = gen_reg_rtx (SImode); 5455}) 5456 5457(define_insn_and_split "*floatsidf2_internal" 5458 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5459 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5460 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5461 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5462 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5463 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d")) 5464 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))] 5465 "!TARGET_FCFID && TARGET_HARD_FLOAT" 5466 "#" 5467 "" 5468 [(pc)] 5469{ 5470 rtx lowword, highword; 5471 gcc_assert (MEM_P (operands[4])); 5472 highword = adjust_address (operands[4], SImode, 0); 5473 lowword = adjust_address (operands[4], SImode, 4); 5474 if (! WORDS_BIG_ENDIAN) 5475 std::swap (lowword, highword); 5476 5477 emit_insn (gen_xorsi3 (operands[6], operands[1], 5478 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff))); 5479 emit_move_insn (lowword, operands[6]); 5480 emit_move_insn (highword, operands[2]); 5481 emit_move_insn (operands[5], operands[4]); 5482 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5483 DONE; 5484} 5485 [(set_attr "length" "24") 5486 (set_attr "type" "fp")]) 5487 5488;; If we don't have a direct conversion to single precision, don't enable this 5489;; conversion for 32-bit without fast math, because we don't have the insn to 5490;; generate the fixup swizzle to avoid double rounding problems. 5491(define_expand "floatunssisf2" 5492 [(set (match_operand:SF 0 "gpc_reg_operand") 5493 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))] 5494 "TARGET_HARD_FLOAT 5495 && ((TARGET_FCFIDUS && TARGET_LFIWZX) 5496 || (TARGET_FCFID 5497 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" 5498{ 5499 if (TARGET_LFIWZX && TARGET_FCFIDUS) 5500 { 5501 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1])); 5502 DONE; 5503 } 5504 else 5505 { 5506 rtx dreg = operands[1]; 5507 if (!REG_P (dreg)) 5508 dreg = force_reg (SImode, dreg); 5509 dreg = convert_to_mode (DImode, dreg, true); 5510 emit_insn (gen_floatdisf2 (operands[0], dreg)); 5511 DONE; 5512 } 5513}) 5514 5515(define_expand "floatunssidf2" 5516 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand") 5517 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand"))) 5518 (use (match_dup 2)) 5519 (use (match_dup 3)) 5520 (clobber (match_dup 4)) 5521 (clobber (match_dup 5))])] 5522 "TARGET_HARD_FLOAT" 5523{ 5524 if (TARGET_LFIWZX && TARGET_FCFID) 5525 { 5526 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1])); 5527 DONE; 5528 } 5529 else if (TARGET_FCFID) 5530 { 5531 rtx dreg = operands[1]; 5532 if (!REG_P (dreg)) 5533 dreg = force_reg (SImode, dreg); 5534 dreg = convert_to_mode (DImode, dreg, true); 5535 emit_insn (gen_floatdidf2 (operands[0], dreg)); 5536 DONE; 5537 } 5538 5539 if (!REG_P (operands[1])) 5540 operands[1] = force_reg (SImode, operands[1]); 5541 operands[2] = force_reg (SImode, GEN_INT (0x43300000)); 5542 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode)); 5543 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false); 5544 operands[5] = gen_reg_rtx (DFmode); 5545}) 5546 5547(define_insn_and_split "*floatunssidf2_internal" 5548 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d") 5549 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) 5550 (use (match_operand:SI 2 "gpc_reg_operand" "r")) 5551 (use (match_operand:DF 3 "gpc_reg_operand" "d")) 5552 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o")) 5553 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))] 5554 "!TARGET_FCFIDU && TARGET_HARD_FLOAT 5555 && !(TARGET_FCFID && TARGET_POWERPC64)" 5556 "#" 5557 "" 5558 [(pc)] 5559{ 5560 rtx lowword, highword; 5561 gcc_assert (MEM_P (operands[4])); 5562 highword = adjust_address (operands[4], SImode, 0); 5563 lowword = adjust_address (operands[4], SImode, 4); 5564 if (! WORDS_BIG_ENDIAN) 5565 std::swap (lowword, highword); 5566 5567 emit_move_insn (lowword, operands[1]); 5568 emit_move_insn (highword, operands[2]); 5569 emit_move_insn (operands[5], operands[4]); 5570 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3])); 5571 DONE; 5572} 5573 [(set_attr "length" "20") 5574 (set_attr "type" "fp")]) 5575 5576;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to 5577;; vector registers. These insns favor doing the sign/zero extension in 5578;; the vector registers, rather then loading up a GPR, doing a sign/zero 5579;; extension and then a direct move. 5580 5581(define_expand "float<QHI:mode><FP_ISA3:mode>2" 5582 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") 5583 (float:FP_ISA3 5584 (match_operand:QHI 1 "input_operand"))) 5585 (clobber (match_scratch:DI 2)) 5586 (clobber (match_scratch:DI 3)) 5587 (clobber (match_scratch:<QHI:MODE> 4))])] 5588 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5589{ 5590 if (MEM_P (operands[1])) 5591 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 5592}) 5593 5594(define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal" 5595 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>") 5596 (float:FP_ISA3 5597 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z"))) 5598 (clobber (match_scratch:DI 2 "=v,wa,v")) 5599 (clobber (match_scratch:DI 3 "=X,r,X")) 5600 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))] 5601 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5602 "#" 5603 "&& reload_completed" 5604 [(const_int 0)] 5605{ 5606 rtx result = operands[0]; 5607 rtx input = operands[1]; 5608 rtx di = operands[2]; 5609 5610 if (!MEM_P (input)) 5611 { 5612 rtx tmp = operands[3]; 5613 if (altivec_register_operand (input, <QHI:MODE>mode)) 5614 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5615 else if (GET_CODE (tmp) == SCRATCH) 5616 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5617 else 5618 { 5619 emit_insn (gen_extend<QHI:mode>di2 (tmp, input)); 5620 emit_move_insn (di, tmp); 5621 } 5622 } 5623 else 5624 { 5625 rtx tmp = operands[4]; 5626 emit_move_insn (tmp, input); 5627 emit_insn (gen_extend<QHI:mode>di2 (di, tmp)); 5628 } 5629 5630 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); 5631 DONE; 5632} 5633 [(set_attr "isa" "p9v,*,p9v")]) 5634 5635(define_expand "floatuns<QHI:mode><FP_ISA3:mode>2" 5636 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand") 5637 (unsigned_float:FP_ISA3 5638 (match_operand:QHI 1 "input_operand"))) 5639 (clobber (match_scratch:DI 2)) 5640 (clobber (match_scratch:DI 3))])] 5641 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5642{ 5643 if (MEM_P (operands[1])) 5644 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 5645}) 5646 5647(define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal" 5648 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>") 5649 (unsigned_float:FP_ISA3 5650 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z"))) 5651 (clobber (match_scratch:DI 2 "=v,wa,wa")) 5652 (clobber (match_scratch:DI 3 "=X,r,X"))] 5653 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64" 5654 "#" 5655 "&& reload_completed" 5656 [(const_int 0)] 5657{ 5658 rtx result = operands[0]; 5659 rtx input = operands[1]; 5660 rtx di = operands[2]; 5661 5662 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode)) 5663 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input)); 5664 else 5665 { 5666 rtx tmp = operands[3]; 5667 if (GET_CODE (tmp) == SCRATCH) 5668 emit_insn (gen_extend<QHI:mode>di2 (di, input)); 5669 else 5670 { 5671 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input)); 5672 emit_move_insn (di, tmp); 5673 } 5674 } 5675 5676 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di)); 5677 DONE; 5678} 5679 [(set_attr "isa" "p9v,*,p9v")]) 5680 5681(define_expand "fix_trunc<mode>si2" 5682 [(set (match_operand:SI 0 "gpc_reg_operand") 5683 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))] 5684 "TARGET_HARD_FLOAT" 5685{ 5686 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)) 5687 { 5688 rtx src = force_reg (<MODE>mode, operands[1]); 5689 5690 if (TARGET_STFIWX) 5691 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src)); 5692 else 5693 { 5694 rtx tmp = gen_reg_rtx (DImode); 5695 rtx stack = rs6000_allocate_stack_temp (DImode, true, false); 5696 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src, 5697 tmp, stack)); 5698 } 5699 DONE; 5700 } 5701}) 5702 5703; Like the convert to float patterns, this insn must be split before 5704; register allocation so that it can allocate the memory slot if it 5705; needed 5706(define_insn_and_split "fix_trunc<mode>si2_stfiwx" 5707 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5708 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 5709 (clobber (match_scratch:DI 2 "=d"))] 5710 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p () 5711 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" 5712 "#" 5713 "" 5714 [(pc)] 5715{ 5716 rtx dest = operands[0]; 5717 rtx src = operands[1]; 5718 rtx tmp = operands[2]; 5719 5720 if (GET_CODE (tmp) == SCRATCH) 5721 tmp = gen_reg_rtx (DImode); 5722 5723 emit_insn (gen_fctiwz_<mode> (tmp, src)); 5724 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32)) 5725 { 5726 dest = rs6000_force_indexed_or_indirect_mem (dest); 5727 emit_insn (gen_stfiwx (dest, tmp)); 5728 DONE; 5729 } 5730 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest)) 5731 { 5732 dest = gen_lowpart (DImode, dest); 5733 emit_move_insn (dest, tmp); 5734 DONE; 5735 } 5736 else 5737 { 5738 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5739 emit_insn (gen_stfiwx (stack, tmp)); 5740 emit_move_insn (dest, stack); 5741 DONE; 5742 } 5743} 5744 [(set_attr "length" "12") 5745 (set_attr "type" "fp")]) 5746 5747(define_insn_and_split "fix_trunc<mode>si2_internal" 5748 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r") 5749 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>"))) 5750 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d")) 5751 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))] 5752 "TARGET_HARD_FLOAT 5753 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)" 5754 "#" 5755 "" 5756 [(pc)] 5757{ 5758 rtx lowword; 5759 gcc_assert (MEM_P (operands[3])); 5760 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 5761 5762 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1])); 5763 emit_move_insn (operands[3], operands[2]); 5764 emit_move_insn (operands[0], lowword); 5765 DONE; 5766} 5767 [(set_attr "length" "16") 5768 (set_attr "type" "fp")]) 5769 5770(define_expand "fix_trunc<mode>di2" 5771 [(set (match_operand:DI 0 "gpc_reg_operand") 5772 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))] 5773 "TARGET_HARD_FLOAT && TARGET_FCFID" 5774 "") 5775 5776(define_insn "*fix_trunc<mode>di2_fctidz" 5777 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 5778 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 5779 "TARGET_HARD_FLOAT && TARGET_FCFID" 5780 "@ 5781 fctidz %0,%1 5782 xscvdpsxds %x0,%x1" 5783 [(set_attr "type" "fp")]) 5784 5785;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR 5786;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the 5787;; vector registers, so we need to do direct moves to the GPRs, but SImode 5788;; values can go in VSX registers. Keeping the direct move part through 5789;; register allocation prevents the register allocator from doing a direct move 5790;; of the SImode value to a GPR, and then a store/load. 5791(define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2" 5792 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r") 5793 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa"))) 5794 (clobber (match_scratch:SI 2 "=X,X,wa"))] 5795 "TARGET_DIRECT_MOVE" 5796 "@ 5797 fctiw<u>z %0,%1 5798 xscvdp<su>xws %x0,%x1 5799 #" 5800 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)" 5801 [(set (match_dup 2) 5802 (any_fix:SI (match_dup 1))) 5803 (set (match_dup 3) 5804 (match_dup 2))] 5805{ 5806 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0])); 5807} 5808 [(set_attr "type" "fp") 5809 (set_attr "length" "4,4,8") 5810 (set_attr "isa" "p9v,p9v,*")]) 5811 5812(define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8" 5813 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa") 5814 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))] 5815 "TARGET_DIRECT_MOVE" 5816 "@ 5817 fctiw<u>z %0,%1 5818 xscvdp<su>xws %x0,%x1" 5819 [(set_attr "type" "fp")]) 5820 5821;; Keep the convert and store together through register allocation to prevent 5822;; the register allocator from getting clever and doing a direct move to a GPR 5823;; and then store for reg+offset stores. 5824(define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem" 5825 [(set (match_operand:QHSI 0 "memory_operand" "=Z") 5826 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa"))) 5827 (clobber (match_scratch:SI 2 "=wa"))] 5828 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR" 5829 "#" 5830 "&& reload_completed" 5831 [(set (match_dup 2) 5832 (any_fix:SI (match_dup 1))) 5833 (set (match_dup 0) 5834 (match_dup 3))] 5835{ 5836 operands[3] = (<QHSI:MODE>mode == SImode 5837 ? operands[2] 5838 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2]))); 5839}) 5840 5841(define_expand "fixuns_trunc<mode>si2" 5842 [(set (match_operand:SI 0 "gpc_reg_operand") 5843 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))] 5844 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX" 5845{ 5846 if (!TARGET_P8_VECTOR) 5847 { 5848 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1])); 5849 DONE; 5850 } 5851}) 5852 5853(define_insn_and_split "fixuns_trunc<mode>si2_stfiwx" 5854 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm") 5855 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))) 5856 (clobber (match_scratch:DI 2 "=d"))] 5857 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ 5858 && TARGET_STFIWX && can_create_pseudo_p () 5859 && !TARGET_P8_VECTOR" 5860 "#" 5861 "" 5862 [(pc)] 5863{ 5864 rtx dest = operands[0]; 5865 rtx src = operands[1]; 5866 rtx tmp = operands[2]; 5867 5868 if (GET_CODE (tmp) == SCRATCH) 5869 tmp = gen_reg_rtx (DImode); 5870 5871 emit_insn (gen_fctiwuz_<mode> (tmp, src)); 5872 if (MEM_P (dest)) 5873 { 5874 dest = rs6000_force_indexed_or_indirect_mem (dest); 5875 emit_insn (gen_stfiwx (dest, tmp)); 5876 DONE; 5877 } 5878 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE) 5879 { 5880 dest = gen_lowpart (DImode, dest); 5881 emit_move_insn (dest, tmp); 5882 DONE; 5883 } 5884 else 5885 { 5886 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 5887 emit_insn (gen_stfiwx (stack, tmp)); 5888 emit_move_insn (dest, stack); 5889 DONE; 5890 } 5891} 5892 [(set_attr "length" "12") 5893 (set_attr "type" "fp")]) 5894 5895(define_insn "fixuns_trunc<mode>di2" 5896 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 5897 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))] 5898 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ" 5899 "@ 5900 fctiduz %0,%1 5901 xscvdpuxds %x0,%x1" 5902 [(set_attr "type" "fp")]) 5903 5904(define_insn "rs6000_mtfsb0" 5905 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")] 5906 UNSPECV_MTFSB0)] 5907 "TARGET_HARD_FLOAT" 5908 "mtfsb0 %0" 5909 [(set_attr "type" "fp")]) 5910 5911(define_insn "rs6000_mtfsb1" 5912 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")] 5913 UNSPECV_MTFSB1)] 5914 "TARGET_HARD_FLOAT" 5915 "mtfsb1 %0" 5916 [(set_attr "type" "fp")]) 5917 5918(define_insn "rs6000_mffscrn" 5919 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 5920 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")] 5921 UNSPECV_MFFSCRN))] 5922 "TARGET_P9_MISC" 5923 "mffscrn %0,%1" 5924 [(set_attr "type" "fp")]) 5925 5926(define_insn "rs6000_mffscdrn" 5927 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 5928 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN)) 5929 (use (match_operand:DF 1 "gpc_reg_operand" "d"))] 5930 "TARGET_P9_MISC" 5931 "mffscdrn %0,%1" 5932 [(set_attr "type" "fp")]) 5933 5934(define_expand "rs6000_set_fpscr_rn" 5935 [(match_operand:DI 0 "reg_or_cint_operand")] 5936 "TARGET_HARD_FLOAT" 5937{ 5938 rtx tmp_df = gen_reg_rtx (DFmode); 5939 5940 /* The floating point rounding control bits are FPSCR[62:63]. Put the 5941 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */ 5942 if (TARGET_P9_MISC) 5943 { 5944 rtx src_df = force_reg (DImode, operands[0]); 5945 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0); 5946 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df)); 5947 DONE; 5948 } 5949 5950 if (CONST_INT_P (operands[0])) 5951 { 5952 if ((INTVAL (operands[0]) & 0x1) == 0x1) 5953 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31))); 5954 else 5955 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31))); 5956 5957 if ((INTVAL (operands[0]) & 0x2) == 0x2) 5958 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30))); 5959 else 5960 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30))); 5961 } 5962 else 5963 { 5964 rtx tmp_rn = gen_reg_rtx (DImode); 5965 rtx tmp_di = gen_reg_rtx (DImode); 5966 5967 /* Extract new RN mode from operand. */ 5968 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3))); 5969 5970 /* Insert new RN mode into FSCPR. */ 5971 emit_insn (gen_rs6000_mffs (tmp_df)); 5972 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); 5973 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4))); 5974 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn)); 5975 5976 /* Need to write to field k=15. The fields are [0:15]. Hence with 5977 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an 5978 8-bit field[0:7]. Need to set the bit that corresponds to the 5979 value of i that you want [0:7]. */ 5980 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); 5981 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df)); 5982 } 5983 DONE; 5984}) 5985 5986(define_expand "rs6000_set_fpscr_drn" 5987 [(match_operand:DI 0 "gpc_reg_operand")] 5988 "TARGET_HARD_FLOAT" 5989{ 5990 rtx tmp_df = gen_reg_rtx (DFmode); 5991 5992 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the 5993 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */ 5994 if (TARGET_P9_MISC) 5995 { 5996 rtx src_df = gen_reg_rtx (DFmode); 5997 5998 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32))); 5999 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0); 6000 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df)); 6001 } 6002 else 6003 { 6004 rtx tmp_rn = gen_reg_rtx (DImode); 6005 rtx tmp_di = gen_reg_rtx (DImode); 6006 6007 /* Extract new DRN mode from operand. */ 6008 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7))); 6009 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32))); 6010 6011 /* Insert new RN mode into FSCPR. */ 6012 emit_insn (gen_rs6000_mffs (tmp_df)); 6013 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0); 6014 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL))); 6015 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn)); 6016 6017 /* Need to write to field 7. The fields are [0:15]. The equation to 6018 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set 6019 i to 0x1 to get field 7 where i selects the field. */ 6020 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0); 6021 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df)); 6022 } 6023 DONE; 6024}) 6025 6026;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ)) 6027;; rather than (set (subreg:SI (reg)) (fix:SI ...)) 6028;; because the first makes it clear that operand 0 is not live 6029;; before the instruction. 6030(define_insn "fctiwz_<mode>" 6031 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 6032 (unspec:DI [(fix:SI 6033 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 6034 UNSPEC_FCTIWZ))] 6035 "TARGET_HARD_FLOAT" 6036 "@ 6037 fctiwz %0,%1 6038 xscvdpsxws %x0,%x1" 6039 [(set_attr "type" "fp")]) 6040 6041(define_insn "fctiwuz_<mode>" 6042 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa") 6043 (unspec:DI [(unsigned_fix:SI 6044 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))] 6045 UNSPEC_FCTIWUZ))] 6046 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ" 6047 "@ 6048 fctiwuz %0,%1 6049 xscvdpuxws %x0,%x1" 6050 [(set_attr "type" "fp")]) 6051 6052;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since 6053;; since the friz instruction does not truncate the value if the floating 6054;; point value is < LONG_MIN or > LONG_MAX. 6055(define_insn "*friz" 6056 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6057 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))] 6058 "TARGET_HARD_FLOAT && TARGET_FPRND 6059 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ" 6060 "@ 6061 friz %0,%1 6062 xsrdpiz %x0,%x1" 6063 [(set_attr "type" "fp")]) 6064 6065;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This 6066;; optimization prevents on ISA 2.06 systems and earlier having to store the 6067;; value from the FPR/vector unit to the stack, load the value into a GPR, sign 6068;; extend it, store it back on the stack from the GPR, load it back into the 6069;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07), 6070;; disable using store and load to sign/zero extend the value. 6071(define_insn_and_split "*round32<mode>2_fprs" 6072 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 6073 (float:SFDF 6074 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 6075 (clobber (match_scratch:DI 2 "=d")) 6076 (clobber (match_scratch:DI 3 "=d"))] 6077 "TARGET_HARD_FLOAT 6078 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID 6079 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()" 6080 "#" 6081 "" 6082 [(pc)] 6083{ 6084 rtx dest = operands[0]; 6085 rtx src = operands[1]; 6086 rtx tmp1 = operands[2]; 6087 rtx tmp2 = operands[3]; 6088 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 6089 6090 if (GET_CODE (tmp1) == SCRATCH) 6091 tmp1 = gen_reg_rtx (DImode); 6092 if (GET_CODE (tmp2) == SCRATCH) 6093 tmp2 = gen_reg_rtx (DImode); 6094 6095 emit_insn (gen_fctiwz_<mode> (tmp1, src)); 6096 emit_insn (gen_stfiwx (stack, tmp1)); 6097 emit_insn (gen_lfiwax (tmp2, stack)); 6098 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 6099 DONE; 6100} 6101 [(set_attr "type" "fpload") 6102 (set_attr "length" "16")]) 6103 6104(define_insn_and_split "*roundu32<mode>2_fprs" 6105 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d") 6106 (unsigned_float:SFDF 6107 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))) 6108 (clobber (match_scratch:DI 2 "=d")) 6109 (clobber (match_scratch:DI 3 "=d"))] 6110 "TARGET_HARD_FLOAT 6111 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE 6112 && can_create_pseudo_p ()" 6113 "#" 6114 "" 6115 [(pc)] 6116{ 6117 rtx dest = operands[0]; 6118 rtx src = operands[1]; 6119 rtx tmp1 = operands[2]; 6120 rtx tmp2 = operands[3]; 6121 rtx stack = rs6000_allocate_stack_temp (SImode, false, true); 6122 6123 if (GET_CODE (tmp1) == SCRATCH) 6124 tmp1 = gen_reg_rtx (DImode); 6125 if (GET_CODE (tmp2) == SCRATCH) 6126 tmp2 = gen_reg_rtx (DImode); 6127 6128 emit_insn (gen_fctiwuz_<mode> (tmp1, src)); 6129 emit_insn (gen_stfiwx (stack, tmp1)); 6130 emit_insn (gen_lfiwzx (tmp2, stack)); 6131 emit_insn (gen_floatdi<mode>2 (dest, tmp2)); 6132 DONE; 6133} 6134 [(set_attr "type" "fpload") 6135 (set_attr "length" "16")]) 6136 6137;; No VSX equivalent to fctid 6138(define_insn "lrint<mode>di2" 6139 [(set (match_operand:DI 0 "gpc_reg_operand" "=d") 6140 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 6141 UNSPEC_FCTID))] 6142 "TARGET_HARD_FLOAT && TARGET_FPRND" 6143 "fctid %0,%1" 6144 [(set_attr "type" "fp")]) 6145 6146(define_insn "btrunc<mode>2" 6147 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 6148 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 6149 UNSPEC_FRIZ))] 6150 "TARGET_HARD_FLOAT && TARGET_FPRND" 6151 "@ 6152 friz %0,%1 6153 xsrdpiz %x0,%x1" 6154 [(set_attr "type" "fp")]) 6155 6156(define_insn "ceil<mode>2" 6157 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 6158 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 6159 UNSPEC_FRIP))] 6160 "TARGET_HARD_FLOAT && TARGET_FPRND" 6161 "@ 6162 frip %0,%1 6163 xsrdpip %x0,%x1" 6164 [(set_attr "type" "fp")]) 6165 6166(define_insn "floor<mode>2" 6167 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>") 6168 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")] 6169 UNSPEC_FRIM))] 6170 "TARGET_HARD_FLOAT && TARGET_FPRND" 6171 "@ 6172 frim %0,%1 6173 xsrdpim %x0,%x1" 6174 [(set_attr "type" "fp")]) 6175 6176;; No VSX equivalent to frin 6177(define_insn "round<mode>2" 6178 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>") 6179 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")] 6180 UNSPEC_FRIN))] 6181 "TARGET_HARD_FLOAT && TARGET_FPRND" 6182 "frin %0,%1" 6183 [(set_attr "type" "fp")]) 6184 6185(define_insn "*xsrdpi<mode>2" 6186 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>") 6187 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")] 6188 UNSPEC_XSRDPI))] 6189 "TARGET_HARD_FLOAT && TARGET_VSX" 6190 "xsrdpi %x0,%x1" 6191 [(set_attr "type" "fp")]) 6192 6193(define_expand "lround<mode>di2" 6194 [(set (match_dup 2) 6195 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")] 6196 UNSPEC_XSRDPI)) 6197 (set (match_operand:DI 0 "gpc_reg_operand") 6198 (unspec:DI [(match_dup 2)] 6199 UNSPEC_FCTID))] 6200 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND" 6201{ 6202 operands[2] = gen_reg_rtx (<MODE>mode); 6203}) 6204 6205; An UNSPEC is used so we don't have to support SImode in FP registers. 6206(define_insn "stfiwx" 6207 [(set (match_operand:SI 0 "memory_operand" "=Z,Z") 6208 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")] 6209 UNSPEC_STFIWX))] 6210 "TARGET_PPC_GFXOPT" 6211 "@ 6212 stfiwx %1,%y0 6213 stxsiwx %x1,%y0" 6214 [(set_attr "type" "fpstore") 6215 (set_attr "isa" "*,p8v")]) 6216 6217;; If we don't have a direct conversion to single precision, don't enable this 6218;; conversion for 32-bit without fast math, because we don't have the insn to 6219;; generate the fixup swizzle to avoid double rounding problems. 6220(define_expand "floatsisf2" 6221 [(set (match_operand:SF 0 "gpc_reg_operand") 6222 (float:SF (match_operand:SI 1 "nonimmediate_operand")))] 6223 "TARGET_HARD_FLOAT 6224 && ((TARGET_FCFIDS && TARGET_LFIWAX) 6225 || (TARGET_FCFID 6226 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))" 6227{ 6228 if (TARGET_FCFIDS && TARGET_LFIWAX) 6229 { 6230 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1])); 6231 DONE; 6232 } 6233 else if (TARGET_FCFID && TARGET_LFIWAX) 6234 { 6235 rtx dfreg = gen_reg_rtx (DFmode); 6236 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1])); 6237 emit_insn (gen_truncdfsf2 (operands[0], dfreg)); 6238 DONE; 6239 } 6240 else 6241 { 6242 rtx dreg = operands[1]; 6243 if (!REG_P (dreg)) 6244 dreg = force_reg (SImode, dreg); 6245 dreg = convert_to_mode (DImode, dreg, false); 6246 emit_insn (gen_floatdisf2 (operands[0], dreg)); 6247 DONE; 6248 } 6249}) 6250 6251(define_insn "floatdidf2" 6252 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6253 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6254 "TARGET_FCFID && TARGET_HARD_FLOAT" 6255 "@ 6256 fcfid %0,%1 6257 xscvsxddp %x0,%x1" 6258 [(set_attr "type" "fp")]) 6259 6260; Allow the combiner to merge source memory operands to the conversion so that 6261; the optimizer/register allocator doesn't try to load the value too early in a 6262; GPR and then use store/load to move it to a FPR and suffer from a store-load 6263; hit. We will split after reload to avoid the trip through the GPRs 6264 6265(define_insn_and_split "*floatdidf2_mem" 6266 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6267 (float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 6268 (clobber (match_scratch:DI 2 "=d,wa"))] 6269 "TARGET_HARD_FLOAT && TARGET_FCFID" 6270 "#" 6271 "&& reload_completed" 6272 [(set (match_dup 2) (match_dup 1)) 6273 (set (match_dup 0) (float:DF (match_dup 2)))] 6274 "" 6275 [(set_attr "length" "8") 6276 (set_attr "type" "fpload")]) 6277 6278(define_expand "floatunsdidf2" 6279 [(set (match_operand:DF 0 "gpc_reg_operand") 6280 (unsigned_float:DF 6281 (match_operand:DI 1 "gpc_reg_operand")))] 6282 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 6283 "") 6284 6285(define_insn "*floatunsdidf2_fcfidu" 6286 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6287 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6288 "TARGET_HARD_FLOAT && TARGET_FCFIDU" 6289 "@ 6290 fcfidu %0,%1 6291 xscvuxddp %x0,%x1" 6292 [(set_attr "type" "fp")]) 6293 6294(define_insn_and_split "*floatunsdidf2_mem" 6295 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa") 6296 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z"))) 6297 (clobber (match_scratch:DI 2 "=d,wa"))] 6298 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))" 6299 "#" 6300 "&& reload_completed" 6301 [(set (match_dup 2) (match_dup 1)) 6302 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))] 6303 "" 6304 [(set_attr "length" "8") 6305 (set_attr "type" "fpload")]) 6306 6307(define_expand "floatdisf2" 6308 [(set (match_operand:SF 0 "gpc_reg_operand") 6309 (float:SF (match_operand:DI 1 "gpc_reg_operand")))] 6310 "TARGET_FCFID && TARGET_HARD_FLOAT 6311 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)" 6312{ 6313 if (!TARGET_FCFIDS) 6314 { 6315 rtx val = operands[1]; 6316 if (!flag_unsafe_math_optimizations) 6317 { 6318 rtx label = gen_label_rtx (); 6319 val = gen_reg_rtx (DImode); 6320 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label)); 6321 emit_label (label); 6322 } 6323 emit_insn (gen_floatdisf2_internal1 (operands[0], val)); 6324 DONE; 6325 } 6326}) 6327 6328(define_insn "floatdisf2_fcfids" 6329 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa") 6330 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6331 "TARGET_HARD_FLOAT && TARGET_FCFIDS" 6332 "@ 6333 fcfids %0,%1 6334 xscvsxdsp %x0,%x1" 6335 [(set_attr "type" "fp") 6336 (set_attr "isa" "*,p8v")]) 6337 6338(define_insn_and_split "*floatdisf2_mem" 6339 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa") 6340 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 6341 (clobber (match_scratch:DI 2 "=d,d,wa"))] 6342 "TARGET_HARD_FLOAT && TARGET_FCFIDS" 6343 "#" 6344 "&& reload_completed" 6345 [(pc)] 6346{ 6347 emit_move_insn (operands[2], operands[1]); 6348 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2])); 6349 DONE; 6350} 6351 [(set_attr "length" "8") 6352 (set_attr "isa" "*,p8v,p8v")]) 6353 6354;; This is not IEEE compliant if rounding mode is "round to nearest". 6355;; If the DI->DF conversion is inexact, then it's possible to suffer 6356;; from double rounding. 6357;; Instead of creating a new cpu type for two FP operations, just use fp 6358(define_insn_and_split "floatdisf2_internal1" 6359 [(set (match_operand:SF 0 "gpc_reg_operand" "=f") 6360 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d"))) 6361 (clobber (match_scratch:DF 2 "=d"))] 6362 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS" 6363 "#" 6364 "&& reload_completed" 6365 [(set (match_dup 2) 6366 (float:DF (match_dup 1))) 6367 (set (match_dup 0) 6368 (float_truncate:SF (match_dup 2)))] 6369 "" 6370 [(set_attr "length" "8") 6371 (set_attr "type" "fp")]) 6372 6373;; Twiddles bits to avoid double rounding. 6374;; Bits that might be truncated when converting to DFmode are replaced 6375;; by a bit that won't be lost at that stage, but is below the SFmode 6376;; rounding position. 6377(define_expand "floatdisf2_internal2" 6378 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "") 6379 (const_int 53))) 6380 (clobber (reg:DI CA_REGNO))]) 6381 (set (match_operand:DI 0 "") (and:DI (match_dup 1) 6382 (const_int 2047))) 6383 (set (match_dup 3) (plus:DI (match_dup 3) 6384 (const_int 1))) 6385 (set (match_dup 0) (plus:DI (match_dup 0) 6386 (const_int 2047))) 6387 (set (match_dup 4) (compare:CCUNS (match_dup 3) 6388 (const_int 2))) 6389 (set (match_dup 0) (ior:DI (match_dup 0) 6390 (match_dup 1))) 6391 (set (match_dup 0) (and:DI (match_dup 0) 6392 (const_int -2048))) 6393 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0)) 6394 (label_ref (match_operand:DI 2 "")) 6395 (pc))) 6396 (set (match_dup 0) (match_dup 1))] 6397 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS" 6398{ 6399 operands[3] = gen_reg_rtx (DImode); 6400 operands[4] = gen_reg_rtx (CCUNSmode); 6401}) 6402 6403(define_expand "floatunsdisf2" 6404 [(set (match_operand:SF 0 "gpc_reg_operand") 6405 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))] 6406 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" 6407 "") 6408 6409(define_insn "floatunsdisf2_fcfidus" 6410 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa") 6411 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))] 6412 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" 6413 "@ 6414 fcfidus %0,%1 6415 xscvuxdsp %x0,%x1" 6416 [(set_attr "type" "fp") 6417 (set_attr "isa" "*,p8v")]) 6418 6419(define_insn_and_split "*floatunsdisf2_mem" 6420 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa") 6421 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z"))) 6422 (clobber (match_scratch:DI 2 "=d,d,wa"))] 6423 "TARGET_HARD_FLOAT && TARGET_FCFIDUS" 6424 "#" 6425 "&& reload_completed" 6426 [(pc)] 6427{ 6428 emit_move_insn (operands[2], operands[1]); 6429 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2])); 6430 DONE; 6431} 6432 [(set_attr "type" "fpload") 6433 (set_attr "length" "8") 6434 (set_attr "isa" "*,p8v,p8v")]) 6435 6436;; Define the TImode operations that can be done in a small number 6437;; of instructions. The & constraints are to prevent the register 6438;; allocator from allocating registers that overlap with the inputs 6439;; (for example, having an input in 7,8 and an output in 6,7). We 6440;; also allow for the output being the same as one of the inputs. 6441 6442(define_expand "addti3" 6443 [(set (match_operand:TI 0 "gpc_reg_operand") 6444 (plus:TI (match_operand:TI 1 "gpc_reg_operand") 6445 (match_operand:TI 2 "reg_or_short_operand")))] 6446 "TARGET_64BIT" 6447{ 6448 rtx lo0 = gen_lowpart (DImode, operands[0]); 6449 rtx lo1 = gen_lowpart (DImode, operands[1]); 6450 rtx lo2 = gen_lowpart (DImode, operands[2]); 6451 rtx hi0 = gen_highpart (DImode, operands[0]); 6452 rtx hi1 = gen_highpart (DImode, operands[1]); 6453 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]); 6454 6455 if (!reg_or_short_operand (lo2, DImode)) 6456 lo2 = force_reg (DImode, lo2); 6457 if (!adde_operand (hi2, DImode)) 6458 hi2 = force_reg (DImode, hi2); 6459 6460 emit_insn (gen_adddi3_carry (lo0, lo1, lo2)); 6461 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2)); 6462 DONE; 6463}) 6464 6465(define_expand "subti3" 6466 [(set (match_operand:TI 0 "gpc_reg_operand") 6467 (minus:TI (match_operand:TI 1 "reg_or_short_operand") 6468 (match_operand:TI 2 "gpc_reg_operand")))] 6469 "TARGET_64BIT" 6470{ 6471 rtx lo0 = gen_lowpart (DImode, operands[0]); 6472 rtx lo1 = gen_lowpart (DImode, operands[1]); 6473 rtx lo2 = gen_lowpart (DImode, operands[2]); 6474 rtx hi0 = gen_highpart (DImode, operands[0]); 6475 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]); 6476 rtx hi2 = gen_highpart (DImode, operands[2]); 6477 6478 if (!reg_or_short_operand (lo1, DImode)) 6479 lo1 = force_reg (DImode, lo1); 6480 if (!adde_operand (hi1, DImode)) 6481 hi1 = force_reg (DImode, hi1); 6482 6483 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1)); 6484 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1)); 6485 DONE; 6486}) 6487 6488;; 128-bit logical operations expanders 6489 6490(define_expand "and<mode>3" 6491 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6492 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6493 (match_operand:BOOL_128 2 "vlogical_operand")))] 6494 "" 6495 "") 6496 6497(define_expand "ior<mode>3" 6498 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6499 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6500 (match_operand:BOOL_128 2 "vlogical_operand")))] 6501 "" 6502 "") 6503 6504(define_expand "xor<mode>3" 6505 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6506 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6507 (match_operand:BOOL_128 2 "vlogical_operand")))] 6508 "" 6509 "") 6510 6511(define_expand "nor<mode>3" 6512 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6513 (and:BOOL_128 6514 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")) 6515 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))] 6516 "" 6517 "") 6518 6519(define_expand "andc<mode>3" 6520 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6521 (and:BOOL_128 6522 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand")) 6523 (match_operand:BOOL_128 1 "vlogical_operand")))] 6524 "" 6525 "") 6526 6527;; Power8 vector logical instructions. 6528(define_expand "eqv<mode>3" 6529 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6530 (not:BOOL_128 6531 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand") 6532 (match_operand:BOOL_128 2 "vlogical_operand"))))] 6533 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6534 "") 6535 6536;; Rewrite nand into canonical form 6537(define_expand "nand<mode>3" 6538 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6539 (ior:BOOL_128 6540 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")) 6541 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))] 6542 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6543 "") 6544 6545;; The canonical form is to have the negated element first, so we need to 6546;; reverse arguments. 6547(define_expand "orc<mode>3" 6548 [(set (match_operand:BOOL_128 0 "vlogical_operand") 6549 (ior:BOOL_128 6550 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand")) 6551 (match_operand:BOOL_128 1 "vlogical_operand")))] 6552 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR" 6553 "") 6554 6555;; 128-bit logical operations insns and split operations 6556(define_insn_and_split "*and<mode>3_internal" 6557 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6558 (and:BOOL_128 6559 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>") 6560 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))] 6561 "" 6562{ 6563 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6564 return "xxland %x0,%x1,%x2"; 6565 6566 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6567 return "vand %0,%1,%2"; 6568 6569 return "#"; 6570} 6571 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6572 [(const_int 0)] 6573{ 6574 rs6000_split_logical (operands, AND, false, false, false); 6575 DONE; 6576} 6577 [(set (attr "type") 6578 (if_then_else 6579 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6580 (const_string "veclogical") 6581 (const_string "integer"))) 6582 (set (attr "length") 6583 (if_then_else 6584 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6585 (const_string "4") 6586 (if_then_else 6587 (match_test "TARGET_POWERPC64") 6588 (const_string "8") 6589 (const_string "16"))))]) 6590 6591;; 128-bit IOR/XOR 6592(define_insn_and_split "*bool<mode>3_internal" 6593 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6594 (match_operator:BOOL_128 3 "boolean_or_operator" 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 "xxl%q3 %x0,%x1,%x2"; 6601 6602 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6603 return "v%q3 %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, GET_CODE (operands[3]), 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 ANDC/ORC 6628(define_insn_and_split "*boolc<mode>3_internal1" 6629 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6630 (match_operator:BOOL_128 3 "boolean_operator" 6631 [(not:BOOL_128 6632 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")) 6633 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))] 6634 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 6635{ 6636 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6637 return "xxl%q3 %x0,%x1,%x2"; 6638 6639 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6640 return "v%q3 %0,%1,%2"; 6641 6642 return "#"; 6643} 6644 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 6645 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6646 [(const_int 0)] 6647{ 6648 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 6649 DONE; 6650} 6651 [(set (attr "type") 6652 (if_then_else 6653 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6654 (const_string "veclogical") 6655 (const_string "integer"))) 6656 (set (attr "length") 6657 (if_then_else 6658 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6659 (const_string "4") 6660 (if_then_else 6661 (match_test "TARGET_POWERPC64") 6662 (const_string "8") 6663 (const_string "16"))))]) 6664 6665(define_insn_and_split "*boolc<mode>3_internal2" 6666 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6667 (match_operator:TI2 3 "boolean_operator" 6668 [(not:TI2 6669 (match_operand:TI2 2 "int_reg_operand" "r,0,r")) 6670 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))] 6671 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6672 "#" 6673 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6674 [(const_int 0)] 6675{ 6676 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true); 6677 DONE; 6678} 6679 [(set_attr "type" "integer") 6680 (set (attr "length") 6681 (if_then_else 6682 (match_test "TARGET_POWERPC64") 6683 (const_string "8") 6684 (const_string "16")))]) 6685 6686;; 128-bit NAND/NOR 6687(define_insn_and_split "*boolcc<mode>3_internal1" 6688 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6689 (match_operator:BOOL_128 3 "boolean_operator" 6690 [(not:BOOL_128 6691 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")) 6692 (not:BOOL_128 6693 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))] 6694 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)" 6695{ 6696 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6697 return "xxl%q3 %x0,%x1,%x2"; 6698 6699 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6700 return "v%q3 %0,%1,%2"; 6701 6702 return "#"; 6703} 6704 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)) 6705 && reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6706 [(const_int 0)] 6707{ 6708 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 6709 DONE; 6710} 6711 [(set (attr "type") 6712 (if_then_else 6713 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6714 (const_string "veclogical") 6715 (const_string "integer"))) 6716 (set (attr "length") 6717 (if_then_else 6718 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6719 (const_string "4") 6720 (if_then_else 6721 (match_test "TARGET_POWERPC64") 6722 (const_string "8") 6723 (const_string "16"))))]) 6724 6725(define_insn_and_split "*boolcc<mode>3_internal2" 6726 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6727 (match_operator:TI2 3 "boolean_operator" 6728 [(not:TI2 6729 (match_operand:TI2 1 "int_reg_operand" "r,0,r")) 6730 (not:TI2 6731 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))] 6732 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6733 "#" 6734 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)" 6735 [(const_int 0)] 6736{ 6737 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true); 6738 DONE; 6739} 6740 [(set_attr "type" "integer") 6741 (set (attr "length") 6742 (if_then_else 6743 (match_test "TARGET_POWERPC64") 6744 (const_string "8") 6745 (const_string "16")))]) 6746 6747 6748;; 128-bit EQV 6749(define_insn_and_split "*eqv<mode>3_internal1" 6750 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6751 (not:BOOL_128 6752 (xor:BOOL_128 6753 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>") 6754 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))] 6755 "TARGET_P8_VECTOR" 6756{ 6757 if (vsx_register_operand (operands[0], <MODE>mode)) 6758 return "xxleqv %x0,%x1,%x2"; 6759 6760 return "#"; 6761} 6762 "TARGET_P8_VECTOR && reload_completed 6763 && int_reg_operand (operands[0], <MODE>mode)" 6764 [(const_int 0)] 6765{ 6766 rs6000_split_logical (operands, XOR, true, false, false); 6767 DONE; 6768} 6769 [(set (attr "type") 6770 (if_then_else 6771 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6772 (const_string "veclogical") 6773 (const_string "integer"))) 6774 (set (attr "length") 6775 (if_then_else 6776 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6777 (const_string "4") 6778 (if_then_else 6779 (match_test "TARGET_POWERPC64") 6780 (const_string "8") 6781 (const_string "16"))))]) 6782 6783(define_insn_and_split "*eqv<mode>3_internal2" 6784 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r") 6785 (not:TI2 6786 (xor:TI2 6787 (match_operand:TI2 1 "int_reg_operand" "r,0,r") 6788 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))] 6789 "!TARGET_P8_VECTOR" 6790 "#" 6791 "reload_completed && !TARGET_P8_VECTOR" 6792 [(const_int 0)] 6793{ 6794 rs6000_split_logical (operands, XOR, true, false, false); 6795 DONE; 6796} 6797 [(set_attr "type" "integer") 6798 (set (attr "length") 6799 (if_then_else 6800 (match_test "TARGET_POWERPC64") 6801 (const_string "8") 6802 (const_string "16")))]) 6803 6804;; 128-bit one's complement 6805(define_insn_and_split "one_cmpl<mode>2" 6806 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>") 6807 (not:BOOL_128 6808 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))] 6809 "" 6810{ 6811 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode)) 6812 return "xxlnor %x0,%x1,%x1"; 6813 6814 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode)) 6815 return "vnor %0,%1,%1"; 6816 6817 return "#"; 6818} 6819 "reload_completed && int_reg_operand (operands[0], <MODE>mode)" 6820 [(const_int 0)] 6821{ 6822 rs6000_split_logical (operands, NOT, false, false, false); 6823 DONE; 6824} 6825 [(set (attr "type") 6826 (if_then_else 6827 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6828 (const_string "veclogical") 6829 (const_string "integer"))) 6830 (set (attr "length") 6831 (if_then_else 6832 (match_test "vsx_register_operand (operands[0], <MODE>mode)") 6833 (const_string "4") 6834 (if_then_else 6835 (match_test "TARGET_POWERPC64") 6836 (const_string "8") 6837 (const_string "16"))))]) 6838 6839 6840;; Now define ways of moving data around. 6841 6842;; Set up a register with a value from the GOT table 6843 6844(define_expand "movsi_got" 6845 [(set (match_operand:SI 0 "gpc_reg_operand") 6846 (unspec:SI [(match_operand:SI 1 "got_operand") 6847 (match_dup 2)] UNSPEC_MOVSI_GOT))] 6848 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 6849{ 6850 if (GET_CODE (operands[1]) == CONST) 6851 { 6852 rtx offset = const0_rtx; 6853 HOST_WIDE_INT value; 6854 6855 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset); 6856 value = INTVAL (offset); 6857 if (value != 0) 6858 { 6859 rtx tmp = (!can_create_pseudo_p () 6860 ? operands[0] 6861 : gen_reg_rtx (Pmode)); 6862 emit_insn (gen_movsi_got (tmp, operands[1])); 6863 emit_insn (gen_addsi3 (operands[0], tmp, offset)); 6864 DONE; 6865 } 6866 } 6867 6868 operands[2] = rs6000_got_register (operands[1]); 6869}) 6870 6871(define_insn "*movsi_got_internal" 6872 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 6873 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "") 6874 (match_operand:SI 2 "gpc_reg_operand" "b")] 6875 UNSPEC_MOVSI_GOT))] 6876 "DEFAULT_ABI == ABI_V4 && flag_pic == 1" 6877 "lwz %0,%a1@got(%2)" 6878 [(set_attr "type" "load")]) 6879 6880;; Used by sched, shorten_branches and final when the GOT pseudo reg 6881;; didn't get allocated to a hard register. 6882(define_split 6883 [(set (match_operand:SI 0 "gpc_reg_operand") 6884 (unspec:SI [(match_operand:SI 1 "got_no_const_operand") 6885 (match_operand:SI 2 "memory_operand")] 6886 UNSPEC_MOVSI_GOT))] 6887 "DEFAULT_ABI == ABI_V4 6888 && flag_pic == 1 6889 && reload_completed" 6890 [(set (match_dup 0) (match_dup 2)) 6891 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)] 6892 UNSPEC_MOVSI_GOT))] 6893 "") 6894 6895;; MR LA 6896;; LWZ LFIWZX LXSIWZX 6897;; STW STFIWX STXSIWX 6898;; LI LIS PLI # 6899;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW 6900;; XXLXOR 0 XXLORC -1 P9 const 6901;; MTVSRWZ MFVSRWZ 6902;; MF%1 MT%0 NOP 6903 6904(define_insn "*movsi_internal1" 6905 [(set (match_operand:SI 0 "nonimmediate_operand" 6906 "=r, r, 6907 r, d, v, 6908 m, Z, Z, 6909 r, r, r, r, 6910 wa, wa, wa, v, 6911 wa, v, v, 6912 wa, r, 6913 r, *h, *h") 6914 (match_operand:SI 1 "input_operand" 6915 "r, U, 6916 m, Z, Z, 6917 r, d, v, 6918 I, L, eI, n, 6919 wa, O, wM, wB, 6920 O, wM, wS, 6921 r, wa, 6922 *h, r, 0"))] 6923 "gpc_reg_operand (operands[0], SImode) 6924 || gpc_reg_operand (operands[1], SImode)" 6925 "@ 6926 mr %0,%1 6927 la %0,%a1 6928 lwz%U1%X1 %0,%1 6929 lfiwzx %0,%y1 6930 lxsiwzx %x0,%y1 6931 stw%U0%X0 %1,%0 6932 stfiwx %1,%y0 6933 stxsiwx %x1,%y0 6934 li %0,%1 6935 lis %0,%v1 6936 li %0,%1 6937 # 6938 xxlor %x0,%x1,%x1 6939 xxspltib %x0,0 6940 xxspltib %x0,255 6941 vspltisw %0,%1 6942 xxlxor %x0,%x0,%x0 6943 xxlorc %x0,%x0,%x0 6944 # 6945 mtvsrwz %x0,%1 6946 mfvsrwz %0,%x1 6947 mf%1 %0 6948 mt%0 %1 6949 nop" 6950 [(set_attr "type" 6951 "*, *, 6952 load, fpload, fpload, 6953 store, fpstore, fpstore, 6954 *, *, *, *, 6955 veclogical, vecsimple, vecsimple, vecsimple, 6956 veclogical, veclogical, vecsimple, 6957 mffgpr, mftgpr, 6958 *, *, *") 6959 (set_attr "length" 6960 "*, *, 6961 *, *, *, 6962 *, *, *, 6963 *, *, *, 8, 6964 *, *, *, *, 6965 *, *, 8, 6966 *, *, 6967 *, *, *") 6968 (set_attr "isa" 6969 "*, *, 6970 *, p8v, p8v, 6971 *, p8v, p8v, 6972 *, *, p10, *, 6973 p8v, p9v, p9v, p8v, 6974 p9v, p8v, p9v, 6975 p8v, p8v, 6976 *, *, *")]) 6977 6978;; Like movsi, but adjust a SF value to be used in a SI context, i.e. 6979;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0)) 6980;; 6981;; Because SF values are actually stored as DF values within the vector 6982;; registers, we need to convert the value to the vector SF format when 6983;; we need to use the bits in a union or similar cases. We only need 6984;; to do this transformation when the value is a vector register. Loads, 6985;; stores, and transfers within GPRs are assumed to be safe. 6986;; 6987;; This is a more general case of reload_gpr_from_vsxsf. That insn must have 6988;; no alternatives, because the call is created as part of secondary_reload, 6989;; and operand #2's register class is used to allocate the temporary register. 6990;; This function is called before reload, and it creates the temporary as 6991;; needed. 6992 6993;; MR LWZ LFIWZX LXSIWZX STW 6994;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX 6995;; MTVSRWZ 6996 6997(define_insn_and_split "movsi_from_sf" 6998 [(set (match_operand:SI 0 "nonimmediate_operand" 6999 "=r, r, ?*d, ?*v, m, 7000 m, wY, Z, r, ?*wa, 7001 wa") 7002 (unspec:SI [(match_operand:SF 1 "input_operand" 7003 "r, m, Z, Z, r, 7004 f, v, wa, wa, wa, 7005 r")] 7006 UNSPEC_SI_FROM_SF)) 7007 (clobber (match_scratch:V4SF 2 7008 "=X, X, X, X, X, 7009 X, X, X, wa, X, 7010 X"))] 7011 "TARGET_NO_SF_SUBREG 7012 && (register_operand (operands[0], SImode) 7013 || register_operand (operands[1], SFmode))" 7014 "@ 7015 mr %0,%1 7016 lwz%U1%X1 %0,%1 7017 lfiwzx %0,%y1 7018 lxsiwzx %x0,%y1 7019 stw%U0%X0 %1,%0 7020 stfs%U0%X0 %1,%0 7021 stxssp %1,%0 7022 stxsspx %x1,%y0 7023 # 7024 xscvdpspn %x0,%x1 7025 mtvsrwz %x0,%1" 7026 "&& reload_completed 7027 && int_reg_operand (operands[0], SImode) 7028 && vsx_reg_sfsubreg_ok (operands[1], SFmode)" 7029 [(const_int 0)] 7030{ 7031 rtx op0 = operands[0]; 7032 rtx op1 = operands[1]; 7033 rtx op2 = operands[2]; 7034 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0)); 7035 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 7036 7037 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 7038 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si)); 7039 DONE; 7040} 7041 [(set_attr "type" 7042 "*, load, fpload, fpload, store, 7043 fpstore, fpstore, fpstore, mftgpr, fp, 7044 mffgpr") 7045 (set_attr "length" 7046 "*, *, *, *, *, 7047 *, *, *, 8, *, 7048 *") 7049 (set_attr "isa" 7050 "*, *, p8v, p8v, *, 7051 *, p9v, p8v, p8v, p8v, 7052 p8v")]) 7053 7054;; movsi_from_sf with zero extension 7055;; 7056;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR 7057;; VSX->VSX MTVSRWZ 7058 7059(define_insn_and_split "*movdi_from_sf_zero_ext" 7060 [(set (match_operand:DI 0 "gpc_reg_operand" 7061 "=r, r, ?*d, ?*v, r, 7062 ?v, wa") 7063 (zero_extend:DI 7064 (unspec:SI [(match_operand:SF 1 "input_operand" 7065 "r, m, Z, Z, wa, 7066 wa, r")] 7067 UNSPEC_SI_FROM_SF))) 7068 (clobber (match_scratch:V4SF 2 7069 "=X, X, X, X, wa, 7070 wa, X"))] 7071 "TARGET_DIRECT_MOVE_64BIT 7072 && (register_operand (operands[0], DImode) 7073 || register_operand (operands[1], SImode))" 7074 "@ 7075 rldicl %0,%1,0,32 7076 lwz%U1%X1 %0,%1 7077 lfiwzx %0,%y1 7078 lxsiwzx %x0,%y1 7079 # 7080 # 7081 mtvsrwz %x0,%1" 7082 "&& reload_completed 7083 && register_operand (operands[0], DImode) 7084 && vsx_reg_sfsubreg_ok (operands[1], SFmode)" 7085 [(const_int 0)] 7086{ 7087 rtx op0 = operands[0]; 7088 rtx op1 = operands[1]; 7089 rtx op2 = operands[2]; 7090 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 7091 7092 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 7093 emit_insn (gen_zero_extendsidi2 (op0, op2_si)); 7094 DONE; 7095} 7096 [(set_attr "type" 7097 "*, load, fpload, fpload, two, 7098 two, mffgpr") 7099 (set_attr "length" 7100 "*, *, *, *, 8, 7101 8, *") 7102 (set_attr "isa" 7103 "*, *, p8v, p8v, p8v, 7104 p9v, p8v")]) 7105 7106;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before 7107;; moving it to SImode. We cannot do a SFmode store without having to do the 7108;; conversion explicitly since that doesn't work in most cases if the input 7109;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the 7110;; former handles cases where the input will not fit in a SFmode, and the 7111;; latter assumes the value has already been rounded. 7112(define_insn "*movsi_from_df" 7113 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa") 7114 (unspec:SI [(float_truncate:SF 7115 (match_operand:DF 1 "gpc_reg_operand" "wa"))] 7116 UNSPEC_SI_FROM_SF))] 7117 "TARGET_NO_SF_SUBREG" 7118 "xscvdpsp %x0,%x1" 7119 [(set_attr "type" "fp")]) 7120 7121;; Split a load of a large constant into the appropriate two-insn 7122;; sequence. 7123 7124(define_split 7125 [(set (match_operand:SI 0 "gpc_reg_operand") 7126 (match_operand:SI 1 "const_int_operand"))] 7127 "num_insns_constant (operands[1], SImode) > 1" 7128 [(set (match_dup 0) 7129 (match_dup 2)) 7130 (set (match_dup 0) 7131 (ior:SI (match_dup 0) 7132 (match_dup 3)))] 7133{ 7134 if (rs6000_emit_set_const (operands[0], operands[1])) 7135 DONE; 7136 else 7137 FAIL; 7138}) 7139 7140;; Split loading -128..127 to use XXSPLITB and VEXTSW2D 7141(define_split 7142 [(set (match_operand:DI 0 "altivec_register_operand") 7143 (match_operand:DI 1 "xxspltib_constant_split"))] 7144 "TARGET_P9_VECTOR && reload_completed" 7145 [(const_int 0)] 7146{ 7147 rtx op0 = operands[0]; 7148 rtx op1 = operands[1]; 7149 int r = REGNO (op0); 7150 rtx op0_v16qi = gen_rtx_REG (V16QImode, r); 7151 7152 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1)); 7153 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi)); 7154 DONE; 7155}) 7156 7157(define_insn "*mov<mode>_internal2" 7158 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y") 7159 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r") 7160 (const_int 0))) 7161 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))] 7162 "" 7163 "@ 7164 cmp<wd>i %2,%0,0 7165 mr. %0,%1 7166 #" 7167 [(set_attr "type" "cmp,logical,cmp") 7168 (set_attr "dot" "yes") 7169 (set_attr "length" "4,4,8")]) 7170 7171(define_split 7172 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand") 7173 (compare:CC (match_operand:P 1 "gpc_reg_operand") 7174 (const_int 0))) 7175 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))] 7176 "reload_completed" 7177 [(set (match_dup 0) (match_dup 1)) 7178 (set (match_dup 2) 7179 (compare:CC (match_dup 0) 7180 (const_int 0)))] 7181 "") 7182 7183(define_expand "mov<mode>" 7184 [(set (match_operand:INT 0 "general_operand") 7185 (match_operand:INT 1 "any_operand"))] 7186 "" 7187{ 7188 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7189 DONE; 7190}) 7191 7192;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI 7193;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ 7194;; MTVSRWZ MF%1 MT%1 NOP 7195(define_insn "*mov<mode>_internal" 7196 [(set (match_operand:QHI 0 "nonimmediate_operand" 7197 "=r, r, wa, m, Z, r, 7198 wa, wa, wa, v, ?v, r, 7199 wa, r, *c*l, *h") 7200 (match_operand:QHI 1 "input_operand" 7201 "r, m, Z, r, wa, i, 7202 wa, O, wM, wB, wS, wa, 7203 r, *h, r, 0"))] 7204 "gpc_reg_operand (operands[0], <MODE>mode) 7205 || gpc_reg_operand (operands[1], <MODE>mode)" 7206 "@ 7207 mr %0,%1 7208 l<wd>z%U1%X1 %0,%1 7209 lxsi<wd>zx %x0,%y1 7210 st<wd>%U0%X0 %1,%0 7211 stxsi<wd>x %x1,%y0 7212 li %0,%1 7213 xxlor %x0,%x1,%x1 7214 xxspltib %x0,0 7215 xxspltib %x0,255 7216 vspltis<wd> %0,%1 7217 # 7218 mfvsrwz %0,%x1 7219 mtvsrwz %x0,%1 7220 mf%1 %0 7221 mt%0 %1 7222 nop" 7223 [(set_attr "type" 7224 "*, load, fpload, store, fpstore, *, 7225 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr, 7226 mffgpr, mfjmpr, mtjmpr, *") 7227 (set_attr "length" 7228 "*, *, *, *, *, *, 7229 *, *, *, *, 8, *, 7230 *, *, *, *") 7231 (set_attr "isa" 7232 "*, *, p9v, *, p9v, *, 7233 p9v, p9v, p9v, p9v, p9v, p9v, 7234 p9v, *, *, *")]) 7235 7236 7237;; Here is how to move condition codes around. When we store CC data in 7238;; an integer register or memory, we store just the high-order 4 bits. 7239;; This lets us not shift in the most common case of CR0. 7240(define_expand "movcc" 7241 [(set (match_operand:CC 0 "nonimmediate_operand") 7242 (match_operand:CC 1 "nonimmediate_operand"))] 7243 "" 7244 "") 7245 7246(define_mode_iterator CC_any [CC CCUNS CCEQ CCFP]) 7247 7248(define_insn "*movcc_<mode>" 7249 [(set (match_operand:CC_any 0 "nonimmediate_operand" 7250 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m") 7251 (match_operand:CC_any 1 "general_operand" 7252 " y,r, r,O,x,y,r,I,*h, r,m,r"))] 7253 "register_operand (operands[0], <MODE>mode) 7254 || register_operand (operands[1], <MODE>mode)" 7255 "@ 7256 mcrf %0,%1 7257 mtcrf 128,%1 7258 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff 7259 crxor %0,%0,%0 7260 mfcr %0%Q1 7261 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000 7262 mr %0,%1 7263 li %0,%1 7264 mf%1 %0 7265 mt%0 %1 7266 lwz%U1%X1 %0,%1 7267 stw%U0%X0 %1,%0" 7268 [(set_attr_alternative "type" 7269 [(const_string "cr_logical") 7270 (const_string "mtcr") 7271 (const_string "mtcr") 7272 (const_string "cr_logical") 7273 (if_then_else (match_test "TARGET_MFCRF") 7274 (const_string "mfcrf") (const_string "mfcr")) 7275 (if_then_else (match_test "TARGET_MFCRF") 7276 (const_string "mfcrf") (const_string "mfcr")) 7277 (const_string "integer") 7278 (const_string "integer") 7279 (const_string "mfjmpr") 7280 (const_string "mtjmpr") 7281 (const_string "load") 7282 (const_string "store")]) 7283 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")]) 7284 7285;; For floating-point, we normally deal with the floating-point registers 7286;; unless -msoft-float is used. The sole exception is that parameter passing 7287;; can produce floating-point values in fixed-point registers. Unless the 7288;; value is a simple constant or already in memory, we deal with this by 7289;; allocating memory and copying the value explicitly via that memory location. 7290 7291;; Move 32-bit binary/decimal floating point 7292(define_expand "mov<mode>" 7293 [(set (match_operand:FMOVE32 0 "nonimmediate_operand") 7294 (match_operand:FMOVE32 1 "any_operand"))] 7295 "<fmove_ok>" 7296{ 7297 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7298 DONE; 7299}) 7300 7301(define_split 7302 [(set (match_operand:FMOVE32 0 "gpc_reg_operand") 7303 (match_operand:FMOVE32 1 "const_double_operand"))] 7304 "reload_completed 7305 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 7306 || (SUBREG_P (operands[0]) 7307 && REG_P (SUBREG_REG (operands[0])) 7308 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7309 [(set (match_dup 2) (match_dup 3))] 7310{ 7311 long l; 7312 7313 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7314 7315 if (! TARGET_POWERPC64) 7316 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode); 7317 else 7318 operands[2] = gen_lowpart (SImode, operands[0]); 7319 7320 operands[3] = gen_int_mode (l, SImode); 7321}) 7322 7323;; Originally, we tried to keep movsf and movsd common, but the differences 7324;; addressing was making it rather difficult to hide with mode attributes. In 7325;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store 7326;; before the VSX stores meant that the register allocator would tend to do a 7327;; direct move to the GPR (which involves conversion from scalar to 7328;; vector/memory formats) to save values in the traditional Altivec registers, 7329;; while SDmode had problems on power6 if the GPR store was not first due to 7330;; the power6 not having an integer store operation. 7331;; 7332;; LWZ LFS LXSSP LXSSPX STFS STXSSP 7333;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP 7334;; MR MT<x> MF<x> NOP 7335 7336(define_insn "movsf_hardfloat" 7337 [(set (match_operand:SF 0 "nonimmediate_operand" 7338 "=!r, f, v, wa, m, wY, 7339 Z, m, wa, !r, f, wa, 7340 !r, *c*l, !r, *h") 7341 (match_operand:SF 1 "input_operand" 7342 "m, m, wY, Z, f, v, 7343 wa, r, j, j, f, wa, 7344 r, r, *h, 0"))] 7345 "(register_operand (operands[0], SFmode) 7346 || register_operand (operands[1], SFmode)) 7347 && TARGET_HARD_FLOAT 7348 && (TARGET_ALLOW_SF_SUBREG 7349 || valid_sf_si_move (operands[0], operands[1], SFmode))" 7350 "@ 7351 lwz%U1%X1 %0,%1 7352 lfs%U1%X1 %0,%1 7353 lxssp %0,%1 7354 lxsspx %x0,%y1 7355 stfs%U0%X0 %1,%0 7356 stxssp %1,%0 7357 stxsspx %x1,%y0 7358 stw%U0%X0 %1,%0 7359 xxlxor %x0,%x0,%x0 7360 li %0,0 7361 fmr %0,%1 7362 xscpsgndp %x0,%x1,%x1 7363 mr %0,%1 7364 mt%0 %1 7365 mf%1 %0 7366 nop" 7367 [(set_attr "type" 7368 "load, fpload, fpload, fpload, fpstore, fpstore, 7369 fpstore, store, veclogical, integer, fpsimple, fpsimple, 7370 *, mtjmpr, mfjmpr, *") 7371 (set_attr "isa" 7372 "*, *, p9v, p8v, *, p9v, 7373 p8v, *, *, *, *, *, 7374 *, *, *, *")]) 7375 7376;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ 7377;; FMR MR MT%0 MF%1 NOP 7378(define_insn "movsd_hardfloat" 7379 [(set (match_operand:SD 0 "nonimmediate_operand" 7380 "=!r, d, m, Z, ?d, ?r, 7381 f, !r, *c*l, !r, *h") 7382 (match_operand:SD 1 "input_operand" 7383 "m, Z, r, wx, r, d, 7384 f, r, r, *h, 0"))] 7385 "(register_operand (operands[0], SDmode) 7386 || register_operand (operands[1], SDmode)) 7387 && TARGET_HARD_FLOAT" 7388 "@ 7389 lwz%U1%X1 %0,%1 7390 lfiwzx %0,%y1 7391 stw%U0%X0 %1,%0 7392 stfiwx %1,%y0 7393 mtvsrwz %x0,%1 7394 mfvsrwz %0,%x1 7395 fmr %0,%1 7396 mr %0,%1 7397 mt%0 %1 7398 mf%1 %0 7399 nop" 7400 [(set_attr "type" 7401 "load, fpload, store, fpstore, mffgpr, mftgpr, 7402 fpsimple, *, mtjmpr, mfjmpr, *") 7403 (set_attr "isa" 7404 "*, p7, *, *, p8v, p8v, 7405 *, *, *, *, *")]) 7406 7407;; MR MT%0 MF%0 LWZ STW LI 7408;; LIS G-const. F/n-const NOP 7409(define_insn "*mov<mode>_softfloat" 7410 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" 7411 "=r, *c*l, r, r, m, r, 7412 r, r, r, *h") 7413 7414 (match_operand:FMOVE32 1 "input_operand" 7415 "r, r, *h, m, r, I, 7416 L, G, Fn, 0"))] 7417 7418 "(gpc_reg_operand (operands[0], <MODE>mode) 7419 || gpc_reg_operand (operands[1], <MODE>mode)) 7420 && TARGET_SOFT_FLOAT" 7421 "@ 7422 mr %0,%1 7423 mt%0 %1 7424 mf%1 %0 7425 lwz%U1%X1 %0,%1 7426 stw%U0%X0 %1,%0 7427 li %0,%1 7428 lis %0,%v1 7429 # 7430 # 7431 nop" 7432 [(set_attr "type" 7433 "*, mtjmpr, mfjmpr, load, store, *, 7434 *, *, *, *") 7435 7436 (set_attr "length" 7437 "*, *, *, *, *, *, 7438 *, *, 8, *")]) 7439 7440;; Like movsf, but adjust a SI value to be used in a SF context, i.e. 7441;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0)) 7442;; 7443;; Because SF values are actually stored as DF values within the vector 7444;; registers, we need to convert the value to the vector SF format when 7445;; we need to use the bits in a union or similar cases. We only need 7446;; to do this transformation when the value is a vector register. Loads, 7447;; stores, and transfers within GPRs are assumed to be safe. 7448;; 7449;; This is a more general case of reload_vsx_from_gprsf. That insn must have 7450;; no alternatives, because the call is created as part of secondary_reload, 7451;; and operand #2's register class is used to allocate the temporary register. 7452;; This function is called before reload, and it creates the temporary as 7453;; needed. 7454 7455;; LWZ LFS LXSSP LXSSPX STW STFIWX 7456;; STXSIWX GPR->VSX VSX->GPR GPR->GPR 7457(define_insn_and_split "movsf_from_si" 7458 [(set (match_operand:SF 0 "nonimmediate_operand" 7459 "=!r, f, v, wa, m, Z, 7460 Z, wa, ?r, !r") 7461 (unspec:SF [(match_operand:SI 1 "input_operand" 7462 "m, m, wY, Z, r, f, 7463 wa, r, wa, r")] 7464 UNSPEC_SF_FROM_SI)) 7465 (clobber (match_scratch:DI 2 7466 "=X, X, X, X, X, X, 7467 X, r, X, X"))] 7468 "TARGET_NO_SF_SUBREG 7469 && (register_operand (operands[0], SFmode) 7470 || register_operand (operands[1], SImode))" 7471 "@ 7472 lwz%U1%X1 %0,%1 7473 lfs%U1%X1 %0,%1 7474 lxssp %0,%1 7475 lxsspx %x0,%y1 7476 stw%U0%X0 %1,%0 7477 stfiwx %1,%y0 7478 stxsiwx %x1,%y0 7479 # 7480 mfvsrwz %0,%x1 7481 mr %0,%1" 7482 7483 "&& reload_completed 7484 && vsx_reg_sfsubreg_ok (operands[0], SFmode) 7485 && int_reg_operand_not_pseudo (operands[1], SImode)" 7486 [(const_int 0)] 7487{ 7488 rtx op0 = operands[0]; 7489 rtx op1 = operands[1]; 7490 rtx op2 = operands[2]; 7491 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1)); 7492 7493 /* Move SF value to upper 32-bits for xscvspdpn. */ 7494 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 7495 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 7496 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 7497 DONE; 7498} 7499 [(set_attr "length" 7500 "*, *, *, *, *, *, 7501 *, 12, *, *") 7502 (set_attr "type" 7503 "load, fpload, fpload, fpload, store, fpstore, 7504 fpstore, vecfloat, mffgpr, *") 7505 (set_attr "isa" 7506 "*, *, p9v, p8v, *, *, 7507 p8v, p8v, p8v, *")]) 7508 7509 7510;; Move 64-bit binary/decimal floating point 7511(define_expand "mov<mode>" 7512 [(set (match_operand:FMOVE64 0 "nonimmediate_operand") 7513 (match_operand:FMOVE64 1 "any_operand"))] 7514 "" 7515{ 7516 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7517 DONE; 7518}) 7519 7520(define_split 7521 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 7522 (match_operand:FMOVE64 1 "const_int_operand"))] 7523 "! TARGET_POWERPC64 && reload_completed 7524 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 7525 || (SUBREG_P (operands[0]) 7526 && REG_P (SUBREG_REG (operands[0])) 7527 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7528 [(set (match_dup 2) (match_dup 4)) 7529 (set (match_dup 3) (match_dup 1))] 7530{ 7531 int endian = (WORDS_BIG_ENDIAN == 0); 7532 HOST_WIDE_INT value = INTVAL (operands[1]); 7533 7534 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 7535 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 7536 operands[4] = GEN_INT (value >> 32); 7537 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 7538}) 7539 7540(define_split 7541 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 7542 (match_operand:FMOVE64 1 "const_double_operand"))] 7543 "! TARGET_POWERPC64 && reload_completed 7544 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 7545 || (SUBREG_P (operands[0]) 7546 && REG_P (SUBREG_REG (operands[0])) 7547 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7548 [(set (match_dup 2) (match_dup 4)) 7549 (set (match_dup 3) (match_dup 5))] 7550{ 7551 int endian = (WORDS_BIG_ENDIAN == 0); 7552 long l[2]; 7553 7554 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7555 7556 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode); 7557 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode); 7558 operands[4] = gen_int_mode (l[endian], SImode); 7559 operands[5] = gen_int_mode (l[1 - endian], SImode); 7560}) 7561 7562(define_split 7563 [(set (match_operand:FMOVE64 0 "gpc_reg_operand") 7564 (match_operand:FMOVE64 1 "const_double_operand"))] 7565 "TARGET_POWERPC64 && reload_completed 7566 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31) 7567 || (SUBREG_P (operands[0]) 7568 && REG_P (SUBREG_REG (operands[0])) 7569 && REGNO (SUBREG_REG (operands[0])) <= 31))" 7570 [(set (match_dup 2) (match_dup 3))] 7571{ 7572 int endian = (WORDS_BIG_ENDIAN == 0); 7573 long l[2]; 7574 HOST_WIDE_INT val; 7575 7576 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l); 7577 7578 operands[2] = gen_lowpart (DImode, operands[0]); 7579 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */ 7580 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32 7581 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian])); 7582 7583 operands[3] = gen_int_mode (val, DImode); 7584}) 7585 7586;; Don't have reload use general registers to load a constant. It is 7587;; less efficient than loading the constant into an FP register, since 7588;; it will probably be used there. 7589 7590;; The move constraints are ordered to prefer floating point registers before 7591;; general purpose registers to avoid doing a store and a load to get the value 7592;; into a floating point register when it is needed for a floating point 7593;; operation. Prefer traditional floating point registers over VSX registers, 7594;; since the D-form version of the memory instructions does not need a GPR for 7595;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec 7596;; registers. 7597 7598;; If we have FPR registers, rs6000_emit_move has moved all constants to memory, 7599;; except for 0.0 which can be created on VSX with an xor instruction. 7600 7601;; STFD LFD FMR LXSD STXSD 7602;; LXSD STXSD XXLOR XXLXOR GPR<-0 7603;; LWZ STW MR 7604 7605 7606(define_insn "*mov<mode>_hardfloat32" 7607 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 7608 "=m, d, d, <f64_p9>, wY, 7609 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r, 7610 Y, r, !r") 7611 (match_operand:FMOVE64 1 "input_operand" 7612 "d, m, d, wY, <f64_p9>, 7613 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>, 7614 r, Y, r"))] 7615 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT 7616 && (gpc_reg_operand (operands[0], <MODE>mode) 7617 || gpc_reg_operand (operands[1], <MODE>mode))" 7618 "@ 7619 stfd%U0%X0 %1,%0 7620 lfd%U1%X1 %0,%1 7621 fmr %0,%1 7622 lxsd %0,%1 7623 stxsd %1,%0 7624 lxsdx %x0,%y1 7625 stxsdx %x1,%y0 7626 xxlor %x0,%x1,%x1 7627 xxlxor %x0,%x0,%x0 7628 # 7629 # 7630 # 7631 #" 7632 [(set_attr "type" 7633 "fpstore, fpload, fpsimple, fpload, fpstore, 7634 fpload, fpstore, veclogical, veclogical, two, 7635 store, load, two") 7636 (set_attr "size" "64") 7637 (set_attr "length" 7638 "*, *, *, *, *, 7639 *, *, *, *, 8, 7640 8, 8, 8") 7641 (set_attr "isa" 7642 "*, *, *, p9v, p9v, 7643 p7v, p7v, *, *, *, 7644 *, *, *")]) 7645 7646;; STW LWZ MR G-const H-const F-const 7647 7648(define_insn "*mov<mode>_softfloat32" 7649 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 7650 "=Y, r, r, r, r, r") 7651 7652 (match_operand:FMOVE64 1 "input_operand" 7653 "r, Y, r, G, H, F"))] 7654 7655 "!TARGET_POWERPC64 7656 && (gpc_reg_operand (operands[0], <MODE>mode) 7657 || gpc_reg_operand (operands[1], <MODE>mode))" 7658 "#" 7659 [(set_attr "type" 7660 "store, load, two, *, *, *") 7661 7662 (set_attr "length" 7663 "8, 8, 8, 8, 12, 16")]) 7664 7665; ld/std require word-aligned displacements -> 'Y' constraint. 7666; List Y->r and r->Y before r->r for reload. 7667 7668;; STFD LFD FMR LXSD STXSD 7669;; LXSDX STXSDX XXLOR XXLXOR LI 0 7670;; STD LD MR MT{CTR,LR} MF{CTR,LR} 7671;; NOP MFVSRD MTVSRD 7672 7673(define_insn "*mov<mode>_hardfloat64" 7674 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 7675 "=m, d, d, <f64_p9>, wY, 7676 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r, 7677 YZ, r, !r, *c*l, !r, 7678 *h, r, <f64_dm>") 7679 (match_operand:FMOVE64 1 "input_operand" 7680 "d, m, d, wY, <f64_p9>, 7681 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>, 7682 r, YZ, r, r, *h, 7683 0, <f64_dm>, r"))] 7684 "TARGET_POWERPC64 && TARGET_HARD_FLOAT 7685 && (gpc_reg_operand (operands[0], <MODE>mode) 7686 || gpc_reg_operand (operands[1], <MODE>mode))" 7687 "@ 7688 stfd%U0%X0 %1,%0 7689 lfd%U1%X1 %0,%1 7690 fmr %0,%1 7691 lxsd %0,%1 7692 stxsd %1,%0 7693 lxsdx %x0,%y1 7694 stxsdx %x1,%y0 7695 xxlor %x0,%x1,%x1 7696 xxlxor %x0,%x0,%x0 7697 li %0,0 7698 std%U0%X0 %1,%0 7699 ld%U1%X1 %0,%1 7700 mr %0,%1 7701 mt%0 %1 7702 mf%1 %0 7703 nop 7704 mfvsrd %0,%x1 7705 mtvsrd %x0,%1" 7706 [(set_attr "type" 7707 "fpstore, fpload, fpsimple, fpload, fpstore, 7708 fpload, fpstore, veclogical, veclogical, integer, 7709 store, load, *, mtjmpr, mfjmpr, 7710 *, mftgpr, mffgpr") 7711 (set_attr "size" "64") 7712 (set_attr "isa" 7713 "*, *, *, p9v, p9v, 7714 p7v, p7v, *, *, *, 7715 *, *, *, *, *, 7716 *, p8v, p8v")]) 7717 7718;; STD LD MR MT<SPR> MF<SPR> G-const 7719;; H-const F-const Special 7720 7721(define_insn "*mov<mode>_softfloat64" 7722 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" 7723 "=Y, r, r, *c*l, r, r, 7724 r, r, *h") 7725 7726 (match_operand:FMOVE64 1 "input_operand" 7727 "r, Y, r, r, *h, G, 7728 H, F, 0"))] 7729 7730 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT 7731 && (gpc_reg_operand (operands[0], <MODE>mode) 7732 || gpc_reg_operand (operands[1], <MODE>mode))" 7733 "@ 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 # 7740 # 7741 # 7742 nop" 7743 [(set_attr "type" 7744 "store, load, *, mtjmpr, mfjmpr, *, 7745 *, *, *") 7746 7747 (set_attr "length" 7748 "*, *, *, *, *, 8, 7749 12, 16, *")]) 7750 7751(define_expand "mov<mode>" 7752 [(set (match_operand:FMOVE128 0 "general_operand") 7753 (match_operand:FMOVE128 1 "any_operand"))] 7754 "" 7755{ 7756 rs6000_emit_move (operands[0], operands[1], <MODE>mode); 7757 DONE; 7758}) 7759 7760;; It's important to list Y->r and r->Y before r->r because otherwise 7761;; reload, given m->r, will try to pick r->r and reload it, which 7762;; doesn't make progress. 7763 7764;; We can't split little endian direct moves of TDmode, because the words are 7765;; not swapped like they are for TImode or TFmode. Subregs therefore are 7766;; problematical. Don't allow direct move for this case. 7767 7768;; FPR load FPR store FPR move FPR zero GPR load 7769;; GPR zero GPR store GPR move MFVSRD MTVSRD 7770 7771(define_insn_and_split "*mov<mode>_64bit_dm" 7772 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" 7773 "=m, d, d, d, Y, 7774 r, r, r, r, d") 7775 7776 (match_operand:FMOVE128_FPR 1 "input_operand" 7777 "d, m, d, <zero_fp>, r, 7778 <zero_fp>, Y, r, d, r"))] 7779 7780 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode) 7781 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN) 7782 && (gpc_reg_operand (operands[0], <MODE>mode) 7783 || gpc_reg_operand (operands[1], <MODE>mode))" 7784 "#" 7785 "&& reload_completed" 7786 [(pc)] 7787{ 7788 rs6000_split_multireg_move (operands[0], operands[1]); 7789 DONE; 7790} 7791 [(set_attr "length" "8") 7792 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v") 7793 (set_attr "max_prefixed_insns" "2") 7794 (set_attr "num_insns" "2")]) 7795 7796(define_insn_and_split "*movtd_64bit_nodm" 7797 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r") 7798 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))] 7799 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN 7800 && (gpc_reg_operand (operands[0], TDmode) 7801 || gpc_reg_operand (operands[1], TDmode))" 7802 "#" 7803 "&& reload_completed" 7804 [(pc)] 7805{ 7806 rs6000_split_multireg_move (operands[0], operands[1]); 7807 DONE; 7808} 7809 [(set_attr "length" "8,8,8,12,12,8") 7810 (set_attr "max_prefixed_insns" "2") 7811 (set_attr "num_insns" "2,2,2,3,3,2")]) 7812 7813(define_insn_and_split "*mov<mode>_32bit" 7814 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r") 7815 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))] 7816 "TARGET_HARD_FLOAT && !TARGET_POWERPC64 7817 && (FLOAT128_2REG_P (<MODE>mode) 7818 || int_reg_operand_not_pseudo (operands[0], <MODE>mode) 7819 || int_reg_operand_not_pseudo (operands[1], <MODE>mode)) 7820 && (gpc_reg_operand (operands[0], <MODE>mode) 7821 || gpc_reg_operand (operands[1], <MODE>mode))" 7822 "#" 7823 "&& reload_completed" 7824 [(pc)] 7825{ 7826 rs6000_split_multireg_move (operands[0], operands[1]); 7827 DONE; 7828} 7829 [(set_attr "length" "8,8,8,8,20,20,16")]) 7830 7831(define_insn_and_split "*mov<mode>_softfloat" 7832 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r") 7833 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))] 7834 "TARGET_SOFT_FLOAT 7835 && (gpc_reg_operand (operands[0], <MODE>mode) 7836 || gpc_reg_operand (operands[1], <MODE>mode))" 7837 "#" 7838 "&& reload_completed" 7839 [(pc)] 7840{ 7841 rs6000_split_multireg_move (operands[0], operands[1]); 7842 DONE; 7843} 7844 [(set_attr_alternative "length" 7845 [(if_then_else (match_test "TARGET_POWERPC64") 7846 (const_string "8") 7847 (const_string "16")) 7848 (if_then_else (match_test "TARGET_POWERPC64") 7849 (const_string "8") 7850 (const_string "16")) 7851 (if_then_else (match_test "TARGET_POWERPC64") 7852 (const_string "16") 7853 (const_string "32")) 7854 (if_then_else (match_test "TARGET_POWERPC64") 7855 (const_string "8") 7856 (const_string "16"))])]) 7857 7858(define_expand "@extenddf<mode>2" 7859 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7860 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))] 7861 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7862{ 7863 if (FLOAT128_IEEE_P (<MODE>mode)) 7864 rs6000_expand_float128_convert (operands[0], operands[1], false); 7865 else if (TARGET_VSX) 7866 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1])); 7867 else 7868 { 7869 rtx zero = gen_reg_rtx (DFmode); 7870 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode); 7871 7872 emit_insn (gen_extenddf2_fprs (<MODE>mode, 7873 operands[0], operands[1], zero)); 7874 } 7875 DONE; 7876}) 7877 7878;; Allow memory operands for the source to be created by the combiner. 7879(define_insn_and_split "@extenddf<mode>2_fprs" 7880 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d") 7881 (float_extend:IBM128 7882 (match_operand:DF 1 "nonimmediate_operand" "d,m,d"))) 7883 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))] 7884 "!TARGET_VSX && TARGET_HARD_FLOAT 7885 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)" 7886 "#" 7887 "&& reload_completed" 7888 [(set (match_dup 3) (match_dup 1)) 7889 (set (match_dup 4) (match_dup 2))] 7890{ 7891 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 7892 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 7893 7894 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 7895 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 7896}) 7897 7898(define_insn_and_split "@extenddf<mode>2_vsx" 7899 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d") 7900 (float_extend:IBM128 7901 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))] 7902 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)" 7903 "#" 7904 "&& reload_completed" 7905 [(set (match_dup 2) (match_dup 1)) 7906 (set (match_dup 3) (match_dup 4))] 7907{ 7908 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 7909 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 7910 7911 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 7912 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 7913 operands[4] = CONST0_RTX (DFmode); 7914}) 7915 7916(define_expand "extendsf<mode>2" 7917 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7918 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))] 7919 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7920{ 7921 if (FLOAT128_IEEE_P (<MODE>mode)) 7922 rs6000_expand_float128_convert (operands[0], operands[1], false); 7923 else 7924 { 7925 rtx tmp = gen_reg_rtx (DFmode); 7926 emit_insn (gen_extendsfdf2 (tmp, operands[1])); 7927 emit_insn (gen_extenddf<mode>2 (operands[0], tmp)); 7928 } 7929 DONE; 7930}) 7931 7932(define_expand "trunc<mode>df2" 7933 [(set (match_operand:DF 0 "gpc_reg_operand") 7934 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))] 7935 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7936{ 7937 if (FLOAT128_IEEE_P (<MODE>mode)) 7938 { 7939 rs6000_expand_float128_convert (operands[0], operands[1], false); 7940 DONE; 7941 } 7942}) 7943 7944(define_insn_and_split "trunc<mode>df2_internal1" 7945 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d") 7946 (float_truncate:DF 7947 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))] 7948 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT 7949 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7950 "@ 7951 # 7952 fmr %0,%1" 7953 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 7954 [(const_int 0)] 7955{ 7956 emit_note (NOTE_INSN_DELETED); 7957 DONE; 7958} 7959 [(set_attr "type" "fpsimple")]) 7960 7961(define_insn "trunc<mode>df2_internal2" 7962 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 7963 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 7964 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT 7965 && TARGET_LONG_DOUBLE_128" 7966 "fadd %0,%1,%L1" 7967 [(set_attr "type" "fp")]) 7968 7969(define_expand "trunc<mode>sf2" 7970 [(set (match_operand:SF 0 "gpc_reg_operand") 7971 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))] 7972 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7973{ 7974 if (FLOAT128_IEEE_P (<MODE>mode)) 7975 rs6000_expand_float128_convert (operands[0], operands[1], false); 7976 else 7977 { 7978 rtx tmp = gen_reg_rtx (DFmode); 7979 emit_insn (gen_trunc<mode>df2 (tmp, operands[1])); 7980 emit_insn (gen_truncdfsf2 (operands[0], tmp)); 7981 } 7982 DONE; 7983}) 7984 7985(define_expand "floatsi<mode>2" 7986 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 7987 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand"))) 7988 (clobber (match_scratch:DI 2))])] 7989 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 7990{ 7991 rtx op0 = operands[0]; 7992 rtx op1 = operands[1]; 7993 7994 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)) 7995 ; 7996 else if (FLOAT128_IEEE_P (<MODE>mode)) 7997 { 7998 rs6000_expand_float128_convert (op0, op1, false); 7999 DONE; 8000 } 8001 else 8002 { 8003 rtx tmp = gen_reg_rtx (DFmode); 8004 expand_float (tmp, op1, false); 8005 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp)); 8006 DONE; 8007 } 8008}) 8009 8010; fadd, but rounding towards zero. 8011; This is probably not the optimal code sequence. 8012(define_insn "fix_trunc_helper<mode>" 8013 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 8014 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")] 8015 UNSPEC_FIX_TRUNC_TF)) 8016 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))] 8017 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)" 8018 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2" 8019 [(set_attr "type" "fp") 8020 (set_attr "length" "20")]) 8021 8022(define_expand "fix_trunc<mode>si2" 8023 [(set (match_operand:SI 0 "gpc_reg_operand") 8024 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))] 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 8033 { 8034 if (FLOAT128_IEEE_P (<MODE>mode)) 8035 rs6000_expand_float128_convert (op0, op1, false); 8036 else 8037 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1)); 8038 DONE; 8039 } 8040}) 8041 8042(define_expand "@fix_trunc<mode>si2_fprs" 8043 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand") 8044 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand"))) 8045 (clobber (match_dup 2)) 8046 (clobber (match_dup 3)) 8047 (clobber (match_dup 4)) 8048 (clobber (match_dup 5))])] 8049 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8050{ 8051 operands[2] = gen_reg_rtx (DFmode); 8052 operands[3] = gen_reg_rtx (DFmode); 8053 operands[4] = gen_reg_rtx (DImode); 8054 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode)); 8055}) 8056 8057(define_insn_and_split "*fix_trunc<mode>si2_internal" 8058 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 8059 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d"))) 8060 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d")) 8061 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d")) 8062 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d")) 8063 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))] 8064 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8065 "#" 8066 "" 8067 [(pc)] 8068{ 8069 rtx lowword; 8070 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1], 8071 operands[3])); 8072 8073 gcc_assert (MEM_P (operands[5])); 8074 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0); 8075 8076 emit_insn (gen_fctiwz_df (operands[4], operands[2])); 8077 emit_move_insn (operands[5], operands[4]); 8078 emit_move_insn (operands[0], lowword); 8079 DONE; 8080}) 8081 8082(define_expand "fix_trunc<mode>di2" 8083 [(set (match_operand:DI 0 "gpc_reg_operand") 8084 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))] 8085 "TARGET_FLOAT128_TYPE" 8086{ 8087 if (!TARGET_FLOAT128_HW) 8088 { 8089 rs6000_expand_float128_convert (operands[0], operands[1], false); 8090 DONE; 8091 } 8092}) 8093 8094(define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2" 8095 [(set (match_operand:SDI 0 "gpc_reg_operand") 8096 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))] 8097 "TARGET_FLOAT128_TYPE" 8098{ 8099 rs6000_expand_float128_convert (operands[0], operands[1], true); 8100 DONE; 8101}) 8102 8103(define_expand "floatdi<mode>2" 8104 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 8105 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))] 8106 "TARGET_FLOAT128_TYPE" 8107{ 8108 if (!TARGET_FLOAT128_HW) 8109 { 8110 rs6000_expand_float128_convert (operands[0], operands[1], false); 8111 DONE; 8112 } 8113}) 8114 8115(define_expand "floatunsdi<IEEE128:mode>2" 8116 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 8117 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))] 8118 "TARGET_FLOAT128_TYPE" 8119{ 8120 if (!TARGET_FLOAT128_HW) 8121 { 8122 rs6000_expand_float128_convert (operands[0], operands[1], true); 8123 DONE; 8124 } 8125}) 8126 8127(define_expand "floatuns<IEEE128:mode>2" 8128 [(set (match_operand:IEEE128 0 "gpc_reg_operand") 8129 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))] 8130 "TARGET_FLOAT128_TYPE" 8131{ 8132 rtx op0 = operands[0]; 8133 rtx op1 = operands[1]; 8134 8135 if (TARGET_FLOAT128_HW) 8136 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1)); 8137 else 8138 rs6000_expand_float128_convert (op0, op1, true); 8139 DONE; 8140}) 8141 8142(define_expand "neg<mode>2" 8143 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 8144 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8145 "FLOAT128_IEEE_P (<MODE>mode) 8146 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" 8147{ 8148 if (FLOAT128_IEEE_P (<MODE>mode)) 8149 { 8150 if (TARGET_FLOAT128_HW) 8151 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1])); 8152 else if (TARGET_FLOAT128_TYPE) 8153 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode, 8154 operands[0], operands[1])); 8155 else 8156 { 8157 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode); 8158 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST, 8159 <MODE>mode, 8160 operands[1], <MODE>mode); 8161 8162 if (target && !rtx_equal_p (target, operands[0])) 8163 emit_move_insn (operands[0], target); 8164 } 8165 DONE; 8166 } 8167}) 8168 8169(define_insn "neg<mode>2_internal" 8170 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d") 8171 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))] 8172 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)" 8173{ 8174 if (REGNO (operands[0]) == REGNO (operands[1]) + 1) 8175 return "fneg %L0,%L1\;fneg %0,%1"; 8176 else 8177 return "fneg %0,%1\;fneg %L0,%L1"; 8178} 8179 [(set_attr "type" "fpsimple") 8180 (set_attr "length" "8")]) 8181 8182(define_expand "abs<mode>2" 8183 [(set (match_operand:FLOAT128 0 "gpc_reg_operand") 8184 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))] 8185 "FLOAT128_IEEE_P (<MODE>mode) 8186 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)" 8187{ 8188 rtx label; 8189 8190 if (FLOAT128_IEEE_P (<MODE>mode)) 8191 { 8192 if (TARGET_FLOAT128_HW) 8193 { 8194 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1])); 8195 DONE; 8196 } 8197 else if (TARGET_FLOAT128_TYPE) 8198 { 8199 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode, 8200 operands[0], operands[1])); 8201 DONE; 8202 } 8203 else 8204 FAIL; 8205 } 8206 8207 label = gen_label_rtx (); 8208 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label)); 8209 emit_label (label); 8210 DONE; 8211}) 8212 8213(define_expand "@abs<mode>2_internal" 8214 [(set (match_operand:IBM128 0 "gpc_reg_operand") 8215 (match_operand:IBM128 1 "gpc_reg_operand")) 8216 (set (match_dup 3) (match_dup 5)) 8217 (set (match_dup 5) (abs:DF (match_dup 5))) 8218 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5))) 8219 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0)) 8220 (label_ref (match_operand 2 "")) 8221 (pc))) 8222 (set (match_dup 6) (neg:DF (match_dup 6)))] 8223 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 8224{ 8225 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 8226 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 8227 operands[3] = gen_reg_rtx (DFmode); 8228 operands[4] = gen_reg_rtx (CCFPmode); 8229 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word); 8230 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word); 8231}) 8232 8233 8234;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector 8235;; register 8236 8237(define_expand "ieee_128bit_negative_zero" 8238 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))] 8239 "TARGET_FLOAT128_TYPE" 8240{ 8241 rtvec v = rtvec_alloc (16); 8242 int i, high; 8243 8244 for (i = 0; i < 16; i++) 8245 RTVEC_ELT (v, i) = const0_rtx; 8246 8247 high = (BYTES_BIG_ENDIAN) ? 0 : 15; 8248 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode); 8249 8250 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v)); 8251 DONE; 8252}) 8253 8254;; IEEE 128-bit negate 8255 8256;; We have 2 insns here for negate and absolute value. The first uses 8257;; match_scratch so that phases like combine can recognize neg/abs as generic 8258;; insns, and second insn after the first split pass loads up the bit to 8259;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of 8260;; neg/abs to create the constant just once. 8261 8262(define_insn_and_split "@ieee_128bit_vsx_neg<mode>2" 8263 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8264 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8265 (clobber (match_scratch:V16QI 2 "=v"))] 8266 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8267 "#" 8268 "&& 1" 8269 [(parallel [(set (match_dup 0) 8270 (neg:IEEE128 (match_dup 1))) 8271 (use (match_dup 2))])] 8272{ 8273 if (GET_CODE (operands[2]) == SCRATCH) 8274 operands[2] = gen_reg_rtx (V16QImode); 8275 8276 operands[3] = gen_reg_rtx (V16QImode); 8277 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8278} 8279 [(set_attr "length" "8") 8280 (set_attr "type" "vecsimple")]) 8281 8282(define_insn "*ieee_128bit_vsx_neg<mode>2_internal" 8283 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8284 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8285 (use (match_operand:V16QI 2 "register_operand" "v"))] 8286 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8287 "xxlxor %x0,%x1,%x2" 8288 [(set_attr "type" "veclogical")]) 8289 8290;; IEEE 128-bit absolute value 8291(define_insn_and_split "@ieee_128bit_vsx_abs<mode>2" 8292 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8293 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8294 (clobber (match_scratch:V16QI 2 "=v"))] 8295 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 8296 "#" 8297 "&& 1" 8298 [(parallel [(set (match_dup 0) 8299 (abs:IEEE128 (match_dup 1))) 8300 (use (match_dup 2))])] 8301{ 8302 if (GET_CODE (operands[2]) == SCRATCH) 8303 operands[2] = gen_reg_rtx (V16QImode); 8304 8305 operands[3] = gen_reg_rtx (V16QImode); 8306 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8307} 8308 [(set_attr "length" "8") 8309 (set_attr "type" "vecsimple")]) 8310 8311(define_insn "*ieee_128bit_vsx_abs<mode>2_internal" 8312 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8313 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa"))) 8314 (use (match_operand:V16QI 2 "register_operand" "v"))] 8315 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8316 "xxlandc %x0,%x1,%x2" 8317 [(set_attr "type" "veclogical")]) 8318 8319;; IEEE 128-bit negative absolute value 8320(define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2" 8321 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8322 (neg:IEEE128 8323 (abs:IEEE128 8324 (match_operand:IEEE128 1 "register_operand" "wa")))) 8325 (clobber (match_scratch:V16QI 2 "=v"))] 8326 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW 8327 && FLOAT128_IEEE_P (<MODE>mode)" 8328 "#" 8329 "&& 1" 8330 [(parallel [(set (match_dup 0) 8331 (neg:IEEE128 (abs:IEEE128 (match_dup 1)))) 8332 (use (match_dup 2))])] 8333{ 8334 if (GET_CODE (operands[2]) == SCRATCH) 8335 operands[2] = gen_reg_rtx (V16QImode); 8336 8337 operands[3] = gen_reg_rtx (V16QImode); 8338 emit_insn (gen_ieee_128bit_negative_zero (operands[2])); 8339} 8340 [(set_attr "length" "8") 8341 (set_attr "type" "vecsimple")]) 8342 8343(define_insn "*ieee_128bit_vsx_nabs<mode>2_internal" 8344 [(set (match_operand:IEEE128 0 "register_operand" "=wa") 8345 (neg:IEEE128 8346 (abs:IEEE128 8347 (match_operand:IEEE128 1 "register_operand" "wa")))) 8348 (use (match_operand:V16QI 2 "register_operand" "v"))] 8349 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW" 8350 "xxlor %x0,%x1,%x2" 8351 [(set_attr "type" "veclogical")]) 8352 8353;; Float128 conversion functions. These expand to library function calls. 8354;; We use expand to convert from IBM double double to IEEE 128-bit 8355;; and trunc for the opposite. 8356(define_expand "extendiftf2" 8357 [(set (match_operand:TF 0 "gpc_reg_operand") 8358 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))] 8359 "TARGET_FLOAT128_TYPE" 8360{ 8361 rs6000_expand_float128_convert (operands[0], operands[1], false); 8362 DONE; 8363}) 8364 8365(define_expand "extendifkf2" 8366 [(set (match_operand:KF 0 "gpc_reg_operand") 8367 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))] 8368 "TARGET_FLOAT128_TYPE" 8369{ 8370 rs6000_expand_float128_convert (operands[0], operands[1], false); 8371 DONE; 8372}) 8373 8374(define_expand "extendtfkf2" 8375 [(set (match_operand:KF 0 "gpc_reg_operand") 8376 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))] 8377 "TARGET_FLOAT128_TYPE" 8378{ 8379 rs6000_expand_float128_convert (operands[0], operands[1], false); 8380 DONE; 8381}) 8382 8383(define_expand "extendtfif2" 8384 [(set (match_operand:IF 0 "gpc_reg_operand") 8385 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))] 8386 "TARGET_FLOAT128_TYPE" 8387{ 8388 rs6000_expand_float128_convert (operands[0], operands[1], false); 8389 DONE; 8390}) 8391 8392(define_expand "trunciftf2" 8393 [(set (match_operand:TF 0 "gpc_reg_operand") 8394 (float_truncate: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 "truncifkf2" 8402 [(set (match_operand:KF 0 "gpc_reg_operand") 8403 (float_truncate: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 "trunckftf2" 8411 [(set (match_operand:TF 0 "gpc_reg_operand") 8412 (float_truncate:TF (match_operand:KF 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 "trunctfif2" 8420 [(set (match_operand:IF 0 "gpc_reg_operand") 8421 (float_truncate: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_insn_and_split "*extend<mode>tf2_internal" 8429 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>") 8430 (float_extend:TF 8431 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))] 8432 "TARGET_FLOAT128_TYPE 8433 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)" 8434 "#" 8435 "&& reload_completed" 8436 [(set (match_dup 0) (match_dup 2))] 8437{ 8438 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1])); 8439}) 8440 8441(define_insn_and_split "*extendtf<mode>2_internal" 8442 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>") 8443 (float_extend:IFKF 8444 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))] 8445 "TARGET_FLOAT128_TYPE 8446 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)" 8447 "#" 8448 "&& reload_completed" 8449 [(set (match_dup 0) (match_dup 2))] 8450{ 8451 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1])); 8452}) 8453 8454 8455;; Reload helper functions used by rs6000_secondary_reload. The patterns all 8456;; must have 3 arguments, and scratch register constraint must be a single 8457;; constraint. 8458 8459;; Reload patterns to support gpr load/store with misaligned mem. 8460;; and multiple gpr load/store at offset >= 0xfffc 8461(define_expand "reload_<mode>_store" 8462 [(parallel [(match_operand 0 "memory_operand" "=m") 8463 (match_operand 1 "gpc_reg_operand" "r") 8464 (match_operand:GPR 2 "register_operand" "=&b")])] 8465 "" 8466{ 8467 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true); 8468 DONE; 8469}) 8470 8471(define_expand "reload_<mode>_load" 8472 [(parallel [(match_operand 0 "gpc_reg_operand" "=r") 8473 (match_operand 1 "memory_operand" "m") 8474 (match_operand:GPR 2 "register_operand" "=b")])] 8475 "" 8476{ 8477 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false); 8478 DONE; 8479}) 8480 8481 8482;; Reload patterns for various types using the vector registers. We may need 8483;; an additional base register to convert the reg+offset addressing to reg+reg 8484;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an 8485;; index register for gpr registers. 8486(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store" 8487 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m") 8488 (match_operand:RELOAD 1 "gpc_reg_operand" "wa") 8489 (match_operand:P 2 "register_operand" "=b")])] 8490 "<P:tptrsize>" 8491{ 8492 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true); 8493 DONE; 8494}) 8495 8496(define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load" 8497 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa") 8498 (match_operand:RELOAD 1 "memory_operand" "m") 8499 (match_operand:P 2 "register_operand" "=b")])] 8500 "<P:tptrsize>" 8501{ 8502 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false); 8503 DONE; 8504}) 8505 8506 8507;; Reload sometimes tries to move the address to a GPR, and can generate 8508;; invalid RTL for addresses involving AND -16. Allow addresses involving 8509;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16. 8510 8511(define_insn_and_split "*vec_reload_and_plus_<mptrsize>" 8512 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 8513 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r") 8514 (match_operand:P 2 "reg_or_cint_operand" "rI")) 8515 (const_int -16)))] 8516 "TARGET_ALTIVEC && reload_completed" 8517 "#" 8518 "&& reload_completed" 8519 [(set (match_dup 0) 8520 (plus:P (match_dup 1) 8521 (match_dup 2))) 8522 (set (match_dup 0) 8523 (and:P (match_dup 0) 8524 (const_int -16)))]) 8525 8526;; Power8 merge instructions to allow direct move to/from floating point 8527;; registers in 32-bit mode. We use TF mode to get two registers to move the 8528;; individual 32-bit parts across. Subreg doesn't work too well on the TF 8529;; value, since it is allocated in reload and not all of the flow information 8530;; is setup for it. We have two patterns to do the two moves between gprs and 8531;; fprs. There isn't a dependancy between the two, but we could potentially 8532;; schedule other instructions between the two instructions. 8533 8534(define_insn "p8_fmrgow_<mode>" 8535 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 8536 (unspec:FMOVE64X [ 8537 (match_operand:DF 1 "register_operand" "d") 8538 (match_operand:DF 2 "register_operand" "d")] 8539 UNSPEC_P8V_FMRGOW))] 8540 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8541 "fmrgow %0,%1,%2" 8542 [(set_attr "type" "fpsimple")]) 8543 8544(define_insn "p8_mtvsrwz" 8545 [(set (match_operand:DF 0 "register_operand" "=d") 8546 (unspec:DF [(match_operand:SI 1 "register_operand" "r")] 8547 UNSPEC_P8V_MTVSRWZ))] 8548 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8549 "mtvsrwz %x0,%1" 8550 [(set_attr "type" "mftgpr")]) 8551 8552(define_insn_and_split "reload_fpr_from_gpr<mode>" 8553 [(set (match_operand:FMOVE64X 0 "register_operand" "=d") 8554 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")] 8555 UNSPEC_P8V_RELOAD_FROM_GPR)) 8556 (clobber (match_operand:IF 2 "register_operand" "=d"))] 8557 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8558 "#" 8559 "&& reload_completed" 8560 [(const_int 0)] 8561{ 8562 rtx dest = operands[0]; 8563 rtx src = operands[1]; 8564 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 8565 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 8566 rtx gpr_hi_reg = gen_highpart (SImode, src); 8567 rtx gpr_lo_reg = gen_lowpart (SImode, src); 8568 8569 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg)); 8570 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg)); 8571 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo)); 8572 DONE; 8573} 8574 [(set_attr "length" "12") 8575 (set_attr "type" "three")]) 8576 8577;; Move 128 bit values from GPRs to VSX registers in 64-bit mode 8578(define_insn "p8_mtvsrd_df" 8579 [(set (match_operand:DF 0 "register_operand" "=wa") 8580 (unspec:DF [(match_operand:DI 1 "register_operand" "r")] 8581 UNSPEC_P8V_MTVSRD))] 8582 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8583 "mtvsrd %x0,%1" 8584 [(set_attr "type" "mftgpr")]) 8585 8586(define_insn "p8_xxpermdi_<mode>" 8587 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 8588 (unspec:FMOVE128_GPR [ 8589 (match_operand:DF 1 "register_operand" "wa") 8590 (match_operand:DF 2 "register_operand" "wa")] 8591 UNSPEC_P8V_XXPERMDI))] 8592 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8593 "xxpermdi %x0,%x1,%x2,0" 8594 [(set_attr "type" "vecperm")]) 8595 8596(define_insn_and_split "reload_vsx_from_gpr<mode>" 8597 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa") 8598 (unspec:FMOVE128_GPR 8599 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")] 8600 UNSPEC_P8V_RELOAD_FROM_GPR)) 8601 (clobber (match_operand:IF 2 "register_operand" "=wa"))] 8602 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8603 "#" 8604 "&& reload_completed" 8605 [(const_int 0)] 8606{ 8607 rtx dest = operands[0]; 8608 rtx src = operands[1]; 8609 /* You might think that we could use op0 as one temp and a DF clobber 8610 as op2, but you'd be wrong. Secondary reload move patterns don't 8611 check for overlap of the clobber and the destination. */ 8612 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0); 8613 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8); 8614 rtx gpr_hi_reg = gen_highpart (DImode, src); 8615 rtx gpr_lo_reg = gen_lowpart (DImode, src); 8616 8617 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg)); 8618 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg)); 8619 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo)); 8620 DONE; 8621} 8622 [(set_attr "length" "12") 8623 (set_attr "type" "three")]) 8624 8625(define_split 8626 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand") 8627 (match_operand:FMOVE128_GPR 1 "input_operand"))] 8628 "reload_completed 8629 && (int_reg_operand (operands[0], <MODE>mode) 8630 || int_reg_operand (operands[1], <MODE>mode)) 8631 && (!TARGET_DIRECT_MOVE_128 8632 || (!vsx_register_operand (operands[0], <MODE>mode) 8633 && !vsx_register_operand (operands[1], <MODE>mode)))" 8634 [(pc)] 8635{ 8636 rs6000_split_multireg_move (operands[0], operands[1]); 8637 DONE; 8638}) 8639 8640;; Move SFmode to a VSX from a GPR register. Because scalar floating point 8641;; type is stored internally as double precision in the VSX registers, we have 8642;; to convert it from the vector format. 8643(define_insn "p8_mtvsrd_sf" 8644 [(set (match_operand:SF 0 "register_operand" "=wa") 8645 (unspec:SF [(match_operand:DI 1 "register_operand" "r")] 8646 UNSPEC_P8V_MTVSRD))] 8647 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8648 "mtvsrd %x0,%1" 8649 [(set_attr "type" "mftgpr")]) 8650 8651(define_insn_and_split "reload_vsx_from_gprsf" 8652 [(set (match_operand:SF 0 "register_operand" "=wa") 8653 (unspec:SF [(match_operand:SF 1 "register_operand" "r")] 8654 UNSPEC_P8V_RELOAD_FROM_GPR)) 8655 (clobber (match_operand:DI 2 "register_operand" "=r"))] 8656 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8657 "#" 8658 "&& reload_completed" 8659 [(const_int 0)] 8660{ 8661 rtx op0 = operands[0]; 8662 rtx op1 = operands[1]; 8663 rtx op2 = operands[2]; 8664 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0); 8665 8666 /* Move SF value to upper 32-bits for xscvspdpn. */ 8667 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32))); 8668 emit_insn (gen_p8_mtvsrd_sf (op0, op2)); 8669 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0)); 8670 DONE; 8671} 8672 [(set_attr "length" "8") 8673 (set_attr "type" "two")]) 8674 8675;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a 8676;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value, 8677;; and then doing a move of that. 8678(define_insn "p8_mfvsrd_3_<mode>" 8679 [(set (match_operand:DF 0 "register_operand" "=r") 8680 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 8681 UNSPEC_P8V_RELOAD_FROM_VSX))] 8682 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8683 "mfvsrd %0,%x1" 8684 [(set_attr "type" "mftgpr")]) 8685 8686(define_insn_and_split "reload_gpr_from_vsx<mode>" 8687 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r") 8688 (unspec:FMOVE128_GPR 8689 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")] 8690 UNSPEC_P8V_RELOAD_FROM_VSX)) 8691 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))] 8692 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8693 "#" 8694 "&& reload_completed" 8695 [(const_int 0)] 8696{ 8697 rtx dest = operands[0]; 8698 rtx src = operands[1]; 8699 rtx tmp = operands[2]; 8700 rtx gpr_hi_reg = gen_highpart (DFmode, dest); 8701 rtx gpr_lo_reg = gen_lowpart (DFmode, dest); 8702 8703 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src)); 8704 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3))); 8705 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp)); 8706 DONE; 8707} 8708 [(set_attr "length" "12") 8709 (set_attr "type" "three")]) 8710 8711;; Move SFmode to a GPR from a VSX register. Because scalar floating point 8712;; type is stored internally as double precision, we have to convert it to the 8713;; vector format. 8714 8715(define_insn_and_split "reload_gpr_from_vsxsf" 8716 [(set (match_operand:SF 0 "register_operand" "=r") 8717 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")] 8718 UNSPEC_P8V_RELOAD_FROM_VSX)) 8719 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))] 8720 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE" 8721 "#" 8722 "&& reload_completed" 8723 [(const_int 0)] 8724{ 8725 rtx op0 = operands[0]; 8726 rtx op1 = operands[1]; 8727 rtx op2 = operands[2]; 8728 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0)); 8729 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2)); 8730 8731 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1)); 8732 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si)); 8733 DONE; 8734} 8735 [(set_attr "length" "8") 8736 (set_attr "type" "two") 8737 (set_attr "isa" "p8v")]) 8738 8739;; Next come the multi-word integer load and store and the load and store 8740;; multiple insns. 8741 8742;; List r->r after r->Y, otherwise reload will try to reload a 8743;; non-offsettable address by using r->r which won't make progress. 8744;; Use of fprs is disparaged slightly otherwise reload prefers to reload 8745;; a gpr into a fpr instead of reloading an invalid 'Y' address 8746 8747;; GPR store GPR load GPR move FPR store FPR load FPR move 8748;; GPR const AVX store AVX store AVX load AVX load VSX move 8749;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const 8750;; AVX const 8751 8752(define_insn "*movdi_internal32" 8753 [(set (match_operand:DI 0 "nonimmediate_operand" 8754 "=Y, r, r, m, ^d, ^d, 8755 r, wY, Z, ^v, $v, ^wa, 8756 wa, wa, v, wa, *i, v, 8757 v") 8758 (match_operand:DI 1 "input_operand" 8759 "r, Y, r, ^d, m, ^d, 8760 IJKnF, ^v, $v, wY, Z, ^wa, 8761 Oj, wM, OjwM, Oj, wM, wS, 8762 wB"))] 8763 "! TARGET_POWERPC64 8764 && (gpc_reg_operand (operands[0], DImode) 8765 || gpc_reg_operand (operands[1], DImode))" 8766 "@ 8767 # 8768 # 8769 # 8770 stfd%U0%X0 %1,%0 8771 lfd%U1%X1 %0,%1 8772 fmr %0,%1 8773 # 8774 stxsd %1,%0 8775 stxsdx %x1,%y0 8776 lxsd %0,%1 8777 lxsdx %x0,%y1 8778 xxlor %x0,%x1,%x1 8779 xxspltib %x0,0 8780 xxspltib %x0,255 8781 vspltisw %0,%1 8782 xxlxor %x0,%x0,%x0 8783 xxlorc %x0,%x0,%x0 8784 # 8785 #" 8786 [(set_attr "type" 8787 "store, load, *, fpstore, fpload, fpsimple, 8788 *, fpstore, fpstore, fpload, fpload, veclogical, 8789 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple, 8790 vecsimple") 8791 (set_attr "size" "64") 8792 (set_attr "length" 8793 "8, 8, 8, *, *, *, 8794 16, *, *, *, *, *, 8795 *, *, *, *, *, 8, 8796 *") 8797 (set_attr "isa" 8798 "*, *, *, *, *, *, 8799 *, p9v, p7v, p9v, p7v, *, 8800 p9v, p9v, p7v, *, *, p7v, 8801 p7v")]) 8802 8803(define_split 8804 [(set (match_operand:DI 0 "gpc_reg_operand") 8805 (match_operand:DI 1 "const_int_operand"))] 8806 "! TARGET_POWERPC64 && reload_completed 8807 && gpr_or_gpr_p (operands[0], operands[1]) 8808 && !direct_move_p (operands[0], operands[1])" 8809 [(set (match_dup 2) (match_dup 4)) 8810 (set (match_dup 3) (match_dup 1))] 8811{ 8812 HOST_WIDE_INT value = INTVAL (operands[1]); 8813 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 8814 DImode); 8815 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 8816 DImode); 8817 operands[4] = GEN_INT (value >> 32); 8818 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000); 8819}) 8820 8821(define_split 8822 [(set (match_operand:DIFD 0 "nonimmediate_operand") 8823 (match_operand:DIFD 1 "input_operand"))] 8824 "reload_completed && !TARGET_POWERPC64 8825 && gpr_or_gpr_p (operands[0], operands[1]) 8826 && !direct_move_p (operands[0], operands[1])" 8827 [(pc)] 8828{ 8829 rs6000_split_multireg_move (operands[0], operands[1]); 8830 DONE; 8831}) 8832 8833;; GPR store GPR load GPR move 8834;; GPR li GPR lis GPR pli GPR # 8835;; FPR store FPR load FPR move 8836;; AVX store AVX store AVX load AVX load VSX move 8837;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 8838;; P9 const AVX const 8839;; From SPR To SPR SPR<->SPR 8840;; VSX->GPR GPR->VSX 8841(define_insn "*movdi_internal64" 8842 [(set (match_operand:DI 0 "nonimmediate_operand" 8843 "=YZ, r, r, 8844 r, r, r, r, 8845 m, ^d, ^d, 8846 wY, Z, $v, $v, ^wa, 8847 wa, wa, v, wa, wa, 8848 v, v, 8849 r, *h, *h, 8850 ?r, ?wa") 8851 (match_operand:DI 1 "input_operand" 8852 "r, YZ, r, 8853 I, L, eI, nF, 8854 ^d, m, ^d, 8855 ^v, $v, wY, Z, ^wa, 8856 Oj, wM, OjwM, Oj, wM, 8857 wS, wB, 8858 *h, r, 0, 8859 wa, r"))] 8860 "TARGET_POWERPC64 8861 && (gpc_reg_operand (operands[0], DImode) 8862 || gpc_reg_operand (operands[1], DImode))" 8863 "@ 8864 std%U0%X0 %1,%0 8865 ld%U1%X1 %0,%1 8866 mr %0,%1 8867 li %0,%1 8868 lis %0,%v1 8869 li %0,%1 8870 # 8871 stfd%U0%X0 %1,%0 8872 lfd%U1%X1 %0,%1 8873 fmr %0,%1 8874 stxsd %1,%0 8875 stxsdx %x1,%y0 8876 lxsd %0,%1 8877 lxsdx %x0,%y1 8878 xxlor %x0,%x1,%x1 8879 xxspltib %x0,0 8880 xxspltib %x0,255 8881 # 8882 xxlxor %x0,%x0,%x0 8883 xxlorc %x0,%x0,%x0 8884 # 8885 # 8886 mf%1 %0 8887 mt%0 %1 8888 nop 8889 mfvsrd %0,%x1 8890 mtvsrd %x0,%1" 8891 [(set_attr "type" 8892 "store, load, *, 8893 *, *, *, *, 8894 fpstore, fpload, fpsimple, 8895 fpstore, fpstore, fpload, fpload, veclogical, 8896 vecsimple, vecsimple, vecsimple, veclogical, veclogical, 8897 vecsimple, vecsimple, 8898 mfjmpr, mtjmpr, *, 8899 mftgpr, mffgpr") 8900 (set_attr "size" "64") 8901 (set_attr "length" 8902 "*, *, *, 8903 *, *, *, 20, 8904 *, *, *, 8905 *, *, *, *, *, 8906 *, *, *, *, *, 8907 8, *, 8908 *, *, *, 8909 *, *") 8910 (set_attr "isa" 8911 "*, *, *, 8912 *, *, p10, *, 8913 *, *, *, 8914 p9v, p7v, p9v, p7v, *, 8915 p9v, p9v, p7v, *, *, 8916 p7v, p7v, 8917 *, *, *, 8918 p8v, p8v")]) 8919 8920; Some DImode loads are best done as a load of -1 followed by a mask 8921; instruction. 8922(define_split 8923 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 8924 (match_operand:DI 1 "const_int_operand"))] 8925 "TARGET_POWERPC64 8926 && num_insns_constant (operands[1], DImode) > 1 8927 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff) 8928 && rs6000_is_valid_and_mask (operands[1], DImode)" 8929 [(set (match_dup 0) 8930 (const_int -1)) 8931 (set (match_dup 0) 8932 (and:DI (match_dup 0) 8933 (match_dup 1)))] 8934 "") 8935 8936;; Split a load of a large constant into the appropriate five-instruction 8937;; sequence. Handle anything in a constant number of insns. 8938;; When non-easy constants can go in the TOC, this should use 8939;; easy_fp_constant predicate. 8940(define_split 8941 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 8942 (match_operand:DI 1 "const_int_operand"))] 8943 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 8944 [(set (match_dup 0) (match_dup 2)) 8945 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 8946{ 8947 if (rs6000_emit_set_const (operands[0], operands[1])) 8948 DONE; 8949 else 8950 FAIL; 8951}) 8952 8953(define_split 8954 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo") 8955 (match_operand:DI 1 "const_scalar_int_operand"))] 8956 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1" 8957 [(set (match_dup 0) (match_dup 2)) 8958 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))] 8959{ 8960 if (rs6000_emit_set_const (operands[0], operands[1])) 8961 DONE; 8962 else 8963 FAIL; 8964}) 8965 8966(define_split 8967 [(set (match_operand:DI 0 "altivec_register_operand") 8968 (match_operand:DI 1 "s5bit_cint_operand"))] 8969 "TARGET_VSX && reload_completed" 8970 [(const_int 0)] 8971{ 8972 rtx op0 = operands[0]; 8973 rtx op1 = operands[1]; 8974 int r = REGNO (op0); 8975 rtx op0_v4si = gen_rtx_REG (V4SImode, r); 8976 8977 emit_insn (gen_altivec_vspltisw (op0_v4si, op1)); 8978 if (op1 != const0_rtx && op1 != constm1_rtx) 8979 { 8980 rtx op0_v2di = gen_rtx_REG (V2DImode, r); 8981 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si)); 8982 } 8983 DONE; 8984}) 8985 8986;; Split integer constants that can be loaded with XXSPLTIB and a 8987;; sign extend operation. 8988(define_split 8989 [(set (match_operand:INT_ISA3 0 "altivec_register_operand") 8990 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))] 8991 "TARGET_P9_VECTOR && reload_completed" 8992 [(const_int 0)] 8993{ 8994 rtx op0 = operands[0]; 8995 rtx op1 = operands[1]; 8996 int r = REGNO (op0); 8997 rtx op0_v16qi = gen_rtx_REG (V16QImode, r); 8998 8999 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1)); 9000 if (<MODE>mode == DImode) 9001 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi)); 9002 else if (<MODE>mode == SImode) 9003 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi)); 9004 else if (<MODE>mode == HImode) 9005 { 9006 rtx op0_v8hi = gen_rtx_REG (V8HImode, r); 9007 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi)); 9008 } 9009 DONE; 9010}) 9011 9012 9013;; TImode/PTImode is similar, except that we usually want to compute the 9014;; address into a register and use lsi/stsi (the exception is during reload). 9015 9016(define_insn "*mov<mode>_string" 9017 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r") 9018 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))] 9019 "! TARGET_POWERPC64 9020 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode)) 9021 && (gpc_reg_operand (operands[0], <MODE>mode) 9022 || gpc_reg_operand (operands[1], <MODE>mode))" 9023 "#" 9024 [(set_attr "type" "store,store,load,load,*,*") 9025 (set_attr "update" "yes") 9026 (set_attr "indexed" "yes") 9027 (set_attr "cell_micro" "conditional")]) 9028 9029(define_insn "*mov<mode>_ppc64" 9030 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r") 9031 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))] 9032 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode) 9033 && (gpc_reg_operand (operands[0], <MODE>mode) 9034 || gpc_reg_operand (operands[1], <MODE>mode)))" 9035{ 9036 return rs6000_output_move_128bit (operands); 9037} 9038 [(set_attr "type" "store,store,load,load,*,*") 9039 (set_attr "length" "8") 9040 (set_attr "max_prefixed_insns" "2")]) 9041 9042(define_split 9043 [(set (match_operand:TI2 0 "int_reg_operand") 9044 (match_operand:TI2 1 "const_scalar_int_operand"))] 9045 "TARGET_POWERPC64 9046 && (VECTOR_MEM_NONE_P (<MODE>mode) 9047 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))" 9048 [(set (match_dup 2) (match_dup 4)) 9049 (set (match_dup 3) (match_dup 5))] 9050{ 9051 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0, 9052 <MODE>mode); 9053 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0, 9054 <MODE>mode); 9055 if (CONST_WIDE_INT_P (operands[1])) 9056 { 9057 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1)); 9058 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0)); 9059 } 9060 else if (CONST_INT_P (operands[1])) 9061 { 9062 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0)); 9063 operands[5] = operands[1]; 9064 } 9065 else 9066 FAIL; 9067}) 9068 9069(define_split 9070 [(set (match_operand:TI2 0 "nonimmediate_operand") 9071 (match_operand:TI2 1 "input_operand"))] 9072 "reload_completed 9073 && gpr_or_gpr_p (operands[0], operands[1]) 9074 && !direct_move_p (operands[0], operands[1]) 9075 && !quad_load_store_p (operands[0], operands[1])" 9076 [(pc)] 9077{ 9078 rs6000_split_multireg_move (operands[0], operands[1]); 9079 DONE; 9080}) 9081 9082(define_expand "setmemsi" 9083 [(parallel [(set (match_operand:BLK 0 "") 9084 (match_operand 2 "const_int_operand")) 9085 (use (match_operand:SI 1 "")) 9086 (use (match_operand:SI 3 ""))])] 9087 "" 9088{ 9089 /* If value to set is not zero, use the library routine. */ 9090 if (operands[2] != const0_rtx) 9091 FAIL; 9092 9093 if (expand_block_clear (operands)) 9094 DONE; 9095 else 9096 FAIL; 9097}) 9098 9099;; String compare N insn. 9100;; Argument 0 is the target (result) 9101;; Argument 1 is the destination 9102;; Argument 2 is the source 9103;; Argument 3 is the length 9104;; Argument 4 is the alignment 9105 9106(define_expand "cmpstrnsi" 9107 [(parallel [(set (match_operand:SI 0) 9108 (compare:SI (match_operand:BLK 1) 9109 (match_operand:BLK 2))) 9110 (use (match_operand:SI 3)) 9111 (use (match_operand:SI 4))])] 9112 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)" 9113{ 9114 if (optimize_insn_for_size_p ()) 9115 FAIL; 9116 9117 if (expand_strn_compare (operands, 0)) 9118 DONE; 9119 else 9120 FAIL; 9121}) 9122 9123;; String compare insn. 9124;; Argument 0 is the target (result) 9125;; Argument 1 is the destination 9126;; Argument 2 is the source 9127;; Argument 3 is the alignment 9128 9129(define_expand "cmpstrsi" 9130 [(parallel [(set (match_operand:SI 0) 9131 (compare:SI (match_operand:BLK 1) 9132 (match_operand:BLK 2))) 9133 (use (match_operand:SI 3))])] 9134 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)" 9135{ 9136 if (optimize_insn_for_size_p ()) 9137 FAIL; 9138 9139 if (expand_strn_compare (operands, 1)) 9140 DONE; 9141 else 9142 FAIL; 9143}) 9144 9145;; Block compare insn. 9146;; Argument 0 is the target (result) 9147;; Argument 1 is the destination 9148;; Argument 2 is the source 9149;; Argument 3 is the length 9150;; Argument 4 is the alignment 9151 9152(define_expand "cmpmemsi" 9153 [(parallel [(set (match_operand:SI 0) 9154 (compare:SI (match_operand:BLK 1) 9155 (match_operand:BLK 2))) 9156 (use (match_operand:SI 3)) 9157 (use (match_operand:SI 4))])] 9158 "TARGET_POPCNTD" 9159{ 9160 if (expand_block_compare (operands)) 9161 DONE; 9162 else 9163 FAIL; 9164}) 9165 9166;; String/block copy insn (source and destination must not overlap). 9167;; Argument 0 is the destination 9168;; Argument 1 is the source 9169;; Argument 2 is the length 9170;; Argument 3 is the alignment 9171 9172(define_expand "cpymemsi" 9173 [(parallel [(set (match_operand:BLK 0 "") 9174 (match_operand:BLK 1 "")) 9175 (use (match_operand:SI 2 "")) 9176 (use (match_operand:SI 3 ""))])] 9177 "" 9178{ 9179 if (expand_block_move (operands, false)) 9180 DONE; 9181 else 9182 FAIL; 9183}) 9184 9185;; String/block move insn (source and destination may overlap). 9186;; Argument 0 is the destination 9187;; Argument 1 is the source 9188;; Argument 2 is the length 9189;; Argument 3 is the alignment 9190 9191(define_expand "movmemsi" 9192 [(parallel [(set (match_operand:BLK 0 "") 9193 (match_operand:BLK 1 "")) 9194 (use (match_operand:SI 2 "")) 9195 (use (match_operand:SI 3 ""))])] 9196 "" 9197{ 9198 if (expand_block_move (operands, true)) 9199 DONE; 9200 else 9201 FAIL; 9202}) 9203 9204 9205;; Define insns that do load or store with update. Some of these we can 9206;; get by using pre-decrement or pre-increment, but the hardware can also 9207;; do cases where the increment is not the size of the object. 9208;; 9209;; In all these cases, we use operands 0 and 1 for the register being 9210;; incremented because those are the operands that local-alloc will 9211;; tie and these are the pair most likely to be tieable (and the ones 9212;; that will benefit the most). 9213 9214(define_insn "*movdi_update1" 9215 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r") 9216 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9217 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))) 9218 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9219 (plus:P (match_dup 1) (match_dup 2)))] 9220 "TARGET_POWERPC64 && TARGET_UPDATE 9221 && (!avoiding_indexed_address_p (DImode) 9222 || !gpc_reg_operand (operands[2], Pmode))" 9223 "@ 9224 ldux %3,%0,%2 9225 ldu %3,%2(%0)" 9226 [(set_attr "type" "load") 9227 (set_attr "update" "yes") 9228 (set_attr "indexed" "yes,no")]) 9229 9230(define_insn "movdi_<mode>_update" 9231 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9232 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))) 9233 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 9234 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9235 (plus:P (match_dup 1) (match_dup 2)))] 9236 "TARGET_POWERPC64 && TARGET_UPDATE 9237 && (!avoiding_indexed_address_p (DImode) 9238 || !gpc_reg_operand (operands[2], Pmode) 9239 || (REG_P (operands[0]) 9240 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 9241 "@ 9242 stdux %3,%0,%2 9243 stdu %3,%2(%0)" 9244 [(set_attr "type" "store") 9245 (set_attr "update" "yes") 9246 (set_attr "indexed" "yes,no")]) 9247 9248;; This pattern is only conditional on TARGET_64BIT, as it is 9249;; needed for stack allocation, even if the user passes -mno-update. 9250(define_insn "movdi_update_stack" 9251 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0") 9252 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))) 9253 (match_operand:DI 3 "gpc_reg_operand" "r,r")) 9254 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b") 9255 (plus:DI (match_dup 1) (match_dup 2)))] 9256 "TARGET_64BIT" 9257 "@ 9258 stdux %3,%0,%2 9259 stdu %3,%2(%0)" 9260 [(set_attr "type" "store") 9261 (set_attr "update" "yes") 9262 (set_attr "indexed" "yes,no")]) 9263 9264(define_insn "*movsi_update1" 9265 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r") 9266 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9267 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 9268 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9269 (plus:P (match_dup 1) (match_dup 2)))] 9270 "TARGET_UPDATE 9271 && (!avoiding_indexed_address_p (SImode) 9272 || !gpc_reg_operand (operands[2], Pmode))" 9273 "@ 9274 lwzux %3,%0,%2 9275 lwzu %3,%2(%0)" 9276 [(set_attr "type" "load") 9277 (set_attr "update" "yes") 9278 (set_attr "indexed" "yes,no")]) 9279 9280(define_insn "*movsi_update2" 9281 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r") 9282 (sign_extend:EXTSI 9283 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0") 9284 (match_operand:P 2 "gpc_reg_operand" "r"))))) 9285 (set (match_operand:P 0 "gpc_reg_operand" "=b") 9286 (plus:P (match_dup 1) (match_dup 2)))] 9287 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)" 9288 "lwaux %3,%0,%2" 9289 [(set_attr "type" "load") 9290 (set_attr "sign_extend" "yes") 9291 (set_attr "update" "yes") 9292 (set_attr "indexed" "yes")]) 9293 9294(define_insn "movsi_<mode>_update" 9295 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9296 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 9297 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 9298 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9299 (plus:P (match_dup 1) (match_dup 2)))] 9300 "TARGET_UPDATE 9301 && (!avoiding_indexed_address_p (SImode) 9302 || !gpc_reg_operand (operands[2], Pmode) 9303 || (REG_P (operands[0]) 9304 && REGNO (operands[0]) == STACK_POINTER_REGNUM))" 9305 "@ 9306 stwux %3,%0,%2 9307 stwu %3,%2(%0)" 9308 [(set_attr "type" "store") 9309 (set_attr "update" "yes") 9310 (set_attr "indexed" "yes,no")]) 9311 9312;; This is an unconditional pattern; needed for stack allocation, even 9313;; if the user passes -mno-update. 9314(define_insn "movsi_update_stack" 9315 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0") 9316 (match_operand:SI 2 "reg_or_short_operand" "r,I"))) 9317 (match_operand:SI 3 "gpc_reg_operand" "r,r")) 9318 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b") 9319 (plus:SI (match_dup 1) (match_dup 2)))] 9320 "TARGET_32BIT" 9321 "@ 9322 stwux %3,%0,%2 9323 stwu %3,%2(%0)" 9324 [(set_attr "type" "store") 9325 (set_attr "update" "yes") 9326 (set_attr "indexed" "yes,no")]) 9327 9328(define_insn "*movhi_update1" 9329 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r") 9330 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9331 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 9332 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9333 (plus:P (match_dup 1) (match_dup 2)))] 9334 "TARGET_UPDATE 9335 && (!avoiding_indexed_address_p (HImode) 9336 || !gpc_reg_operand (operands[2], SImode))" 9337 "@ 9338 lhzux %3,%0,%2 9339 lhzu %3,%2(%0)" 9340 [(set_attr "type" "load") 9341 (set_attr "update" "yes") 9342 (set_attr "indexed" "yes,no")]) 9343 9344(define_insn "*movhi_update2" 9345 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r") 9346 (zero_extend:EXTHI 9347 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9348 (match_operand:P 2 "reg_or_short_operand" "r,I"))))) 9349 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9350 (plus:P (match_dup 1) (match_dup 2)))] 9351 "TARGET_UPDATE 9352 && (!avoiding_indexed_address_p (HImode) 9353 || !gpc_reg_operand (operands[2], Pmode))" 9354 "@ 9355 lhzux %3,%0,%2 9356 lhzu %3,%2(%0)" 9357 [(set_attr "type" "load") 9358 (set_attr "update" "yes") 9359 (set_attr "indexed" "yes,no")]) 9360 9361(define_insn "*movhi_update3" 9362 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r") 9363 (sign_extend:EXTHI 9364 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9365 (match_operand:P 2 "reg_or_short_operand" "r,I"))))) 9366 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9367 (plus:P (match_dup 1) (match_dup 2)))] 9368 "TARGET_UPDATE 9369 && !(avoiding_indexed_address_p (HImode) 9370 && gpc_reg_operand (operands[2], Pmode))" 9371 "@ 9372 lhaux %3,%0,%2 9373 lhau %3,%2(%0)" 9374 [(set_attr "type" "load") 9375 (set_attr "sign_extend" "yes") 9376 (set_attr "update" "yes") 9377 (set_attr "indexed" "yes,no")]) 9378 9379(define_insn "*movhi_update4" 9380 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9381 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 9382 (match_operand:HI 3 "gpc_reg_operand" "r,r")) 9383 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9384 (plus:P (match_dup 1) (match_dup 2)))] 9385 "TARGET_UPDATE 9386 && (!avoiding_indexed_address_p (HImode) 9387 || !gpc_reg_operand (operands[2], Pmode))" 9388 "@ 9389 sthux %3,%0,%2 9390 sthu %3,%2(%0)" 9391 [(set_attr "type" "store") 9392 (set_attr "update" "yes") 9393 (set_attr "indexed" "yes,no")]) 9394 9395(define_insn "*movqi_update1" 9396 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r") 9397 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9398 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 9399 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9400 (plus:P (match_dup 1) (match_dup 2)))] 9401 "TARGET_UPDATE 9402 && (!avoiding_indexed_address_p (QImode) 9403 || !gpc_reg_operand (operands[2], Pmode))" 9404 "@ 9405 lbzux %3,%0,%2 9406 lbzu %3,%2(%0)" 9407 [(set_attr "type" "load") 9408 (set_attr "update" "yes") 9409 (set_attr "indexed" "yes,no")]) 9410 9411(define_insn "*movqi_update2" 9412 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r") 9413 (zero_extend:EXTQI 9414 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9415 (match_operand:P 2 "reg_or_short_operand" "r,I"))))) 9416 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9417 (plus:P (match_dup 1) (match_dup 2)))] 9418 "TARGET_UPDATE 9419 && (!avoiding_indexed_address_p (QImode) 9420 || !gpc_reg_operand (operands[2], Pmode))" 9421 "@ 9422 lbzux %3,%0,%2 9423 lbzu %3,%2(%0)" 9424 [(set_attr "type" "load") 9425 (set_attr "update" "yes") 9426 (set_attr "indexed" "yes,no")]) 9427 9428(define_insn "*movqi_update3" 9429 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9430 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 9431 (match_operand:QI 3 "gpc_reg_operand" "r,r")) 9432 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9433 (plus:P (match_dup 1) (match_dup 2)))] 9434 "TARGET_UPDATE 9435 && (!avoiding_indexed_address_p (QImode) 9436 || !gpc_reg_operand (operands[2], Pmode))" 9437 "@ 9438 stbux %3,%0,%2 9439 stbu %3,%2(%0)" 9440 [(set_attr "type" "store") 9441 (set_attr "update" "yes") 9442 (set_attr "indexed" "yes,no")]) 9443 9444(define_insn "*mov<SFDF:mode>_update1" 9445 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>") 9446 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9447 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 9448 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9449 (plus:P (match_dup 1) (match_dup 2)))] 9450 "TARGET_HARD_FLOAT && TARGET_UPDATE 9451 && (!avoiding_indexed_address_p (<SFDF:MODE>mode) 9452 || !gpc_reg_operand (operands[2], Pmode))" 9453 "@ 9454 lf<sd>ux %3,%0,%2 9455 lf<sd>u %3,%2(%0)" 9456 [(set_attr "type" "fpload") 9457 (set_attr "update" "yes") 9458 (set_attr "indexed" "yes,no") 9459 (set_attr "size" "<SFDF:bits>")]) 9460 9461(define_insn "*mov<SFDF:mode>_update2" 9462 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9463 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 9464 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>")) 9465 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9466 (plus:P (match_dup 1) (match_dup 2)))] 9467 "TARGET_HARD_FLOAT && TARGET_UPDATE 9468 && (!avoiding_indexed_address_p (<SFDF:MODE>mode) 9469 || !gpc_reg_operand (operands[2], Pmode))" 9470 "@ 9471 stf<sd>ux %3,%0,%2 9472 stf<sd>u %3,%2(%0)" 9473 [(set_attr "type" "fpstore") 9474 (set_attr "update" "yes") 9475 (set_attr "indexed" "yes,no") 9476 (set_attr "size" "<SFDF:bits>")]) 9477 9478(define_insn "*movsf_update3" 9479 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r") 9480 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9481 (match_operand:P 2 "reg_or_short_operand" "r,I")))) 9482 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9483 (plus:P (match_dup 1) (match_dup 2)))] 9484 "TARGET_SOFT_FLOAT && TARGET_UPDATE 9485 && (!avoiding_indexed_address_p (SFmode) 9486 || !gpc_reg_operand (operands[2], Pmode))" 9487 "@ 9488 lwzux %3,%0,%2 9489 lwzu %3,%2(%0)" 9490 [(set_attr "type" "load") 9491 (set_attr "update" "yes") 9492 (set_attr "indexed" "yes,no")]) 9493 9494(define_insn "*movsf_update4" 9495 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0") 9496 (match_operand:P 2 "reg_or_short_operand" "r,I"))) 9497 (match_operand:SF 3 "gpc_reg_operand" "r,r")) 9498 (set (match_operand:P 0 "gpc_reg_operand" "=b,b") 9499 (plus:P (match_dup 1) (match_dup 2)))] 9500 "TARGET_SOFT_FLOAT && TARGET_UPDATE 9501 && (!avoiding_indexed_address_p (SFmode) 9502 || !gpc_reg_operand (operands[2], Pmode))" 9503 "@ 9504 stwux %3,%0,%2 9505 stwu %3,%2(%0)" 9506 [(set_attr "type" "store") 9507 (set_attr "update" "yes") 9508 (set_attr "indexed" "yes,no")]) 9509 9510 9511;; After inserting conditional returns we can sometimes have 9512;; unnecessary register moves. Unfortunately we cannot have a 9513;; modeless peephole here, because some single SImode sets have early 9514;; clobber outputs. Although those sets expand to multi-ppc-insn 9515;; sequences, using get_attr_length here will smash the operands 9516;; array. Neither is there an early_cobbler_p predicate. 9517;; Also this optimization interferes with scalars going into 9518;; altivec registers (the code does reloading through the FPRs). 9519(define_peephole2 9520 [(set (match_operand:DF 0 "gpc_reg_operand") 9521 (match_operand:DF 1 "any_operand")) 9522 (set (match_operand:DF 2 "gpc_reg_operand") 9523 (match_dup 0))] 9524 "!TARGET_VSX 9525 && peep2_reg_dead_p (2, operands[0])" 9526 [(set (match_dup 2) (match_dup 1))]) 9527 9528(define_peephole2 9529 [(set (match_operand:SF 0 "gpc_reg_operand") 9530 (match_operand:SF 1 "any_operand")) 9531 (set (match_operand:SF 2 "gpc_reg_operand") 9532 (match_dup 0))] 9533 "!TARGET_P8_VECTOR 9534 && peep2_reg_dead_p (2, operands[0])" 9535 [(set (match_dup 2) (match_dup 1))]) 9536 9537 9538;; TLS support. 9539 9540(define_insn "*tls_gd_pcrel<bits>" 9541 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9542 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") 9543 (const_int 0)] 9544 UNSPEC_TLSGD))] 9545 "HAVE_AS_TLS && TARGET_ELF" 9546 "la %0,%1@got@tlsgd@pcrel" 9547 [(set_attr "prefixed" "yes")]) 9548 9549(define_insn_and_split "*tls_gd<bits>" 9550 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9551 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") 9552 (match_operand:P 2 "gpc_reg_operand" "b")] 9553 UNSPEC_TLSGD))] 9554 "HAVE_AS_TLS && TARGET_ELF" 9555 "addi %0,%2,%1@got@tlsgd" 9556 "&& TARGET_CMODEL != CMODEL_SMALL" 9557 [(set (match_dup 3) 9558 (high:P 9559 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD))) 9560 (set (match_dup 0) 9561 (lo_sum:P (match_dup 3) 9562 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))] 9563{ 9564 operands[3] = gen_reg_rtx (<MODE>mode); 9565} 9566 [(set (attr "length") 9567 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9568 (const_int 8) 9569 (const_int 4)))]) 9570 9571(define_insn "*tls_gd_high<bits>" 9572 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9573 (high:P 9574 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "") 9575 (match_operand:P 2 "gpc_reg_operand" "b")] 9576 UNSPEC_TLSGD)))] 9577 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9578 "addis %0,%2,%1@got@tlsgd@ha") 9579 9580(define_insn "*tls_gd_low<bits>" 9581 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9582 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 9583 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "") 9584 (match_operand:P 3 "gpc_reg_operand" "b")] 9585 UNSPEC_TLSGD)))] 9586 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9587 "addi %0,%1,%2@got@tlsgd@l") 9588 9589(define_insn "*tls_ld_pcrel<bits>" 9590 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9591 (unspec:P [(const_int 0)] 9592 UNSPEC_TLSLD))] 9593 "HAVE_AS_TLS && TARGET_ELF" 9594 "la %0,%&@got@tlsld@pcrel" 9595 [(set_attr "prefixed" "yes")]) 9596 9597(define_insn_and_split "*tls_ld<bits>" 9598 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9599 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] 9600 UNSPEC_TLSLD))] 9601 "HAVE_AS_TLS && TARGET_ELF" 9602 "addi %0,%1,%&@got@tlsld" 9603 "&& TARGET_CMODEL != CMODEL_SMALL" 9604 [(set (match_dup 2) 9605 (high:P 9606 (unspec:P [(match_dup 1)] UNSPEC_TLSLD))) 9607 (set (match_dup 0) 9608 (lo_sum:P (match_dup 2) 9609 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))] 9610{ 9611 operands[2] = gen_reg_rtx (<MODE>mode); 9612} 9613 [(set (attr "length") 9614 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9615 (const_int 8) 9616 (const_int 4)))]) 9617 9618(define_insn "*tls_ld_high<bits>" 9619 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9620 (high:P 9621 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")] 9622 UNSPEC_TLSLD)))] 9623 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9624 "addis %0,%1,%&@got@tlsld@ha") 9625 9626(define_insn "*tls_ld_low<bits>" 9627 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9628 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 9629 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")] 9630 UNSPEC_TLSLD)))] 9631 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 9632 "addi %0,%1,%&@got@tlsld@l") 9633 9634(define_insn "tls_dtprel_<bits>" 9635 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9636 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9637 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9638 UNSPEC_TLSDTPREL))] 9639 "HAVE_AS_TLS" 9640 "addi %0,%1,%2@dtprel" 9641 [(set (attr "prefixed") 9642 (if_then_else (match_test "rs6000_tls_size == 16") 9643 (const_string "no") 9644 (const_string "yes")))]) 9645 9646(define_insn "tls_dtprel_ha_<bits>" 9647 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9648 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9649 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9650 UNSPEC_TLSDTPRELHA))] 9651 "HAVE_AS_TLS" 9652 "addis %0,%1,%2@dtprel@ha") 9653 9654(define_insn "tls_dtprel_lo_<bits>" 9655 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9656 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9657 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9658 UNSPEC_TLSDTPRELLO))] 9659 "HAVE_AS_TLS" 9660 "addi %0,%1,%2@dtprel@l") 9661 9662(define_insn_and_split "tls_got_dtprel_<bits>" 9663 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9664 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9665 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9666 UNSPEC_TLSGOTDTPREL))] 9667 "HAVE_AS_TLS" 9668 "<ptrload> %0,%2@got@dtprel(%1)" 9669 "&& TARGET_CMODEL != CMODEL_SMALL" 9670 [(set (match_dup 3) 9671 (high:P 9672 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL))) 9673 (set (match_dup 0) 9674 (lo_sum:P (match_dup 3) 9675 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))] 9676{ 9677 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9678} 9679 [(set (attr "length") 9680 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9681 (const_int 8) 9682 (const_int 4)))]) 9683 9684(define_insn "*tls_got_dtprel_high<bits>" 9685 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9686 (high:P 9687 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9688 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9689 UNSPEC_TLSGOTDTPREL)))] 9690 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9691 "addis %0,%1,%2@got@dtprel@ha") 9692 9693(define_insn "*tls_got_dtprel_low<bits>" 9694 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9695 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 9696 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b") 9697 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9698 UNSPEC_TLSGOTDTPREL)))] 9699 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9700 "<ptrload> %0,%2@got@dtprel@l(%1)") 9701 9702(define_insn "tls_tprel_<bits>" 9703 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9704 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9705 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9706 UNSPEC_TLSTPREL))] 9707 "HAVE_AS_TLS" 9708 "addi %0,%1,%2@tprel" 9709 [(set (attr "prefixed") 9710 (if_then_else (match_test "rs6000_tls_size == 16") 9711 (const_string "no") 9712 (const_string "yes")))]) 9713 9714(define_insn "tls_tprel_ha_<bits>" 9715 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9716 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9717 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9718 UNSPEC_TLSTPRELHA))] 9719 "HAVE_AS_TLS" 9720 "addis %0,%1,%2@tprel@ha") 9721 9722(define_insn "tls_tprel_lo_<bits>" 9723 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9724 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9725 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9726 UNSPEC_TLSTPRELLO))] 9727 "HAVE_AS_TLS" 9728 "addi %0,%1,%2@tprel@l") 9729 9730(define_insn "*tls_got_tprel_pcrel_<bits>" 9731 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9732 (unspec:P [(const_int 0) 9733 (match_operand:P 1 "rs6000_tls_symbol_ref" "")] 9734 UNSPEC_TLSGOTTPREL))] 9735 "HAVE_AS_TLS" 9736 "<ptrload> %0,%1@got@tprel@pcrel" 9737 [(set_attr "prefixed" "yes")]) 9738 9739;; "b" output constraint here and on tls_tls input to support linker tls 9740;; optimization. The linker may edit the instructions emitted by a 9741;; tls_got_tprel/tls_tls pair to addis,addi. 9742(define_insn_and_split "tls_got_tprel_<bits>" 9743 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9744 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9745 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9746 UNSPEC_TLSGOTTPREL))] 9747 "HAVE_AS_TLS" 9748 "<ptrload> %0,%2@got@tprel(%1)" 9749 "&& TARGET_CMODEL != CMODEL_SMALL" 9750 [(set (match_dup 3) 9751 (high:P 9752 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL))) 9753 (set (match_dup 0) 9754 (lo_sum:P (match_dup 3) 9755 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))] 9756{ 9757 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode); 9758} 9759 [(set (attr "length") 9760 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL")) 9761 (const_int 8) 9762 (const_int 4)))]) 9763 9764(define_insn "*tls_got_tprel_high<bits>" 9765 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 9766 (high:P 9767 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9768 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9769 UNSPEC_TLSGOTTPREL)))] 9770 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9771 "addis %0,%1,%2@got@tprel@ha") 9772 9773(define_insn "*tls_got_tprel_low<bits>" 9774 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9775 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 9776 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b") 9777 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9778 UNSPEC_TLSGOTTPREL)))] 9779 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL" 9780 "<ptrload> %0,%2@got@tprel@l(%1)") 9781 9782(define_insn "tls_tls_pcrel_<bits>" 9783 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9784 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9785 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9786 UNSPEC_TLSTLS_PCREL))] 9787 "TARGET_ELF && HAVE_AS_TLS" 9788 "add %0,%1,%2@tls@pcrel") 9789 9790(define_insn "tls_tls_<bits>" 9791 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 9792 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 9793 (match_operand:P 2 "rs6000_tls_symbol_ref" "")] 9794 UNSPEC_TLSTLS))] 9795 "TARGET_ELF && HAVE_AS_TLS" 9796 "add %0,%1,%2@tls") 9797 9798(define_expand "tls_get_tpointer" 9799 [(set (match_operand:SI 0 "gpc_reg_operand") 9800 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))] 9801 "TARGET_XCOFF && HAVE_AS_TLS" 9802{ 9803 emit_insn (gen_tls_get_tpointer_internal ()); 9804 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3)); 9805 DONE; 9806}) 9807 9808(define_insn "tls_get_tpointer_internal" 9809 [(set (reg:SI 3) 9810 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS)) 9811 (clobber (reg:SI LR_REGNO))] 9812 "TARGET_XCOFF && HAVE_AS_TLS" 9813 "bla __get_tpointer") 9814 9815(define_expand "tls_get_addr<mode>" 9816 [(set (match_operand:P 0 "gpc_reg_operand") 9817 (unspec:P [(match_operand:P 1 "gpc_reg_operand") 9818 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))] 9819 "TARGET_XCOFF && HAVE_AS_TLS" 9820{ 9821 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]); 9822 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]); 9823 emit_insn (gen_tls_get_addr_internal<mode> ()); 9824 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3)); 9825 DONE; 9826}) 9827 9828(define_insn "tls_get_addr_internal<mode>" 9829 [(set (reg:P 3) 9830 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS)) 9831 (clobber (reg:P 0)) 9832 (clobber (reg:P 4)) 9833 (clobber (reg:P 5)) 9834 (clobber (reg:P 11)) 9835 (clobber (reg:CC CR0_REGNO)) 9836 (clobber (reg:P LR_REGNO))] 9837 "TARGET_XCOFF && HAVE_AS_TLS" 9838 "bla __tls_get_addr") 9839 9840;; Next come insns related to the calling sequence. 9841;; 9842;; First, an insn to allocate new stack space for dynamic use (e.g., alloca). 9843;; We move the back-chain and decrement the stack pointer. 9844;; 9845;; Operand1 is more naturally reg_or_short_operand. However, for a large 9846;; constant alloca, using that predicate will force the generic code to put 9847;; the constant size into a register before calling the expander. 9848;; 9849;; As a result the expander would not have the constant size information 9850;; in those cases and would have to generate less efficient code. 9851;; 9852;; Thus we allow reg_or_cint_operand instead so that the expander can see 9853;; the constant size. The value is forced into a register if necessary. 9854;; 9855(define_expand "allocate_stack" 9856 [(set (match_operand 0 "gpc_reg_operand") 9857 (minus (reg 1) (match_operand 1 "reg_or_cint_operand"))) 9858 (set (reg 1) 9859 (minus (reg 1) (match_dup 1)))] 9860 "" 9861{ 9862 rtx chain = gen_reg_rtx (Pmode); 9863 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx); 9864 rtx neg_op0; 9865 rtx insn, par, set, mem; 9866 9867 /* By allowing reg_or_cint_operand as the predicate we can get 9868 better code for stack-clash-protection because we do not lose 9869 size information. But the rest of the code expects the operand 9870 to be reg_or_short_operand. If it isn't, then force it into 9871 a register. */ 9872 rtx orig_op1 = operands[1]; 9873 if (!reg_or_short_operand (operands[1], Pmode)) 9874 operands[1] = force_reg (Pmode, operands[1]); 9875 9876 emit_move_insn (chain, stack_bot); 9877 9878 /* Check stack bounds if necessary. */ 9879 if (crtl->limit_stack) 9880 { 9881 rtx available; 9882 available = expand_binop (Pmode, sub_optab, 9883 stack_pointer_rtx, stack_limit_rtx, 9884 NULL_RTX, 1, OPTAB_WIDEN); 9885 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx)); 9886 } 9887 9888 /* Allocate and probe if requested. 9889 This may look similar to the loop we use for prologue allocations, 9890 but it is critically different. For the former we know the loop 9891 will iterate, but do not know that generally here. The former 9892 uses that knowledge to rotate the loop. Combining them would be 9893 possible with some performance cost. */ 9894 if (flag_stack_clash_protection) 9895 { 9896 rtx rounded_size, last_addr, residual; 9897 HOST_WIDE_INT probe_interval; 9898 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr, 9899 &residual, &probe_interval, 9900 orig_op1); 9901 9902 /* We do occasionally get in here with constant sizes, we might 9903 as well do a reasonable job when we obviously can. */ 9904 if (rounded_size != const0_rtx) 9905 { 9906 rtx loop_lab, end_loop; 9907 bool rotated = CONST_INT_P (rounded_size); 9908 rtx update = GEN_INT (-probe_interval); 9909 if (probe_interval > 32768) 9910 update = force_reg (Pmode, update); 9911 9912 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop, 9913 last_addr, rotated); 9914 9915 if (TARGET_32BIT) 9916 emit_insn (gen_movsi_update_stack (stack_pointer_rtx, 9917 stack_pointer_rtx, 9918 update, chain)); 9919 else 9920 emit_insn (gen_movdi_update_stack (stack_pointer_rtx, 9921 stack_pointer_rtx, 9922 update, chain)); 9923 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop, 9924 last_addr, rotated); 9925 } 9926 9927 /* Now handle residuals. We just have to set operands[1] correctly 9928 and let the rest of the expander run. */ 9929 operands[1] = residual; 9930 } 9931 9932 if (!(CONST_INT_P (operands[1]) 9933 && IN_RANGE (INTVAL (operands[1]), -32767, 32768))) 9934 { 9935 operands[1] = force_reg (Pmode, operands[1]); 9936 neg_op0 = gen_reg_rtx (Pmode); 9937 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1])); 9938 } 9939 else 9940 neg_op0 = GEN_INT (-INTVAL (operands[1])); 9941 9942 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack 9943 : gen_movdi_update_stack)) 9944 (stack_pointer_rtx, stack_pointer_rtx, neg_op0, 9945 chain)); 9946 /* Since we didn't use gen_frame_mem to generate the MEM, grab 9947 it now and set the alias set/attributes. The above gen_*_update 9948 calls will generate a PARALLEL with the MEM set being the first 9949 operation. */ 9950 par = PATTERN (insn); 9951 gcc_assert (GET_CODE (par) == PARALLEL); 9952 set = XVECEXP (par, 0, 0); 9953 gcc_assert (GET_CODE (set) == SET); 9954 mem = SET_DEST (set); 9955 gcc_assert (MEM_P (mem)); 9956 MEM_NOTRAP_P (mem) = 1; 9957 set_mem_alias_set (mem, get_frame_alias_set ()); 9958 9959 emit_move_insn (operands[0], virtual_stack_dynamic_rtx); 9960 DONE; 9961}) 9962 9963;; These patterns say how to save and restore the stack pointer. We need not 9964;; save the stack pointer at function level since we are careful to 9965;; preserve the backchain. At block level, we have to restore the backchain 9966;; when we restore the stack pointer. 9967;; 9968;; For nonlocal gotos, we must save both the stack pointer and its 9969;; backchain and restore both. Note that in the nonlocal case, the 9970;; save area is a memory location. 9971 9972(define_expand "save_stack_function" 9973 [(match_operand 0 "any_operand") 9974 (match_operand 1 "any_operand")] 9975 "" 9976 "DONE;") 9977 9978(define_expand "restore_stack_function" 9979 [(match_operand 0 "any_operand") 9980 (match_operand 1 "any_operand")] 9981 "" 9982 "DONE;") 9983 9984;; Adjust stack pointer (op0) to a new value (op1). 9985;; First copy old stack backchain to new location, and ensure that the 9986;; scheduler won't reorder the sp assignment before the backchain write. 9987(define_expand "restore_stack_block" 9988 [(set (match_dup 2) (match_dup 3)) 9989 (set (match_dup 4) (match_dup 2)) 9990 (match_dup 5) 9991 (set (match_operand 0 "register_operand") 9992 (match_operand 1 "register_operand"))] 9993 "" 9994{ 9995 rtvec p; 9996 9997 operands[1] = force_reg (Pmode, operands[1]); 9998 operands[2] = gen_reg_rtx (Pmode); 9999 operands[3] = gen_frame_mem (Pmode, operands[0]); 10000 operands[4] = gen_frame_mem (Pmode, operands[1]); 10001 p = rtvec_alloc (1); 10002 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 10003 const0_rtx); 10004 operands[5] = gen_rtx_PARALLEL (VOIDmode, p); 10005}) 10006 10007(define_expand "save_stack_nonlocal" 10008 [(set (match_dup 3) (match_dup 4)) 10009 (set (match_operand 0 "memory_operand") (match_dup 3)) 10010 (set (match_dup 2) (match_operand 1 "register_operand"))] 10011 "" 10012{ 10013 int units_per_word = (TARGET_32BIT) ? 4 : 8; 10014 10015 /* Copy the backchain to the first word, sp to the second. */ 10016 operands[0] = adjust_address_nv (operands[0], Pmode, 0); 10017 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word); 10018 operands[3] = gen_reg_rtx (Pmode); 10019 operands[4] = gen_frame_mem (Pmode, operands[1]); 10020}) 10021 10022(define_expand "restore_stack_nonlocal" 10023 [(set (match_dup 2) (match_operand 1 "memory_operand")) 10024 (set (match_dup 3) (match_dup 4)) 10025 (set (match_dup 5) (match_dup 2)) 10026 (match_dup 6) 10027 (set (match_operand 0 "register_operand") (match_dup 3))] 10028 "" 10029{ 10030 int units_per_word = (TARGET_32BIT) ? 4 : 8; 10031 rtvec p; 10032 10033 /* Restore the backchain from the first word, sp from the second. */ 10034 operands[2] = gen_reg_rtx (Pmode); 10035 operands[3] = gen_reg_rtx (Pmode); 10036 operands[1] = adjust_address_nv (operands[1], Pmode, 0); 10037 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word); 10038 operands[5] = gen_frame_mem (Pmode, operands[3]); 10039 p = rtvec_alloc (1); 10040 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]), 10041 const0_rtx); 10042 operands[6] = gen_rtx_PARALLEL (VOIDmode, p); 10043}) 10044 10045;; Load up a PC-relative address. Print_operand_address will append a @pcrel 10046;; to the symbol or label. 10047(define_insn "*pcrel_local_addr" 10048 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10049 (match_operand:DI 1 "pcrel_local_address"))] 10050 "TARGET_PCREL" 10051 "la %0,%a1" 10052 [(set_attr "prefixed" "yes")]) 10053 10054;; Load up a PC-relative address to an external symbol. If the symbol and the 10055;; program are both defined in the main program, the linker will optimize this 10056;; to a PADDI. Otherwise, it will create a GOT address that is relocated by 10057;; the dynamic linker and loaded up. Print_operand_address will append a 10058;; @got@pcrel to the symbol. 10059(define_insn "*pcrel_extern_addr" 10060 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10061 (match_operand:DI 1 "pcrel_external_address"))] 10062 "TARGET_PCREL" 10063 "ld %0,%a1" 10064 [(set_attr "prefixed" "yes") 10065 (set_attr "type" "load")]) 10066 10067;; TOC register handling. 10068 10069;; Code to initialize the TOC register... 10070 10071(define_insn "load_toc_aix_si" 10072 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10073 (unspec:SI [(const_int 0)] UNSPEC_TOC)) 10074 (use (reg:SI 2))])] 10075 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT" 10076{ 10077 char buf[30]; 10078 extern int need_toc_init; 10079 need_toc_init = 1; 10080 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1); 10081 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 10082 operands[2] = gen_rtx_REG (Pmode, 2); 10083 return "lwz %0,%1(%2)"; 10084} 10085 [(set_attr "type" "load") 10086 (set_attr "update" "no") 10087 (set_attr "indexed" "no")]) 10088 10089(define_insn "load_toc_aix_di" 10090 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10091 (unspec:DI [(const_int 0)] UNSPEC_TOC)) 10092 (use (reg:DI 2))])] 10093 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT" 10094{ 10095 char buf[30]; 10096 extern int need_toc_init; 10097 need_toc_init = 1; 10098 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 10099 !TARGET_ELF || !TARGET_MINIMAL_TOC); 10100 if (TARGET_ELF) 10101 strcat (buf, "@toc"); 10102 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf)); 10103 operands[2] = gen_rtx_REG (Pmode, 2); 10104 return "ld %0,%1(%2)"; 10105} 10106 [(set_attr "type" "load") 10107 (set_attr "update" "no") 10108 (set_attr "indexed" "no")]) 10109 10110(define_insn "load_toc_v4_pic_si" 10111 [(set (reg:SI LR_REGNO) 10112 (unspec:SI [(const_int 0)] UNSPEC_TOC))] 10113 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT" 10114 "bl _GLOBAL_OFFSET_TABLE_@local-4" 10115 [(set_attr "type" "branch")]) 10116 10117(define_expand "load_toc_v4_PIC_1" 10118 [(parallel [(set (reg:SI LR_REGNO) 10119 (match_operand:SI 0 "immediate_operand" "s")) 10120 (use (unspec [(match_dup 0)] UNSPEC_TOC))])] 10121 "TARGET_ELF && DEFAULT_ABI == ABI_V4 10122 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10123 "") 10124 10125(define_insn "load_toc_v4_PIC_1_normal" 10126 [(set (reg:SI LR_REGNO) 10127 (match_operand:SI 0 "immediate_operand" "s")) 10128 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 10129 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 10130 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10131 "bcl 20,31,%0\n%0:" 10132 [(set_attr "type" "branch") 10133 (set_attr "cannot_copy" "yes")]) 10134 10135(define_insn "load_toc_v4_PIC_1_476" 10136 [(set (reg:SI LR_REGNO) 10137 (match_operand:SI 0 "immediate_operand" "s")) 10138 (use (unspec [(match_dup 0)] UNSPEC_TOC))] 10139 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 10140 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))" 10141{ 10142 char name[32]; 10143 static char templ[32]; 10144 10145 get_ppc476_thunk_name (name); 10146 sprintf (templ, "bl %s\n%%0:", name); 10147 return templ; 10148} 10149 [(set_attr "type" "branch") 10150 (set_attr "cannot_copy" "yes")]) 10151 10152(define_expand "load_toc_v4_PIC_1b" 10153 [(parallel [(set (reg:SI LR_REGNO) 10154 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10155 (label_ref (match_operand 1 ""))] 10156 UNSPEC_TOCPTR)) 10157 (match_dup 1)])] 10158 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10159 "") 10160 10161(define_insn "load_toc_v4_PIC_1b_normal" 10162 [(set (reg:SI LR_REGNO) 10163 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10164 (label_ref (match_operand 1 "" ""))] 10165 UNSPEC_TOCPTR)) 10166 (match_dup 1)] 10167 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10168 "bcl 20,31,$+8\;.long %0-$" 10169 [(set_attr "type" "branch") 10170 (set_attr "length" "8")]) 10171 10172(define_insn "load_toc_v4_PIC_1b_476" 10173 [(set (reg:SI LR_REGNO) 10174 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s") 10175 (label_ref (match_operand 1 "" ""))] 10176 UNSPEC_TOCPTR)) 10177 (match_dup 1)] 10178 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10179{ 10180 char name[32]; 10181 static char templ[32]; 10182 10183 get_ppc476_thunk_name (name); 10184 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name); 10185 return templ; 10186} 10187 [(set_attr "type" "branch") 10188 (set_attr "length" "16")]) 10189 10190(define_insn "load_toc_v4_PIC_2" 10191 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10192 (mem:SI (plus:SI 10193 (match_operand:SI 1 "gpc_reg_operand" "b") 10194 (const 10195 (minus:SI (match_operand:SI 2 "immediate_operand" "s") 10196 (match_operand:SI 3 "immediate_operand" "s"))))))] 10197 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2" 10198 "lwz %0,%2-%3(%1)" 10199 [(set_attr "type" "load")]) 10200 10201(define_insn "load_toc_v4_PIC_3b" 10202 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10203 (plus:SI 10204 (match_operand:SI 1 "gpc_reg_operand" "b") 10205 (high:SI 10206 (const 10207 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 10208 (match_operand:SI 3 "symbol_ref_operand" "s"))))))] 10209 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 10210 "addis %0,%1,%2-%3@ha") 10211 10212(define_insn "load_toc_v4_PIC_3c" 10213 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10214 (lo_sum:SI 10215 (match_operand:SI 1 "gpc_reg_operand" "b") 10216 (const 10217 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s") 10218 (match_operand:SI 3 "symbol_ref_operand" "s")))))] 10219 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic" 10220 "addi %0,%1,%2-%3@l") 10221 10222;; If the TOC is shared over a translation unit, as happens with all 10223;; the kinds of PIC that we support, we need to restore the TOC 10224;; pointer only when jumping over units of translation. 10225;; On Darwin, we need to reload the picbase. 10226 10227(define_expand "builtin_setjmp_receiver" 10228 [(use (label_ref (match_operand 0 "")))] 10229 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1) 10230 || (TARGET_TOC && TARGET_MINIMAL_TOC) 10231 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)" 10232{ 10233#if TARGET_MACHO 10234 if (DEFAULT_ABI == ABI_DARWIN) 10235 { 10236 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME); 10237 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM); 10238 rtx tmplabrtx; 10239 char tmplab[20]; 10240 10241 crtl->uses_pic_offset_table = 1; 10242 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR", 10243 CODE_LABEL_NUMBER (operands[0])); 10244 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab)); 10245 10246 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx)); 10247 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO)); 10248 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg, 10249 picrtx, tmplabrtx)); 10250 } 10251 else 10252#endif 10253 rs6000_emit_load_toc_table (FALSE); 10254 DONE; 10255}) 10256 10257;; Largetoc support 10258(define_insn "*largetoc_high" 10259 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 10260 (high:DI 10261 (unspec [(match_operand:DI 1 "" "") 10262 (match_operand:DI 2 "gpc_reg_operand" "b")] 10263 UNSPEC_TOCREL)))] 10264 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10265 "addis %0,%2,%1@toc@ha") 10266 10267(define_insn "*largetoc_high_aix<mode>" 10268 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 10269 (high:P 10270 (unspec [(match_operand:P 1 "" "") 10271 (match_operand:P 2 "gpc_reg_operand" "b")] 10272 UNSPEC_TOCREL)))] 10273 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10274 "addis %0,%1@u(%2)") 10275 10276(define_insn "*largetoc_high_plus" 10277 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r") 10278 (high:DI 10279 (plus:DI 10280 (unspec [(match_operand:DI 1 "" "") 10281 (match_operand:DI 2 "gpc_reg_operand" "b")] 10282 UNSPEC_TOCREL) 10283 (match_operand:DI 3 "add_cint_operand" "n"))))] 10284 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10285 "addis %0,%2,%1+%3@toc@ha") 10286 10287(define_insn "*largetoc_high_plus_aix<mode>" 10288 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r") 10289 (high:P 10290 (plus:P 10291 (unspec [(match_operand:P 1 "" "") 10292 (match_operand:P 2 "gpc_reg_operand" "b")] 10293 UNSPEC_TOCREL) 10294 (match_operand:P 3 "add_cint_operand" "n"))))] 10295 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10296 "addis %0,%1+%3@u(%2)") 10297 10298(define_insn "*largetoc_low" 10299 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 10300 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b") 10301 (match_operand:DI 2 "" "")))] 10302 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL" 10303 "addi %0,%1,%2@l") 10304 10305(define_insn "*largetoc_low_aix<mode>" 10306 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10307 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b") 10308 (match_operand:P 2 "" "")))] 10309 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL" 10310 "la %0,%2@l(%1)") 10311 10312(define_insn_and_split "*tocref<mode>" 10313 [(set (match_operand:P 0 "gpc_reg_operand" "=b") 10314 (match_operand:P 1 "small_toc_ref" "R"))] 10315 "TARGET_TOC 10316 && legitimate_constant_pool_address_p (operands[1], QImode, false)" 10317 "la %0,%a1" 10318 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed" 10319 [(set (match_dup 0) (high:P (match_dup 1))) 10320 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))]) 10321 10322;; Elf specific ways of loading addresses for non-PIC code. 10323;; The output of this could be r0, but we make a very strong 10324;; preference for a base register because it will usually 10325;; be needed there. 10326(define_insn "elf_high" 10327 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r") 10328 (high:SI (match_operand 1 "" "")))] 10329 "TARGET_ELF && !TARGET_64BIT && !flag_pic" 10330 "lis %0,%1@ha") 10331 10332(define_insn "elf_low" 10333 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 10334 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b") 10335 (match_operand 2 "" "")))] 10336 "TARGET_ELF && !TARGET_64BIT && !flag_pic" 10337 "la %0,%2@l(%1)") 10338 10339(define_insn "*pltseq_tocsave_<mode>" 10340 [(set (match_operand:P 0 "memory_operand" "=m") 10341 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b") 10342 (match_operand:P 2 "symbol_ref_operand" "s") 10343 (match_operand:P 3 "" "")] 10344 UNSPEC_PLTSEQ))] 10345 "TARGET_PLTSEQ 10346 && DEFAULT_ABI == ABI_ELFv2" 10347{ 10348 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE); 10349}) 10350 10351(define_insn "*pltseq_plt16_ha_<mode>" 10352 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10353 (unspec:P [(match_operand:P 1 "" "") 10354 (match_operand:P 2 "symbol_ref_operand" "s") 10355 (match_operand:P 3 "" "")] 10356 UNSPEC_PLT16_HA))] 10357 "TARGET_PLTSEQ" 10358{ 10359 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA); 10360}) 10361 10362(define_insn "*pltseq_plt16_lo_<mode>" 10363 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10364 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b") 10365 (match_operand:P 2 "symbol_ref_operand" "s") 10366 (match_operand:P 3 "" "")] 10367 UNSPECV_PLT16_LO))] 10368 "TARGET_PLTSEQ" 10369{ 10370 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO); 10371} 10372 [(set_attr "type" "load")]) 10373 10374(define_insn "*pltseq_mtctr_<mode>" 10375 [(set (match_operand:P 0 "register_operand" "=c") 10376 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") 10377 (match_operand:P 2 "symbol_ref_operand" "s") 10378 (match_operand:P 3 "" "")] 10379 UNSPEC_PLTSEQ))] 10380 "TARGET_PLTSEQ" 10381{ 10382 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR); 10383}) 10384 10385(define_insn "*pltseq_plt_pcrel<mode>" 10386 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 10387 (unspec_volatile:P [(match_operand:P 1 "" "") 10388 (match_operand:P 2 "symbol_ref_operand" "s") 10389 (match_operand:P 3 "" "")] 10390 UNSPECV_PLT_PCREL))] 10391 "HAVE_AS_PLTSEQ && TARGET_ELF 10392 && rs6000_pcrel_p (cfun)" 10393{ 10394 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34); 10395} 10396 [(set_attr "type" "load") 10397 (set_attr "length" "12")]) 10398 10399;; Call and call_value insns 10400;; For the purposes of expanding calls, Darwin is very similar to SYSV. 10401(define_expand "call" 10402 [(parallel [(call (mem:SI (match_operand 0 "address_operand")) 10403 (match_operand 1 "")) 10404 (use (match_operand 2 "")) 10405 (clobber (reg:SI LR_REGNO))])] 10406 "" 10407{ 10408#if TARGET_MACHO 10409 if (MACHOPIC_INDIRECT) 10410 operands[0] = machopic_indirect_call_target (operands[0]); 10411#endif 10412 10413 gcc_assert (MEM_P (operands[0])); 10414 10415 operands[0] = XEXP (operands[0], 0); 10416 10417 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10418 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]); 10419 else if (DEFAULT_ABI == ABI_V4) 10420 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]); 10421 else if (DEFAULT_ABI == ABI_DARWIN) 10422 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]); 10423 else 10424 gcc_unreachable (); 10425 10426 DONE; 10427}) 10428 10429(define_expand "call_value" 10430 [(parallel [(set (match_operand 0 "") 10431 (call (mem:SI (match_operand 1 "address_operand")) 10432 (match_operand 2 ""))) 10433 (use (match_operand 3 "")) 10434 (clobber (reg:SI LR_REGNO))])] 10435 "" 10436{ 10437#if TARGET_MACHO 10438 if (MACHOPIC_INDIRECT) 10439 operands[1] = machopic_indirect_call_target (operands[1]); 10440#endif 10441 10442 gcc_assert (MEM_P (operands[1])); 10443 10444 operands[1] = XEXP (operands[1], 0); 10445 10446 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10447 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]); 10448 else if (DEFAULT_ABI == ABI_V4) 10449 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]); 10450 else if (DEFAULT_ABI == ABI_DARWIN) 10451 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]); 10452 else 10453 gcc_unreachable (); 10454 10455 DONE; 10456}) 10457 10458;; Call to function in current module. No TOC pointer reload needed. 10459;; Operand2 is nonzero if we are using the V.4 calling sequence and 10460;; either the function was not prototyped, or it was prototyped as a 10461;; variable argument function. It is > 0 if FP registers were passed 10462;; and < 0 if they were not. 10463 10464(define_insn "*call_local<mode>" 10465 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s")) 10466 (match_operand 1)) 10467 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10468 (clobber (reg:P LR_REGNO))] 10469 "(INTVAL (operands[2]) & CALL_LONG) == 0" 10470{ 10471 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10472 output_asm_insn ("crxor 6,6,6", operands); 10473 10474 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10475 output_asm_insn ("creqv 6,6,6", operands); 10476 10477 if (rs6000_pcrel_p (cfun)) 10478 return "bl %z0@notoc"; 10479 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0"; 10480} 10481 [(set_attr "type" "branch") 10482 (set_attr "length" "4,8")]) 10483 10484(define_insn "*call_value_local<mode>" 10485 [(set (match_operand 0 "" "") 10486 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s")) 10487 (match_operand 2))) 10488 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10489 (clobber (reg:P LR_REGNO))] 10490 "(INTVAL (operands[3]) & CALL_LONG) == 0" 10491{ 10492 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10493 output_asm_insn ("crxor 6,6,6", operands); 10494 10495 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10496 output_asm_insn ("creqv 6,6,6", operands); 10497 10498 if (rs6000_pcrel_p (cfun)) 10499 return "bl %z1@notoc"; 10500 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1"; 10501} 10502 [(set_attr "type" "branch") 10503 (set_attr "length" "4,8")]) 10504 10505 10506;; A function pointer under System V is just a normal pointer 10507;; operands[0] is the function pointer 10508;; operands[1] is the tls call arg 10509;; operands[2] is the value FUNCTION_ARG returns for the VOID argument 10510;; which indicates how to set cr1 10511 10512(define_insn "*call_indirect_nonlocal_sysv<mode>" 10513 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 10514 (match_operand 1)) 10515 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 10516 (clobber (reg:P LR_REGNO))] 10517 "DEFAULT_ABI == ABI_V4 10518 || DEFAULT_ABI == ABI_DARWIN" 10519{ 10520 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10521 output_asm_insn ("crxor 6,6,6", operands); 10522 10523 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10524 output_asm_insn ("creqv 6,6,6", operands); 10525 10526 return rs6000_indirect_call_template (operands, 0); 10527} 10528 [(set_attr "type" "jmpreg") 10529 (set (attr "length") 10530 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") 10531 (match_test "which_alternative != 1")) 10532 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 10533 (const_string "12") 10534 (ior (and (match_test "!rs6000_speculate_indirect_jumps") 10535 (match_test "which_alternative != 1")) 10536 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 10537 (const_string "8")] 10538 (const_string "4")))]) 10539 10540(define_insn "*call_nonlocal_sysv<mode>" 10541 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 10542 (match_operand 1)) 10543 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10544 (clobber (reg:P LR_REGNO))] 10545 "(DEFAULT_ABI == ABI_DARWIN 10546 || (DEFAULT_ABI == ABI_V4 10547 && (INTVAL (operands[2]) & CALL_LONG) == 0))" 10548{ 10549 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10550 output_asm_insn ("crxor 6,6,6", operands); 10551 10552 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10553 output_asm_insn ("creqv 6,6,6", operands); 10554 10555 return rs6000_call_template (operands, 0); 10556} 10557 [(set_attr "type" "branch,branch") 10558 (set_attr "length" "4,8")]) 10559 10560(define_insn "*call_nonlocal_sysv_secure<mode>" 10561 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 10562 (match_operand 1)) 10563 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10564 (use (match_operand:SI 3 "register_operand" "r,r")) 10565 (clobber (reg:P LR_REGNO))] 10566 "(DEFAULT_ABI == ABI_V4 10567 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0]) 10568 && (INTVAL (operands[2]) & CALL_LONG) == 0)" 10569{ 10570 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10571 output_asm_insn ("crxor 6,6,6", operands); 10572 10573 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10574 output_asm_insn ("creqv 6,6,6", operands); 10575 10576 return rs6000_call_template (operands, 0); 10577} 10578 [(set_attr "type" "branch,branch") 10579 (set_attr "length" "4,8")]) 10580 10581(define_insn "*call_value_indirect_nonlocal_sysv<mode>" 10582 [(set (match_operand 0 "" "") 10583 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 10584 (match_operand:P 2 "unspec_tls" ""))) 10585 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 10586 (clobber (reg:P LR_REGNO))] 10587 "DEFAULT_ABI == ABI_V4 10588 || DEFAULT_ABI == ABI_DARWIN" 10589{ 10590 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10591 output_asm_insn ("crxor 6,6,6", operands); 10592 10593 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10594 output_asm_insn ("creqv 6,6,6", operands); 10595 10596 return rs6000_indirect_call_template (operands, 1); 10597} 10598 [(set_attr "type" "jmpreg") 10599 (set (attr "length") 10600 (plus 10601 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])") 10602 (const_int 4) 10603 (const_int 0)) 10604 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10605 (match_test "which_alternative != 1")) 10606 (const_int 8) 10607 (const_int 4))))]) 10608 10609(define_insn "*call_value_nonlocal_sysv<mode>" 10610 [(set (match_operand 0 "" "") 10611 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 10612 (match_operand:P 2 "unspec_tls" ""))) 10613 (use (match_operand:SI 3 "immediate_operand" "n")) 10614 (clobber (reg:P LR_REGNO))] 10615 "(DEFAULT_ABI == ABI_DARWIN 10616 || (DEFAULT_ABI == ABI_V4 10617 && (INTVAL (operands[3]) & CALL_LONG) == 0))" 10618{ 10619 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10620 output_asm_insn ("crxor 6,6,6", operands); 10621 10622 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10623 output_asm_insn ("creqv 6,6,6", operands); 10624 10625 return rs6000_call_template (operands, 1); 10626} 10627 [(set_attr "type" "branch") 10628 (set (attr "length") 10629 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])") 10630 (const_int 8) 10631 (const_int 4)))]) 10632 10633(define_insn "*call_value_nonlocal_sysv_secure<mode>" 10634 [(set (match_operand 0 "" "") 10635 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 10636 (match_operand:P 2 "unspec_tls" ""))) 10637 (use (match_operand:SI 3 "immediate_operand" "n")) 10638 (use (match_operand:SI 4 "register_operand" "r")) 10639 (clobber (reg:P LR_REGNO))] 10640 "(DEFAULT_ABI == ABI_V4 10641 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1]) 10642 && (INTVAL (operands[3]) & CALL_LONG) == 0)" 10643{ 10644 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10645 output_asm_insn ("crxor 6,6,6", operands); 10646 10647 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10648 output_asm_insn ("creqv 6,6,6", operands); 10649 10650 return rs6000_call_template (operands, 1); 10651} 10652 [(set_attr "type" "branch") 10653 (set (attr "length") 10654 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])") 10655 (const_int 8) 10656 (const_int 4)))]) 10657 10658;; Call to AIX abi function which may be in another module. 10659;; Restore the TOC pointer (r2) after the call. 10660 10661(define_insn "*call_nonlocal_aix<mode>" 10662 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s")) 10663 (match_operand 1)) 10664 (use (match_operand:SI 2 "immediate_operand" "n")) 10665 (clobber (reg:P LR_REGNO))] 10666 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10667 && (INTVAL (operands[2]) & CALL_LONG) == 0" 10668{ 10669 return rs6000_call_template (operands, 0); 10670} 10671 [(set_attr "type" "branch") 10672 (set (attr "length") 10673 (if_then_else (match_test "rs6000_pcrel_p (cfun)") 10674 (const_int 4) 10675 (const_int 8)))]) 10676 10677(define_insn "*call_value_nonlocal_aix<mode>" 10678 [(set (match_operand 0 "" "") 10679 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s")) 10680 (match_operand:P 2 "unspec_tls" ""))) 10681 (use (match_operand:SI 3 "immediate_operand" "n")) 10682 (clobber (reg:P LR_REGNO))] 10683 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10684 && (INTVAL (operands[3]) & CALL_LONG) == 0" 10685{ 10686 return rs6000_call_template (operands, 1); 10687} 10688 [(set_attr "type" "branch") 10689 (set (attr "length") 10690 (if_then_else (match_test "rs6000_pcrel_p (cfun)") 10691 (const_int 4) 10692 (const_int 8)))]) 10693 10694;; Call to indirect functions with the AIX abi using a 3 word descriptor. 10695;; Operand0 is the addresss of the function to call 10696;; Operand3 is the location in the function descriptor to load r2 from 10697;; Operand4 is the offset of the stack location holding the current TOC pointer 10698 10699(define_insn "*call_indirect_aix<mode>" 10700 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 10701 (match_operand 1)) 10702 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 10703 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>")) 10704 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT)) 10705 (clobber (reg:P LR_REGNO))] 10706 "DEFAULT_ABI == ABI_AIX" 10707{ 10708 return rs6000_indirect_call_template (operands, 0); 10709} 10710 [(set_attr "type" "jmpreg") 10711 (set (attr "length") 10712 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10713 (match_test "which_alternative != 1")) 10714 (const_string "16") 10715 (const_string "12")))]) 10716 10717(define_insn "*call_value_indirect_aix<mode>" 10718 [(set (match_operand 0 "" "") 10719 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 10720 (match_operand:P 2 "unspec_tls" ""))) 10721 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 10722 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>")) 10723 (set (reg:P TOC_REGNUM) 10724 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")] 10725 UNSPEC_TOCSLOT)) 10726 (clobber (reg:P LR_REGNO))] 10727 "DEFAULT_ABI == ABI_AIX" 10728{ 10729 return rs6000_indirect_call_template (operands, 1); 10730} 10731 [(set_attr "type" "jmpreg") 10732 (set (attr "length") 10733 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10734 (match_test "which_alternative != 1")) 10735 (const_string "16") 10736 (const_string "12")))]) 10737 10738;; Call to indirect functions with the ELFv2 ABI. 10739;; Operand0 is the addresss of the function to call 10740;; Operand3 is the offset of the stack location holding the current TOC pointer 10741 10742(define_insn "*call_indirect_elfv2<mode>" 10743 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 10744 (match_operand 1)) 10745 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 10746 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT)) 10747 (clobber (reg:P LR_REGNO))] 10748 "DEFAULT_ABI == ABI_ELFv2" 10749{ 10750 return rs6000_indirect_call_template (operands, 0); 10751} 10752 [(set_attr "type" "jmpreg") 10753 (set (attr "length") 10754 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10755 (match_test "which_alternative != 1")) 10756 (const_string "12") 10757 (const_string "8")))]) 10758 10759(define_insn "*call_indirect_pcrel<mode>" 10760 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 10761 (match_operand 1)) 10762 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 10763 (clobber (reg:P LR_REGNO))] 10764 "rs6000_pcrel_p (cfun)" 10765{ 10766 return rs6000_indirect_call_template (operands, 0); 10767} 10768 [(set_attr "type" "jmpreg") 10769 (set (attr "length") 10770 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10771 (match_test "which_alternative != 1")) 10772 (const_string "8") 10773 (const_string "4")))]) 10774 10775(define_insn "*call_value_indirect_elfv2<mode>" 10776 [(set (match_operand 0 "" "") 10777 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 10778 (match_operand:P 2 "unspec_tls" ""))) 10779 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 10780 (set (reg:P TOC_REGNUM) 10781 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] 10782 UNSPEC_TOCSLOT)) 10783 (clobber (reg:P LR_REGNO))] 10784 "DEFAULT_ABI == ABI_ELFv2" 10785{ 10786 return rs6000_indirect_call_template (operands, 1); 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_value_indirect_pcrel<mode>" 10796 [(set (match_operand 0 "" "") 10797 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 10798 (match_operand:P 2 "unspec_tls" ""))) 10799 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 10800 (clobber (reg:P LR_REGNO))] 10801 "rs6000_pcrel_p (cfun)" 10802{ 10803 return rs6000_indirect_call_template (operands, 1); 10804} 10805 [(set_attr "type" "jmpreg") 10806 (set (attr "length") 10807 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps") 10808 (match_test "which_alternative != 1")) 10809 (const_string "8") 10810 (const_string "4")))]) 10811 10812;; Call subroutine returning any type. 10813(define_expand "untyped_call" 10814 [(parallel [(call (match_operand 0 "") 10815 (const_int 0)) 10816 (match_operand 1 "") 10817 (match_operand 2 "")])] 10818 "" 10819{ 10820 int i; 10821 10822 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx)); 10823 10824 for (int i = 0; i < XVECLEN (operands[2], 0); i++) 10825 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i))); 10826 emit_insn (gen_blockage ()); 10827 10828 for (i = 0; i < XVECLEN (operands[2], 0); i++) 10829 { 10830 rtx set = XVECEXP (operands[2], 0, i); 10831 emit_move_insn (SET_DEST (set), SET_SRC (set)); 10832 } 10833 10834 /* The optimizer does not know that the call sets the function value 10835 registers we stored in the result block. We avoid problems by 10836 claiming that all hard registers are used and clobbered at this 10837 point. */ 10838 emit_insn (gen_blockage ()); 10839 10840 DONE; 10841}) 10842 10843;; sibling call patterns 10844(define_expand "sibcall" 10845 [(parallel [(call (mem:SI (match_operand 0 "address_operand")) 10846 (match_operand 1 "")) 10847 (use (match_operand 2 "")) 10848 (simple_return)])] 10849 "" 10850{ 10851#if TARGET_MACHO 10852 if (MACHOPIC_INDIRECT) 10853 operands[0] = machopic_indirect_call_target (operands[0]); 10854#endif 10855 10856 gcc_assert (MEM_P (operands[0])); 10857 gcc_assert (CONST_INT_P (operands[1])); 10858 10859 operands[0] = XEXP (operands[0], 0); 10860 10861 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10862 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]); 10863 else if (DEFAULT_ABI == ABI_V4) 10864 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]); 10865 else if (DEFAULT_ABI == ABI_DARWIN) 10866 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]); 10867 else 10868 gcc_unreachable (); 10869 10870 DONE; 10871}) 10872 10873(define_expand "sibcall_value" 10874 [(parallel [(set (match_operand 0 "register_operand") 10875 (call (mem:SI (match_operand 1 "address_operand")) 10876 (match_operand 2 ""))) 10877 (use (match_operand 3 "")) 10878 (simple_return)])] 10879 "" 10880{ 10881#if TARGET_MACHO 10882 if (MACHOPIC_INDIRECT) 10883 operands[1] = machopic_indirect_call_target (operands[1]); 10884#endif 10885 10886 gcc_assert (MEM_P (operands[1])); 10887 gcc_assert (CONST_INT_P (operands[2])); 10888 10889 operands[1] = XEXP (operands[1], 0); 10890 10891 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) 10892 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]); 10893 else if (DEFAULT_ABI == ABI_V4) 10894 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]); 10895 else if (DEFAULT_ABI == ABI_DARWIN) 10896 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]); 10897 else 10898 gcc_unreachable (); 10899 10900 DONE; 10901}) 10902 10903(define_insn "*sibcall_local32" 10904 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s")) 10905 (match_operand 1)) 10906 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10907 (simple_return)] 10908 "(INTVAL (operands[2]) & CALL_LONG) == 0" 10909{ 10910 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10911 output_asm_insn ("crxor 6,6,6", operands); 10912 10913 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10914 output_asm_insn ("creqv 6,6,6", operands); 10915 10916 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0"; 10917} 10918 [(set_attr "type" "branch") 10919 (set_attr "length" "4,8")]) 10920 10921(define_insn "*sibcall_local64" 10922 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s")) 10923 (match_operand 1)) 10924 (use (match_operand:SI 2 "immediate_operand" "O,n")) 10925 (simple_return)] 10926 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0" 10927{ 10928 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10929 output_asm_insn ("crxor 6,6,6", operands); 10930 10931 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10932 output_asm_insn ("creqv 6,6,6", operands); 10933 10934 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0"; 10935} 10936 [(set_attr "type" "branch") 10937 (set_attr "length" "4,8")]) 10938 10939(define_insn "*sibcall_value_local32" 10940 [(set (match_operand 0 "" "") 10941 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s")) 10942 (match_operand 2))) 10943 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10944 (simple_return)] 10945 "(INTVAL (operands[3]) & CALL_LONG) == 0" 10946{ 10947 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10948 output_asm_insn ("crxor 6,6,6", operands); 10949 10950 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10951 output_asm_insn ("creqv 6,6,6", operands); 10952 10953 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1"; 10954} 10955 [(set_attr "type" "branch") 10956 (set_attr "length" "4,8")]) 10957 10958(define_insn "*sibcall_value_local64" 10959 [(set (match_operand 0 "" "") 10960 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s")) 10961 (match_operand 2))) 10962 (use (match_operand:SI 3 "immediate_operand" "O,n")) 10963 (simple_return)] 10964 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0" 10965{ 10966 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 10967 output_asm_insn ("crxor 6,6,6", operands); 10968 10969 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 10970 output_asm_insn ("creqv 6,6,6", operands); 10971 10972 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1"; 10973} 10974 [(set_attr "type" "branch") 10975 (set_attr "length" "4,8")]) 10976 10977(define_insn "*sibcall_indirect_nonlocal_sysv<mode>" 10978 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X")) 10979 (match_operand 1)) 10980 (use (match_operand:SI 2 "immediate_operand" "n,n,n")) 10981 (simple_return)] 10982 "DEFAULT_ABI == ABI_V4 10983 || DEFAULT_ABI == ABI_DARWIN" 10984{ 10985 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 10986 output_asm_insn ("crxor 6,6,6", operands); 10987 10988 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 10989 output_asm_insn ("creqv 6,6,6", operands); 10990 10991 return rs6000_indirect_sibcall_template (operands, 0); 10992} 10993 [(set_attr "type" "jmpreg") 10994 (set (attr "length") 10995 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") 10996 (match_test "which_alternative != 1")) 10997 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 10998 (const_string "12") 10999 (ior (and (match_test "!rs6000_speculate_indirect_jumps") 11000 (match_test "which_alternative != 1")) 11001 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11002 (const_string "8")] 11003 (const_string "4")))]) 11004 11005(define_insn "*sibcall_nonlocal_sysv<mode>" 11006 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s")) 11007 (match_operand 1)) 11008 (use (match_operand 2 "immediate_operand" "O,n")) 11009 (simple_return)] 11010 "(DEFAULT_ABI == ABI_DARWIN 11011 || DEFAULT_ABI == ABI_V4) 11012 && (INTVAL (operands[2]) & CALL_LONG) == 0" 11013{ 11014 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS) 11015 output_asm_insn ("crxor 6,6,6", operands); 11016 11017 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS) 11018 output_asm_insn ("creqv 6,6,6", operands); 11019 11020 return rs6000_sibcall_template (operands, 0); 11021} 11022 [(set_attr "type" "branch") 11023 (set_attr "length" "4,8")]) 11024 11025(define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>" 11026 [(set (match_operand 0 "" "") 11027 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X")) 11028 (match_operand 2))) 11029 (use (match_operand:SI 3 "immediate_operand" "n,n,n")) 11030 (simple_return)] 11031 "DEFAULT_ABI == ABI_V4 11032 || DEFAULT_ABI == ABI_DARWIN" 11033{ 11034 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11035 output_asm_insn ("crxor 6,6,6", operands); 11036 11037 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11038 output_asm_insn ("creqv 6,6,6", operands); 11039 11040 return rs6000_indirect_sibcall_template (operands, 1); 11041} 11042 [(set_attr "type" "jmpreg") 11043 (set (attr "length") 11044 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps") 11045 (match_test "which_alternative != 1")) 11046 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11047 (const_string "12") 11048 (ior (and (match_test "!rs6000_speculate_indirect_jumps") 11049 (match_test "which_alternative != 1")) 11050 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))")) 11051 (const_string "8")] 11052 (const_string "4")))]) 11053 11054(define_insn "*sibcall_value_nonlocal_sysv<mode>" 11055 [(set (match_operand 0 "" "") 11056 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s")) 11057 (match_operand 2))) 11058 (use (match_operand:SI 3 "immediate_operand" "O,n")) 11059 (simple_return)] 11060 "(DEFAULT_ABI == ABI_DARWIN 11061 || DEFAULT_ABI == ABI_V4) 11062 && (INTVAL (operands[3]) & CALL_LONG) == 0" 11063{ 11064 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS) 11065 output_asm_insn ("crxor 6,6,6", operands); 11066 11067 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS) 11068 output_asm_insn ("creqv 6,6,6", operands); 11069 11070 return rs6000_sibcall_template (operands, 1); 11071} 11072 [(set_attr "type" "branch") 11073 (set_attr "length" "4,8")]) 11074 11075;; AIX ABI sibling call patterns. 11076 11077(define_insn "*sibcall_aix<mode>" 11078 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c")) 11079 (match_operand 1)) 11080 (simple_return)] 11081 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11082{ 11083 if (which_alternative == 0) 11084 return rs6000_sibcall_template (operands, 0); 11085 else 11086 return "b%T0"; 11087} 11088 [(set_attr "type" "branch")]) 11089 11090(define_insn "*sibcall_value_aix<mode>" 11091 [(set (match_operand 0 "" "") 11092 (call (mem:SI (match_operand:P 1 "call_operand" "s,c")) 11093 (match_operand 2))) 11094 (simple_return)] 11095 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2" 11096{ 11097 if (which_alternative == 0) 11098 return rs6000_sibcall_template (operands, 1); 11099 else 11100 return "b%T1"; 11101} 11102 [(set_attr "type" "branch")]) 11103 11104(define_expand "sibcall_epilogue" 11105 [(use (const_int 0))] 11106 "" 11107{ 11108 if (!TARGET_SCHED_PROLOG) 11109 emit_insn (gen_blockage ()); 11110 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL); 11111 DONE; 11112}) 11113 11114;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and 11115;; all of memory. This blocks insns from being moved across this point. 11116 11117(define_insn "blockage" 11118 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] 11119 "" 11120 "" 11121 [(set_attr "length" "0")]) 11122 11123(define_expand "probe_stack_address" 11124 [(use (match_operand 0 "address_operand"))] 11125 "" 11126{ 11127 operands[0] = gen_rtx_MEM (Pmode, operands[0]); 11128 MEM_VOLATILE_P (operands[0]) = 1; 11129 11130 if (TARGET_64BIT) 11131 emit_insn (gen_probe_stack_di (operands[0])); 11132 else 11133 emit_insn (gen_probe_stack_si (operands[0])); 11134 DONE; 11135}) 11136 11137(define_insn "probe_stack_<mode>" 11138 [(set (match_operand:P 0 "memory_operand" "=m") 11139 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))] 11140 "" 11141{ 11142 operands[1] = gen_rtx_REG (Pmode, 0); 11143 return "st<wd>%U0%X0 %1,%0"; 11144} 11145 [(set_attr "type" "store") 11146 (set (attr "update") 11147 (if_then_else (match_operand 0 "update_address_mem") 11148 (const_string "yes") 11149 (const_string "no"))) 11150 (set (attr "indexed") 11151 (if_then_else (match_operand 0 "indexed_address_mem") 11152 (const_string "yes") 11153 (const_string "no")))]) 11154 11155(define_insn "probe_stack_range<P:mode>" 11156 [(set (match_operand:P 0 "register_operand" "=&r") 11157 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0") 11158 (match_operand:P 2 "register_operand" "r") 11159 (match_operand:P 3 "register_operand" "r")] 11160 UNSPECV_PROBE_STACK_RANGE))] 11161 "" 11162 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);" 11163 [(set_attr "type" "three")]) 11164 11165;; Compare insns are next. Note that the RS/6000 has two types of compares, 11166;; signed & unsigned, and one type of branch. 11167;; 11168;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc 11169;; insns, and branches. 11170 11171(define_expand "cbranch<mode>4" 11172 [(use (match_operator 0 "comparison_operator" 11173 [(match_operand:GPR 1 "gpc_reg_operand") 11174 (match_operand:GPR 2 "reg_or_short_operand")])) 11175 (use (match_operand 3))] 11176 "" 11177{ 11178 /* Take care of the possibility that operands[2] might be negative but 11179 this might be a logical operation. That insn doesn't exist. */ 11180 if (CONST_INT_P (operands[2]) 11181 && INTVAL (operands[2]) < 0) 11182 { 11183 operands[2] = force_reg (<MODE>mode, operands[2]); 11184 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]), 11185 GET_MODE (operands[0]), 11186 operands[1], operands[2]); 11187 } 11188 11189 rs6000_emit_cbranch (<MODE>mode, operands); 11190 DONE; 11191}) 11192 11193(define_expand "cbranch<mode>4" 11194 [(use (match_operator 0 "comparison_operator" 11195 [(match_operand:FP 1 "gpc_reg_operand") 11196 (match_operand:FP 2 "gpc_reg_operand")])) 11197 (use (match_operand 3))] 11198 "" 11199{ 11200 rs6000_emit_cbranch (<MODE>mode, operands); 11201 DONE; 11202}) 11203 11204(define_expand "cstore<mode>4_signed" 11205 [(use (match_operator 1 "signed_comparison_operator" 11206 [(match_operand:P 2 "gpc_reg_operand") 11207 (match_operand:P 3 "gpc_reg_operand")])) 11208 (clobber (match_operand:P 0 "gpc_reg_operand"))] 11209 "" 11210{ 11211 enum rtx_code cond_code = GET_CODE (operands[1]); 11212 11213 rtx op0 = operands[0]; 11214 rtx op1 = operands[2]; 11215 rtx op2 = operands[3]; 11216 11217 if (cond_code == GE || cond_code == LT) 11218 { 11219 cond_code = swap_condition (cond_code); 11220 std::swap (op1, op2); 11221 } 11222 11223 rtx tmp1 = gen_reg_rtx (<MODE>mode); 11224 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11225 rtx tmp3 = gen_reg_rtx (<MODE>mode); 11226 11227 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11228 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh))); 11229 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh))); 11230 11231 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2)); 11232 11233 if (cond_code == LE) 11234 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2)); 11235 else 11236 { 11237 rtx tmp4 = gen_reg_rtx (<MODE>mode); 11238 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2)); 11239 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx)); 11240 } 11241 11242 DONE; 11243}) 11244 11245(define_expand "cstore<mode>4_unsigned" 11246 [(use (match_operator 1 "unsigned_comparison_operator" 11247 [(match_operand:P 2 "gpc_reg_operand") 11248 (match_operand:P 3 "reg_or_short_operand")])) 11249 (clobber (match_operand:P 0 "gpc_reg_operand"))] 11250 "" 11251{ 11252 enum rtx_code cond_code = GET_CODE (operands[1]); 11253 11254 rtx op0 = operands[0]; 11255 rtx op1 = operands[2]; 11256 rtx op2 = operands[3]; 11257 11258 if (cond_code == GEU || cond_code == LTU) 11259 { 11260 cond_code = swap_condition (cond_code); 11261 std::swap (op1, op2); 11262 } 11263 11264 if (!gpc_reg_operand (op1, <MODE>mode)) 11265 op1 = force_reg (<MODE>mode, op1); 11266 if (!reg_or_short_operand (op2, <MODE>mode)) 11267 op2 = force_reg (<MODE>mode, op2); 11268 11269 rtx tmp = gen_reg_rtx (<MODE>mode); 11270 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11271 11272 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2)); 11273 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2)); 11274 11275 if (cond_code == LEU) 11276 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx)); 11277 else 11278 emit_insn (gen_neg<mode>2 (op0, tmp2)); 11279 11280 DONE; 11281}) 11282 11283(define_expand "cstore_si_as_di" 11284 [(use (match_operator 1 "unsigned_comparison_operator" 11285 [(match_operand:SI 2 "gpc_reg_operand") 11286 (match_operand:SI 3 "reg_or_short_operand")])) 11287 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 11288 "" 11289{ 11290 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0; 11291 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1])); 11292 11293 operands[2] = force_reg (SImode, operands[2]); 11294 operands[3] = force_reg (SImode, operands[3]); 11295 rtx op1 = gen_reg_rtx (DImode); 11296 rtx op2 = gen_reg_rtx (DImode); 11297 convert_move (op1, operands[2], uns_flag); 11298 convert_move (op2, operands[3], uns_flag); 11299 11300 if (cond_code == GT || cond_code == LE) 11301 { 11302 cond_code = swap_condition (cond_code); 11303 std::swap (op1, op2); 11304 } 11305 11306 rtx tmp = gen_reg_rtx (DImode); 11307 rtx tmp2 = gen_reg_rtx (DImode); 11308 emit_insn (gen_subdi3 (tmp, op1, op2)); 11309 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63))); 11310 11311 rtx tmp3; 11312 switch (cond_code) 11313 { 11314 default: 11315 gcc_unreachable (); 11316 case LT: 11317 tmp3 = tmp2; 11318 break; 11319 case GE: 11320 tmp3 = gen_reg_rtx (DImode); 11321 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx)); 11322 break; 11323 } 11324 11325 convert_move (operands[0], tmp3, 1); 11326 11327 DONE; 11328}) 11329 11330(define_expand "cstore<mode>4_signed_imm" 11331 [(use (match_operator 1 "signed_comparison_operator" 11332 [(match_operand:GPR 2 "gpc_reg_operand") 11333 (match_operand:GPR 3 "immediate_operand")])) 11334 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11335 "" 11336{ 11337 bool invert = false; 11338 11339 enum rtx_code cond_code = GET_CODE (operands[1]); 11340 11341 rtx op0 = operands[0]; 11342 rtx op1 = operands[2]; 11343 HOST_WIDE_INT val = INTVAL (operands[3]); 11344 11345 if (cond_code == GE || cond_code == GT) 11346 { 11347 cond_code = reverse_condition (cond_code); 11348 invert = true; 11349 } 11350 11351 if (cond_code == LE) 11352 val++; 11353 11354 rtx tmp = gen_reg_rtx (<MODE>mode); 11355 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 11356 rtx x = gen_reg_rtx (<MODE>mode); 11357 if (val < 0) 11358 emit_insn (gen_and<mode>3 (x, op1, tmp)); 11359 else 11360 emit_insn (gen_ior<mode>3 (x, op1, tmp)); 11361 11362 if (invert) 11363 { 11364 rtx tmp = gen_reg_rtx (<MODE>mode); 11365 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 11366 x = tmp; 11367 } 11368 11369 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11370 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 11371 11372 DONE; 11373}) 11374 11375(define_expand "cstore<mode>4_unsigned_imm" 11376 [(use (match_operator 1 "unsigned_comparison_operator" 11377 [(match_operand:GPR 2 "gpc_reg_operand") 11378 (match_operand:GPR 3 "immediate_operand")])) 11379 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11380 "" 11381{ 11382 bool invert = false; 11383 11384 enum rtx_code cond_code = GET_CODE (operands[1]); 11385 11386 rtx op0 = operands[0]; 11387 rtx op1 = operands[2]; 11388 HOST_WIDE_INT val = INTVAL (operands[3]); 11389 11390 if (cond_code == GEU || cond_code == GTU) 11391 { 11392 cond_code = reverse_condition (cond_code); 11393 invert = true; 11394 } 11395 11396 if (cond_code == LEU) 11397 val++; 11398 11399 rtx tmp = gen_reg_rtx (<MODE>mode); 11400 rtx tmp2 = gen_reg_rtx (<MODE>mode); 11401 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val))); 11402 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1)); 11403 rtx x = gen_reg_rtx (<MODE>mode); 11404 if (val < 0) 11405 emit_insn (gen_ior<mode>3 (x, tmp, tmp2)); 11406 else 11407 emit_insn (gen_and<mode>3 (x, tmp, tmp2)); 11408 11409 if (invert) 11410 { 11411 rtx tmp = gen_reg_rtx (<MODE>mode); 11412 emit_insn (gen_one_cmpl<mode>2 (tmp, x)); 11413 x = tmp; 11414 } 11415 11416 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1; 11417 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh))); 11418 11419 DONE; 11420}) 11421 11422(define_expand "cstore<mode>4" 11423 [(use (match_operator 1 "comparison_operator" 11424 [(match_operand:GPR 2 "gpc_reg_operand") 11425 (match_operand:GPR 3 "reg_or_short_operand")])) 11426 (clobber (match_operand:GPR 0 "gpc_reg_operand"))] 11427 "" 11428{ 11429 /* Expanding EQ and NE directly to some machine instructions does not help 11430 but does hurt combine. So don't. */ 11431 if (GET_CODE (operands[1]) == EQ) 11432 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3])); 11433 else if (<MODE>mode == Pmode 11434 && GET_CODE (operands[1]) == NE) 11435 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3])); 11436 else if (GET_CODE (operands[1]) == NE) 11437 { 11438 rtx tmp = gen_reg_rtx (<MODE>mode); 11439 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3])); 11440 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); 11441 } 11442 11443 /* If ISEL is fast, expand to it. */ 11444 else if (TARGET_ISEL) 11445 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx); 11446 11447 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu 11448 etc. combinations magically work out just right. */ 11449 else if (<MODE>mode == Pmode 11450 && unsigned_comparison_operator (operands[1], VOIDmode)) 11451 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1], 11452 operands[2], operands[3])); 11453 11454 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */ 11455 else if (<MODE>mode == SImode && Pmode == DImode) 11456 emit_insn (gen_cstore_si_as_di (operands[0], operands[1], 11457 operands[2], operands[3])); 11458 11459 /* For signed comparisons against a constant, we can do some simple 11460 bit-twiddling. */ 11461 else if (signed_comparison_operator (operands[1], VOIDmode) 11462 && CONST_INT_P (operands[3])) 11463 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1], 11464 operands[2], operands[3])); 11465 11466 /* And similarly for unsigned comparisons. */ 11467 else if (unsigned_comparison_operator (operands[1], VOIDmode) 11468 && CONST_INT_P (operands[3])) 11469 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1], 11470 operands[2], operands[3])); 11471 11472 /* We also do not want to use mfcr for signed comparisons. */ 11473 else if (<MODE>mode == Pmode 11474 && signed_comparison_operator (operands[1], VOIDmode)) 11475 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1], 11476 operands[2], operands[3])); 11477 11478 /* Everything else, use the mfcr brute force. */ 11479 else 11480 rs6000_emit_sCOND (<MODE>mode, operands); 11481 11482 DONE; 11483}) 11484 11485(define_expand "cstore<mode>4" 11486 [(use (match_operator 1 "comparison_operator" 11487 [(match_operand:FP 2 "gpc_reg_operand") 11488 (match_operand:FP 3 "gpc_reg_operand")])) 11489 (clobber (match_operand:SI 0 "gpc_reg_operand"))] 11490 "" 11491{ 11492 rs6000_emit_sCOND (<MODE>mode, operands); 11493 DONE; 11494}) 11495 11496 11497(define_expand "stack_protect_set" 11498 [(match_operand 0 "memory_operand") 11499 (match_operand 1 "memory_operand")] 11500 "" 11501{ 11502 if (rs6000_stack_protector_guard == SSP_TLS) 11503 { 11504 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg); 11505 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset); 11506 rtx addr = gen_rtx_PLUS (Pmode, reg, offset); 11507 operands[1] = gen_rtx_MEM (Pmode, addr); 11508 } 11509 11510 if (TARGET_64BIT) 11511 emit_insn (gen_stack_protect_setdi (operands[0], operands[1])); 11512 else 11513 emit_insn (gen_stack_protect_setsi (operands[0], operands[1])); 11514 11515 DONE; 11516}) 11517 11518(define_insn "stack_protect_setsi" 11519 [(set (match_operand:SI 0 "memory_operand" "=m") 11520 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET)) 11521 (set (match_scratch:SI 2 "=&r") (const_int 0))] 11522 "TARGET_32BIT" 11523 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0" 11524 [(set_attr "type" "three") 11525 (set_attr "length" "12")]) 11526 11527;; We can't use the prefixed attribute here because there are two memory 11528;; instructions. We can't split the insn due to the fact that this operation 11529;; needs to be done in one piece. 11530(define_insn "stack_protect_setdi" 11531 [(set (match_operand:DI 0 "memory_operand" "=Y") 11532 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET)) 11533 (set (match_scratch:DI 2 "=&r") (const_int 0))] 11534 "TARGET_64BIT" 11535{ 11536 if (prefixed_memory (operands[1], DImode)) 11537 output_asm_insn ("pld %2,%1", operands); 11538 else 11539 output_asm_insn ("ld%U1%X1 %2,%1", operands); 11540 11541 if (prefixed_memory (operands[0], DImode)) 11542 output_asm_insn ("pstd %2,%0", operands); 11543 else 11544 output_asm_insn ("std%U0%X0 %2,%0", operands); 11545 11546 return "li %2,0"; 11547} 11548 [(set_attr "type" "three") 11549 11550 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each 11551 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for 11552 ;; the LI 0 at the end. 11553 (set_attr "prefixed" "no") 11554 (set_attr "num_insns" "3") 11555 (set (attr "length") 11556 (cond [(and (match_operand 0 "prefixed_memory") 11557 (match_operand 1 "prefixed_memory")) 11558 (const_int 24) 11559 11560 (ior (match_operand 0 "prefixed_memory") 11561 (match_operand 1 "prefixed_memory")) 11562 (const_int 20)] 11563 11564 (const_int 12)))]) 11565 11566(define_expand "stack_protect_test" 11567 [(match_operand 0 "memory_operand") 11568 (match_operand 1 "memory_operand") 11569 (match_operand 2 "")] 11570 "" 11571{ 11572 rtx guard = operands[1]; 11573 11574 if (rs6000_stack_protector_guard == SSP_TLS) 11575 { 11576 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg); 11577 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset); 11578 rtx addr = gen_rtx_PLUS (Pmode, reg, offset); 11579 guard = gen_rtx_MEM (Pmode, addr); 11580 } 11581 11582 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST); 11583 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]); 11584 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]); 11585 emit_jump_insn (jump); 11586 11587 DONE; 11588}) 11589 11590(define_insn "stack_protect_testsi" 11591 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 11592 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m") 11593 (match_operand:SI 2 "memory_operand" "m,m")] 11594 UNSPEC_SP_TEST)) 11595 (set (match_scratch:SI 4 "=r,r") (const_int 0)) 11596 (clobber (match_scratch:SI 3 "=&r,&r"))] 11597 "TARGET_32BIT" 11598 "@ 11599 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0 11600 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0" 11601 [(set_attr "length" "16,20")]) 11602 11603;; We can't use the prefixed attribute here because there are two memory 11604;; instructions. We can't split the insn due to the fact that this operation 11605;; needs to be done in one piece. 11606(define_insn "stack_protect_testdi" 11607 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y") 11608 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y") 11609 (match_operand:DI 2 "memory_operand" "Y,Y")] 11610 UNSPEC_SP_TEST)) 11611 (set (match_scratch:DI 4 "=r,r") (const_int 0)) 11612 (clobber (match_scratch:DI 3 "=&r,&r"))] 11613 "TARGET_64BIT" 11614{ 11615 if (prefixed_memory (operands[1], DImode)) 11616 output_asm_insn ("pld %3,%1", operands); 11617 else 11618 output_asm_insn ("ld%U1%X1 %3,%1", operands); 11619 11620 if (prefixed_memory (operands[2], DImode)) 11621 output_asm_insn ("pld %4,%2", operands); 11622 else 11623 output_asm_insn ("ld%U2%X2 %4,%2", operands); 11624 11625 if (which_alternative == 0) 11626 output_asm_insn ("xor. %3,%3,%4", operands); 11627 else 11628 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands); 11629 11630 return "li %4,0"; 11631} 11632 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each 11633 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or 11634 ;; 8 bytes to do the test. 11635 [(set_attr "prefixed" "no") 11636 (set_attr "num_insns" "4,5") 11637 (set (attr "length") 11638 (cond [(and (match_operand 1 "prefixed_memory") 11639 (match_operand 2 "prefixed_memory")) 11640 (if_then_else (eq_attr "alternative" "0") 11641 (const_int 28) 11642 (const_int 32)) 11643 11644 (ior (match_operand 1 "prefixed_memory") 11645 (match_operand 2 "prefixed_memory")) 11646 (if_then_else (eq_attr "alternative" "0") 11647 (const_int 20) 11648 (const_int 24))] 11649 11650 (if_then_else (eq_attr "alternative" "0") 11651 (const_int 16) 11652 (const_int 20))))]) 11653 11654 11655;; Here are the actual compare insns. 11656(define_insn "*cmp<mode>_signed" 11657 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 11658 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r") 11659 (match_operand:GPR 2 "reg_or_short_operand" "rI")))] 11660 "" 11661 "cmp<wd>%I2 %0,%1,%2" 11662 [(set_attr "type" "cmp")]) 11663 11664(define_insn "*cmp<mode>_unsigned" 11665 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y") 11666 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r") 11667 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))] 11668 "" 11669 "cmpl<wd>%I2 %0,%1,%2" 11670 [(set_attr "type" "cmp")]) 11671 11672;; If we are comparing a register for equality with a large constant, 11673;; we can do this with an XOR followed by a compare. But this is profitable 11674;; only if the large constant is only used for the comparison (and in this 11675;; case we already have a register to reuse as scratch). 11676;; 11677;; For 64-bit registers, we could only do so if the constant's bit 15 is clear: 11678;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available. 11679 11680(define_peephole2 11681 [(set (match_operand:SI 0 "register_operand") 11682 (match_operand:SI 1 "logical_const_operand")) 11683 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator" 11684 [(match_dup 0) 11685 (match_operand:SI 2 "logical_const_operand")])) 11686 (set (match_operand:CC 4 "cc_reg_operand") 11687 (compare:CC (match_operand:SI 5 "gpc_reg_operand") 11688 (match_dup 0))) 11689 (set (pc) 11690 (if_then_else (match_operator 6 "equality_operator" 11691 [(match_dup 4) (const_int 0)]) 11692 (match_operand 7 "") 11693 (match_operand 8 "")))] 11694 "peep2_reg_dead_p (3, operands[0]) 11695 && peep2_reg_dead_p (4, operands[4]) 11696 && REGNO (operands[0]) != REGNO (operands[5])" 11697 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9))) 11698 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10))) 11699 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))] 11700 11701{ 11702 /* Get the constant we are comparing against, and see what it looks like 11703 when sign-extended from 16 to 32 bits. Then see what constant we could 11704 XOR with SEXTC to get the sign-extended value. */ 11705 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]), 11706 SImode, 11707 operands[1], operands[2]); 11708 HOST_WIDE_INT c = INTVAL (cnst); 11709 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000; 11710 HOST_WIDE_INT xorv = c ^ sextc; 11711 11712 operands[9] = GEN_INT (xorv); 11713 operands[10] = GEN_INT (sextc); 11714}) 11715 11716;; Only need to compare second words if first words equal 11717(define_insn "*cmp<mode>_internal1" 11718 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 11719 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 11720 (match_operand:IBM128 2 "gpc_reg_operand" "d")))] 11721 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode) 11722 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 11723 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2" 11724 [(set_attr "type" "fpcompare") 11725 (set_attr "length" "12")]) 11726 11727(define_insn_and_split "*cmp<IBM128:mode>_internal2" 11728 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 11729 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d") 11730 (match_operand:IBM128 2 "gpc_reg_operand" "d"))) 11731 (clobber (match_scratch:DF 3 "=d")) 11732 (clobber (match_scratch:DF 4 "=d")) 11733 (clobber (match_scratch:DF 5 "=d")) 11734 (clobber (match_scratch:DF 6 "=d")) 11735 (clobber (match_scratch:DF 7 "=d")) 11736 (clobber (match_scratch:DF 8 "=d")) 11737 (clobber (match_scratch:DF 9 "=d")) 11738 (clobber (match_scratch:DF 10 "=d")) 11739 (clobber (match_scratch:GPR 11 "=b"))] 11740 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode) 11741 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128" 11742 "#" 11743 "&& reload_completed" 11744 [(set (match_dup 3) (match_dup 14)) 11745 (set (match_dup 4) (match_dup 15)) 11746 (set (match_dup 9) (abs:DF (match_dup 5))) 11747 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3))) 11748 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0)) 11749 (label_ref (match_dup 12)) 11750 (pc))) 11751 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7))) 11752 (set (pc) (label_ref (match_dup 13))) 11753 (match_dup 12) 11754 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7))) 11755 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8))) 11756 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9))) 11757 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4))) 11758 (match_dup 13)] 11759{ 11760 REAL_VALUE_TYPE rv; 11761 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0; 11762 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode); 11763 11764 operands[5] = simplify_gen_subreg (DFmode, operands[1], 11765 <IBM128:MODE>mode, hi_word); 11766 operands[6] = simplify_gen_subreg (DFmode, operands[1], 11767 <IBM128:MODE>mode, lo_word); 11768 operands[7] = simplify_gen_subreg (DFmode, operands[2], 11769 <IBM128:MODE>mode, hi_word); 11770 operands[8] = simplify_gen_subreg (DFmode, operands[2], 11771 <IBM128:MODE>mode, lo_word); 11772 operands[12] = gen_label_rtx (); 11773 operands[13] = gen_label_rtx (); 11774 real_inf (&rv); 11775 operands[14] = force_const_mem (DFmode, 11776 const_double_from_real_value (rv, DFmode)); 11777 operands[15] = force_const_mem (DFmode, 11778 const_double_from_real_value (dconst0, 11779 DFmode)); 11780 if (TARGET_TOC) 11781 { 11782 rtx tocref; 11783 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]); 11784 operands[14] = gen_const_mem (DFmode, tocref); 11785 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]); 11786 operands[15] = gen_const_mem (DFmode, tocref); 11787 set_mem_alias_set (operands[14], get_TOC_alias_set ()); 11788 set_mem_alias_set (operands[15], get_TOC_alias_set ()); 11789 } 11790}) 11791 11792;; Now we have the scc insns. We can do some combinations because of the 11793;; way the machine works. 11794;; 11795;; Note that this is probably faster if we can put an insn between the 11796;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most 11797;; cases the insns below which don't use an intermediate CR field will 11798;; be used instead. 11799(define_insn "set<mode>_cc" 11800 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11801 (match_operator:GPR 1 "scc_comparison_operator" 11802 [(match_operand 2 "cc_reg_operand" "y") 11803 (const_int 0)]))] 11804 "" 11805 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1" 11806 [(set (attr "type") 11807 (cond [(match_test "TARGET_MFCRF") 11808 (const_string "mfcrf") 11809 ] 11810 (const_string "mfcr"))) 11811 (set_attr "length" "8")]) 11812 11813 11814(define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu]) 11815(define_code_attr UNS [(eq "CC") 11816 (ne "CC") 11817 (lt "CC") (ltu "CCUNS") 11818 (gt "CC") (gtu "CCUNS") 11819 (le "CC") (leu "CCUNS") 11820 (ge "CC") (geu "CCUNS")]) 11821(define_code_attr UNSu_ [(eq "") 11822 (ne "") 11823 (lt "") (ltu "u_") 11824 (gt "") (gtu "u_") 11825 (le "") (leu "u_") 11826 (ge "") (geu "u_")]) 11827(define_code_attr UNSIK [(eq "I") 11828 (ne "I") 11829 (lt "I") (ltu "K") 11830 (gt "I") (gtu "K") 11831 (le "I") (leu "K") 11832 (ge "I") (geu "K")]) 11833 11834(define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel" 11835 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11836 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r") 11837 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>"))) 11838 (clobber (match_scratch:GPR 3 "=r")) 11839 (clobber (match_scratch:GPR 4 "=r")) 11840 (clobber (match_scratch:<UNS> 5 "=y"))] 11841 "TARGET_ISEL 11842 && !(<CODE> == EQ && operands[2] == const0_rtx) 11843 && !(<CODE> == NE && operands[2] == const0_rtx 11844 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)" 11845 "#" 11846 "&& 1" 11847 [(pc)] 11848{ 11849 rtx_code code = <CODE>; 11850 if (CONST_INT_P (operands[2]) && code != EQ && code != NE) 11851 { 11852 HOST_WIDE_INT val = INTVAL (operands[2]); 11853 if (code == LT && val != -0x8000) 11854 { 11855 code = LE; 11856 val--; 11857 } 11858 if (code == GT && val != 0x7fff) 11859 { 11860 code = GE; 11861 val++; 11862 } 11863 if (code == LTU && val != 0) 11864 { 11865 code = LEU; 11866 val--; 11867 } 11868 if (code == GTU && val != 0xffff) 11869 { 11870 code = GEU; 11871 val++; 11872 } 11873 operands[2] = GEN_INT (val); 11874 } 11875 11876 if (code == NE || code == LE || code == GE || code == LEU || code == GEU) 11877 operands[3] = const0_rtx; 11878 else 11879 { 11880 if (GET_CODE (operands[3]) == SCRATCH) 11881 operands[3] = gen_reg_rtx (<GPR:MODE>mode); 11882 emit_move_insn (operands[3], const0_rtx); 11883 } 11884 11885 if (GET_CODE (operands[4]) == SCRATCH) 11886 operands[4] = gen_reg_rtx (<GPR:MODE>mode); 11887 emit_move_insn (operands[4], const1_rtx); 11888 11889 if (GET_CODE (operands[5]) == SCRATCH) 11890 operands[5] = gen_reg_rtx (<UNS>mode); 11891 11892 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]); 11893 emit_insn (gen_rtx_SET (operands[5], c1)); 11894 11895 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx); 11896 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]); 11897 emit_move_insn (operands[0], x); 11898 11899 DONE; 11900} 11901 [(set (attr "cost") 11902 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ) 11903 || <CODE> == NE 11904 || <CODE> == LE || <CODE> == GE 11905 || <CODE> == LEU || <CODE> == GEU") 11906 (const_string "9") 11907 (const_string "10")))]) 11908 11909(define_mode_attr scc_eq_op2 [(SI "rKLI") 11910 (DI "rKJI")]) 11911 11912(define_expand "eq<mode>3" 11913 [(parallel [ 11914 (set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11915 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 11916 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 11917 (clobber (match_scratch:GPR 3 "=r")) 11918 (clobber (match_scratch:GPR 4 "=r"))])] 11919 "" 11920{ 11921 if (TARGET_ISEL && operands[2] != const0_rtx) 11922 { 11923 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1], 11924 operands[2])); 11925 DONE; 11926 } 11927}) 11928 11929(define_insn_and_split "*eq<mode>3" 11930 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 11931 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r") 11932 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>"))) 11933 (clobber (match_scratch:GPR 3 "=r")) 11934 (clobber (match_scratch:GPR 4 "=r"))] 11935 "!(TARGET_ISEL && operands[2] != const0_rtx)" 11936 "#" 11937 "&& 1" 11938 [(set (match_dup 4) 11939 (clz:GPR (match_dup 3))) 11940 (set (match_dup 0) 11941 (lshiftrt:GPR (match_dup 4) 11942 (match_dup 5)))] 11943{ 11944 operands[3] = rs6000_emit_eqne (<MODE>mode, 11945 operands[1], operands[2], operands[3]); 11946 11947 if (GET_CODE (operands[4]) == SCRATCH) 11948 operands[4] = gen_reg_rtx (<MODE>mode); 11949 11950 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode))); 11951} 11952 [(set (attr "length") 11953 (if_then_else (match_test "operands[2] == const0_rtx") 11954 (const_string "8") 11955 (const_string "12")))]) 11956 11957(define_expand "ne<mode>3" 11958 [(parallel [ 11959 (set (match_operand:P 0 "gpc_reg_operand" "=r") 11960 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 11961 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) 11962 (clobber (match_scratch:P 3 "=r")) 11963 (clobber (match_scratch:P 4 "=r")) 11964 (clobber (reg:P CA_REGNO))])] 11965 "" 11966{ 11967 if (TARGET_ISEL && operands[2] != const0_rtx) 11968 { 11969 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1], 11970 operands[2])); 11971 DONE; 11972 } 11973}) 11974 11975(define_insn_and_split "*ne<mode>3" 11976 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 11977 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 11978 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))) 11979 (clobber (match_scratch:P 3 "=r")) 11980 (clobber (match_scratch:P 4 "=r")) 11981 (clobber (reg:P CA_REGNO))] 11982 "!(TARGET_ISEL && operands[2] != const0_rtx)" 11983 "#" 11984 "&& 1" 11985 [(parallel [(set (match_dup 4) 11986 (plus:P (match_dup 3) 11987 (const_int -1))) 11988 (set (reg:P CA_REGNO) 11989 (ne:P (match_dup 3) 11990 (const_int 0)))]) 11991 (parallel [(set (match_dup 0) 11992 (plus:P (plus:P (not:P (match_dup 4)) 11993 (reg:P CA_REGNO)) 11994 (match_dup 3))) 11995 (clobber (reg:P CA_REGNO))])] 11996{ 11997 operands[3] = rs6000_emit_eqne (<MODE>mode, 11998 operands[1], operands[2], operands[3]); 11999 12000 if (GET_CODE (operands[4]) == SCRATCH) 12001 operands[4] = gen_reg_rtx (<MODE>mode); 12002} 12003 [(set (attr "length") 12004 (if_then_else (match_test "operands[2] == const0_rtx") 12005 (const_string "8") 12006 (const_string "12")))]) 12007 12008(define_insn_and_split "*neg_eq_<mode>" 12009 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12010 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12011 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12012 (clobber (match_scratch:P 3 "=r")) 12013 (clobber (match_scratch:P 4 "=r")) 12014 (clobber (reg:P CA_REGNO))] 12015 "" 12016 "#" 12017 "" 12018 [(parallel [(set (match_dup 4) 12019 (plus:P (match_dup 3) 12020 (const_int -1))) 12021 (set (reg:P CA_REGNO) 12022 (ne:P (match_dup 3) 12023 (const_int 0)))]) 12024 (parallel [(set (match_dup 0) 12025 (plus:P (reg:P CA_REGNO) 12026 (const_int -1))) 12027 (clobber (reg:P CA_REGNO))])] 12028{ 12029 operands[3] = rs6000_emit_eqne (<MODE>mode, 12030 operands[1], operands[2], operands[3]); 12031 12032 if (GET_CODE (operands[4]) == SCRATCH) 12033 operands[4] = gen_reg_rtx (<MODE>mode); 12034} 12035 [(set (attr "length") 12036 (if_then_else (match_test "operands[2] == const0_rtx") 12037 (const_string "8") 12038 (const_string "12")))]) 12039 12040(define_insn_and_split "*neg_ne_<mode>" 12041 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12042 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12043 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12044 (clobber (match_scratch:P 3 "=r")) 12045 (clobber (match_scratch:P 4 "=r")) 12046 (clobber (reg:P CA_REGNO))] 12047 "" 12048 "#" 12049 "" 12050 [(parallel [(set (match_dup 4) 12051 (neg:P (match_dup 3))) 12052 (set (reg:P CA_REGNO) 12053 (eq:P (match_dup 3) 12054 (const_int 0)))]) 12055 (parallel [(set (match_dup 0) 12056 (plus:P (reg:P CA_REGNO) 12057 (const_int -1))) 12058 (clobber (reg:P CA_REGNO))])] 12059{ 12060 operands[3] = rs6000_emit_eqne (<MODE>mode, 12061 operands[1], operands[2], operands[3]); 12062 12063 if (GET_CODE (operands[4]) == SCRATCH) 12064 operands[4] = gen_reg_rtx (<MODE>mode); 12065} 12066 [(set (attr "length") 12067 (if_then_else (match_test "operands[2] == const0_rtx") 12068 (const_string "8") 12069 (const_string "12")))]) 12070 12071(define_insn_and_split "*plus_eq_<mode>" 12072 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12073 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12074 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 12075 (match_operand:P 3 "gpc_reg_operand" "r"))) 12076 (clobber (match_scratch:P 4 "=r")) 12077 (clobber (match_scratch:P 5 "=r")) 12078 (clobber (reg:P CA_REGNO))] 12079 "" 12080 "#" 12081 "" 12082 [(parallel [(set (match_dup 5) 12083 (neg:P (match_dup 4))) 12084 (set (reg:P CA_REGNO) 12085 (eq:P (match_dup 4) 12086 (const_int 0)))]) 12087 (parallel [(set (match_dup 0) 12088 (plus:P (match_dup 3) 12089 (reg:P CA_REGNO))) 12090 (clobber (reg:P CA_REGNO))])] 12091{ 12092 operands[4] = rs6000_emit_eqne (<MODE>mode, 12093 operands[1], operands[2], operands[4]); 12094 12095 if (GET_CODE (operands[5]) == SCRATCH) 12096 operands[5] = gen_reg_rtx (<MODE>mode); 12097} 12098 [(set (attr "length") 12099 (if_then_else (match_test "operands[2] == const0_rtx") 12100 (const_string "8") 12101 (const_string "12")))]) 12102 12103(define_insn_and_split "*plus_ne_<mode>" 12104 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12105 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12106 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")) 12107 (match_operand:P 3 "gpc_reg_operand" "r"))) 12108 (clobber (match_scratch:P 4 "=r")) 12109 (clobber (match_scratch:P 5 "=r")) 12110 (clobber (reg:P CA_REGNO))] 12111 "" 12112 "#" 12113 "" 12114 [(parallel [(set (match_dup 5) 12115 (plus:P (match_dup 4) 12116 (const_int -1))) 12117 (set (reg:P CA_REGNO) 12118 (ne:P (match_dup 4) 12119 (const_int 0)))]) 12120 (parallel [(set (match_dup 0) 12121 (plus:P (match_dup 3) 12122 (reg:P CA_REGNO))) 12123 (clobber (reg:P CA_REGNO))])] 12124{ 12125 operands[4] = rs6000_emit_eqne (<MODE>mode, 12126 operands[1], operands[2], operands[4]); 12127 12128 if (GET_CODE (operands[5]) == SCRATCH) 12129 operands[5] = gen_reg_rtx (<MODE>mode); 12130} 12131 [(set (attr "length") 12132 (if_then_else (match_test "operands[2] == const0_rtx") 12133 (const_string "8") 12134 (const_string "12")))]) 12135 12136(define_insn_and_split "*minus_eq_<mode>" 12137 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12138 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 12139 (eq:P (match_operand:P 1 "gpc_reg_operand" "r") 12140 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12141 (clobber (match_scratch:P 4 "=r")) 12142 (clobber (match_scratch:P 5 "=r")) 12143 (clobber (reg:P CA_REGNO))] 12144 "" 12145 "#" 12146 "" 12147 [(parallel [(set (match_dup 5) 12148 (plus:P (match_dup 4) 12149 (const_int -1))) 12150 (set (reg:P CA_REGNO) 12151 (ne:P (match_dup 4) 12152 (const_int 0)))]) 12153 (parallel [(set (match_dup 0) 12154 (plus:P (plus:P (match_dup 3) 12155 (reg:P CA_REGNO)) 12156 (const_int -1))) 12157 (clobber (reg:P CA_REGNO))])] 12158{ 12159 operands[4] = rs6000_emit_eqne (<MODE>mode, 12160 operands[1], operands[2], operands[4]); 12161 12162 if (GET_CODE (operands[5]) == SCRATCH) 12163 operands[5] = gen_reg_rtx (<MODE>mode); 12164} 12165 [(set (attr "length") 12166 (if_then_else (match_test "operands[2] == const0_rtx") 12167 (const_string "8") 12168 (const_string "12")))]) 12169 12170(define_insn_and_split "*minus_ne_<mode>" 12171 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 12172 (minus:P (match_operand:P 3 "gpc_reg_operand" "r") 12173 (ne:P (match_operand:P 1 "gpc_reg_operand" "r") 12174 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))) 12175 (clobber (match_scratch:P 4 "=r")) 12176 (clobber (match_scratch:P 5 "=r")) 12177 (clobber (reg:P CA_REGNO))] 12178 "" 12179 "#" 12180 "" 12181 [(parallel [(set (match_dup 5) 12182 (neg:P (match_dup 4))) 12183 (set (reg:P CA_REGNO) 12184 (eq:P (match_dup 4) 12185 (const_int 0)))]) 12186 (parallel [(set (match_dup 0) 12187 (plus:P (plus:P (match_dup 3) 12188 (reg:P CA_REGNO)) 12189 (const_int -1))) 12190 (clobber (reg:P CA_REGNO))])] 12191{ 12192 operands[4] = rs6000_emit_eqne (<MODE>mode, 12193 operands[1], operands[2], operands[4]); 12194 12195 if (GET_CODE (operands[5]) == SCRATCH) 12196 operands[5] = gen_reg_rtx (<MODE>mode); 12197} 12198 [(set (attr "length") 12199 (if_then_else (match_test "operands[2] == const0_rtx") 12200 (const_string "8") 12201 (const_string "12")))]) 12202 12203(define_insn_and_split "*eqsi3_ext<mode>" 12204 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 12205 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 12206 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 12207 (clobber (match_scratch:SI 3 "=r")) 12208 (clobber (match_scratch:SI 4 "=r"))] 12209 "" 12210 "#" 12211 "" 12212 [(set (match_dup 4) 12213 (clz:SI (match_dup 3))) 12214 (set (match_dup 0) 12215 (zero_extend:EXTSI 12216 (lshiftrt:SI (match_dup 4) 12217 (const_int 5))))] 12218{ 12219 operands[3] = rs6000_emit_eqne (SImode, 12220 operands[1], operands[2], operands[3]); 12221 12222 if (GET_CODE (operands[4]) == SCRATCH) 12223 operands[4] = gen_reg_rtx (SImode); 12224} 12225 [(set (attr "length") 12226 (if_then_else (match_test "operands[2] == const0_rtx") 12227 (const_string "8") 12228 (const_string "12")))]) 12229 12230(define_insn_and_split "*nesi3_ext<mode>" 12231 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r") 12232 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r") 12233 (match_operand:SI 2 "scc_eq_operand" "rKLI"))) 12234 (clobber (match_scratch:SI 3 "=r")) 12235 (clobber (match_scratch:SI 4 "=r")) 12236 (clobber (match_scratch:EXTSI 5 "=r"))] 12237 "!TARGET_ISEL" 12238 "#" 12239 "&& 1" 12240 [(set (match_dup 4) 12241 (clz:SI (match_dup 3))) 12242 (set (match_dup 5) 12243 (zero_extend:EXTSI 12244 (lshiftrt:SI (match_dup 4) 12245 (const_int 5)))) 12246 (set (match_dup 0) 12247 (xor:EXTSI (match_dup 5) 12248 (const_int 1)))] 12249{ 12250 operands[3] = rs6000_emit_eqne (SImode, 12251 operands[1], operands[2], operands[3]); 12252 12253 if (GET_CODE (operands[4]) == SCRATCH) 12254 operands[4] = gen_reg_rtx (SImode); 12255 if (GET_CODE (operands[5]) == SCRATCH) 12256 operands[5] = gen_reg_rtx (<MODE>mode); 12257} 12258 [(set (attr "length") 12259 (if_then_else (match_test "operands[2] == const0_rtx") 12260 (const_string "12") 12261 (const_string "16")))]) 12262 12263 12264(define_code_iterator fp_rev [ordered ne unle unge]) 12265(define_code_iterator fp_two [ltgt le ge unlt ungt uneq]) 12266 12267(define_insn_and_split "*<code><mode>_cc" 12268 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12269 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y") 12270 (const_int 0)))] 12271 "!flag_finite_math_only" 12272 "#" 12273 "&& 1" 12274 [(pc)] 12275{ 12276 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>); 12277 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx); 12278 rtx tmp = gen_reg_rtx (<MODE>mode); 12279 emit_move_insn (tmp, eq); 12280 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx)); 12281 DONE; 12282} 12283 [(set_attr "length" "12")]) 12284 12285(define_insn_and_split "*<code><mode>_cc" 12286 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 12287 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y") 12288 (const_int 0)))] 12289 "!flag_finite_math_only" 12290 "#" 12291 "&& 1" 12292 [(pc)] 12293{ 12294 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]); 12295 12296 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx)); 12297 DONE; 12298} 12299 [(set_attr "length" "12")]) 12300 12301;; Conditional branches. 12302;; These either are a single bc insn, or a bc around a b. 12303 12304(define_insn "*cbranch" 12305 [(set (pc) 12306 (if_then_else (match_operator 1 "branch_comparison_operator" 12307 [(match_operand 2 "cc_reg_operand" "y") 12308 (const_int 0)]) 12309 (label_ref (match_operand 0)) 12310 (pc)))] 12311 "" 12312{ 12313 return output_cbranch (operands[1], "%l0", 0, insn); 12314} 12315 [(set_attr "type" "branch") 12316 (set (attr "length") 12317 (if_then_else (and (ge (minus (match_dup 0) (pc)) 12318 (const_int -32768)) 12319 (lt (minus (match_dup 0) (pc)) 12320 (const_int 32764))) 12321 (const_int 4) 12322 (const_int 8)))]) 12323 12324(define_insn_and_split "*cbranch_2insn" 12325 [(set (pc) 12326 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator" 12327 [(match_operand 2 "cc_reg_operand" "y") 12328 (const_int 0)]) 12329 (label_ref (match_operand 0)) 12330 (pc)))] 12331 "!flag_finite_math_only" 12332 "#" 12333 "&& 1" 12334 [(pc)] 12335{ 12336 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]); 12337 12338 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0); 12339 12340 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]); 12341 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx); 12342 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx); 12343 emit_jump_insn (gen_rtx_SET (pc_rtx, ite)); 12344 12345 if (note) 12346 { 12347 profile_probability prob 12348 = profile_probability::from_reg_br_prob_note (XINT (note, 0)); 12349 12350 add_reg_br_prob_note (get_last_insn (), prob); 12351 } 12352 12353 DONE; 12354} 12355 [(set_attr "type" "branch") 12356 (set (attr "length") 12357 (if_then_else (and (ge (minus (match_dup 0) (pc)) 12358 (const_int -32764)) 12359 (lt (minus (match_dup 0) (pc)) 12360 (const_int 32760))) 12361 (const_int 8) 12362 (const_int 16)))]) 12363 12364;; Conditional return. 12365(define_insn "*creturn" 12366 [(set (pc) 12367 (if_then_else (match_operator 0 "branch_comparison_operator" 12368 [(match_operand 1 "cc_reg_operand" "y") 12369 (const_int 0)]) 12370 (any_return) 12371 (pc)))] 12372 "<return_pred>" 12373{ 12374 return output_cbranch (operands[0], NULL, 0, insn); 12375} 12376 [(set_attr "type" "jmpreg")]) 12377 12378;; Logic on condition register values. 12379 12380; This pattern matches things like 12381; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0)) 12382; (eq:SI (reg:CCFP 68) (const_int 0))) 12383; (const_int 1))) 12384; which are generated by the branch logic. 12385; Prefer destructive operations where BT = BB (for crXX BT,BA,BB) 12386 12387(define_insn "@cceq_ior_compare_<mode>" 12388 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12389 (compare:CCEQ (match_operator:GPR 1 "boolean_operator" 12390 [(match_operator:GPR 2 12391 "branch_positive_comparison_operator" 12392 [(match_operand 3 12393 "cc_reg_operand" "y,y") 12394 (const_int 0)]) 12395 (match_operator:GPR 4 12396 "branch_positive_comparison_operator" 12397 [(match_operand 5 12398 "cc_reg_operand" "0,y") 12399 (const_int 0)])]) 12400 (const_int 1)))] 12401 "" 12402 "cr%q1 %E0,%j2,%j4" 12403 [(set_attr "type" "cr_logical") 12404 (set_attr "cr_logical_3op" "no,yes")]) 12405 12406; Why is the constant -1 here, but 1 in the previous pattern? 12407; Because ~1 has all but the low bit set. 12408(define_insn "cceq_ior_compare_complement" 12409 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12410 (compare:CCEQ (match_operator:SI 1 "boolean_operator" 12411 [(not:SI (match_operator:SI 2 12412 "branch_positive_comparison_operator" 12413 [(match_operand 3 12414 "cc_reg_operand" "y,y") 12415 (const_int 0)])) 12416 (match_operator:SI 4 12417 "branch_positive_comparison_operator" 12418 [(match_operand 5 12419 "cc_reg_operand" "0,y") 12420 (const_int 0)])]) 12421 (const_int -1)))] 12422 "" 12423 "cr%q1 %E0,%j2,%j4" 12424 [(set_attr "type" "cr_logical") 12425 (set_attr "cr_logical_3op" "no,yes")]) 12426 12427(define_insn "@cceq_rev_compare_<mode>" 12428 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y") 12429 (compare:CCEQ (match_operator:GPR 1 12430 "branch_positive_comparison_operator" 12431 [(match_operand 2 12432 "cc_reg_operand" "0,y") 12433 (const_int 0)]) 12434 (const_int 0)))] 12435 "" 12436 "crnot %E0,%j1" 12437 [(set_attr "type" "cr_logical") 12438 (set_attr "cr_logical_3op" "no,yes")]) 12439 12440;; If we are comparing the result of two comparisons, this can be done 12441;; using creqv or crxor. 12442 12443(define_insn_and_split "" 12444 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y") 12445 (compare:CCEQ (match_operator 1 "branch_comparison_operator" 12446 [(match_operand 2 "cc_reg_operand" "y") 12447 (const_int 0)]) 12448 (match_operator 3 "branch_comparison_operator" 12449 [(match_operand 4 "cc_reg_operand" "y") 12450 (const_int 0)])))] 12451 "" 12452 "#" 12453 "" 12454 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3)) 12455 (match_dup 5)))] 12456{ 12457 int positive_1, positive_2; 12458 12459 positive_1 = branch_positive_comparison_operator (operands[1], 12460 GET_MODE (operands[1])); 12461 positive_2 = branch_positive_comparison_operator (operands[3], 12462 GET_MODE (operands[3])); 12463 12464 if (! positive_1) 12465 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]), 12466 GET_CODE (operands[1])), 12467 SImode, 12468 operands[2], const0_rtx); 12469 else if (GET_MODE (operands[1]) != SImode) 12470 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode, 12471 operands[2], const0_rtx); 12472 12473 if (! positive_2) 12474 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]), 12475 GET_CODE (operands[3])), 12476 SImode, 12477 operands[4], const0_rtx); 12478 else if (GET_MODE (operands[3]) != SImode) 12479 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode, 12480 operands[4], const0_rtx); 12481 12482 if (positive_1 == positive_2) 12483 { 12484 operands[1] = gen_rtx_NOT (SImode, operands[1]); 12485 operands[5] = constm1_rtx; 12486 } 12487 else 12488 { 12489 operands[5] = const1_rtx; 12490 } 12491}) 12492 12493;; Unconditional branch and return. 12494 12495(define_insn "jump" 12496 [(set (pc) 12497 (label_ref (match_operand 0)))] 12498 "" 12499 "b %l0" 12500 [(set_attr "type" "branch")]) 12501 12502(define_insn "<return_str>return" 12503 [(any_return)] 12504 "<return_pred>" 12505 "blr" 12506 [(set_attr "type" "jmpreg")]) 12507 12508(define_expand "indirect_jump" 12509 [(set (pc) (match_operand 0 "register_operand"))] 12510 "" 12511{ 12512 if (!rs6000_speculate_indirect_jumps) { 12513 rtx ccreg = gen_reg_rtx (CCmode); 12514 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg)); 12515 DONE; 12516 } 12517}) 12518 12519(define_insn "*indirect_jump<mode>" 12520 [(set (pc) 12521 (match_operand:P 0 "register_operand" "c,*l"))] 12522 "rs6000_speculate_indirect_jumps" 12523 "b%T0" 12524 [(set_attr "type" "jmpreg")]) 12525 12526(define_insn "@indirect_jump<mode>_nospec" 12527 [(set (pc) (match_operand:P 0 "register_operand" "c,*l")) 12528 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))] 12529 "!rs6000_speculate_indirect_jumps" 12530 "crset %E1\;beq%T0- %1\;b $" 12531 [(set_attr "type" "jmpreg") 12532 (set_attr "length" "12")]) 12533 12534;; Table jump for switch statements: 12535(define_expand "tablejump" 12536 [(use (match_operand 0)) 12537 (use (label_ref (match_operand 1)))] 12538 "" 12539{ 12540 if (rs6000_speculate_indirect_jumps) 12541 { 12542 if (TARGET_32BIT) 12543 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1])); 12544 else 12545 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1])); 12546 } 12547 else 12548 { 12549 rtx ccreg = gen_reg_rtx (CCmode); 12550 rtx jump; 12551 if (TARGET_32BIT) 12552 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg); 12553 else 12554 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg); 12555 emit_jump_insn (jump); 12556 } 12557 DONE; 12558}) 12559 12560(define_expand "tablejumpsi" 12561 [(set (match_dup 3) 12562 (plus:SI (match_operand:SI 0) 12563 (match_dup 2))) 12564 (parallel [(set (pc) 12565 (match_dup 3)) 12566 (use (label_ref (match_operand 1)))])] 12567 "TARGET_32BIT && rs6000_speculate_indirect_jumps" 12568{ 12569 operands[0] = force_reg (SImode, operands[0]); 12570 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); 12571 operands[3] = gen_reg_rtx (SImode); 12572}) 12573 12574(define_expand "tablejumpsi_nospec" 12575 [(set (match_dup 4) 12576 (plus:SI (match_operand:SI 0) 12577 (match_dup 3))) 12578 (parallel [(set (pc) 12579 (match_dup 4)) 12580 (use (label_ref (match_operand 1))) 12581 (clobber (match_operand 2))])] 12582 "TARGET_32BIT && !rs6000_speculate_indirect_jumps" 12583{ 12584 operands[0] = force_reg (SImode, operands[0]); 12585 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1])); 12586 operands[4] = gen_reg_rtx (SImode); 12587}) 12588 12589(define_expand "tablejumpdi" 12590 [(set (match_dup 4) 12591 (sign_extend:DI (match_operand:SI 0 "lwa_operand"))) 12592 (set (match_dup 3) 12593 (plus:DI (match_dup 4) 12594 (match_dup 2))) 12595 (parallel [(set (pc) 12596 (match_dup 3)) 12597 (use (label_ref (match_operand 1)))])] 12598 "TARGET_64BIT && rs6000_speculate_indirect_jumps" 12599{ 12600 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); 12601 operands[3] = gen_reg_rtx (DImode); 12602 operands[4] = gen_reg_rtx (DImode); 12603}) 12604 12605(define_expand "tablejumpdi_nospec" 12606 [(set (match_dup 5) 12607 (sign_extend:DI (match_operand:SI 0 "lwa_operand"))) 12608 (set (match_dup 4) 12609 (plus:DI (match_dup 5) 12610 (match_dup 3))) 12611 (parallel [(set (pc) 12612 (match_dup 4)) 12613 (use (label_ref (match_operand 1))) 12614 (clobber (match_operand 2))])] 12615 "TARGET_64BIT && !rs6000_speculate_indirect_jumps" 12616{ 12617 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1])); 12618 operands[4] = gen_reg_rtx (DImode); 12619 operands[5] = gen_reg_rtx (DImode); 12620}) 12621 12622(define_insn "*tablejump<mode>_internal1" 12623 [(set (pc) 12624 (match_operand:P 0 "register_operand" "c,*l")) 12625 (use (label_ref (match_operand 1)))] 12626 "rs6000_speculate_indirect_jumps" 12627 "b%T0" 12628 [(set_attr "type" "jmpreg")]) 12629 12630(define_insn "*tablejump<mode>_internal1_nospec" 12631 [(set (pc) 12632 (match_operand:P 0 "register_operand" "c,*l")) 12633 (use (label_ref (match_operand 1))) 12634 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))] 12635 "!rs6000_speculate_indirect_jumps" 12636 "crset %E2\;beq%T0- %2\;b $" 12637 [(set_attr "type" "jmpreg") 12638 (set_attr "length" "12")]) 12639 12640(define_insn "nop" 12641 [(unspec [(const_int 0)] UNSPEC_NOP)] 12642 "" 12643 "nop") 12644 12645(define_insn "group_ending_nop" 12646 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)] 12647 "" 12648{ 12649 operands[0] = gen_rtx_REG (Pmode, 12650 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2); 12651 return "ori %0,%0,0"; 12652}) 12653 12654(define_insn "speculation_barrier" 12655 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)] 12656 "" 12657{ 12658 operands[0] = gen_rtx_REG (Pmode, 31); 12659 return "ori %0,%0,0"; 12660}) 12661 12662;; Define the subtract-one-and-jump insns, starting with the template 12663;; so loop.c knows what to generate. 12664 12665(define_expand "doloop_end" 12666 [(use (match_operand 0)) ; loop pseudo 12667 (use (match_operand 1))] ; label 12668 "" 12669{ 12670 if (GET_MODE (operands[0]) != Pmode) 12671 FAIL; 12672 12673 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1])); 12674 DONE; 12675}) 12676 12677(define_expand "@ctr<mode>" 12678 [(parallel [(set (pc) 12679 (if_then_else (ne (match_operand:P 0 "register_operand") 12680 (const_int 1)) 12681 (label_ref (match_operand 1)) 12682 (pc))) 12683 (set (match_dup 0) 12684 (plus:P (match_dup 0) 12685 (const_int -1))) 12686 (clobber (match_scratch:CC 2)) 12687 (clobber (match_scratch:P 3))])] 12688 "" 12689 "") 12690 12691;; We need to be able to do this for any operand, including MEM, or we 12692;; will cause reload to blow up since we don't allow output reloads on 12693;; JUMP_INSNs. 12694;; For the length attribute to be calculated correctly, the 12695;; label MUST be operand 0. 12696;; rs6000_legitimate_combined_insn prevents combine creating any of 12697;; the ctr<mode> insns. 12698 12699(define_code_iterator eqne [eq ne]) 12700(define_code_attr bd [(eq "bdz") (ne "bdnz")]) 12701(define_code_attr bd_neg [(eq "bdnz") (ne "bdz")]) 12702 12703(define_insn "<bd>_<mode>" 12704 [(set (pc) 12705 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12706 (const_int 1)) 12707 (label_ref (match_operand 0)) 12708 (pc))) 12709 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l") 12710 (plus:P (match_dup 1) 12711 (const_int -1))) 12712 (clobber (match_scratch:CC 3 "=X,&x,&x,&x")) 12713 (clobber (match_scratch:P 4 "=X,X,&r,r"))] 12714 "" 12715{ 12716 if (which_alternative != 0) 12717 return "#"; 12718 else if (get_attr_length (insn) == 4) 12719 return "<bd> %l0"; 12720 else 12721 return "<bd_neg> $+8\;b %l0"; 12722} 12723 [(set_attr "type" "branch") 12724 (set_attr_alternative "length" 12725 [(if_then_else (and (ge (minus (match_dup 0) (pc)) 12726 (const_int -32768)) 12727 (lt (minus (match_dup 0) (pc)) 12728 (const_int 32764))) 12729 (const_int 4) 12730 (const_int 8)) 12731 (const_string "16") 12732 (const_string "20") 12733 (const_string "20")])]) 12734 12735;; Now the splitter if we could not allocate the CTR register 12736(define_split 12737 [(set (pc) 12738 (if_then_else (match_operator 2 "comparison_operator" 12739 [(match_operand:P 1 "gpc_reg_operand") 12740 (const_int 1)]) 12741 (match_operand 5) 12742 (match_operand 6))) 12743 (set (match_operand:P 0 "nonimmediate_operand") 12744 (plus:P (match_dup 1) 12745 (const_int -1))) 12746 (clobber (match_scratch:CC 3)) 12747 (clobber (match_scratch:P 4))] 12748 "reload_completed" 12749 [(set (pc) 12750 (if_then_else (match_dup 7) 12751 (match_dup 5) 12752 (match_dup 6)))] 12753{ 12754 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3], 12755 const0_rtx); 12756 emit_insn (gen_rtx_SET (operands[3], 12757 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx))); 12758 if (int_reg_operand (operands[0], <MODE>mode)) 12759 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx)); 12760 else 12761 { 12762 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx)); 12763 emit_move_insn (operands[0], operands[4]); 12764 } 12765 /* No DONE so branch comes from the pattern. */ 12766}) 12767 12768;; patterns for bdnzt/bdnzf/bdzt/bdzf 12769;; Note that in the case of long branches we have to decompose this into 12770;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition 12771;; and the CR bit, which means there is no way to conveniently invert the 12772;; comparison as is done with plain bdnz/bdz. 12773 12774(define_insn "<bd>tf_<mode>" 12775 [(set (pc) 12776 (if_then_else 12777 (and 12778 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b") 12779 (const_int 1)) 12780 (match_operator 3 "branch_comparison_operator" 12781 [(match_operand 4 "cc_reg_operand" "y,y,y,y") 12782 (const_int 0)])) 12783 (label_ref (match_operand 0)) 12784 (pc))) 12785 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l") 12786 (plus:P (match_dup 1) 12787 (const_int -1))) 12788 (clobber (match_scratch:P 5 "=X,X,&r,r")) 12789 (clobber (match_scratch:CC 6 "=X,&y,&y,&y")) 12790 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))] 12791 "" 12792{ 12793 if (which_alternative != 0) 12794 return "#"; 12795 else if (get_attr_length (insn) == 4) 12796 { 12797 if (branch_positive_comparison_operator (operands[3], 12798 GET_MODE (operands[3]))) 12799 return "<bd>t %j3,%l0"; 12800 else 12801 return "<bd>f %j3,%l0"; 12802 } 12803 else 12804 { 12805 static char seq[96]; 12806 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn); 12807 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs); 12808 return seq; 12809 } 12810} 12811 [(set_attr "type" "branch") 12812 (set_attr_alternative "length" 12813 [(if_then_else (and (ge (minus (match_dup 0) (pc)) 12814 (const_int -32768)) 12815 (lt (minus (match_dup 0) (pc)) 12816 (const_int 32764))) 12817 (const_int 4) 12818 (const_int 8)) 12819 (const_string "16") 12820 (const_string "20") 12821 (const_string "20")])]) 12822 12823;; Now the splitter if we could not allocate the CTR register 12824(define_split 12825 [(set (pc) 12826 (if_then_else 12827 (and 12828 (match_operator 1 "comparison_operator" 12829 [(match_operand:P 0 "gpc_reg_operand") 12830 (const_int 1)]) 12831 (match_operator 3 "branch_comparison_operator" 12832 [(match_operand 2 "cc_reg_operand") 12833 (const_int 0)])) 12834 (match_operand 4) 12835 (match_operand 5))) 12836 (set (match_operand:P 6 "nonimmediate_operand") 12837 (plus:P (match_dup 0) 12838 (const_int -1))) 12839 (clobber (match_scratch:P 7)) 12840 (clobber (match_scratch:CC 8)) 12841 (clobber (match_scratch:CCEQ 9))] 12842 "reload_completed" 12843[(pc)] 12844{ 12845 rtx ctr = operands[0]; 12846 rtx ctrcmp = operands[1]; 12847 rtx ccin = operands[2]; 12848 rtx cccmp = operands[3]; 12849 rtx dst1 = operands[4]; 12850 rtx dst2 = operands[5]; 12851 rtx ctrout = operands[6]; 12852 rtx ctrtmp = operands[7]; 12853 enum rtx_code cmpcode = GET_CODE (ctrcmp); 12854 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp)); 12855 if (!ispos) 12856 cmpcode = reverse_condition (cmpcode); 12857 /* Generate crand/crandc here. */ 12858 emit_insn (gen_rtx_SET (operands[8], 12859 gen_rtx_COMPARE (CCmode, ctr, const1_rtx))); 12860 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx); 12861 12862 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp); 12863 if (ispos) 12864 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc, 12865 operands[8], cccmp, ccin)); 12866 else 12867 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc, 12868 operands[8], cccmp, ccin)); 12869 if (int_reg_operand (ctrout, <MODE>mode)) 12870 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx)); 12871 else 12872 { 12873 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx)); 12874 emit_move_insn (ctrout, ctrtmp); 12875 } 12876 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx); 12877 emit_jump_insn (gen_rtx_SET (pc_rtx, 12878 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp, 12879 dst1, dst2))); 12880 DONE; 12881}) 12882 12883 12884(define_insn "trap" 12885 [(trap_if (const_int 1) (const_int 0))] 12886 "" 12887 "trap" 12888 [(set_attr "type" "trap")]) 12889 12890(define_expand "ctrap<mode>4" 12891 [(trap_if (match_operator 0 "ordered_comparison_operator" 12892 [(match_operand:GPR 1 "register_operand") 12893 (match_operand:GPR 2 "reg_or_short_operand")]) 12894 (match_operand 3 "zero_constant" ""))] 12895 "" 12896 "") 12897 12898(define_insn "" 12899 [(trap_if (match_operator 0 "ordered_comparison_operator" 12900 [(match_operand:GPR 1 "register_operand" "r") 12901 (match_operand:GPR 2 "reg_or_short_operand" "rI")]) 12902 (const_int 0))] 12903 "" 12904 "t<wd>%V0%I2 %1,%2" 12905 [(set_attr "type" "trap")]) 12906 12907;; Insns related to generating the function prologue and epilogue. 12908 12909(define_expand "prologue" 12910 [(use (const_int 0))] 12911 "" 12912{ 12913 rs6000_emit_prologue (); 12914 if (!TARGET_SCHED_PROLOG) 12915 emit_insn (gen_blockage ()); 12916 DONE; 12917}) 12918 12919(define_insn "*movesi_from_cr_one" 12920 [(match_parallel 0 "mfcr_operation" 12921 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 12922 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y") 12923 (match_operand 3 "immediate_operand" "n")] 12924 UNSPEC_MOVESI_FROM_CR))])] 12925 "TARGET_MFCRF" 12926{ 12927 int mask = 0; 12928 int i; 12929 for (i = 0; i < XVECLEN (operands[0], 0); i++) 12930 { 12931 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 12932 operands[4] = GEN_INT (mask); 12933 output_asm_insn ("mfcr %1,%4", operands); 12934 } 12935 return ""; 12936} 12937 [(set_attr "type" "mfcrf")]) 12938 12939;; Don't include the volatile CRs since their values are not used wrt CR save 12940;; in the prologue and doing so prevents shrink-wrapping because we can't move the 12941;; prologue past an insn (early exit test) that defines a register used in the 12942;; prologue. 12943(define_insn "prologue_movesi_from_cr" 12944 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 12945 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO) 12946 (reg:CC CR4_REGNO)] 12947 UNSPEC_MOVESI_FROM_CR))] 12948 "" 12949 "mfcr %0" 12950 [(set_attr "type" "mfcr")]) 12951 12952(define_insn "*crsave" 12953 [(match_parallel 0 "crsave_operation" 12954 [(set (match_operand:SI 1 "memory_operand" "=m") 12955 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 12956 "" 12957 "stw %2,%1" 12958 [(set_attr "type" "store")]) 12959 12960(define_insn "*stmw" 12961 [(match_parallel 0 "stmw_operation" 12962 [(set (match_operand:SI 1 "memory_operand" "=m") 12963 (match_operand:SI 2 "gpc_reg_operand" "r"))])] 12964 "TARGET_MULTIPLE" 12965 "stmw %2,%1" 12966 [(set_attr "type" "store") 12967 (set_attr "update" "yes") 12968 (set_attr "indexed" "yes")]) 12969 12970; The following comment applies to: 12971; save_gpregs_* 12972; save_fpregs_* 12973; restore_gpregs* 12974; return_and_restore_gpregs* 12975; return_and_restore_fpregs* 12976; return_and_restore_fpregs_aix* 12977; 12978; The out-of-line save / restore functions expects one input argument. 12979; Since those are not standard call_insn's, we must avoid using 12980; MATCH_OPERAND for that argument. That way the register rename 12981; optimization will not try to rename this register. 12982; Each pattern is repeated for each possible register number used in 12983; various ABIs (r11, r1, and for some functions r12) 12984 12985(define_insn "*save_gpregs_<mode>_r11" 12986 [(match_parallel 0 "any_parallel_operand" 12987 [(clobber (reg:P LR_REGNO)) 12988 (use (match_operand:P 1 "symbol_ref_operand" "s")) 12989 (use (reg:P 11)) 12990 (set (match_operand:P 2 "memory_operand" "=m") 12991 (match_operand:P 3 "gpc_reg_operand" "r"))])] 12992 "" 12993 "bl %1" 12994 [(set_attr "type" "branch")]) 12995 12996(define_insn "*save_gpregs_<mode>_r12" 12997 [(match_parallel 0 "any_parallel_operand" 12998 [(clobber (reg:P LR_REGNO)) 12999 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13000 (use (reg:P 12)) 13001 (set (match_operand:P 2 "memory_operand" "=m") 13002 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13003 "" 13004 "bl %1" 13005 [(set_attr "type" "branch")]) 13006 13007(define_insn "*save_gpregs_<mode>_r1" 13008 [(match_parallel 0 "any_parallel_operand" 13009 [(clobber (reg:P LR_REGNO)) 13010 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13011 (use (reg:P 1)) 13012 (set (match_operand:P 2 "memory_operand" "=m") 13013 (match_operand:P 3 "gpc_reg_operand" "r"))])] 13014 "" 13015 "bl %1" 13016 [(set_attr "type" "branch")]) 13017 13018(define_insn "*save_fpregs_<mode>_r11" 13019 [(match_parallel 0 "any_parallel_operand" 13020 [(clobber (reg:P LR_REGNO)) 13021 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13022 (use (reg:P 11)) 13023 (set (match_operand:DF 2 "memory_operand" "=m") 13024 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13025 "" 13026 "bl %1" 13027 [(set_attr "type" "branch")]) 13028 13029(define_insn "*save_fpregs_<mode>_r12" 13030 [(match_parallel 0 "any_parallel_operand" 13031 [(clobber (reg:P LR_REGNO)) 13032 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13033 (use (reg:P 12)) 13034 (set (match_operand:DF 2 "memory_operand" "=m") 13035 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13036 "" 13037 "bl %1" 13038 [(set_attr "type" "branch")]) 13039 13040(define_insn "*save_fpregs_<mode>_r1" 13041 [(match_parallel 0 "any_parallel_operand" 13042 [(clobber (reg:P LR_REGNO)) 13043 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13044 (use (reg:P 1)) 13045 (set (match_operand:DF 2 "memory_operand" "=m") 13046 (match_operand:DF 3 "gpc_reg_operand" "d"))])] 13047 "" 13048 "bl %1" 13049 [(set_attr "type" "branch")]) 13050 13051; This is to explain that changes to the stack pointer should 13052; not be moved over loads from or stores to stack memory. 13053(define_insn "stack_tie" 13054 [(match_parallel 0 "tie_operand" 13055 [(set (mem:BLK (reg 1)) (const_int 0))])] 13056 "" 13057 "" 13058 [(set_attr "length" "0")]) 13059 13060; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to 13061; stay behind all restores from the stack, it cannot be reordered to before 13062; one. See PR77687. This insn is an add or mr, and a memory clobber. 13063(define_insn "stack_restore_tie" 13064 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r") 13065 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r") 13066 (match_operand:SI 2 "reg_or_cint_operand" "O,rI"))) 13067 (set (mem:BLK (scratch)) (const_int 0))] 13068 "TARGET_32BIT" 13069 "@ 13070 mr %0,%1 13071 add%I2 %0,%1,%2" 13072 [(set_attr "type" "*,add")]) 13073 13074(define_expand "epilogue" 13075 [(use (const_int 0))] 13076 "" 13077{ 13078 if (!TARGET_SCHED_PROLOG) 13079 emit_insn (gen_blockage ()); 13080 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL); 13081 DONE; 13082}) 13083 13084; On some processors, doing the mtcrf one CC register at a time is 13085; faster (like on the 604e). On others, doing them all at once is 13086; faster; for instance, on the 601 and 750. 13087 13088(define_expand "movsi_to_cr_one" 13089 [(set (match_operand:CC 0 "cc_reg_operand") 13090 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand") 13091 (match_dup 2)] UNSPEC_MOVESI_TO_CR))] 13092 "" 13093 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));") 13094 13095(define_insn "*movsi_to_cr" 13096 [(match_parallel 0 "mtcrf_operation" 13097 [(set (match_operand:CC 1 "cc_reg_operand" "=y") 13098 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r") 13099 (match_operand 3 "immediate_operand" "n")] 13100 UNSPEC_MOVESI_TO_CR))])] 13101 "" 13102{ 13103 int mask = 0; 13104 int i; 13105 for (i = 0; i < XVECLEN (operands[0], 0); i++) 13106 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1)); 13107 operands[4] = GEN_INT (mask); 13108 return "mtcrf %4,%2"; 13109} 13110 [(set_attr "type" "mtcr")]) 13111 13112(define_insn "*mtcrfsi" 13113 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 13114 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 13115 (match_operand 2 "immediate_operand" "n")] 13116 UNSPEC_MOVESI_TO_CR))] 13117 "REG_P (operands[0]) 13118 && CR_REGNO_P (REGNO (operands[0])) 13119 && CONST_INT_P (operands[2]) 13120 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))" 13121 "mtcrf %R0,%1" 13122 [(set_attr "type" "mtcr")]) 13123 13124; The load-multiple instructions have similar properties. 13125; Note that "load_multiple" is a name known to the machine-independent 13126; code that actually corresponds to the PowerPC load-string. 13127 13128(define_insn "*lmw" 13129 [(match_parallel 0 "lmw_operation" 13130 [(set (match_operand:SI 1 "gpc_reg_operand" "=r") 13131 (match_operand:SI 2 "memory_operand" "m"))])] 13132 "TARGET_MULTIPLE" 13133 "lmw %1,%2" 13134 [(set_attr "type" "load") 13135 (set_attr "update" "yes") 13136 (set_attr "indexed" "yes") 13137 (set_attr "cell_micro" "always")]) 13138 13139; FIXME: "any_parallel_operand" is a bit flexible... 13140 13141; The following comment applies to: 13142; save_gpregs_* 13143; save_fpregs_* 13144; restore_gpregs* 13145; return_and_restore_gpregs* 13146; return_and_restore_fpregs* 13147; return_and_restore_fpregs_aix* 13148; 13149; The out-of-line save / restore functions expects one input argument. 13150; Since those are not standard call_insn's, we must avoid using 13151; MATCH_OPERAND for that argument. That way the register rename 13152; optimization will not try to rename this register. 13153; Each pattern is repeated for each possible register number used in 13154; various ABIs (r11, r1, and for some functions r12) 13155 13156(define_insn "*restore_gpregs_<mode>_r11" 13157 [(match_parallel 0 "any_parallel_operand" 13158 [(clobber (reg:P LR_REGNO)) 13159 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13160 (use (reg:P 11)) 13161 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13162 (match_operand:P 3 "memory_operand" "m"))])] 13163 "" 13164 "bl %1" 13165 [(set_attr "type" "branch")]) 13166 13167(define_insn "*restore_gpregs_<mode>_r12" 13168 [(match_parallel 0 "any_parallel_operand" 13169 [(clobber (reg:P LR_REGNO)) 13170 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13171 (use (reg:P 12)) 13172 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13173 (match_operand:P 3 "memory_operand" "m"))])] 13174 "" 13175 "bl %1" 13176 [(set_attr "type" "branch")]) 13177 13178(define_insn "*restore_gpregs_<mode>_r1" 13179 [(match_parallel 0 "any_parallel_operand" 13180 [(clobber (reg:P LR_REGNO)) 13181 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13182 (use (reg:P 1)) 13183 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13184 (match_operand:P 3 "memory_operand" "m"))])] 13185 "" 13186 "bl %1" 13187 [(set_attr "type" "branch")]) 13188 13189(define_insn "*return_and_restore_gpregs_<mode>_r11" 13190 [(match_parallel 0 "any_parallel_operand" 13191 [(return) 13192 (clobber (reg:P LR_REGNO)) 13193 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13194 (use (reg:P 11)) 13195 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13196 (match_operand:P 3 "memory_operand" "m"))])] 13197 "" 13198 "b %1" 13199 [(set_attr "type" "branch")]) 13200 13201(define_insn "*return_and_restore_gpregs_<mode>_r12" 13202 [(match_parallel 0 "any_parallel_operand" 13203 [(return) 13204 (clobber (reg:P LR_REGNO)) 13205 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13206 (use (reg:P 12)) 13207 (set (match_operand:P 2 "gpc_reg_operand" "=r") 13208 (match_operand:P 3 "memory_operand" "m"))])] 13209 "" 13210 "b %1" 13211 [(set_attr "type" "branch")]) 13212 13213(define_insn "*return_and_restore_gpregs_<mode>_r1" 13214 [(match_parallel 0 "any_parallel_operand" 13215 [(return) 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 "b %1" 13223 [(set_attr "type" "branch")]) 13224 13225(define_insn "*return_and_restore_fpregs_<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:DF 2 "gpc_reg_operand" "=d") 13232 (match_operand:DF 3 "memory_operand" "m"))])] 13233 "" 13234 "b %1" 13235 [(set_attr "type" "branch")]) 13236 13237(define_insn "*return_and_restore_fpregs_<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:DF 2 "gpc_reg_operand" "=d") 13244 (match_operand:DF 3 "memory_operand" "m"))])] 13245 "" 13246 "b %1" 13247 [(set_attr "type" "branch")]) 13248 13249(define_insn "*return_and_restore_fpregs_<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:DF 2 "gpc_reg_operand" "=d") 13256 (match_operand:DF 3 "memory_operand" "m"))])] 13257 "" 13258 "b %1" 13259 [(set_attr "type" "branch")]) 13260 13261(define_insn "*return_and_restore_fpregs_aix_<mode>_r11" 13262 [(match_parallel 0 "any_parallel_operand" 13263 [(return) 13264 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13265 (use (reg:P 11)) 13266 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13267 (match_operand:DF 3 "memory_operand" "m"))])] 13268 "" 13269 "b %1" 13270 [(set_attr "type" "branch")]) 13271 13272(define_insn "*return_and_restore_fpregs_aix_<mode>_r1" 13273 [(match_parallel 0 "any_parallel_operand" 13274 [(return) 13275 (use (match_operand:P 1 "symbol_ref_operand" "s")) 13276 (use (reg:P 1)) 13277 (set (match_operand:DF 2 "gpc_reg_operand" "=d") 13278 (match_operand:DF 3 "memory_operand" "m"))])] 13279 "" 13280 "b %1" 13281 [(set_attr "type" "branch")]) 13282 13283; This is used in compiling the unwind routines. 13284(define_expand "eh_return" 13285 [(use (match_operand 0 "general_operand"))] 13286 "" 13287{ 13288 emit_insn (gen_eh_set_lr (Pmode, operands[0])); 13289 DONE; 13290}) 13291 13292; We can't expand this before we know where the link register is stored. 13293(define_insn_and_split "@eh_set_lr_<mode>" 13294 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR) 13295 (clobber (match_scratch:P 1 "=&b"))] 13296 "" 13297 "#" 13298 "reload_completed" 13299 [(const_int 0)] 13300{ 13301 rs6000_emit_eh_reg_restore (operands[0], operands[1]); 13302 DONE; 13303}) 13304 13305(define_insn "prefetch" 13306 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a") 13307 (match_operand:SI 1 "const_int_operand" "n") 13308 (match_operand:SI 2 "const_int_operand" "n"))] 13309 "" 13310{ 13311 13312 13313 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7). 13314 AIX does not support the dcbtstt and dcbtt extended mnemonics. 13315 The AIX assembler does not support the three operand form of dcbt 13316 and dcbtst on Power 7 (-mpwr7). */ 13317 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE; 13318 13319 if (REG_P (operands[0])) 13320 { 13321 if (INTVAL (operands[1]) == 0) 13322 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16"; 13323 else 13324 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16"; 13325 } 13326 else 13327 { 13328 if (INTVAL (operands[1]) == 0) 13329 return inst_select ? "dcbt %a0" : "dcbt %a0,16"; 13330 else 13331 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16"; 13332 } 13333} 13334 [(set_attr "type" "load")]) 13335 13336;; Handle -fsplit-stack. 13337 13338(define_expand "split_stack_prologue" 13339 [(const_int 0)] 13340 "" 13341{ 13342 rs6000_expand_split_stack_prologue (); 13343 DONE; 13344}) 13345 13346(define_expand "load_split_stack_limit" 13347 [(set (match_operand 0) 13348 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))] 13349 "" 13350{ 13351 emit_insn (gen_rtx_SET (operands[0], 13352 gen_rtx_UNSPEC (Pmode, 13353 gen_rtvec (1, const0_rtx), 13354 UNSPEC_STACK_CHECK))); 13355 DONE; 13356}) 13357 13358(define_insn "load_split_stack_limit_di" 13359 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 13360 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))] 13361 "TARGET_64BIT" 13362 "ld %0,-0x7040(13)" 13363 [(set_attr "type" "load") 13364 (set_attr "update" "no") 13365 (set_attr "indexed" "no")]) 13366 13367(define_insn "load_split_stack_limit_si" 13368 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 13369 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))] 13370 "!TARGET_64BIT" 13371 "lwz %0,-0x7020(2)" 13372 [(set_attr "type" "load") 13373 (set_attr "update" "no") 13374 (set_attr "indexed" "no")]) 13375 13376;; A return instruction which the middle-end doesn't see. 13377;; Use r0 to stop regrename twiddling with lr restore insns emitted 13378;; after the call to __morestack. 13379(define_insn "split_stack_return" 13380 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)] 13381 "" 13382 "blr" 13383 [(set_attr "type" "jmpreg")]) 13384 13385;; If there are operand 0 bytes available on the stack, jump to 13386;; operand 1. 13387(define_expand "split_stack_space_check" 13388 [(set (match_dup 2) 13389 (unspec [(const_int 0)] UNSPEC_STACK_CHECK)) 13390 (set (match_dup 3) 13391 (minus (reg STACK_POINTER_REGNUM) 13392 (match_operand 0))) 13393 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2))) 13394 (set (pc) (if_then_else 13395 (geu (match_dup 4) (const_int 0)) 13396 (label_ref (match_operand 1)) 13397 (pc)))] 13398 "" 13399{ 13400 rs6000_split_stack_space_check (operands[0], operands[1]); 13401 DONE; 13402}) 13403 13404(define_insn "bpermd_<mode>" 13405 [(set (match_operand:P 0 "gpc_reg_operand" "=r") 13406 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r") 13407 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))] 13408 "TARGET_POPCNTD" 13409 "bpermd %0,%1,%2" 13410 [(set_attr "type" "popcnt")]) 13411 13412 13413;; Builtin fma support. Handle 13414;; Note that the conditions for expansion are in the FMA_F iterator. 13415 13416(define_expand "fma<mode>4" 13417 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13418 (fma:FMA_F 13419 (match_operand:FMA_F 1 "gpc_reg_operand") 13420 (match_operand:FMA_F 2 "gpc_reg_operand") 13421 (match_operand:FMA_F 3 "gpc_reg_operand")))] 13422 "" 13423 "") 13424 13425(define_insn "*fma<mode>4_fpr" 13426 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 13427 (fma:SFDF 13428 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa") 13429 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 13430 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))] 13431 "TARGET_HARD_FLOAT" 13432 "@ 13433 fmadd<s> %0,%1,%2,%3 13434 xsmadda<sd>p %x0,%x1,%x2 13435 xsmaddm<sd>p %x0,%x1,%x3" 13436 [(set_attr "type" "fp") 13437 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 13438 13439; Altivec only has fma and nfms. 13440(define_expand "fms<mode>4" 13441 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13442 (fma:FMA_F 13443 (match_operand:FMA_F 1 "gpc_reg_operand") 13444 (match_operand:FMA_F 2 "gpc_reg_operand") 13445 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))] 13446 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13447 "") 13448 13449(define_insn "*fms<mode>4_fpr" 13450 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 13451 (fma:SFDF 13452 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa") 13453 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 13454 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))] 13455 "TARGET_HARD_FLOAT" 13456 "@ 13457 fmsub<s> %0,%1,%2,%3 13458 xsmsuba<sd>p %x0,%x1,%x2 13459 xsmsubm<sd>p %x0,%x1,%x3" 13460 [(set_attr "type" "fp") 13461 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 13462 13463;; If signed zeros are ignored, -(a * b - c) = -a * b + c. 13464(define_expand "fnma<mode>4" 13465 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13466 (neg:FMA_F 13467 (fma:FMA_F 13468 (match_operand:FMA_F 1 "gpc_reg_operand") 13469 (match_operand:FMA_F 2 "gpc_reg_operand") 13470 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))] 13471 "!HONOR_SIGNED_ZEROS (<MODE>mode)" 13472 "") 13473 13474;; If signed zeros are ignored, -(a * b + c) = -a * b - c. 13475(define_expand "fnms<mode>4" 13476 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13477 (neg:FMA_F 13478 (fma:FMA_F 13479 (match_operand:FMA_F 1 "gpc_reg_operand") 13480 (match_operand:FMA_F 2 "gpc_reg_operand") 13481 (match_operand:FMA_F 3 "gpc_reg_operand"))))] 13482 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13483 "") 13484 13485; Not an official optab name, but used from builtins. 13486(define_expand "nfma<mode>4" 13487 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13488 (neg:FMA_F 13489 (fma:FMA_F 13490 (match_operand:FMA_F 1 "gpc_reg_operand") 13491 (match_operand:FMA_F 2 "gpc_reg_operand") 13492 (match_operand:FMA_F 3 "gpc_reg_operand"))))] 13493 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)" 13494 "") 13495 13496(define_insn "*nfma<mode>4_fpr" 13497 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 13498 (neg:SFDF 13499 (fma:SFDF 13500 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa") 13501 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 13502 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))] 13503 "TARGET_HARD_FLOAT" 13504 "@ 13505 fnmadd<s> %0,%1,%2,%3 13506 xsnmadda<sd>p %x0,%x1,%x2 13507 xsnmaddm<sd>p %x0,%x1,%x3" 13508 [(set_attr "type" "fp") 13509 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 13510 13511; Not an official optab name, but used from builtins. 13512(define_expand "nfms<mode>4" 13513 [(set (match_operand:FMA_F 0 "gpc_reg_operand") 13514 (neg:FMA_F 13515 (fma:FMA_F 13516 (match_operand:FMA_F 1 "gpc_reg_operand") 13517 (match_operand:FMA_F 2 "gpc_reg_operand") 13518 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))] 13519 "" 13520 "") 13521 13522(define_insn "*nfmssf4_fpr" 13523 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa") 13524 (neg:SFDF 13525 (fma:SFDF 13526 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa") 13527 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0") 13528 (neg:SFDF 13529 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))] 13530 "TARGET_HARD_FLOAT" 13531 "@ 13532 fnmsub<s> %0,%1,%2,%3 13533 xsnmsuba<sd>p %x0,%x1,%x2 13534 xsnmsubm<sd>p %x0,%x1,%x3" 13535 [(set_attr "type" "fp") 13536 (set_attr "isa" "*,<Fisa>,<Fisa>")]) 13537 13538(define_expand "rs6000_get_timebase" 13539 [(use (match_operand:DI 0 "gpc_reg_operand"))] 13540 "" 13541{ 13542 if (TARGET_POWERPC64) 13543 emit_insn (gen_rs6000_mftb_di (operands[0])); 13544 else 13545 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0])); 13546 DONE; 13547}) 13548 13549(define_insn "rs6000_get_timebase_ppc32" 13550 [(set (match_operand:DI 0 "gpc_reg_operand" "=r") 13551 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB)) 13552 (clobber (match_scratch:SI 1 "=r")) 13553 (clobber (match_scratch:CC 2 "=y"))] 13554 "!TARGET_POWERPC64" 13555{ 13556 if (WORDS_BIG_ENDIAN) 13557 if (TARGET_MFCRF) 13558 { 13559 return "mfspr %0,269\;" 13560 "mfspr %L0,268\;" 13561 "mfspr %1,269\;" 13562 "cmpw %2,%0,%1\;" 13563 "bne- %2,$-16"; 13564 } 13565 else 13566 { 13567 return "mftbu %0\;" 13568 "mftb %L0\;" 13569 "mftbu %1\;" 13570 "cmpw %2,%0,%1\;" 13571 "bne- %2,$-16"; 13572 } 13573 else 13574 if (TARGET_MFCRF) 13575 { 13576 return "mfspr %L0,269\;" 13577 "mfspr %0,268\;" 13578 "mfspr %1,269\;" 13579 "cmpw %2,%L0,%1\;" 13580 "bne- %2,$-16"; 13581 } 13582 else 13583 { 13584 return "mftbu %L0\;" 13585 "mftb %0\;" 13586 "mftbu %1\;" 13587 "cmpw %2,%L0,%1\;" 13588 "bne- %2,$-16"; 13589 } 13590} 13591 [(set_attr "length" "20")]) 13592 13593(define_insn "rs6000_mftb_<mode>" 13594 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r") 13595 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))] 13596 "" 13597{ 13598 if (TARGET_MFCRF) 13599 return "mfspr %0,268"; 13600 else 13601 return "mftb %0"; 13602}) 13603 13604 13605;; The ISA 3.0 mffsl instruction is a lower latency instruction 13606;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR. 13607(define_insn "rs6000_mffsl_hw" 13608 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 13609 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))] 13610 "TARGET_HARD_FLOAT" 13611 "mffsl %0") 13612 13613(define_expand "rs6000_mffsl" 13614 [(set (match_operand:DF 0 "gpc_reg_operand") 13615 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))] 13616 "TARGET_HARD_FLOAT" 13617{ 13618 /* If the low latency mffsl instruction (ISA 3.0) is available use it, 13619 otherwise fall back to the older mffs instruction to emulate the mffsl 13620 instruction. */ 13621 13622 if (!TARGET_P9_MISC) 13623 { 13624 rtx tmp1 = gen_reg_rtx (DFmode); 13625 13626 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl 13627 instruction using the mffs instruction and masking the result. */ 13628 emit_insn (gen_rs6000_mffs (tmp1)); 13629 13630 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0); 13631 rtx tmp2 = gen_reg_rtx (DImode); 13632 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL))); 13633 13634 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0); 13635 emit_move_insn (operands[0], tmp2df); 13636 DONE; 13637 } 13638 13639 emit_insn (gen_rs6000_mffsl_hw (operands[0])); 13640 DONE; 13641}) 13642 13643(define_insn "rs6000_mffs" 13644 [(set (match_operand:DF 0 "gpc_reg_operand" "=d") 13645 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))] 13646 "TARGET_HARD_FLOAT" 13647 "mffs %0") 13648 13649(define_insn "rs6000_mtfsf" 13650 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i") 13651 (match_operand:DF 1 "gpc_reg_operand" "d")] 13652 UNSPECV_MTFSF)] 13653 "TARGET_HARD_FLOAT" 13654 "mtfsf %0,%1") 13655 13656(define_insn "rs6000_mtfsf_hi" 13657 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n") 13658 (match_operand:DF 1 "gpc_reg_operand" "d")] 13659 UNSPECV_MTFSF_HI)] 13660 "TARGET_HARD_FLOAT" 13661 "mtfsf %0,%1,0,1") 13662 13663 13664;; Power8 fusion support for fusing an addis instruction with a D-form load of 13665;; a GPR. The addis instruction must be adjacent to the load, and use the same 13666;; register that is being loaded. The fused ops must be physically adjacent. 13667 13668;; On Power8 GPR loads, we try to use the register that is being load. The 13669;; peephole2 then gathers any other fused possibilities that it can find after 13670;; register allocation. If power9 fusion is selected, we also fuse floating 13671;; point loads/stores. 13672 13673;; Find cases where the addis that feeds into a load instruction is either used 13674;; once or is the same as the target register, and replace it with the fusion 13675;; insn 13676 13677(define_peephole2 13678 [(set (match_operand:P 0 "base_reg_operand") 13679 (match_operand:P 1 "fusion_gpr_addis")) 13680 (set (match_operand:INT1 2 "base_reg_operand") 13681 (match_operand:INT1 3 "fusion_gpr_mem_load"))] 13682 "TARGET_P8_FUSION 13683 && fusion_gpr_load_p (operands[0], operands[1], operands[2], 13684 operands[3])" 13685 [(const_int 0)] 13686{ 13687 expand_fusion_gpr_load (operands); 13688 DONE; 13689}) 13690 13691;; Fusion insn, created by the define_peephole2 above (and eventually by 13692;; reload) 13693 13694(define_insn "*fusion_gpr_load_<mode>" 13695 [(set (match_operand:INT1 0 "base_reg_operand" "=b") 13696 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")] 13697 UNSPEC_FUSION_GPR))] 13698 "TARGET_P8_FUSION" 13699{ 13700 return emit_fusion_gpr_load (operands[0], operands[1]); 13701} 13702 [(set_attr "type" "load") 13703 (set_attr "length" "8")]) 13704 13705 13706;; Optimize cases where we want to do a D-form load (register+offset) on 13707;; ISA 2.06/2.07 to an Altivec register, and the register allocator 13708;; has generated: 13709;; LFD 0,32(3) 13710;; XXLOR 32,0,0 13711;; 13712;; and we change this to: 13713;; LI 0,32 13714;; LXSDX 32,3,9 13715 13716(define_peephole2 13717 [(match_scratch:P 0 "b") 13718 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand") 13719 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand")) 13720 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand") 13721 (match_dup 1))] 13722 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])" 13723 [(set (match_dup 0) 13724 (match_dup 4)) 13725 (set (match_dup 3) 13726 (match_dup 5))] 13727{ 13728 rtx tmp_reg = operands[0]; 13729 rtx mem = operands[2]; 13730 rtx addr = XEXP (mem, 0); 13731 rtx add_op0, add_op1, new_addr; 13732 13733 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM); 13734 add_op0 = XEXP (addr, 0); 13735 add_op1 = XEXP (addr, 1); 13736 gcc_assert (REG_P (add_op0)); 13737 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg); 13738 13739 operands[4] = add_op1; 13740 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr); 13741}) 13742 13743;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an 13744;; Altivec register, and the register allocator has generated: 13745;; XXLOR 0,32,32 13746;; STFD 0,32(3) 13747;; 13748;; and we change this to: 13749;; LI 0,32 13750;; STXSDX 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 "altivec_register_operand")) 13756 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_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 5) 13762 (match_dup 2))] 13763{ 13764 rtx tmp_reg = operands[0]; 13765 rtx mem = operands[3]; 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 13780;; Miscellaneous ISA 2.06 (power7) instructions 13781(define_insn "addg6s" 13782 [(set (match_operand:SI 0 "register_operand" "=r") 13783 (unspec:SI [(match_operand:SI 1 "register_operand" "r") 13784 (match_operand:SI 2 "register_operand" "r")] 13785 UNSPEC_ADDG6S))] 13786 "TARGET_POPCNTD" 13787 "addg6s %0,%1,%2" 13788 [(set_attr "type" "integer")]) 13789 13790(define_insn "cdtbcd" 13791 [(set (match_operand:SI 0 "register_operand" "=r") 13792 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 13793 UNSPEC_CDTBCD))] 13794 "TARGET_POPCNTD" 13795 "cdtbcd %0,%1" 13796 [(set_attr "type" "integer")]) 13797 13798(define_insn "cbcdtd" 13799 [(set (match_operand:SI 0 "register_operand" "=r") 13800 (unspec:SI [(match_operand:SI 1 "register_operand" "r")] 13801 UNSPEC_CBCDTD))] 13802 "TARGET_POPCNTD" 13803 "cbcdtd %0,%1" 13804 [(set_attr "type" "integer")]) 13805 13806(define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE 13807 UNSPEC_DIVEU]) 13808 13809(define_int_attr div_extend [(UNSPEC_DIVE "e") 13810 (UNSPEC_DIVEU "eu")]) 13811 13812(define_insn "div<div_extend>_<mode>" 13813 [(set (match_operand:GPR 0 "register_operand" "=r") 13814 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r") 13815 (match_operand:GPR 2 "register_operand" "r")] 13816 UNSPEC_DIV_EXTEND))] 13817 "TARGET_POPCNTD" 13818 "div<wd><div_extend> %0,%1,%2" 13819 [(set_attr "type" "div") 13820 (set_attr "size" "<bits>")]) 13821 13822 13823;; Pack/unpack 128-bit floating point types that take 2 scalar registers 13824 13825; Type of the 64-bit part when packing/unpacking 128-bit floating point types 13826(define_mode_attr FP128_64 [(TF "DF") 13827 (IF "DF") 13828 (TD "DI") 13829 (KF "DI")]) 13830 13831(define_expand "unpack<mode>" 13832 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand") 13833 (unspec:<FP128_64> 13834 [(match_operand:FMOVE128 1 "register_operand") 13835 (match_operand:QI 2 "const_0_to_1_operand")] 13836 UNSPEC_UNPACK_128BIT))] 13837 "FLOAT128_2REG_P (<MODE>mode)" 13838 "") 13839 13840(define_insn_and_split "unpack<mode>_dm" 13841 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m") 13842 (unspec:<FP128_64> 13843 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r") 13844 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")] 13845 UNSPEC_UNPACK_128BIT))] 13846 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)" 13847 "#" 13848 "&& reload_completed" 13849 [(set (match_dup 0) (match_dup 3))] 13850{ 13851 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 13852 13853 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 13854 { 13855 emit_note (NOTE_INSN_DELETED); 13856 DONE; 13857 } 13858 13859 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 13860} 13861 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")]) 13862 13863(define_insn_and_split "unpack<mode>_nodm" 13864 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m") 13865 (unspec:<FP128_64> 13866 [(match_operand:FMOVE128 1 "register_operand" "d,d") 13867 (match_operand:QI 2 "const_0_to_1_operand" "i,i")] 13868 UNSPEC_UNPACK_128BIT))] 13869 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)" 13870 "#" 13871 "&& reload_completed" 13872 [(set (match_dup 0) (match_dup 3))] 13873{ 13874 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]); 13875 13876 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno) 13877 { 13878 emit_note (NOTE_INSN_DELETED); 13879 DONE; 13880 } 13881 13882 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno); 13883} 13884 [(set_attr "type" "fp,fpstore")]) 13885 13886(define_insn_and_split "pack<mode>" 13887 [(set (match_operand:FMOVE128 0 "register_operand" "=&d") 13888 (unspec:FMOVE128 13889 [(match_operand:<FP128_64> 1 "register_operand" "d") 13890 (match_operand:<FP128_64> 2 "register_operand" "d")] 13891 UNSPEC_PACK_128BIT))] 13892 "FLOAT128_2REG_P (<MODE>mode)" 13893 "#" 13894 "&& reload_completed" 13895 [(set (match_dup 3) (match_dup 1)) 13896 (set (match_dup 4) (match_dup 2))] 13897{ 13898 unsigned dest_hi = REGNO (operands[0]); 13899 unsigned dest_lo = dest_hi + 1; 13900 13901 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo)); 13902 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo)); 13903 13904 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi); 13905 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo); 13906} 13907 [(set_attr "type" "fp") 13908 (set_attr "length" "8")]) 13909 13910(define_insn "unpack<mode>" 13911 [(set (match_operand:DI 0 "register_operand" "=wa,wa") 13912 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa") 13913 (match_operand:QI 2 "const_0_to_1_operand" "O,i")] 13914 UNSPEC_UNPACK_128BIT))] 13915 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)" 13916{ 13917 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0) 13918 return ASM_COMMENT_START " xxpermdi to same register"; 13919 13920 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3); 13921 return "xxpermdi %x0,%x1,%x1,%3"; 13922} 13923 [(set_attr "type" "vecperm")]) 13924 13925(define_insn "pack<mode>" 13926 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa") 13927 (unspec:FMOVE128_VSX 13928 [(match_operand:DI 1 "register_operand" "wa") 13929 (match_operand:DI 2 "register_operand" "wa")] 13930 UNSPEC_PACK_128BIT))] 13931 "TARGET_VSX" 13932 "xxpermdi %x0,%x1,%x2,0" 13933 [(set_attr "type" "vecperm")]) 13934 13935 13936 13937;; ISA 2.08 IEEE 128-bit floating point support. 13938 13939(define_insn "add<mode>3" 13940 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13941 (plus:IEEE128 13942 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13943 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13944 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13945 "xsaddqp %0,%1,%2" 13946 [(set_attr "type" "vecfloat") 13947 (set_attr "size" "128")]) 13948 13949(define_insn "sub<mode>3" 13950 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13951 (minus:IEEE128 13952 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13953 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13954 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13955 "xssubqp %0,%1,%2" 13956 [(set_attr "type" "vecfloat") 13957 (set_attr "size" "128")]) 13958 13959(define_insn "mul<mode>3" 13960 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13961 (mult:IEEE128 13962 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13963 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13964 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13965 "xsmulqp %0,%1,%2" 13966 [(set_attr "type" "qmul") 13967 (set_attr "size" "128")]) 13968 13969(define_insn "div<mode>3" 13970 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13971 (div:IEEE128 13972 (match_operand:IEEE128 1 "altivec_register_operand" "v") 13973 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 13974 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13975 "xsdivqp %0,%1,%2" 13976 [(set_attr "type" "vecdiv") 13977 (set_attr "size" "128")]) 13978 13979(define_insn "sqrt<mode>2" 13980 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 13981 (sqrt:IEEE128 13982 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 13983 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 13984 "xssqrtqp %0,%1" 13985 [(set_attr "type" "vecdiv") 13986 (set_attr "size" "128")]) 13987 13988(define_expand "copysign<mode>3" 13989 [(use (match_operand:IEEE128 0 "altivec_register_operand")) 13990 (use (match_operand:IEEE128 1 "altivec_register_operand")) 13991 (use (match_operand:IEEE128 2 "altivec_register_operand"))] 13992 "FLOAT128_IEEE_P (<MODE>mode)" 13993{ 13994 if (TARGET_FLOAT128_HW) 13995 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1], 13996 operands[2])); 13997 else 13998 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1], 13999 operands[2])); 14000 DONE; 14001}) 14002 14003(define_insn "copysign<mode>3_hard" 14004 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14005 (unspec:IEEE128 14006 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14007 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14008 UNSPEC_COPYSIGN))] 14009 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14010 "xscpsgnqp %0,%2,%1" 14011 [(set_attr "type" "vecmove") 14012 (set_attr "size" "128")]) 14013 14014(define_insn "copysign<mode>3_soft" 14015 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14016 (unspec:IEEE128 14017 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14018 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14019 UNSPEC_COPYSIGN)) 14020 (clobber (match_scratch:IEEE128 3 "=&v"))] 14021 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14022 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1" 14023 [(set_attr "type" "veccomplex") 14024 (set_attr "length" "8")]) 14025 14026(define_insn "@neg<mode>2_hw" 14027 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14028 (neg:IEEE128 14029 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14030 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14031 "xsnegqp %0,%1" 14032 [(set_attr "type" "vecmove") 14033 (set_attr "size" "128")]) 14034 14035 14036(define_insn "@abs<mode>2_hw" 14037 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14038 (abs:IEEE128 14039 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14040 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14041 "xsabsqp %0,%1" 14042 [(set_attr "type" "vecmove") 14043 (set_attr "size" "128")]) 14044 14045 14046(define_insn "*nabs<mode>2_hw" 14047 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14048 (neg:IEEE128 14049 (abs:IEEE128 14050 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))] 14051 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14052 "xsnabsqp %0,%1" 14053 [(set_attr "type" "vecmove") 14054 (set_attr "size" "128")]) 14055 14056;; Initially don't worry about doing fusion 14057(define_insn "fma<mode>4_hw" 14058 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14059 (fma:IEEE128 14060 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14061 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14062 (match_operand:IEEE128 3 "altivec_register_operand" "0")))] 14063 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14064 "xsmaddqp %0,%1,%2" 14065 [(set_attr "type" "qmul") 14066 (set_attr "size" "128")]) 14067 14068(define_insn "*fms<mode>4_hw" 14069 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14070 (fma:IEEE128 14071 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14072 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14073 (neg:IEEE128 14074 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 14075 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14076 "xsmsubqp %0,%1,%2" 14077 [(set_attr "type" "qmul") 14078 (set_attr "size" "128")]) 14079 14080(define_insn "*nfma<mode>4_hw" 14081 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14082 (neg:IEEE128 14083 (fma:IEEE128 14084 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14085 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14086 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))] 14087 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14088 "xsnmaddqp %0,%1,%2" 14089 [(set_attr "type" "qmul") 14090 (set_attr "size" "128")]) 14091 14092(define_insn "*nfms<mode>4_hw" 14093 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14094 (neg:IEEE128 14095 (fma:IEEE128 14096 (match_operand:IEEE128 1 "altivec_register_operand" "%v") 14097 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14098 (neg:IEEE128 14099 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))] 14100 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14101 "xsnmsubqp %0,%1,%2" 14102 [(set_attr "type" "qmul") 14103 (set_attr "size" "128")]) 14104 14105(define_insn "extend<SFDF:mode><IEEE128:mode>2_hw" 14106 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14107 (float_extend:IEEE128 14108 (match_operand:SFDF 1 "altivec_register_operand" "v")))] 14109 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14110 "xscvdpqp %0,%1" 14111 [(set_attr "type" "vecfloat") 14112 (set_attr "size" "128")]) 14113 14114;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating 14115;; point is a simple copy. 14116(define_insn_and_split "extendkftf2" 14117 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa") 14118 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))] 14119 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD" 14120 "@ 14121 # 14122 xxlor %x0,%x1,%x1" 14123 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 14124 [(const_int 0)] 14125{ 14126 emit_note (NOTE_INSN_DELETED); 14127 DONE; 14128} 14129 [(set_attr "type" "*,veclogical") 14130 (set_attr "length" "0,4")]) 14131 14132(define_insn_and_split "trunctfkf2" 14133 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa") 14134 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))] 14135 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD" 14136 "@ 14137 # 14138 xxlor %x0,%x1,%x1" 14139 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])" 14140 [(const_int 0)] 14141{ 14142 emit_note (NOTE_INSN_DELETED); 14143 DONE; 14144} 14145 [(set_attr "type" "*,veclogical") 14146 (set_attr "length" "0,4")]) 14147 14148(define_insn "trunc<mode>df2_hw" 14149 [(set (match_operand:DF 0 "altivec_register_operand" "=v") 14150 (float_truncate:DF 14151 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14152 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14153 "xscvqpdp %0,%1" 14154 [(set_attr "type" "vecfloat") 14155 (set_attr "size" "128")]) 14156 14157;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing 14158;; the KFmode -> DFmode conversion using round to odd rather than the normal 14159;; conversion 14160(define_insn_and_split "trunc<mode>sf2_hw" 14161 [(set (match_operand:SF 0 "vsx_register_operand" "=wa") 14162 (float_truncate:SF 14163 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 14164 (clobber (match_scratch:DF 2 "=v"))] 14165 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14166 "#" 14167 "&& 1" 14168 [(set (match_dup 2) 14169 (unspec:DF [(match_dup 1)] 14170 UNSPEC_TRUNC_ROUND_TO_ODD)) 14171 (set (match_dup 0) 14172 (float_truncate:SF (match_dup 2)))] 14173{ 14174 if (GET_CODE (operands[2]) == SCRATCH) 14175 operands[2] = gen_reg_rtx (DFmode); 14176} 14177 [(set_attr "type" "vecfloat") 14178 (set_attr "length" "8") 14179 (set_attr "isa" "p8v")]) 14180 14181;; Conversion between IEEE 128-bit and integer types 14182 14183;; The fix function for DImode and SImode was declared earlier as a 14184;; define_expand. It calls into rs6000_expand_float128_convert if we don't 14185;; have IEEE 128-bit hardware support. QImode and HImode are not provided 14186;; unless we have the IEEE 128-bit hardware. 14187;; 14188;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have 14189;; to provide a GPR target that used direct move and a conversion in the GPR 14190;; which works around QImode/HImode not being allowed in vector registers in 14191;; ISA 2.07 (power8). 14192(define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw" 14193 [(set (match_operand:SDI 0 "altivec_register_operand" "=v") 14194 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14195 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14196 "xscvqp<su><wd>z %0,%1" 14197 [(set_attr "type" "vecfloat") 14198 (set_attr "size" "128")]) 14199 14200(define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2" 14201 [(set (match_operand:QHI 0 "altivec_register_operand" "=v") 14202 (any_fix:QHI 14203 (match_operand:IEEE128 1 "altivec_register_operand" "v")))] 14204 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14205 "xscvqp<su>wz %0,%1" 14206 [(set_attr "type" "vecfloat") 14207 (set_attr "size" "128")]) 14208 14209;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit 14210;; floating point value to 8/16/32-bit integer to GPR in order to save it. 14211(define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem" 14212 [(set (match_operand:QHSI 0 "memory_operand" "=Z") 14213 (any_fix:QHSI 14214 (match_operand:IEEE128 1 "altivec_register_operand" "v"))) 14215 (clobber (match_scratch:QHSI 2 "=v"))] 14216 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14217 "#" 14218 "&& reload_completed" 14219 [(set (match_dup 2) 14220 (any_fix:QHSI (match_dup 1))) 14221 (set (match_dup 0) 14222 (match_dup 2))]) 14223 14224(define_insn "float_<mode>di2_hw" 14225 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14226 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))] 14227 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14228 "xscvsdqp %0,%1" 14229 [(set_attr "type" "vecfloat") 14230 (set_attr "size" "128")]) 14231 14232(define_insn_and_split "float_<mode>si2_hw" 14233 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14234 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ"))) 14235 (clobber (match_scratch:DI 2 "=v"))] 14236 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14237 "#" 14238 "&& 1" 14239 [(set (match_dup 2) 14240 (sign_extend:DI (match_dup 1))) 14241 (set (match_dup 0) 14242 (float:IEEE128 (match_dup 2)))] 14243{ 14244 if (GET_CODE (operands[2]) == SCRATCH) 14245 operands[2] = gen_reg_rtx (DImode); 14246 14247 if (MEM_P (operands[1])) 14248 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 14249}) 14250 14251(define_insn_and_split "float<QHI:mode><IEEE128:mode>2" 14252 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 14253 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) 14254 (clobber (match_scratch:DI 2 "=X,r,X"))] 14255 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14256 "#" 14257 "&& reload_completed" 14258 [(const_int 0)] 14259{ 14260 rtx dest = operands[0]; 14261 rtx src = operands[1]; 14262 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest)); 14263 14264 if (altivec_register_operand (src, <QHI:MODE>mode)) 14265 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src)); 14266 else if (int_reg_operand (src, <QHI:MODE>mode)) 14267 { 14268 rtx ext_di = operands[2]; 14269 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src)); 14270 emit_move_insn (dest_di, ext_di); 14271 } 14272 else if (MEM_P (src)) 14273 { 14274 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest)); 14275 emit_move_insn (dest_qhi, src); 14276 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi)); 14277 } 14278 else 14279 gcc_unreachable (); 14280 14281 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di)); 14282 DONE; 14283} 14284 [(set_attr "length" "8,12,12") 14285 (set_attr "type" "vecfloat") 14286 (set_attr "size" "128")]) 14287 14288(define_insn "floatuns_<mode>di2_hw" 14289 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14290 (unsigned_float:IEEE128 14291 (match_operand:DI 1 "altivec_register_operand" "v")))] 14292 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14293 "xscvudqp %0,%1" 14294 [(set_attr "type" "vecfloat") 14295 (set_attr "size" "128")]) 14296 14297(define_insn_and_split "floatuns_<mode>si2_hw" 14298 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14299 (unsigned_float:IEEE128 14300 (match_operand:SI 1 "nonimmediate_operand" "vrZ"))) 14301 (clobber (match_scratch:DI 2 "=v"))] 14302 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14303 "#" 14304 "&& 1" 14305 [(set (match_dup 2) 14306 (zero_extend:DI (match_dup 1))) 14307 (set (match_dup 0) 14308 (float:IEEE128 (match_dup 2)))] 14309{ 14310 if (GET_CODE (operands[2]) == SCRATCH) 14311 operands[2] = gen_reg_rtx (DImode); 14312 14313 if (MEM_P (operands[1])) 14314 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]); 14315}) 14316 14317(define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2" 14318 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v") 14319 (unsigned_float:IEEE128 14320 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z"))) 14321 (clobber (match_scratch:DI 2 "=X,r,X"))] 14322 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)" 14323 "#" 14324 "&& reload_completed" 14325 [(const_int 0)] 14326{ 14327 rtx dest = operands[0]; 14328 rtx src = operands[1]; 14329 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest)); 14330 14331 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src)) 14332 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src)); 14333 else if (int_reg_operand (src, <QHI:MODE>mode)) 14334 { 14335 rtx ext_di = operands[2]; 14336 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src)); 14337 emit_move_insn (dest_di, ext_di); 14338 } 14339 else 14340 gcc_unreachable (); 14341 14342 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di)); 14343 DONE; 14344} 14345 [(set_attr "length" "8,12,8") 14346 (set_attr "type" "vecfloat") 14347 (set_attr "size" "128")]) 14348 14349;; IEEE 128-bit round to integer built-in functions 14350(define_insn "floor<mode>2" 14351 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14352 (unspec:IEEE128 14353 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14354 UNSPEC_FRIM))] 14355 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14356 "xsrqpi 1,%0,%1,3" 14357 [(set_attr "type" "vecfloat") 14358 (set_attr "size" "128")]) 14359 14360(define_insn "ceil<mode>2" 14361 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14362 (unspec:IEEE128 14363 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14364 UNSPEC_FRIP))] 14365 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14366 "xsrqpi 1,%0,%1,2" 14367 [(set_attr "type" "vecfloat") 14368 (set_attr "size" "128")]) 14369 14370(define_insn "btrunc<mode>2" 14371 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14372 (unspec:IEEE128 14373 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14374 UNSPEC_FRIZ))] 14375 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14376 "xsrqpi 1,%0,%1,1" 14377 [(set_attr "type" "vecfloat") 14378 (set_attr "size" "128")]) 14379 14380(define_insn "round<mode>2" 14381 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14382 (unspec:IEEE128 14383 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14384 UNSPEC_FRIN))] 14385 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14386 "xsrqpi 0,%0,%1,0" 14387 [(set_attr "type" "vecfloat") 14388 (set_attr "size" "128")]) 14389 14390;; IEEE 128-bit instructions with round to odd semantics 14391(define_insn "add<mode>3_odd" 14392 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14393 (unspec:IEEE128 14394 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14395 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14396 UNSPEC_ADD_ROUND_TO_ODD))] 14397 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14398 "xsaddqpo %0,%1,%2" 14399 [(set_attr "type" "vecfloat") 14400 (set_attr "size" "128")]) 14401 14402(define_insn "sub<mode>3_odd" 14403 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14404 (unspec:IEEE128 14405 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14406 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14407 UNSPEC_SUB_ROUND_TO_ODD))] 14408 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14409 "xssubqpo %0,%1,%2" 14410 [(set_attr "type" "vecfloat") 14411 (set_attr "size" "128")]) 14412 14413(define_insn "mul<mode>3_odd" 14414 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14415 (unspec:IEEE128 14416 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14417 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14418 UNSPEC_MUL_ROUND_TO_ODD))] 14419 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14420 "xsmulqpo %0,%1,%2" 14421 [(set_attr "type" "qmul") 14422 (set_attr "size" "128")]) 14423 14424(define_insn "div<mode>3_odd" 14425 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14426 (unspec:IEEE128 14427 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14428 (match_operand:IEEE128 2 "altivec_register_operand" "v")] 14429 UNSPEC_DIV_ROUND_TO_ODD))] 14430 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14431 "xsdivqpo %0,%1,%2" 14432 [(set_attr "type" "vecdiv") 14433 (set_attr "size" "128")]) 14434 14435(define_insn "sqrt<mode>2_odd" 14436 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14437 (unspec:IEEE128 14438 [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14439 UNSPEC_SQRT_ROUND_TO_ODD))] 14440 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14441 "xssqrtqpo %0,%1" 14442 [(set_attr "type" "vecdiv") 14443 (set_attr "size" "128")]) 14444 14445(define_insn "fma<mode>4_odd" 14446 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14447 (unspec:IEEE128 14448 [(match_operand:IEEE128 1 "altivec_register_operand" "v") 14449 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14450 (match_operand:IEEE128 3 "altivec_register_operand" "0")] 14451 UNSPEC_FMA_ROUND_TO_ODD))] 14452 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14453 "xsmaddqpo %0,%1,%2" 14454 [(set_attr "type" "qmul") 14455 (set_attr "size" "128")]) 14456 14457(define_insn "*fms<mode>4_odd" 14458 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14459 (unspec:IEEE128 14460 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 14461 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14462 (neg:IEEE128 14463 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] 14464 UNSPEC_FMA_ROUND_TO_ODD))] 14465 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14466 "xsmsubqpo %0,%1,%2" 14467 [(set_attr "type" "qmul") 14468 (set_attr "size" "128")]) 14469 14470(define_insn "*nfma<mode>4_odd" 14471 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14472 (neg:IEEE128 14473 (unspec:IEEE128 14474 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 14475 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14476 (match_operand:IEEE128 3 "altivec_register_operand" "0")] 14477 UNSPEC_FMA_ROUND_TO_ODD)))] 14478 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14479 "xsnmaddqpo %0,%1,%2" 14480 [(set_attr "type" "qmul") 14481 (set_attr "size" "128")]) 14482 14483(define_insn "*nfms<mode>4_odd" 14484 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v") 14485 (neg:IEEE128 14486 (unspec:IEEE128 14487 [(match_operand:IEEE128 1 "altivec_register_operand" "%v") 14488 (match_operand:IEEE128 2 "altivec_register_operand" "v") 14489 (neg:IEEE128 14490 (match_operand:IEEE128 3 "altivec_register_operand" "0"))] 14491 UNSPEC_FMA_ROUND_TO_ODD)))] 14492 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14493 "xsnmsubqpo %0,%1,%2" 14494 [(set_attr "type" "qmul") 14495 (set_attr "size" "128")]) 14496 14497(define_insn "trunc<mode>df2_odd" 14498 [(set (match_operand:DF 0 "vsx_register_operand" "=v") 14499 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")] 14500 UNSPEC_TRUNC_ROUND_TO_ODD))] 14501 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14502 "xscvqpdpo %0,%1" 14503 [(set_attr "type" "vecfloat") 14504 (set_attr "size" "128")]) 14505 14506;; IEEE 128-bit comparisons 14507(define_insn "*cmp<mode>_hw" 14508 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y") 14509 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v") 14510 (match_operand:IEEE128 2 "altivec_register_operand" "v")))] 14511 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)" 14512 "xscmpuqp %0,%1,%2" 14513 [(set_attr "type" "veccmp") 14514 (set_attr "size" "128")]) 14515 14516;; Miscellaneous ISA 3.0 (power9) instructions 14517 14518(define_insn "darn_32" 14519 [(set (match_operand:SI 0 "register_operand" "=r") 14520 (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))] 14521 "TARGET_P9_MISC" 14522 "darn %0,0" 14523 [(set_attr "type" "integer")]) 14524 14525(define_insn "darn_raw" 14526 [(set (match_operand:DI 0 "register_operand" "=r") 14527 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))] 14528 "TARGET_P9_MISC && TARGET_64BIT" 14529 "darn %0,2" 14530 [(set_attr "type" "integer")]) 14531 14532(define_insn "darn" 14533 [(set (match_operand:DI 0 "register_operand" "=r") 14534 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))] 14535 "TARGET_P9_MISC && TARGET_64BIT" 14536 "darn %0,1" 14537 [(set_attr "type" "integer")]) 14538 14539;; Test byte within range. 14540;; 14541;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14542;; represents a byte whose value is ignored in this context and 14543;; vv, the least significant byte, holds the byte value that is to 14544;; be tested for membership within the range specified by operand 2. 14545;; The bytes of operand 2 are organized as xx:xx:hi:lo. 14546;; 14547;; Return in target register operand 0 a value of 1 if lo <= vv and 14548;; vv <= hi. Otherwise, set register operand 0 to 0. 14549;; 14550;; Though the instructions to which this expansion maps operate on 14551;; 64-bit registers, the current implementation only operates on 14552;; SI-mode operands as the high-order bits provide no information 14553;; that is not already available in the low-order bits. To avoid the 14554;; costs of data widening operations, future enhancements might allow 14555;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 14556(define_expand "cmprb" 14557 [(set (match_dup 3) 14558 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14559 (match_operand:SI 2 "gpc_reg_operand" "r")] 14560 UNSPEC_CMPRB)) 14561 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 14562 (if_then_else:SI (lt (match_dup 3) 14563 (const_int 0)) 14564 (const_int -1) 14565 (if_then_else (gt (match_dup 3) 14566 (const_int 0)) 14567 (const_int 1) 14568 (const_int 0))))] 14569 "TARGET_P9_MISC" 14570{ 14571 operands[3] = gen_reg_rtx (CCmode); 14572}) 14573 14574;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14575;; represents a byte whose value is ignored in this context and 14576;; vv, the least significant byte, holds the byte value that is to 14577;; be tested for membership within the range specified by operand 2. 14578;; The bytes of operand 2 are organized as xx:xx:hi:lo. 14579;; 14580;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if 14581;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other 14582;; 3 bits of the target CR register are all set to 0. 14583(define_insn "*cmprb_internal" 14584 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 14585 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14586 (match_operand:SI 2 "gpc_reg_operand" "r")] 14587 UNSPEC_CMPRB))] 14588 "TARGET_P9_MISC" 14589 "cmprb %0,0,%1,%2" 14590 [(set_attr "type" "logical")]) 14591 14592;; Set operand 0 register to -1 if the LT bit (0x8) of condition 14593;; register operand 1 is on. Otherwise, set operand 0 register to 1 14594;; if the GT bit (0x4) of condition register operand 1 is on. 14595;; Otherwise, set operand 0 to 0. Note that the result stored into 14596;; register operand 0 is non-zero iff either the LT or GT bits are on 14597;; within condition register operand 1. 14598(define_insn "setb_signed" 14599 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 14600 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y") 14601 (const_int 0)) 14602 (const_int -1) 14603 (if_then_else (gt (match_dup 1) 14604 (const_int 0)) 14605 (const_int 1) 14606 (const_int 0))))] 14607 "TARGET_P9_MISC" 14608 "setb %0,%1" 14609 [(set_attr "type" "logical")]) 14610 14611(define_insn "setb_unsigned" 14612 [(set (match_operand:SI 0 "gpc_reg_operand" "=r") 14613 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y") 14614 (const_int 0)) 14615 (const_int -1) 14616 (if_then_else (gtu (match_dup 1) 14617 (const_int 0)) 14618 (const_int 1) 14619 (const_int 0))))] 14620 "TARGET_P9_MISC" 14621 "setb %0,%1" 14622 [(set_attr "type" "logical")]) 14623 14624;; Test byte within two ranges. 14625;; 14626;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14627;; represents a byte whose value is ignored in this context and 14628;; vv, the least significant byte, holds the byte value that is to 14629;; be tested for membership within the range specified by operand 2. 14630;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. 14631;; 14632;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and 14633;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register 14634;; operand 0 to 0. 14635;; 14636;; Though the instructions to which this expansion maps operate on 14637;; 64-bit registers, the current implementation only operates on 14638;; SI-mode operands as the high-order bits provide no information 14639;; that is not already available in the low-order bits. To avoid the 14640;; costs of data widening operations, future enhancements might allow 14641;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 14642(define_expand "cmprb2" 14643 [(set (match_dup 3) 14644 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14645 (match_operand:SI 2 "gpc_reg_operand" "r")] 14646 UNSPEC_CMPRB2)) 14647 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 14648 (if_then_else:SI (lt (match_dup 3) 14649 (const_int 0)) 14650 (const_int -1) 14651 (if_then_else (gt (match_dup 3) 14652 (const_int 0)) 14653 (const_int 1) 14654 (const_int 0))))] 14655 "TARGET_P9_MISC" 14656{ 14657 operands[3] = gen_reg_rtx (CCmode); 14658}) 14659 14660;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14661;; represents a byte whose value is ignored in this context and 14662;; vv, the least significant byte, holds the byte value that is to 14663;; be tested for membership within the ranges specified by operand 2. 14664;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2. 14665;; 14666;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if 14667;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). 14668;; Otherwise, set the GT bit to 0. The other 3 bits of the target 14669;; CR register are all set to 0. 14670(define_insn "*cmprb2_internal" 14671 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 14672 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14673 (match_operand:SI 2 "gpc_reg_operand" "r")] 14674 UNSPEC_CMPRB2))] 14675 "TARGET_P9_MISC" 14676 "cmprb %0,1,%1,%2" 14677 [(set_attr "type" "logical")]) 14678 14679;; Test byte membership within set of 8 bytes. 14680;; 14681;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14682;; represents a byte whose value is ignored in this context and 14683;; vv, the least significant byte, holds the byte value that is to 14684;; be tested for membership within the set specified by operand 2. 14685;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. 14686;; 14687;; Return in target register operand 0 a value of 1 if vv equals one 14688;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set 14689;; register operand 0 to 0. Note that the 8 byte values held within 14690;; operand 2 need not be unique. 14691;; 14692;; Though the instructions to which this expansion maps operate on 14693;; 64-bit registers, the current implementation requires that operands 14694;; 0 and 1 have mode SI as the high-order bits provide no information 14695;; that is not already available in the low-order bits. To avoid the 14696;; costs of data widening operations, future enhancements might allow 14697;; DI mode for operand 0 and/or might allow operand 1 to be QI mode. 14698(define_expand "cmpeqb" 14699 [(set (match_dup 3) 14700 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14701 (match_operand:DI 2 "gpc_reg_operand" "r")] 14702 UNSPEC_CMPEQB)) 14703 (set (match_operand:SI 0 "gpc_reg_operand" "=r") 14704 (if_then_else:SI (lt (match_dup 3) 14705 (const_int 0)) 14706 (const_int -1) 14707 (if_then_else (gt (match_dup 3) 14708 (const_int 0)) 14709 (const_int 1) 14710 (const_int 0))))] 14711 "TARGET_P9_MISC && TARGET_64BIT" 14712{ 14713 operands[3] = gen_reg_rtx (CCmode); 14714}) 14715 14716;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx 14717;; represents a byte whose value is ignored in this context and 14718;; vv, the least significant byte, holds the byte value that is to 14719;; be tested for membership within the set specified by operand 2. 14720;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7. 14721;; 14722;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv 14723;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, 14724;; set the GT bit to zero. The other 3 bits of the target CR register 14725;; are all set to 0. 14726(define_insn "*cmpeqb_internal" 14727 [(set (match_operand:CC 0 "cc_reg_operand" "=y") 14728 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r") 14729 (match_operand:DI 2 "gpc_reg_operand" "r")] 14730 UNSPEC_CMPEQB))] 14731 "TARGET_P9_MISC && TARGET_64BIT" 14732 "cmpeqb %0,%1,%2" 14733 [(set_attr "type" "logical")]) 14734 14735 14736(include "sync.md") 14737(include "vector.md") 14738(include "vsx.md") 14739(include "altivec.md") 14740(include "mma.md") 14741(include "dfp.md") 14742(include "crypto.md") 14743(include "htm.md") 14744