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)
5 ;; This file is part of GCC.
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.
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.
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/>.
21 ;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 (STACK_POINTER_REGNUM 1)
31 (STATIC_CHAIN_REGNUM 11)
32 (HARD_FRAME_POINTER_REGNUM 31)
36 (FIRST_ALTIVEC_REGNO 64)
37 (LAST_ALTIVEC_REGNO 95)
41 (ARG_POINTER_REGNUM 99)
53 (FRAME_POINTER_REGNUM 110)
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
72 UNSPEC_LD_MPIC ; load_macho_picbase
73 UNSPEC_RELD_MPIC ; re-load_macho_picbase
74 UNSPEC_MPIC_CORRECT ; macho_correct_pic
90 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
108 UNSPEC_MACHOPIC_OFFSET
122 UNSPEC_P8V_RELOAD_FROM_GPR
125 UNSPEC_P8V_RELOAD_FROM_VSX
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
159 ;; UNSPEC_VOLATILE usage
162 (define_c_enum "unspecv"
164 UNSPECV_LL ; load-locked
165 UNSPECV_SC ; store-conditional
166 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
167 UNSPECV_EH_RR ; eh_reg_restore
168 UNSPECV_ISYNC ; isync instruction
169 UNSPECV_MFTB ; move from time base
170 UNSPECV_DARN ; darn 1 (deliver a random number)
171 UNSPECV_DARN_32 ; darn 2
172 UNSPECV_DARN_RAW ; darn 0
173 UNSPECV_NLGR ; non-local goto receiver
174 UNSPECV_MFFS ; Move from FPSCR
175 UNSPECV_MFFSL ; Move from FPSCR light instruction version
176 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
177 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
178 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
179 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
180 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
181 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
182 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
183 UNSPECV_SPEC_BARRIER ; Speculation barrier
188 ; The three different kinds of epilogue.
189 (define_enum "epilogue_type" [normal sibcall eh_return])
191 ;; Define an insn type attribute. This is used in function unit delay
195 add,logical,shift,insert,
197 exts,cntlz,popcnt,isel,
198 load,store,fpload,fpstore,vecload,vecstore,
200 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
201 cr_logical,mfcr,mfcrf,mtcr,
202 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
203 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
204 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
205 veclogical,veccmpfx,vecexts,vecmove,
206 htm,htmsimple,dfp,mma"
207 (const_string "integer"))
209 ;; What data size does this instruction work on?
210 ;; This is used for insert, mul and others as necessary.
211 (define_attr "size" "8,16,32,64,128" (const_string "32"))
213 ;; What is the insn_cost for this insn? The target hook can still override
214 ;; this. For optimizing for size the "length" attribute is used instead.
215 (define_attr "cost" "" (const_int 0))
217 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
218 ;; This is used for add, logical, shift, exts, mul.
219 (define_attr "dot" "no,yes" (const_string "no"))
221 ;; Does this instruction sign-extend its result?
222 ;; This is used for load insns.
223 (define_attr "sign_extend" "no,yes" (const_string "no"))
225 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
226 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
228 ;; Does this instruction use indexed (that is, reg+reg) addressing?
229 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
230 ;; it is automatically set based on that. If a load or store instruction
231 ;; has fewer than two operands it needs to set this attribute manually
232 ;; or the compiler will crash.
233 (define_attr "indexed" "no,yes"
234 (if_then_else (ior (match_operand 0 "indexed_address_mem")
235 (match_operand 1 "indexed_address_mem"))
237 (const_string "no")))
239 ;; Does this instruction use update addressing?
240 ;; This is used for load and store insns. See the comments for "indexed".
241 (define_attr "update" "no,yes"
242 (if_then_else (ior (match_operand 0 "update_address_mem")
243 (match_operand 1 "update_address_mem"))
245 (const_string "no")))
247 ;; Is this instruction using operands[2] as shift amount, and can that be a
249 ;; This is used for shift insns.
250 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
252 ;; Is this instruction using a shift amount from a register?
253 ;; This is used for shift insns.
254 (define_attr "var_shift" "no,yes"
255 (if_then_else (and (eq_attr "type" "shift")
256 (eq_attr "maybe_var_shift" "yes"))
257 (if_then_else (match_operand 2 "gpc_reg_operand")
260 (const_string "no")))
262 ;; Is copying of this instruction disallowed?
263 (define_attr "cannot_copy" "no,yes" (const_string "no"))
266 ;; Whether an insn is a prefixed insn, and an initial 'p' should be printed
267 ;; before the instruction. A prefixed instruction has a prefix instruction
268 ;; word that extends the immediate value of the instructions from 12-16 bits to
269 ;; 34 bits. The macro ASM_OUTPUT_OPCODE emits a leading 'p' for prefixed
270 ;; insns. The default "length" attribute will also be adjusted by default to
272 (define_attr "prefixed" "no,yes"
273 (cond [(ior (match_test "!TARGET_PREFIXED")
274 (match_test "!NONJUMP_INSN_P (insn)"))
277 (eq_attr "type" "load,fpload,vecload")
278 (if_then_else (match_test "prefixed_load_p (insn)")
282 (eq_attr "type" "store,fpstore,vecstore")
283 (if_then_else (match_test "prefixed_store_p (insn)")
287 (eq_attr "type" "integer,add")
288 (if_then_else (match_test "prefixed_paddi_p (insn)")
290 (const_string "no"))]
292 (const_string "no")))
294 ;; Return the number of real hardware instructions in a combined insn. If it
295 ;; is 0, just use the length / 4.
296 (define_attr "num_insns" "" (const_int 0))
298 ;; If an insn is prefixed, return the maximum number of prefixed instructions
299 ;; in the insn. The macro ADJUST_INSN_LENGTH uses this number to adjust the
301 (define_attr "max_prefixed_insns" "" (const_int 1))
303 ;; Length of the instruction (in bytes). This length does not consider the
304 ;; length for prefixed instructions. The macro ADJUST_INSN_LENGTH will adjust
305 ;; the length if there are prefixed instructions.
307 ;; While it might be tempting to use num_insns to calculate the length, it can
308 ;; be problematical unless all insn lengths are adjusted to use num_insns
309 ;; (i.e. if num_insns is 0, it will get the length, which in turn will get
310 ;; num_insns and recurse).
311 (define_attr "length" "" (const_int 4))
313 ;; Processor type -- this attribute must exactly match the processor_type
314 ;; enumeration in rs6000-opts.h.
316 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
317 ppc750,ppc7400,ppc7450,
318 ppc403,ppc405,ppc440,ppc476,
319 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
320 power4,power5,power6,power7,power8,power9,power10,
321 rs64a,mpccore,cell,ppca2,titan"
322 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
324 ;; The ISA we implement.
325 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,p10"
326 (const_string "any"))
328 ;; Is this alternative enabled for the current CPU/ISA/etc.?
329 (define_attr "enabled" ""
331 [(eq_attr "isa" "any")
334 (and (eq_attr "isa" "p5")
335 (match_test "TARGET_POPCNTB"))
338 (and (eq_attr "isa" "p6")
339 (match_test "TARGET_CMPB"))
342 (and (eq_attr "isa" "p7")
343 (match_test "TARGET_POPCNTD"))
346 (and (eq_attr "isa" "p7v")
347 (match_test "TARGET_VSX"))
350 (and (eq_attr "isa" "p8v")
351 (match_test "TARGET_P8_VECTOR"))
354 (and (eq_attr "isa" "p9v")
355 (match_test "TARGET_P9_VECTOR"))
358 (and (eq_attr "isa" "p9kf")
359 (match_test "TARGET_FLOAT128_TYPE"))
362 (and (eq_attr "isa" "p9tf")
363 (match_test "FLOAT128_VECTOR_P (TFmode)"))
366 (and (eq_attr "isa" "p10")
367 (match_test "TARGET_POWER10"))
371 ;; If this instruction is microcoded on the CELL processor
372 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
373 (define_attr "cell_micro" "not,conditional,always"
374 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
375 (eq_attr "dot" "yes"))
376 (and (eq_attr "type" "load")
377 (eq_attr "sign_extend" "yes"))
378 (and (eq_attr "type" "shift")
379 (eq_attr "var_shift" "yes")))
380 (const_string "always")
381 (const_string "not")))
383 (automata_option "ndfa")
396 (include "e300c2c3.md")
397 (include "e500mc.md")
398 (include "e500mc64.md")
401 (include "power4.md")
402 (include "power5.md")
403 (include "power6.md")
404 (include "power7.md")
405 (include "power8.md")
406 (include "power9.md")
407 (include "power10.md")
412 (include "predicates.md")
413 (include "constraints.md")
418 ; This mode iterator allows :GPR to be used to indicate the allowable size
419 ; of whole values in GPRs.
420 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
422 ; And again, for patterns that need two (potentially) different integer modes.
423 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
425 ; Any supported integer mode.
426 (define_mode_iterator INT [QI HI SI DI TI PTI])
428 ; Any supported integer mode that fits in one register.
429 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
431 ; Integer modes supported in VSX registers with ISA 3.0 instructions
432 (define_mode_iterator INT_ISA3 [QI HI SI DI])
434 ; Everything we can extend QImode to.
435 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
437 ; Everything we can extend HImode to.
438 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
440 ; Everything we can extend SImode to.
441 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
443 ; QImode or HImode for small integer moves and small atomic ops
444 (define_mode_iterator QHI [QI HI])
446 ; QImode, HImode, SImode for fused ops only for GPR loads
447 (define_mode_iterator QHSI [QI HI SI])
449 ; HImode or SImode for sign extended fusion ops
450 (define_mode_iterator HSI [HI SI])
452 ; SImode or DImode, even if DImode doesn't fit in GPRs.
453 (define_mode_iterator SDI [SI DI])
455 ; The size of a pointer. Also, the size of the value that a record-condition
456 ; (one with a '.') will compare; and the size used for arithmetic carries.
457 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
459 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
460 ; PTImode is GPR only)
461 (define_mode_iterator TI2 [TI PTI])
463 ; Any hardware-supported floating-point mode
464 (define_mode_iterator FP [
465 (SF "TARGET_HARD_FLOAT")
466 (DF "TARGET_HARD_FLOAT")
467 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
468 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
469 (KF "TARGET_FLOAT128_TYPE")
473 ; Any fma capable floating-point mode.
474 (define_mode_iterator FMA_F [
475 (SF "TARGET_HARD_FLOAT")
476 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
477 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
478 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
479 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
480 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
483 ; Floating point move iterators to combine binary and decimal moves
484 (define_mode_iterator FMOVE32 [SF SD])
485 (define_mode_iterator FMOVE64 [DF DD])
486 (define_mode_iterator FMOVE64X [DI DF DD])
487 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
488 (IF "FLOAT128_IBM_P (IFmode)")
489 (TD "TARGET_HARD_FLOAT")])
491 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
492 (IF "FLOAT128_2REG_P (IFmode)")
493 (TD "TARGET_HARD_FLOAT")])
495 ; Iterators for 128 bit types for direct move
496 (define_mode_iterator FMOVE128_GPR [TI
504 (KF "FLOAT128_VECTOR_P (KFmode)")
505 (TF "FLOAT128_VECTOR_P (TFmode)")])
507 ; Iterator for 128-bit VSX types for pack/unpack
508 (define_mode_iterator FMOVE128_VSX [V1TI KF])
510 ; Iterators for converting to/from TFmode
511 (define_mode_iterator IFKF [IF KF])
513 ; Constraints for moving IF/KFmode.
514 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
516 ; Whether a floating point move is ok, don't allow SD without hardware FP
517 (define_mode_attr fmove_ok [(SF "")
519 (SD "TARGET_HARD_FLOAT")
522 ; Convert REAL_VALUE to the appropriate bits
523 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
524 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
525 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
526 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
528 ; Whether 0.0 has an all-zero bit pattern
529 (define_mode_attr zero_fp [(SF "j")
538 ; Definitions for 64-bit VSX
539 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
541 ; Definitions for 64-bit direct move
542 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
544 ; Definitions for 64-bit use of altivec registers
545 (define_mode_attr f64_av [(DF "v") (DD "wn")])
547 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
548 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
550 ; These modes do not fit in integer registers in 32-bit mode.
551 (define_mode_iterator DIFD [DI DF DD])
553 ; Iterator for reciprocal estimate instructions
554 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
557 (define_mode_iterator SFDF [SF DF])
559 ; And again, for when we need two FP modes in a pattern.
560 (define_mode_iterator SFDF2 [SF DF])
562 ; A generic s/d attribute, for sp/dp for example.
563 (define_mode_attr sd [(SF "s") (DF "d")
564 (V4SF "s") (V2DF "d")])
566 ; "s" or nothing, for fmuls/fmul for example.
567 (define_mode_attr s [(SF "s") (DF "")])
569 ; Iterator for 128-bit floating point that uses the IBM double-double format
570 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
571 (TF "FLOAT128_IBM_P (TFmode)")])
573 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
574 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
575 (TF "FLOAT128_IEEE_P (TFmode)")])
577 ; Iterator for 128-bit floating point
578 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
579 (IF "TARGET_FLOAT128_TYPE")
580 (TF "TARGET_LONG_DOUBLE_128")])
582 ; Iterator for signbit on 64-bit machines with direct move
583 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
584 (TF "FLOAT128_VECTOR_P (TFmode)")])
586 ; Iterator for ISA 3.0 supported floating point types
587 (define_mode_iterator FP_ISA3 [SF DF])
589 ; SF/DF constraint for arithmetic on traditional floating point registers
590 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
592 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
593 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
594 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
596 (define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")])
598 ; Which isa is needed for those float instructions?
599 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
602 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
604 ; Conditional returns.
605 (define_code_iterator any_return [return simple_return])
606 (define_code_attr return_pred [(return "direct_return ()")
607 (simple_return "1")])
608 (define_code_attr return_str [(return "") (simple_return "simple_")])
611 (define_code_iterator iorxor [ior xor])
612 (define_code_iterator and_ior_xor [and ior xor])
614 ; Signed/unsigned variants of ops.
615 (define_code_iterator any_extend [sign_extend zero_extend])
616 (define_code_iterator any_fix [fix unsigned_fix])
617 (define_code_iterator any_float [float unsigned_float])
619 (define_code_attr u [(sign_extend "")
624 (define_code_attr su [(sign_extend "s")
629 (unsigned_float "u")])
631 (define_code_attr az [(sign_extend "a")
636 (unsigned_float "z")])
638 (define_code_attr uns [(fix "")
641 (unsigned_float "uns")])
643 ; Various instructions that come in SI and DI forms.
644 ; A generic w/d attribute, for things like cmpw/cmpd.
645 (define_mode_attr wd [(QI "b")
656 ; For double extract from different origin types
657 (define_mode_attr du_or_d [(QI "du")
666 ;; How many bits in this mode?
667 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
668 (SF "32") (DF "64")])
671 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
673 ;; Bitmask for shift instructions
674 (define_mode_attr hH [(SI "h") (DI "H")])
676 ;; A mode twice the size of the given mode
677 (define_mode_attr dmode [(SI "di") (DI "ti")])
678 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
680 ;; Suffix for reload patterns
681 (define_mode_attr ptrsize [(SI "32bit")
684 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
685 (DI "TARGET_64BIT")])
687 (define_mode_attr mptrsize [(SI "si")
690 (define_mode_attr ptrload [(SI "lwz")
693 (define_mode_attr ptrm [(SI "m")
696 (define_mode_attr rreg [(SF "f")
703 (define_mode_attr rreg2 [(SF "f")
706 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
707 (DF "TARGET_FCFID")])
709 ;; Mode iterator for logical operations on 128-bit types
710 (define_mode_iterator BOOL_128 [TI
712 (V16QI "TARGET_ALTIVEC")
713 (V8HI "TARGET_ALTIVEC")
714 (V4SI "TARGET_ALTIVEC")
715 (V4SF "TARGET_ALTIVEC")
716 (V2DI "TARGET_ALTIVEC")
717 (V2DF "TARGET_ALTIVEC")
718 (V1TI "TARGET_ALTIVEC")])
720 ;; For the GPRs we use 3 constraints for register outputs, two that are the
721 ;; same as the output register, and a third where the output register is an
722 ;; early clobber, so we don't have to deal with register overlaps. For the
723 ;; vector types, we prefer to use the vector registers. For TI mode, allow
726 ;; Mode attribute for boolean operation register constraints for output
727 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
729 (V16QI "wa,v,&?r,?r,?r")
730 (V8HI "wa,v,&?r,?r,?r")
731 (V4SI "wa,v,&?r,?r,?r")
732 (V4SF "wa,v,&?r,?r,?r")
733 (V2DI "wa,v,&?r,?r,?r")
734 (V2DF "wa,v,&?r,?r,?r")
735 (V1TI "wa,v,&?r,?r,?r")])
737 ;; Mode attribute for boolean operation register constraints for operand1
738 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
746 (V1TI "wa,v,r,0,r")])
748 ;; Mode attribute for boolean operation register constraints for operand2
749 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
757 (V1TI "wa,v,r,r,0")])
759 ;; Mode attribute for boolean operation register constraints for operand1
760 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
761 ;; is used for operand1 or operand2
762 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
770 (V1TI "wa,v,r,0,0")])
772 ;; Reload iterator for creating the function to allocate a base register to
773 ;; supplement addressing modes.
774 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
775 SF SD SI DF DD DI TI PTI KF IF TF
778 ;; Iterate over smin, smax
779 (define_code_iterator fp_minmax [smin smax])
781 (define_code_attr minmax [(smin "min")
784 (define_code_attr SMINMAX [(smin "SMIN")
787 ;; Iterator to optimize the following cases:
788 ;; D-form load to FPR register & move to Altivec register
789 ;; Move Altivec register to FPR register and store
790 (define_mode_iterator ALTIVEC_DFORM [DF
791 (SF "TARGET_P8_VECTOR")
792 (DI "TARGET_POWERPC64")])
794 (include "darwin.md")
796 ;; Start with fixed-point load and store insns. Here we put only the more
797 ;; complex forms. Basic data transfer is done later.
799 (define_insn "zero_extendqi<mode>2"
800 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
801 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
808 [(set_attr "type" "load,shift,fpload,vecperm")
809 (set_attr "isa" "*,*,p9v,p9v")])
811 (define_insn_and_split "*zero_extendqi<mode>2_dot"
812 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
813 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
815 (clobber (match_scratch:EXTQI 0 "=r,r"))]
820 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
822 (zero_extend:EXTQI (match_dup 1)))
824 (compare:CC (match_dup 0)
827 [(set_attr "type" "logical")
828 (set_attr "dot" "yes")
829 (set_attr "length" "4,8")])
831 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
832 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
833 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
835 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
836 (zero_extend:EXTQI (match_dup 1)))]
841 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
843 (zero_extend:EXTQI (match_dup 1)))
845 (compare:CC (match_dup 0)
848 [(set_attr "type" "logical")
849 (set_attr "dot" "yes")
850 (set_attr "length" "4,8")])
853 (define_insn "zero_extendhi<mode>2"
854 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
855 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
859 rlwinm %0,%1,0,0xffff
862 [(set_attr "type" "load,shift,fpload,vecperm")
863 (set_attr "isa" "*,*,p9v,p9v")])
865 (define_insn_and_split "*zero_extendhi<mode>2_dot"
866 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
867 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
869 (clobber (match_scratch:EXTHI 0 "=r,r"))]
874 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
876 (zero_extend:EXTHI (match_dup 1)))
878 (compare:CC (match_dup 0)
881 [(set_attr "type" "logical")
882 (set_attr "dot" "yes")
883 (set_attr "length" "4,8")])
885 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
886 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
887 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
889 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
890 (zero_extend:EXTHI (match_dup 1)))]
895 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
897 (zero_extend:EXTHI (match_dup 1)))
899 (compare:CC (match_dup 0)
902 [(set_attr "type" "logical")
903 (set_attr "dot" "yes")
904 (set_attr "length" "4,8")])
907 (define_insn "zero_extendsi<mode>2"
908 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
909 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
918 xxextractuw %x0,%x1,4"
919 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
920 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
922 (define_insn_and_split "*zero_extendsi<mode>2_dot"
923 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
924 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
926 (clobber (match_scratch:EXTSI 0 "=r,r"))]
931 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
933 (zero_extend:DI (match_dup 1)))
935 (compare:CC (match_dup 0)
938 [(set_attr "type" "shift")
939 (set_attr "dot" "yes")
940 (set_attr "length" "4,8")])
942 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
943 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
944 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
946 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
947 (zero_extend:EXTSI (match_dup 1)))]
952 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
954 (zero_extend:EXTSI (match_dup 1)))
956 (compare:CC (match_dup 0)
959 [(set_attr "type" "shift")
960 (set_attr "dot" "yes")
961 (set_attr "length" "4,8")])
964 (define_insn "extendqi<mode>2"
965 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
966 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
971 [(set_attr "type" "exts,vecperm")
972 (set_attr "isa" "*,p9v")])
974 (define_insn_and_split "*extendqi<mode>2_dot"
975 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
976 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
978 (clobber (match_scratch:EXTQI 0 "=r,r"))]
983 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
985 (sign_extend:EXTQI (match_dup 1)))
987 (compare:CC (match_dup 0)
990 [(set_attr "type" "exts")
991 (set_attr "dot" "yes")
992 (set_attr "length" "4,8")])
994 (define_insn_and_split "*extendqi<mode>2_dot2"
995 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
996 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
998 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
999 (sign_extend:EXTQI (match_dup 1)))]
1004 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1006 (sign_extend:EXTQI (match_dup 1)))
1008 (compare:CC (match_dup 0)
1011 [(set_attr "type" "exts")
1012 (set_attr "dot" "yes")
1013 (set_attr "length" "4,8")])
1016 (define_expand "extendhi<mode>2"
1017 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
1018 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
1022 (define_insn "*extendhi<mode>2"
1023 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
1024 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
1031 [(set_attr "type" "load,exts,fpload,vecperm")
1032 (set_attr "sign_extend" "yes")
1033 (set_attr "length" "*,*,8,*")
1034 (set_attr "isa" "*,*,p9v,p9v")])
1037 [(set (match_operand:EXTHI 0 "altivec_register_operand")
1039 (match_operand:HI 1 "indexed_or_indirect_operand")))]
1040 "TARGET_P9_VECTOR && reload_completed"
1044 (sign_extend:EXTHI (match_dup 2)))]
1046 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
1049 (define_insn_and_split "*extendhi<mode>2_dot"
1050 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1051 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1053 (clobber (match_scratch:EXTHI 0 "=r,r"))]
1058 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1060 (sign_extend:EXTHI (match_dup 1)))
1062 (compare:CC (match_dup 0)
1065 [(set_attr "type" "exts")
1066 (set_attr "dot" "yes")
1067 (set_attr "length" "4,8")])
1069 (define_insn_and_split "*extendhi<mode>2_dot2"
1070 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1071 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1073 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1074 (sign_extend:EXTHI (match_dup 1)))]
1079 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1081 (sign_extend:EXTHI (match_dup 1)))
1083 (compare:CC (match_dup 0)
1086 [(set_attr "type" "exts")
1087 (set_attr "dot" "yes")
1088 (set_attr "length" "4,8")])
1091 (define_insn "extendsi<mode>2"
1092 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1093 "=r, r, d, wa, wa, v, v, wr")
1094 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1095 "YZ, r, Z, Z, r, v, v, ?wa")))]
1106 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1107 (set_attr "sign_extend" "yes")
1108 (set_attr "length" "*,*,*,*,*,*,8,8")
1109 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1112 [(set (match_operand:EXTSI 0 "int_reg_operand")
1113 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1114 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1118 (sign_extend:DI (match_dup 2)))]
1120 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1124 [(set (match_operand:DI 0 "altivec_register_operand")
1125 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1126 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1129 rtx dest = operands[0];
1130 rtx src = operands[1];
1131 int dest_regno = REGNO (dest);
1132 int src_regno = REGNO (src);
1133 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1134 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1136 if (BYTES_BIG_ENDIAN)
1138 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1139 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1143 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1144 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1149 (define_insn_and_split "*extendsi<mode>2_dot"
1150 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1151 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1153 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1158 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1160 (sign_extend:EXTSI (match_dup 1)))
1162 (compare:CC (match_dup 0)
1165 [(set_attr "type" "exts")
1166 (set_attr "dot" "yes")
1167 (set_attr "length" "4,8")])
1169 (define_insn_and_split "*extendsi<mode>2_dot2"
1170 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1171 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1173 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1174 (sign_extend:EXTSI (match_dup 1)))]
1179 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1181 (sign_extend:EXTSI (match_dup 1)))
1183 (compare:CC (match_dup 0)
1186 [(set_attr "type" "exts")
1187 (set_attr "dot" "yes")
1188 (set_attr "length" "4,8")])
1190 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1192 (define_insn "*macchwc"
1193 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1194 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1195 (match_operand:SI 2 "gpc_reg_operand" "r")
1198 (match_operand:HI 1 "gpc_reg_operand" "r")))
1199 (match_operand:SI 4 "gpc_reg_operand" "0"))
1201 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1202 (plus:SI (mult:SI (ashiftrt:SI
1210 [(set_attr "type" "halfmul")])
1212 (define_insn "*macchw"
1213 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1214 (plus:SI (mult:SI (ashiftrt:SI
1215 (match_operand:SI 2 "gpc_reg_operand" "r")
1218 (match_operand:HI 1 "gpc_reg_operand" "r")))
1219 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1222 [(set_attr "type" "halfmul")])
1224 (define_insn "*macchwuc"
1225 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1226 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1227 (match_operand:SI 2 "gpc_reg_operand" "r")
1230 (match_operand:HI 1 "gpc_reg_operand" "r")))
1231 (match_operand:SI 4 "gpc_reg_operand" "0"))
1233 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1234 (plus:SI (mult:SI (lshiftrt:SI
1242 [(set_attr "type" "halfmul")])
1244 (define_insn "*macchwu"
1245 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1246 (plus:SI (mult:SI (lshiftrt:SI
1247 (match_operand:SI 2 "gpc_reg_operand" "r")
1250 (match_operand:HI 1 "gpc_reg_operand" "r")))
1251 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1254 [(set_attr "type" "halfmul")])
1256 (define_insn "*machhwc"
1257 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1258 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1259 (match_operand:SI 1 "gpc_reg_operand" "%r")
1262 (match_operand:SI 2 "gpc_reg_operand" "r")
1264 (match_operand:SI 4 "gpc_reg_operand" "0"))
1266 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1267 (plus:SI (mult:SI (ashiftrt:SI
1276 [(set_attr "type" "halfmul")])
1278 (define_insn "*machhw"
1279 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1280 (plus:SI (mult:SI (ashiftrt:SI
1281 (match_operand:SI 1 "gpc_reg_operand" "%r")
1284 (match_operand:SI 2 "gpc_reg_operand" "r")
1286 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1289 [(set_attr "type" "halfmul")])
1291 (define_insn "*machhwuc"
1292 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1293 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1294 (match_operand:SI 1 "gpc_reg_operand" "%r")
1297 (match_operand:SI 2 "gpc_reg_operand" "r")
1299 (match_operand:SI 4 "gpc_reg_operand" "0"))
1301 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1302 (plus:SI (mult:SI (lshiftrt:SI
1311 [(set_attr "type" "halfmul")])
1313 (define_insn "*machhwu"
1314 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1315 (plus:SI (mult:SI (lshiftrt:SI
1316 (match_operand:SI 1 "gpc_reg_operand" "%r")
1319 (match_operand:SI 2 "gpc_reg_operand" "r")
1321 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1324 [(set_attr "type" "halfmul")])
1326 (define_insn "*maclhwc"
1327 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1328 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1329 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1331 (match_operand:HI 2 "gpc_reg_operand" "r")))
1332 (match_operand:SI 4 "gpc_reg_operand" "0"))
1334 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1335 (plus:SI (mult:SI (sign_extend:SI
1342 [(set_attr "type" "halfmul")])
1344 (define_insn "*maclhw"
1345 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1346 (plus:SI (mult:SI (sign_extend:SI
1347 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1349 (match_operand:HI 2 "gpc_reg_operand" "r")))
1350 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1353 [(set_attr "type" "halfmul")])
1355 (define_insn "*maclhwuc"
1356 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1357 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1358 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1360 (match_operand:HI 2 "gpc_reg_operand" "r")))
1361 (match_operand:SI 4 "gpc_reg_operand" "0"))
1363 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1364 (plus:SI (mult:SI (zero_extend:SI
1371 [(set_attr "type" "halfmul")])
1373 (define_insn "*maclhwu"
1374 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1375 (plus:SI (mult:SI (zero_extend:SI
1376 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1378 (match_operand:HI 2 "gpc_reg_operand" "r")))
1379 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1382 [(set_attr "type" "halfmul")])
1384 (define_insn "*nmacchwc"
1385 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1386 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1387 (mult:SI (ashiftrt:SI
1388 (match_operand:SI 2 "gpc_reg_operand" "r")
1391 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1393 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1394 (minus:SI (match_dup 4)
1395 (mult:SI (ashiftrt:SI
1402 [(set_attr "type" "halfmul")])
1404 (define_insn "*nmacchw"
1405 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1406 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1407 (mult:SI (ashiftrt:SI
1408 (match_operand:SI 2 "gpc_reg_operand" "r")
1411 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1414 [(set_attr "type" "halfmul")])
1416 (define_insn "*nmachhwc"
1417 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1418 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1419 (mult:SI (ashiftrt:SI
1420 (match_operand:SI 1 "gpc_reg_operand" "%r")
1423 (match_operand:SI 2 "gpc_reg_operand" "r")
1426 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1427 (minus:SI (match_dup 4)
1428 (mult:SI (ashiftrt:SI
1436 [(set_attr "type" "halfmul")])
1438 (define_insn "*nmachhw"
1439 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1440 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1441 (mult:SI (ashiftrt:SI
1442 (match_operand:SI 1 "gpc_reg_operand" "%r")
1445 (match_operand:SI 2 "gpc_reg_operand" "r")
1449 [(set_attr "type" "halfmul")])
1451 (define_insn "*nmaclhwc"
1452 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1453 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1454 (mult:SI (sign_extend:SI
1455 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1457 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1459 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1460 (minus:SI (match_dup 4)
1461 (mult:SI (sign_extend:SI
1467 [(set_attr "type" "halfmul")])
1469 (define_insn "*nmaclhw"
1470 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1471 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1472 (mult:SI (sign_extend:SI
1473 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1475 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1478 [(set_attr "type" "halfmul")])
1480 (define_insn "*mulchwc"
1481 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1482 (compare:CC (mult:SI (ashiftrt:SI
1483 (match_operand:SI 2 "gpc_reg_operand" "r")
1486 (match_operand:HI 1 "gpc_reg_operand" "r")))
1488 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1489 (mult:SI (ashiftrt:SI
1496 [(set_attr "type" "halfmul")])
1498 (define_insn "*mulchw"
1499 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1500 (mult:SI (ashiftrt:SI
1501 (match_operand:SI 2 "gpc_reg_operand" "r")
1504 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1507 [(set_attr "type" "halfmul")])
1509 (define_insn "*mulchwuc"
1510 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1511 (compare:CC (mult:SI (lshiftrt:SI
1512 (match_operand:SI 2 "gpc_reg_operand" "r")
1515 (match_operand:HI 1 "gpc_reg_operand" "r")))
1517 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1518 (mult:SI (lshiftrt:SI
1525 [(set_attr "type" "halfmul")])
1527 (define_insn "*mulchwu"
1528 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1529 (mult:SI (lshiftrt:SI
1530 (match_operand:SI 2 "gpc_reg_operand" "r")
1533 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1536 [(set_attr "type" "halfmul")])
1538 (define_insn "*mulhhwc"
1539 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1540 (compare:CC (mult:SI (ashiftrt:SI
1541 (match_operand:SI 1 "gpc_reg_operand" "%r")
1544 (match_operand:SI 2 "gpc_reg_operand" "r")
1547 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1548 (mult:SI (ashiftrt:SI
1556 [(set_attr "type" "halfmul")])
1558 (define_insn "*mulhhw"
1559 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1560 (mult:SI (ashiftrt:SI
1561 (match_operand:SI 1 "gpc_reg_operand" "%r")
1564 (match_operand:SI 2 "gpc_reg_operand" "r")
1568 [(set_attr "type" "halfmul")])
1570 (define_insn "*mulhhwuc"
1571 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1572 (compare:CC (mult:SI (lshiftrt:SI
1573 (match_operand:SI 1 "gpc_reg_operand" "%r")
1576 (match_operand:SI 2 "gpc_reg_operand" "r")
1579 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1580 (mult:SI (lshiftrt:SI
1588 [(set_attr "type" "halfmul")])
1590 (define_insn "*mulhhwu"
1591 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1592 (mult:SI (lshiftrt:SI
1593 (match_operand:SI 1 "gpc_reg_operand" "%r")
1596 (match_operand:SI 2 "gpc_reg_operand" "r")
1600 [(set_attr "type" "halfmul")])
1602 (define_insn "*mullhwc"
1603 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1604 (compare:CC (mult:SI (sign_extend:SI
1605 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1607 (match_operand:HI 2 "gpc_reg_operand" "r")))
1609 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1610 (mult:SI (sign_extend:SI
1616 [(set_attr "type" "halfmul")])
1618 (define_insn "*mullhw"
1619 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1620 (mult:SI (sign_extend:SI
1621 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1623 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1626 [(set_attr "type" "halfmul")])
1628 (define_insn "*mullhwuc"
1629 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1630 (compare:CC (mult:SI (zero_extend:SI
1631 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1633 (match_operand:HI 2 "gpc_reg_operand" "r")))
1635 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1636 (mult:SI (zero_extend:SI
1642 [(set_attr "type" "halfmul")])
1644 (define_insn "*mullhwu"
1645 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1646 (mult:SI (zero_extend:SI
1647 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1649 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1652 [(set_attr "type" "halfmul")])
1654 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1655 (define_insn "dlmzb"
1656 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1657 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1658 (match_operand:SI 2 "gpc_reg_operand" "r")]
1660 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1661 (unspec:SI [(match_dup 1)
1667 (define_expand "strlensi"
1668 [(set (match_operand:SI 0 "gpc_reg_operand")
1669 (unspec:SI [(match_operand:BLK 1 "general_operand")
1670 (match_operand:QI 2 "const_int_operand")
1671 (match_operand 3 "const_int_operand")]
1672 UNSPEC_DLMZB_STRLEN))
1673 (clobber (match_scratch:CC 4))]
1674 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1676 rtx result = operands[0];
1677 rtx src = operands[1];
1678 rtx search_char = operands[2];
1679 rtx align = operands[3];
1680 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1681 rtx loop_label, end_label, mem, cr0, cond;
1682 if (search_char != const0_rtx
1683 || !CONST_INT_P (align)
1684 || INTVAL (align) < 8)
1686 word1 = gen_reg_rtx (SImode);
1687 word2 = gen_reg_rtx (SImode);
1688 scratch_dlmzb = gen_reg_rtx (SImode);
1689 scratch_string = gen_reg_rtx (Pmode);
1690 loop_label = gen_label_rtx ();
1691 end_label = gen_label_rtx ();
1692 addr = force_reg (Pmode, XEXP (src, 0));
1693 emit_move_insn (scratch_string, addr);
1694 emit_label (loop_label);
1695 mem = change_address (src, SImode, scratch_string);
1696 emit_move_insn (word1, mem);
1697 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1698 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1699 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1700 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1701 emit_jump_insn (gen_rtx_SET (pc_rtx,
1702 gen_rtx_IF_THEN_ELSE (VOIDmode,
1708 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1709 emit_jump_insn (gen_rtx_SET (pc_rtx,
1710 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1712 emit_label (end_label);
1713 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1714 emit_insn (gen_subsi3 (result, scratch_string, addr));
1715 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1719 ;; Fixed-point arithmetic insns.
1721 (define_expand "add<mode>3"
1722 [(set (match_operand:SDI 0 "gpc_reg_operand")
1723 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1724 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1727 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1729 rtx lo0 = gen_lowpart (SImode, operands[0]);
1730 rtx lo1 = gen_lowpart (SImode, operands[1]);
1731 rtx lo2 = gen_lowpart (SImode, operands[2]);
1732 rtx hi0 = gen_highpart (SImode, operands[0]);
1733 rtx hi1 = gen_highpart (SImode, operands[1]);
1734 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1736 if (!reg_or_short_operand (lo2, SImode))
1737 lo2 = force_reg (SImode, lo2);
1738 if (!adde_operand (hi2, SImode))
1739 hi2 = force_reg (SImode, hi2);
1741 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1742 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1746 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1748 rtx tmp = ((!can_create_pseudo_p ()
1749 || rtx_equal_p (operands[0], operands[1]))
1750 ? operands[0] : gen_reg_rtx (<MODE>mode));
1752 /* Adding a constant to r0 is not a valid insn, so use a different
1753 strategy in that case. */
1754 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1756 if (operands[0] == operands[1])
1758 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1759 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1763 HOST_WIDE_INT val = INTVAL (operands[2]);
1764 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1765 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1767 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1770 /* The ordering here is important for the prolog expander.
1771 When space is allocated from the stack, adding 'low' first may
1772 produce a temporary deallocation (which would be bad). */
1773 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1774 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1779 (define_insn "*add<mode>3"
1780 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r,r")
1781 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b,b")
1782 (match_operand:GPR 2 "add_operand" "r,I,L,eI")))]
1789 [(set_attr "type" "add")
1790 (set_attr "isa" "*,*,*,p10")])
1792 (define_insn "*addsi3_high"
1793 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1794 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1795 (high:SI (match_operand 2 "" ""))))]
1796 "TARGET_MACHO && !TARGET_64BIT"
1797 "addis %0,%1,ha16(%2)"
1798 [(set_attr "type" "add")])
1800 (define_insn_and_split "*add<mode>3_dot"
1801 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1802 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1803 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1805 (clobber (match_scratch:GPR 0 "=r,r"))]
1806 "<MODE>mode == Pmode"
1810 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1812 (plus:GPR (match_dup 1)
1815 (compare:CC (match_dup 0)
1818 [(set_attr "type" "add")
1819 (set_attr "dot" "yes")
1820 (set_attr "length" "4,8")])
1822 (define_insn_and_split "*add<mode>3_dot2"
1823 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1824 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1825 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1827 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1828 (plus:GPR (match_dup 1)
1830 "<MODE>mode == Pmode"
1834 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1836 (plus:GPR (match_dup 1)
1839 (compare:CC (match_dup 0)
1842 [(set_attr "type" "add")
1843 (set_attr "dot" "yes")
1844 (set_attr "length" "4,8")])
1846 (define_insn_and_split "*add<mode>3_imm_dot"
1847 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1848 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1849 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1851 (clobber (match_scratch:GPR 0 "=r,r"))
1852 (clobber (reg:GPR CA_REGNO))]
1853 "<MODE>mode == Pmode"
1857 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1859 (plus:GPR (match_dup 1)
1862 (compare:CC (match_dup 0)
1865 [(set_attr "type" "add")
1866 (set_attr "dot" "yes")
1867 (set_attr "length" "4,8")])
1869 (define_insn_and_split "*add<mode>3_imm_dot2"
1870 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1871 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1872 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1874 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1875 (plus:GPR (match_dup 1)
1877 (clobber (reg:GPR CA_REGNO))]
1878 "<MODE>mode == Pmode"
1882 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1884 (plus:GPR (match_dup 1)
1887 (compare:CC (match_dup 0)
1890 [(set_attr "type" "add")
1891 (set_attr "dot" "yes")
1892 (set_attr "length" "4,8")])
1894 ;; Split an add that we can't do in one insn into two insns, each of which
1895 ;; does one 16-bit part. This is used by combine. Note that the low-order
1896 ;; add should be last in case the result gets used in an address.
1899 [(set (match_operand:GPR 0 "gpc_reg_operand")
1900 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1901 (match_operand:GPR 2 "non_add_cint_operand")))]
1903 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1904 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1906 HOST_WIDE_INT val = INTVAL (operands[2]);
1907 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1908 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1910 operands[4] = GEN_INT (low);
1911 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1912 operands[3] = GEN_INT (rest);
1913 else if (can_create_pseudo_p ())
1915 operands[3] = gen_reg_rtx (DImode);
1916 emit_move_insn (operands[3], operands[2]);
1917 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1925 (define_insn "add<mode>3_carry"
1926 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1927 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1928 (match_operand:P 2 "reg_or_short_operand" "rI")))
1929 (set (reg:P CA_REGNO)
1930 (ltu:P (plus:P (match_dup 1)
1935 [(set_attr "type" "add")])
1937 (define_insn "*add<mode>3_imm_carry_pos"
1938 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1939 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1940 (match_operand:P 2 "short_cint_operand" "n")))
1941 (set (reg:P CA_REGNO)
1942 (geu:P (match_dup 1)
1943 (match_operand:P 3 "const_int_operand" "n")))]
1944 "INTVAL (operands[2]) > 0
1945 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1947 [(set_attr "type" "add")])
1949 (define_insn "*add<mode>3_imm_carry_0"
1950 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1951 (match_operand:P 1 "gpc_reg_operand" "r"))
1952 (set (reg:P CA_REGNO)
1956 [(set_attr "type" "add")])
1958 (define_insn "*add<mode>3_imm_carry_m1"
1959 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1960 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1962 (set (reg:P CA_REGNO)
1967 [(set_attr "type" "add")])
1969 (define_insn "*add<mode>3_imm_carry_neg"
1970 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1971 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1972 (match_operand:P 2 "short_cint_operand" "n")))
1973 (set (reg:P CA_REGNO)
1974 (gtu:P (match_dup 1)
1975 (match_operand:P 3 "const_int_operand" "n")))]
1976 "INTVAL (operands[2]) < 0
1977 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1979 [(set_attr "type" "add")])
1982 (define_expand "add<mode>3_carry_in"
1984 (set (match_operand:GPR 0 "gpc_reg_operand")
1985 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1986 (match_operand:GPR 2 "adde_operand"))
1987 (reg:GPR CA_REGNO)))
1988 (clobber (reg:GPR CA_REGNO))])]
1991 if (operands[2] == const0_rtx)
1993 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1996 if (operands[2] == constm1_rtx)
1998 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
2003 (define_insn "*add<mode>3_carry_in_internal"
2004 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2005 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2006 (match_operand:GPR 2 "gpc_reg_operand" "r"))
2007 (reg:GPR CA_REGNO)))
2008 (clobber (reg:GPR CA_REGNO))]
2011 [(set_attr "type" "add")])
2013 (define_insn "*add<mode>3_carry_in_internal2"
2014 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2015 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2017 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2018 (clobber (reg:GPR CA_REGNO))]
2021 [(set_attr "type" "add")])
2023 (define_insn "add<mode>3_carry_in_0"
2024 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2025 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2026 (reg:GPR CA_REGNO)))
2027 (clobber (reg:GPR CA_REGNO))]
2030 [(set_attr "type" "add")])
2032 (define_insn "add<mode>3_carry_in_m1"
2033 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2034 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
2037 (clobber (reg:GPR CA_REGNO))]
2040 [(set_attr "type" "add")])
2043 (define_expand "one_cmpl<mode>2"
2044 [(set (match_operand:SDI 0 "gpc_reg_operand")
2045 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
2048 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2050 rs6000_split_logical (operands, NOT, false, false, false);
2055 (define_insn "*one_cmpl<mode>2"
2056 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2057 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2061 (define_insn_and_split "*one_cmpl<mode>2_dot"
2062 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2063 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2065 (clobber (match_scratch:GPR 0 "=r,r"))]
2066 "<MODE>mode == Pmode"
2070 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2072 (not:GPR (match_dup 1)))
2074 (compare:CC (match_dup 0)
2077 [(set_attr "type" "logical")
2078 (set_attr "dot" "yes")
2079 (set_attr "length" "4,8")])
2081 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2082 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2083 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2085 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2086 (not:GPR (match_dup 1)))]
2087 "<MODE>mode == Pmode"
2091 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2093 (not:GPR (match_dup 1)))
2095 (compare:CC (match_dup 0)
2098 [(set_attr "type" "logical")
2099 (set_attr "dot" "yes")
2100 (set_attr "length" "4,8")])
2103 (define_expand "sub<mode>3"
2104 [(set (match_operand:SDI 0 "gpc_reg_operand")
2105 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2106 (match_operand:SDI 2 "gpc_reg_operand")))]
2109 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2111 rtx lo0 = gen_lowpart (SImode, operands[0]);
2112 rtx lo1 = gen_lowpart (SImode, operands[1]);
2113 rtx lo2 = gen_lowpart (SImode, operands[2]);
2114 rtx hi0 = gen_highpart (SImode, operands[0]);
2115 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2116 rtx hi2 = gen_highpart (SImode, operands[2]);
2118 if (!reg_or_short_operand (lo1, SImode))
2119 lo1 = force_reg (SImode, lo1);
2120 if (!adde_operand (hi1, SImode))
2121 hi1 = force_reg (SImode, hi1);
2123 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2124 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2128 if (short_cint_operand (operands[1], <MODE>mode))
2130 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2135 (define_insn "*subf<mode>3"
2136 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2137 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2138 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2141 [(set_attr "type" "add")])
2143 (define_insn_and_split "*subf<mode>3_dot"
2144 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2145 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2146 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2148 (clobber (match_scratch:GPR 0 "=r,r"))]
2149 "<MODE>mode == Pmode"
2153 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2155 (minus:GPR (match_dup 2)
2158 (compare:CC (match_dup 0)
2161 [(set_attr "type" "add")
2162 (set_attr "dot" "yes")
2163 (set_attr "length" "4,8")])
2165 (define_insn_and_split "*subf<mode>3_dot2"
2166 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2167 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2168 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2170 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2171 (minus:GPR (match_dup 2)
2173 "<MODE>mode == Pmode"
2177 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2179 (minus:GPR (match_dup 2)
2182 (compare:CC (match_dup 0)
2185 [(set_attr "type" "add")
2186 (set_attr "dot" "yes")
2187 (set_attr "length" "4,8")])
2189 (define_insn "subf<mode>3_imm"
2190 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2191 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2192 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2193 (clobber (reg:GPR CA_REGNO))]
2196 [(set_attr "type" "add")])
2198 (define_insn_and_split "subf<mode>3_carry_dot2"
2199 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2200 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2201 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2203 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2204 (minus:P (match_dup 2)
2206 (set (reg:P CA_REGNO)
2207 (leu:P (match_dup 1)
2209 "<MODE>mode == Pmode"
2213 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2214 [(parallel [(set (match_dup 0)
2215 (minus:P (match_dup 2)
2217 (set (reg:P CA_REGNO)
2218 (leu:P (match_dup 1)
2221 (compare:CC (match_dup 0)
2224 [(set_attr "type" "add")
2225 (set_attr "dot" "yes")
2226 (set_attr "length" "4,8")])
2228 (define_insn "subf<mode>3_carry"
2229 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2230 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2231 (match_operand:P 1 "gpc_reg_operand" "r")))
2232 (set (reg:P CA_REGNO)
2233 (leu:P (match_dup 1)
2237 [(set_attr "type" "add")])
2239 (define_insn "*subf<mode>3_imm_carry_0"
2240 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2241 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2242 (set (reg:P CA_REGNO)
2247 [(set_attr "type" "add")])
2249 (define_insn "*subf<mode>3_imm_carry_m1"
2250 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2251 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2252 (set (reg:P CA_REGNO)
2256 [(set_attr "type" "add")])
2259 (define_expand "subf<mode>3_carry_in"
2261 (set (match_operand:GPR 0 "gpc_reg_operand")
2262 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2264 (match_operand:GPR 2 "adde_operand")))
2265 (clobber (reg:GPR CA_REGNO))])]
2268 if (operands[2] == const0_rtx)
2270 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2273 if (operands[2] == constm1_rtx)
2275 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2280 (define_insn "*subf<mode>3_carry_in_internal"
2281 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2282 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2284 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2285 (clobber (reg:GPR CA_REGNO))]
2288 [(set_attr "type" "add")])
2290 (define_insn "subf<mode>3_carry_in_0"
2291 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2292 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2293 (reg:GPR CA_REGNO)))
2294 (clobber (reg:GPR CA_REGNO))]
2297 [(set_attr "type" "add")])
2299 (define_insn "subf<mode>3_carry_in_m1"
2300 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2301 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2302 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2304 (clobber (reg:GPR CA_REGNO))]
2307 [(set_attr "type" "add")])
2309 (define_insn "subf<mode>3_carry_in_xx"
2310 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2311 (plus:GPR (reg:GPR CA_REGNO)
2313 (clobber (reg:GPR CA_REGNO))]
2316 [(set_attr "type" "add")])
2319 (define_insn "@neg<mode>2"
2320 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2321 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2324 [(set_attr "type" "add")])
2326 (define_insn_and_split "*neg<mode>2_dot"
2327 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2328 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2330 (clobber (match_scratch:GPR 0 "=r,r"))]
2331 "<MODE>mode == Pmode"
2335 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2337 (neg:GPR (match_dup 1)))
2339 (compare:CC (match_dup 0)
2342 [(set_attr "type" "add")
2343 (set_attr "dot" "yes")
2344 (set_attr "length" "4,8")])
2346 (define_insn_and_split "*neg<mode>2_dot2"
2347 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2348 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2350 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2351 (neg:GPR (match_dup 1)))]
2352 "<MODE>mode == Pmode"
2356 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2358 (neg:GPR (match_dup 1)))
2360 (compare:CC (match_dup 0)
2363 [(set_attr "type" "add")
2364 (set_attr "dot" "yes")
2365 (set_attr "length" "4,8")])
2368 (define_insn "clz<mode>2"
2369 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2370 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2373 [(set_attr "type" "cntlz")])
2375 (define_expand "ctz<mode>2"
2376 [(set (match_operand:GPR 0 "gpc_reg_operand")
2377 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2382 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2386 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2387 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2388 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2392 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2393 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2394 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2395 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2399 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2400 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2401 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2402 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2408 (define_insn "ctz<mode>2_hw"
2409 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2410 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2413 [(set_attr "type" "cntlz")])
2415 (define_expand "ffs<mode>2"
2416 [(set (match_operand:GPR 0 "gpc_reg_operand")
2417 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2420 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2421 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2422 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2423 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2424 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2425 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2426 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2431 (define_expand "popcount<mode>2"
2432 [(set (match_operand:GPR 0 "gpc_reg_operand")
2433 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2434 "TARGET_POPCNTB || TARGET_POPCNTD"
2436 rs6000_emit_popcount (operands[0], operands[1]);
2440 (define_insn "popcntb<mode>2"
2441 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2442 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2446 [(set_attr "type" "popcnt")])
2448 (define_insn "popcntd<mode>2"
2449 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2450 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2453 [(set_attr "type" "popcnt")])
2456 (define_expand "parity<mode>2"
2457 [(set (match_operand:GPR 0 "gpc_reg_operand")
2458 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2461 rs6000_emit_parity (operands[0], operands[1]);
2465 (define_insn "parity<mode>2_cmpb"
2466 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2467 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2468 "TARGET_CMPB && TARGET_POPCNTB"
2470 [(set_attr "type" "popcnt")])
2472 (define_insn "cfuged"
2473 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2474 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2475 (match_operand:DI 2 "gpc_reg_operand" "r")]
2477 "TARGET_POWER10 && TARGET_64BIT"
2479 [(set_attr "type" "integer")])
2481 (define_insn "cntlzdm"
2482 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2483 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2484 (match_operand:DI 2 "gpc_reg_operand" "r")]
2486 "TARGET_POWER10 && TARGET_POWERPC64"
2488 [(set_attr "type" "integer")])
2490 (define_insn "cnttzdm"
2491 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2492 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2493 (match_operand:DI 2 "gpc_reg_operand" "r")]
2495 "TARGET_POWER10 && TARGET_POWERPC64"
2497 [(set_attr "type" "integer")])
2499 (define_insn "pdepd"
2500 [(set (match_operand:DI 0 "register_operand" "=r")
2501 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2502 (match_operand:DI 2 "gpc_reg_operand" "r")]
2504 "TARGET_POWER10 && TARGET_POWERPC64"
2506 [(set_attr "type" "integer")])
2508 (define_insn "pextd"
2509 [(set (match_operand:DI 0 "register_operand" "=r")
2510 (unspec:DI [(match_operand:DI 1 "gpc_reg_operand" "r")
2511 (match_operand:DI 2 "gpc_reg_operand" "r")]
2513 "TARGET_POWER10 && TARGET_POWERPC64"
2515 [(set_attr "type" "integer")])
2517 (define_insn "cmpb<mode>3"
2518 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2519 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2520 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2523 [(set_attr "type" "cmp")])
2525 ;; Since the hardware zeros the upper part of the register, save generating the
2526 ;; AND immediate if we are converting to unsigned
2527 (define_insn "*bswap<mode>2_extenddi"
2528 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2530 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2533 [(set_attr "type" "load")])
2535 (define_insn "*bswaphi2_extendsi"
2536 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2538 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2541 [(set_attr "type" "load")])
2543 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2544 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2545 ;; load with byte swap, which can be slower than doing it in the registers. It
2546 ;; also prevents certain failures with the RELOAD register allocator.
2548 (define_expand "bswap<mode>2"
2549 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2550 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2553 rtx dest = operands[0];
2554 rtx src = operands[1];
2556 if (!REG_P (dest) && !REG_P (src))
2557 src = force_reg (<MODE>mode, src);
2561 src = rs6000_force_indexed_or_indirect_mem (src);
2562 emit_insn (gen_bswap<mode>2_load (dest, src));
2564 else if (MEM_P (dest))
2566 dest = rs6000_force_indexed_or_indirect_mem (dest);
2567 emit_insn (gen_bswap<mode>2_store (dest, src));
2570 emit_insn (gen_bswap<mode>2_reg (dest, src));
2574 (define_insn "bswap<mode>2_load"
2575 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2576 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2579 [(set_attr "type" "load")])
2581 (define_insn "bswap<mode>2_store"
2582 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2583 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2586 [(set_attr "type" "store")])
2588 (define_insn_and_split "bswaphi2_reg"
2589 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2591 (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2592 (clobber (match_scratch:SI 2 "=&r,X"))]
2597 "reload_completed && int_reg_operand (operands[0], HImode)"
2599 (and:SI (lshiftrt:SI (match_dup 4)
2603 (and:SI (ashift:SI (match_dup 4)
2605 (const_int 65280))) ;; 0xff00
2607 (ior:SI (match_dup 3)
2610 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2611 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2613 [(set_attr "length" "12,4")
2614 (set_attr "type" "*,vecperm")
2615 (set_attr "isa" "*,p9v")])
2617 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2618 ;; zero_extract insns do not change for -mlittle.
2619 (define_insn_and_split "bswapsi2_reg"
2620 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2622 (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2627 "reload_completed && int_reg_operand (operands[0], SImode)"
2628 [(set (match_dup 0) ; DABC
2629 (rotate:SI (match_dup 1)
2631 (set (match_dup 0) ; DCBC
2632 (ior:SI (and:SI (ashift:SI (match_dup 1)
2634 (const_int 16711680))
2635 (and:SI (match_dup 0)
2636 (const_int -16711681))))
2637 (set (match_dup 0) ; DCBA
2638 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2641 (and:SI (match_dup 0)
2642 (const_int -256))))]
2644 [(set_attr "length" "12,4")
2645 (set_attr "type" "*,vecperm")
2646 (set_attr "isa" "*,p9v")])
2648 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2649 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2652 (define_expand "bswapdi2"
2653 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2655 (match_operand:DI 1 "reg_or_mem_operand")))
2656 (clobber (match_scratch:DI 2))
2657 (clobber (match_scratch:DI 3))])]
2660 rtx dest = operands[0];
2661 rtx src = operands[1];
2663 if (!REG_P (dest) && !REG_P (src))
2664 operands[1] = src = force_reg (DImode, src);
2666 if (TARGET_POWERPC64 && TARGET_LDBRX)
2670 src = rs6000_force_indexed_or_indirect_mem (src);
2671 emit_insn (gen_bswapdi2_load (dest, src));
2673 else if (MEM_P (dest))
2675 dest = rs6000_force_indexed_or_indirect_mem (dest);
2676 emit_insn (gen_bswapdi2_store (dest, src));
2678 else if (TARGET_P9_VECTOR)
2679 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2681 emit_insn (gen_bswapdi2_reg (dest, src));
2685 if (!TARGET_POWERPC64)
2687 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2688 that uses 64-bit registers needs the same scratch registers as 64-bit
2690 emit_insn (gen_bswapdi2_32bit (dest, src));
2695 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2696 (define_insn "bswapdi2_load"
2697 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2698 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2699 "TARGET_POWERPC64 && TARGET_LDBRX"
2701 [(set_attr "type" "load")])
2703 (define_insn "bswapdi2_store"
2704 [(set (match_operand:DI 0 "memory_operand" "=Z")
2705 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2706 "TARGET_POWERPC64 && TARGET_LDBRX"
2708 [(set_attr "type" "store")])
2710 (define_insn "bswapdi2_xxbrd"
2711 [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2712 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2715 [(set_attr "type" "vecperm")
2716 (set_attr "isa" "p9v")])
2718 (define_insn "bswapdi2_reg"
2719 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2720 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2721 (clobber (match_scratch:DI 2 "=&r"))
2722 (clobber (match_scratch:DI 3 "=&r"))]
2723 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2725 [(set_attr "length" "36")])
2727 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2728 (define_insn "*bswapdi2_64bit"
2729 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2730 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2731 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2732 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2733 "TARGET_POWERPC64 && !TARGET_LDBRX
2734 && (REG_P (operands[0]) || REG_P (operands[1]))
2735 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2736 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2738 [(set_attr "length" "16,12,36")])
2741 [(set (match_operand:DI 0 "gpc_reg_operand")
2742 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2743 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2744 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2745 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2748 rtx dest = operands[0];
2749 rtx src = operands[1];
2750 rtx op2 = operands[2];
2751 rtx op3 = operands[3];
2752 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2753 BYTES_BIG_ENDIAN ? 4 : 0);
2754 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2755 BYTES_BIG_ENDIAN ? 4 : 0);
2761 addr1 = XEXP (src, 0);
2762 if (GET_CODE (addr1) == PLUS)
2764 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2765 if (TARGET_AVOID_XFORM)
2767 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2771 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2773 else if (TARGET_AVOID_XFORM)
2775 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2780 emit_move_insn (op2, GEN_INT (4));
2781 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2784 word1 = change_address (src, SImode, addr1);
2785 word2 = change_address (src, SImode, addr2);
2787 if (BYTES_BIG_ENDIAN)
2789 emit_insn (gen_bswapsi2 (op3_32, word2));
2790 emit_insn (gen_bswapsi2 (dest_32, word1));
2794 emit_insn (gen_bswapsi2 (op3_32, word1));
2795 emit_insn (gen_bswapsi2 (dest_32, word2));
2798 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2799 emit_insn (gen_iordi3 (dest, dest, op3));
2804 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2805 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2806 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2807 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2808 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2811 rtx dest = operands[0];
2812 rtx src = operands[1];
2813 rtx op2 = operands[2];
2814 rtx op3 = operands[3];
2815 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2816 BYTES_BIG_ENDIAN ? 4 : 0);
2817 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2818 BYTES_BIG_ENDIAN ? 4 : 0);
2824 addr1 = XEXP (dest, 0);
2825 if (GET_CODE (addr1) == PLUS)
2827 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2828 if (TARGET_AVOID_XFORM)
2830 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2834 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2836 else if (TARGET_AVOID_XFORM)
2838 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2843 emit_move_insn (op2, GEN_INT (4));
2844 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2847 word1 = change_address (dest, SImode, addr1);
2848 word2 = change_address (dest, SImode, addr2);
2850 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2852 if (BYTES_BIG_ENDIAN)
2854 emit_insn (gen_bswapsi2 (word1, src_si));
2855 emit_insn (gen_bswapsi2 (word2, op3_si));
2859 emit_insn (gen_bswapsi2 (word2, src_si));
2860 emit_insn (gen_bswapsi2 (word1, op3_si));
2866 [(set (match_operand:DI 0 "gpc_reg_operand")
2867 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2868 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2869 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2870 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2873 rtx dest = operands[0];
2874 rtx src = operands[1];
2875 rtx op2 = operands[2];
2876 rtx op3 = operands[3];
2877 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2878 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2879 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2880 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2881 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2883 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2884 emit_insn (gen_bswapsi2 (dest_si, src_si));
2885 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2886 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2887 emit_insn (gen_iordi3 (dest, dest, op3));
2891 (define_insn "bswapdi2_32bit"
2892 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2893 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2894 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2895 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2897 [(set_attr "length" "16,12,36")])
2900 [(set (match_operand:DI 0 "gpc_reg_operand")
2901 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2902 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2903 "!TARGET_POWERPC64 && reload_completed"
2906 rtx dest = operands[0];
2907 rtx src = operands[1];
2908 rtx op2 = operands[2];
2909 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2910 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2916 addr1 = XEXP (src, 0);
2917 if (GET_CODE (addr1) == PLUS)
2919 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2920 if (TARGET_AVOID_XFORM
2921 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2923 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2927 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2929 else if (TARGET_AVOID_XFORM
2930 || REGNO (addr1) == REGNO (dest2))
2932 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2937 emit_move_insn (op2, GEN_INT (4));
2938 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2941 word1 = change_address (src, SImode, addr1);
2942 word2 = change_address (src, SImode, addr2);
2944 emit_insn (gen_bswapsi2 (dest2, word1));
2945 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2946 thus allowing us to omit an early clobber on the output. */
2947 emit_insn (gen_bswapsi2 (dest1, word2));
2952 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2953 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2954 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2955 "!TARGET_POWERPC64 && reload_completed"
2958 rtx dest = operands[0];
2959 rtx src = operands[1];
2960 rtx op2 = operands[2];
2961 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2962 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2968 addr1 = XEXP (dest, 0);
2969 if (GET_CODE (addr1) == PLUS)
2971 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2972 if (TARGET_AVOID_XFORM)
2974 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2978 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2980 else if (TARGET_AVOID_XFORM)
2982 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2987 emit_move_insn (op2, GEN_INT (4));
2988 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2991 word1 = change_address (dest, SImode, addr1);
2992 word2 = change_address (dest, SImode, addr2);
2994 emit_insn (gen_bswapsi2 (word2, src1));
2995 emit_insn (gen_bswapsi2 (word1, src2));
3000 [(set (match_operand:DI 0 "gpc_reg_operand")
3001 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
3002 (clobber (match_operand:SI 2 ""))]
3003 "!TARGET_POWERPC64 && reload_completed"
3006 rtx dest = operands[0];
3007 rtx src = operands[1];
3008 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
3009 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
3010 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
3011 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
3013 emit_insn (gen_bswapsi2 (dest1, src2));
3014 emit_insn (gen_bswapsi2 (dest2, src1));
3019 (define_insn "mul<mode>3"
3020 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3021 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3022 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
3027 [(set_attr "type" "mul")
3029 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
3031 (match_operand:GPR 2 "short_cint_operand")
3032 (const_string "16")]
3033 (const_string "<bits>")))])
3035 (define_insn_and_split "*mul<mode>3_dot"
3036 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3037 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3038 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3040 (clobber (match_scratch:GPR 0 "=r,r"))]
3041 "<MODE>mode == Pmode"
3045 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3047 (mult:GPR (match_dup 1)
3050 (compare:CC (match_dup 0)
3053 [(set_attr "type" "mul")
3054 (set_attr "size" "<bits>")
3055 (set_attr "dot" "yes")
3056 (set_attr "length" "4,8")])
3058 (define_insn_and_split "*mul<mode>3_dot2"
3059 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3060 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3061 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3063 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3064 (mult:GPR (match_dup 1)
3066 "<MODE>mode == Pmode"
3070 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3072 (mult:GPR (match_dup 1)
3075 (compare:CC (match_dup 0)
3078 [(set_attr "type" "mul")
3079 (set_attr "size" "<bits>")
3080 (set_attr "dot" "yes")
3081 (set_attr "length" "4,8")])
3084 (define_expand "<su>mul<mode>3_highpart"
3085 [(set (match_operand:GPR 0 "gpc_reg_operand")
3087 (mult:<DMODE> (any_extend:<DMODE>
3088 (match_operand:GPR 1 "gpc_reg_operand"))
3090 (match_operand:GPR 2 "gpc_reg_operand")))
3094 if (<MODE>mode == SImode && TARGET_POWERPC64)
3096 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
3101 if (!WORDS_BIG_ENDIAN)
3103 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
3109 (define_insn "*<su>mul<mode>3_highpart"
3110 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3112 (mult:<DMODE> (any_extend:<DMODE>
3113 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3115 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3117 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3118 "mulh<wd><u> %0,%1,%2"
3119 [(set_attr "type" "mul")
3120 (set_attr "size" "<bits>")])
3122 (define_insn "<su>mulsi3_highpart_le"
3123 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3125 (mult:DI (any_extend:DI
3126 (match_operand:SI 1 "gpc_reg_operand" "r"))
3128 (match_operand:SI 2 "gpc_reg_operand" "r")))
3130 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3132 [(set_attr "type" "mul")])
3134 (define_insn "<su>muldi3_highpart_le"
3135 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3137 (mult:TI (any_extend:TI
3138 (match_operand:DI 1 "gpc_reg_operand" "r"))
3140 (match_operand:DI 2 "gpc_reg_operand" "r")))
3142 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3144 [(set_attr "type" "mul")
3145 (set_attr "size" "64")])
3147 (define_insn "<su>mulsi3_highpart_64"
3148 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3151 (mult:DI (any_extend:DI
3152 (match_operand:SI 1 "gpc_reg_operand" "r"))
3154 (match_operand:SI 2 "gpc_reg_operand" "r")))
3158 [(set_attr "type" "mul")])
3160 (define_expand "<u>mul<mode><dmode>3"
3161 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3162 (mult:<DMODE> (any_extend:<DMODE>
3163 (match_operand:GPR 1 "gpc_reg_operand"))
3165 (match_operand:GPR 2 "gpc_reg_operand"))))]
3166 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3168 rtx l = gen_reg_rtx (<MODE>mode);
3169 rtx h = gen_reg_rtx (<MODE>mode);
3170 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3171 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3172 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3173 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3177 (define_insn "*maddld<mode>4"
3178 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3179 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3180 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3181 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3183 "maddld %0,%1,%2,%3"
3184 [(set_attr "type" "mul")])
3186 (define_insn "udiv<mode>3"
3187 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3188 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3189 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3192 [(set_attr "type" "div")
3193 (set_attr "size" "<bits>")])
3196 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3197 ;; modulus. If it isn't a power of two, force operands into register and do
3199 (define_expand "div<mode>3"
3200 [(set (match_operand:GPR 0 "gpc_reg_operand")
3201 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3202 (match_operand:GPR 2 "reg_or_cint_operand")))]
3205 if (CONST_INT_P (operands[2])
3206 && INTVAL (operands[2]) > 0
3207 && exact_log2 (INTVAL (operands[2])) >= 0)
3209 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3213 operands[2] = force_reg (<MODE>mode, operands[2]);
3216 (define_insn "*div<mode>3"
3217 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3218 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3219 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3222 [(set_attr "type" "div")
3223 (set_attr "size" "<bits>")])
3225 (define_insn "div<mode>3_sra"
3226 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3227 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3228 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3229 (clobber (reg:GPR CA_REGNO))]
3231 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3232 [(set_attr "type" "two")
3233 (set_attr "length" "8")])
3235 (define_insn_and_split "*div<mode>3_sra_dot"
3236 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3237 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3238 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3240 (clobber (match_scratch:GPR 0 "=r,r"))
3241 (clobber (reg:GPR CA_REGNO))]
3242 "<MODE>mode == Pmode"
3244 sra<wd>i %0,%1,%p2\;addze. %0,%0
3246 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3247 [(parallel [(set (match_dup 0)
3248 (div:GPR (match_dup 1)
3250 (clobber (reg:GPR CA_REGNO))])
3252 (compare:CC (match_dup 0)
3255 [(set_attr "type" "two")
3256 (set_attr "length" "8,12")
3257 (set_attr "cell_micro" "not")])
3259 (define_insn_and_split "*div<mode>3_sra_dot2"
3260 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3261 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3262 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3264 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3265 (div:GPR (match_dup 1)
3267 (clobber (reg:GPR CA_REGNO))]
3268 "<MODE>mode == Pmode"
3270 sra<wd>i %0,%1,%p2\;addze. %0,%0
3272 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3273 [(parallel [(set (match_dup 0)
3274 (div:GPR (match_dup 1)
3276 (clobber (reg:GPR CA_REGNO))])
3278 (compare:CC (match_dup 0)
3281 [(set_attr "type" "two")
3282 (set_attr "length" "8,12")
3283 (set_attr "cell_micro" "not")])
3285 (define_expand "mod<mode>3"
3286 [(set (match_operand:GPR 0 "gpc_reg_operand")
3287 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3288 (match_operand:GPR 2 "reg_or_cint_operand")))]
3295 if (!CONST_INT_P (operands[2])
3296 || INTVAL (operands[2]) <= 0
3297 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3302 operands[2] = force_reg (<MODE>mode, operands[2]);
3306 temp1 = gen_reg_rtx (<MODE>mode);
3307 temp2 = gen_reg_rtx (<MODE>mode);
3309 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3310 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3311 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3316 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3317 ;; mod, prefer putting the result of mod into a different register
3318 (define_insn "*mod<mode>3"
3319 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3320 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3321 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3324 [(set_attr "type" "div")
3325 (set_attr "size" "<bits>")])
3328 (define_insn "umod<mode>3"
3329 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3330 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3331 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3334 [(set_attr "type" "div")
3335 (set_attr "size" "<bits>")])
3337 ;; On machines with modulo support, do a combined div/mod the old fashioned
3338 ;; method, since the multiply/subtract is faster than doing the mod instruction
3342 [(set (match_operand:GPR 0 "gpc_reg_operand")
3343 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3344 (match_operand:GPR 2 "gpc_reg_operand")))
3345 (set (match_operand:GPR 3 "gpc_reg_operand")
3346 (mod:GPR (match_dup 1)
3349 && ! reg_mentioned_p (operands[0], operands[1])
3350 && ! reg_mentioned_p (operands[0], operands[2])
3351 && ! reg_mentioned_p (operands[3], operands[1])
3352 && ! reg_mentioned_p (operands[3], operands[2])"
3354 (div:GPR (match_dup 1)
3357 (mult:GPR (match_dup 0)
3360 (minus:GPR (match_dup 1)
3364 [(set (match_operand:GPR 0 "gpc_reg_operand")
3365 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3366 (match_operand:GPR 2 "gpc_reg_operand")))
3367 (set (match_operand:GPR 3 "gpc_reg_operand")
3368 (umod:GPR (match_dup 1)
3371 && ! reg_mentioned_p (operands[0], operands[1])
3372 && ! reg_mentioned_p (operands[0], operands[2])
3373 && ! reg_mentioned_p (operands[3], operands[1])
3374 && ! reg_mentioned_p (operands[3], operands[2])"
3376 (udiv:GPR (match_dup 1)
3379 (mult:GPR (match_dup 0)
3382 (minus:GPR (match_dup 1)
3386 ;; Logical instructions
3387 ;; The logical instructions are mostly combined by using match_operator,
3388 ;; but the plain AND insns are somewhat different because there is no
3389 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3390 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3392 (define_expand "and<mode>3"
3393 [(set (match_operand:SDI 0 "gpc_reg_operand")
3394 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3395 (match_operand:SDI 2 "reg_or_cint_operand")))]
3398 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3400 rs6000_split_logical (operands, AND, false, false, false);
3404 if (CONST_INT_P (operands[2]))
3406 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3408 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3412 if (logical_const_operand (operands[2], <MODE>mode))
3414 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3418 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3420 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3424 operands[2] = force_reg (<MODE>mode, operands[2]);
3429 (define_insn "and<mode>3_imm"
3430 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3431 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3432 (match_operand:GPR 2 "logical_const_operand" "n")))
3433 (clobber (match_scratch:CC 3 "=x"))]
3434 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3435 "andi%e2. %0,%1,%u2"
3436 [(set_attr "type" "logical")
3437 (set_attr "dot" "yes")])
3439 (define_insn_and_split "*and<mode>3_imm_dot"
3440 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3441 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3442 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3444 (clobber (match_scratch:GPR 0 "=r,r"))
3445 (clobber (match_scratch:CC 4 "=X,x"))]
3446 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3447 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3451 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3452 [(parallel [(set (match_dup 0)
3453 (and:GPR (match_dup 1)
3455 (clobber (match_dup 4))])
3457 (compare:CC (match_dup 0)
3460 [(set_attr "type" "logical")
3461 (set_attr "dot" "yes")
3462 (set_attr "length" "4,8")])
3464 (define_insn_and_split "*and<mode>3_imm_dot2"
3465 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3466 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3467 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3469 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3470 (and:GPR (match_dup 1)
3472 (clobber (match_scratch:CC 4 "=X,x"))]
3473 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3474 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3478 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3479 [(parallel [(set (match_dup 0)
3480 (and:GPR (match_dup 1)
3482 (clobber (match_dup 4))])
3484 (compare:CC (match_dup 0)
3487 [(set_attr "type" "logical")
3488 (set_attr "dot" "yes")
3489 (set_attr "length" "4,8")])
3491 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3492 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3493 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3494 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3496 (clobber (match_scratch:GPR 0 "=r,r"))]
3497 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3498 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3502 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3504 (and:GPR (match_dup 1)
3507 (compare:CC (match_dup 0)
3510 [(set_attr "type" "logical")
3511 (set_attr "dot" "yes")
3512 (set_attr "length" "4,8")])
3514 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3515 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3516 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3517 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3519 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3520 (and:GPR (match_dup 1)
3522 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3523 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3527 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3529 (and:GPR (match_dup 1)
3532 (compare:CC (match_dup 0)
3535 [(set_attr "type" "logical")
3536 (set_attr "dot" "yes")
3537 (set_attr "length" "4,8")])
3539 (define_insn "*and<mode>3_imm_dot_shifted"
3540 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3543 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3544 (match_operand:SI 4 "const_int_operand" "n"))
3545 (match_operand:GPR 2 "const_int_operand" "n"))
3547 (clobber (match_scratch:GPR 0 "=r"))]
3548 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3549 << INTVAL (operands[4])),
3551 && (<MODE>mode == Pmode
3552 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3554 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3555 return "andi%e2. %0,%1,%u2";
3557 [(set_attr "type" "logical")
3558 (set_attr "dot" "yes")])
3561 (define_insn "and<mode>3_mask"
3562 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3563 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3564 (match_operand:GPR 2 "const_int_operand" "n")))]
3565 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3567 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3569 [(set_attr "type" "shift")])
3571 (define_insn_and_split "*and<mode>3_mask_dot"
3572 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3573 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3574 (match_operand:GPR 2 "const_int_operand" "n,n"))
3576 (clobber (match_scratch:GPR 0 "=r,r"))]
3577 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3578 && !logical_const_operand (operands[2], <MODE>mode)
3579 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3581 if (which_alternative == 0)
3582 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3586 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3588 (and:GPR (match_dup 1)
3591 (compare:CC (match_dup 0)
3594 [(set_attr "type" "shift")
3595 (set_attr "dot" "yes")
3596 (set_attr "length" "4,8")])
3598 (define_insn_and_split "*and<mode>3_mask_dot2"
3599 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3600 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3601 (match_operand:GPR 2 "const_int_operand" "n,n"))
3603 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3604 (and:GPR (match_dup 1)
3606 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3607 && !logical_const_operand (operands[2], <MODE>mode)
3608 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3610 if (which_alternative == 0)
3611 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3615 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3617 (and:GPR (match_dup 1)
3620 (compare:CC (match_dup 0)
3623 [(set_attr "type" "shift")
3624 (set_attr "dot" "yes")
3625 (set_attr "length" "4,8")])
3628 (define_insn_and_split "*and<mode>3_2insn"
3629 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3630 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3631 (match_operand:GPR 2 "const_int_operand" "n")))]
3632 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3633 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3634 || logical_const_operand (operands[2], <MODE>mode))"
3639 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3642 [(set_attr "type" "shift")
3643 (set_attr "length" "8")])
3645 (define_insn_and_split "*and<mode>3_2insn_dot"
3646 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3647 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3648 (match_operand:GPR 2 "const_int_operand" "n,n"))
3650 (clobber (match_scratch:GPR 0 "=r,r"))]
3651 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3652 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3653 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3654 || logical_const_operand (operands[2], <MODE>mode))"
3656 "&& reload_completed"
3659 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3662 [(set_attr "type" "shift")
3663 (set_attr "dot" "yes")
3664 (set_attr "length" "8,12")])
3666 (define_insn_and_split "*and<mode>3_2insn_dot2"
3667 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3668 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3669 (match_operand:GPR 2 "const_int_operand" "n,n"))
3671 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3672 (and:GPR (match_dup 1)
3674 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3675 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3676 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3677 || logical_const_operand (operands[2], <MODE>mode))"
3679 "&& reload_completed"
3682 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3685 [(set_attr "type" "shift")
3686 (set_attr "dot" "yes")
3687 (set_attr "length" "8,12")])
3690 (define_expand "<code><mode>3"
3691 [(set (match_operand:SDI 0 "gpc_reg_operand")
3692 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3693 (match_operand:SDI 2 "reg_or_cint_operand")))]
3696 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3698 rs6000_split_logical (operands, <CODE>, false, false, false);
3702 if (non_logical_cint_operand (operands[2], <MODE>mode))
3704 rtx tmp = ((!can_create_pseudo_p ()
3705 || rtx_equal_p (operands[0], operands[1]))
3706 ? operands[0] : gen_reg_rtx (<MODE>mode));
3708 HOST_WIDE_INT value = INTVAL (operands[2]);
3709 HOST_WIDE_INT lo = value & 0xffff;
3710 HOST_WIDE_INT hi = value - lo;
3712 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3713 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3717 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3718 operands[2] = force_reg (<MODE>mode, operands[2]);
3722 [(set (match_operand:GPR 0 "gpc_reg_operand")
3723 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3724 (match_operand:GPR 2 "non_logical_cint_operand")))]
3727 (iorxor:GPR (match_dup 1)
3730 (iorxor:GPR (match_dup 3)
3733 operands[3] = ((!can_create_pseudo_p ()
3734 || rtx_equal_p (operands[0], operands[1]))
3735 ? operands[0] : gen_reg_rtx (<MODE>mode));
3737 HOST_WIDE_INT value = INTVAL (operands[2]);
3738 HOST_WIDE_INT lo = value & 0xffff;
3739 HOST_WIDE_INT hi = value - lo;
3741 operands[4] = GEN_INT (hi);
3742 operands[5] = GEN_INT (lo);
3745 (define_insn "*bool<mode>3_imm"
3746 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3747 (match_operator:GPR 3 "boolean_or_operator"
3748 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3749 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3752 [(set_attr "type" "logical")])
3754 (define_insn "*bool<mode>3"
3755 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3756 (match_operator:GPR 3 "boolean_operator"
3757 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3758 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3761 [(set_attr "type" "logical")])
3763 (define_insn_and_split "*bool<mode>3_dot"
3764 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3765 (compare:CC (match_operator:GPR 3 "boolean_operator"
3766 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3767 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3769 (clobber (match_scratch:GPR 0 "=r,r"))]
3770 "<MODE>mode == Pmode"
3774 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3778 (compare:CC (match_dup 0)
3781 [(set_attr "type" "logical")
3782 (set_attr "dot" "yes")
3783 (set_attr "length" "4,8")])
3785 (define_insn_and_split "*bool<mode>3_dot2"
3786 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3787 (compare:CC (match_operator:GPR 3 "boolean_operator"
3788 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3789 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3791 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3793 "<MODE>mode == Pmode"
3797 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3801 (compare:CC (match_dup 0)
3804 [(set_attr "type" "logical")
3805 (set_attr "dot" "yes")
3806 (set_attr "length" "4,8")])
3809 (define_insn "*boolc<mode>3"
3810 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3811 (match_operator:GPR 3 "boolean_operator"
3812 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3813 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3816 [(set_attr "type" "logical")])
3818 (define_insn_and_split "*boolc<mode>3_dot"
3819 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3820 (compare:CC (match_operator:GPR 3 "boolean_operator"
3821 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3822 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3824 (clobber (match_scratch:GPR 0 "=r,r"))]
3825 "<MODE>mode == Pmode"
3829 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3833 (compare:CC (match_dup 0)
3836 [(set_attr "type" "logical")
3837 (set_attr "dot" "yes")
3838 (set_attr "length" "4,8")])
3840 (define_insn_and_split "*boolc<mode>3_dot2"
3841 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3842 (compare:CC (match_operator:GPR 3 "boolean_operator"
3843 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3844 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3846 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3848 "<MODE>mode == Pmode"
3852 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3856 (compare:CC (match_dup 0)
3859 [(set_attr "type" "logical")
3860 (set_attr "dot" "yes")
3861 (set_attr "length" "4,8")])
3864 (define_insn "*boolcc<mode>3"
3865 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866 (match_operator:GPR 3 "boolean_operator"
3867 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3868 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3871 [(set_attr "type" "logical")])
3873 (define_insn_and_split "*boolcc<mode>3_dot"
3874 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3875 (compare:CC (match_operator:GPR 3 "boolean_operator"
3876 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3877 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3879 (clobber (match_scratch:GPR 0 "=r,r"))]
3880 "<MODE>mode == Pmode"
3884 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3888 (compare:CC (match_dup 0)
3891 [(set_attr "type" "logical")
3892 (set_attr "dot" "yes")
3893 (set_attr "length" "4,8")])
3895 (define_insn_and_split "*boolcc<mode>3_dot2"
3896 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3897 (compare:CC (match_operator:GPR 3 "boolean_operator"
3898 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3899 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3901 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3903 "<MODE>mode == Pmode"
3907 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3911 (compare:CC (match_dup 0)
3914 [(set_attr "type" "logical")
3915 (set_attr "dot" "yes")
3916 (set_attr "length" "4,8")])
3919 ;; TODO: Should have dots of this as well.
3920 (define_insn "*eqv<mode>3"
3921 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3922 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3923 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3926 [(set_attr "type" "logical")])
3928 ;; Rotate-and-mask and insert.
3930 (define_insn "*rotl<mode>3_mask"
3931 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3932 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3933 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3934 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3935 (match_operand:GPR 3 "const_int_operand" "n")))]
3936 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3938 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3940 [(set_attr "type" "shift")
3941 (set_attr "maybe_var_shift" "yes")])
3943 (define_insn_and_split "*rotl<mode>3_mask_dot"
3944 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3946 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3947 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3948 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3949 (match_operand:GPR 3 "const_int_operand" "n,n"))
3951 (clobber (match_scratch:GPR 0 "=r,r"))]
3952 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3953 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3955 if (which_alternative == 0)
3956 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3960 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3962 (and:GPR (match_dup 4)
3965 (compare:CC (match_dup 0)
3968 [(set_attr "type" "shift")
3969 (set_attr "maybe_var_shift" "yes")
3970 (set_attr "dot" "yes")
3971 (set_attr "length" "4,8")])
3973 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3974 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3976 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3977 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3978 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3979 (match_operand:GPR 3 "const_int_operand" "n,n"))
3981 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3982 (and:GPR (match_dup 4)
3984 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3985 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3987 if (which_alternative == 0)
3988 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3992 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3994 (and:GPR (match_dup 4)
3997 (compare:CC (match_dup 0)
4000 [(set_attr "type" "shift")
4001 (set_attr "maybe_var_shift" "yes")
4002 (set_attr "dot" "yes")
4003 (set_attr "length" "4,8")])
4005 ; Special case for less-than-0. We can do it with just one machine
4006 ; instruction, but the generic optimizers do not realise it is cheap.
4007 (define_insn "*lt0_<mode>di"
4008 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4009 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
4013 [(set_attr "type" "shift")])
4015 (define_insn "*lt0_<mode>si"
4016 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4017 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
4020 "rlwinm %0,%1,1,31,31"
4021 [(set_attr "type" "shift")])
4025 ; Two forms for insert (the two arms of the IOR are not canonicalized,
4026 ; both are an AND so are the same precedence).
4027 (define_insn "*rotl<mode>3_insert"
4028 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4029 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4030 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4031 (match_operand:SI 2 "const_int_operand" "n")])
4032 (match_operand:GPR 3 "const_int_operand" "n"))
4033 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4034 (match_operand:GPR 6 "const_int_operand" "n"))))]
4035 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4036 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4038 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4040 [(set_attr "type" "insert")])
4041 ; FIXME: this needs an attr "size", so that the scheduler can see the
4042 ; difference between rlwimi and rldimi. We also might want dot forms,
4043 ; but not for rlwimi on POWER4 and similar processors.
4045 (define_insn "*rotl<mode>3_insert_2"
4046 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4047 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
4048 (match_operand:GPR 6 "const_int_operand" "n"))
4049 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
4050 [(match_operand:GPR 1 "gpc_reg_operand" "r")
4051 (match_operand:SI 2 "const_int_operand" "n")])
4052 (match_operand:GPR 3 "const_int_operand" "n"))))]
4053 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
4054 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
4056 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
4058 [(set_attr "type" "insert")])
4060 ; There are also some forms without one of the ANDs.
4061 (define_insn "*rotl<mode>3_insert_3"
4062 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4063 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4064 (match_operand:GPR 4 "const_int_operand" "n"))
4065 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4066 (match_operand:SI 2 "const_int_operand" "n"))))]
4067 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
4069 if (<MODE>mode == SImode)
4070 return "rlwimi %0,%1,%h2,0,31-%h2";
4072 return "rldimi %0,%1,%H2,0";
4074 [(set_attr "type" "insert")])
4076 (define_insn "*rotl<mode>3_insert_4"
4077 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4078 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
4079 (match_operand:GPR 4 "const_int_operand" "n"))
4080 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4081 (match_operand:SI 2 "const_int_operand" "n"))))]
4082 "<MODE>mode == SImode &&
4083 GET_MODE_PRECISION (<MODE>mode)
4084 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
4086 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
4087 - INTVAL (operands[2]));
4088 if (<MODE>mode == SImode)
4089 return "rlwimi %0,%1,%h2,32-%h2,31";
4091 return "rldimi %0,%1,%H2,64-%H2";
4093 [(set_attr "type" "insert")])
4095 (define_insn "*rotlsi3_insert_5"
4096 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
4097 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
4098 (match_operand:SI 2 "const_int_operand" "n,n"))
4099 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
4100 (match_operand:SI 4 "const_int_operand" "n,n"))))]
4101 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
4102 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
4103 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4107 [(set_attr "type" "insert")])
4109 (define_insn "*rotldi3_insert_6"
4110 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4111 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4112 (match_operand:DI 2 "const_int_operand" "n"))
4113 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4114 (match_operand:DI 4 "const_int_operand" "n"))))]
4115 "exact_log2 (-UINTVAL (operands[2])) > 0
4116 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4118 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4119 return "rldimi %0,%3,0,%5";
4121 [(set_attr "type" "insert")
4122 (set_attr "size" "64")])
4124 (define_insn "*rotldi3_insert_7"
4125 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4126 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4127 (match_operand:DI 4 "const_int_operand" "n"))
4128 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4129 (match_operand:DI 2 "const_int_operand" "n"))))]
4130 "exact_log2 (-UINTVAL (operands[2])) > 0
4131 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4133 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4134 return "rldimi %0,%3,0,%5";
4136 [(set_attr "type" "insert")
4137 (set_attr "size" "64")])
4140 ; This handles the important case of multiple-precision shifts. There is
4141 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4143 [(set (match_operand:GPR 0 "gpc_reg_operand")
4144 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4145 (match_operand:SI 3 "const_int_operand"))
4146 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4147 (match_operand:SI 4 "const_int_operand"))))]
4148 "can_create_pseudo_p ()
4149 && INTVAL (operands[3]) + INTVAL (operands[4])
4150 >= GET_MODE_PRECISION (<MODE>mode)"
4152 (lshiftrt:GPR (match_dup 2)
4155 (ior:GPR (and:GPR (match_dup 5)
4157 (ashift:GPR (match_dup 1)
4160 unsigned HOST_WIDE_INT mask = 1;
4161 mask = (mask << INTVAL (operands[3])) - 1;
4162 operands[5] = gen_reg_rtx (<MODE>mode);
4163 operands[6] = GEN_INT (mask);
4167 [(set (match_operand:GPR 0 "gpc_reg_operand")
4168 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4169 (match_operand:SI 4 "const_int_operand"))
4170 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4171 (match_operand:SI 3 "const_int_operand"))))]
4172 "can_create_pseudo_p ()
4173 && INTVAL (operands[3]) + INTVAL (operands[4])
4174 >= GET_MODE_PRECISION (<MODE>mode)"
4176 (lshiftrt:GPR (match_dup 2)
4179 (ior:GPR (and:GPR (match_dup 5)
4181 (ashift:GPR (match_dup 1)
4184 unsigned HOST_WIDE_INT mask = 1;
4185 mask = (mask << INTVAL (operands[3])) - 1;
4186 operands[5] = gen_reg_rtx (<MODE>mode);
4187 operands[6] = GEN_INT (mask);
4191 ; Another important case is setting some bits to 1; we can do that with
4192 ; an insert instruction, in many cases.
4193 (define_insn_and_split "*ior<mode>_mask"
4194 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4195 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4196 (match_operand:GPR 2 "const_int_operand" "n")))
4197 (clobber (match_scratch:GPR 3 "=r"))]
4198 "!logical_const_operand (operands[2], <MODE>mode)
4199 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4205 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4208 (and:GPR (match_dup 1)
4212 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4213 if (GET_CODE (operands[3]) == SCRATCH)
4214 operands[3] = gen_reg_rtx (<MODE>mode);
4215 operands[4] = GEN_INT (ne);
4216 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4218 [(set_attr "type" "two")
4219 (set_attr "length" "8")])
4222 ; Yet another case is an rldimi with the second value coming from memory.
4223 ; The zero_extend that should become part of the rldimi is merged into the
4224 ; load from memory instead. Split things properly again.
4226 [(set (match_operand:DI 0 "gpc_reg_operand")
4227 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4228 (match_operand:SI 2 "const_int_operand"))
4229 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4230 "INTVAL (operands[2]) == <bits>"
4232 (zero_extend:DI (match_dup 3)))
4234 (ior:DI (and:DI (match_dup 4)
4236 (ashift:DI (match_dup 1)
4239 operands[4] = gen_reg_rtx (DImode);
4240 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4245 [(set (match_operand:SI 0 "gpc_reg_operand")
4246 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4247 (match_operand:SI 2 "const_int_operand"))
4248 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4249 "INTVAL (operands[2]) == <bits>"
4251 (zero_extend:SI (match_dup 3)))
4253 (ior:SI (and:SI (match_dup 4)
4255 (ashift:SI (match_dup 1)
4258 operands[4] = gen_reg_rtx (SImode);
4259 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4263 ;; Now the simple shifts.
4265 (define_insn "rotl<mode>3"
4266 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4267 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4268 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4270 "rotl<wd>%I2 %0,%1,%<hH>2"
4271 [(set_attr "type" "shift")
4272 (set_attr "maybe_var_shift" "yes")])
4274 (define_insn "*rotlsi3_64"
4275 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4277 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4278 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4280 "rotlw%I2 %0,%1,%h2"
4281 [(set_attr "type" "shift")
4282 (set_attr "maybe_var_shift" "yes")])
4284 (define_insn_and_split "*rotl<mode>3_dot"
4285 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4286 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4287 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4289 (clobber (match_scratch:GPR 0 "=r,r"))]
4290 "<MODE>mode == Pmode"
4292 rotl<wd>%I2. %0,%1,%<hH>2
4294 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4296 (rotate:GPR (match_dup 1)
4299 (compare:CC (match_dup 0)
4302 [(set_attr "type" "shift")
4303 (set_attr "maybe_var_shift" "yes")
4304 (set_attr "dot" "yes")
4305 (set_attr "length" "4,8")])
4307 (define_insn_and_split "*rotl<mode>3_dot2"
4308 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4309 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4310 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4312 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4313 (rotate:GPR (match_dup 1)
4315 "<MODE>mode == Pmode"
4317 rotl<wd>%I2. %0,%1,%<hH>2
4319 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4321 (rotate:GPR (match_dup 1)
4324 (compare:CC (match_dup 0)
4327 [(set_attr "type" "shift")
4328 (set_attr "maybe_var_shift" "yes")
4329 (set_attr "dot" "yes")
4330 (set_attr "length" "4,8")])
4333 (define_insn "ashl<mode>3"
4334 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4335 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4336 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4338 "sl<wd>%I2 %0,%1,%<hH>2"
4339 [(set_attr "type" "shift")
4340 (set_attr "maybe_var_shift" "yes")])
4342 (define_insn "*ashlsi3_64"
4343 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4345 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4346 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4349 [(set_attr "type" "shift")
4350 (set_attr "maybe_var_shift" "yes")])
4352 (define_insn_and_split "*ashl<mode>3_dot"
4353 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4354 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4355 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4357 (clobber (match_scratch:GPR 0 "=r,r"))]
4358 "<MODE>mode == Pmode"
4360 sl<wd>%I2. %0,%1,%<hH>2
4362 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4364 (ashift:GPR (match_dup 1)
4367 (compare:CC (match_dup 0)
4370 [(set_attr "type" "shift")
4371 (set_attr "maybe_var_shift" "yes")
4372 (set_attr "dot" "yes")
4373 (set_attr "length" "4,8")])
4375 (define_insn_and_split "*ashl<mode>3_dot2"
4376 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4377 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4378 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4380 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4381 (ashift:GPR (match_dup 1)
4383 "<MODE>mode == Pmode"
4385 sl<wd>%I2. %0,%1,%<hH>2
4387 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4389 (ashift:GPR (match_dup 1)
4392 (compare:CC (match_dup 0)
4395 [(set_attr "type" "shift")
4396 (set_attr "maybe_var_shift" "yes")
4397 (set_attr "dot" "yes")
4398 (set_attr "length" "4,8")])
4400 ;; Pretend we have a memory form of extswsli until register allocation is done
4401 ;; so that we use LWZ to load the value from memory, instead of LWA.
4402 (define_insn_and_split "ashdi3_extswsli"
4403 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4405 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4406 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4411 "&& reload_completed && MEM_P (operands[1])"
4415 (ashift:DI (sign_extend:DI (match_dup 3))
4418 operands[3] = gen_lowpart (SImode, operands[0]);
4420 [(set_attr "type" "shift")
4421 (set_attr "maybe_var_shift" "no")])
4424 (define_insn_and_split "ashdi3_extswsli_dot"
4425 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4428 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4429 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4431 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4438 "&& reload_completed
4439 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4440 || memory_operand (operands[1], SImode))"
4443 rtx dest = operands[0];
4444 rtx src = operands[1];
4445 rtx shift = operands[2];
4446 rtx cr = operands[3];
4453 src2 = gen_lowpart (SImode, dest);
4454 emit_move_insn (src2, src);
4457 if (REGNO (cr) == CR0_REGNO)
4459 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4463 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4464 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4467 [(set_attr "type" "shift")
4468 (set_attr "maybe_var_shift" "no")
4469 (set_attr "dot" "yes")
4470 (set_attr "length" "4,8,8,12")])
4472 (define_insn_and_split "ashdi3_extswsli_dot2"
4473 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4476 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4477 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4479 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4480 (ashift:DI (sign_extend:DI (match_dup 1))
4488 "&& reload_completed
4489 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4490 || memory_operand (operands[1], SImode))"
4493 rtx dest = operands[0];
4494 rtx src = operands[1];
4495 rtx shift = operands[2];
4496 rtx cr = operands[3];
4503 src2 = gen_lowpart (SImode, dest);
4504 emit_move_insn (src2, src);
4507 if (REGNO (cr) == CR0_REGNO)
4509 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4513 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4514 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4517 [(set_attr "type" "shift")
4518 (set_attr "maybe_var_shift" "no")
4519 (set_attr "dot" "yes")
4520 (set_attr "length" "4,8,8,12")])
4522 (define_insn "lshr<mode>3"
4523 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4524 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4525 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4527 "sr<wd>%I2 %0,%1,%<hH>2"
4528 [(set_attr "type" "shift")
4529 (set_attr "maybe_var_shift" "yes")])
4531 (define_insn "*lshrsi3_64"
4532 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4534 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4535 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4538 [(set_attr "type" "shift")
4539 (set_attr "maybe_var_shift" "yes")])
4541 (define_insn_and_split "*lshr<mode>3_dot"
4542 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4543 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4544 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4546 (clobber (match_scratch:GPR 0 "=r,r"))]
4547 "<MODE>mode == Pmode"
4549 sr<wd>%I2. %0,%1,%<hH>2
4551 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4553 (lshiftrt:GPR (match_dup 1)
4556 (compare:CC (match_dup 0)
4559 [(set_attr "type" "shift")
4560 (set_attr "maybe_var_shift" "yes")
4561 (set_attr "dot" "yes")
4562 (set_attr "length" "4,8")])
4564 (define_insn_and_split "*lshr<mode>3_dot2"
4565 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4566 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4567 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4569 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4570 (lshiftrt:GPR (match_dup 1)
4572 "<MODE>mode == Pmode"
4574 sr<wd>%I2. %0,%1,%<hH>2
4576 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4578 (lshiftrt:GPR (match_dup 1)
4581 (compare:CC (match_dup 0)
4584 [(set_attr "type" "shift")
4585 (set_attr "maybe_var_shift" "yes")
4586 (set_attr "dot" "yes")
4587 (set_attr "length" "4,8")])
4590 (define_insn "ashr<mode>3"
4591 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4592 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4593 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4594 (clobber (reg:GPR CA_REGNO))]
4596 "sra<wd>%I2 %0,%1,%<hH>2"
4597 [(set_attr "type" "shift")
4598 (set_attr "maybe_var_shift" "yes")])
4600 (define_insn "*ashrsi3_64"
4601 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4603 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4604 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4605 (clobber (reg:SI CA_REGNO))]
4608 [(set_attr "type" "shift")
4609 (set_attr "maybe_var_shift" "yes")])
4611 (define_insn_and_split "*ashr<mode>3_dot"
4612 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4613 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4614 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4616 (clobber (match_scratch:GPR 0 "=r,r"))
4617 (clobber (reg:GPR CA_REGNO))]
4618 "<MODE>mode == Pmode"
4620 sra<wd>%I2. %0,%1,%<hH>2
4622 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4623 [(parallel [(set (match_dup 0)
4624 (ashiftrt:GPR (match_dup 1)
4626 (clobber (reg:GPR CA_REGNO))])
4628 (compare:CC (match_dup 0)
4631 [(set_attr "type" "shift")
4632 (set_attr "maybe_var_shift" "yes")
4633 (set_attr "dot" "yes")
4634 (set_attr "length" "4,8")])
4636 (define_insn_and_split "*ashr<mode>3_dot2"
4637 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4638 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4639 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4641 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4642 (ashiftrt:GPR (match_dup 1)
4644 (clobber (reg:GPR CA_REGNO))]
4645 "<MODE>mode == Pmode"
4647 sra<wd>%I2. %0,%1,%<hH>2
4649 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4650 [(parallel [(set (match_dup 0)
4651 (ashiftrt:GPR (match_dup 1)
4653 (clobber (reg:GPR CA_REGNO))])
4655 (compare:CC (match_dup 0)
4658 [(set_attr "type" "shift")
4659 (set_attr "maybe_var_shift" "yes")
4660 (set_attr "dot" "yes")
4661 (set_attr "length" "4,8")])
4663 ;; Builtins to replace a division to generate FRE reciprocal estimate
4664 ;; instructions and the necessary fixup instructions
4665 (define_expand "recip<mode>3"
4666 [(match_operand:RECIPF 0 "gpc_reg_operand")
4667 (match_operand:RECIPF 1 "gpc_reg_operand")
4668 (match_operand:RECIPF 2 "gpc_reg_operand")]
4669 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4671 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4675 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4676 ;; hardware division. This is only done before register allocation and with
4677 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4678 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4679 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4681 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4682 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4683 (match_operand 2 "gpc_reg_operand")))]
4684 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4685 && can_create_pseudo_p () && flag_finite_math_only
4686 && !flag_trapping_math && flag_reciprocal_math"
4689 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4693 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4694 ;; appropriate fixup.
4695 (define_expand "rsqrt<mode>2"
4696 [(match_operand:RECIPF 0 "gpc_reg_operand")
4697 (match_operand:RECIPF 1 "gpc_reg_operand")]
4698 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4700 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4704 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4705 ;; modes here, and also add in conditional vsx/power8-vector support to access
4706 ;; values in the traditional Altivec registers if the appropriate
4707 ;; -mupper-regs-{df,sf} option is enabled.
4709 (define_expand "abs<mode>2"
4710 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4711 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4715 (define_insn "*abs<mode>2_fpr"
4716 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4717 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4722 [(set_attr "type" "fpsimple")])
4724 (define_insn "*nabs<mode>2_fpr"
4725 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4728 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4733 [(set_attr "type" "fpsimple")])
4735 (define_expand "neg<mode>2"
4736 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4737 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4741 (define_insn "*neg<mode>2_fpr"
4742 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4743 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4748 [(set_attr "type" "fpsimple")])
4750 (define_expand "add<mode>3"
4751 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4752 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4753 (match_operand:SFDF 2 "gpc_reg_operand")))]
4757 (define_insn "*add<mode>3_fpr"
4758 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4759 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4760 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4764 xsadd<sd>p %x0,%x1,%x2"
4765 [(set_attr "type" "fp")
4766 (set_attr "isa" "*,<Fisa>")])
4768 (define_expand "sub<mode>3"
4769 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4770 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4771 (match_operand:SFDF 2 "gpc_reg_operand")))]
4775 (define_insn "*sub<mode>3_fpr"
4776 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4777 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4778 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4782 xssub<sd>p %x0,%x1,%x2"
4783 [(set_attr "type" "fp")
4784 (set_attr "isa" "*,<Fisa>")])
4786 (define_expand "mul<mode>3"
4787 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4788 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4789 (match_operand:SFDF 2 "gpc_reg_operand")))]
4793 (define_insn "*mul<mode>3_fpr"
4794 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4795 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4796 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4800 xsmul<sd>p %x0,%x1,%x2"
4801 [(set_attr "type" "dmul")
4802 (set_attr "isa" "*,<Fisa>")])
4804 (define_expand "div<mode>3"
4805 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4806 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4807 (match_operand:SFDF 2 "gpc_reg_operand")))]
4810 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4811 && can_create_pseudo_p () && flag_finite_math_only
4812 && !flag_trapping_math && flag_reciprocal_math)
4814 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4819 (define_insn "*div<mode>3_fpr"
4820 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4821 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4822 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4826 xsdiv<sd>p %x0,%x1,%x2"
4827 [(set_attr "type" "<sd>div")
4828 (set_attr "isa" "*,<Fisa>")])
4830 (define_insn "*sqrt<mode>2_internal"
4831 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4832 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4833 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4836 xssqrt<sd>p %x0,%x1"
4837 [(set_attr "type" "<sd>sqrt")
4838 (set_attr "isa" "*,<Fisa>")])
4840 (define_expand "sqrt<mode>2"
4841 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4842 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4843 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4845 if (<MODE>mode == SFmode
4846 && TARGET_RECIP_PRECISION
4847 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4848 && !optimize_function_for_size_p (cfun)
4849 && flag_finite_math_only && !flag_trapping_math
4850 && flag_unsafe_math_optimizations)
4852 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4857 ;; Floating point reciprocal approximation
4858 (define_insn "fre<sd>"
4859 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4860 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4866 [(set_attr "type" "fp")
4867 (set_attr "isa" "*,<Fisa>")])
4869 (define_insn "*rsqrt<mode>2"
4870 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4871 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4873 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4876 xsrsqrte<sd>p %x0,%x1"
4877 [(set_attr "type" "fp")
4878 (set_attr "isa" "*,<Fisa>")])
4880 ;; Floating point comparisons
4881 (define_insn "*cmp<mode>_fpr"
4882 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4883 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4884 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4888 xscmpudp %0,%x1,%x2"
4889 [(set_attr "type" "fpcompare")
4890 (set_attr "isa" "*,<Fisa>")])
4892 ;; Floating point conversions
4893 (define_expand "extendsfdf2"
4894 [(set (match_operand:DF 0 "gpc_reg_operand")
4895 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4898 if (HONOR_SNANS (SFmode))
4899 operands[1] = force_reg (SFmode, operands[1]);
4902 (define_insn_and_split "*extendsfdf2_fpr"
4903 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4904 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4905 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4911 xscpsgndp %x0,%x1,%x1
4914 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4917 emit_note (NOTE_INSN_DELETED);
4920 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4921 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4923 (define_insn "*extendsfdf2_snan"
4924 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4925 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4926 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4930 [(set_attr "type" "fp")
4931 (set_attr "isa" "*,p8v")])
4933 (define_expand "truncdfsf2"
4934 [(set (match_operand:SF 0 "gpc_reg_operand")
4935 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4939 (define_insn "*truncdfsf2_fpr"
4940 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4941 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4946 [(set_attr "type" "fp")
4947 (set_attr "isa" "*,p8v")])
4949 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4950 ;; builtins.c and optabs.c that are not correct for IBM long double
4951 ;; when little-endian.
4952 (define_expand "signbit<mode>2"
4954 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4956 (subreg:DI (match_dup 2) 0))
4959 (set (match_operand:SI 0 "gpc_reg_operand")
4962 && (!FLOAT128_IEEE_P (<MODE>mode)
4963 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4965 if (FLOAT128_IEEE_P (<MODE>mode))
4967 rtx dest = operands[0];
4968 rtx src = operands[1];
4969 rtx tmp = gen_reg_rtx (DImode);
4970 rtx dest_di = gen_lowpart (DImode, dest);
4972 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4973 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4976 operands[2] = gen_reg_rtx (DFmode);
4977 operands[3] = gen_reg_rtx (DImode);
4978 if (TARGET_POWERPC64)
4980 operands[4] = gen_reg_rtx (DImode);
4981 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4982 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4983 WORDS_BIG_ENDIAN ? 4 : 0);
4987 operands[4] = gen_reg_rtx (SImode);
4988 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4989 WORDS_BIG_ENDIAN ? 0 : 4);
4990 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4994 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4995 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4996 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4997 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4999 ;; After register allocation, if the _Float128 had originally been in GPRs, the
5000 ;; split allows the post reload phases to eliminate the move, and do the shift
5001 ;; directly with the register that contains the signbit.
5002 (define_insn_and_split "@signbit<mode>2_dm"
5003 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
5004 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
5006 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5010 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
5014 operands[2] = gen_highpart (DImode, operands[1]);
5016 [(set_attr "type" "mftgpr,*")])
5018 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
5019 ;; register and then doing a direct move if the value comes from memory. On
5020 ;; little endian, we have to load the 2nd double-word to get the sign bit.
5021 (define_insn_and_split "*signbit<mode>2_dm_mem"
5022 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
5023 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
5025 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
5031 rtx dest = operands[0];
5032 rtx src = operands[1];
5033 rtx addr = XEXP (src, 0);
5035 if (WORDS_BIG_ENDIAN)
5036 operands[2] = adjust_address (src, DImode, 0);
5038 else if (REG_P (addr) || SUBREG_P (addr))
5039 operands[2] = adjust_address (src, DImode, 8);
5041 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
5042 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
5043 operands[2] = adjust_address (src, DImode, 8);
5047 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
5048 emit_insn (gen_rtx_SET (tmp, addr));
5049 operands[2] = change_address (src, DImode,
5050 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
5054 (define_expand "copysign<mode>3"
5056 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
5058 (neg:SFDF (abs:SFDF (match_dup 1))))
5059 (set (match_operand:SFDF 0 "gpc_reg_operand")
5060 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
5065 && ((TARGET_PPC_GFXOPT
5066 && !HONOR_NANS (<MODE>mode)
5067 && !HONOR_SIGNED_ZEROS (<MODE>mode))
5069 || VECTOR_UNIT_VSX_P (<MODE>mode))"
5071 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
5073 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
5078 operands[3] = gen_reg_rtx (<MODE>mode);
5079 operands[4] = gen_reg_rtx (<MODE>mode);
5080 operands[5] = CONST0_RTX (<MODE>mode);
5083 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
5084 ;; compiler from optimizing -0.0
5085 (define_insn "copysign<mode>3_fcpsgn"
5086 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5087 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
5088 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
5090 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
5093 xscpsgndp %x0,%x2,%x1"
5094 [(set_attr "type" "fpsimple")])
5096 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
5097 ;; fsel instruction and some auxiliary computations. Then we just have a
5098 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
5100 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
5101 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
5102 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
5103 ;; define_splits to make them if made by combine. On VSX machines we have the
5104 ;; min/max instructions.
5106 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
5107 ;; to allow either DF/SF to use only traditional registers.
5109 (define_expand "s<minmax><mode>3"
5110 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5111 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5112 (match_operand:SFDF 2 "gpc_reg_operand")))]
5115 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5119 (define_insn "*s<minmax><mode>3_vsx"
5120 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5121 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5122 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5123 "TARGET_VSX && TARGET_HARD_FLOAT"
5125 return (TARGET_P9_MINMAX
5126 ? "xs<minmax>cdp %x0,%x1,%x2"
5127 : "xs<minmax>dp %x0,%x1,%x2");
5129 [(set_attr "type" "fp")])
5131 ;; The conditional move instructions allow us to perform max and min operations
5132 ;; even when we don't have the appropriate max/min instruction using the FSEL
5135 (define_insn_and_split "*s<minmax><mode>3_fpr"
5136 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5137 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5138 (match_operand:SFDF 2 "gpc_reg_operand")))]
5139 "!TARGET_VSX && TARGET_MINMAX"
5144 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5148 (define_expand "mov<mode>cc"
5149 [(set (match_operand:GPR 0 "gpc_reg_operand")
5150 (if_then_else:GPR (match_operand 1 "comparison_operator")
5151 (match_operand:GPR 2 "gpc_reg_operand")
5152 (match_operand:GPR 3 "gpc_reg_operand")))]
5155 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5161 ;; We use the BASE_REGS for the isel input operands because, if rA is
5162 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5163 ;; because we may switch the operands and rB may end up being rA.
5165 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5166 ;; leave out the mode in operand 4 and use one pattern, but reload can
5167 ;; change the mode underneath our feet and then gets confused trying
5168 ;; to reload the value.
5169 (define_mode_iterator CCEITHER [CC CCUNS])
5170 (define_mode_attr un [(CC "") (CCUNS "un")])
5171 (define_insn "isel_<un>signed_<GPR:mode>"
5172 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5174 (match_operator 1 "scc_comparison_operator"
5175 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5177 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5178 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5181 [(set_attr "type" "isel")])
5183 ;; These patterns can be useful for combine; they let combine know that
5184 ;; isel can handle reversed comparisons so long as the operands are
5187 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5188 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5190 (match_operator 1 "scc_rev_comparison_operator"
5191 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5193 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5194 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5197 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5198 return "isel %0,%3,%2,%j1";
5200 [(set_attr "type" "isel")])
5202 ; Set Boolean Condition (Reverse)
5203 (define_insn "setbc_<un>signed_<GPR:mode>"
5204 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5205 (match_operator:GPR 1 "scc_comparison_operator"
5206 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5210 [(set_attr "type" "isel")])
5212 (define_insn "*setbcr_<un>signed_<GPR:mode>"
5213 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5214 (match_operator:GPR 1 "scc_rev_comparison_operator"
5215 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5219 [(set_attr "type" "isel")])
5221 ; Set Negative Boolean Condition (Reverse)
5222 (define_insn "*setnbc_<un>signed_<GPR:mode>"
5223 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5224 (neg:GPR (match_operator:GPR 1 "scc_comparison_operator"
5225 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5229 [(set_attr "type" "isel")])
5231 (define_insn "*setnbcr_<un>signed_<GPR:mode>"
5232 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
5233 (neg:GPR (match_operator:GPR 1 "scc_rev_comparison_operator"
5234 [(match_operand:CCEITHER 2 "cc_reg_operand" "y")
5238 [(set_attr "type" "isel")])
5240 ;; Floating point conditional move
5241 (define_expand "mov<mode>cc"
5242 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5243 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5244 (match_operand:SFDF 2 "gpc_reg_operand")
5245 (match_operand:SFDF 3 "gpc_reg_operand")))]
5246 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5248 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5254 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5255 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5257 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5258 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5259 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5260 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5261 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5263 [(set_attr "type" "fp")])
5265 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5266 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5268 (match_operator:CCFP 1 "fpmask_comparison_operator"
5269 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5270 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5271 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5272 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5273 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5278 (if_then_else:V2DI (match_dup 1)
5282 (if_then_else:SFDF (ne (match_dup 6)
5287 if (GET_CODE (operands[6]) == SCRATCH)
5288 operands[6] = gen_reg_rtx (V2DImode);
5290 operands[7] = CONSTM1_RTX (V2DImode);
5291 operands[8] = CONST0_RTX (V2DImode);
5293 [(set_attr "length" "8")
5294 (set_attr "type" "vecperm")])
5296 ;; Handle inverting the fpmask comparisons.
5297 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5298 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5300 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5301 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5302 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5303 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5304 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5305 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5310 (if_then_else:V2DI (match_dup 9)
5314 (if_then_else:SFDF (ne (match_dup 6)
5319 rtx op1 = operands[1];
5320 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5322 if (GET_CODE (operands[6]) == SCRATCH)
5323 operands[6] = gen_reg_rtx (V2DImode);
5325 operands[7] = CONSTM1_RTX (V2DImode);
5326 operands[8] = CONST0_RTX (V2DImode);
5328 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5330 [(set_attr "length" "8")
5331 (set_attr "type" "vecperm")])
5333 (define_insn "*fpmask<mode>"
5334 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5336 (match_operator:CCFP 1 "fpmask_comparison_operator"
5337 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5338 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5339 (match_operand:V2DI 4 "all_ones_constant" "")
5340 (match_operand:V2DI 5 "zero_constant" "")))]
5342 "xscmp%V1dp %x0,%x2,%x3"
5343 [(set_attr "type" "fpcompare")])
5345 (define_insn "*xxsel<mode>"
5346 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5347 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5348 (match_operand:V2DI 2 "zero_constant" ""))
5349 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5350 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5352 "xxsel %x0,%x4,%x3,%x1"
5353 [(set_attr "type" "vecmove")])
5356 ;; Conversions to and from floating-point.
5358 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5359 ; don't want to support putting SImode in FPR registers.
5360 (define_insn "lfiwax"
5361 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5362 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5364 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5370 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5371 (set_attr "isa" "*,p8v,p8v,p9v")])
5373 ; This split must be run before register allocation because it allocates the
5374 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5375 ; it earlier to allow for the combiner to merge insns together where it might
5376 ; not be needed and also in case the insns are deleted as dead code.
5378 (define_insn_and_split "floatsi<mode>2_lfiwax"
5379 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5380 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5381 (clobber (match_scratch:DI 2 "=d,wa"))]
5382 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5383 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5388 rtx dest = operands[0];
5389 rtx src = operands[1];
5392 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5393 tmp = convert_to_mode (DImode, src, false);
5397 if (GET_CODE (tmp) == SCRATCH)
5398 tmp = gen_reg_rtx (DImode);
5401 src = rs6000_force_indexed_or_indirect_mem (src);
5402 emit_insn (gen_lfiwax (tmp, src));
5406 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5407 emit_move_insn (stack, src);
5408 emit_insn (gen_lfiwax (tmp, stack));
5411 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5414 [(set_attr "length" "12")
5415 (set_attr "type" "fpload")])
5417 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5418 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5421 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5422 (clobber (match_scratch:DI 2 "=d,wa"))]
5423 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5428 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5429 if (GET_CODE (operands[2]) == SCRATCH)
5430 operands[2] = gen_reg_rtx (DImode);
5431 if (TARGET_P8_VECTOR)
5432 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5434 emit_insn (gen_lfiwax (operands[2], operands[1]));
5435 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5438 [(set_attr "length" "8")
5439 (set_attr "type" "fpload")])
5441 (define_insn "lfiwzx"
5442 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5443 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5445 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5450 xxextractuw %x0,%x1,4"
5451 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5452 (set_attr "isa" "*,p8v,p8v,p9v")])
5454 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5455 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5456 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5457 (clobber (match_scratch:DI 2 "=d,wa"))]
5458 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5463 rtx dest = operands[0];
5464 rtx src = operands[1];
5467 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5468 tmp = convert_to_mode (DImode, src, true);
5472 if (GET_CODE (tmp) == SCRATCH)
5473 tmp = gen_reg_rtx (DImode);
5476 src = rs6000_force_indexed_or_indirect_mem (src);
5477 emit_insn (gen_lfiwzx (tmp, src));
5481 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5482 emit_move_insn (stack, src);
5483 emit_insn (gen_lfiwzx (tmp, stack));
5486 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5489 [(set_attr "length" "12")
5490 (set_attr "type" "fpload")])
5492 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5493 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5494 (unsigned_float:SFDF
5496 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5497 (clobber (match_scratch:DI 2 "=d,wa"))]
5498 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5503 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5504 if (GET_CODE (operands[2]) == SCRATCH)
5505 operands[2] = gen_reg_rtx (DImode);
5506 if (TARGET_P8_VECTOR)
5507 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5509 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5510 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5513 [(set_attr "length" "8")
5514 (set_attr "type" "fpload")])
5516 ; For each of these conversions, there is a define_expand, a define_insn
5517 ; with a '#' template, and a define_split (with C code). The idea is
5518 ; to allow constant folding with the template of the define_insn,
5519 ; then to have the insns split later (between sched1 and final).
5521 (define_expand "floatsidf2"
5522 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5523 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5526 (clobber (match_dup 4))
5527 (clobber (match_dup 5))
5528 (clobber (match_dup 6))])]
5531 if (TARGET_LFIWAX && TARGET_FCFID)
5533 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5536 else if (TARGET_FCFID)
5538 rtx dreg = operands[1];
5540 dreg = force_reg (SImode, dreg);
5541 dreg = convert_to_mode (DImode, dreg, false);
5542 emit_insn (gen_floatdidf2 (operands[0], dreg));
5546 if (!REG_P (operands[1]))
5547 operands[1] = force_reg (SImode, operands[1]);
5548 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5549 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5550 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5551 operands[5] = gen_reg_rtx (DFmode);
5552 operands[6] = gen_reg_rtx (SImode);
5555 (define_insn_and_split "*floatsidf2_internal"
5556 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5557 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5558 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5559 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5560 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5561 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5562 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5563 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5568 rtx lowword, highword;
5569 gcc_assert (MEM_P (operands[4]));
5570 highword = adjust_address (operands[4], SImode, 0);
5571 lowword = adjust_address (operands[4], SImode, 4);
5572 if (! WORDS_BIG_ENDIAN)
5573 std::swap (lowword, highword);
5575 emit_insn (gen_xorsi3 (operands[6], operands[1],
5576 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5577 emit_move_insn (lowword, operands[6]);
5578 emit_move_insn (highword, operands[2]);
5579 emit_move_insn (operands[5], operands[4]);
5580 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5583 [(set_attr "length" "24")
5584 (set_attr "type" "fp")])
5586 ;; If we don't have a direct conversion to single precision, don't enable this
5587 ;; conversion for 32-bit without fast math, because we don't have the insn to
5588 ;; generate the fixup swizzle to avoid double rounding problems.
5589 (define_expand "floatunssisf2"
5590 [(set (match_operand:SF 0 "gpc_reg_operand")
5591 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5593 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5595 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5597 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5599 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5604 rtx dreg = operands[1];
5606 dreg = force_reg (SImode, dreg);
5607 dreg = convert_to_mode (DImode, dreg, true);
5608 emit_insn (gen_floatdisf2 (operands[0], dreg));
5613 (define_expand "floatunssidf2"
5614 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5615 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5618 (clobber (match_dup 4))
5619 (clobber (match_dup 5))])]
5622 if (TARGET_LFIWZX && TARGET_FCFID)
5624 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5627 else if (TARGET_FCFID)
5629 rtx dreg = operands[1];
5631 dreg = force_reg (SImode, dreg);
5632 dreg = convert_to_mode (DImode, dreg, true);
5633 emit_insn (gen_floatdidf2 (operands[0], dreg));
5637 if (!REG_P (operands[1]))
5638 operands[1] = force_reg (SImode, operands[1]);
5639 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5640 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5641 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5642 operands[5] = gen_reg_rtx (DFmode);
5645 (define_insn_and_split "*floatunssidf2_internal"
5646 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5647 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5648 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5649 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5650 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5651 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5652 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5653 && !(TARGET_FCFID && TARGET_POWERPC64)"
5658 rtx lowword, highword;
5659 gcc_assert (MEM_P (operands[4]));
5660 highword = adjust_address (operands[4], SImode, 0);
5661 lowword = adjust_address (operands[4], SImode, 4);
5662 if (! WORDS_BIG_ENDIAN)
5663 std::swap (lowword, highword);
5665 emit_move_insn (lowword, operands[1]);
5666 emit_move_insn (highword, operands[2]);
5667 emit_move_insn (operands[5], operands[4]);
5668 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5671 [(set_attr "length" "20")
5672 (set_attr "type" "fp")])
5674 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5675 ;; vector registers. These insns favor doing the sign/zero extension in
5676 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5677 ;; extension and then a direct move.
5679 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5680 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5682 (match_operand:QHI 1 "input_operand")))
5683 (clobber (match_scratch:DI 2))
5684 (clobber (match_scratch:DI 3))
5685 (clobber (match_scratch:<QHI:MODE> 4))])]
5686 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5688 if (MEM_P (operands[1]))
5689 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5692 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5693 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5695 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5696 (clobber (match_scratch:DI 2 "=v,wa,v"))
5697 (clobber (match_scratch:DI 3 "=X,r,X"))
5698 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5699 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5701 "&& reload_completed"
5704 rtx result = operands[0];
5705 rtx input = operands[1];
5706 rtx di = operands[2];
5710 rtx tmp = operands[3];
5711 if (altivec_register_operand (input, <QHI:MODE>mode))
5712 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5713 else if (GET_CODE (tmp) == SCRATCH)
5714 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5717 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5718 emit_move_insn (di, tmp);
5723 rtx tmp = operands[4];
5724 emit_move_insn (tmp, input);
5725 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5728 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5731 [(set_attr "isa" "p9v,*,p9v")])
5733 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5734 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5735 (unsigned_float:FP_ISA3
5736 (match_operand:QHI 1 "input_operand")))
5737 (clobber (match_scratch:DI 2))
5738 (clobber (match_scratch:DI 3))])]
5739 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5741 if (MEM_P (operands[1]))
5742 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5745 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5746 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5747 (unsigned_float:FP_ISA3
5748 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5749 (clobber (match_scratch:DI 2 "=v,wa,wa"))
5750 (clobber (match_scratch:DI 3 "=X,r,X"))]
5751 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5753 "&& reload_completed"
5756 rtx result = operands[0];
5757 rtx input = operands[1];
5758 rtx di = operands[2];
5760 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5761 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5764 rtx tmp = operands[3];
5765 if (GET_CODE (tmp) == SCRATCH)
5766 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5769 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5770 emit_move_insn (di, tmp);
5774 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5777 [(set_attr "isa" "p9v,*,p9v")])
5779 (define_expand "fix_trunc<mode>si2"
5780 [(set (match_operand:SI 0 "gpc_reg_operand")
5781 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5784 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5786 rtx src = force_reg (<MODE>mode, operands[1]);
5789 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5792 rtx tmp = gen_reg_rtx (DImode);
5793 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5794 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5801 ; Like the convert to float patterns, this insn must be split before
5802 ; register allocation so that it can allocate the memory slot if it
5804 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5805 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5806 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5807 (clobber (match_scratch:DI 2 "=d"))]
5808 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5809 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5814 rtx dest = operands[0];
5815 rtx src = operands[1];
5816 rtx tmp = operands[2];
5818 if (GET_CODE (tmp) == SCRATCH)
5819 tmp = gen_reg_rtx (DImode);
5821 emit_insn (gen_fctiwz_<mode> (tmp, src));
5822 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5824 dest = rs6000_force_indexed_or_indirect_mem (dest);
5825 emit_insn (gen_stfiwx (dest, tmp));
5828 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5830 dest = gen_lowpart (DImode, dest);
5831 emit_move_insn (dest, tmp);
5836 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5837 emit_insn (gen_stfiwx (stack, tmp));
5838 emit_move_insn (dest, stack);
5842 [(set_attr "length" "12")
5843 (set_attr "type" "fp")])
5845 (define_insn_and_split "fix_trunc<mode>si2_internal"
5846 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5847 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5848 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5849 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5851 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5857 gcc_assert (MEM_P (operands[3]));
5858 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5860 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5861 emit_move_insn (operands[3], operands[2]);
5862 emit_move_insn (operands[0], lowword);
5865 [(set_attr "length" "16")
5866 (set_attr "type" "fp")])
5868 (define_expand "fix_trunc<mode>di2"
5869 [(set (match_operand:DI 0 "gpc_reg_operand")
5870 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5871 "TARGET_HARD_FLOAT && TARGET_FCFID"
5874 (define_insn "*fix_trunc<mode>di2_fctidz"
5875 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5876 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5877 "TARGET_HARD_FLOAT && TARGET_FCFID"
5881 [(set_attr "type" "fp")])
5883 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5884 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5885 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5886 ;; values can go in VSX registers. Keeping the direct move part through
5887 ;; register allocation prevents the register allocator from doing a direct move
5888 ;; of the SImode value to a GPR, and then a store/load.
5889 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5890 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5891 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5892 (clobber (match_scratch:SI 2 "=X,X,wa"))]
5893 "TARGET_DIRECT_MOVE"
5896 xscvdp<su>xws %x0,%x1
5898 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5900 (any_fix:SI (match_dup 1)))
5904 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5906 [(set_attr "type" "fp")
5907 (set_attr "length" "4,4,8")
5908 (set_attr "isa" "p9v,p9v,*")])
5910 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5911 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5912 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5913 "TARGET_DIRECT_MOVE"
5916 xscvdp<su>xws %x0,%x1"
5917 [(set_attr "type" "fp")])
5919 ;; Keep the convert and store together through register allocation to prevent
5920 ;; the register allocator from getting clever and doing a direct move to a GPR
5921 ;; and then store for reg+offset stores.
5922 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5923 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5924 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5925 (clobber (match_scratch:SI 2 "=wa"))]
5926 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5928 "&& reload_completed"
5930 (any_fix:SI (match_dup 1)))
5934 operands[3] = (<QHSI:MODE>mode == SImode
5936 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5939 (define_expand "fixuns_trunc<mode>si2"
5940 [(set (match_operand:SI 0 "gpc_reg_operand")
5941 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5942 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5944 if (!TARGET_P8_VECTOR)
5946 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5951 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5952 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5953 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5954 (clobber (match_scratch:DI 2 "=d"))]
5955 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5956 && TARGET_STFIWX && can_create_pseudo_p ()
5957 && !TARGET_P8_VECTOR"
5962 rtx dest = operands[0];
5963 rtx src = operands[1];
5964 rtx tmp = operands[2];
5966 if (GET_CODE (tmp) == SCRATCH)
5967 tmp = gen_reg_rtx (DImode);
5969 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5972 dest = rs6000_force_indexed_or_indirect_mem (dest);
5973 emit_insn (gen_stfiwx (dest, tmp));
5976 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5978 dest = gen_lowpart (DImode, dest);
5979 emit_move_insn (dest, tmp);
5984 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5985 emit_insn (gen_stfiwx (stack, tmp));
5986 emit_move_insn (dest, stack);
5990 [(set_attr "length" "12")
5991 (set_attr "type" "fp")])
5993 (define_insn "fixuns_trunc<mode>di2"
5994 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5995 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5996 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
6000 [(set_attr "type" "fp")])
6002 (define_insn "rs6000_mtfsb0"
6003 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6007 [(set_attr "type" "fp")])
6009 (define_insn "rs6000_mtfsb1"
6010 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
6014 [(set_attr "type" "fp")])
6016 (define_insn "rs6000_mffscrn"
6017 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6018 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
6022 [(set_attr "type" "fp")])
6024 (define_insn "rs6000_mffscdrn"
6025 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
6026 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
6027 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
6030 [(set_attr "type" "fp")])
6032 (define_expand "rs6000_set_fpscr_rn"
6033 [(match_operand:DI 0 "reg_or_cint_operand")]
6036 rtx tmp_df = gen_reg_rtx (DFmode);
6038 /* The floating point rounding control bits are FPSCR[62:63]. Put the
6039 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
6042 rtx src_df = force_reg (DImode, operands[0]);
6043 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
6044 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
6048 if (CONST_INT_P (operands[0]))
6050 if ((INTVAL (operands[0]) & 0x1) == 0x1)
6051 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
6053 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
6055 if ((INTVAL (operands[0]) & 0x2) == 0x2)
6056 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
6058 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
6062 rtx tmp_rn = gen_reg_rtx (DImode);
6063 rtx tmp_di = gen_reg_rtx (DImode);
6065 /* Extract new RN mode from operand. */
6066 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
6068 /* Insert new RN mode into FSCPR. */
6069 emit_insn (gen_rs6000_mffs (tmp_df));
6070 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6071 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
6072 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6074 /* Need to write to field k=15. The fields are [0:15]. Hence with
6075 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
6076 8-bit field[0:7]. Need to set the bit that corresponds to the
6077 value of i that you want [0:7]. */
6078 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6079 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
6084 (define_expand "rs6000_set_fpscr_drn"
6085 [(match_operand:DI 0 "gpc_reg_operand")]
6088 rtx tmp_df = gen_reg_rtx (DFmode);
6090 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
6091 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
6094 rtx src_df = gen_reg_rtx (DFmode);
6096 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
6097 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
6098 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
6102 rtx tmp_rn = gen_reg_rtx (DImode);
6103 rtx tmp_di = gen_reg_rtx (DImode);
6105 /* Extract new DRN mode from operand. */
6106 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
6107 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
6109 /* Insert new RN mode into FSCPR. */
6110 emit_insn (gen_rs6000_mffs (tmp_df));
6111 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
6112 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFFULL)));
6113 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
6115 /* Need to write to field 7. The fields are [0:15]. The equation to
6116 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
6117 i to 0x1 to get field 7 where i selects the field. */
6118 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
6119 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
6124 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
6125 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
6126 ;; because the first makes it clear that operand 0 is not live
6127 ;; before the instruction.
6128 (define_insn "fctiwz_<mode>"
6129 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6131 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6137 [(set_attr "type" "fp")])
6139 (define_insn "fctiwuz_<mode>"
6140 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
6141 (unspec:DI [(unsigned_fix:SI
6142 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
6144 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
6148 [(set_attr "type" "fp")])
6150 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6151 ;; since the friz instruction does not truncate the value if the floating
6152 ;; point value is < LONG_MIN or > LONG_MAX.
6153 (define_insn "*friz"
6154 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6155 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6156 "TARGET_HARD_FLOAT && TARGET_FPRND
6157 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6161 [(set_attr "type" "fp")])
6163 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6164 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6165 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6166 ;; extend it, store it back on the stack from the GPR, load it back into the
6167 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6168 ;; disable using store and load to sign/zero extend the value.
6169 (define_insn_and_split "*round32<mode>2_fprs"
6170 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6172 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6173 (clobber (match_scratch:DI 2 "=d"))
6174 (clobber (match_scratch:DI 3 "=d"))]
6176 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6177 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6182 rtx dest = operands[0];
6183 rtx src = operands[1];
6184 rtx tmp1 = operands[2];
6185 rtx tmp2 = operands[3];
6186 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6188 if (GET_CODE (tmp1) == SCRATCH)
6189 tmp1 = gen_reg_rtx (DImode);
6190 if (GET_CODE (tmp2) == SCRATCH)
6191 tmp2 = gen_reg_rtx (DImode);
6193 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6194 emit_insn (gen_stfiwx (stack, tmp1));
6195 emit_insn (gen_lfiwax (tmp2, stack));
6196 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6199 [(set_attr "type" "fpload")
6200 (set_attr "length" "16")])
6202 (define_insn_and_split "*roundu32<mode>2_fprs"
6203 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6204 (unsigned_float:SFDF
6205 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6206 (clobber (match_scratch:DI 2 "=d"))
6207 (clobber (match_scratch:DI 3 "=d"))]
6209 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6210 && can_create_pseudo_p ()"
6215 rtx dest = operands[0];
6216 rtx src = operands[1];
6217 rtx tmp1 = operands[2];
6218 rtx tmp2 = operands[3];
6219 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6221 if (GET_CODE (tmp1) == SCRATCH)
6222 tmp1 = gen_reg_rtx (DImode);
6223 if (GET_CODE (tmp2) == SCRATCH)
6224 tmp2 = gen_reg_rtx (DImode);
6226 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6227 emit_insn (gen_stfiwx (stack, tmp1));
6228 emit_insn (gen_lfiwzx (tmp2, stack));
6229 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6232 [(set_attr "type" "fpload")
6233 (set_attr "length" "16")])
6235 ;; No VSX equivalent to fctid
6236 (define_insn "lrint<mode>di2"
6237 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6238 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6240 "TARGET_HARD_FLOAT && TARGET_FPRND"
6242 [(set_attr "type" "fp")])
6244 (define_insn "btrunc<mode>2"
6245 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6246 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6248 "TARGET_HARD_FLOAT && TARGET_FPRND"
6252 [(set_attr "type" "fp")])
6254 (define_insn "ceil<mode>2"
6255 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6256 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6258 "TARGET_HARD_FLOAT && TARGET_FPRND"
6262 [(set_attr "type" "fp")])
6264 (define_insn "floor<mode>2"
6265 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6266 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6268 "TARGET_HARD_FLOAT && TARGET_FPRND"
6272 [(set_attr "type" "fp")])
6274 ;; No VSX equivalent to frin
6275 (define_insn "round<mode>2"
6276 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6277 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6279 "TARGET_HARD_FLOAT && TARGET_FPRND"
6281 [(set_attr "type" "fp")])
6283 (define_insn "*xsrdpi<mode>2"
6284 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6285 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6287 "TARGET_HARD_FLOAT && TARGET_VSX"
6289 [(set_attr "type" "fp")])
6291 (define_expand "lround<mode>di2"
6293 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6295 (set (match_operand:DI 0 "gpc_reg_operand")
6296 (unspec:DI [(match_dup 2)]
6298 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6300 operands[2] = gen_reg_rtx (<MODE>mode);
6303 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6304 (define_insn "stfiwx"
6305 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6306 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6312 [(set_attr "type" "fpstore")
6313 (set_attr "isa" "*,p8v")])
6315 ;; If we don't have a direct conversion to single precision, don't enable this
6316 ;; conversion for 32-bit without fast math, because we don't have the insn to
6317 ;; generate the fixup swizzle to avoid double rounding problems.
6318 (define_expand "floatsisf2"
6319 [(set (match_operand:SF 0 "gpc_reg_operand")
6320 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6322 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6324 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6326 if (TARGET_FCFIDS && TARGET_LFIWAX)
6328 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6331 else if (TARGET_FCFID && TARGET_LFIWAX)
6333 rtx dfreg = gen_reg_rtx (DFmode);
6334 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6335 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6340 rtx dreg = operands[1];
6342 dreg = force_reg (SImode, dreg);
6343 dreg = convert_to_mode (DImode, dreg, false);
6344 emit_insn (gen_floatdisf2 (operands[0], dreg));
6349 (define_insn "floatdidf2"
6350 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6351 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6352 "TARGET_FCFID && TARGET_HARD_FLOAT"
6356 [(set_attr "type" "fp")])
6358 ; Allow the combiner to merge source memory operands to the conversion so that
6359 ; the optimizer/register allocator doesn't try to load the value too early in a
6360 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6361 ; hit. We will split after reload to avoid the trip through the GPRs
6363 (define_insn_and_split "*floatdidf2_mem"
6364 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6365 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6366 (clobber (match_scratch:DI 2 "=d,wa"))]
6367 "TARGET_HARD_FLOAT && TARGET_FCFID"
6369 "&& reload_completed"
6370 [(set (match_dup 2) (match_dup 1))
6371 (set (match_dup 0) (float:DF (match_dup 2)))]
6373 [(set_attr "length" "8")
6374 (set_attr "type" "fpload")])
6376 (define_expand "floatunsdidf2"
6377 [(set (match_operand:DF 0 "gpc_reg_operand")
6379 (match_operand:DI 1 "gpc_reg_operand")))]
6380 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6383 (define_insn "*floatunsdidf2_fcfidu"
6384 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6385 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6386 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6390 [(set_attr "type" "fp")])
6392 (define_insn_and_split "*floatunsdidf2_mem"
6393 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6394 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6395 (clobber (match_scratch:DI 2 "=d,wa"))]
6396 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6398 "&& reload_completed"
6399 [(set (match_dup 2) (match_dup 1))
6400 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6402 [(set_attr "length" "8")
6403 (set_attr "type" "fpload")])
6405 (define_expand "floatdisf2"
6406 [(set (match_operand:SF 0 "gpc_reg_operand")
6407 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6408 "TARGET_FCFID && TARGET_HARD_FLOAT
6409 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6413 rtx val = operands[1];
6414 if (!flag_unsafe_math_optimizations)
6416 rtx label = gen_label_rtx ();
6417 val = gen_reg_rtx (DImode);
6418 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6421 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6426 (define_insn "floatdisf2_fcfids"
6427 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6428 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6429 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6433 [(set_attr "type" "fp")
6434 (set_attr "isa" "*,p8v")])
6436 (define_insn_and_split "*floatdisf2_mem"
6437 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6438 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6439 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6440 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6442 "&& reload_completed"
6445 emit_move_insn (operands[2], operands[1]);
6446 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6449 [(set_attr "length" "8")
6450 (set_attr "isa" "*,p8v,p8v")])
6452 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6453 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6454 ;; from double rounding.
6455 ;; Instead of creating a new cpu type for two FP operations, just use fp
6456 (define_insn_and_split "floatdisf2_internal1"
6457 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6458 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6459 (clobber (match_scratch:DF 2 "=d"))]
6460 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6462 "&& reload_completed"
6464 (float:DF (match_dup 1)))
6466 (float_truncate:SF (match_dup 2)))]
6468 [(set_attr "length" "8")
6469 (set_attr "type" "fp")])
6471 ;; Twiddles bits to avoid double rounding.
6472 ;; Bits that might be truncated when converting to DFmode are replaced
6473 ;; by a bit that won't be lost at that stage, but is below the SFmode
6474 ;; rounding position.
6475 (define_expand "floatdisf2_internal2"
6476 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6478 (clobber (reg:DI CA_REGNO))])
6479 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6481 (set (match_dup 3) (plus:DI (match_dup 3)
6483 (set (match_dup 0) (plus:DI (match_dup 0)
6485 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6487 (set (match_dup 0) (ior:DI (match_dup 0)
6489 (set (match_dup 0) (and:DI (match_dup 0)
6491 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6492 (label_ref (match_operand:DI 2 ""))
6494 (set (match_dup 0) (match_dup 1))]
6495 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6497 operands[3] = gen_reg_rtx (DImode);
6498 operands[4] = gen_reg_rtx (CCUNSmode);
6501 (define_expand "floatunsdisf2"
6502 [(set (match_operand:SF 0 "gpc_reg_operand")
6503 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6504 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6507 (define_insn "floatunsdisf2_fcfidus"
6508 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6509 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6510 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6514 [(set_attr "type" "fp")
6515 (set_attr "isa" "*,p8v")])
6517 (define_insn_and_split "*floatunsdisf2_mem"
6518 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6519 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6520 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6521 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6523 "&& reload_completed"
6526 emit_move_insn (operands[2], operands[1]);
6527 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6530 [(set_attr "type" "fpload")
6531 (set_attr "length" "8")
6532 (set_attr "isa" "*,p8v,p8v")])
6534 ;; Define the TImode operations that can be done in a small number
6535 ;; of instructions. The & constraints are to prevent the register
6536 ;; allocator from allocating registers that overlap with the inputs
6537 ;; (for example, having an input in 7,8 and an output in 6,7). We
6538 ;; also allow for the output being the same as one of the inputs.
6540 (define_expand "addti3"
6541 [(set (match_operand:TI 0 "gpc_reg_operand")
6542 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6543 (match_operand:TI 2 "reg_or_short_operand")))]
6546 rtx lo0 = gen_lowpart (DImode, operands[0]);
6547 rtx lo1 = gen_lowpart (DImode, operands[1]);
6548 rtx lo2 = gen_lowpart (DImode, operands[2]);
6549 rtx hi0 = gen_highpart (DImode, operands[0]);
6550 rtx hi1 = gen_highpart (DImode, operands[1]);
6551 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6553 if (!reg_or_short_operand (lo2, DImode))
6554 lo2 = force_reg (DImode, lo2);
6555 if (!adde_operand (hi2, DImode))
6556 hi2 = force_reg (DImode, hi2);
6558 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6559 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6563 (define_expand "subti3"
6564 [(set (match_operand:TI 0 "gpc_reg_operand")
6565 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6566 (match_operand:TI 2 "gpc_reg_operand")))]
6569 rtx lo0 = gen_lowpart (DImode, operands[0]);
6570 rtx lo1 = gen_lowpart (DImode, operands[1]);
6571 rtx lo2 = gen_lowpart (DImode, operands[2]);
6572 rtx hi0 = gen_highpart (DImode, operands[0]);
6573 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6574 rtx hi2 = gen_highpart (DImode, operands[2]);
6576 if (!reg_or_short_operand (lo1, DImode))
6577 lo1 = force_reg (DImode, lo1);
6578 if (!adde_operand (hi1, DImode))
6579 hi1 = force_reg (DImode, hi1);
6581 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6582 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6586 ;; 128-bit logical operations expanders
6588 (define_expand "and<mode>3"
6589 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6590 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6591 (match_operand:BOOL_128 2 "vlogical_operand")))]
6595 (define_expand "ior<mode>3"
6596 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6597 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6598 (match_operand:BOOL_128 2 "vlogical_operand")))]
6602 (define_expand "xor<mode>3"
6603 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6604 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6605 (match_operand:BOOL_128 2 "vlogical_operand")))]
6609 (define_expand "nor<mode>3"
6610 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6612 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6613 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6617 (define_expand "andc<mode>3"
6618 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6620 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6621 (match_operand:BOOL_128 1 "vlogical_operand")))]
6625 ;; Power8 vector logical instructions.
6626 (define_expand "eqv<mode>3"
6627 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6629 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6630 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6631 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6634 ;; Rewrite nand into canonical form
6635 (define_expand "nand<mode>3"
6636 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6638 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6639 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6640 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6643 ;; The canonical form is to have the negated element first, so we need to
6644 ;; reverse arguments.
6645 (define_expand "orc<mode>3"
6646 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6648 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6649 (match_operand:BOOL_128 1 "vlogical_operand")))]
6650 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6653 ;; 128-bit logical operations insns and split operations
6654 (define_insn_and_split "*and<mode>3_internal"
6655 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6657 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6658 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6661 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6662 return "xxland %x0,%x1,%x2";
6664 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6665 return "vand %0,%1,%2";
6669 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6672 rs6000_split_logical (operands, AND, false, false, false);
6677 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6678 (const_string "veclogical")
6679 (const_string "integer")))
6680 (set (attr "length")
6682 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6685 (match_test "TARGET_POWERPC64")
6687 (const_string "16"))))])
6690 (define_insn_and_split "*bool<mode>3_internal"
6691 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6692 (match_operator:BOOL_128 3 "boolean_or_operator"
6693 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6694 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6697 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6698 return "xxl%q3 %x0,%x1,%x2";
6700 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6701 return "v%q3 %0,%1,%2";
6705 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6708 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6713 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6714 (const_string "veclogical")
6715 (const_string "integer")))
6716 (set (attr "length")
6718 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6721 (match_test "TARGET_POWERPC64")
6723 (const_string "16"))))])
6726 (define_insn_and_split "*boolc<mode>3_internal1"
6727 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6728 (match_operator:BOOL_128 3 "boolean_operator"
6730 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6731 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6732 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6734 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6735 return "xxl%q3 %x0,%x1,%x2";
6737 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6738 return "v%q3 %0,%1,%2";
6742 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6743 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6746 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6751 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6752 (const_string "veclogical")
6753 (const_string "integer")))
6754 (set (attr "length")
6756 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6759 (match_test "TARGET_POWERPC64")
6761 (const_string "16"))))])
6763 (define_insn_and_split "*boolc<mode>3_internal2"
6764 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6765 (match_operator:TI2 3 "boolean_operator"
6767 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6768 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6769 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6771 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6774 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6777 [(set_attr "type" "integer")
6778 (set (attr "length")
6780 (match_test "TARGET_POWERPC64")
6782 (const_string "16")))])
6785 (define_insn_and_split "*boolcc<mode>3_internal1"
6786 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6787 (match_operator:BOOL_128 3 "boolean_operator"
6789 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6791 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6792 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6794 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6795 return "xxl%q3 %x0,%x1,%x2";
6797 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6798 return "v%q3 %0,%1,%2";
6802 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6803 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6806 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6811 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6812 (const_string "veclogical")
6813 (const_string "integer")))
6814 (set (attr "length")
6816 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6819 (match_test "TARGET_POWERPC64")
6821 (const_string "16"))))])
6823 (define_insn_and_split "*boolcc<mode>3_internal2"
6824 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6825 (match_operator:TI2 3 "boolean_operator"
6827 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6829 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6830 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6832 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6835 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6838 [(set_attr "type" "integer")
6839 (set (attr "length")
6841 (match_test "TARGET_POWERPC64")
6843 (const_string "16")))])
6847 (define_insn_and_split "*eqv<mode>3_internal1"
6848 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6851 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6852 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6855 if (vsx_register_operand (operands[0], <MODE>mode))
6856 return "xxleqv %x0,%x1,%x2";
6860 "TARGET_P8_VECTOR && reload_completed
6861 && int_reg_operand (operands[0], <MODE>mode)"
6864 rs6000_split_logical (operands, XOR, true, false, false);
6869 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6870 (const_string "veclogical")
6871 (const_string "integer")))
6872 (set (attr "length")
6874 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6877 (match_test "TARGET_POWERPC64")
6879 (const_string "16"))))])
6881 (define_insn_and_split "*eqv<mode>3_internal2"
6882 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6885 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6886 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6889 "reload_completed && !TARGET_P8_VECTOR"
6892 rs6000_split_logical (operands, XOR, true, false, false);
6895 [(set_attr "type" "integer")
6896 (set (attr "length")
6898 (match_test "TARGET_POWERPC64")
6900 (const_string "16")))])
6902 ;; 128-bit one's complement
6903 (define_insn_and_split "one_cmpl<mode>2"
6904 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6906 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6909 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6910 return "xxlnor %x0,%x1,%x1";
6912 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6913 return "vnor %0,%1,%1";
6917 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6920 rs6000_split_logical (operands, NOT, false, false, false);
6925 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6926 (const_string "veclogical")
6927 (const_string "integer")))
6928 (set (attr "length")
6930 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6933 (match_test "TARGET_POWERPC64")
6935 (const_string "16"))))])
6938 ;; Now define ways of moving data around.
6940 ;; Set up a register with a value from the GOT table
6942 (define_expand "movsi_got"
6943 [(set (match_operand:SI 0 "gpc_reg_operand")
6944 (unspec:SI [(match_operand:SI 1 "got_operand")
6945 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6946 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6948 if (GET_CODE (operands[1]) == CONST)
6950 rtx offset = const0_rtx;
6951 HOST_WIDE_INT value;
6953 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6954 value = INTVAL (offset);
6957 rtx tmp = (!can_create_pseudo_p ()
6959 : gen_reg_rtx (Pmode));
6960 emit_insn (gen_movsi_got (tmp, operands[1]));
6961 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6966 operands[2] = rs6000_got_register (operands[1]);
6969 (define_insn "*movsi_got_internal"
6970 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6971 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6972 (match_operand:SI 2 "gpc_reg_operand" "b")]
6974 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6975 "lwz %0,%a1@got(%2)"
6976 [(set_attr "type" "load")])
6978 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6979 ;; didn't get allocated to a hard register.
6981 [(set (match_operand:SI 0 "gpc_reg_operand")
6982 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6983 (match_operand:SI 2 "memory_operand")]
6985 "DEFAULT_ABI == ABI_V4
6987 && reload_completed"
6988 [(set (match_dup 0) (match_dup 2))
6989 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6994 ;; LWZ LFIWZX LXSIWZX
6995 ;; STW STFIWX STXSIWX
6997 ;; XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6998 ;; XXLXOR 0 XXLORC -1 P9 const
7002 (define_insn "*movsi_internal1"
7003 [(set (match_operand:SI 0 "nonimmediate_operand"
7012 (match_operand:SI 1 "input_operand"
7021 "gpc_reg_operand (operands[0], SImode)
7022 || gpc_reg_operand (operands[1], SImode)"
7050 load, fpload, fpload,
7051 store, fpstore, fpstore,
7053 veclogical, vecsimple, vecsimple, vecsimple,
7054 veclogical, veclogical, vecsimple,
7076 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
7077 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
7079 ;; Because SF values are actually stored as DF values within the vector
7080 ;; registers, we need to convert the value to the vector SF format when
7081 ;; we need to use the bits in a union or similar cases. We only need
7082 ;; to do this transformation when the value is a vector register. Loads,
7083 ;; stores, and transfers within GPRs are assumed to be safe.
7085 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
7086 ;; no alternatives, because the call is created as part of secondary_reload,
7087 ;; and operand #2's register class is used to allocate the temporary register.
7088 ;; This function is called before reload, and it creates the temporary as
7091 ;; MR LWZ LFIWZX LXSIWZX STW
7092 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
7095 (define_insn_and_split "movsi_from_sf"
7096 [(set (match_operand:SI 0 "nonimmediate_operand"
7097 "=r, r, ?*d, ?*v, m,
7100 (unspec:SI [(match_operand:SF 1 "input_operand"
7105 (clobber (match_scratch:V4SF 2
7109 "TARGET_NO_SF_SUBREG
7110 && (register_operand (operands[0], SImode)
7111 || register_operand (operands[1], SFmode))"
7124 "&& reload_completed
7125 && int_reg_operand (operands[0], SImode)
7126 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7129 rtx op0 = operands[0];
7130 rtx op1 = operands[1];
7131 rtx op2 = operands[2];
7132 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
7133 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7135 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7136 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
7140 "*, load, fpload, fpload, store,
7141 fpstore, fpstore, fpstore, mftgpr, fp,
7149 *, p9v, p8v, p8v, p8v,
7152 ;; movsi_from_sf with zero extension
7154 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7157 (define_insn_and_split "*movdi_from_sf_zero_ext"
7158 [(set (match_operand:DI 0 "gpc_reg_operand"
7159 "=r, r, ?*d, ?*v, r,
7162 (unspec:SI [(match_operand:SF 1 "input_operand"
7165 UNSPEC_SI_FROM_SF)))
7166 (clobber (match_scratch:V4SF 2
7169 "TARGET_DIRECT_MOVE_64BIT
7170 && (register_operand (operands[0], DImode)
7171 || register_operand (operands[1], SImode))"
7180 "&& reload_completed
7181 && register_operand (operands[0], DImode)
7182 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7185 rtx op0 = operands[0];
7186 rtx op1 = operands[1];
7187 rtx op2 = operands[2];
7188 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7190 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7191 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7195 "*, load, fpload, fpload, two,
7201 "*, *, p8v, p8v, p8v,
7204 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7205 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7206 ;; conversion explicitly since that doesn't work in most cases if the input
7207 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7208 ;; former handles cases where the input will not fit in a SFmode, and the
7209 ;; latter assumes the value has already been rounded.
7210 (define_insn "*movsi_from_df"
7211 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7212 (unspec:SI [(float_truncate:SF
7213 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7214 UNSPEC_SI_FROM_SF))]
7215 "TARGET_NO_SF_SUBREG"
7217 [(set_attr "type" "fp")])
7219 ;; Split a load of a large constant into the appropriate two-insn
7223 [(set (match_operand:SI 0 "gpc_reg_operand")
7224 (match_operand:SI 1 "const_int_operand"))]
7225 "num_insns_constant (operands[1], SImode) > 1"
7229 (ior:SI (match_dup 0)
7232 if (rs6000_emit_set_const (operands[0], operands[1]))
7238 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7240 [(set (match_operand:DI 0 "altivec_register_operand")
7241 (match_operand:DI 1 "xxspltib_constant_split"))]
7242 "TARGET_P9_VECTOR && reload_completed"
7245 rtx op0 = operands[0];
7246 rtx op1 = operands[1];
7247 int r = REGNO (op0);
7248 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7250 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7251 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7255 (define_insn "*mov<mode>_internal2"
7256 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7257 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7259 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7265 [(set_attr "type" "cmp,logical,cmp")
7266 (set_attr "dot" "yes")
7267 (set_attr "length" "4,4,8")])
7270 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7271 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7273 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7275 [(set (match_dup 0) (match_dup 1))
7277 (compare:CC (match_dup 0)
7281 (define_expand "mov<mode>"
7282 [(set (match_operand:INT 0 "general_operand")
7283 (match_operand:INT 1 "any_operand"))]
7286 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7290 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7291 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7292 ;; MTVSRWZ MF%1 MT%1 NOP
7293 (define_insn "*mov<mode>_internal"
7294 [(set (match_operand:QHI 0 "nonimmediate_operand"
7295 "=r, r, wa, m, Z, r,
7296 wa, wa, wa, v, ?v, r,
7298 (match_operand:QHI 1 "input_operand"
7300 wa, O, wM, wB, wS, wa,
7302 "gpc_reg_operand (operands[0], <MODE>mode)
7303 || gpc_reg_operand (operands[1], <MODE>mode)"
7322 "*, load, fpload, store, fpstore, *,
7323 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7324 mffgpr, mfjmpr, mtjmpr, *")
7330 "*, *, p9v, *, p9v, *,
7331 p9v, p9v, p9v, p9v, p9v, p9v,
7335 ;; Here is how to move condition codes around. When we store CC data in
7336 ;; an integer register or memory, we store just the high-order 4 bits.
7337 ;; This lets us not shift in the most common case of CR0.
7338 (define_expand "movcc"
7339 [(set (match_operand:CC 0 "nonimmediate_operand")
7340 (match_operand:CC 1 "nonimmediate_operand"))]
7344 (define_mode_iterator CC_any [CC CCUNS CCEQ CCFP])
7346 (define_insn "*movcc_<mode>"
7347 [(set (match_operand:CC_any 0 "nonimmediate_operand"
7348 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7349 (match_operand:CC_any 1 "general_operand"
7350 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7351 "register_operand (operands[0], <MODE>mode)
7352 || register_operand (operands[1], <MODE>mode)"
7356 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7359 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7366 [(set_attr_alternative "type"
7367 [(const_string "cr_logical")
7368 (const_string "mtcr")
7369 (const_string "mtcr")
7370 (const_string "cr_logical")
7371 (if_then_else (match_test "TARGET_MFCRF")
7372 (const_string "mfcrf") (const_string "mfcr"))
7373 (if_then_else (match_test "TARGET_MFCRF")
7374 (const_string "mfcrf") (const_string "mfcr"))
7375 (const_string "integer")
7376 (const_string "integer")
7377 (const_string "mfjmpr")
7378 (const_string "mtjmpr")
7379 (const_string "load")
7380 (const_string "store")])
7381 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7383 ;; For floating-point, we normally deal with the floating-point registers
7384 ;; unless -msoft-float is used. The sole exception is that parameter passing
7385 ;; can produce floating-point values in fixed-point registers. Unless the
7386 ;; value is a simple constant or already in memory, we deal with this by
7387 ;; allocating memory and copying the value explicitly via that memory location.
7389 ;; Move 32-bit binary/decimal floating point
7390 (define_expand "mov<mode>"
7391 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7392 (match_operand:FMOVE32 1 "any_operand"))]
7395 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7400 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7401 (match_operand:FMOVE32 1 "const_double_operand"))]
7403 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7404 || (SUBREG_P (operands[0])
7405 && REG_P (SUBREG_REG (operands[0]))
7406 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7407 [(set (match_dup 2) (match_dup 3))]
7411 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7413 if (! TARGET_POWERPC64)
7414 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7416 operands[2] = gen_lowpart (SImode, operands[0]);
7418 operands[3] = gen_int_mode (l, SImode);
7421 ;; Originally, we tried to keep movsf and movsd common, but the differences
7422 ;; addressing was making it rather difficult to hide with mode attributes. In
7423 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7424 ;; before the VSX stores meant that the register allocator would tend to do a
7425 ;; direct move to the GPR (which involves conversion from scalar to
7426 ;; vector/memory formats) to save values in the traditional Altivec registers,
7427 ;; while SDmode had problems on power6 if the GPR store was not first due to
7428 ;; the power6 not having an integer store operation.
7430 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7431 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7432 ;; MR MT<x> MF<x> NOP
7434 (define_insn "movsf_hardfloat"
7435 [(set (match_operand:SF 0 "nonimmediate_operand"
7436 "=!r, f, v, wa, m, wY,
7437 Z, m, wa, !r, f, wa,
7439 (match_operand:SF 1 "input_operand"
7443 "(register_operand (operands[0], SFmode)
7444 || register_operand (operands[1], SFmode))
7445 && TARGET_HARD_FLOAT
7446 && (TARGET_ALLOW_SF_SUBREG
7447 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7460 xscpsgndp %x0,%x1,%x1
7466 "load, fpload, fpload, fpload, fpstore, fpstore,
7467 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7468 *, mtjmpr, mfjmpr, *")
7470 "*, *, p9v, p8v, *, p9v,
7474 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7475 ;; FMR MR MT%0 MF%1 NOP
7476 (define_insn "movsd_hardfloat"
7477 [(set (match_operand:SD 0 "nonimmediate_operand"
7478 "=!r, d, m, Z, ?d, ?r,
7479 f, !r, *c*l, !r, *h")
7480 (match_operand:SD 1 "input_operand"
7483 "(register_operand (operands[0], SDmode)
7484 || register_operand (operands[1], SDmode))
7485 && TARGET_HARD_FLOAT"
7499 "load, fpload, store, fpstore, mffgpr, mftgpr,
7500 fpsimple, *, mtjmpr, mfjmpr, *")
7502 "*, p7, *, *, p8v, p8v,
7505 ;; MR MT%0 MF%0 LWZ STW LI
7506 ;; LIS G-const. F/n-const NOP
7507 (define_insn "*mov<mode>_softfloat"
7508 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7509 "=r, *c*l, r, r, m, r,
7512 (match_operand:FMOVE32 1 "input_operand"
7516 "(gpc_reg_operand (operands[0], <MODE>mode)
7517 || gpc_reg_operand (operands[1], <MODE>mode))
7518 && TARGET_SOFT_FLOAT"
7531 "*, mtjmpr, mfjmpr, load, store, *,
7538 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7539 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7541 ;; Because SF values are actually stored as DF values within the vector
7542 ;; registers, we need to convert the value to the vector SF format when
7543 ;; we need to use the bits in a union or similar cases. We only need
7544 ;; to do this transformation when the value is a vector register. Loads,
7545 ;; stores, and transfers within GPRs are assumed to be safe.
7547 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7548 ;; no alternatives, because the call is created as part of secondary_reload,
7549 ;; and operand #2's register class is used to allocate the temporary register.
7550 ;; This function is called before reload, and it creates the temporary as
7553 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7554 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7555 (define_insn_and_split "movsf_from_si"
7556 [(set (match_operand:SF 0 "nonimmediate_operand"
7557 "=!r, f, v, wa, m, Z,
7559 (unspec:SF [(match_operand:SI 1 "input_operand"
7563 (clobber (match_scratch:DI 2
7566 "TARGET_NO_SF_SUBREG
7567 && (register_operand (operands[0], SFmode)
7568 || register_operand (operands[1], SImode))"
7581 "&& reload_completed
7582 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7583 && int_reg_operand_not_pseudo (operands[1], SImode)"
7586 rtx op0 = operands[0];
7587 rtx op1 = operands[1];
7588 rtx op2 = operands[2];
7589 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7591 /* Move SF value to upper 32-bits for xscvspdpn. */
7592 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7593 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7594 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7601 "load, fpload, fpload, fpload, store, fpstore,
7602 fpstore, vecfloat, mffgpr, *")
7604 "*, *, p9v, p8v, *, *,
7605 p8v, p8v, p8v, *")])
7608 ;; Move 64-bit binary/decimal floating point
7609 (define_expand "mov<mode>"
7610 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7611 (match_operand:FMOVE64 1 "any_operand"))]
7614 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7619 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7620 (match_operand:FMOVE64 1 "const_int_operand"))]
7621 "! TARGET_POWERPC64 && reload_completed
7622 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7623 || (SUBREG_P (operands[0])
7624 && REG_P (SUBREG_REG (operands[0]))
7625 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7626 [(set (match_dup 2) (match_dup 4))
7627 (set (match_dup 3) (match_dup 1))]
7629 int endian = (WORDS_BIG_ENDIAN == 0);
7630 HOST_WIDE_INT value = INTVAL (operands[1]);
7632 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7633 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7634 operands[4] = GEN_INT (value >> 32);
7635 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7639 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7640 (match_operand:FMOVE64 1 "const_double_operand"))]
7641 "! TARGET_POWERPC64 && reload_completed
7642 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7643 || (SUBREG_P (operands[0])
7644 && REG_P (SUBREG_REG (operands[0]))
7645 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7646 [(set (match_dup 2) (match_dup 4))
7647 (set (match_dup 3) (match_dup 5))]
7649 int endian = (WORDS_BIG_ENDIAN == 0);
7652 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7654 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7655 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7656 operands[4] = gen_int_mode (l[endian], SImode);
7657 operands[5] = gen_int_mode (l[1 - endian], SImode);
7661 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7662 (match_operand:FMOVE64 1 "const_double_operand"))]
7663 "TARGET_POWERPC64 && reload_completed
7664 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7665 || (SUBREG_P (operands[0])
7666 && REG_P (SUBREG_REG (operands[0]))
7667 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7668 [(set (match_dup 2) (match_dup 3))]
7670 int endian = (WORDS_BIG_ENDIAN == 0);
7674 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7676 operands[2] = gen_lowpart (DImode, operands[0]);
7677 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7678 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7679 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7681 operands[3] = gen_int_mode (val, DImode);
7684 ;; Don't have reload use general registers to load a constant. It is
7685 ;; less efficient than loading the constant into an FP register, since
7686 ;; it will probably be used there.
7688 ;; The move constraints are ordered to prefer floating point registers before
7689 ;; general purpose registers to avoid doing a store and a load to get the value
7690 ;; into a floating point register when it is needed for a floating point
7691 ;; operation. Prefer traditional floating point registers over VSX registers,
7692 ;; since the D-form version of the memory instructions does not need a GPR for
7693 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7696 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7697 ;; except for 0.0 which can be created on VSX with an xor instruction.
7699 ;; STFD LFD FMR LXSD STXSD
7700 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7704 (define_insn "*mov<mode>_hardfloat32"
7705 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7706 "=m, d, d, <f64_p9>, wY,
7707 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7709 (match_operand:FMOVE64 1 "input_operand"
7710 "d, m, d, wY, <f64_p9>,
7711 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7713 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7714 && (gpc_reg_operand (operands[0], <MODE>mode)
7715 || gpc_reg_operand (operands[1], <MODE>mode))"
7731 "fpstore, fpload, fpsimple, fpload, fpstore,
7732 fpload, fpstore, veclogical, veclogical, two,
7734 (set_attr "size" "64")
7744 ;; STW LWZ MR G-const H-const F-const
7746 (define_insn "*mov<mode>_softfloat32"
7747 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7748 "=Y, r, r, r, r, r")
7750 (match_operand:FMOVE64 1 "input_operand"
7751 "r, Y, r, G, H, F"))]
7754 && (gpc_reg_operand (operands[0], <MODE>mode)
7755 || gpc_reg_operand (operands[1], <MODE>mode))"
7758 "store, load, two, *, *, *")
7761 "8, 8, 8, 8, 12, 16")])
7763 ; ld/std require word-aligned displacements -> 'Y' constraint.
7764 ; List Y->r and r->Y before r->r for reload.
7766 ;; STFD LFD FMR LXSD STXSD
7767 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7768 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7769 ;; NOP MFVSRD MTVSRD
7771 (define_insn "*mov<mode>_hardfloat64"
7772 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7773 "=m, d, d, <f64_p9>, wY,
7774 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7775 YZ, r, !r, *c*l, !r,
7777 (match_operand:FMOVE64 1 "input_operand"
7778 "d, m, d, wY, <f64_p9>,
7779 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7782 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7783 && (gpc_reg_operand (operands[0], <MODE>mode)
7784 || gpc_reg_operand (operands[1], <MODE>mode))"
7805 "fpstore, fpload, fpsimple, fpload, fpstore,
7806 fpload, fpstore, veclogical, veclogical, integer,
7807 store, load, *, mtjmpr, mfjmpr,
7809 (set_attr "size" "64")
7816 ;; STD LD MR MT<SPR> MF<SPR> G-const
7817 ;; H-const F-const Special
7819 (define_insn "*mov<mode>_softfloat64"
7820 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7821 "=Y, r, r, *c*l, r, r,
7824 (match_operand:FMOVE64 1 "input_operand"
7828 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7829 && (gpc_reg_operand (operands[0], <MODE>mode)
7830 || gpc_reg_operand (operands[1], <MODE>mode))"
7842 "store, load, *, mtjmpr, mfjmpr, *,
7849 (define_expand "mov<mode>"
7850 [(set (match_operand:FMOVE128 0 "general_operand")
7851 (match_operand:FMOVE128 1 "any_operand"))]
7854 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7858 ;; It's important to list Y->r and r->Y before r->r because otherwise
7859 ;; reload, given m->r, will try to pick r->r and reload it, which
7860 ;; doesn't make progress.
7862 ;; We can't split little endian direct moves of TDmode, because the words are
7863 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7864 ;; problematical. Don't allow direct move for this case.
7866 ;; FPR load FPR store FPR move FPR zero GPR load
7867 ;; GPR zero GPR store GPR move MFVSRD MTVSRD
7869 (define_insn_and_split "*mov<mode>_64bit_dm"
7870 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand"
7874 (match_operand:FMOVE128_FPR 1 "input_operand"
7875 "d, m, d, <zero_fp>, r,
7876 <zero_fp>, Y, r, d, r"))]
7878 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7879 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7880 && (gpc_reg_operand (operands[0], <MODE>mode)
7881 || gpc_reg_operand (operands[1], <MODE>mode))"
7883 "&& reload_completed"
7886 rs6000_split_multireg_move (operands[0], operands[1]);
7889 [(set_attr "length" "8")
7890 (set_attr "isa" "*,*,*,*,*,*,*,*,p8v,p8v")
7891 (set_attr "max_prefixed_insns" "2")
7892 (set_attr "num_insns" "2")])
7894 (define_insn_and_split "*movtd_64bit_nodm"
7895 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7896 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7897 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7898 && (gpc_reg_operand (operands[0], TDmode)
7899 || gpc_reg_operand (operands[1], TDmode))"
7901 "&& reload_completed"
7904 rs6000_split_multireg_move (operands[0], operands[1]);
7907 [(set_attr "length" "8,8,8,12,12,8")
7908 (set_attr "max_prefixed_insns" "2")
7909 (set_attr "num_insns" "2,2,2,3,3,2")])
7911 (define_insn_and_split "*mov<mode>_32bit"
7912 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7913 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7914 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7915 && (FLOAT128_2REG_P (<MODE>mode)
7916 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7917 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7918 && (gpc_reg_operand (operands[0], <MODE>mode)
7919 || gpc_reg_operand (operands[1], <MODE>mode))"
7921 "&& reload_completed"
7924 rs6000_split_multireg_move (operands[0], operands[1]);
7927 [(set_attr "length" "8,8,8,8,20,20,16")])
7929 (define_insn_and_split "*mov<mode>_softfloat"
7930 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7931 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7933 && (gpc_reg_operand (operands[0], <MODE>mode)
7934 || gpc_reg_operand (operands[1], <MODE>mode))"
7936 "&& reload_completed"
7939 rs6000_split_multireg_move (operands[0], operands[1]);
7942 [(set_attr_alternative "length"
7943 [(if_then_else (match_test "TARGET_POWERPC64")
7945 (const_string "16"))
7946 (if_then_else (match_test "TARGET_POWERPC64")
7948 (const_string "16"))
7949 (if_then_else (match_test "TARGET_POWERPC64")
7951 (const_string "32"))
7952 (if_then_else (match_test "TARGET_POWERPC64")
7954 (const_string "16"))])])
7956 (define_expand "@extenddf<mode>2"
7957 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7958 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7959 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7961 if (FLOAT128_IEEE_P (<MODE>mode))
7962 rs6000_expand_float128_convert (operands[0], operands[1], false);
7963 else if (TARGET_VSX)
7964 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7967 rtx zero = gen_reg_rtx (DFmode);
7968 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7970 emit_insn (gen_extenddf2_fprs (<MODE>mode,
7971 operands[0], operands[1], zero));
7976 ;; Allow memory operands for the source to be created by the combiner.
7977 (define_insn_and_split "@extenddf<mode>2_fprs"
7978 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7979 (float_extend:IBM128
7980 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7981 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7982 "!TARGET_VSX && TARGET_HARD_FLOAT
7983 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7985 "&& reload_completed"
7986 [(set (match_dup 3) (match_dup 1))
7987 (set (match_dup 4) (match_dup 2))]
7989 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7990 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7992 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7993 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7996 (define_insn_and_split "@extenddf<mode>2_vsx"
7997 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7998 (float_extend:IBM128
7999 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
8000 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
8002 "&& reload_completed"
8003 [(set (match_dup 2) (match_dup 1))
8004 (set (match_dup 3) (match_dup 4))]
8006 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8007 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8009 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8010 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8011 operands[4] = CONST0_RTX (DFmode);
8014 (define_expand "extendsf<mode>2"
8015 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8016 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
8017 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8019 if (FLOAT128_IEEE_P (<MODE>mode))
8020 rs6000_expand_float128_convert (operands[0], operands[1], false);
8023 rtx tmp = gen_reg_rtx (DFmode);
8024 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
8025 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
8030 (define_expand "trunc<mode>df2"
8031 [(set (match_operand:DF 0 "gpc_reg_operand")
8032 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8033 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8035 if (FLOAT128_IEEE_P (<MODE>mode))
8037 rs6000_expand_float128_convert (operands[0], operands[1], false);
8042 (define_insn_and_split "trunc<mode>df2_internal1"
8043 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
8045 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
8046 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
8047 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8051 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
8054 emit_note (NOTE_INSN_DELETED);
8057 [(set_attr "type" "fpsimple")])
8059 (define_insn "trunc<mode>df2_internal2"
8060 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8061 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8062 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
8063 && TARGET_LONG_DOUBLE_128"
8065 [(set_attr "type" "fp")])
8067 (define_expand "trunc<mode>sf2"
8068 [(set (match_operand:SF 0 "gpc_reg_operand")
8069 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8070 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8072 if (FLOAT128_IEEE_P (<MODE>mode))
8073 rs6000_expand_float128_convert (operands[0], operands[1], false);
8076 rtx tmp = gen_reg_rtx (DFmode);
8077 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
8078 emit_insn (gen_truncdfsf2 (operands[0], tmp));
8083 (define_expand "floatsi<mode>2"
8084 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8085 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
8086 (clobber (match_scratch:DI 2))])]
8087 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8089 rtx op0 = operands[0];
8090 rtx op1 = operands[1];
8092 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8094 else if (FLOAT128_IEEE_P (<MODE>mode))
8096 rs6000_expand_float128_convert (op0, op1, false);
8101 rtx tmp = gen_reg_rtx (DFmode);
8102 expand_float (tmp, op1, false);
8103 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
8108 ; fadd, but rounding towards zero.
8109 ; This is probably not the optimal code sequence.
8110 (define_insn "fix_trunc_helper<mode>"
8111 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
8112 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
8113 UNSPEC_FIX_TRUNC_TF))
8114 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
8115 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8116 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
8117 [(set_attr "type" "fp")
8118 (set_attr "length" "20")])
8120 (define_expand "fix_trunc<mode>si2"
8121 [(set (match_operand:SI 0 "gpc_reg_operand")
8122 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8123 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8125 rtx op0 = operands[0];
8126 rtx op1 = operands[1];
8128 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
8132 if (FLOAT128_IEEE_P (<MODE>mode))
8133 rs6000_expand_float128_convert (op0, op1, false);
8135 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
8140 (define_expand "@fix_trunc<mode>si2_fprs"
8141 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
8142 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
8143 (clobber (match_dup 2))
8144 (clobber (match_dup 3))
8145 (clobber (match_dup 4))
8146 (clobber (match_dup 5))])]
8147 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8149 operands[2] = gen_reg_rtx (DFmode);
8150 operands[3] = gen_reg_rtx (DFmode);
8151 operands[4] = gen_reg_rtx (DImode);
8152 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
8155 (define_insn_and_split "*fix_trunc<mode>si2_internal"
8156 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
8157 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
8158 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
8159 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
8160 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
8161 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
8162 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8168 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
8171 gcc_assert (MEM_P (operands[5]));
8172 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
8174 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
8175 emit_move_insn (operands[5], operands[4]);
8176 emit_move_insn (operands[0], lowword);
8180 (define_expand "fix_trunc<mode>di2"
8181 [(set (match_operand:DI 0 "gpc_reg_operand")
8182 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8183 "TARGET_FLOAT128_TYPE"
8185 if (!TARGET_FLOAT128_HW)
8187 rs6000_expand_float128_convert (operands[0], operands[1], false);
8192 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8193 [(set (match_operand:SDI 0 "gpc_reg_operand")
8194 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8195 "TARGET_FLOAT128_TYPE"
8197 rs6000_expand_float128_convert (operands[0], operands[1], true);
8201 (define_expand "floatdi<mode>2"
8202 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8203 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8204 "TARGET_FLOAT128_TYPE"
8206 if (!TARGET_FLOAT128_HW)
8208 rs6000_expand_float128_convert (operands[0], operands[1], false);
8213 (define_expand "floatunsdi<IEEE128:mode>2"
8214 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8215 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8216 "TARGET_FLOAT128_TYPE"
8218 if (!TARGET_FLOAT128_HW)
8220 rs6000_expand_float128_convert (operands[0], operands[1], true);
8225 (define_expand "floatuns<IEEE128:mode>2"
8226 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8227 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8228 "TARGET_FLOAT128_TYPE"
8230 rtx op0 = operands[0];
8231 rtx op1 = operands[1];
8233 if (TARGET_FLOAT128_HW)
8234 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8236 rs6000_expand_float128_convert (op0, op1, true);
8240 (define_expand "neg<mode>2"
8241 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8242 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8243 "FLOAT128_IEEE_P (<MODE>mode)
8244 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8246 if (FLOAT128_IEEE_P (<MODE>mode))
8248 if (TARGET_FLOAT128_HW)
8249 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8250 else if (TARGET_FLOAT128_TYPE)
8251 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8252 operands[0], operands[1]));
8255 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8256 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8258 operands[1], <MODE>mode);
8260 if (target && !rtx_equal_p (target, operands[0]))
8261 emit_move_insn (operands[0], target);
8267 (define_insn "neg<mode>2_internal"
8268 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8269 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8270 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8272 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8273 return "fneg %L0,%L1\;fneg %0,%1";
8275 return "fneg %0,%1\;fneg %L0,%L1";
8277 [(set_attr "type" "fpsimple")
8278 (set_attr "length" "8")])
8280 (define_expand "abs<mode>2"
8281 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8282 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8283 "FLOAT128_IEEE_P (<MODE>mode)
8284 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8288 if (FLOAT128_IEEE_P (<MODE>mode))
8290 if (TARGET_FLOAT128_HW)
8292 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8295 else if (TARGET_FLOAT128_TYPE)
8297 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8298 operands[0], operands[1]));
8305 label = gen_label_rtx ();
8306 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8311 (define_expand "@abs<mode>2_internal"
8312 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8313 (match_operand:IBM128 1 "gpc_reg_operand"))
8314 (set (match_dup 3) (match_dup 5))
8315 (set (match_dup 5) (abs:DF (match_dup 5)))
8316 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8317 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8318 (label_ref (match_operand 2 ""))
8320 (set (match_dup 6) (neg:DF (match_dup 6)))]
8321 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8323 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8324 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8325 operands[3] = gen_reg_rtx (DFmode);
8326 operands[4] = gen_reg_rtx (CCFPmode);
8327 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8328 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8332 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8335 (define_expand "ieee_128bit_negative_zero"
8336 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8337 "TARGET_FLOAT128_TYPE"
8339 rtvec v = rtvec_alloc (16);
8342 for (i = 0; i < 16; i++)
8343 RTVEC_ELT (v, i) = const0_rtx;
8345 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8346 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8348 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8352 ;; IEEE 128-bit negate
8354 ;; We have 2 insns here for negate and absolute value. The first uses
8355 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8356 ;; insns, and second insn after the first split pass loads up the bit to
8357 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8358 ;; neg/abs to create the constant just once.
8360 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8361 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8362 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8363 (clobber (match_scratch:V16QI 2 "=v"))]
8364 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8367 [(parallel [(set (match_dup 0)
8368 (neg:IEEE128 (match_dup 1)))
8369 (use (match_dup 2))])]
8371 if (GET_CODE (operands[2]) == SCRATCH)
8372 operands[2] = gen_reg_rtx (V16QImode);
8374 operands[3] = gen_reg_rtx (V16QImode);
8375 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8377 [(set_attr "length" "8")
8378 (set_attr "type" "vecsimple")])
8380 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8381 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8382 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8383 (use (match_operand:V16QI 2 "register_operand" "v"))]
8384 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8385 "xxlxor %x0,%x1,%x2"
8386 [(set_attr "type" "veclogical")])
8388 ;; IEEE 128-bit absolute value
8389 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8390 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8391 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8392 (clobber (match_scratch:V16QI 2 "=v"))]
8393 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8396 [(parallel [(set (match_dup 0)
8397 (abs:IEEE128 (match_dup 1)))
8398 (use (match_dup 2))])]
8400 if (GET_CODE (operands[2]) == SCRATCH)
8401 operands[2] = gen_reg_rtx (V16QImode);
8403 operands[3] = gen_reg_rtx (V16QImode);
8404 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8406 [(set_attr "length" "8")
8407 (set_attr "type" "vecsimple")])
8409 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8410 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8411 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8412 (use (match_operand:V16QI 2 "register_operand" "v"))]
8413 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8414 "xxlandc %x0,%x1,%x2"
8415 [(set_attr "type" "veclogical")])
8417 ;; IEEE 128-bit negative absolute value
8418 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8419 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8422 (match_operand:IEEE128 1 "register_operand" "wa"))))
8423 (clobber (match_scratch:V16QI 2 "=v"))]
8424 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8425 && FLOAT128_IEEE_P (<MODE>mode)"
8428 [(parallel [(set (match_dup 0)
8429 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8430 (use (match_dup 2))])]
8432 if (GET_CODE (operands[2]) == SCRATCH)
8433 operands[2] = gen_reg_rtx (V16QImode);
8435 operands[3] = gen_reg_rtx (V16QImode);
8436 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8438 [(set_attr "length" "8")
8439 (set_attr "type" "vecsimple")])
8441 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8442 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8445 (match_operand:IEEE128 1 "register_operand" "wa"))))
8446 (use (match_operand:V16QI 2 "register_operand" "v"))]
8447 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8449 [(set_attr "type" "veclogical")])
8451 ;; Float128 conversion functions. These expand to library function calls.
8452 ;; We use expand to convert from IBM double double to IEEE 128-bit
8453 ;; and trunc for the opposite.
8454 (define_expand "extendiftf2"
8455 [(set (match_operand:TF 0 "gpc_reg_operand")
8456 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8457 "TARGET_FLOAT128_TYPE"
8459 rs6000_expand_float128_convert (operands[0], operands[1], false);
8463 (define_expand "extendifkf2"
8464 [(set (match_operand:KF 0 "gpc_reg_operand")
8465 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8466 "TARGET_FLOAT128_TYPE"
8468 rs6000_expand_float128_convert (operands[0], operands[1], false);
8472 (define_expand "extendtfkf2"
8473 [(set (match_operand:KF 0 "gpc_reg_operand")
8474 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8475 "TARGET_FLOAT128_TYPE"
8477 rs6000_expand_float128_convert (operands[0], operands[1], false);
8481 (define_expand "extendtfif2"
8482 [(set (match_operand:IF 0 "gpc_reg_operand")
8483 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8484 "TARGET_FLOAT128_TYPE"
8486 rs6000_expand_float128_convert (operands[0], operands[1], false);
8490 (define_expand "trunciftf2"
8491 [(set (match_operand:TF 0 "gpc_reg_operand")
8492 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8493 "TARGET_FLOAT128_TYPE"
8495 rs6000_expand_float128_convert (operands[0], operands[1], false);
8499 (define_expand "truncifkf2"
8500 [(set (match_operand:KF 0 "gpc_reg_operand")
8501 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8502 "TARGET_FLOAT128_TYPE"
8504 rs6000_expand_float128_convert (operands[0], operands[1], false);
8508 (define_expand "trunckftf2"
8509 [(set (match_operand:TF 0 "gpc_reg_operand")
8510 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8511 "TARGET_FLOAT128_TYPE"
8513 rs6000_expand_float128_convert (operands[0], operands[1], false);
8517 (define_expand "trunctfif2"
8518 [(set (match_operand:IF 0 "gpc_reg_operand")
8519 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8520 "TARGET_FLOAT128_TYPE"
8522 rs6000_expand_float128_convert (operands[0], operands[1], false);
8526 (define_insn_and_split "*extend<mode>tf2_internal"
8527 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8529 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8530 "TARGET_FLOAT128_TYPE
8531 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8533 "&& reload_completed"
8534 [(set (match_dup 0) (match_dup 2))]
8536 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8539 (define_insn_and_split "*extendtf<mode>2_internal"
8540 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8542 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8543 "TARGET_FLOAT128_TYPE
8544 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8546 "&& reload_completed"
8547 [(set (match_dup 0) (match_dup 2))]
8549 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8553 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8554 ;; must have 3 arguments, and scratch register constraint must be a single
8557 ;; Reload patterns to support gpr load/store with misaligned mem.
8558 ;; and multiple gpr load/store at offset >= 0xfffc
8559 (define_expand "reload_<mode>_store"
8560 [(parallel [(match_operand 0 "memory_operand" "=m")
8561 (match_operand 1 "gpc_reg_operand" "r")
8562 (match_operand:GPR 2 "register_operand" "=&b")])]
8565 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8569 (define_expand "reload_<mode>_load"
8570 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8571 (match_operand 1 "memory_operand" "m")
8572 (match_operand:GPR 2 "register_operand" "=b")])]
8575 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8580 ;; Reload patterns for various types using the vector registers. We may need
8581 ;; an additional base register to convert the reg+offset addressing to reg+reg
8582 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8583 ;; index register for gpr registers.
8584 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8585 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8586 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8587 (match_operand:P 2 "register_operand" "=b")])]
8590 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8594 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8595 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8596 (match_operand:RELOAD 1 "memory_operand" "m")
8597 (match_operand:P 2 "register_operand" "=b")])]
8600 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8605 ;; Reload sometimes tries to move the address to a GPR, and can generate
8606 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8607 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8609 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8610 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8611 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8612 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8614 "TARGET_ALTIVEC && reload_completed"
8616 "&& reload_completed"
8618 (plus:P (match_dup 1)
8621 (and:P (match_dup 0)
8624 ;; Power8 merge instructions to allow direct move to/from floating point
8625 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8626 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8627 ;; value, since it is allocated in reload and not all of the flow information
8628 ;; is setup for it. We have two patterns to do the two moves between gprs and
8629 ;; fprs. There isn't a dependancy between the two, but we could potentially
8630 ;; schedule other instructions between the two instructions.
8632 (define_insn "p8_fmrgow_<mode>"
8633 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8635 (match_operand:DF 1 "register_operand" "d")
8636 (match_operand:DF 2 "register_operand" "d")]
8637 UNSPEC_P8V_FMRGOW))]
8638 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8640 [(set_attr "type" "fpsimple")])
8642 (define_insn "p8_mtvsrwz"
8643 [(set (match_operand:DF 0 "register_operand" "=d")
8644 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8645 UNSPEC_P8V_MTVSRWZ))]
8646 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8648 [(set_attr "type" "mftgpr")])
8650 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8651 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8652 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8653 UNSPEC_P8V_RELOAD_FROM_GPR))
8654 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8655 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8657 "&& reload_completed"
8660 rtx dest = operands[0];
8661 rtx src = operands[1];
8662 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8663 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8664 rtx gpr_hi_reg = gen_highpart (SImode, src);
8665 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8667 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8668 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8669 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8672 [(set_attr "length" "12")
8673 (set_attr "type" "three")])
8675 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8676 (define_insn "p8_mtvsrd_df"
8677 [(set (match_operand:DF 0 "register_operand" "=wa")
8678 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8679 UNSPEC_P8V_MTVSRD))]
8680 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8682 [(set_attr "type" "mftgpr")])
8684 (define_insn "p8_xxpermdi_<mode>"
8685 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8686 (unspec:FMOVE128_GPR [
8687 (match_operand:DF 1 "register_operand" "wa")
8688 (match_operand:DF 2 "register_operand" "wa")]
8689 UNSPEC_P8V_XXPERMDI))]
8690 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8691 "xxpermdi %x0,%x1,%x2,0"
8692 [(set_attr "type" "vecperm")])
8694 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8695 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8696 (unspec:FMOVE128_GPR
8697 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8698 UNSPEC_P8V_RELOAD_FROM_GPR))
8699 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8700 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8702 "&& reload_completed"
8705 rtx dest = operands[0];
8706 rtx src = operands[1];
8707 /* You might think that we could use op0 as one temp and a DF clobber
8708 as op2, but you'd be wrong. Secondary reload move patterns don't
8709 check for overlap of the clobber and the destination. */
8710 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8711 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8712 rtx gpr_hi_reg = gen_highpart (DImode, src);
8713 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8715 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8716 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8717 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8720 [(set_attr "length" "12")
8721 (set_attr "type" "three")])
8724 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8725 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8727 && (int_reg_operand (operands[0], <MODE>mode)
8728 || int_reg_operand (operands[1], <MODE>mode))
8729 && (!TARGET_DIRECT_MOVE_128
8730 || (!vsx_register_operand (operands[0], <MODE>mode)
8731 && !vsx_register_operand (operands[1], <MODE>mode)))"
8734 rs6000_split_multireg_move (operands[0], operands[1]);
8738 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8739 ;; type is stored internally as double precision in the VSX registers, we have
8740 ;; to convert it from the vector format.
8741 (define_insn "p8_mtvsrd_sf"
8742 [(set (match_operand:SF 0 "register_operand" "=wa")
8743 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8744 UNSPEC_P8V_MTVSRD))]
8745 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8747 [(set_attr "type" "mftgpr")])
8749 (define_insn_and_split "reload_vsx_from_gprsf"
8750 [(set (match_operand:SF 0 "register_operand" "=wa")
8751 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8752 UNSPEC_P8V_RELOAD_FROM_GPR))
8753 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8754 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8756 "&& reload_completed"
8759 rtx op0 = operands[0];
8760 rtx op1 = operands[1];
8761 rtx op2 = operands[2];
8762 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8764 /* Move SF value to upper 32-bits for xscvspdpn. */
8765 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8766 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8767 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8770 [(set_attr "length" "8")
8771 (set_attr "type" "two")])
8773 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8774 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8775 ;; and then doing a move of that.
8776 (define_insn "p8_mfvsrd_3_<mode>"
8777 [(set (match_operand:DF 0 "register_operand" "=r")
8778 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8779 UNSPEC_P8V_RELOAD_FROM_VSX))]
8780 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8782 [(set_attr "type" "mftgpr")])
8784 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8785 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8786 (unspec:FMOVE128_GPR
8787 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8788 UNSPEC_P8V_RELOAD_FROM_VSX))
8789 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8790 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8792 "&& reload_completed"
8795 rtx dest = operands[0];
8796 rtx src = operands[1];
8797 rtx tmp = operands[2];
8798 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8799 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8801 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8802 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8803 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8806 [(set_attr "length" "12")
8807 (set_attr "type" "three")])
8809 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8810 ;; type is stored internally as double precision, we have to convert it to the
8813 (define_insn_and_split "reload_gpr_from_vsxsf"
8814 [(set (match_operand:SF 0 "register_operand" "=r")
8815 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8816 UNSPEC_P8V_RELOAD_FROM_VSX))
8817 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8818 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8820 "&& reload_completed"
8823 rtx op0 = operands[0];
8824 rtx op1 = operands[1];
8825 rtx op2 = operands[2];
8826 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8827 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8829 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8830 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8833 [(set_attr "length" "8")
8834 (set_attr "type" "two")
8835 (set_attr "isa" "p8v")])
8837 ;; Next come the multi-word integer load and store and the load and store
8840 ;; List r->r after r->Y, otherwise reload will try to reload a
8841 ;; non-offsettable address by using r->r which won't make progress.
8842 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8843 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8845 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8846 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8847 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8850 (define_insn "*movdi_internal32"
8851 [(set (match_operand:DI 0 "nonimmediate_operand"
8852 "=Y, r, r, m, ^d, ^d,
8853 r, wY, Z, ^v, $v, ^wa,
8854 wa, wa, v, wa, *i, v,
8856 (match_operand:DI 1 "input_operand"
8857 "r, Y, r, ^d, m, ^d,
8858 IJKnF, ^v, $v, wY, Z, ^wa,
8859 Oj, wM, OjwM, Oj, wM, wS,
8862 && (gpc_reg_operand (operands[0], DImode)
8863 || gpc_reg_operand (operands[1], DImode))"
8885 "store, load, *, fpstore, fpload, fpsimple,
8886 *, fpstore, fpstore, fpload, fpload, veclogical,
8887 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8889 (set_attr "size" "64")
8897 *, p9v, p7v, p9v, p7v, *,
8898 p9v, p9v, p7v, *, *, p7v,
8902 [(set (match_operand:DI 0 "gpc_reg_operand")
8903 (match_operand:DI 1 "const_int_operand"))]
8904 "! TARGET_POWERPC64 && reload_completed
8905 && gpr_or_gpr_p (operands[0], operands[1])
8906 && !direct_move_p (operands[0], operands[1])"
8907 [(set (match_dup 2) (match_dup 4))
8908 (set (match_dup 3) (match_dup 1))]
8910 HOST_WIDE_INT value = INTVAL (operands[1]);
8911 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8913 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8915 operands[4] = GEN_INT (value >> 32);
8916 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8920 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8921 (match_operand:DIFD 1 "input_operand"))]
8922 "reload_completed && !TARGET_POWERPC64
8923 && gpr_or_gpr_p (operands[0], operands[1])
8924 && !direct_move_p (operands[0], operands[1])"
8927 rs6000_split_multireg_move (operands[0], operands[1]);
8931 ;; GPR store GPR load GPR move
8932 ;; GPR li GPR lis GPR pli GPR #
8933 ;; FPR store FPR load FPR move
8934 ;; AVX store AVX store AVX load AVX load VSX move
8935 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1
8936 ;; P9 const AVX const
8937 ;; From SPR To SPR SPR<->SPR
8938 ;; VSX->GPR GPR->VSX
8939 (define_insn "*movdi_internal64"
8940 [(set (match_operand:DI 0 "nonimmediate_operand"
8949 (match_operand:DI 1 "input_operand"
8954 Oj, wM, OjwM, Oj, wM,
8959 && (gpc_reg_operand (operands[0], DImode)
8960 || gpc_reg_operand (operands[1], DImode))"
8992 fpstore, fpload, fpsimple,
8993 fpstore, fpstore, fpload, fpload, veclogical,
8994 vecsimple, vecsimple, vecsimple, veclogical, veclogical,
8995 vecsimple, vecsimple,
8998 (set_attr "size" "64")
9012 p9v, p7v, p9v, p7v, *,
9013 p9v, p9v, p7v, *, *,
9018 ; Some DImode loads are best done as a load of -1 followed by a mask
9021 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9022 (match_operand:DI 1 "const_int_operand"))]
9024 && num_insns_constant (operands[1], DImode) > 1
9025 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
9026 && rs6000_is_valid_and_mask (operands[1], DImode)"
9030 (and:DI (match_dup 0)
9034 ;; Split a load of a large constant into the appropriate five-instruction
9035 ;; sequence. Handle anything in a constant number of insns.
9036 ;; When non-easy constants can go in the TOC, this should use
9037 ;; easy_fp_constant predicate.
9039 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9040 (match_operand:DI 1 "const_int_operand"))]
9041 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9042 [(set (match_dup 0) (match_dup 2))
9043 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
9045 if (rs6000_emit_set_const (operands[0], operands[1]))
9052 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
9053 (match_operand:DI 1 "const_scalar_int_operand"))]
9054 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
9055 [(set (match_dup 0) (match_dup 2))
9056 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
9058 if (rs6000_emit_set_const (operands[0], operands[1]))
9065 [(set (match_operand:DI 0 "altivec_register_operand")
9066 (match_operand:DI 1 "s5bit_cint_operand"))]
9067 "TARGET_VSX && reload_completed"
9070 rtx op0 = operands[0];
9071 rtx op1 = operands[1];
9072 int r = REGNO (op0);
9073 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
9075 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
9076 if (op1 != const0_rtx && op1 != constm1_rtx)
9078 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
9079 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
9084 ;; Split integer constants that can be loaded with XXSPLTIB and a
9085 ;; sign extend operation.
9087 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
9088 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
9089 "TARGET_P9_VECTOR && reload_completed"
9092 rtx op0 = operands[0];
9093 rtx op1 = operands[1];
9094 int r = REGNO (op0);
9095 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
9097 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
9098 if (<MODE>mode == DImode)
9099 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
9100 else if (<MODE>mode == SImode)
9101 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
9102 else if (<MODE>mode == HImode)
9104 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
9105 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
9111 ;; TImode/PTImode is similar, except that we usually want to compute the
9112 ;; address into a register and use lsi/stsi (the exception is during reload).
9114 (define_insn "*mov<mode>_string"
9115 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
9116 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
9118 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
9119 && (gpc_reg_operand (operands[0], <MODE>mode)
9120 || gpc_reg_operand (operands[1], <MODE>mode))"
9122 [(set_attr "type" "store,store,load,load,*,*")
9123 (set_attr "update" "yes")
9124 (set_attr "indexed" "yes")
9125 (set_attr "cell_micro" "conditional")])
9127 (define_insn "*mov<mode>_ppc64"
9128 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
9129 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
9130 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
9131 && (gpc_reg_operand (operands[0], <MODE>mode)
9132 || gpc_reg_operand (operands[1], <MODE>mode)))"
9134 return rs6000_output_move_128bit (operands);
9136 [(set_attr "type" "store,store,load,load,*,*")
9137 (set_attr "length" "8")
9138 (set_attr "max_prefixed_insns" "2")])
9141 [(set (match_operand:TI2 0 "int_reg_operand")
9142 (match_operand:TI2 1 "const_scalar_int_operand"))]
9144 && (VECTOR_MEM_NONE_P (<MODE>mode)
9145 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
9146 [(set (match_dup 2) (match_dup 4))
9147 (set (match_dup 3) (match_dup 5))]
9149 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
9151 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
9153 if (CONST_WIDE_INT_P (operands[1]))
9155 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
9156 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
9158 else if (CONST_INT_P (operands[1]))
9160 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
9161 operands[5] = operands[1];
9168 [(set (match_operand:TI2 0 "nonimmediate_operand")
9169 (match_operand:TI2 1 "input_operand"))]
9171 && gpr_or_gpr_p (operands[0], operands[1])
9172 && !direct_move_p (operands[0], operands[1])
9173 && !quad_load_store_p (operands[0], operands[1])"
9176 rs6000_split_multireg_move (operands[0], operands[1]);
9180 (define_expand "setmemsi"
9181 [(parallel [(set (match_operand:BLK 0 "")
9182 (match_operand 2 "const_int_operand"))
9183 (use (match_operand:SI 1 ""))
9184 (use (match_operand:SI 3 ""))])]
9187 /* If value to set is not zero, use the library routine. */
9188 if (operands[2] != const0_rtx)
9191 if (expand_block_clear (operands))
9197 ;; String compare N insn.
9198 ;; Argument 0 is the target (result)
9199 ;; Argument 1 is the destination
9200 ;; Argument 2 is the source
9201 ;; Argument 3 is the length
9202 ;; Argument 4 is the alignment
9204 (define_expand "cmpstrnsi"
9205 [(parallel [(set (match_operand:SI 0)
9206 (compare:SI (match_operand:BLK 1)
9207 (match_operand:BLK 2)))
9208 (use (match_operand:SI 3))
9209 (use (match_operand:SI 4))])]
9210 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9212 if (optimize_insn_for_size_p ())
9215 if (expand_strn_compare (operands, 0))
9221 ;; String compare insn.
9222 ;; Argument 0 is the target (result)
9223 ;; Argument 1 is the destination
9224 ;; Argument 2 is the source
9225 ;; Argument 3 is the alignment
9227 (define_expand "cmpstrsi"
9228 [(parallel [(set (match_operand:SI 0)
9229 (compare:SI (match_operand:BLK 1)
9230 (match_operand:BLK 2)))
9231 (use (match_operand:SI 3))])]
9232 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9234 if (optimize_insn_for_size_p ())
9237 if (expand_strn_compare (operands, 1))
9243 ;; Block compare insn.
9244 ;; Argument 0 is the target (result)
9245 ;; Argument 1 is the destination
9246 ;; Argument 2 is the source
9247 ;; Argument 3 is the length
9248 ;; Argument 4 is the alignment
9250 (define_expand "cmpmemsi"
9251 [(parallel [(set (match_operand:SI 0)
9252 (compare:SI (match_operand:BLK 1)
9253 (match_operand:BLK 2)))
9254 (use (match_operand:SI 3))
9255 (use (match_operand:SI 4))])]
9258 if (expand_block_compare (operands))
9264 ;; String/block copy insn (source and destination must not overlap).
9265 ;; Argument 0 is the destination
9266 ;; Argument 1 is the source
9267 ;; Argument 2 is the length
9268 ;; Argument 3 is the alignment
9270 (define_expand "cpymemsi"
9271 [(parallel [(set (match_operand:BLK 0 "")
9272 (match_operand:BLK 1 ""))
9273 (use (match_operand:SI 2 ""))
9274 (use (match_operand:SI 3 ""))])]
9277 if (expand_block_move (operands, false))
9283 ;; String/block move insn (source and destination may overlap).
9284 ;; Argument 0 is the destination
9285 ;; Argument 1 is the source
9286 ;; Argument 2 is the length
9287 ;; Argument 3 is the alignment
9289 (define_expand "movmemsi"
9290 [(parallel [(set (match_operand:BLK 0 "")
9291 (match_operand:BLK 1 ""))
9292 (use (match_operand:SI 2 ""))
9293 (use (match_operand:SI 3 ""))])]
9296 if (expand_block_move (operands, true))
9303 ;; Define insns that do load or store with update. Some of these we can
9304 ;; get by using pre-decrement or pre-increment, but the hardware can also
9305 ;; do cases where the increment is not the size of the object.
9307 ;; In all these cases, we use operands 0 and 1 for the register being
9308 ;; incremented because those are the operands that local-alloc will
9309 ;; tie and these are the pair most likely to be tieable (and the ones
9310 ;; that will benefit the most).
9312 (define_insn "*movdi_update1"
9313 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9314 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9315 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9316 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9317 (plus:P (match_dup 1) (match_dup 2)))]
9318 "TARGET_POWERPC64 && TARGET_UPDATE
9319 && (!avoiding_indexed_address_p (DImode)
9320 || !gpc_reg_operand (operands[2], Pmode))"
9324 [(set_attr "type" "load")
9325 (set_attr "update" "yes")
9326 (set_attr "indexed" "yes,no")])
9328 (define_insn "movdi_<mode>_update"
9329 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9330 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9331 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9332 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9333 (plus:P (match_dup 1) (match_dup 2)))]
9334 "TARGET_POWERPC64 && TARGET_UPDATE
9335 && (!avoiding_indexed_address_p (DImode)
9336 || !gpc_reg_operand (operands[2], Pmode)
9337 || (REG_P (operands[0])
9338 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9342 [(set_attr "type" "store")
9343 (set_attr "update" "yes")
9344 (set_attr "indexed" "yes,no")])
9346 ;; This pattern is only conditional on TARGET_64BIT, as it is
9347 ;; needed for stack allocation, even if the user passes -mno-update.
9348 (define_insn "movdi_update_stack"
9349 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9350 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9351 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9352 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9353 (plus:DI (match_dup 1) (match_dup 2)))]
9358 [(set_attr "type" "store")
9359 (set_attr "update" "yes")
9360 (set_attr "indexed" "yes,no")])
9362 (define_insn "*movsi_update1"
9363 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9364 (mem:SI (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)))]
9369 && (!avoiding_indexed_address_p (SImode)
9370 || !gpc_reg_operand (operands[2], Pmode))"
9374 [(set_attr "type" "load")
9375 (set_attr "update" "yes")
9376 (set_attr "indexed" "yes,no")])
9378 (define_insn "*movsi_update2"
9379 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9381 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9382 (match_operand:P 2 "gpc_reg_operand" "r")))))
9383 (set (match_operand:P 0 "gpc_reg_operand" "=b")
9384 (plus:P (match_dup 1) (match_dup 2)))]
9385 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9387 [(set_attr "type" "load")
9388 (set_attr "sign_extend" "yes")
9389 (set_attr "update" "yes")
9390 (set_attr "indexed" "yes")])
9392 (define_insn "movsi_<mode>_update"
9393 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9394 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9395 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9396 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9397 (plus:P (match_dup 1) (match_dup 2)))]
9399 && (!avoiding_indexed_address_p (SImode)
9400 || !gpc_reg_operand (operands[2], Pmode)
9401 || (REG_P (operands[0])
9402 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9406 [(set_attr "type" "store")
9407 (set_attr "update" "yes")
9408 (set_attr "indexed" "yes,no")])
9410 ;; This is an unconditional pattern; needed for stack allocation, even
9411 ;; if the user passes -mno-update.
9412 (define_insn "movsi_update_stack"
9413 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9414 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9415 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9416 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9417 (plus:SI (match_dup 1) (match_dup 2)))]
9422 [(set_attr "type" "store")
9423 (set_attr "update" "yes")
9424 (set_attr "indexed" "yes,no")])
9426 (define_insn "*movhi_update1"
9427 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9428 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9429 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9430 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9431 (plus:P (match_dup 1) (match_dup 2)))]
9433 && (!avoiding_indexed_address_p (HImode)
9434 || !gpc_reg_operand (operands[2], SImode))"
9438 [(set_attr "type" "load")
9439 (set_attr "update" "yes")
9440 (set_attr "indexed" "yes,no")])
9442 (define_insn "*movhi_update2"
9443 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9445 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9446 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9447 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9448 (plus:P (match_dup 1) (match_dup 2)))]
9450 && (!avoiding_indexed_address_p (HImode)
9451 || !gpc_reg_operand (operands[2], Pmode))"
9455 [(set_attr "type" "load")
9456 (set_attr "update" "yes")
9457 (set_attr "indexed" "yes,no")])
9459 (define_insn "*movhi_update3"
9460 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9462 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9463 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9464 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9465 (plus:P (match_dup 1) (match_dup 2)))]
9467 && !(avoiding_indexed_address_p (HImode)
9468 && gpc_reg_operand (operands[2], Pmode))"
9472 [(set_attr "type" "load")
9473 (set_attr "sign_extend" "yes")
9474 (set_attr "update" "yes")
9475 (set_attr "indexed" "yes,no")])
9477 (define_insn "*movhi_update4"
9478 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9479 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9480 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9481 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9482 (plus:P (match_dup 1) (match_dup 2)))]
9484 && (!avoiding_indexed_address_p (HImode)
9485 || !gpc_reg_operand (operands[2], Pmode))"
9489 [(set_attr "type" "store")
9490 (set_attr "update" "yes")
9491 (set_attr "indexed" "yes,no")])
9493 (define_insn "*movqi_update1"
9494 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9495 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9496 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9497 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9498 (plus:P (match_dup 1) (match_dup 2)))]
9500 && (!avoiding_indexed_address_p (QImode)
9501 || !gpc_reg_operand (operands[2], Pmode))"
9505 [(set_attr "type" "load")
9506 (set_attr "update" "yes")
9507 (set_attr "indexed" "yes,no")])
9509 (define_insn "*movqi_update2"
9510 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9512 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9513 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9514 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9515 (plus:P (match_dup 1) (match_dup 2)))]
9517 && (!avoiding_indexed_address_p (QImode)
9518 || !gpc_reg_operand (operands[2], Pmode))"
9522 [(set_attr "type" "load")
9523 (set_attr "update" "yes")
9524 (set_attr "indexed" "yes,no")])
9526 (define_insn "*movqi_update3"
9527 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9528 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9529 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9530 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9531 (plus:P (match_dup 1) (match_dup 2)))]
9533 && (!avoiding_indexed_address_p (QImode)
9534 || !gpc_reg_operand (operands[2], Pmode))"
9538 [(set_attr "type" "store")
9539 (set_attr "update" "yes")
9540 (set_attr "indexed" "yes,no")])
9542 (define_insn "*mov<SFDF:mode>_update1"
9543 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<SFDF:Ff>,<SFDF:Ff>")
9544 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9545 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9546 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9547 (plus:P (match_dup 1) (match_dup 2)))]
9548 "TARGET_HARD_FLOAT && TARGET_UPDATE
9549 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9550 || !gpc_reg_operand (operands[2], Pmode))"
9554 [(set_attr "type" "fpload")
9555 (set_attr "update" "yes")
9556 (set_attr "indexed" "yes,no")
9557 (set_attr "size" "<SFDF:bits>")])
9559 (define_insn "*mov<SFDF:mode>_update2"
9560 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9561 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9562 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:Ff>,<SFDF:Ff>"))
9563 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9564 (plus:P (match_dup 1) (match_dup 2)))]
9565 "TARGET_HARD_FLOAT && TARGET_UPDATE
9566 && (!avoiding_indexed_address_p (<SFDF:MODE>mode)
9567 || !gpc_reg_operand (operands[2], Pmode))"
9571 [(set_attr "type" "fpstore")
9572 (set_attr "update" "yes")
9573 (set_attr "indexed" "yes,no")
9574 (set_attr "size" "<SFDF:bits>")])
9576 (define_insn "*movsf_update3"
9577 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9578 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9579 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9580 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9581 (plus:P (match_dup 1) (match_dup 2)))]
9582 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9583 && (!avoiding_indexed_address_p (SFmode)
9584 || !gpc_reg_operand (operands[2], Pmode))"
9588 [(set_attr "type" "load")
9589 (set_attr "update" "yes")
9590 (set_attr "indexed" "yes,no")])
9592 (define_insn "*movsf_update4"
9593 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9594 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9595 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9596 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9597 (plus:P (match_dup 1) (match_dup 2)))]
9598 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9599 && (!avoiding_indexed_address_p (SFmode)
9600 || !gpc_reg_operand (operands[2], Pmode))"
9604 [(set_attr "type" "store")
9605 (set_attr "update" "yes")
9606 (set_attr "indexed" "yes,no")])
9609 ;; After inserting conditional returns we can sometimes have
9610 ;; unnecessary register moves. Unfortunately we cannot have a
9611 ;; modeless peephole here, because some single SImode sets have early
9612 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9613 ;; sequences, using get_attr_length here will smash the operands
9614 ;; array. Neither is there an early_cobbler_p predicate.
9615 ;; Also this optimization interferes with scalars going into
9616 ;; altivec registers (the code does reloading through the FPRs).
9618 [(set (match_operand:DF 0 "gpc_reg_operand")
9619 (match_operand:DF 1 "any_operand"))
9620 (set (match_operand:DF 2 "gpc_reg_operand")
9623 && peep2_reg_dead_p (2, operands[0])"
9624 [(set (match_dup 2) (match_dup 1))])
9627 [(set (match_operand:SF 0 "gpc_reg_operand")
9628 (match_operand:SF 1 "any_operand"))
9629 (set (match_operand:SF 2 "gpc_reg_operand")
9632 && peep2_reg_dead_p (2, operands[0])"
9633 [(set (match_dup 2) (match_dup 1))])
9638 (define_insn "*tls_gd_pcrel<bits>"
9639 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9640 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9643 "HAVE_AS_TLS && TARGET_ELF"
9644 "la %0,%1@got@tlsgd@pcrel"
9645 [(set_attr "prefixed" "yes")])
9647 (define_insn_and_split "*tls_gd<bits>"
9648 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9649 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9650 (match_operand:P 2 "gpc_reg_operand" "b")]
9652 "HAVE_AS_TLS && TARGET_ELF"
9653 "addi %0,%2,%1@got@tlsgd"
9654 "&& TARGET_CMODEL != CMODEL_SMALL"
9657 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9659 (lo_sum:P (match_dup 3)
9660 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9662 operands[3] = gen_reg_rtx (<MODE>mode);
9664 [(set (attr "length")
9665 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9669 (define_insn "*tls_gd_high<bits>"
9670 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9672 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9673 (match_operand:P 2 "gpc_reg_operand" "b")]
9675 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9676 "addis %0,%2,%1@got@tlsgd@ha")
9678 (define_insn "*tls_gd_low<bits>"
9679 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9680 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9681 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9682 (match_operand:P 3 "gpc_reg_operand" "b")]
9684 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9685 "addi %0,%1,%2@got@tlsgd@l")
9687 (define_insn "*tls_ld_pcrel<bits>"
9688 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9689 (unspec:P [(const_int 0)]
9691 "HAVE_AS_TLS && TARGET_ELF"
9692 "la %0,%&@got@tlsld@pcrel"
9693 [(set_attr "prefixed" "yes")])
9695 (define_insn_and_split "*tls_ld<bits>"
9696 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9697 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9699 "HAVE_AS_TLS && TARGET_ELF"
9700 "addi %0,%1,%&@got@tlsld"
9701 "&& TARGET_CMODEL != CMODEL_SMALL"
9704 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9706 (lo_sum:P (match_dup 2)
9707 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9709 operands[2] = gen_reg_rtx (<MODE>mode);
9711 [(set (attr "length")
9712 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9716 (define_insn "*tls_ld_high<bits>"
9717 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9719 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9721 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9722 "addis %0,%1,%&@got@tlsld@ha")
9724 (define_insn "*tls_ld_low<bits>"
9725 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9726 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9727 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9729 "HAVE_AS_TLS && TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
9730 "addi %0,%1,%&@got@tlsld@l")
9732 (define_insn "tls_dtprel_<bits>"
9733 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9734 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9735 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9738 "addi %0,%1,%2@dtprel"
9739 [(set (attr "prefixed")
9740 (if_then_else (match_test "rs6000_tls_size == 16")
9742 (const_string "yes")))])
9744 (define_insn "tls_dtprel_ha_<bits>"
9745 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9746 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9747 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9748 UNSPEC_TLSDTPRELHA))]
9750 "addis %0,%1,%2@dtprel@ha")
9752 (define_insn "tls_dtprel_lo_<bits>"
9753 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9754 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9755 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9756 UNSPEC_TLSDTPRELLO))]
9758 "addi %0,%1,%2@dtprel@l")
9760 (define_insn_and_split "tls_got_dtprel_<bits>"
9761 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9762 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9763 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9764 UNSPEC_TLSGOTDTPREL))]
9766 "<ptrload> %0,%2@got@dtprel(%1)"
9767 "&& TARGET_CMODEL != CMODEL_SMALL"
9770 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9772 (lo_sum:P (match_dup 3)
9773 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9775 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9777 [(set (attr "length")
9778 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9782 (define_insn "*tls_got_dtprel_high<bits>"
9783 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9785 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9786 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9787 UNSPEC_TLSGOTDTPREL)))]
9788 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9789 "addis %0,%1,%2@got@dtprel@ha")
9791 (define_insn "*tls_got_dtprel_low<bits>"
9792 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9793 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9794 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9795 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9796 UNSPEC_TLSGOTDTPREL)))]
9797 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9798 "<ptrload> %0,%2@got@dtprel@l(%1)")
9800 (define_insn "tls_tprel_<bits>"
9801 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9802 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9803 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9806 "addi %0,%1,%2@tprel"
9807 [(set (attr "prefixed")
9808 (if_then_else (match_test "rs6000_tls_size == 16")
9810 (const_string "yes")))])
9812 (define_insn "tls_tprel_ha_<bits>"
9813 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9814 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9815 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9816 UNSPEC_TLSTPRELHA))]
9818 "addis %0,%1,%2@tprel@ha")
9820 (define_insn "tls_tprel_lo_<bits>"
9821 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9822 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9823 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9824 UNSPEC_TLSTPRELLO))]
9826 "addi %0,%1,%2@tprel@l")
9828 (define_insn "*tls_got_tprel_pcrel_<bits>"
9829 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9830 (unspec:P [(const_int 0)
9831 (match_operand:P 1 "rs6000_tls_symbol_ref" "")]
9832 UNSPEC_TLSGOTTPREL))]
9834 "<ptrload> %0,%1@got@tprel@pcrel"
9835 [(set_attr "prefixed" "yes")])
9837 ;; "b" output constraint here and on tls_tls input to support linker tls
9838 ;; optimization. The linker may edit the instructions emitted by a
9839 ;; tls_got_tprel/tls_tls pair to addis,addi.
9840 (define_insn_and_split "tls_got_tprel_<bits>"
9841 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9842 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9843 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9844 UNSPEC_TLSGOTTPREL))]
9846 "<ptrload> %0,%2@got@tprel(%1)"
9847 "&& TARGET_CMODEL != CMODEL_SMALL"
9850 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9852 (lo_sum:P (match_dup 3)
9853 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9855 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9857 [(set (attr "length")
9858 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9862 (define_insn "*tls_got_tprel_high<bits>"
9863 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9865 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9866 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9867 UNSPEC_TLSGOTTPREL)))]
9868 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9869 "addis %0,%1,%2@got@tprel@ha")
9871 (define_insn "*tls_got_tprel_low<bits>"
9872 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9873 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9874 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9875 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9876 UNSPEC_TLSGOTTPREL)))]
9877 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9878 "<ptrload> %0,%2@got@tprel@l(%1)")
9880 (define_insn "tls_tls_pcrel_<bits>"
9881 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9882 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9883 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9884 UNSPEC_TLSTLS_PCREL))]
9885 "TARGET_ELF && HAVE_AS_TLS"
9886 "add %0,%1,%2@tls@pcrel")
9888 (define_insn "tls_tls_<bits>"
9889 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9890 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9891 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9893 "TARGET_ELF && HAVE_AS_TLS"
9896 (define_expand "tls_get_tpointer"
9897 [(set (match_operand:SI 0 "gpc_reg_operand")
9898 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9899 "TARGET_XCOFF && HAVE_AS_TLS"
9901 emit_insn (gen_tls_get_tpointer_internal ());
9902 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9906 (define_insn "tls_get_tpointer_internal"
9908 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9909 (clobber (reg:SI LR_REGNO))]
9910 "TARGET_XCOFF && HAVE_AS_TLS"
9911 "bla __get_tpointer")
9913 (define_expand "tls_get_addr<mode>"
9914 [(set (match_operand:P 0 "gpc_reg_operand")
9915 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9916 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9917 "TARGET_XCOFF && HAVE_AS_TLS"
9919 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9920 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9921 emit_insn (gen_tls_get_addr_internal<mode> ());
9922 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9926 (define_insn "tls_get_addr_internal<mode>"
9928 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9932 (clobber (reg:P 11))
9933 (clobber (reg:CC CR0_REGNO))
9934 (clobber (reg:P LR_REGNO))]
9935 "TARGET_XCOFF && HAVE_AS_TLS"
9936 "bla __tls_get_addr")
9938 ;; Next come insns related to the calling sequence.
9940 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9941 ;; We move the back-chain and decrement the stack pointer.
9943 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9944 ;; constant alloca, using that predicate will force the generic code to put
9945 ;; the constant size into a register before calling the expander.
9947 ;; As a result the expander would not have the constant size information
9948 ;; in those cases and would have to generate less efficient code.
9950 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9951 ;; the constant size. The value is forced into a register if necessary.
9953 (define_expand "allocate_stack"
9954 [(set (match_operand 0 "gpc_reg_operand")
9955 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9957 (minus (reg 1) (match_dup 1)))]
9960 rtx chain = gen_reg_rtx (Pmode);
9961 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9963 rtx insn, par, set, mem;
9965 /* By allowing reg_or_cint_operand as the predicate we can get
9966 better code for stack-clash-protection because we do not lose
9967 size information. But the rest of the code expects the operand
9968 to be reg_or_short_operand. If it isn't, then force it into
9970 rtx orig_op1 = operands[1];
9971 if (!reg_or_short_operand (operands[1], Pmode))
9972 operands[1] = force_reg (Pmode, operands[1]);
9974 emit_move_insn (chain, stack_bot);
9976 /* Check stack bounds if necessary. */
9977 if (crtl->limit_stack)
9980 available = expand_binop (Pmode, sub_optab,
9981 stack_pointer_rtx, stack_limit_rtx,
9982 NULL_RTX, 1, OPTAB_WIDEN);
9983 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9986 /* Allocate and probe if requested.
9987 This may look similar to the loop we use for prologue allocations,
9988 but it is critically different. For the former we know the loop
9989 will iterate, but do not know that generally here. The former
9990 uses that knowledge to rotate the loop. Combining them would be
9991 possible with some performance cost. */
9992 if (flag_stack_clash_protection)
9994 rtx rounded_size, last_addr, residual;
9995 HOST_WIDE_INT probe_interval;
9996 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9997 &residual, &probe_interval,
10000 /* We do occasionally get in here with constant sizes, we might
10001 as well do a reasonable job when we obviously can. */
10002 if (rounded_size != const0_rtx)
10004 rtx loop_lab, end_loop;
10005 bool rotated = CONST_INT_P (rounded_size);
10006 rtx update = GEN_INT (-probe_interval);
10007 if (probe_interval > 32768)
10008 update = force_reg (Pmode, update);
10010 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10011 last_addr, rotated);
10014 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10018 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
10021 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10022 last_addr, rotated);
10025 /* Now handle residuals. We just have to set operands[1] correctly
10026 and let the rest of the expander run. */
10027 operands[1] = residual;
10030 if (!(CONST_INT_P (operands[1])
10031 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
10033 operands[1] = force_reg (Pmode, operands[1]);
10034 neg_op0 = gen_reg_rtx (Pmode);
10035 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
10038 neg_op0 = GEN_INT (-INTVAL (operands[1]));
10040 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10041 : gen_movdi_update_stack))
10042 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10044 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10045 it now and set the alias set/attributes. The above gen_*_update
10046 calls will generate a PARALLEL with the MEM set being the first
10048 par = PATTERN (insn);
10049 gcc_assert (GET_CODE (par) == PARALLEL);
10050 set = XVECEXP (par, 0, 0);
10051 gcc_assert (GET_CODE (set) == SET);
10052 mem = SET_DEST (set);
10053 gcc_assert (MEM_P (mem));
10054 MEM_NOTRAP_P (mem) = 1;
10055 set_mem_alias_set (mem, get_frame_alias_set ());
10057 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10061 ;; These patterns say how to save and restore the stack pointer. We need not
10062 ;; save the stack pointer at function level since we are careful to
10063 ;; preserve the backchain. At block level, we have to restore the backchain
10064 ;; when we restore the stack pointer.
10066 ;; For nonlocal gotos, we must save both the stack pointer and its
10067 ;; backchain and restore both. Note that in the nonlocal case, the
10068 ;; save area is a memory location.
10070 (define_expand "save_stack_function"
10071 [(match_operand 0 "any_operand")
10072 (match_operand 1 "any_operand")]
10076 (define_expand "restore_stack_function"
10077 [(match_operand 0 "any_operand")
10078 (match_operand 1 "any_operand")]
10082 ;; Adjust stack pointer (op0) to a new value (op1).
10083 ;; First copy old stack backchain to new location, and ensure that the
10084 ;; scheduler won't reorder the sp assignment before the backchain write.
10085 (define_expand "restore_stack_block"
10086 [(set (match_dup 2) (match_dup 3))
10087 (set (match_dup 4) (match_dup 2))
10089 (set (match_operand 0 "register_operand")
10090 (match_operand 1 "register_operand"))]
10095 operands[1] = force_reg (Pmode, operands[1]);
10096 operands[2] = gen_reg_rtx (Pmode);
10097 operands[3] = gen_frame_mem (Pmode, operands[0]);
10098 operands[4] = gen_frame_mem (Pmode, operands[1]);
10099 p = rtvec_alloc (1);
10100 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10102 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10105 (define_expand "save_stack_nonlocal"
10106 [(set (match_dup 3) (match_dup 4))
10107 (set (match_operand 0 "memory_operand") (match_dup 3))
10108 (set (match_dup 2) (match_operand 1 "register_operand"))]
10111 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10113 /* Copy the backchain to the first word, sp to the second. */
10114 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10115 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10116 operands[3] = gen_reg_rtx (Pmode);
10117 operands[4] = gen_frame_mem (Pmode, operands[1]);
10120 (define_expand "restore_stack_nonlocal"
10121 [(set (match_dup 2) (match_operand 1 "memory_operand"))
10122 (set (match_dup 3) (match_dup 4))
10123 (set (match_dup 5) (match_dup 2))
10125 (set (match_operand 0 "register_operand") (match_dup 3))]
10128 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10131 /* Restore the backchain from the first word, sp from the second. */
10132 operands[2] = gen_reg_rtx (Pmode);
10133 operands[3] = gen_reg_rtx (Pmode);
10134 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10135 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10136 operands[5] = gen_frame_mem (Pmode, operands[3]);
10137 p = rtvec_alloc (1);
10138 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10140 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10143 ;; Load up a PC-relative address. Print_operand_address will append a @pcrel
10144 ;; to the symbol or label.
10145 (define_insn "*pcrel_local_addr"
10146 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10147 (match_operand:DI 1 "pcrel_local_address"))]
10150 [(set_attr "prefixed" "yes")])
10152 ;; Load up a PC-relative address to an external symbol. If the symbol and the
10153 ;; program are both defined in the main program, the linker will optimize this
10154 ;; to a PADDI. Otherwise, it will create a GOT address that is relocated by
10155 ;; the dynamic linker and loaded up. Print_operand_address will append a
10156 ;; @got@pcrel to the symbol.
10157 (define_insn "*pcrel_extern_addr"
10158 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10159 (match_operand:DI 1 "pcrel_external_address"))]
10162 [(set_attr "prefixed" "yes")
10163 (set_attr "type" "load")])
10165 ;; TOC register handling.
10167 ;; Code to initialize the TOC register...
10169 (define_insn "load_toc_aix_si"
10170 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10171 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10172 (use (reg:SI 2))])]
10173 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10176 extern int need_toc_init;
10178 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
10179 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10180 operands[2] = gen_rtx_REG (Pmode, 2);
10181 return "lwz %0,%1(%2)";
10183 [(set_attr "type" "load")
10184 (set_attr "update" "no")
10185 (set_attr "indexed" "no")])
10187 (define_insn "load_toc_aix_di"
10188 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10189 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10190 (use (reg:DI 2))])]
10191 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10194 extern int need_toc_init;
10196 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
10197 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10199 strcat (buf, "@toc");
10200 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10201 operands[2] = gen_rtx_REG (Pmode, 2);
10202 return "ld %0,%1(%2)";
10204 [(set_attr "type" "load")
10205 (set_attr "update" "no")
10206 (set_attr "indexed" "no")])
10208 (define_insn "load_toc_v4_pic_si"
10209 [(set (reg:SI LR_REGNO)
10210 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10211 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10212 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10213 [(set_attr "type" "branch")])
10215 (define_expand "load_toc_v4_PIC_1"
10216 [(parallel [(set (reg:SI LR_REGNO)
10217 (match_operand:SI 0 "immediate_operand" "s"))
10218 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10219 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10220 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10223 (define_insn "load_toc_v4_PIC_1_normal"
10224 [(set (reg:SI LR_REGNO)
10225 (match_operand:SI 0 "immediate_operand" "s"))
10226 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10227 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10228 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10229 "bcl 20,31,%0\n%0:"
10230 [(set_attr "type" "branch")
10231 (set_attr "cannot_copy" "yes")])
10233 (define_insn "load_toc_v4_PIC_1_476"
10234 [(set (reg:SI LR_REGNO)
10235 (match_operand:SI 0 "immediate_operand" "s"))
10236 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10237 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10238 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10241 static char templ[32];
10243 get_ppc476_thunk_name (name);
10244 sprintf (templ, "bl %s\n%%0:", name);
10247 [(set_attr "type" "branch")
10248 (set_attr "cannot_copy" "yes")])
10250 (define_expand "load_toc_v4_PIC_1b"
10251 [(parallel [(set (reg:SI LR_REGNO)
10252 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10253 (label_ref (match_operand 1 ""))]
10256 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10259 (define_insn "load_toc_v4_PIC_1b_normal"
10260 [(set (reg:SI LR_REGNO)
10261 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10262 (label_ref (match_operand 1 "" ""))]
10265 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10266 "bcl 20,31,$+8\;.long %0-$"
10267 [(set_attr "type" "branch")
10268 (set_attr "length" "8")])
10270 (define_insn "load_toc_v4_PIC_1b_476"
10271 [(set (reg:SI LR_REGNO)
10272 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10273 (label_ref (match_operand 1 "" ""))]
10276 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10279 static char templ[32];
10281 get_ppc476_thunk_name (name);
10282 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10285 [(set_attr "type" "branch")
10286 (set_attr "length" "16")])
10288 (define_insn "load_toc_v4_PIC_2"
10289 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10291 (match_operand:SI 1 "gpc_reg_operand" "b")
10293 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10294 (match_operand:SI 3 "immediate_operand" "s"))))))]
10295 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10297 [(set_attr "type" "load")])
10299 (define_insn "load_toc_v4_PIC_3b"
10300 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10302 (match_operand:SI 1 "gpc_reg_operand" "b")
10305 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10306 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10307 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10308 "addis %0,%1,%2-%3@ha")
10310 (define_insn "load_toc_v4_PIC_3c"
10311 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10313 (match_operand:SI 1 "gpc_reg_operand" "b")
10315 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10316 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10317 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10318 "addi %0,%1,%2-%3@l")
10320 ;; If the TOC is shared over a translation unit, as happens with all
10321 ;; the kinds of PIC that we support, we need to restore the TOC
10322 ;; pointer only when jumping over units of translation.
10323 ;; On Darwin, we need to reload the picbase.
10325 (define_expand "builtin_setjmp_receiver"
10326 [(use (label_ref (match_operand 0 "")))]
10327 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10328 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10329 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10332 if (DEFAULT_ABI == ABI_DARWIN)
10334 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10335 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10339 crtl->uses_pic_offset_table = 1;
10340 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10341 CODE_LABEL_NUMBER (operands[0]));
10342 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10344 emit_insn (gen_load_macho_picbase (Pmode, tmplabrtx));
10345 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10346 emit_insn (gen_macho_correct_pic (Pmode, picreg, picreg,
10347 picrtx, tmplabrtx));
10351 rs6000_emit_load_toc_table (FALSE);
10355 ;; Largetoc support
10356 (define_insn "*largetoc_high"
10357 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10359 (unspec [(match_operand:DI 1 "" "")
10360 (match_operand:DI 2 "gpc_reg_operand" "b")]
10362 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10363 "addis %0,%2,%1@toc@ha")
10365 (define_insn "*largetoc_high_aix<mode>"
10366 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10368 (unspec [(match_operand:P 1 "" "")
10369 (match_operand:P 2 "gpc_reg_operand" "b")]
10371 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10372 "addis %0,%1@u(%2)")
10374 (define_insn "*largetoc_high_plus"
10375 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10378 (unspec [(match_operand:DI 1 "" "")
10379 (match_operand:DI 2 "gpc_reg_operand" "b")]
10381 (match_operand:DI 3 "add_cint_operand" "n"))))]
10382 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10383 "addis %0,%2,%1+%3@toc@ha")
10385 (define_insn "*largetoc_high_plus_aix<mode>"
10386 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10389 (unspec [(match_operand:P 1 "" "")
10390 (match_operand:P 2 "gpc_reg_operand" "b")]
10392 (match_operand:P 3 "add_cint_operand" "n"))))]
10393 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10394 "addis %0,%1+%3@u(%2)")
10396 (define_insn "*largetoc_low"
10397 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10398 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10399 (match_operand:DI 2 "" "")))]
10400 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10403 (define_insn "*largetoc_low_aix<mode>"
10404 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10405 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10406 (match_operand:P 2 "" "")))]
10407 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10410 (define_insn_and_split "*tocref<mode>"
10411 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10412 (match_operand:P 1 "small_toc_ref" "R"))]
10414 && legitimate_constant_pool_address_p (operands[1], QImode, false)"
10416 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10417 [(set (match_dup 0) (high:P (match_dup 1)))
10418 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10420 ;; Elf specific ways of loading addresses for non-PIC code.
10421 ;; The output of this could be r0, but we make a very strong
10422 ;; preference for a base register because it will usually
10423 ;; be needed there.
10424 (define_insn "elf_high"
10425 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10426 (high:SI (match_operand 1 "" "")))]
10427 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10430 (define_insn "elf_low"
10431 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10432 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10433 (match_operand 2 "" "")))]
10434 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10437 (define_insn "*pltseq_tocsave_<mode>"
10438 [(set (match_operand:P 0 "memory_operand" "=m")
10439 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10440 (match_operand:P 2 "symbol_ref_operand" "s")
10441 (match_operand:P 3 "" "")]
10444 && DEFAULT_ABI == ABI_ELFv2"
10446 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10449 (define_insn "*pltseq_plt16_ha_<mode>"
10450 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10451 (unspec:P [(match_operand:P 1 "" "")
10452 (match_operand:P 2 "symbol_ref_operand" "s")
10453 (match_operand:P 3 "" "")]
10457 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10460 (define_insn "*pltseq_plt16_lo_<mode>"
10461 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10462 (unspec_volatile:P [(match_operand:P 1 "gpc_reg_operand" "b")
10463 (match_operand:P 2 "symbol_ref_operand" "s")
10464 (match_operand:P 3 "" "")]
10465 UNSPECV_PLT16_LO))]
10468 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10470 [(set_attr "type" "load")])
10472 (define_insn "*pltseq_mtctr_<mode>"
10473 [(set (match_operand:P 0 "register_operand" "=c")
10474 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10475 (match_operand:P 2 "symbol_ref_operand" "s")
10476 (match_operand:P 3 "" "")]
10480 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10483 (define_insn "*pltseq_plt_pcrel<mode>"
10484 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10485 (unspec_volatile:P [(match_operand:P 1 "" "")
10486 (match_operand:P 2 "symbol_ref_operand" "s")
10487 (match_operand:P 3 "" "")]
10488 UNSPECV_PLT_PCREL))]
10489 "HAVE_AS_PLTSEQ && TARGET_ELF
10490 && rs6000_pcrel_p (cfun)"
10492 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10494 [(set_attr "type" "load")
10495 (set_attr "length" "12")])
10497 ;; Call and call_value insns
10498 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10499 (define_expand "call"
10500 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10501 (match_operand 1 ""))
10502 (use (match_operand 2 ""))
10503 (clobber (reg:SI LR_REGNO))])]
10507 if (MACHOPIC_INDIRECT)
10508 operands[0] = machopic_indirect_call_target (operands[0]);
10511 gcc_assert (MEM_P (operands[0]));
10513 operands[0] = XEXP (operands[0], 0);
10515 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10516 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10517 else if (DEFAULT_ABI == ABI_V4)
10518 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10519 else if (DEFAULT_ABI == ABI_DARWIN)
10520 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10522 gcc_unreachable ();
10527 (define_expand "call_value"
10528 [(parallel [(set (match_operand 0 "")
10529 (call (mem:SI (match_operand 1 "address_operand"))
10530 (match_operand 2 "")))
10531 (use (match_operand 3 ""))
10532 (clobber (reg:SI LR_REGNO))])]
10536 if (MACHOPIC_INDIRECT)
10537 operands[1] = machopic_indirect_call_target (operands[1]);
10540 gcc_assert (MEM_P (operands[1]));
10542 operands[1] = XEXP (operands[1], 0);
10544 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10545 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10546 else if (DEFAULT_ABI == ABI_V4)
10547 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10548 else if (DEFAULT_ABI == ABI_DARWIN)
10549 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10551 gcc_unreachable ();
10556 ;; Call to function in current module. No TOC pointer reload needed.
10557 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10558 ;; either the function was not prototyped, or it was prototyped as a
10559 ;; variable argument function. It is > 0 if FP registers were passed
10560 ;; and < 0 if they were not.
10562 (define_insn "*call_local<mode>"
10563 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s,s"))
10565 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10566 (clobber (reg:P LR_REGNO))]
10567 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10569 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10570 output_asm_insn ("crxor 6,6,6", operands);
10572 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10573 output_asm_insn ("creqv 6,6,6", operands);
10575 if (rs6000_pcrel_p (cfun))
10576 return "bl %z0@notoc";
10577 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10579 [(set_attr "type" "branch")
10580 (set_attr "length" "4,8")])
10582 (define_insn "*call_value_local<mode>"
10583 [(set (match_operand 0 "" "")
10584 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s,s"))
10585 (match_operand 2)))
10586 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10587 (clobber (reg:P LR_REGNO))]
10588 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10590 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10591 output_asm_insn ("crxor 6,6,6", operands);
10593 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10594 output_asm_insn ("creqv 6,6,6", operands);
10596 if (rs6000_pcrel_p (cfun))
10597 return "bl %z1@notoc";
10598 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10600 [(set_attr "type" "branch")
10601 (set_attr "length" "4,8")])
10604 ;; A function pointer under System V is just a normal pointer
10605 ;; operands[0] is the function pointer
10606 ;; operands[1] is the tls call arg
10607 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10608 ;; which indicates how to set cr1
10610 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10611 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10613 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10614 (clobber (reg:P LR_REGNO))]
10615 "DEFAULT_ABI == ABI_V4
10616 || DEFAULT_ABI == ABI_DARWIN"
10618 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10619 output_asm_insn ("crxor 6,6,6", operands);
10621 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10622 output_asm_insn ("creqv 6,6,6", operands);
10624 return rs6000_indirect_call_template (operands, 0);
10626 [(set_attr "type" "jmpreg")
10627 (set (attr "length")
10628 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10629 (match_test "which_alternative != 1"))
10630 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10631 (const_string "12")
10632 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10633 (match_test "which_alternative != 1"))
10634 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10635 (const_string "8")]
10636 (const_string "4")))])
10638 (define_insn "*call_nonlocal_sysv<mode>"
10639 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10641 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10642 (clobber (reg:P LR_REGNO))]
10643 "(DEFAULT_ABI == ABI_DARWIN
10644 || (DEFAULT_ABI == ABI_V4
10645 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10647 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10648 output_asm_insn ("crxor 6,6,6", operands);
10650 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10651 output_asm_insn ("creqv 6,6,6", operands);
10653 return rs6000_call_template (operands, 0);
10655 [(set_attr "type" "branch,branch")
10656 (set_attr "length" "4,8")])
10658 (define_insn "*call_nonlocal_sysv_secure<mode>"
10659 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10661 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10662 (use (match_operand:SI 3 "register_operand" "r,r"))
10663 (clobber (reg:P LR_REGNO))]
10664 "(DEFAULT_ABI == ABI_V4
10665 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10666 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10668 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10669 output_asm_insn ("crxor 6,6,6", operands);
10671 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10672 output_asm_insn ("creqv 6,6,6", operands);
10674 return rs6000_call_template (operands, 0);
10676 [(set_attr "type" "branch,branch")
10677 (set_attr "length" "4,8")])
10679 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10680 [(set (match_operand 0 "" "")
10681 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10682 (match_operand:P 2 "unspec_tls" "")))
10683 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10684 (clobber (reg:P LR_REGNO))]
10685 "DEFAULT_ABI == ABI_V4
10686 || DEFAULT_ABI == ABI_DARWIN"
10688 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10689 output_asm_insn ("crxor 6,6,6", operands);
10691 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10692 output_asm_insn ("creqv 6,6,6", operands);
10694 return rs6000_indirect_call_template (operands, 1);
10696 [(set_attr "type" "jmpreg")
10697 (set (attr "length")
10699 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10702 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10703 (match_test "which_alternative != 1"))
10707 (define_insn "*call_value_nonlocal_sysv<mode>"
10708 [(set (match_operand 0 "" "")
10709 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10710 (match_operand:P 2 "unspec_tls" "")))
10711 (use (match_operand:SI 3 "immediate_operand" "n"))
10712 (clobber (reg:P LR_REGNO))]
10713 "(DEFAULT_ABI == ABI_DARWIN
10714 || (DEFAULT_ABI == ABI_V4
10715 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10717 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10718 output_asm_insn ("crxor 6,6,6", operands);
10720 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10721 output_asm_insn ("creqv 6,6,6", operands);
10723 return rs6000_call_template (operands, 1);
10725 [(set_attr "type" "branch")
10726 (set (attr "length")
10727 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10731 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10732 [(set (match_operand 0 "" "")
10733 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10734 (match_operand:P 2 "unspec_tls" "")))
10735 (use (match_operand:SI 3 "immediate_operand" "n"))
10736 (use (match_operand:SI 4 "register_operand" "r"))
10737 (clobber (reg:P LR_REGNO))]
10738 "(DEFAULT_ABI == ABI_V4
10739 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10740 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10742 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10743 output_asm_insn ("crxor 6,6,6", operands);
10745 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10746 output_asm_insn ("creqv 6,6,6", operands);
10748 return rs6000_call_template (operands, 1);
10750 [(set_attr "type" "branch")
10751 (set (attr "length")
10752 (if_then_else (match_test "IS_V4_FP_ARGS (operands[3])")
10756 ;; Call to AIX abi function which may be in another module.
10757 ;; Restore the TOC pointer (r2) after the call.
10759 (define_insn "*call_nonlocal_aix<mode>"
10760 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10762 (use (match_operand:SI 2 "immediate_operand" "n"))
10763 (clobber (reg:P LR_REGNO))]
10764 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10765 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10767 return rs6000_call_template (operands, 0);
10769 [(set_attr "type" "branch")
10770 (set (attr "length")
10771 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10775 (define_insn "*call_value_nonlocal_aix<mode>"
10776 [(set (match_operand 0 "" "")
10777 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10778 (match_operand:P 2 "unspec_tls" "")))
10779 (use (match_operand:SI 3 "immediate_operand" "n"))
10780 (clobber (reg:P LR_REGNO))]
10781 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10782 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10784 return rs6000_call_template (operands, 1);
10786 [(set_attr "type" "branch")
10787 (set (attr "length")
10788 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10792 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10793 ;; Operand0 is the addresss of the function to call
10794 ;; Operand3 is the location in the function descriptor to load r2 from
10795 ;; Operand4 is the offset of the stack location holding the current TOC pointer
10797 (define_insn "*call_indirect_aix<mode>"
10798 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10800 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10801 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10802 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10803 (clobber (reg:P LR_REGNO))]
10804 "DEFAULT_ABI == ABI_AIX"
10806 return rs6000_indirect_call_template (operands, 0);
10808 [(set_attr "type" "jmpreg")
10809 (set (attr "length")
10810 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10811 (match_test "which_alternative != 1"))
10812 (const_string "16")
10813 (const_string "12")))])
10815 (define_insn "*call_value_indirect_aix<mode>"
10816 [(set (match_operand 0 "" "")
10817 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10818 (match_operand:P 2 "unspec_tls" "")))
10819 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10820 (use (match_operand:P 4 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10821 (set (reg:P TOC_REGNUM)
10822 (unspec:P [(match_operand:P 5 "const_int_operand" "n,n,n")]
10824 (clobber (reg:P LR_REGNO))]
10825 "DEFAULT_ABI == ABI_AIX"
10827 return rs6000_indirect_call_template (operands, 1);
10829 [(set_attr "type" "jmpreg")
10830 (set (attr "length")
10831 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10832 (match_test "which_alternative != 1"))
10833 (const_string "16")
10834 (const_string "12")))])
10836 ;; Call to indirect functions with the ELFv2 ABI.
10837 ;; Operand0 is the addresss of the function to call
10838 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10840 (define_insn "*call_indirect_elfv2<mode>"
10841 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10843 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10844 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10845 (clobber (reg:P LR_REGNO))]
10846 "DEFAULT_ABI == ABI_ELFv2"
10848 return rs6000_indirect_call_template (operands, 0);
10850 [(set_attr "type" "jmpreg")
10851 (set (attr "length")
10852 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10853 (match_test "which_alternative != 1"))
10854 (const_string "12")
10855 (const_string "8")))])
10857 (define_insn "*call_indirect_pcrel<mode>"
10858 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10860 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10861 (clobber (reg:P LR_REGNO))]
10862 "rs6000_pcrel_p (cfun)"
10864 return rs6000_indirect_call_template (operands, 0);
10866 [(set_attr "type" "jmpreg")
10867 (set (attr "length")
10868 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10869 (match_test "which_alternative != 1"))
10871 (const_string "4")))])
10873 (define_insn "*call_value_indirect_elfv2<mode>"
10874 [(set (match_operand 0 "" "")
10875 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10876 (match_operand:P 2 "unspec_tls" "")))
10877 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10878 (set (reg:P TOC_REGNUM)
10879 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10881 (clobber (reg:P LR_REGNO))]
10882 "DEFAULT_ABI == ABI_ELFv2"
10884 return rs6000_indirect_call_template (operands, 1);
10886 [(set_attr "type" "jmpreg")
10887 (set (attr "length")
10888 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10889 (match_test "which_alternative != 1"))
10890 (const_string "12")
10891 (const_string "8")))])
10893 (define_insn "*call_value_indirect_pcrel<mode>"
10894 [(set (match_operand 0 "" "")
10895 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10896 (match_operand:P 2 "unspec_tls" "")))
10897 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10898 (clobber (reg:P LR_REGNO))]
10899 "rs6000_pcrel_p (cfun)"
10901 return rs6000_indirect_call_template (operands, 1);
10903 [(set_attr "type" "jmpreg")
10904 (set (attr "length")
10905 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10906 (match_test "which_alternative != 1"))
10908 (const_string "4")))])
10910 ;; Call subroutine returning any type.
10911 (define_expand "untyped_call"
10912 [(parallel [(call (match_operand 0 "")
10914 (match_operand 1 "")
10915 (match_operand 2 "")])]
10920 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10922 for (int i = 0; i < XVECLEN (operands[2], 0); i++)
10923 emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i)));
10924 emit_insn (gen_blockage ());
10926 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10928 rtx set = XVECEXP (operands[2], 0, i);
10929 emit_move_insn (SET_DEST (set), SET_SRC (set));
10932 /* The optimizer does not know that the call sets the function value
10933 registers we stored in the result block. We avoid problems by
10934 claiming that all hard registers are used and clobbered at this
10936 emit_insn (gen_blockage ());
10941 ;; sibling call patterns
10942 (define_expand "sibcall"
10943 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10944 (match_operand 1 ""))
10945 (use (match_operand 2 ""))
10950 if (MACHOPIC_INDIRECT)
10951 operands[0] = machopic_indirect_call_target (operands[0]);
10954 gcc_assert (MEM_P (operands[0]));
10955 gcc_assert (CONST_INT_P (operands[1]));
10957 operands[0] = XEXP (operands[0], 0);
10959 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10960 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10961 else if (DEFAULT_ABI == ABI_V4)
10962 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10963 else if (DEFAULT_ABI == ABI_DARWIN)
10964 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10966 gcc_unreachable ();
10971 (define_expand "sibcall_value"
10972 [(parallel [(set (match_operand 0 "register_operand")
10973 (call (mem:SI (match_operand 1 "address_operand"))
10974 (match_operand 2 "")))
10975 (use (match_operand 3 ""))
10980 if (MACHOPIC_INDIRECT)
10981 operands[1] = machopic_indirect_call_target (operands[1]);
10984 gcc_assert (MEM_P (operands[1]));
10985 gcc_assert (CONST_INT_P (operands[2]));
10987 operands[1] = XEXP (operands[1], 0);
10989 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10990 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10991 else if (DEFAULT_ABI == ABI_V4)
10992 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10993 else if (DEFAULT_ABI == ABI_DARWIN)
10994 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10996 gcc_unreachable ();
11001 (define_insn "*sibcall_local32"
11002 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11004 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11006 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11008 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11009 output_asm_insn ("crxor 6,6,6", operands);
11011 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11012 output_asm_insn ("creqv 6,6,6", operands);
11014 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11016 [(set_attr "type" "branch")
11017 (set_attr "length" "4,8")])
11019 (define_insn "*sibcall_local64"
11020 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11022 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11024 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11026 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11027 output_asm_insn ("crxor 6,6,6", operands);
11029 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11030 output_asm_insn ("creqv 6,6,6", operands);
11032 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
11034 [(set_attr "type" "branch")
11035 (set_attr "length" "4,8")])
11037 (define_insn "*sibcall_value_local32"
11038 [(set (match_operand 0 "" "")
11039 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11040 (match_operand 2)))
11041 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11043 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11045 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11046 output_asm_insn ("crxor 6,6,6", operands);
11048 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11049 output_asm_insn ("creqv 6,6,6", operands);
11051 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11053 [(set_attr "type" "branch")
11054 (set_attr "length" "4,8")])
11056 (define_insn "*sibcall_value_local64"
11057 [(set (match_operand 0 "" "")
11058 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11059 (match_operand 2)))
11060 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11062 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11064 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11065 output_asm_insn ("crxor 6,6,6", operands);
11067 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11068 output_asm_insn ("creqv 6,6,6", operands);
11070 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
11072 [(set_attr "type" "branch")
11073 (set_attr "length" "4,8")])
11075 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
11076 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
11078 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
11080 "DEFAULT_ABI == ABI_V4
11081 || DEFAULT_ABI == ABI_DARWIN"
11083 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11084 output_asm_insn ("crxor 6,6,6", operands);
11086 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11087 output_asm_insn ("creqv 6,6,6", operands);
11089 return rs6000_indirect_sibcall_template (operands, 0);
11091 [(set_attr "type" "jmpreg")
11092 (set (attr "length")
11093 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11094 (match_test "which_alternative != 1"))
11095 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11096 (const_string "12")
11097 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11098 (match_test "which_alternative != 1"))
11099 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11100 (const_string "8")]
11101 (const_string "4")))])
11103 (define_insn "*sibcall_nonlocal_sysv<mode>"
11104 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11106 (use (match_operand 2 "immediate_operand" "O,n"))
11108 "(DEFAULT_ABI == ABI_DARWIN
11109 || DEFAULT_ABI == ABI_V4)
11110 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11112 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11113 output_asm_insn ("crxor 6,6,6", operands);
11115 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11116 output_asm_insn ("creqv 6,6,6", operands);
11118 return rs6000_sibcall_template (operands, 0);
11120 [(set_attr "type" "branch")
11121 (set_attr "length" "4,8")])
11123 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
11124 [(set (match_operand 0 "" "")
11125 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
11126 (match_operand 2)))
11127 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
11129 "DEFAULT_ABI == ABI_V4
11130 || DEFAULT_ABI == ABI_DARWIN"
11132 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11133 output_asm_insn ("crxor 6,6,6", operands);
11135 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11136 output_asm_insn ("creqv 6,6,6", operands);
11138 return rs6000_indirect_sibcall_template (operands, 1);
11140 [(set_attr "type" "jmpreg")
11141 (set (attr "length")
11142 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
11143 (match_test "which_alternative != 1"))
11144 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11145 (const_string "12")
11146 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
11147 (match_test "which_alternative != 1"))
11148 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
11149 (const_string "8")]
11150 (const_string "4")))])
11152 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11153 [(set (match_operand 0 "" "")
11154 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11155 (match_operand 2)))
11156 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11158 "(DEFAULT_ABI == ABI_DARWIN
11159 || DEFAULT_ABI == ABI_V4)
11160 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11162 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11163 output_asm_insn ("crxor 6,6,6", operands);
11165 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11166 output_asm_insn ("creqv 6,6,6", operands);
11168 return rs6000_sibcall_template (operands, 1);
11170 [(set_attr "type" "branch")
11171 (set_attr "length" "4,8")])
11173 ;; AIX ABI sibling call patterns.
11175 (define_insn "*sibcall_aix<mode>"
11176 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11179 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11181 if (which_alternative == 0)
11182 return rs6000_sibcall_template (operands, 0);
11186 [(set_attr "type" "branch")])
11188 (define_insn "*sibcall_value_aix<mode>"
11189 [(set (match_operand 0 "" "")
11190 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11191 (match_operand 2)))
11193 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11195 if (which_alternative == 0)
11196 return rs6000_sibcall_template (operands, 1);
11200 [(set_attr "type" "branch")])
11202 (define_expand "sibcall_epilogue"
11203 [(use (const_int 0))]
11206 if (!TARGET_SCHED_PROLOG)
11207 emit_insn (gen_blockage ());
11208 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11212 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11213 ;; all of memory. This blocks insns from being moved across this point.
11215 (define_insn "blockage"
11216 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11219 [(set_attr "length" "0")])
11221 (define_expand "probe_stack_address"
11222 [(use (match_operand 0 "address_operand"))]
11225 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11226 MEM_VOLATILE_P (operands[0]) = 1;
11229 emit_insn (gen_probe_stack_di (operands[0]));
11231 emit_insn (gen_probe_stack_si (operands[0]));
11235 (define_insn "probe_stack_<mode>"
11236 [(set (match_operand:P 0 "memory_operand" "=m")
11237 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11240 operands[1] = gen_rtx_REG (Pmode, 0);
11241 return "st<wd>%U0%X0 %1,%0";
11243 [(set_attr "type" "store")
11244 (set (attr "update")
11245 (if_then_else (match_operand 0 "update_address_mem")
11246 (const_string "yes")
11247 (const_string "no")))
11248 (set (attr "indexed")
11249 (if_then_else (match_operand 0 "indexed_address_mem")
11250 (const_string "yes")
11251 (const_string "no")))])
11253 (define_insn "probe_stack_range<P:mode>"
11254 [(set (match_operand:P 0 "register_operand" "=&r")
11255 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11256 (match_operand:P 2 "register_operand" "r")
11257 (match_operand:P 3 "register_operand" "r")]
11258 UNSPECV_PROBE_STACK_RANGE))]
11260 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11261 [(set_attr "type" "three")])
11263 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11264 ;; signed & unsigned, and one type of branch.
11266 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11267 ;; insns, and branches.
11269 (define_expand "cbranch<mode>4"
11270 [(use (match_operator 0 "comparison_operator"
11271 [(match_operand:GPR 1 "gpc_reg_operand")
11272 (match_operand:GPR 2 "reg_or_short_operand")]))
11273 (use (match_operand 3))]
11276 /* Take care of the possibility that operands[2] might be negative but
11277 this might be a logical operation. That insn doesn't exist. */
11278 if (CONST_INT_P (operands[2])
11279 && INTVAL (operands[2]) < 0)
11281 operands[2] = force_reg (<MODE>mode, operands[2]);
11282 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11283 GET_MODE (operands[0]),
11284 operands[1], operands[2]);
11287 rs6000_emit_cbranch (<MODE>mode, operands);
11291 (define_expand "cbranch<mode>4"
11292 [(use (match_operator 0 "comparison_operator"
11293 [(match_operand:FP 1 "gpc_reg_operand")
11294 (match_operand:FP 2 "gpc_reg_operand")]))
11295 (use (match_operand 3))]
11298 rs6000_emit_cbranch (<MODE>mode, operands);
11302 (define_expand "cstore<mode>4_signed"
11303 [(use (match_operator 1 "signed_comparison_operator"
11304 [(match_operand:P 2 "gpc_reg_operand")
11305 (match_operand:P 3 "gpc_reg_operand")]))
11306 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11309 enum rtx_code cond_code = GET_CODE (operands[1]);
11311 rtx op0 = operands[0];
11312 rtx op1 = operands[2];
11313 rtx op2 = operands[3];
11315 if (cond_code == GE || cond_code == LT)
11317 cond_code = swap_condition (cond_code);
11318 std::swap (op1, op2);
11321 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11322 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11323 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11325 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11326 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11327 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11329 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11331 if (cond_code == LE)
11332 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11335 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11336 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11337 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11343 (define_expand "cstore<mode>4_unsigned"
11344 [(use (match_operator 1 "unsigned_comparison_operator"
11345 [(match_operand:P 2 "gpc_reg_operand")
11346 (match_operand:P 3 "reg_or_short_operand")]))
11347 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11350 enum rtx_code cond_code = GET_CODE (operands[1]);
11352 rtx op0 = operands[0];
11353 rtx op1 = operands[2];
11354 rtx op2 = operands[3];
11356 if (cond_code == GEU || cond_code == LTU)
11358 cond_code = swap_condition (cond_code);
11359 std::swap (op1, op2);
11362 if (!gpc_reg_operand (op1, <MODE>mode))
11363 op1 = force_reg (<MODE>mode, op1);
11364 if (!reg_or_short_operand (op2, <MODE>mode))
11365 op2 = force_reg (<MODE>mode, op2);
11367 rtx tmp = gen_reg_rtx (<MODE>mode);
11368 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11370 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11371 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11373 if (cond_code == LEU)
11374 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11376 emit_insn (gen_neg<mode>2 (op0, tmp2));
11381 (define_expand "cstore_si_as_di"
11382 [(use (match_operator 1 "unsigned_comparison_operator"
11383 [(match_operand:SI 2 "gpc_reg_operand")
11384 (match_operand:SI 3 "reg_or_short_operand")]))
11385 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11388 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11389 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11391 operands[2] = force_reg (SImode, operands[2]);
11392 operands[3] = force_reg (SImode, operands[3]);
11393 rtx op1 = gen_reg_rtx (DImode);
11394 rtx op2 = gen_reg_rtx (DImode);
11395 convert_move (op1, operands[2], uns_flag);
11396 convert_move (op2, operands[3], uns_flag);
11398 if (cond_code == GT || cond_code == LE)
11400 cond_code = swap_condition (cond_code);
11401 std::swap (op1, op2);
11404 rtx tmp = gen_reg_rtx (DImode);
11405 rtx tmp2 = gen_reg_rtx (DImode);
11406 emit_insn (gen_subdi3 (tmp, op1, op2));
11407 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11413 gcc_unreachable ();
11418 tmp3 = gen_reg_rtx (DImode);
11419 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11423 convert_move (operands[0], tmp3, 1);
11428 (define_expand "cstore<mode>4_signed_imm"
11429 [(use (match_operator 1 "signed_comparison_operator"
11430 [(match_operand:GPR 2 "gpc_reg_operand")
11431 (match_operand:GPR 3 "immediate_operand")]))
11432 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11435 bool invert = false;
11437 enum rtx_code cond_code = GET_CODE (operands[1]);
11439 rtx op0 = operands[0];
11440 rtx op1 = operands[2];
11441 HOST_WIDE_INT val = INTVAL (operands[3]);
11443 if (cond_code == GE || cond_code == GT)
11445 cond_code = reverse_condition (cond_code);
11449 if (cond_code == LE)
11452 rtx tmp = gen_reg_rtx (<MODE>mode);
11453 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11454 rtx x = gen_reg_rtx (<MODE>mode);
11456 emit_insn (gen_and<mode>3 (x, op1, tmp));
11458 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11462 rtx tmp = gen_reg_rtx (<MODE>mode);
11463 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11467 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11468 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11473 (define_expand "cstore<mode>4_unsigned_imm"
11474 [(use (match_operator 1 "unsigned_comparison_operator"
11475 [(match_operand:GPR 2 "gpc_reg_operand")
11476 (match_operand:GPR 3 "immediate_operand")]))
11477 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11480 bool invert = false;
11482 enum rtx_code cond_code = GET_CODE (operands[1]);
11484 rtx op0 = operands[0];
11485 rtx op1 = operands[2];
11486 HOST_WIDE_INT val = INTVAL (operands[3]);
11488 if (cond_code == GEU || cond_code == GTU)
11490 cond_code = reverse_condition (cond_code);
11494 if (cond_code == LEU)
11497 rtx tmp = gen_reg_rtx (<MODE>mode);
11498 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11499 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11500 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11501 rtx x = gen_reg_rtx (<MODE>mode);
11503 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11505 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11509 rtx tmp = gen_reg_rtx (<MODE>mode);
11510 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11514 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11515 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11520 (define_expand "cstore<mode>4"
11521 [(use (match_operator 1 "comparison_operator"
11522 [(match_operand:GPR 2 "gpc_reg_operand")
11523 (match_operand:GPR 3 "reg_or_short_operand")]))
11524 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11527 /* Everything is best done with setbc[r] if available. */
11528 if (TARGET_POWER10)
11529 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11531 /* Expanding EQ and NE directly to some machine instructions does not help
11532 but does hurt combine. So don't. */
11533 if (GET_CODE (operands[1]) == EQ)
11534 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11535 else if (<MODE>mode == Pmode
11536 && GET_CODE (operands[1]) == NE)
11537 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11538 else if (GET_CODE (operands[1]) == NE)
11540 rtx tmp = gen_reg_rtx (<MODE>mode);
11541 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11542 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11545 /* If ISEL is fast, expand to it. */
11546 else if (TARGET_ISEL)
11547 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11549 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11550 etc. combinations magically work out just right. */
11551 else if (<MODE>mode == Pmode
11552 && unsigned_comparison_operator (operands[1], VOIDmode))
11553 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11554 operands[2], operands[3]));
11556 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11557 else if (<MODE>mode == SImode && Pmode == DImode)
11558 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11559 operands[2], operands[3]));
11561 /* For signed comparisons against a constant, we can do some simple
11563 else if (signed_comparison_operator (operands[1], VOIDmode)
11564 && CONST_INT_P (operands[3]))
11565 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11566 operands[2], operands[3]));
11568 /* And similarly for unsigned comparisons. */
11569 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11570 && CONST_INT_P (operands[3]))
11571 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11572 operands[2], operands[3]));
11574 /* We also do not want to use mfcr for signed comparisons. */
11575 else if (<MODE>mode == Pmode
11576 && signed_comparison_operator (operands[1], VOIDmode))
11577 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11578 operands[2], operands[3]));
11580 /* Everything else, use the mfcr brute force. */
11582 rs6000_emit_sCOND (<MODE>mode, operands);
11587 (define_expand "cstore<mode>4"
11588 [(use (match_operator 1 "comparison_operator"
11589 [(match_operand:FP 2 "gpc_reg_operand")
11590 (match_operand:FP 3 "gpc_reg_operand")]))
11591 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11594 rs6000_emit_sCOND (<MODE>mode, operands);
11599 (define_expand "stack_protect_set"
11600 [(match_operand 0 "memory_operand")
11601 (match_operand 1 "memory_operand")]
11604 if (rs6000_stack_protector_guard == SSP_TLS)
11606 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11607 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11608 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11609 operands[1] = gen_rtx_MEM (Pmode, addr);
11613 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11615 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11620 (define_insn "stack_protect_setsi"
11621 [(set (match_operand:SI 0 "memory_operand" "=m")
11622 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11623 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11625 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11626 [(set_attr "type" "three")
11627 (set_attr "length" "12")])
11629 ;; We can't use the prefixed attribute here because there are two memory
11630 ;; instructions. We can't split the insn due to the fact that this operation
11631 ;; needs to be done in one piece.
11632 (define_insn "stack_protect_setdi"
11633 [(set (match_operand:DI 0 "memory_operand" "=Y")
11634 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11635 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11638 if (prefixed_memory (operands[1], DImode))
11639 output_asm_insn ("pld %2,%1", operands);
11641 output_asm_insn ("ld%U1%X1 %2,%1", operands);
11643 if (prefixed_memory (operands[0], DImode))
11644 output_asm_insn ("pstd %2,%0", operands);
11646 output_asm_insn ("std%U0%X0 %2,%0", operands);
11650 [(set_attr "type" "three")
11652 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11653 ;; prefixed instruction + 4 bytes for the possible NOP). Add in 4 bytes for
11654 ;; the LI 0 at the end.
11655 (set_attr "prefixed" "no")
11656 (set_attr "num_insns" "3")
11657 (set (attr "length")
11658 (cond [(and (match_operand 0 "prefixed_memory")
11659 (match_operand 1 "prefixed_memory"))
11662 (ior (match_operand 0 "prefixed_memory")
11663 (match_operand 1 "prefixed_memory"))
11668 (define_expand "stack_protect_test"
11669 [(match_operand 0 "memory_operand")
11670 (match_operand 1 "memory_operand")
11671 (match_operand 2 "")]
11674 rtx guard = operands[1];
11676 if (rs6000_stack_protector_guard == SSP_TLS)
11678 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11679 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11680 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11681 guard = gen_rtx_MEM (Pmode, addr);
11684 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11685 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11686 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11687 emit_jump_insn (jump);
11692 (define_insn "stack_protect_testsi"
11693 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11694 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11695 (match_operand:SI 2 "memory_operand" "m,m")]
11697 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11698 (clobber (match_scratch:SI 3 "=&r,&r"))]
11701 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11702 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11703 [(set_attr "length" "16,20")])
11705 ;; We can't use the prefixed attribute here because there are two memory
11706 ;; instructions. We can't split the insn due to the fact that this operation
11707 ;; needs to be done in one piece.
11708 (define_insn "stack_protect_testdi"
11709 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11710 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11711 (match_operand:DI 2 "memory_operand" "Y,Y")]
11713 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11714 (clobber (match_scratch:DI 3 "=&r,&r"))]
11717 if (prefixed_memory (operands[1], DImode))
11718 output_asm_insn ("pld %3,%1", operands);
11720 output_asm_insn ("ld%U1%X1 %3,%1", operands);
11722 if (prefixed_memory (operands[2], DImode))
11723 output_asm_insn ("pld %4,%2", operands);
11725 output_asm_insn ("ld%U2%X2 %4,%2", operands);
11727 if (which_alternative == 0)
11728 output_asm_insn ("xor. %3,%3,%4", operands);
11730 output_asm_insn ("cmpld %0,%3,%4\;li %3,0", operands);
11734 ;; Back to back prefixed memory instructions take 20 bytes (8 bytes for each
11735 ;; prefixed instruction + 4 bytes for the possible NOP). Add in either 4 or
11736 ;; 8 bytes to do the test.
11737 [(set_attr "prefixed" "no")
11738 (set_attr "num_insns" "4,5")
11739 (set (attr "length")
11740 (cond [(and (match_operand 1 "prefixed_memory")
11741 (match_operand 2 "prefixed_memory"))
11742 (if_then_else (eq_attr "alternative" "0")
11746 (ior (match_operand 1 "prefixed_memory")
11747 (match_operand 2 "prefixed_memory"))
11748 (if_then_else (eq_attr "alternative" "0")
11752 (if_then_else (eq_attr "alternative" "0")
11754 (const_int 20))))])
11757 ;; Here are the actual compare insns.
11758 (define_insn "*cmp<mode>_signed"
11759 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11760 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11761 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11763 "cmp<wd>%I2 %0,%1,%2"
11764 [(set_attr "type" "cmp")])
11766 (define_insn "*cmp<mode>_unsigned"
11767 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11768 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11769 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11771 "cmpl<wd>%I2 %0,%1,%2"
11772 [(set_attr "type" "cmp")])
11774 ;; If we are comparing a register for equality with a large constant,
11775 ;; we can do this with an XOR followed by a compare. But this is profitable
11776 ;; only if the large constant is only used for the comparison (and in this
11777 ;; case we already have a register to reuse as scratch).
11779 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11780 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11783 [(set (match_operand:SI 0 "register_operand")
11784 (match_operand:SI 1 "logical_const_operand"))
11785 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11787 (match_operand:SI 2 "logical_const_operand")]))
11788 (set (match_operand:CC 4 "cc_reg_operand")
11789 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11792 (if_then_else (match_operator 6 "equality_operator"
11793 [(match_dup 4) (const_int 0)])
11794 (match_operand 7 "")
11795 (match_operand 8 "")))]
11796 "peep2_reg_dead_p (3, operands[0])
11797 && peep2_reg_dead_p (4, operands[4])
11798 && REGNO (operands[0]) != REGNO (operands[5])"
11799 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11800 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11801 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11804 /* Get the constant we are comparing against, and see what it looks like
11805 when sign-extended from 16 to 32 bits. Then see what constant we could
11806 XOR with SEXTC to get the sign-extended value. */
11807 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11809 operands[1], operands[2]);
11810 HOST_WIDE_INT c = INTVAL (cnst);
11811 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11812 HOST_WIDE_INT xorv = c ^ sextc;
11814 operands[9] = GEN_INT (xorv);
11815 operands[10] = GEN_INT (sextc);
11818 ;; Only need to compare second words if first words equal
11819 (define_insn "*cmp<mode>_internal1"
11820 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11821 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11822 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11823 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11824 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11825 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11826 [(set_attr "type" "fpcompare")
11827 (set_attr "length" "12")])
11829 (define_insn_and_split "*cmp<IBM128:mode>_internal2"
11830 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11831 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11832 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11833 (clobber (match_scratch:DF 3 "=d"))
11834 (clobber (match_scratch:DF 4 "=d"))
11835 (clobber (match_scratch:DF 5 "=d"))
11836 (clobber (match_scratch:DF 6 "=d"))
11837 (clobber (match_scratch:DF 7 "=d"))
11838 (clobber (match_scratch:DF 8 "=d"))
11839 (clobber (match_scratch:DF 9 "=d"))
11840 (clobber (match_scratch:DF 10 "=d"))
11841 (clobber (match_scratch:GPR 11 "=b"))]
11842 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<IBM128:MODE>mode)
11843 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11845 "&& reload_completed"
11846 [(set (match_dup 3) (match_dup 14))
11847 (set (match_dup 4) (match_dup 15))
11848 (set (match_dup 9) (abs:DF (match_dup 5)))
11849 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11850 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11851 (label_ref (match_dup 12))
11853 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11854 (set (pc) (label_ref (match_dup 13)))
11856 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11857 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11858 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11859 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11862 REAL_VALUE_TYPE rv;
11863 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11864 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11866 operands[5] = simplify_gen_subreg (DFmode, operands[1],
11867 <IBM128:MODE>mode, hi_word);
11868 operands[6] = simplify_gen_subreg (DFmode, operands[1],
11869 <IBM128:MODE>mode, lo_word);
11870 operands[7] = simplify_gen_subreg (DFmode, operands[2],
11871 <IBM128:MODE>mode, hi_word);
11872 operands[8] = simplify_gen_subreg (DFmode, operands[2],
11873 <IBM128:MODE>mode, lo_word);
11874 operands[12] = gen_label_rtx ();
11875 operands[13] = gen_label_rtx ();
11877 operands[14] = force_const_mem (DFmode,
11878 const_double_from_real_value (rv, DFmode));
11879 operands[15] = force_const_mem (DFmode,
11880 const_double_from_real_value (dconst0,
11885 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11886 operands[14] = gen_const_mem (DFmode, tocref);
11887 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11888 operands[15] = gen_const_mem (DFmode, tocref);
11889 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11890 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11894 ;; Now we have the scc insns. We can do some combinations because of the
11895 ;; way the machine works.
11897 ;; Note that this is probably faster if we can put an insn between the
11898 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11899 ;; cases the insns below which don't use an intermediate CR field will
11900 ;; be used instead.
11901 (define_insn "set<mode>_cc"
11902 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11903 (match_operator:GPR 1 "scc_comparison_operator"
11904 [(match_operand 2 "cc_reg_operand" "y")
11907 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11908 [(set (attr "type")
11909 (cond [(match_test "TARGET_MFCRF")
11910 (const_string "mfcrf")
11912 (const_string "mfcr")))
11913 (set_attr "length" "8")])
11916 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11917 (define_code_attr UNS [(eq "CC")
11919 (lt "CC") (ltu "CCUNS")
11920 (gt "CC") (gtu "CCUNS")
11921 (le "CC") (leu "CCUNS")
11922 (ge "CC") (geu "CCUNS")])
11923 (define_code_attr UNSu_ [(eq "")
11928 (ge "") (geu "u_")])
11929 (define_code_attr UNSIK [(eq "I")
11934 (ge "I") (geu "K")])
11936 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11937 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11938 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11939 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11940 (clobber (match_scratch:GPR 3 "=r"))
11941 (clobber (match_scratch:GPR 4 "=r"))
11942 (clobber (match_scratch:<UNS> 5 "=y"))]
11943 "!TARGET_POWER10 && TARGET_ISEL
11944 && !(<CODE> == EQ && operands[2] == const0_rtx)
11945 && !(<CODE> == NE && operands[2] == const0_rtx
11946 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11951 rtx_code code = <CODE>;
11952 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11954 HOST_WIDE_INT val = INTVAL (operands[2]);
11955 if (code == LT && val != -0x8000)
11960 if (code == GT && val != 0x7fff)
11965 if (code == LTU && val != 0)
11970 if (code == GTU && val != 0xffff)
11975 operands[2] = GEN_INT (val);
11978 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11979 operands[3] = const0_rtx;
11982 if (GET_CODE (operands[3]) == SCRATCH)
11983 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11984 emit_move_insn (operands[3], const0_rtx);
11987 if (GET_CODE (operands[4]) == SCRATCH)
11988 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11989 emit_move_insn (operands[4], const1_rtx);
11991 if (GET_CODE (operands[5]) == SCRATCH)
11992 operands[5] = gen_reg_rtx (<UNS>mode);
11994 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11995 emit_insn (gen_rtx_SET (operands[5], c1));
11997 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11998 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11999 emit_move_insn (operands[0], x);
12003 [(set (attr "cost")
12004 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12006 || <CODE> == LE || <CODE> == GE
12007 || <CODE> == LEU || <CODE> == GEU")
12009 (const_string "10")))])
12011 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12014 (define_expand "eq<mode>3"
12016 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12017 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12018 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12019 (clobber (match_scratch:GPR 3 "=r"))
12020 (clobber (match_scratch:GPR 4 "=r"))])]
12023 if (TARGET_POWER10)
12025 rtx cc = gen_reg_rtx (CCmode);
12026 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12027 emit_insn (gen_rtx_SET (cc, compare));
12028 rtx eq = gen_rtx_fmt_ee (EQ, <MODE>mode, cc, const0_rtx);
12029 emit_insn (gen_setbc_signed_<mode> (operands[0], eq, cc));
12033 if (TARGET_ISEL && operands[2] != const0_rtx)
12035 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12041 (define_insn_and_split "*eq<mode>3"
12042 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12043 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12044 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12045 (clobber (match_scratch:GPR 3 "=r"))
12046 (clobber (match_scratch:GPR 4 "=r"))]
12047 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12050 [(set (match_dup 4)
12051 (clz:GPR (match_dup 3)))
12053 (lshiftrt:GPR (match_dup 4)
12056 operands[3] = rs6000_emit_eqne (<MODE>mode,
12057 operands[1], operands[2], operands[3]);
12059 if (GET_CODE (operands[4]) == SCRATCH)
12060 operands[4] = gen_reg_rtx (<MODE>mode);
12062 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12064 [(set (attr "length")
12065 (if_then_else (match_test "operands[2] == const0_rtx")
12067 (const_string "12")))])
12069 (define_expand "ne<mode>3"
12071 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12072 (ne:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12073 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12074 (clobber (match_scratch:GPR 3 "=r"))
12075 (clobber (match_scratch:GPR 4 "=r"))
12076 (clobber (reg:GPR CA_REGNO))])]
12079 if (TARGET_POWER10)
12081 rtx cc = gen_reg_rtx (CCmode);
12082 rtx compare = gen_rtx_COMPARE (CCmode, operands[1], operands[2]);
12083 emit_insn (gen_rtx_SET (cc, compare));
12084 rtx ne = gen_rtx_fmt_ee (NE, <MODE>mode, cc, const0_rtx);
12085 emit_insn (gen_setbc_signed_<mode> (operands[0], ne, cc));
12089 if (<MODE>mode != Pmode)
12091 rtx x = gen_reg_rtx (<MODE>mode);
12092 emit_insn (gen_eq<mode>3 (x, operands[1], operands[2]));
12093 emit_insn (gen_xor<mode>3 (operands[0], x, const1_rtx));
12097 if (TARGET_ISEL && operands[2] != const0_rtx)
12099 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12105 (define_insn_and_split "*ne<mode>3"
12106 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12107 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12108 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12109 (clobber (match_scratch:P 3 "=r"))
12110 (clobber (match_scratch:P 4 "=r"))
12111 (clobber (reg:P CA_REGNO))]
12112 "!TARGET_POWER10 && !(TARGET_ISEL && operands[2] != const0_rtx)"
12115 [(parallel [(set (match_dup 4)
12116 (plus:P (match_dup 3)
12118 (set (reg:P CA_REGNO)
12119 (ne:P (match_dup 3)
12121 (parallel [(set (match_dup 0)
12122 (plus:P (plus:P (not:P (match_dup 4))
12125 (clobber (reg:P CA_REGNO))])]
12127 operands[3] = rs6000_emit_eqne (<MODE>mode,
12128 operands[1], operands[2], operands[3]);
12130 if (GET_CODE (operands[4]) == SCRATCH)
12131 operands[4] = gen_reg_rtx (<MODE>mode);
12133 [(set (attr "length")
12134 (if_then_else (match_test "operands[2] == const0_rtx")
12136 (const_string "12")))])
12138 (define_insn_and_split "*neg_eq_<mode>"
12139 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12140 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12141 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12142 (clobber (match_scratch:P 3 "=r"))
12143 (clobber (match_scratch:P 4 "=r"))
12144 (clobber (reg:P CA_REGNO))]
12148 [(parallel [(set (match_dup 4)
12149 (plus:P (match_dup 3)
12151 (set (reg:P CA_REGNO)
12152 (ne:P (match_dup 3)
12154 (parallel [(set (match_dup 0)
12155 (plus:P (reg:P CA_REGNO)
12157 (clobber (reg:P CA_REGNO))])]
12159 operands[3] = rs6000_emit_eqne (<MODE>mode,
12160 operands[1], operands[2], operands[3]);
12162 if (GET_CODE (operands[4]) == SCRATCH)
12163 operands[4] = gen_reg_rtx (<MODE>mode);
12165 [(set (attr "length")
12166 (if_then_else (match_test "operands[2] == const0_rtx")
12168 (const_string "12")))])
12170 (define_insn_and_split "*neg_ne_<mode>"
12171 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12172 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12173 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12174 (clobber (match_scratch:P 3 "=r"))
12175 (clobber (match_scratch:P 4 "=r"))
12176 (clobber (reg:P CA_REGNO))]
12180 [(parallel [(set (match_dup 4)
12181 (neg:P (match_dup 3)))
12182 (set (reg:P CA_REGNO)
12183 (eq:P (match_dup 3)
12185 (parallel [(set (match_dup 0)
12186 (plus:P (reg:P CA_REGNO)
12188 (clobber (reg:P CA_REGNO))])]
12190 operands[3] = rs6000_emit_eqne (<MODE>mode,
12191 operands[1], operands[2], operands[3]);
12193 if (GET_CODE (operands[4]) == SCRATCH)
12194 operands[4] = gen_reg_rtx (<MODE>mode);
12196 [(set (attr "length")
12197 (if_then_else (match_test "operands[2] == const0_rtx")
12199 (const_string "12")))])
12201 (define_insn_and_split "*plus_eq_<mode>"
12202 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12203 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12204 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12205 (match_operand:P 3 "gpc_reg_operand" "r")))
12206 (clobber (match_scratch:P 4 "=r"))
12207 (clobber (match_scratch:P 5 "=r"))
12208 (clobber (reg:P CA_REGNO))]
12212 [(parallel [(set (match_dup 5)
12213 (neg:P (match_dup 4)))
12214 (set (reg:P CA_REGNO)
12215 (eq:P (match_dup 4)
12217 (parallel [(set (match_dup 0)
12218 (plus:P (match_dup 3)
12220 (clobber (reg:P CA_REGNO))])]
12222 operands[4] = rs6000_emit_eqne (<MODE>mode,
12223 operands[1], operands[2], operands[4]);
12225 if (GET_CODE (operands[5]) == SCRATCH)
12226 operands[5] = gen_reg_rtx (<MODE>mode);
12228 [(set (attr "length")
12229 (if_then_else (match_test "operands[2] == const0_rtx")
12231 (const_string "12")))])
12233 (define_insn_and_split "*plus_ne_<mode>"
12234 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12235 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12236 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12237 (match_operand:P 3 "gpc_reg_operand" "r")))
12238 (clobber (match_scratch:P 4 "=r"))
12239 (clobber (match_scratch:P 5 "=r"))
12240 (clobber (reg:P CA_REGNO))]
12244 [(parallel [(set (match_dup 5)
12245 (plus:P (match_dup 4)
12247 (set (reg:P CA_REGNO)
12248 (ne:P (match_dup 4)
12250 (parallel [(set (match_dup 0)
12251 (plus:P (match_dup 3)
12253 (clobber (reg:P CA_REGNO))])]
12255 operands[4] = rs6000_emit_eqne (<MODE>mode,
12256 operands[1], operands[2], operands[4]);
12258 if (GET_CODE (operands[5]) == SCRATCH)
12259 operands[5] = gen_reg_rtx (<MODE>mode);
12261 [(set (attr "length")
12262 (if_then_else (match_test "operands[2] == const0_rtx")
12264 (const_string "12")))])
12266 (define_insn_and_split "*minus_eq_<mode>"
12267 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12268 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12269 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12270 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12271 (clobber (match_scratch:P 4 "=r"))
12272 (clobber (match_scratch:P 5 "=r"))
12273 (clobber (reg:P CA_REGNO))]
12277 [(parallel [(set (match_dup 5)
12278 (plus:P (match_dup 4)
12280 (set (reg:P CA_REGNO)
12281 (ne:P (match_dup 4)
12283 (parallel [(set (match_dup 0)
12284 (plus:P (plus:P (match_dup 3)
12287 (clobber (reg:P CA_REGNO))])]
12289 operands[4] = rs6000_emit_eqne (<MODE>mode,
12290 operands[1], operands[2], operands[4]);
12292 if (GET_CODE (operands[5]) == SCRATCH)
12293 operands[5] = gen_reg_rtx (<MODE>mode);
12295 [(set (attr "length")
12296 (if_then_else (match_test "operands[2] == const0_rtx")
12298 (const_string "12")))])
12300 (define_insn_and_split "*minus_ne_<mode>"
12301 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12302 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12303 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12304 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12305 (clobber (match_scratch:P 4 "=r"))
12306 (clobber (match_scratch:P 5 "=r"))
12307 (clobber (reg:P CA_REGNO))]
12311 [(parallel [(set (match_dup 5)
12312 (neg:P (match_dup 4)))
12313 (set (reg:P CA_REGNO)
12314 (eq:P (match_dup 4)
12316 (parallel [(set (match_dup 0)
12317 (plus:P (plus:P (match_dup 3)
12320 (clobber (reg:P CA_REGNO))])]
12322 operands[4] = rs6000_emit_eqne (<MODE>mode,
12323 operands[1], operands[2], operands[4]);
12325 if (GET_CODE (operands[5]) == SCRATCH)
12326 operands[5] = gen_reg_rtx (<MODE>mode);
12328 [(set (attr "length")
12329 (if_then_else (match_test "operands[2] == const0_rtx")
12331 (const_string "12")))])
12333 (define_insn_and_split "*eqsi3_ext<mode>"
12334 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12335 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12336 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12337 (clobber (match_scratch:SI 3 "=r"))
12338 (clobber (match_scratch:SI 4 "=r"))]
12342 [(set (match_dup 4)
12343 (clz:SI (match_dup 3)))
12346 (lshiftrt:SI (match_dup 4)
12349 operands[3] = rs6000_emit_eqne (SImode,
12350 operands[1], operands[2], operands[3]);
12352 if (GET_CODE (operands[4]) == SCRATCH)
12353 operands[4] = gen_reg_rtx (SImode);
12355 [(set (attr "length")
12356 (if_then_else (match_test "operands[2] == const0_rtx")
12358 (const_string "12")))])
12360 (define_insn_and_split "*nesi3_ext<mode>"
12361 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12362 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12363 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12364 (clobber (match_scratch:SI 3 "=r"))
12365 (clobber (match_scratch:SI 4 "=r"))
12366 (clobber (match_scratch:EXTSI 5 "=r"))]
12370 [(set (match_dup 4)
12371 (clz:SI (match_dup 3)))
12374 (lshiftrt:SI (match_dup 4)
12377 (xor:EXTSI (match_dup 5)
12380 operands[3] = rs6000_emit_eqne (SImode,
12381 operands[1], operands[2], operands[3]);
12383 if (GET_CODE (operands[4]) == SCRATCH)
12384 operands[4] = gen_reg_rtx (SImode);
12385 if (GET_CODE (operands[5]) == SCRATCH)
12386 operands[5] = gen_reg_rtx (<MODE>mode);
12388 [(set (attr "length")
12389 (if_then_else (match_test "operands[2] == const0_rtx")
12390 (const_string "12")
12391 (const_string "16")))])
12394 (define_code_iterator fp_rev [ordered ne unle unge])
12395 (define_code_iterator fp_two [ltgt le ge unlt ungt uneq])
12397 (define_insn_and_split "*<code><mode>_cc"
12398 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12399 (fp_rev:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12401 "!flag_finite_math_only"
12406 rtx_code revcode = reverse_condition_maybe_unordered (<CODE>);
12407 rtx eq = gen_rtx_fmt_ee (revcode, <MODE>mode, operands[1], const0_rtx);
12408 rtx tmp = gen_reg_rtx (<MODE>mode);
12409 emit_move_insn (tmp, eq);
12410 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
12413 [(set_attr "length" "12")])
12415 (define_insn_and_split "*<code><mode>_cc"
12416 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12417 (fp_two:GPR (match_operand:CCFP 1 "cc_reg_operand" "y")
12419 "!flag_finite_math_only"
12424 rtx cc = rs6000_emit_fp_cror (<CODE>, <MODE>mode, operands[1]);
12426 emit_move_insn (operands[0], gen_rtx_EQ (<MODE>mode, cc, const0_rtx));
12429 [(set_attr "length" "12")])
12431 ;; Conditional branches.
12432 ;; These either are a single bc insn, or a bc around a b.
12434 (define_insn "*cbranch"
12436 (if_then_else (match_operator 1 "branch_comparison_operator"
12437 [(match_operand 2 "cc_reg_operand" "y")
12439 (label_ref (match_operand 0))
12443 return output_cbranch (operands[1], "%l0", 0, insn);
12445 [(set_attr "type" "branch")
12446 (set (attr "length")
12447 (if_then_else (and (ge (minus (match_dup 0) (pc))
12448 (const_int -32768))
12449 (lt (minus (match_dup 0) (pc))
12450 (const_int 32764)))
12454 (define_insn_and_split "*cbranch_2insn"
12456 (if_then_else (match_operator 1 "extra_insn_branch_comparison_operator"
12457 [(match_operand 2 "cc_reg_operand" "y")
12459 (label_ref (match_operand 0))
12461 "!flag_finite_math_only"
12466 rtx cc = rs6000_emit_fp_cror (GET_CODE (operands[1]), SImode, operands[2]);
12468 rtx note = find_reg_note (curr_insn, REG_BR_PROB, 0);
12470 rtx loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands[0]);
12471 rtx cond = gen_rtx_EQ (CCEQmode, cc, const0_rtx);
12472 rtx ite = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, loc_ref, pc_rtx);
12473 emit_jump_insn (gen_rtx_SET (pc_rtx, ite));
12477 profile_probability prob
12478 = profile_probability::from_reg_br_prob_note (XINT (note, 0));
12480 add_reg_br_prob_note (get_last_insn (), prob);
12485 [(set_attr "type" "branch")
12486 (set (attr "length")
12487 (if_then_else (and (ge (minus (match_dup 0) (pc))
12488 (const_int -32764))
12489 (lt (minus (match_dup 0) (pc))
12490 (const_int 32760)))
12494 ;; Conditional return.
12495 (define_insn "*creturn"
12497 (if_then_else (match_operator 0 "branch_comparison_operator"
12498 [(match_operand 1 "cc_reg_operand" "y")
12504 return output_cbranch (operands[0], NULL, 0, insn);
12506 [(set_attr "type" "jmpreg")])
12508 ;; Logic on condition register values.
12510 ; This pattern matches things like
12511 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12512 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12514 ; which are generated by the branch logic.
12515 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12517 (define_insn "@cceq_ior_compare_<mode>"
12518 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12519 (compare:CCEQ (match_operator:GPR 1 "boolean_operator"
12520 [(match_operator:GPR 2
12521 "branch_positive_comparison_operator"
12523 "cc_reg_operand" "y,y")
12525 (match_operator:GPR 4
12526 "branch_positive_comparison_operator"
12528 "cc_reg_operand" "0,y")
12532 "cr%q1 %E0,%j2,%j4"
12533 [(set_attr "type" "cr_logical")
12534 (set_attr "cr_logical_3op" "no,yes")])
12536 ; Why is the constant -1 here, but 1 in the previous pattern?
12537 ; Because ~1 has all but the low bit set.
12538 (define_insn "cceq_ior_compare_complement"
12539 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12540 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12541 [(not:SI (match_operator:SI 2
12542 "branch_positive_comparison_operator"
12544 "cc_reg_operand" "y,y")
12546 (match_operator:SI 4
12547 "branch_positive_comparison_operator"
12549 "cc_reg_operand" "0,y")
12553 "cr%q1 %E0,%j2,%j4"
12554 [(set_attr "type" "cr_logical")
12555 (set_attr "cr_logical_3op" "no,yes")])
12557 (define_insn "@cceq_rev_compare_<mode>"
12558 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12559 (compare:CCEQ (match_operator:GPR 1
12560 "branch_positive_comparison_operator"
12562 "cc_reg_operand" "0,y")
12567 [(set_attr "type" "cr_logical")
12568 (set_attr "cr_logical_3op" "no,yes")])
12570 ;; If we are comparing the result of two comparisons, this can be done
12571 ;; using creqv or crxor.
12573 (define_insn_and_split ""
12574 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12575 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12576 [(match_operand 2 "cc_reg_operand" "y")
12578 (match_operator 3 "branch_comparison_operator"
12579 [(match_operand 4 "cc_reg_operand" "y")
12584 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12587 int positive_1, positive_2;
12589 positive_1 = branch_positive_comparison_operator (operands[1],
12590 GET_MODE (operands[1]));
12591 positive_2 = branch_positive_comparison_operator (operands[3],
12592 GET_MODE (operands[3]));
12595 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12596 GET_CODE (operands[1])),
12598 operands[2], const0_rtx);
12599 else if (GET_MODE (operands[1]) != SImode)
12600 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12601 operands[2], const0_rtx);
12604 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12605 GET_CODE (operands[3])),
12607 operands[4], const0_rtx);
12608 else if (GET_MODE (operands[3]) != SImode)
12609 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12610 operands[4], const0_rtx);
12612 if (positive_1 == positive_2)
12614 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12615 operands[5] = constm1_rtx;
12619 operands[5] = const1_rtx;
12623 ;; Unconditional branch and return.
12625 (define_insn "jump"
12627 (label_ref (match_operand 0)))]
12630 [(set_attr "type" "branch")])
12632 (define_insn "<return_str>return"
12636 [(set_attr "type" "jmpreg")])
12638 (define_expand "indirect_jump"
12639 [(set (pc) (match_operand 0 "register_operand"))]
12642 if (!rs6000_speculate_indirect_jumps) {
12643 rtx ccreg = gen_reg_rtx (CCmode);
12644 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12649 (define_insn "*indirect_jump<mode>"
12651 (match_operand:P 0 "register_operand" "c,*l"))]
12652 "rs6000_speculate_indirect_jumps"
12654 [(set_attr "type" "jmpreg")])
12656 (define_insn "@indirect_jump<mode>_nospec"
12657 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12658 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12659 "!rs6000_speculate_indirect_jumps"
12660 "crset %E1\;beq%T0- %1\;b $"
12661 [(set_attr "type" "jmpreg")
12662 (set_attr "length" "12")])
12664 ;; Table jump for switch statements:
12665 (define_expand "tablejump"
12666 [(use (match_operand 0))
12667 (use (label_ref (match_operand 1)))]
12670 if (rs6000_speculate_indirect_jumps)
12673 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12675 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12679 rtx ccreg = gen_reg_rtx (CCmode);
12682 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12684 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12685 emit_jump_insn (jump);
12690 (define_expand "tablejumpsi"
12691 [(set (match_dup 3)
12692 (plus:SI (match_operand:SI 0)
12694 (parallel [(set (pc)
12696 (use (label_ref (match_operand 1)))])]
12697 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12699 operands[0] = force_reg (SImode, operands[0]);
12700 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12701 operands[3] = gen_reg_rtx (SImode);
12704 (define_expand "tablejumpsi_nospec"
12705 [(set (match_dup 4)
12706 (plus:SI (match_operand:SI 0)
12708 (parallel [(set (pc)
12710 (use (label_ref (match_operand 1)))
12711 (clobber (match_operand 2))])]
12712 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12714 operands[0] = force_reg (SImode, operands[0]);
12715 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12716 operands[4] = gen_reg_rtx (SImode);
12719 (define_expand "tablejumpdi"
12720 [(set (match_dup 4)
12721 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12723 (plus:DI (match_dup 4)
12725 (parallel [(set (pc)
12727 (use (label_ref (match_operand 1)))])]
12728 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12730 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12731 operands[3] = gen_reg_rtx (DImode);
12732 operands[4] = gen_reg_rtx (DImode);
12735 (define_expand "tablejumpdi_nospec"
12736 [(set (match_dup 5)
12737 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12739 (plus:DI (match_dup 5)
12741 (parallel [(set (pc)
12743 (use (label_ref (match_operand 1)))
12744 (clobber (match_operand 2))])]
12745 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12747 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12748 operands[4] = gen_reg_rtx (DImode);
12749 operands[5] = gen_reg_rtx (DImode);
12752 (define_insn "*tablejump<mode>_internal1"
12754 (match_operand:P 0 "register_operand" "c,*l"))
12755 (use (label_ref (match_operand 1)))]
12756 "rs6000_speculate_indirect_jumps"
12758 [(set_attr "type" "jmpreg")])
12760 (define_insn "*tablejump<mode>_internal1_nospec"
12762 (match_operand:P 0 "register_operand" "c,*l"))
12763 (use (label_ref (match_operand 1)))
12764 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12765 "!rs6000_speculate_indirect_jumps"
12766 "crset %E2\;beq%T0- %2\;b $"
12767 [(set_attr "type" "jmpreg")
12768 (set_attr "length" "12")])
12771 [(unspec [(const_int 0)] UNSPEC_NOP)]
12775 (define_insn "group_ending_nop"
12776 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12779 operands[0] = gen_rtx_REG (Pmode,
12780 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12781 return "ori %0,%0,0";
12784 (define_insn "speculation_barrier"
12785 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12788 operands[0] = gen_rtx_REG (Pmode, 31);
12789 return "ori %0,%0,0";
12792 ;; Define the subtract-one-and-jump insns, starting with the template
12793 ;; so loop.c knows what to generate.
12795 (define_expand "doloop_end"
12796 [(use (match_operand 0)) ; loop pseudo
12797 (use (match_operand 1))] ; label
12800 if (GET_MODE (operands[0]) != Pmode)
12803 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12807 (define_expand "@ctr<mode>"
12808 [(parallel [(set (pc)
12809 (if_then_else (ne (match_operand:P 0 "register_operand")
12811 (label_ref (match_operand 1))
12814 (plus:P (match_dup 0)
12816 (clobber (match_scratch:CC 2))
12817 (clobber (match_scratch:P 3))])]
12821 ;; We need to be able to do this for any operand, including MEM, or we
12822 ;; will cause reload to blow up since we don't allow output reloads on
12824 ;; For the length attribute to be calculated correctly, the
12825 ;; label MUST be operand 0.
12826 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12827 ;; the ctr<mode> insns.
12829 (define_code_iterator eqne [eq ne])
12830 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12831 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12833 (define_insn "<bd>_<mode>"
12835 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12837 (label_ref (match_operand 0))
12839 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12840 (plus:P (match_dup 1)
12842 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12843 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12846 if (which_alternative != 0)
12848 else if (get_attr_length (insn) == 4)
12851 return "<bd_neg> $+8\;b %l0";
12853 [(set_attr "type" "branch")
12854 (set_attr_alternative "length"
12855 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12856 (const_int -32768))
12857 (lt (minus (match_dup 0) (pc))
12858 (const_int 32764)))
12861 (const_string "16")
12862 (const_string "20")
12863 (const_string "20")])])
12865 ;; Now the splitter if we could not allocate the CTR register
12868 (if_then_else (match_operator 2 "comparison_operator"
12869 [(match_operand:P 1 "gpc_reg_operand")
12872 (match_operand 6)))
12873 (set (match_operand:P 0 "nonimmediate_operand")
12874 (plus:P (match_dup 1)
12876 (clobber (match_scratch:CC 3))
12877 (clobber (match_scratch:P 4))]
12880 (if_then_else (match_dup 7)
12884 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12886 emit_insn (gen_rtx_SET (operands[3],
12887 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12888 if (int_reg_operand (operands[0], <MODE>mode))
12889 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12892 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12893 emit_move_insn (operands[0], operands[4]);
12895 /* No DONE so branch comes from the pattern. */
12898 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12899 ;; Note that in the case of long branches we have to decompose this into
12900 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12901 ;; and the CR bit, which means there is no way to conveniently invert the
12902 ;; comparison as is done with plain bdnz/bdz.
12904 (define_insn "<bd>tf_<mode>"
12908 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12910 (match_operator 3 "branch_comparison_operator"
12911 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12913 (label_ref (match_operand 0))
12915 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12916 (plus:P (match_dup 1)
12918 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12919 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12920 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12923 if (which_alternative != 0)
12925 else if (get_attr_length (insn) == 4)
12927 if (branch_positive_comparison_operator (operands[3],
12928 GET_MODE (operands[3])))
12929 return "<bd>t %j3,%l0";
12931 return "<bd>f %j3,%l0";
12935 static char seq[96];
12936 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12937 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12941 [(set_attr "type" "branch")
12942 (set_attr_alternative "length"
12943 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12944 (const_int -32768))
12945 (lt (minus (match_dup 0) (pc))
12946 (const_int 32764)))
12949 (const_string "16")
12950 (const_string "20")
12951 (const_string "20")])])
12953 ;; Now the splitter if we could not allocate the CTR register
12958 (match_operator 1 "comparison_operator"
12959 [(match_operand:P 0 "gpc_reg_operand")
12961 (match_operator 3 "branch_comparison_operator"
12962 [(match_operand 2 "cc_reg_operand")
12965 (match_operand 5)))
12966 (set (match_operand:P 6 "nonimmediate_operand")
12967 (plus:P (match_dup 0)
12969 (clobber (match_scratch:P 7))
12970 (clobber (match_scratch:CC 8))
12971 (clobber (match_scratch:CCEQ 9))]
12975 rtx ctr = operands[0];
12976 rtx ctrcmp = operands[1];
12977 rtx ccin = operands[2];
12978 rtx cccmp = operands[3];
12979 rtx dst1 = operands[4];
12980 rtx dst2 = operands[5];
12981 rtx ctrout = operands[6];
12982 rtx ctrtmp = operands[7];
12983 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12984 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12986 cmpcode = reverse_condition (cmpcode);
12987 /* Generate crand/crandc here. */
12988 emit_insn (gen_rtx_SET (operands[8],
12989 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12990 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12992 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12994 emit_insn (gen_cceq_ior_compare (SImode, operands[9], andexpr, ctrcmpcc,
12995 operands[8], cccmp, ccin));
12997 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12998 operands[8], cccmp, ccin));
12999 if (int_reg_operand (ctrout, <MODE>mode))
13000 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
13003 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
13004 emit_move_insn (ctrout, ctrtmp);
13006 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
13007 emit_jump_insn (gen_rtx_SET (pc_rtx,
13008 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
13014 (define_insn "trap"
13015 [(trap_if (const_int 1) (const_int 0))]
13018 [(set_attr "type" "trap")])
13020 (define_expand "ctrap<mode>4"
13021 [(trap_if (match_operator 0 "ordered_comparison_operator"
13022 [(match_operand:GPR 1 "register_operand")
13023 (match_operand:GPR 2 "reg_or_short_operand")])
13024 (match_operand 3 "zero_constant" ""))]
13029 [(trap_if (match_operator 0 "ordered_comparison_operator"
13030 [(match_operand:GPR 1 "register_operand" "r")
13031 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13034 "t<wd>%V0%I2 %1,%2"
13035 [(set_attr "type" "trap")])
13037 ;; Insns related to generating the function prologue and epilogue.
13039 (define_expand "prologue"
13040 [(use (const_int 0))]
13043 rs6000_emit_prologue ();
13044 if (!TARGET_SCHED_PROLOG)
13045 emit_insn (gen_blockage ());
13049 (define_insn "*movesi_from_cr_one"
13050 [(match_parallel 0 "mfcr_operation"
13051 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13052 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13053 (match_operand 3 "immediate_operand" "n")]
13054 UNSPEC_MOVESI_FROM_CR))])]
13059 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13061 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13062 operands[4] = GEN_INT (mask);
13063 output_asm_insn ("mfcr %1,%4", operands);
13067 [(set_attr "type" "mfcrf")])
13069 ;; Don't include the volatile CRs since their values are not used wrt CR save
13070 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13071 ;; prologue past an insn (early exit test) that defines a register used in the
13073 (define_insn "prologue_movesi_from_cr"
13074 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13075 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13076 (reg:CC CR4_REGNO)]
13077 UNSPEC_MOVESI_FROM_CR))]
13080 [(set_attr "type" "mfcr")])
13082 (define_insn "*crsave"
13083 [(match_parallel 0 "crsave_operation"
13084 [(set (match_operand:SI 1 "memory_operand" "=m")
13085 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13088 [(set_attr "type" "store")])
13090 (define_insn "*stmw"
13091 [(match_parallel 0 "stmw_operation"
13092 [(set (match_operand:SI 1 "memory_operand" "=m")
13093 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13096 [(set_attr "type" "store")
13097 (set_attr "update" "yes")
13098 (set_attr "indexed" "yes")])
13100 ; The following comment applies to:
13104 ; return_and_restore_gpregs*
13105 ; return_and_restore_fpregs*
13106 ; return_and_restore_fpregs_aix*
13108 ; The out-of-line save / restore functions expects one input argument.
13109 ; Since those are not standard call_insn's, we must avoid using
13110 ; MATCH_OPERAND for that argument. That way the register rename
13111 ; optimization will not try to rename this register.
13112 ; Each pattern is repeated for each possible register number used in
13113 ; various ABIs (r11, r1, and for some functions r12)
13115 (define_insn "*save_gpregs_<mode>_r11"
13116 [(match_parallel 0 "any_parallel_operand"
13117 [(clobber (reg:P LR_REGNO))
13118 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13120 (set (match_operand:P 2 "memory_operand" "=m")
13121 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13124 [(set_attr "type" "branch")])
13126 (define_insn "*save_gpregs_<mode>_r12"
13127 [(match_parallel 0 "any_parallel_operand"
13128 [(clobber (reg:P LR_REGNO))
13129 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13131 (set (match_operand:P 2 "memory_operand" "=m")
13132 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13135 [(set_attr "type" "branch")])
13137 (define_insn "*save_gpregs_<mode>_r1"
13138 [(match_parallel 0 "any_parallel_operand"
13139 [(clobber (reg:P LR_REGNO))
13140 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13142 (set (match_operand:P 2 "memory_operand" "=m")
13143 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13146 [(set_attr "type" "branch")])
13148 (define_insn "*save_fpregs_<mode>_r11"
13149 [(match_parallel 0 "any_parallel_operand"
13150 [(clobber (reg:P LR_REGNO))
13151 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13153 (set (match_operand:DF 2 "memory_operand" "=m")
13154 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13157 [(set_attr "type" "branch")])
13159 (define_insn "*save_fpregs_<mode>_r12"
13160 [(match_parallel 0 "any_parallel_operand"
13161 [(clobber (reg:P LR_REGNO))
13162 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13164 (set (match_operand:DF 2 "memory_operand" "=m")
13165 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13168 [(set_attr "type" "branch")])
13170 (define_insn "*save_fpregs_<mode>_r1"
13171 [(match_parallel 0 "any_parallel_operand"
13172 [(clobber (reg:P LR_REGNO))
13173 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13175 (set (match_operand:DF 2 "memory_operand" "=m")
13176 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13179 [(set_attr "type" "branch")])
13181 ; This is to explain that changes to the stack pointer should
13182 ; not be moved over loads from or stores to stack memory.
13183 (define_insn "stack_tie"
13184 [(match_parallel 0 "tie_operand"
13185 [(set (mem:BLK (reg 1)) (const_int 0))])]
13188 [(set_attr "length" "0")])
13190 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13191 ; stay behind all restores from the stack, it cannot be reordered to before
13192 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13193 (define_insn "stack_restore_tie"
13194 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13195 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13196 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13197 (set (mem:BLK (scratch)) (const_int 0))]
13202 [(set_attr "type" "*,add")])
13204 (define_expand "epilogue"
13205 [(use (const_int 0))]
13208 if (!TARGET_SCHED_PROLOG)
13209 emit_insn (gen_blockage ());
13210 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
13214 ; On some processors, doing the mtcrf one CC register at a time is
13215 ; faster (like on the 604e). On others, doing them all at once is
13216 ; faster; for instance, on the 601 and 750.
13218 (define_expand "movsi_to_cr_one"
13219 [(set (match_operand:CC 0 "cc_reg_operand")
13220 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13221 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13223 "operands[2] = GEN_INT (1 << (7 - (REGNO (operands[0]) - CR0_REGNO)));")
13225 (define_insn "*movsi_to_cr"
13226 [(match_parallel 0 "mtcrf_operation"
13227 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13228 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13229 (match_operand 3 "immediate_operand" "n")]
13230 UNSPEC_MOVESI_TO_CR))])]
13235 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13236 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13237 operands[4] = GEN_INT (mask);
13238 return "mtcrf %4,%2";
13240 [(set_attr "type" "mtcr")])
13242 (define_insn "*mtcrfsi"
13243 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13244 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13245 (match_operand 2 "immediate_operand" "n")]
13246 UNSPEC_MOVESI_TO_CR))]
13247 "REG_P (operands[0])
13248 && CR_REGNO_P (REGNO (operands[0]))
13249 && CONST_INT_P (operands[2])
13250 && INTVAL (operands[2]) == 1 << (7 - (REGNO (operands[0]) - CR0_REGNO))"
13252 [(set_attr "type" "mtcr")])
13254 ; The load-multiple instructions have similar properties.
13255 ; Note that "load_multiple" is a name known to the machine-independent
13256 ; code that actually corresponds to the PowerPC load-string.
13258 (define_insn "*lmw"
13259 [(match_parallel 0 "lmw_operation"
13260 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13261 (match_operand:SI 2 "memory_operand" "m"))])]
13264 [(set_attr "type" "load")
13265 (set_attr "update" "yes")
13266 (set_attr "indexed" "yes")
13267 (set_attr "cell_micro" "always")])
13269 ; FIXME: "any_parallel_operand" is a bit flexible...
13271 ; The following comment applies to:
13275 ; return_and_restore_gpregs*
13276 ; return_and_restore_fpregs*
13277 ; return_and_restore_fpregs_aix*
13279 ; The out-of-line save / restore functions expects one input argument.
13280 ; Since those are not standard call_insn's, we must avoid using
13281 ; MATCH_OPERAND for that argument. That way the register rename
13282 ; optimization will not try to rename this register.
13283 ; Each pattern is repeated for each possible register number used in
13284 ; various ABIs (r11, r1, and for some functions r12)
13286 (define_insn "*restore_gpregs_<mode>_r11"
13287 [(match_parallel 0 "any_parallel_operand"
13288 [(clobber (reg:P LR_REGNO))
13289 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13291 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13292 (match_operand:P 3 "memory_operand" "m"))])]
13295 [(set_attr "type" "branch")])
13297 (define_insn "*restore_gpregs_<mode>_r12"
13298 [(match_parallel 0 "any_parallel_operand"
13299 [(clobber (reg:P LR_REGNO))
13300 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13302 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13303 (match_operand:P 3 "memory_operand" "m"))])]
13306 [(set_attr "type" "branch")])
13308 (define_insn "*restore_gpregs_<mode>_r1"
13309 [(match_parallel 0 "any_parallel_operand"
13310 [(clobber (reg:P LR_REGNO))
13311 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13313 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13314 (match_operand:P 3 "memory_operand" "m"))])]
13317 [(set_attr "type" "branch")])
13319 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13320 [(match_parallel 0 "any_parallel_operand"
13322 (clobber (reg:P LR_REGNO))
13323 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13325 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13326 (match_operand:P 3 "memory_operand" "m"))])]
13329 [(set_attr "type" "branch")])
13331 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13332 [(match_parallel 0 "any_parallel_operand"
13334 (clobber (reg:P LR_REGNO))
13335 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13337 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13338 (match_operand:P 3 "memory_operand" "m"))])]
13341 [(set_attr "type" "branch")])
13343 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13344 [(match_parallel 0 "any_parallel_operand"
13346 (clobber (reg:P LR_REGNO))
13347 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13349 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13350 (match_operand:P 3 "memory_operand" "m"))])]
13353 [(set_attr "type" "branch")])
13355 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13356 [(match_parallel 0 "any_parallel_operand"
13358 (clobber (reg:P LR_REGNO))
13359 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13361 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13362 (match_operand:DF 3 "memory_operand" "m"))])]
13365 [(set_attr "type" "branch")])
13367 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13368 [(match_parallel 0 "any_parallel_operand"
13370 (clobber (reg:P LR_REGNO))
13371 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13373 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13374 (match_operand:DF 3 "memory_operand" "m"))])]
13377 [(set_attr "type" "branch")])
13379 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13380 [(match_parallel 0 "any_parallel_operand"
13382 (clobber (reg:P LR_REGNO))
13383 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13385 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13386 (match_operand:DF 3 "memory_operand" "m"))])]
13389 [(set_attr "type" "branch")])
13391 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13392 [(match_parallel 0 "any_parallel_operand"
13394 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13396 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13397 (match_operand:DF 3 "memory_operand" "m"))])]
13400 [(set_attr "type" "branch")])
13402 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13403 [(match_parallel 0 "any_parallel_operand"
13405 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13407 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13408 (match_operand:DF 3 "memory_operand" "m"))])]
13411 [(set_attr "type" "branch")])
13413 ; This is used in compiling the unwind routines.
13414 (define_expand "eh_return"
13415 [(use (match_operand 0 "general_operand"))]
13418 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13422 ; We can't expand this before we know where the link register is stored.
13423 (define_insn_and_split "@eh_set_lr_<mode>"
13424 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13425 (clobber (match_scratch:P 1 "=&b"))]
13431 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13435 (define_insn "prefetch"
13436 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13437 (match_operand:SI 1 "const_int_operand" "n")
13438 (match_operand:SI 2 "const_int_operand" "n"))]
13443 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13444 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13445 The AIX assembler does not support the three operand form of dcbt
13446 and dcbtst on Power 7 (-mpwr7). */
13447 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13449 if (REG_P (operands[0]))
13451 if (INTVAL (operands[1]) == 0)
13452 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13454 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13458 if (INTVAL (operands[1]) == 0)
13459 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13461 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13464 [(set_attr "type" "load")])
13466 ;; Handle -fsplit-stack.
13468 (define_expand "split_stack_prologue"
13472 rs6000_expand_split_stack_prologue ();
13476 (define_expand "load_split_stack_limit"
13477 [(set (match_operand 0)
13478 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13481 emit_insn (gen_rtx_SET (operands[0],
13482 gen_rtx_UNSPEC (Pmode,
13483 gen_rtvec (1, const0_rtx),
13484 UNSPEC_STACK_CHECK)));
13488 (define_insn "load_split_stack_limit_di"
13489 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13490 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13492 "ld %0,-0x7040(13)"
13493 [(set_attr "type" "load")
13494 (set_attr "update" "no")
13495 (set_attr "indexed" "no")])
13497 (define_insn "load_split_stack_limit_si"
13498 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13499 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13501 "lwz %0,-0x7020(2)"
13502 [(set_attr "type" "load")
13503 (set_attr "update" "no")
13504 (set_attr "indexed" "no")])
13506 ;; A return instruction which the middle-end doesn't see.
13507 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13508 ;; after the call to __morestack.
13509 (define_insn "split_stack_return"
13510 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13513 [(set_attr "type" "jmpreg")])
13515 ;; If there are operand 0 bytes available on the stack, jump to
13517 (define_expand "split_stack_space_check"
13518 [(set (match_dup 2)
13519 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13521 (minus (reg STACK_POINTER_REGNUM)
13522 (match_operand 0)))
13523 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13524 (set (pc) (if_then_else
13525 (geu (match_dup 4) (const_int 0))
13526 (label_ref (match_operand 1))
13530 rs6000_split_stack_space_check (operands[0], operands[1]);
13534 (define_insn "bpermd_<mode>"
13535 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13536 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13537 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13540 [(set_attr "type" "popcnt")])
13543 ;; Builtin fma support. Handle
13544 ;; Note that the conditions for expansion are in the FMA_F iterator.
13546 (define_expand "fma<mode>4"
13547 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13549 (match_operand:FMA_F 1 "gpc_reg_operand")
13550 (match_operand:FMA_F 2 "gpc_reg_operand")
13551 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13555 (define_insn "*fma<mode>4_fpr"
13556 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13558 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13559 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13560 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13561 "TARGET_HARD_FLOAT"
13563 fmadd<s> %0,%1,%2,%3
13564 xsmadda<sd>p %x0,%x1,%x2
13565 xsmaddm<sd>p %x0,%x1,%x3"
13566 [(set_attr "type" "fp")
13567 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13569 ; Altivec only has fma and nfms.
13570 (define_expand "fms<mode>4"
13571 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13573 (match_operand:FMA_F 1 "gpc_reg_operand")
13574 (match_operand:FMA_F 2 "gpc_reg_operand")
13575 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13576 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13579 (define_insn "*fms<mode>4_fpr"
13580 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13582 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13583 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13584 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13585 "TARGET_HARD_FLOAT"
13587 fmsub<s> %0,%1,%2,%3
13588 xsmsuba<sd>p %x0,%x1,%x2
13589 xsmsubm<sd>p %x0,%x1,%x3"
13590 [(set_attr "type" "fp")
13591 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13593 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13594 (define_expand "fnma<mode>4"
13595 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13598 (match_operand:FMA_F 1 "gpc_reg_operand")
13599 (match_operand:FMA_F 2 "gpc_reg_operand")
13600 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13601 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13604 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13605 (define_expand "fnms<mode>4"
13606 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13609 (match_operand:FMA_F 1 "gpc_reg_operand")
13610 (match_operand:FMA_F 2 "gpc_reg_operand")
13611 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13612 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13615 ; Not an official optab name, but used from builtins.
13616 (define_expand "nfma<mode>4"
13617 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13620 (match_operand:FMA_F 1 "gpc_reg_operand")
13621 (match_operand:FMA_F 2 "gpc_reg_operand")
13622 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13623 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13626 (define_insn "*nfma<mode>4_fpr"
13627 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13630 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13631 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13632 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13633 "TARGET_HARD_FLOAT"
13635 fnmadd<s> %0,%1,%2,%3
13636 xsnmadda<sd>p %x0,%x1,%x2
13637 xsnmaddm<sd>p %x0,%x1,%x3"
13638 [(set_attr "type" "fp")
13639 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13641 ; Not an official optab name, but used from builtins.
13642 (define_expand "nfms<mode>4"
13643 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13646 (match_operand:FMA_F 1 "gpc_reg_operand")
13647 (match_operand:FMA_F 2 "gpc_reg_operand")
13648 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13652 (define_insn "*nfmssf4_fpr"
13653 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13656 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13657 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13659 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13660 "TARGET_HARD_FLOAT"
13662 fnmsub<s> %0,%1,%2,%3
13663 xsnmsuba<sd>p %x0,%x1,%x2
13664 xsnmsubm<sd>p %x0,%x1,%x3"
13665 [(set_attr "type" "fp")
13666 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13668 (define_expand "rs6000_get_timebase"
13669 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13672 if (TARGET_POWERPC64)
13673 emit_insn (gen_rs6000_mftb_di (operands[0]));
13675 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13679 (define_insn "rs6000_get_timebase_ppc32"
13680 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13681 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13682 (clobber (match_scratch:SI 1 "=r"))
13683 (clobber (match_scratch:CC 2 "=y"))]
13684 "!TARGET_POWERPC64"
13686 if (WORDS_BIG_ENDIAN)
13689 return "mfspr %0,269\;"
13697 return "mftbu %0\;"
13706 return "mfspr %L0,269\;"
13714 return "mftbu %L0\;"
13721 [(set_attr "length" "20")])
13723 (define_insn "rs6000_mftb_<mode>"
13724 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13725 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13729 return "mfspr %0,268";
13735 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13736 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13737 (define_insn "rs6000_mffsl_hw"
13738 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13739 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13740 "TARGET_HARD_FLOAT"
13743 (define_expand "rs6000_mffsl"
13744 [(set (match_operand:DF 0 "gpc_reg_operand")
13745 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13746 "TARGET_HARD_FLOAT"
13748 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13749 otherwise fall back to the older mffs instruction to emulate the mffsl
13752 if (!TARGET_P9_MISC)
13754 rtx tmp1 = gen_reg_rtx (DFmode);
13756 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13757 instruction using the mffs instruction and masking the result. */
13758 emit_insn (gen_rs6000_mffs (tmp1));
13760 rtx tmp1di = simplify_gen_subreg (DImode, tmp1, DFmode, 0);
13761 rtx tmp2 = gen_reg_rtx (DImode);
13762 emit_insn (gen_anddi3 (tmp2, tmp1di, GEN_INT (0x70007f0ffLL)));
13764 rtx tmp2df = simplify_gen_subreg (DFmode, tmp2, DImode, 0);
13765 emit_move_insn (operands[0], tmp2df);
13769 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13773 (define_insn "rs6000_mffs"
13774 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13775 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13776 "TARGET_HARD_FLOAT"
13779 (define_insn "rs6000_mtfsf"
13780 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13781 (match_operand:DF 1 "gpc_reg_operand" "d")]
13783 "TARGET_HARD_FLOAT"
13786 (define_insn "rs6000_mtfsf_hi"
13787 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13788 (match_operand:DF 1 "gpc_reg_operand" "d")]
13790 "TARGET_HARD_FLOAT"
13794 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13795 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13796 ;; register that is being loaded. The fused ops must be physically adjacent.
13798 ;; On Power8 GPR loads, we try to use the register that is being load. The
13799 ;; peephole2 then gathers any other fused possibilities that it can find after
13800 ;; register allocation. If power9 fusion is selected, we also fuse floating
13801 ;; point loads/stores.
13803 ;; Find cases where the addis that feeds into a load instruction is either used
13804 ;; once or is the same as the target register, and replace it with the fusion
13808 [(set (match_operand:P 0 "base_reg_operand")
13809 (match_operand:P 1 "fusion_gpr_addis"))
13810 (set (match_operand:INT1 2 "base_reg_operand")
13811 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13813 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13817 expand_fusion_gpr_load (operands);
13821 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13824 (define_insn "*fusion_gpr_load_<mode>"
13825 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13826 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13827 UNSPEC_FUSION_GPR))]
13830 return emit_fusion_gpr_load (operands[0], operands[1]);
13832 [(set_attr "type" "load")
13833 (set_attr "length" "8")])
13836 ;; Optimize cases where we want to do a D-form load (register+offset) on
13837 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13842 ;; and we change this to:
13847 [(match_scratch:P 0 "b")
13848 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13849 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13850 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13852 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13853 [(set (match_dup 0)
13858 rtx tmp_reg = operands[0];
13859 rtx mem = operands[2];
13860 rtx addr = XEXP (mem, 0);
13861 rtx add_op0, add_op1, new_addr;
13863 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13864 add_op0 = XEXP (addr, 0);
13865 add_op1 = XEXP (addr, 1);
13866 gcc_assert (REG_P (add_op0));
13867 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13869 operands[4] = add_op1;
13870 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13873 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13874 ;; Altivec register, and the register allocator has generated:
13878 ;; and we change this to:
13883 [(match_scratch:P 0 "b")
13884 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13885 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13886 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13888 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13889 [(set (match_dup 0)
13894 rtx tmp_reg = operands[0];
13895 rtx mem = operands[3];
13896 rtx addr = XEXP (mem, 0);
13897 rtx add_op0, add_op1, new_addr;
13899 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13900 add_op0 = XEXP (addr, 0);
13901 add_op1 = XEXP (addr, 1);
13902 gcc_assert (REG_P (add_op0));
13903 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13905 operands[4] = add_op1;
13906 operands[5] = change_address (mem, <ALTIVEC_DFORM:MODE>mode, new_addr);
13910 ;; Miscellaneous ISA 2.06 (power7) instructions
13911 (define_insn "addg6s"
13912 [(set (match_operand:SI 0 "register_operand" "=r")
13913 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13914 (match_operand:SI 2 "register_operand" "r")]
13918 [(set_attr "type" "integer")])
13920 (define_insn "cdtbcd"
13921 [(set (match_operand:SI 0 "register_operand" "=r")
13922 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13926 [(set_attr "type" "integer")])
13928 (define_insn "cbcdtd"
13929 [(set (match_operand:SI 0 "register_operand" "=r")
13930 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13934 [(set_attr "type" "integer")])
13936 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13939 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13940 (UNSPEC_DIVEU "eu")])
13942 (define_insn "div<div_extend>_<mode>"
13943 [(set (match_operand:GPR 0 "register_operand" "=r")
13944 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13945 (match_operand:GPR 2 "register_operand" "r")]
13946 UNSPEC_DIV_EXTEND))]
13948 "div<wd><div_extend> %0,%1,%2"
13949 [(set_attr "type" "div")
13950 (set_attr "size" "<bits>")])
13953 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13955 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13956 (define_mode_attr FP128_64 [(TF "DF")
13961 (define_expand "unpack<mode>"
13962 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13964 [(match_operand:FMOVE128 1 "register_operand")
13965 (match_operand:QI 2 "const_0_to_1_operand")]
13966 UNSPEC_UNPACK_128BIT))]
13967 "FLOAT128_2REG_P (<MODE>mode)"
13970 (define_insn_and_split "unpack<mode>_dm"
13971 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13973 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13974 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13975 UNSPEC_UNPACK_128BIT))]
13976 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13978 "&& reload_completed"
13979 [(set (match_dup 0) (match_dup 3))]
13981 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13983 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13985 emit_note (NOTE_INSN_DELETED);
13989 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13991 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13993 (define_insn_and_split "unpack<mode>_nodm"
13994 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13996 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13997 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13998 UNSPEC_UNPACK_128BIT))]
13999 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14001 "&& reload_completed"
14002 [(set (match_dup 0) (match_dup 3))]
14004 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14006 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14008 emit_note (NOTE_INSN_DELETED);
14012 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14014 [(set_attr "type" "fp,fpstore")])
14016 (define_insn_and_split "pack<mode>"
14017 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
14019 [(match_operand:<FP128_64> 1 "register_operand" "d")
14020 (match_operand:<FP128_64> 2 "register_operand" "d")]
14021 UNSPEC_PACK_128BIT))]
14022 "FLOAT128_2REG_P (<MODE>mode)"
14024 "&& reload_completed"
14025 [(set (match_dup 3) (match_dup 1))
14026 (set (match_dup 4) (match_dup 2))]
14028 unsigned dest_hi = REGNO (operands[0]);
14029 unsigned dest_lo = dest_hi + 1;
14031 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14032 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14034 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14035 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14037 [(set_attr "type" "fp")
14038 (set_attr "length" "8")])
14040 (define_insn "unpack<mode>"
14041 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14042 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14043 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14044 UNSPEC_UNPACK_128BIT))]
14045 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14047 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14048 return ASM_COMMENT_START " xxpermdi to same register";
14050 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14051 return "xxpermdi %x0,%x1,%x1,%3";
14053 [(set_attr "type" "vecperm")])
14055 (define_insn "pack<mode>"
14056 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14057 (unspec:FMOVE128_VSX
14058 [(match_operand:DI 1 "register_operand" "wa")
14059 (match_operand:DI 2 "register_operand" "wa")]
14060 UNSPEC_PACK_128BIT))]
14062 "xxpermdi %x0,%x1,%x2,0"
14063 [(set_attr "type" "vecperm")])
14067 ;; ISA 2.08 IEEE 128-bit floating point support.
14069 (define_insn "add<mode>3"
14070 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14072 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14073 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14074 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14076 [(set_attr "type" "vecfloat")
14077 (set_attr "size" "128")])
14079 (define_insn "sub<mode>3"
14080 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14082 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14083 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14084 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14086 [(set_attr "type" "vecfloat")
14087 (set_attr "size" "128")])
14089 (define_insn "mul<mode>3"
14090 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14092 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14093 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14094 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14096 [(set_attr "type" "qmul")
14097 (set_attr "size" "128")])
14099 (define_insn "div<mode>3"
14100 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14102 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14103 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14104 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14106 [(set_attr "type" "vecdiv")
14107 (set_attr "size" "128")])
14109 (define_insn "sqrt<mode>2"
14110 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14112 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14113 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14115 [(set_attr "type" "vecdiv")
14116 (set_attr "size" "128")])
14118 (define_expand "copysign<mode>3"
14119 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14120 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14121 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14122 "FLOAT128_IEEE_P (<MODE>mode)"
14124 if (TARGET_FLOAT128_HW)
14125 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14128 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14133 (define_insn "copysign<mode>3_hard"
14134 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14136 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14137 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14139 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14140 "xscpsgnqp %0,%2,%1"
14141 [(set_attr "type" "vecmove")
14142 (set_attr "size" "128")])
14144 (define_insn "copysign<mode>3_soft"
14145 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14147 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14148 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14150 (clobber (match_scratch:IEEE128 3 "=&v"))]
14151 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14152 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14153 [(set_attr "type" "veccomplex")
14154 (set_attr "length" "8")])
14156 (define_insn "@neg<mode>2_hw"
14157 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14159 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14160 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14162 [(set_attr "type" "vecmove")
14163 (set_attr "size" "128")])
14166 (define_insn "@abs<mode>2_hw"
14167 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14169 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14170 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14172 [(set_attr "type" "vecmove")
14173 (set_attr "size" "128")])
14176 (define_insn "*nabs<mode>2_hw"
14177 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14180 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14181 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14183 [(set_attr "type" "vecmove")
14184 (set_attr "size" "128")])
14186 ;; Initially don't worry about doing fusion
14187 (define_insn "fma<mode>4_hw"
14188 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14190 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14191 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14192 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14193 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14194 "xsmaddqp %0,%1,%2"
14195 [(set_attr "type" "qmul")
14196 (set_attr "size" "128")])
14198 (define_insn "*fms<mode>4_hw"
14199 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14201 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14202 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14204 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14205 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14206 "xsmsubqp %0,%1,%2"
14207 [(set_attr "type" "qmul")
14208 (set_attr "size" "128")])
14210 (define_insn "*nfma<mode>4_hw"
14211 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14214 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14215 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14216 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14217 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14218 "xsnmaddqp %0,%1,%2"
14219 [(set_attr "type" "qmul")
14220 (set_attr "size" "128")])
14222 (define_insn "*nfms<mode>4_hw"
14223 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14226 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14227 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14229 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14230 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14231 "xsnmsubqp %0,%1,%2"
14232 [(set_attr "type" "qmul")
14233 (set_attr "size" "128")])
14235 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14236 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14237 (float_extend:IEEE128
14238 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14239 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14241 [(set_attr "type" "vecfloat")
14242 (set_attr "size" "128")])
14244 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14245 ;; point is a simple copy.
14246 (define_insn_and_split "extendkftf2"
14247 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14248 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14249 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14253 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14256 emit_note (NOTE_INSN_DELETED);
14259 [(set_attr "type" "*,veclogical")
14260 (set_attr "length" "0,4")])
14262 (define_insn_and_split "trunctfkf2"
14263 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14264 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14265 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14269 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14272 emit_note (NOTE_INSN_DELETED);
14275 [(set_attr "type" "*,veclogical")
14276 (set_attr "length" "0,4")])
14278 (define_insn "trunc<mode>df2_hw"
14279 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14281 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14282 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14284 [(set_attr "type" "vecfloat")
14285 (set_attr "size" "128")])
14287 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14288 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14290 (define_insn_and_split "trunc<mode>sf2_hw"
14291 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14293 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14294 (clobber (match_scratch:DF 2 "=v"))]
14295 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14298 [(set (match_dup 2)
14299 (unspec:DF [(match_dup 1)]
14300 UNSPEC_TRUNC_ROUND_TO_ODD))
14302 (float_truncate:SF (match_dup 2)))]
14304 if (GET_CODE (operands[2]) == SCRATCH)
14305 operands[2] = gen_reg_rtx (DFmode);
14307 [(set_attr "type" "vecfloat")
14308 (set_attr "length" "8")
14309 (set_attr "isa" "p8v")])
14311 ;; Conversion between IEEE 128-bit and integer types
14313 ;; The fix function for DImode and SImode was declared earlier as a
14314 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14315 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14316 ;; unless we have the IEEE 128-bit hardware.
14318 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14319 ;; to provide a GPR target that used direct move and a conversion in the GPR
14320 ;; which works around QImode/HImode not being allowed in vector registers in
14321 ;; ISA 2.07 (power8).
14322 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14323 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14324 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14325 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14326 "xscvqp<su><wd>z %0,%1"
14327 [(set_attr "type" "vecfloat")
14328 (set_attr "size" "128")])
14330 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14331 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14333 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14334 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14335 "xscvqp<su>wz %0,%1"
14336 [(set_attr "type" "vecfloat")
14337 (set_attr "size" "128")])
14339 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14340 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14341 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14342 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14344 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14345 (clobber (match_scratch:QHSI 2 "=v"))]
14346 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14348 "&& reload_completed"
14349 [(set (match_dup 2)
14350 (any_fix:QHSI (match_dup 1)))
14354 (define_insn "float_<mode>di2_hw"
14355 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14356 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14357 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14359 [(set_attr "type" "vecfloat")
14360 (set_attr "size" "128")])
14362 (define_insn_and_split "float_<mode>si2_hw"
14363 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14364 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14365 (clobber (match_scratch:DI 2 "=v"))]
14366 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14369 [(set (match_dup 2)
14370 (sign_extend:DI (match_dup 1)))
14372 (float:IEEE128 (match_dup 2)))]
14374 if (GET_CODE (operands[2]) == SCRATCH)
14375 operands[2] = gen_reg_rtx (DImode);
14377 if (MEM_P (operands[1]))
14378 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14381 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14382 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14383 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14384 (clobber (match_scratch:DI 2 "=X,r,X"))]
14385 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14387 "&& reload_completed"
14390 rtx dest = operands[0];
14391 rtx src = operands[1];
14392 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14394 if (altivec_register_operand (src, <QHI:MODE>mode))
14395 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14396 else if (int_reg_operand (src, <QHI:MODE>mode))
14398 rtx ext_di = operands[2];
14399 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14400 emit_move_insn (dest_di, ext_di);
14402 else if (MEM_P (src))
14404 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14405 emit_move_insn (dest_qhi, src);
14406 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14409 gcc_unreachable ();
14411 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14414 [(set_attr "length" "8,12,12")
14415 (set_attr "type" "vecfloat")
14416 (set_attr "size" "128")])
14418 (define_insn "floatuns_<mode>di2_hw"
14419 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14420 (unsigned_float:IEEE128
14421 (match_operand:DI 1 "altivec_register_operand" "v")))]
14422 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14424 [(set_attr "type" "vecfloat")
14425 (set_attr "size" "128")])
14427 (define_insn_and_split "floatuns_<mode>si2_hw"
14428 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14429 (unsigned_float:IEEE128
14430 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14431 (clobber (match_scratch:DI 2 "=v"))]
14432 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14435 [(set (match_dup 2)
14436 (zero_extend:DI (match_dup 1)))
14438 (float:IEEE128 (match_dup 2)))]
14440 if (GET_CODE (operands[2]) == SCRATCH)
14441 operands[2] = gen_reg_rtx (DImode);
14443 if (MEM_P (operands[1]))
14444 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14447 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14448 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14449 (unsigned_float:IEEE128
14450 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14451 (clobber (match_scratch:DI 2 "=X,r,X"))]
14452 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14454 "&& reload_completed"
14457 rtx dest = operands[0];
14458 rtx src = operands[1];
14459 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14461 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14462 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14463 else if (int_reg_operand (src, <QHI:MODE>mode))
14465 rtx ext_di = operands[2];
14466 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14467 emit_move_insn (dest_di, ext_di);
14470 gcc_unreachable ();
14472 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14475 [(set_attr "length" "8,12,8")
14476 (set_attr "type" "vecfloat")
14477 (set_attr "size" "128")])
14479 ;; IEEE 128-bit round to integer built-in functions
14480 (define_insn "floor<mode>2"
14481 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14483 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14485 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14487 [(set_attr "type" "vecfloat")
14488 (set_attr "size" "128")])
14490 (define_insn "ceil<mode>2"
14491 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14493 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14495 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14497 [(set_attr "type" "vecfloat")
14498 (set_attr "size" "128")])
14500 (define_insn "btrunc<mode>2"
14501 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14503 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14505 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14507 [(set_attr "type" "vecfloat")
14508 (set_attr "size" "128")])
14510 (define_insn "round<mode>2"
14511 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14513 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14515 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14517 [(set_attr "type" "vecfloat")
14518 (set_attr "size" "128")])
14520 ;; IEEE 128-bit instructions with round to odd semantics
14521 (define_insn "add<mode>3_odd"
14522 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14524 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14525 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14526 UNSPEC_ADD_ROUND_TO_ODD))]
14527 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14528 "xsaddqpo %0,%1,%2"
14529 [(set_attr "type" "vecfloat")
14530 (set_attr "size" "128")])
14532 (define_insn "sub<mode>3_odd"
14533 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14535 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14536 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14537 UNSPEC_SUB_ROUND_TO_ODD))]
14538 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14539 "xssubqpo %0,%1,%2"
14540 [(set_attr "type" "vecfloat")
14541 (set_attr "size" "128")])
14543 (define_insn "mul<mode>3_odd"
14544 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14546 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14547 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14548 UNSPEC_MUL_ROUND_TO_ODD))]
14549 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14550 "xsmulqpo %0,%1,%2"
14551 [(set_attr "type" "qmul")
14552 (set_attr "size" "128")])
14554 (define_insn "div<mode>3_odd"
14555 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14557 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14558 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14559 UNSPEC_DIV_ROUND_TO_ODD))]
14560 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14561 "xsdivqpo %0,%1,%2"
14562 [(set_attr "type" "vecdiv")
14563 (set_attr "size" "128")])
14565 (define_insn "sqrt<mode>2_odd"
14566 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14568 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14569 UNSPEC_SQRT_ROUND_TO_ODD))]
14570 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14572 [(set_attr "type" "vecdiv")
14573 (set_attr "size" "128")])
14575 (define_insn "fma<mode>4_odd"
14576 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14578 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14579 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14580 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14581 UNSPEC_FMA_ROUND_TO_ODD))]
14582 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14583 "xsmaddqpo %0,%1,%2"
14584 [(set_attr "type" "qmul")
14585 (set_attr "size" "128")])
14587 (define_insn "*fms<mode>4_odd"
14588 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14590 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14591 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14593 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14594 UNSPEC_FMA_ROUND_TO_ODD))]
14595 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14596 "xsmsubqpo %0,%1,%2"
14597 [(set_attr "type" "qmul")
14598 (set_attr "size" "128")])
14600 (define_insn "*nfma<mode>4_odd"
14601 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14604 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14605 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14606 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14607 UNSPEC_FMA_ROUND_TO_ODD)))]
14608 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14609 "xsnmaddqpo %0,%1,%2"
14610 [(set_attr "type" "qmul")
14611 (set_attr "size" "128")])
14613 (define_insn "*nfms<mode>4_odd"
14614 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14617 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14618 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14620 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14621 UNSPEC_FMA_ROUND_TO_ODD)))]
14622 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14623 "xsnmsubqpo %0,%1,%2"
14624 [(set_attr "type" "qmul")
14625 (set_attr "size" "128")])
14627 (define_insn "trunc<mode>df2_odd"
14628 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14629 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14630 UNSPEC_TRUNC_ROUND_TO_ODD))]
14631 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14633 [(set_attr "type" "vecfloat")
14634 (set_attr "size" "128")])
14636 ;; IEEE 128-bit comparisons
14637 (define_insn "*cmp<mode>_hw"
14638 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14639 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14640 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14641 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14642 "xscmpuqp %0,%1,%2"
14643 [(set_attr "type" "veccmp")
14644 (set_attr "size" "128")])
14646 ;; Miscellaneous ISA 3.0 (power9) instructions
14648 (define_insn "darn_32"
14649 [(set (match_operand:SI 0 "register_operand" "=r")
14650 (unspec_volatile:SI [(const_int 0)] UNSPECV_DARN_32))]
14653 [(set_attr "type" "integer")])
14655 (define_insn "darn_raw"
14656 [(set (match_operand:DI 0 "register_operand" "=r")
14657 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN_RAW))]
14658 "TARGET_P9_MISC && TARGET_64BIT"
14660 [(set_attr "type" "integer")])
14662 (define_insn "darn"
14663 [(set (match_operand:DI 0 "register_operand" "=r")
14664 (unspec_volatile:DI [(const_int 0)] UNSPECV_DARN))]
14665 "TARGET_P9_MISC && TARGET_64BIT"
14667 [(set_attr "type" "integer")])
14669 ;; Test byte within range.
14671 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14672 ;; represents a byte whose value is ignored in this context and
14673 ;; vv, the least significant byte, holds the byte value that is to
14674 ;; be tested for membership within the range specified by operand 2.
14675 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14677 ;; Return in target register operand 0 a value of 1 if lo <= vv and
14678 ;; vv <= hi. Otherwise, set register operand 0 to 0.
14680 ;; Though the instructions to which this expansion maps operate on
14681 ;; 64-bit registers, the current implementation only operates on
14682 ;; SI-mode operands as the high-order bits provide no information
14683 ;; that is not already available in the low-order bits. To avoid the
14684 ;; costs of data widening operations, future enhancements might allow
14685 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14686 (define_expand "cmprb"
14687 [(set (match_dup 3)
14688 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14689 (match_operand:SI 2 "gpc_reg_operand" "r")]
14691 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14692 (if_then_else:SI (lt (match_dup 3)
14695 (if_then_else (gt (match_dup 3)
14701 operands[3] = gen_reg_rtx (CCmode);
14704 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14705 ;; represents a byte whose value is ignored in this context and
14706 ;; vv, the least significant byte, holds the byte value that is to
14707 ;; be tested for membership within the range specified by operand 2.
14708 ;; The bytes of operand 2 are organized as xx:xx:hi:lo.
14710 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14711 ;; lo <= vv and vv <= hi. Otherwise, set the GT bit to 0. The other
14712 ;; 3 bits of the target CR register are all set to 0.
14713 (define_insn "*cmprb_internal"
14714 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14715 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14716 (match_operand:SI 2 "gpc_reg_operand" "r")]
14720 [(set_attr "type" "logical")])
14722 ;; Set operand 0 register to -1 if the LT bit (0x8) of condition
14723 ;; register operand 1 is on. Otherwise, set operand 0 register to 1
14724 ;; if the GT bit (0x4) of condition register operand 1 is on.
14725 ;; Otherwise, set operand 0 to 0. Note that the result stored into
14726 ;; register operand 0 is non-zero iff either the LT or GT bits are on
14727 ;; within condition register operand 1.
14728 (define_insn "setb_signed"
14729 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14730 (if_then_else:SI (lt (match_operand:CC 1 "cc_reg_operand" "y")
14733 (if_then_else (gt (match_dup 1)
14739 [(set_attr "type" "logical")])
14741 (define_insn "setb_unsigned"
14742 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
14743 (if_then_else:SI (ltu (match_operand:CCUNS 1 "cc_reg_operand" "y")
14746 (if_then_else (gtu (match_dup 1)
14752 [(set_attr "type" "logical")])
14754 ;; Test byte within two ranges.
14756 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14757 ;; represents a byte whose value is ignored in this context and
14758 ;; vv, the least significant byte, holds the byte value that is to
14759 ;; be tested for membership within the range specified by operand 2.
14760 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14762 ;; Return in target register operand 0 a value of 1 if (lo_1 <= vv and
14763 ;; vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2). Otherwise, set register
14766 ;; Though the instructions to which this expansion maps operate on
14767 ;; 64-bit registers, the current implementation only operates on
14768 ;; SI-mode operands as the high-order bits provide no information
14769 ;; that is not already available in the low-order bits. To avoid the
14770 ;; costs of data widening operations, future enhancements might allow
14771 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14772 (define_expand "cmprb2"
14773 [(set (match_dup 3)
14774 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14775 (match_operand:SI 2 "gpc_reg_operand" "r")]
14777 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14778 (if_then_else:SI (lt (match_dup 3)
14781 (if_then_else (gt (match_dup 3)
14787 operands[3] = gen_reg_rtx (CCmode);
14790 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14791 ;; represents a byte whose value is ignored in this context and
14792 ;; vv, the least significant byte, holds the byte value that is to
14793 ;; be tested for membership within the ranges specified by operand 2.
14794 ;; The bytes of operand 2 are organized as hi_1:lo_1:hi_2:lo_2.
14796 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if
14797 ;; (lo_1 <= vv and vv <= hi_1) or if (lo_2 <= vv and vv <= hi_2).
14798 ;; Otherwise, set the GT bit to 0. The other 3 bits of the target
14799 ;; CR register are all set to 0.
14800 (define_insn "*cmprb2_internal"
14801 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14802 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14803 (match_operand:SI 2 "gpc_reg_operand" "r")]
14807 [(set_attr "type" "logical")])
14809 ;; Test byte membership within set of 8 bytes.
14811 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14812 ;; represents a byte whose value is ignored in this context and
14813 ;; vv, the least significant byte, holds the byte value that is to
14814 ;; be tested for membership within the set specified by operand 2.
14815 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14817 ;; Return in target register operand 0 a value of 1 if vv equals one
14818 ;; of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise, set
14819 ;; register operand 0 to 0. Note that the 8 byte values held within
14820 ;; operand 2 need not be unique.
14822 ;; Though the instructions to which this expansion maps operate on
14823 ;; 64-bit registers, the current implementation requires that operands
14824 ;; 0 and 1 have mode SI as the high-order bits provide no information
14825 ;; that is not already available in the low-order bits. To avoid the
14826 ;; costs of data widening operations, future enhancements might allow
14827 ;; DI mode for operand 0 and/or might allow operand 1 to be QI mode.
14828 (define_expand "cmpeqb"
14829 [(set (match_dup 3)
14830 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14831 (match_operand:DI 2 "gpc_reg_operand" "r")]
14833 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
14834 (if_then_else:SI (lt (match_dup 3)
14837 (if_then_else (gt (match_dup 3)
14841 "TARGET_P9_MISC && TARGET_64BIT"
14843 operands[3] = gen_reg_rtx (CCmode);
14846 ;; The bytes of operand 1 are organized as xx:xx:xx:vv, where xx
14847 ;; represents a byte whose value is ignored in this context and
14848 ;; vv, the least significant byte, holds the byte value that is to
14849 ;; be tested for membership within the set specified by operand 2.
14850 ;; The bytes of operand 2 are organized as e0:e1:e2:e3:e4:e5:e6:e7.
14852 ;; Set bit 1 (the GT bit, 0x4) of CR register operand 0 to 1 if vv
14853 ;; equals one of the values e0, e1, e2, e3, e4, e5, e6, or e7. Otherwise,
14854 ;; set the GT bit to zero. The other 3 bits of the target CR register
14855 ;; are all set to 0.
14856 (define_insn "*cmpeqb_internal"
14857 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
14858 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
14859 (match_operand:DI 2 "gpc_reg_operand" "r")]
14861 "TARGET_P9_MISC && TARGET_64BIT"
14863 [(set_attr "type" "logical")])
14866 (include "sync.md")
14867 (include "vector.md")
14869 (include "altivec.md")
14872 (include "crypto.md")