1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2019 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_FRSP ; frsp for POWER machines
62 UNSPEC_PROBE_STACK ; probe stack memory reference
63 UNSPEC_TOCPTR ; address of a word pointing to the TOC
64 UNSPEC_TOC ; address of the TOC (more-or-less)
65 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
67 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
74 UNSPEC_LD_MPIC ; load_macho_picbase
75 UNSPEC_RELD_MPIC ; re-load_macho_picbase
76 UNSPEC_MPIC_CORRECT ; macho_correct_pic
91 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
109 UNSPEC_MACHOPIC_OFFSET
123 UNSPEC_P8V_RELOAD_FROM_GPR
126 UNSPEC_P8V_RELOAD_FROM_VSX
137 UNSPEC_ADD_ROUND_TO_ODD
138 UNSPEC_SUB_ROUND_TO_ODD
139 UNSPEC_MUL_ROUND_TO_ODD
140 UNSPEC_DIV_ROUND_TO_ODD
141 UNSPEC_FMA_ROUND_TO_ODD
142 UNSPEC_SQRT_ROUND_TO_ODD
143 UNSPEC_TRUNC_ROUND_TO_ODD
154 ;; UNSPEC_VOLATILE usage
157 (define_c_enum "unspecv"
159 UNSPECV_LL ; load-locked
160 UNSPECV_SC ; store-conditional
161 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
162 UNSPECV_EH_RR ; eh_reg_restore
163 UNSPECV_ISYNC ; isync instruction
164 UNSPECV_MFTB ; move from time base
165 UNSPECV_NLGR ; non-local goto receiver
166 UNSPECV_MFFS ; Move from FPSCR
167 UNSPECV_MFFSL ; Move from FPSCR light instruction version
168 UNSPECV_MFFSCRN ; Move from FPSCR float rounding mode
169 UNSPECV_MFFSCDRN ; Move from FPSCR decimal float rounding mode
170 UNSPECV_MTFSF ; Move to FPSCR Fields 8 to 15
171 UNSPECV_MTFSF_HI ; Move to FPSCR Fields 0 to 7
172 UNSPECV_MTFSB0 ; Set FPSCR Field bit to 0
173 UNSPECV_MTFSB1 ; Set FPSCR Field bit to 1
174 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
175 UNSPECV_SPEC_BARRIER ; Speculation barrier
178 ; The three different kinds of epilogue.
179 (define_enum "epilogue_type" [normal sibcall eh_return])
181 ;; Define an insn type attribute. This is used in function unit delay
185 add,logical,shift,insert,
187 exts,cntlz,popcnt,isel,
188 load,store,fpload,fpstore,vecload,vecstore,
190 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
191 cr_logical,mfcr,mfcrf,mtcr,
192 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
193 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
194 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
195 veclogical,veccmpfx,vecexts,vecmove,
197 (const_string "integer"))
199 ;; What data size does this instruction work on?
200 ;; This is used for insert, mul and others as necessary.
201 (define_attr "size" "8,16,32,64,128" (const_string "32"))
203 ;; What is the insn_cost for this insn? The target hook can still override
204 ;; this. For optimizing for size the "length" attribute is used instead.
205 (define_attr "cost" "" (const_int 0))
207 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
208 ;; This is used for add, logical, shift, exts, mul.
209 (define_attr "dot" "no,yes" (const_string "no"))
211 ;; Does this instruction sign-extend its result?
212 ;; This is used for load insns.
213 (define_attr "sign_extend" "no,yes" (const_string "no"))
215 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
216 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
218 ;; Does this instruction use indexed (that is, reg+reg) addressing?
219 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
220 ;; it is automatically set based on that. If a load or store instruction
221 ;; has fewer than two operands it needs to set this attribute manually
222 ;; or the compiler will crash.
223 (define_attr "indexed" "no,yes"
224 (if_then_else (ior (match_operand 0 "indexed_address_mem")
225 (match_operand 1 "indexed_address_mem"))
227 (const_string "no")))
229 ;; Does this instruction use update addressing?
230 ;; This is used for load and store insns. See the comments for "indexed".
231 (define_attr "update" "no,yes"
232 (if_then_else (ior (match_operand 0 "update_address_mem")
233 (match_operand 1 "update_address_mem"))
235 (const_string "no")))
237 ;; Is this instruction using operands[2] as shift amount, and can that be a
239 ;; This is used for shift insns.
240 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
242 ;; Is this instruction using a shift amount from a register?
243 ;; This is used for shift insns.
244 (define_attr "var_shift" "no,yes"
245 (if_then_else (and (eq_attr "type" "shift")
246 (eq_attr "maybe_var_shift" "yes"))
247 (if_then_else (match_operand 2 "gpc_reg_operand")
250 (const_string "no")))
252 ;; Is copying of this instruction disallowed?
253 (define_attr "cannot_copy" "no,yes" (const_string "no"))
255 ;; Length of the instruction (in bytes).
256 (define_attr "length" "" (const_int 4))
258 ;; Processor type -- this attribute must exactly match the processor_type
259 ;; enumeration in rs6000-opts.h.
261 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
262 ppc750,ppc7400,ppc7450,
263 ppc403,ppc405,ppc440,ppc476,
264 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
265 power4,power5,power6,power7,power8,power9,future,
266 rs64a,mpccore,cell,ppca2,titan"
267 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
269 ;; The ISA we implement.
270 (define_attr "isa" "any,p5,p6,p7,p7v,p8v,p9v,p9kf,p9tf,fut"
271 (const_string "any"))
273 ;; Is this alternative enabled for the current CPU/ISA/etc.?
274 (define_attr "enabled" ""
276 [(eq_attr "isa" "any")
279 (and (eq_attr "isa" "p5")
280 (match_test "TARGET_POPCNTB"))
283 (and (eq_attr "isa" "p6")
284 (match_test "TARGET_CMPB"))
287 (and (eq_attr "isa" "p7")
288 (match_test "TARGET_POPCNTD"))
291 (and (eq_attr "isa" "p7v")
292 (match_test "TARGET_VSX"))
295 (and (eq_attr "isa" "p8v")
296 (match_test "TARGET_P8_VECTOR"))
299 (and (eq_attr "isa" "p9v")
300 (match_test "TARGET_P9_VECTOR"))
303 (and (eq_attr "isa" "p9kf")
304 (match_test "TARGET_FLOAT128_TYPE"))
307 (and (eq_attr "isa" "p9tf")
308 (match_test "FLOAT128_VECTOR_P (TFmode)"))
311 (and (eq_attr "isa" "fut")
312 (match_test "TARGET_FUTURE"))
316 ;; If this instruction is microcoded on the CELL processor
317 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
318 (define_attr "cell_micro" "not,conditional,always"
319 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
320 (eq_attr "dot" "yes"))
321 (and (eq_attr "type" "load")
322 (eq_attr "sign_extend" "yes"))
323 (and (eq_attr "type" "shift")
324 (eq_attr "var_shift" "yes")))
325 (const_string "always")
326 (const_string "not")))
328 (automata_option "ndfa")
341 (include "e300c2c3.md")
342 (include "e500mc.md")
343 (include "e500mc64.md")
346 (include "power4.md")
347 (include "power5.md")
348 (include "power6.md")
349 (include "power7.md")
350 (include "power8.md")
351 (include "power9.md")
356 (include "predicates.md")
357 (include "constraints.md")
359 (include "darwin.md")
364 ; This mode iterator allows :GPR to be used to indicate the allowable size
365 ; of whole values in GPRs.
366 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
368 ; And again, for patterns that need two (potentially) different integer modes.
369 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
371 ; Any supported integer mode.
372 (define_mode_iterator INT [QI HI SI DI TI PTI])
374 ; Any supported integer mode that fits in one register.
375 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
377 ; Integer modes supported in VSX registers with ISA 3.0 instructions
378 (define_mode_iterator INT_ISA3 [QI HI SI DI])
380 ; Everything we can extend QImode to.
381 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
383 ; Everything we can extend HImode to.
384 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
386 ; Everything we can extend SImode to.
387 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
389 ; QImode or HImode for small integer moves and small atomic ops
390 (define_mode_iterator QHI [QI HI])
392 ; QImode, HImode, SImode for fused ops only for GPR loads
393 (define_mode_iterator QHSI [QI HI SI])
395 ; HImode or SImode for sign extended fusion ops
396 (define_mode_iterator HSI [HI SI])
398 ; SImode or DImode, even if DImode doesn't fit in GPRs.
399 (define_mode_iterator SDI [SI DI])
401 ; The size of a pointer. Also, the size of the value that a record-condition
402 ; (one with a '.') will compare; and the size used for arithmetic carries.
403 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
405 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
406 ; PTImode is GPR only)
407 (define_mode_iterator TI2 [TI PTI])
409 ; Any hardware-supported floating-point mode
410 (define_mode_iterator FP [
411 (SF "TARGET_HARD_FLOAT")
412 (DF "TARGET_HARD_FLOAT")
413 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
414 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
415 (KF "TARGET_FLOAT128_TYPE")
419 ; Any fma capable floating-point mode.
420 (define_mode_iterator FMA_F [
421 (SF "TARGET_HARD_FLOAT")
422 (DF "TARGET_HARD_FLOAT || VECTOR_UNIT_VSX_P (DFmode)")
423 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
424 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
425 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
426 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
429 ; Floating point move iterators to combine binary and decimal moves
430 (define_mode_iterator FMOVE32 [SF SD])
431 (define_mode_iterator FMOVE64 [DF DD])
432 (define_mode_iterator FMOVE64X [DI DF DD])
433 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
434 (IF "FLOAT128_IBM_P (IFmode)")
435 (TD "TARGET_HARD_FLOAT")])
437 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
438 (IF "FLOAT128_2REG_P (IFmode)")
439 (TD "TARGET_HARD_FLOAT")])
441 ; Iterators for 128 bit types for direct move
442 (define_mode_iterator FMOVE128_GPR [TI
450 (KF "FLOAT128_VECTOR_P (KFmode)")
451 (TF "FLOAT128_VECTOR_P (TFmode)")])
453 ; Iterator for 128-bit VSX types for pack/unpack
454 (define_mode_iterator FMOVE128_VSX [V1TI KF])
456 ; Iterators for converting to/from TFmode
457 (define_mode_iterator IFKF [IF KF])
459 ; Constraints for moving IF/KFmode.
460 (define_mode_attr IFKF_reg [(IF "d") (KF "wa")])
462 ; Whether a floating point move is ok, don't allow SD without hardware FP
463 (define_mode_attr fmove_ok [(SF "")
465 (SD "TARGET_HARD_FLOAT")
468 ; Convert REAL_VALUE to the appropriate bits
469 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
470 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
471 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
472 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
474 ; Whether 0.0 has an all-zero bit pattern
475 (define_mode_attr zero_fp [(SF "j")
484 ; Definitions for 64-bit VSX
485 (define_mode_attr f64_vsx [(DF "wa") (DD "wn")])
487 ; Definitions for 64-bit direct move
488 (define_mode_attr f64_dm [(DF "wa") (DD "d")])
490 ; Definitions for 64-bit use of altivec registers
491 (define_mode_attr f64_av [(DF "v") (DD "wn")])
493 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
494 (define_mode_attr f64_p9 [(DF "v") (DD "wn")])
496 ; These modes do not fit in integer registers in 32-bit mode.
497 (define_mode_iterator DIFD [DI DF DD])
499 ; Iterator for reciprocal estimate instructions
500 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
503 (define_mode_iterator SFDF [SF DF])
505 ; And again, for when we need two FP modes in a pattern.
506 (define_mode_iterator SFDF2 [SF DF])
508 ; A generic s/d attribute, for sp/dp for example.
509 (define_mode_attr sd [(SF "s") (DF "d")
510 (V4SF "s") (V2DF "d")])
512 ; "s" or nothing, for fmuls/fmul for example.
513 (define_mode_attr s [(SF "s") (DF "")])
515 ; Iterator for 128-bit floating point that uses the IBM double-double format
516 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
517 (TF "FLOAT128_IBM_P (TFmode)")])
519 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
520 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
521 (TF "FLOAT128_IEEE_P (TFmode)")])
523 ; Iterator for 128-bit floating point
524 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
525 (IF "TARGET_FLOAT128_TYPE")
526 (TF "TARGET_LONG_DOUBLE_128")])
528 ; Iterator for signbit on 64-bit machines with direct move
529 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
530 (TF "FLOAT128_VECTOR_P (TFmode)")])
532 ; Iterator for ISA 3.0 supported floating point types
533 (define_mode_iterator FP_ISA3 [SF DF])
535 ; SF/DF constraint for arithmetic on traditional floating point registers
536 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
538 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
539 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
540 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
542 (define_mode_attr Fv [(SF "wa") (DF "wa") (DI "wa")])
544 ; Which isa is needed for those float instructions?
545 (define_mode_attr Fisa [(SF "p8v") (DF "*") (DI "*")])
548 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
549 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
551 ; Conditional returns.
552 (define_code_iterator any_return [return simple_return])
553 (define_code_attr return_pred [(return "direct_return ()")
554 (simple_return "1")])
555 (define_code_attr return_str [(return "") (simple_return "simple_")])
558 (define_code_iterator iorxor [ior xor])
559 (define_code_iterator and_ior_xor [and ior xor])
561 ; Signed/unsigned variants of ops.
562 (define_code_iterator any_extend [sign_extend zero_extend])
563 (define_code_iterator any_fix [fix unsigned_fix])
564 (define_code_iterator any_float [float unsigned_float])
566 (define_code_attr u [(sign_extend "")
571 (define_code_attr su [(sign_extend "s")
576 (unsigned_float "u")])
578 (define_code_attr az [(sign_extend "a")
583 (unsigned_float "z")])
585 (define_code_attr uns [(fix "")
588 (unsigned_float "uns")])
590 ; Various instructions that come in SI and DI forms.
591 ; A generic w/d attribute, for things like cmpw/cmpd.
592 (define_mode_attr wd [(QI "b")
603 ;; How many bits in this mode?
604 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")
605 (SF "32") (DF "64")])
608 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
610 ;; Bitmask for shift instructions
611 (define_mode_attr hH [(SI "h") (DI "H")])
613 ;; A mode twice the size of the given mode
614 (define_mode_attr dmode [(SI "di") (DI "ti")])
615 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
617 ;; Suffix for reload patterns
618 (define_mode_attr ptrsize [(SI "32bit")
621 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
622 (DI "TARGET_64BIT")])
624 (define_mode_attr mptrsize [(SI "si")
627 (define_mode_attr ptrload [(SI "lwz")
630 (define_mode_attr ptrm [(SI "m")
633 (define_mode_attr rreg [(SF "f")
640 (define_mode_attr rreg2 [(SF "f")
643 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
644 (DF "TARGET_FCFID")])
646 ;; Mode iterator for logical operations on 128-bit types
647 (define_mode_iterator BOOL_128 [TI
649 (V16QI "TARGET_ALTIVEC")
650 (V8HI "TARGET_ALTIVEC")
651 (V4SI "TARGET_ALTIVEC")
652 (V4SF "TARGET_ALTIVEC")
653 (V2DI "TARGET_ALTIVEC")
654 (V2DF "TARGET_ALTIVEC")
655 (V1TI "TARGET_ALTIVEC")])
657 ;; For the GPRs we use 3 constraints for register outputs, two that are the
658 ;; same as the output register, and a third where the output register is an
659 ;; early clobber, so we don't have to deal with register overlaps. For the
660 ;; vector types, we prefer to use the vector registers. For TI mode, allow
663 ;; Mode attribute for boolean operation register constraints for output
664 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wa,v")
666 (V16QI "wa,v,&?r,?r,?r")
667 (V8HI "wa,v,&?r,?r,?r")
668 (V4SI "wa,v,&?r,?r,?r")
669 (V4SF "wa,v,&?r,?r,?r")
670 (V2DI "wa,v,&?r,?r,?r")
671 (V2DF "wa,v,&?r,?r,?r")
672 (V1TI "wa,v,&?r,?r,?r")])
674 ;; Mode attribute for boolean operation register constraints for operand1
675 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wa,v")
683 (V1TI "wa,v,r,0,r")])
685 ;; Mode attribute for boolean operation register constraints for operand2
686 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wa,v")
694 (V1TI "wa,v,r,r,0")])
696 ;; Mode attribute for boolean operation register constraints for operand1
697 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
698 ;; is used for operand1 or operand2
699 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wa,v")
707 (V1TI "wa,v,r,0,0")])
709 ;; Reload iterator for creating the function to allocate a base register to
710 ;; supplement addressing modes.
711 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
712 SF SD SI DF DD DI TI PTI KF IF TF])
714 ;; Iterate over smin, smax
715 (define_code_iterator fp_minmax [smin smax])
717 (define_code_attr minmax [(smin "min")
720 (define_code_attr SMINMAX [(smin "SMIN")
723 ;; Iterator to optimize the following cases:
724 ;; D-form load to FPR register & move to Altivec register
725 ;; Move Altivec register to FPR register and store
726 (define_mode_iterator ALTIVEC_DFORM [DF
727 (SF "TARGET_P8_VECTOR")
728 (DI "TARGET_POWERPC64")])
731 ;; Start with fixed-point load and store insns. Here we put only the more
732 ;; complex forms. Basic data transfer is done later.
734 (define_insn "zero_extendqi<mode>2"
735 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wa,^v")
736 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,v")))]
743 [(set_attr "type" "load,shift,fpload,vecperm")
744 (set_attr "isa" "*,*,p9v,p9v")])
746 (define_insn_and_split "*zero_extendqi<mode>2_dot"
747 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
748 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
750 (clobber (match_scratch:EXTQI 0 "=r,r"))]
755 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
757 (zero_extend:EXTQI (match_dup 1)))
759 (compare:CC (match_dup 0)
762 [(set_attr "type" "logical")
763 (set_attr "dot" "yes")
764 (set_attr "length" "4,8")])
766 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
767 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
768 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
770 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
771 (zero_extend:EXTQI (match_dup 1)))]
776 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
778 (zero_extend:EXTQI (match_dup 1)))
780 (compare:CC (match_dup 0)
783 [(set_attr "type" "logical")
784 (set_attr "dot" "yes")
785 (set_attr "length" "4,8")])
788 (define_insn "zero_extendhi<mode>2"
789 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wa,^v")
790 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
794 rlwinm %0,%1,0,0xffff
797 [(set_attr "type" "load,shift,fpload,vecperm")
798 (set_attr "isa" "*,*,p9v,p9v")])
800 (define_insn_and_split "*zero_extendhi<mode>2_dot"
801 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
802 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
804 (clobber (match_scratch:EXTHI 0 "=r,r"))]
809 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
811 (zero_extend:EXTHI (match_dup 1)))
813 (compare:CC (match_dup 0)
816 [(set_attr "type" "logical")
817 (set_attr "dot" "yes")
818 (set_attr "length" "4,8")])
820 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
821 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
822 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
824 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
825 (zero_extend:EXTHI (match_dup 1)))]
830 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
832 (zero_extend:EXTHI (match_dup 1)))
834 (compare:CC (match_dup 0)
837 [(set_attr "type" "logical")
838 (set_attr "dot" "yes")
839 (set_attr "length" "4,8")])
842 (define_insn "zero_extendsi<mode>2"
843 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,d,wa,wa,r,wa")
844 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wa,wa")))]
853 xxextractuw %x0,%x1,4"
854 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")
855 (set_attr "isa" "*,*,p7,p8v,p8v,p8v,p9v")])
857 (define_insn_and_split "*zero_extendsi<mode>2_dot"
858 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
859 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
861 (clobber (match_scratch:EXTSI 0 "=r,r"))]
866 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
868 (zero_extend:DI (match_dup 1)))
870 (compare:CC (match_dup 0)
873 [(set_attr "type" "shift")
874 (set_attr "dot" "yes")
875 (set_attr "length" "4,8")])
877 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
878 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
879 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
881 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
882 (zero_extend:EXTSI (match_dup 1)))]
887 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
889 (zero_extend:EXTSI (match_dup 1)))
891 (compare:CC (match_dup 0)
894 [(set_attr "type" "shift")
895 (set_attr "dot" "yes")
896 (set_attr "length" "4,8")])
899 (define_insn "extendqi<mode>2"
900 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*v")
901 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*v")))]
906 [(set_attr "type" "exts,vecperm")
907 (set_attr "isa" "*,p9v")])
909 (define_insn_and_split "*extendqi<mode>2_dot"
910 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
911 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
913 (clobber (match_scratch:EXTQI 0 "=r,r"))]
918 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
920 (sign_extend:EXTQI (match_dup 1)))
922 (compare:CC (match_dup 0)
925 [(set_attr "type" "exts")
926 (set_attr "dot" "yes")
927 (set_attr "length" "4,8")])
929 (define_insn_and_split "*extendqi<mode>2_dot2"
930 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
931 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
933 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
934 (sign_extend:EXTQI (match_dup 1)))]
939 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
941 (sign_extend:EXTQI (match_dup 1)))
943 (compare:CC (match_dup 0)
946 [(set_attr "type" "exts")
947 (set_attr "dot" "yes")
948 (set_attr "length" "4,8")])
951 (define_expand "extendhi<mode>2"
952 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
953 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
957 (define_insn "*extendhi<mode>2"
958 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*v,?*v")
959 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,v")))]
966 [(set_attr "type" "load,exts,fpload,vecperm")
967 (set_attr "sign_extend" "yes")
968 (set_attr "length" "*,*,8,*")
969 (set_attr "isa" "*,*,p9v,p9v")])
972 [(set (match_operand:EXTHI 0 "altivec_register_operand")
974 (match_operand:HI 1 "indexed_or_indirect_operand")))]
975 "TARGET_P9_VECTOR && reload_completed"
979 (sign_extend:EXTHI (match_dup 2)))]
981 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
984 (define_insn_and_split "*extendhi<mode>2_dot"
985 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
986 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
988 (clobber (match_scratch:EXTHI 0 "=r,r"))]
993 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
995 (sign_extend:EXTHI (match_dup 1)))
997 (compare:CC (match_dup 0)
1000 [(set_attr "type" "exts")
1001 (set_attr "dot" "yes")
1002 (set_attr "length" "4,8")])
1004 (define_insn_and_split "*extendhi<mode>2_dot2"
1005 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1006 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
1008 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
1009 (sign_extend:EXTHI (match_dup 1)))]
1014 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1016 (sign_extend:EXTHI (match_dup 1)))
1018 (compare:CC (match_dup 0)
1021 [(set_attr "type" "exts")
1022 (set_attr "dot" "yes")
1023 (set_attr "length" "4,8")])
1026 (define_insn "extendsi<mode>2"
1027 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1028 "=r, r, d, wa, wa, v, v, wr")
1029 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1030 "YZ, r, Z, Z, r, v, v, ?wa")))]
1041 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1042 (set_attr "sign_extend" "yes")
1043 (set_attr "length" "*,*,*,*,*,*,8,8")
1044 (set_attr "isa" "*,*,p6,p8v,p8v,p9v,p8v,p8v")])
1047 [(set (match_operand:EXTSI 0 "int_reg_operand")
1048 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1049 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1053 (sign_extend:DI (match_dup 2)))]
1055 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1059 [(set (match_operand:DI 0 "altivec_register_operand")
1060 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1061 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1064 rtx dest = operands[0];
1065 rtx src = operands[1];
1066 int dest_regno = REGNO (dest);
1067 int src_regno = REGNO (src);
1068 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1069 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1071 if (BYTES_BIG_ENDIAN)
1073 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1074 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1078 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1079 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1084 (define_insn_and_split "*extendsi<mode>2_dot"
1085 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1086 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1088 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1093 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1095 (sign_extend:EXTSI (match_dup 1)))
1097 (compare:CC (match_dup 0)
1100 [(set_attr "type" "exts")
1101 (set_attr "dot" "yes")
1102 (set_attr "length" "4,8")])
1104 (define_insn_and_split "*extendsi<mode>2_dot2"
1105 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1106 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1108 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1109 (sign_extend:EXTSI (match_dup 1)))]
1114 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1116 (sign_extend:EXTSI (match_dup 1)))
1118 (compare:CC (match_dup 0)
1121 [(set_attr "type" "exts")
1122 (set_attr "dot" "yes")
1123 (set_attr "length" "4,8")])
1125 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1127 (define_insn "*macchwc"
1128 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1129 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1130 (match_operand:SI 2 "gpc_reg_operand" "r")
1133 (match_operand:HI 1 "gpc_reg_operand" "r")))
1134 (match_operand:SI 4 "gpc_reg_operand" "0"))
1136 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1137 (plus:SI (mult:SI (ashiftrt:SI
1145 [(set_attr "type" "halfmul")])
1147 (define_insn "*macchw"
1148 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1149 (plus:SI (mult:SI (ashiftrt:SI
1150 (match_operand:SI 2 "gpc_reg_operand" "r")
1153 (match_operand:HI 1 "gpc_reg_operand" "r")))
1154 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1157 [(set_attr "type" "halfmul")])
1159 (define_insn "*macchwuc"
1160 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1161 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1162 (match_operand:SI 2 "gpc_reg_operand" "r")
1165 (match_operand:HI 1 "gpc_reg_operand" "r")))
1166 (match_operand:SI 4 "gpc_reg_operand" "0"))
1168 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1169 (plus:SI (mult:SI (lshiftrt:SI
1177 [(set_attr "type" "halfmul")])
1179 (define_insn "*macchwu"
1180 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1181 (plus:SI (mult:SI (lshiftrt:SI
1182 (match_operand:SI 2 "gpc_reg_operand" "r")
1185 (match_operand:HI 1 "gpc_reg_operand" "r")))
1186 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1189 [(set_attr "type" "halfmul")])
1191 (define_insn "*machhwc"
1192 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1193 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1194 (match_operand:SI 1 "gpc_reg_operand" "%r")
1197 (match_operand:SI 2 "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
1211 [(set_attr "type" "halfmul")])
1213 (define_insn "*machhw"
1214 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1215 (plus:SI (mult:SI (ashiftrt:SI
1216 (match_operand:SI 1 "gpc_reg_operand" "%r")
1219 (match_operand:SI 2 "gpc_reg_operand" "r")
1221 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1224 [(set_attr "type" "halfmul")])
1226 (define_insn "*machhwuc"
1227 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1228 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1229 (match_operand:SI 1 "gpc_reg_operand" "%r")
1232 (match_operand:SI 2 "gpc_reg_operand" "r")
1234 (match_operand:SI 4 "gpc_reg_operand" "0"))
1236 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1237 (plus:SI (mult:SI (lshiftrt:SI
1246 [(set_attr "type" "halfmul")])
1248 (define_insn "*machhwu"
1249 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1250 (plus:SI (mult:SI (lshiftrt:SI
1251 (match_operand:SI 1 "gpc_reg_operand" "%r")
1254 (match_operand:SI 2 "gpc_reg_operand" "r")
1256 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1259 [(set_attr "type" "halfmul")])
1261 (define_insn "*maclhwc"
1262 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1263 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1264 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1266 (match_operand:HI 2 "gpc_reg_operand" "r")))
1267 (match_operand:SI 4 "gpc_reg_operand" "0"))
1269 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1270 (plus:SI (mult:SI (sign_extend:SI
1277 [(set_attr "type" "halfmul")])
1279 (define_insn "*maclhw"
1280 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1281 (plus:SI (mult:SI (sign_extend:SI
1282 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1284 (match_operand:HI 2 "gpc_reg_operand" "r")))
1285 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1288 [(set_attr "type" "halfmul")])
1290 (define_insn "*maclhwuc"
1291 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1292 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1293 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1295 (match_operand:HI 2 "gpc_reg_operand" "r")))
1296 (match_operand:SI 4 "gpc_reg_operand" "0"))
1298 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1299 (plus:SI (mult:SI (zero_extend:SI
1306 [(set_attr "type" "halfmul")])
1308 (define_insn "*maclhwu"
1309 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1310 (plus:SI (mult:SI (zero_extend:SI
1311 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1313 (match_operand:HI 2 "gpc_reg_operand" "r")))
1314 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1317 [(set_attr "type" "halfmul")])
1319 (define_insn "*nmacchwc"
1320 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1321 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1322 (mult:SI (ashiftrt:SI
1323 (match_operand:SI 2 "gpc_reg_operand" "r")
1326 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1328 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1329 (minus:SI (match_dup 4)
1330 (mult:SI (ashiftrt:SI
1337 [(set_attr "type" "halfmul")])
1339 (define_insn "*nmacchw"
1340 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1341 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1342 (mult:SI (ashiftrt:SI
1343 (match_operand:SI 2 "gpc_reg_operand" "r")
1346 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1349 [(set_attr "type" "halfmul")])
1351 (define_insn "*nmachhwc"
1352 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1353 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1354 (mult:SI (ashiftrt:SI
1355 (match_operand:SI 1 "gpc_reg_operand" "%r")
1358 (match_operand:SI 2 "gpc_reg_operand" "r")
1361 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1362 (minus:SI (match_dup 4)
1363 (mult:SI (ashiftrt:SI
1371 [(set_attr "type" "halfmul")])
1373 (define_insn "*nmachhw"
1374 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1375 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1376 (mult:SI (ashiftrt:SI
1377 (match_operand:SI 1 "gpc_reg_operand" "%r")
1380 (match_operand:SI 2 "gpc_reg_operand" "r")
1384 [(set_attr "type" "halfmul")])
1386 (define_insn "*nmaclhwc"
1387 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1388 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1389 (mult:SI (sign_extend:SI
1390 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1392 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1394 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1395 (minus:SI (match_dup 4)
1396 (mult:SI (sign_extend:SI
1402 [(set_attr "type" "halfmul")])
1404 (define_insn "*nmaclhw"
1405 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1406 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1407 (mult:SI (sign_extend:SI
1408 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1410 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1413 [(set_attr "type" "halfmul")])
1415 (define_insn "*mulchwc"
1416 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1417 (compare:CC (mult:SI (ashiftrt:SI
1418 (match_operand:SI 2 "gpc_reg_operand" "r")
1421 (match_operand:HI 1 "gpc_reg_operand" "r")))
1423 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1424 (mult:SI (ashiftrt:SI
1431 [(set_attr "type" "halfmul")])
1433 (define_insn "*mulchw"
1434 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1435 (mult:SI (ashiftrt:SI
1436 (match_operand:SI 2 "gpc_reg_operand" "r")
1439 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1442 [(set_attr "type" "halfmul")])
1444 (define_insn "*mulchwuc"
1445 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1446 (compare:CC (mult:SI (lshiftrt:SI
1447 (match_operand:SI 2 "gpc_reg_operand" "r")
1450 (match_operand:HI 1 "gpc_reg_operand" "r")))
1452 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1453 (mult:SI (lshiftrt:SI
1460 [(set_attr "type" "halfmul")])
1462 (define_insn "*mulchwu"
1463 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1464 (mult:SI (lshiftrt:SI
1465 (match_operand:SI 2 "gpc_reg_operand" "r")
1468 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1471 [(set_attr "type" "halfmul")])
1473 (define_insn "*mulhhwc"
1474 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1475 (compare:CC (mult:SI (ashiftrt:SI
1476 (match_operand:SI 1 "gpc_reg_operand" "%r")
1479 (match_operand:SI 2 "gpc_reg_operand" "r")
1482 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1483 (mult:SI (ashiftrt:SI
1491 [(set_attr "type" "halfmul")])
1493 (define_insn "*mulhhw"
1494 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1495 (mult:SI (ashiftrt:SI
1496 (match_operand:SI 1 "gpc_reg_operand" "%r")
1499 (match_operand:SI 2 "gpc_reg_operand" "r")
1503 [(set_attr "type" "halfmul")])
1505 (define_insn "*mulhhwuc"
1506 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1507 (compare:CC (mult:SI (lshiftrt:SI
1508 (match_operand:SI 1 "gpc_reg_operand" "%r")
1511 (match_operand:SI 2 "gpc_reg_operand" "r")
1514 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1515 (mult:SI (lshiftrt:SI
1523 [(set_attr "type" "halfmul")])
1525 (define_insn "*mulhhwu"
1526 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1527 (mult:SI (lshiftrt:SI
1528 (match_operand:SI 1 "gpc_reg_operand" "%r")
1531 (match_operand:SI 2 "gpc_reg_operand" "r")
1535 [(set_attr "type" "halfmul")])
1537 (define_insn "*mullhwc"
1538 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1539 (compare:CC (mult:SI (sign_extend:SI
1540 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1542 (match_operand:HI 2 "gpc_reg_operand" "r")))
1544 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1545 (mult:SI (sign_extend:SI
1551 [(set_attr "type" "halfmul")])
1553 (define_insn "*mullhw"
1554 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1555 (mult:SI (sign_extend:SI
1556 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1558 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1561 [(set_attr "type" "halfmul")])
1563 (define_insn "*mullhwuc"
1564 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1565 (compare:CC (mult:SI (zero_extend:SI
1566 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1568 (match_operand:HI 2 "gpc_reg_operand" "r")))
1570 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1571 (mult:SI (zero_extend:SI
1577 [(set_attr "type" "halfmul")])
1579 (define_insn "*mullhwu"
1580 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1581 (mult:SI (zero_extend:SI
1582 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1584 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1587 [(set_attr "type" "halfmul")])
1589 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1590 (define_insn "dlmzb"
1591 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1592 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1593 (match_operand:SI 2 "gpc_reg_operand" "r")]
1595 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1596 (unspec:SI [(match_dup 1)
1602 (define_expand "strlensi"
1603 [(set (match_operand:SI 0 "gpc_reg_operand")
1604 (unspec:SI [(match_operand:BLK 1 "general_operand")
1605 (match_operand:QI 2 "const_int_operand")
1606 (match_operand 3 "const_int_operand")]
1607 UNSPEC_DLMZB_STRLEN))
1608 (clobber (match_scratch:CC 4))]
1609 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1611 rtx result = operands[0];
1612 rtx src = operands[1];
1613 rtx search_char = operands[2];
1614 rtx align = operands[3];
1615 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1616 rtx loop_label, end_label, mem, cr0, cond;
1617 if (search_char != const0_rtx
1618 || !CONST_INT_P (align)
1619 || INTVAL (align) < 8)
1621 word1 = gen_reg_rtx (SImode);
1622 word2 = gen_reg_rtx (SImode);
1623 scratch_dlmzb = gen_reg_rtx (SImode);
1624 scratch_string = gen_reg_rtx (Pmode);
1625 loop_label = gen_label_rtx ();
1626 end_label = gen_label_rtx ();
1627 addr = force_reg (Pmode, XEXP (src, 0));
1628 emit_move_insn (scratch_string, addr);
1629 emit_label (loop_label);
1630 mem = change_address (src, SImode, scratch_string);
1631 emit_move_insn (word1, mem);
1632 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1633 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1634 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1635 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1636 emit_jump_insn (gen_rtx_SET (pc_rtx,
1637 gen_rtx_IF_THEN_ELSE (VOIDmode,
1643 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1644 emit_jump_insn (gen_rtx_SET (pc_rtx,
1645 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1647 emit_label (end_label);
1648 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1649 emit_insn (gen_subsi3 (result, scratch_string, addr));
1650 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1654 ;; Fixed-point arithmetic insns.
1656 (define_expand "add<mode>3"
1657 [(set (match_operand:SDI 0 "gpc_reg_operand")
1658 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1659 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1662 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1664 rtx lo0 = gen_lowpart (SImode, operands[0]);
1665 rtx lo1 = gen_lowpart (SImode, operands[1]);
1666 rtx lo2 = gen_lowpart (SImode, operands[2]);
1667 rtx hi0 = gen_highpart (SImode, operands[0]);
1668 rtx hi1 = gen_highpart (SImode, operands[1]);
1669 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1671 if (!reg_or_short_operand (lo2, SImode))
1672 lo2 = force_reg (SImode, lo2);
1673 if (!adde_operand (hi2, SImode))
1674 hi2 = force_reg (SImode, hi2);
1676 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1677 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1681 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1683 rtx tmp = ((!can_create_pseudo_p ()
1684 || rtx_equal_p (operands[0], operands[1]))
1685 ? operands[0] : gen_reg_rtx (<MODE>mode));
1687 /* Adding a constant to r0 is not a valid insn, so use a different
1688 strategy in that case. */
1689 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1691 if (operands[0] == operands[1])
1693 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1694 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1698 HOST_WIDE_INT val = INTVAL (operands[2]);
1699 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1700 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1702 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1705 /* The ordering here is important for the prolog expander.
1706 When space is allocated from the stack, adding 'low' first may
1707 produce a temporary deallocation (which would be bad). */
1708 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1709 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1714 (define_insn "*add<mode>3"
1715 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1716 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1717 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1723 [(set_attr "type" "add")])
1725 (define_insn "*addsi3_high"
1726 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1727 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1728 (high:SI (match_operand 2 "" ""))))]
1729 "TARGET_MACHO && !TARGET_64BIT"
1730 "addis %0,%1,ha16(%2)"
1731 [(set_attr "type" "add")])
1733 (define_insn_and_split "*add<mode>3_dot"
1734 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1735 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1736 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1738 (clobber (match_scratch:GPR 0 "=r,r"))]
1739 "<MODE>mode == Pmode"
1743 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1745 (plus:GPR (match_dup 1)
1748 (compare:CC (match_dup 0)
1751 [(set_attr "type" "add")
1752 (set_attr "dot" "yes")
1753 (set_attr "length" "4,8")])
1755 (define_insn_and_split "*add<mode>3_dot2"
1756 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1757 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1758 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1760 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1761 (plus:GPR (match_dup 1)
1763 "<MODE>mode == Pmode"
1767 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1769 (plus:GPR (match_dup 1)
1772 (compare:CC (match_dup 0)
1775 [(set_attr "type" "add")
1776 (set_attr "dot" "yes")
1777 (set_attr "length" "4,8")])
1779 (define_insn_and_split "*add<mode>3_imm_dot"
1780 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1781 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1782 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1784 (clobber (match_scratch:GPR 0 "=r,r"))
1785 (clobber (reg:GPR CA_REGNO))]
1786 "<MODE>mode == Pmode"
1790 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1792 (plus:GPR (match_dup 1)
1795 (compare:CC (match_dup 0)
1798 [(set_attr "type" "add")
1799 (set_attr "dot" "yes")
1800 (set_attr "length" "4,8")])
1802 (define_insn_and_split "*add<mode>3_imm_dot2"
1803 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1804 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1805 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1807 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1808 (plus:GPR (match_dup 1)
1810 (clobber (reg:GPR CA_REGNO))]
1811 "<MODE>mode == Pmode"
1815 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1817 (plus:GPR (match_dup 1)
1820 (compare:CC (match_dup 0)
1823 [(set_attr "type" "add")
1824 (set_attr "dot" "yes")
1825 (set_attr "length" "4,8")])
1827 ;; Split an add that we can't do in one insn into two insns, each of which
1828 ;; does one 16-bit part. This is used by combine. Note that the low-order
1829 ;; add should be last in case the result gets used in an address.
1832 [(set (match_operand:GPR 0 "gpc_reg_operand")
1833 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1834 (match_operand:GPR 2 "non_add_cint_operand")))]
1836 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1837 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1839 HOST_WIDE_INT val = INTVAL (operands[2]);
1840 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1841 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1843 operands[4] = GEN_INT (low);
1844 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1845 operands[3] = GEN_INT (rest);
1846 else if (can_create_pseudo_p ())
1848 operands[3] = gen_reg_rtx (DImode);
1849 emit_move_insn (operands[3], operands[2]);
1850 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1858 (define_insn "add<mode>3_carry"
1859 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1860 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1861 (match_operand:P 2 "reg_or_short_operand" "rI")))
1862 (set (reg:P CA_REGNO)
1863 (ltu:P (plus:P (match_dup 1)
1868 [(set_attr "type" "add")])
1870 (define_insn "*add<mode>3_imm_carry_pos"
1871 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1872 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1873 (match_operand:P 2 "short_cint_operand" "n")))
1874 (set (reg:P CA_REGNO)
1875 (geu:P (match_dup 1)
1876 (match_operand:P 3 "const_int_operand" "n")))]
1877 "INTVAL (operands[2]) > 0
1878 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1880 [(set_attr "type" "add")])
1882 (define_insn "*add<mode>3_imm_carry_0"
1883 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1884 (match_operand:P 1 "gpc_reg_operand" "r"))
1885 (set (reg:P CA_REGNO)
1889 [(set_attr "type" "add")])
1891 (define_insn "*add<mode>3_imm_carry_m1"
1892 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1893 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1895 (set (reg:P CA_REGNO)
1900 [(set_attr "type" "add")])
1902 (define_insn "*add<mode>3_imm_carry_neg"
1903 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1904 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1905 (match_operand:P 2 "short_cint_operand" "n")))
1906 (set (reg:P CA_REGNO)
1907 (gtu:P (match_dup 1)
1908 (match_operand:P 3 "const_int_operand" "n")))]
1909 "INTVAL (operands[2]) < 0
1910 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1912 [(set_attr "type" "add")])
1915 (define_expand "add<mode>3_carry_in"
1917 (set (match_operand:GPR 0 "gpc_reg_operand")
1918 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1919 (match_operand:GPR 2 "adde_operand"))
1920 (reg:GPR CA_REGNO)))
1921 (clobber (reg:GPR CA_REGNO))])]
1924 if (operands[2] == const0_rtx)
1926 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1929 if (operands[2] == constm1_rtx)
1931 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1936 (define_insn "*add<mode>3_carry_in_internal"
1937 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1938 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1939 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1940 (reg:GPR CA_REGNO)))
1941 (clobber (reg:GPR CA_REGNO))]
1944 [(set_attr "type" "add")])
1946 (define_insn "*add<mode>3_carry_in_internal2"
1947 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1948 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1950 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1951 (clobber (reg:GPR CA_REGNO))]
1954 [(set_attr "type" "add")])
1956 (define_insn "add<mode>3_carry_in_0"
1957 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1958 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1959 (reg:GPR CA_REGNO)))
1960 (clobber (reg:GPR CA_REGNO))]
1963 [(set_attr "type" "add")])
1965 (define_insn "add<mode>3_carry_in_m1"
1966 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1967 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1970 (clobber (reg:GPR CA_REGNO))]
1973 [(set_attr "type" "add")])
1976 (define_expand "one_cmpl<mode>2"
1977 [(set (match_operand:SDI 0 "gpc_reg_operand")
1978 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1981 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1983 rs6000_split_logical (operands, NOT, false, false, false);
1988 (define_insn "*one_cmpl<mode>2"
1989 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1990 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1994 (define_insn_and_split "*one_cmpl<mode>2_dot"
1995 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1996 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1998 (clobber (match_scratch:GPR 0 "=r,r"))]
1999 "<MODE>mode == Pmode"
2003 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2005 (not:GPR (match_dup 1)))
2007 (compare:CC (match_dup 0)
2010 [(set_attr "type" "logical")
2011 (set_attr "dot" "yes")
2012 (set_attr "length" "4,8")])
2014 (define_insn_and_split "*one_cmpl<mode>2_dot2"
2015 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2016 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2018 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2019 (not:GPR (match_dup 1)))]
2020 "<MODE>mode == Pmode"
2024 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2026 (not:GPR (match_dup 1)))
2028 (compare:CC (match_dup 0)
2031 [(set_attr "type" "logical")
2032 (set_attr "dot" "yes")
2033 (set_attr "length" "4,8")])
2036 (define_expand "sub<mode>3"
2037 [(set (match_operand:SDI 0 "gpc_reg_operand")
2038 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2039 (match_operand:SDI 2 "gpc_reg_operand")))]
2042 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2044 rtx lo0 = gen_lowpart (SImode, operands[0]);
2045 rtx lo1 = gen_lowpart (SImode, operands[1]);
2046 rtx lo2 = gen_lowpart (SImode, operands[2]);
2047 rtx hi0 = gen_highpart (SImode, operands[0]);
2048 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2049 rtx hi2 = gen_highpart (SImode, operands[2]);
2051 if (!reg_or_short_operand (lo1, SImode))
2052 lo1 = force_reg (SImode, lo1);
2053 if (!adde_operand (hi1, SImode))
2054 hi1 = force_reg (SImode, hi1);
2056 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2057 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2061 if (short_cint_operand (operands[1], <MODE>mode))
2063 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2068 (define_insn "*subf<mode>3"
2069 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2070 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2071 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2074 [(set_attr "type" "add")])
2076 (define_insn_and_split "*subf<mode>3_dot"
2077 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2078 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2079 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2081 (clobber (match_scratch:GPR 0 "=r,r"))]
2082 "<MODE>mode == Pmode"
2086 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2088 (minus:GPR (match_dup 2)
2091 (compare:CC (match_dup 0)
2094 [(set_attr "type" "add")
2095 (set_attr "dot" "yes")
2096 (set_attr "length" "4,8")])
2098 (define_insn_and_split "*subf<mode>3_dot2"
2099 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2100 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2101 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2103 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2104 (minus:GPR (match_dup 2)
2106 "<MODE>mode == Pmode"
2110 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2112 (minus:GPR (match_dup 2)
2115 (compare:CC (match_dup 0)
2118 [(set_attr "type" "add")
2119 (set_attr "dot" "yes")
2120 (set_attr "length" "4,8")])
2122 (define_insn "subf<mode>3_imm"
2123 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2124 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2125 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2126 (clobber (reg:GPR CA_REGNO))]
2129 [(set_attr "type" "add")])
2131 (define_insn_and_split "subf<mode>3_carry_dot2"
2132 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2133 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2134 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2136 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2137 (minus:P (match_dup 2)
2139 (set (reg:P CA_REGNO)
2140 (leu:P (match_dup 1)
2142 "<MODE>mode == Pmode"
2146 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2147 [(parallel [(set (match_dup 0)
2148 (minus:P (match_dup 2)
2150 (set (reg:P CA_REGNO)
2151 (leu:P (match_dup 1)
2154 (compare:CC (match_dup 0)
2157 [(set_attr "type" "add")
2158 (set_attr "dot" "yes")
2159 (set_attr "length" "4,8")])
2161 (define_insn "subf<mode>3_carry"
2162 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2163 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2164 (match_operand:P 1 "gpc_reg_operand" "r")))
2165 (set (reg:P CA_REGNO)
2166 (leu:P (match_dup 1)
2170 [(set_attr "type" "add")])
2172 (define_insn "*subf<mode>3_imm_carry_0"
2173 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2174 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2175 (set (reg:P CA_REGNO)
2180 [(set_attr "type" "add")])
2182 (define_insn "*subf<mode>3_imm_carry_m1"
2183 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2184 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2185 (set (reg:P CA_REGNO)
2189 [(set_attr "type" "add")])
2192 (define_expand "subf<mode>3_carry_in"
2194 (set (match_operand:GPR 0 "gpc_reg_operand")
2195 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2197 (match_operand:GPR 2 "adde_operand")))
2198 (clobber (reg:GPR CA_REGNO))])]
2201 if (operands[2] == const0_rtx)
2203 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2206 if (operands[2] == constm1_rtx)
2208 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2213 (define_insn "*subf<mode>3_carry_in_internal"
2214 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2215 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2217 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2218 (clobber (reg:GPR CA_REGNO))]
2221 [(set_attr "type" "add")])
2223 (define_insn "subf<mode>3_carry_in_0"
2224 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2225 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2226 (reg:GPR CA_REGNO)))
2227 (clobber (reg:GPR CA_REGNO))]
2230 [(set_attr "type" "add")])
2232 (define_insn "subf<mode>3_carry_in_m1"
2233 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2234 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2235 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2237 (clobber (reg:GPR CA_REGNO))]
2240 [(set_attr "type" "add")])
2242 (define_insn "subf<mode>3_carry_in_xx"
2243 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2244 (plus:GPR (reg:GPR CA_REGNO)
2246 (clobber (reg:GPR CA_REGNO))]
2249 [(set_attr "type" "add")])
2252 (define_insn "@neg<mode>2"
2253 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2254 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2257 [(set_attr "type" "add")])
2259 (define_insn_and_split "*neg<mode>2_dot"
2260 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2261 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2263 (clobber (match_scratch:GPR 0 "=r,r"))]
2264 "<MODE>mode == Pmode"
2268 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2270 (neg:GPR (match_dup 1)))
2272 (compare:CC (match_dup 0)
2275 [(set_attr "type" "add")
2276 (set_attr "dot" "yes")
2277 (set_attr "length" "4,8")])
2279 (define_insn_and_split "*neg<mode>2_dot2"
2280 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2281 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2283 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2284 (neg:GPR (match_dup 1)))]
2285 "<MODE>mode == Pmode"
2289 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2291 (neg:GPR (match_dup 1)))
2293 (compare:CC (match_dup 0)
2296 [(set_attr "type" "add")
2297 (set_attr "dot" "yes")
2298 (set_attr "length" "4,8")])
2301 (define_insn "clz<mode>2"
2302 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2303 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2306 [(set_attr "type" "cntlz")])
2308 (define_expand "ctz<mode>2"
2309 [(set (match_operand:GPR 0 "gpc_reg_operand")
2310 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2315 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2319 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2320 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2321 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2325 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2326 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2327 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2328 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2332 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2333 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2334 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2335 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2341 (define_insn "ctz<mode>2_hw"
2342 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2343 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2346 [(set_attr "type" "cntlz")])
2348 (define_expand "ffs<mode>2"
2349 [(set (match_operand:GPR 0 "gpc_reg_operand")
2350 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2353 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2354 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2355 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2356 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2357 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2358 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2359 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2364 (define_expand "popcount<mode>2"
2365 [(set (match_operand:GPR 0 "gpc_reg_operand")
2366 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2367 "TARGET_POPCNTB || TARGET_POPCNTD"
2369 rs6000_emit_popcount (operands[0], operands[1]);
2373 (define_insn "popcntb<mode>2"
2374 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2375 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2379 [(set_attr "type" "popcnt")])
2381 (define_insn "popcntd<mode>2"
2382 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2383 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2386 [(set_attr "type" "popcnt")])
2389 (define_expand "parity<mode>2"
2390 [(set (match_operand:GPR 0 "gpc_reg_operand")
2391 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2394 rs6000_emit_parity (operands[0], operands[1]);
2398 (define_insn "parity<mode>2_cmpb"
2399 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2400 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2401 "TARGET_CMPB && TARGET_POPCNTB"
2403 [(set_attr "type" "popcnt")])
2405 (define_insn "cmpb<mode>3"
2406 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2407 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2408 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2411 [(set_attr "type" "cmp")])
2413 ;; Since the hardware zeros the upper part of the register, save generating the
2414 ;; AND immediate if we are converting to unsigned
2415 (define_insn "*bswap<mode>2_extenddi"
2416 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2418 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2421 [(set_attr "type" "load")])
2423 (define_insn "*bswaphi2_extendsi"
2424 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2426 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2429 [(set_attr "type" "load")])
2431 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2432 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2433 ;; load with byte swap, which can be slower than doing it in the registers. It
2434 ;; also prevents certain failures with the RELOAD register allocator.
2436 (define_expand "bswap<mode>2"
2437 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2438 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2441 rtx dest = operands[0];
2442 rtx src = operands[1];
2444 if (!REG_P (dest) && !REG_P (src))
2445 src = force_reg (<MODE>mode, src);
2449 src = rs6000_force_indexed_or_indirect_mem (src);
2450 emit_insn (gen_bswap<mode>2_load (dest, src));
2452 else if (MEM_P (dest))
2454 dest = rs6000_force_indexed_or_indirect_mem (dest);
2455 emit_insn (gen_bswap<mode>2_store (dest, src));
2458 emit_insn (gen_bswap<mode>2_reg (dest, src));
2462 (define_insn "bswap<mode>2_load"
2463 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2464 (bswap:HSI (match_operand:HSI 1 "indexed_or_indirect_operand" "Z")))]
2467 [(set_attr "type" "load")])
2469 (define_insn "bswap<mode>2_store"
2470 [(set (match_operand:HSI 0 "indexed_or_indirect_operand" "=Z")
2471 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2474 [(set_attr "type" "store")])
2476 (define_insn_and_split "bswaphi2_reg"
2477 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wa")
2479 (match_operand:HI 1 "gpc_reg_operand" "r,wa")))
2480 (clobber (match_scratch:SI 2 "=&r,X"))]
2485 "reload_completed && int_reg_operand (operands[0], HImode)"
2487 (and:SI (lshiftrt:SI (match_dup 4)
2491 (and:SI (ashift:SI (match_dup 4)
2493 (const_int 65280))) ;; 0xff00
2495 (ior:SI (match_dup 3)
2498 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2499 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2501 [(set_attr "length" "12,4")
2502 (set_attr "type" "*,vecperm")
2503 (set_attr "isa" "*,p9v")])
2505 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2506 ;; zero_extract insns do not change for -mlittle.
2507 (define_insn_and_split "bswapsi2_reg"
2508 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wa")
2510 (match_operand:SI 1 "gpc_reg_operand" "r,wa")))]
2515 "reload_completed && int_reg_operand (operands[0], SImode)"
2516 [(set (match_dup 0) ; DABC
2517 (rotate:SI (match_dup 1)
2519 (set (match_dup 0) ; DCBC
2520 (ior:SI (and:SI (ashift:SI (match_dup 1)
2522 (const_int 16711680))
2523 (and:SI (match_dup 0)
2524 (const_int -16711681))))
2525 (set (match_dup 0) ; DCBA
2526 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2529 (and:SI (match_dup 0)
2530 (const_int -256))))]
2532 [(set_attr "length" "12,4")
2533 (set_attr "type" "*,vecperm")
2534 (set_attr "isa" "*,p9v")])
2536 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2537 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2540 (define_expand "bswapdi2"
2541 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2543 (match_operand:DI 1 "reg_or_mem_operand")))
2544 (clobber (match_scratch:DI 2))
2545 (clobber (match_scratch:DI 3))])]
2548 rtx dest = operands[0];
2549 rtx src = operands[1];
2551 if (!REG_P (dest) && !REG_P (src))
2552 operands[1] = src = force_reg (DImode, src);
2554 if (TARGET_POWERPC64 && TARGET_LDBRX)
2558 src = rs6000_force_indexed_or_indirect_mem (src);
2559 emit_insn (gen_bswapdi2_load (dest, src));
2561 else if (MEM_P (dest))
2563 dest = rs6000_force_indexed_or_indirect_mem (dest);
2564 emit_insn (gen_bswapdi2_store (dest, src));
2566 else if (TARGET_P9_VECTOR)
2567 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2569 emit_insn (gen_bswapdi2_reg (dest, src));
2573 if (!TARGET_POWERPC64)
2575 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2576 that uses 64-bit registers needs the same scratch registers as 64-bit
2578 emit_insn (gen_bswapdi2_32bit (dest, src));
2583 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2584 (define_insn "bswapdi2_load"
2585 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2586 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "Z")))]
2587 "TARGET_POWERPC64 && TARGET_LDBRX"
2589 [(set_attr "type" "load")])
2591 (define_insn "bswapdi2_store"
2592 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "=Z")
2593 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2594 "TARGET_POWERPC64 && TARGET_LDBRX"
2596 [(set_attr "type" "store")])
2598 (define_insn "bswapdi2_xxbrd"
2599 [(set (match_operand:DI 0 "gpc_reg_operand" "=wa")
2600 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wa")))]
2603 [(set_attr "type" "vecperm")
2604 (set_attr "isa" "p9v")])
2606 (define_insn "bswapdi2_reg"
2607 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2608 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2609 (clobber (match_scratch:DI 2 "=&r"))
2610 (clobber (match_scratch:DI 3 "=&r"))]
2611 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2613 [(set_attr "length" "36")])
2615 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2616 (define_insn "*bswapdi2_64bit"
2617 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2618 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2619 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2620 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2621 "TARGET_POWERPC64 && !TARGET_LDBRX
2622 && (REG_P (operands[0]) || REG_P (operands[1]))
2623 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2624 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2626 [(set_attr "length" "16,12,36")])
2629 [(set (match_operand:DI 0 "gpc_reg_operand")
2630 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2631 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2632 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2633 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2636 rtx dest = operands[0];
2637 rtx src = operands[1];
2638 rtx op2 = operands[2];
2639 rtx op3 = operands[3];
2640 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2641 BYTES_BIG_ENDIAN ? 4 : 0);
2642 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2643 BYTES_BIG_ENDIAN ? 4 : 0);
2649 addr1 = XEXP (src, 0);
2650 if (GET_CODE (addr1) == PLUS)
2652 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2653 if (TARGET_AVOID_XFORM)
2655 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2659 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2661 else if (TARGET_AVOID_XFORM)
2663 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2668 emit_move_insn (op2, GEN_INT (4));
2669 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2672 word1 = change_address (src, SImode, addr1);
2673 word2 = change_address (src, SImode, addr2);
2675 if (BYTES_BIG_ENDIAN)
2677 emit_insn (gen_bswapsi2 (op3_32, word2));
2678 emit_insn (gen_bswapsi2 (dest_32, word1));
2682 emit_insn (gen_bswapsi2 (op3_32, word1));
2683 emit_insn (gen_bswapsi2 (dest_32, word2));
2686 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2687 emit_insn (gen_iordi3 (dest, dest, op3));
2692 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2693 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2694 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2695 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2696 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2699 rtx dest = operands[0];
2700 rtx src = operands[1];
2701 rtx op2 = operands[2];
2702 rtx op3 = operands[3];
2703 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2704 BYTES_BIG_ENDIAN ? 4 : 0);
2705 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2706 BYTES_BIG_ENDIAN ? 4 : 0);
2712 addr1 = XEXP (dest, 0);
2713 if (GET_CODE (addr1) == PLUS)
2715 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2716 if (TARGET_AVOID_XFORM)
2718 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2722 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2724 else if (TARGET_AVOID_XFORM)
2726 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2731 emit_move_insn (op2, GEN_INT (4));
2732 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2735 word1 = change_address (dest, SImode, addr1);
2736 word2 = change_address (dest, SImode, addr2);
2738 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2740 if (BYTES_BIG_ENDIAN)
2742 emit_insn (gen_bswapsi2 (word1, src_si));
2743 emit_insn (gen_bswapsi2 (word2, op3_si));
2747 emit_insn (gen_bswapsi2 (word2, src_si));
2748 emit_insn (gen_bswapsi2 (word1, op3_si));
2754 [(set (match_operand:DI 0 "gpc_reg_operand")
2755 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2756 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2757 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2758 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2761 rtx dest = operands[0];
2762 rtx src = operands[1];
2763 rtx op2 = operands[2];
2764 rtx op3 = operands[3];
2765 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2766 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2767 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2768 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2769 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2771 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2772 emit_insn (gen_bswapsi2 (dest_si, src_si));
2773 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2774 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2775 emit_insn (gen_iordi3 (dest, dest, op3));
2779 (define_insn "bswapdi2_32bit"
2780 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2781 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2782 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2783 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2785 [(set_attr "length" "16,12,36")])
2788 [(set (match_operand:DI 0 "gpc_reg_operand")
2789 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2790 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2791 "!TARGET_POWERPC64 && reload_completed"
2794 rtx dest = operands[0];
2795 rtx src = operands[1];
2796 rtx op2 = operands[2];
2797 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2798 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2804 addr1 = XEXP (src, 0);
2805 if (GET_CODE (addr1) == PLUS)
2807 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2808 if (TARGET_AVOID_XFORM
2809 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2811 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2815 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2817 else if (TARGET_AVOID_XFORM
2818 || REGNO (addr1) == REGNO (dest2))
2820 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2825 emit_move_insn (op2, GEN_INT (4));
2826 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2829 word1 = change_address (src, SImode, addr1);
2830 word2 = change_address (src, SImode, addr2);
2832 emit_insn (gen_bswapsi2 (dest2, word1));
2833 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2834 thus allowing us to omit an early clobber on the output. */
2835 emit_insn (gen_bswapsi2 (dest1, word2));
2840 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2841 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2842 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2843 "!TARGET_POWERPC64 && reload_completed"
2846 rtx dest = operands[0];
2847 rtx src = operands[1];
2848 rtx op2 = operands[2];
2849 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2850 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2856 addr1 = XEXP (dest, 0);
2857 if (GET_CODE (addr1) == PLUS)
2859 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2860 if (TARGET_AVOID_XFORM)
2862 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2866 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2868 else if (TARGET_AVOID_XFORM)
2870 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2875 emit_move_insn (op2, GEN_INT (4));
2876 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2879 word1 = change_address (dest, SImode, addr1);
2880 word2 = change_address (dest, SImode, addr2);
2882 emit_insn (gen_bswapsi2 (word2, src1));
2883 emit_insn (gen_bswapsi2 (word1, src2));
2888 [(set (match_operand:DI 0 "gpc_reg_operand")
2889 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2890 (clobber (match_operand:SI 2 ""))]
2891 "!TARGET_POWERPC64 && reload_completed"
2894 rtx dest = operands[0];
2895 rtx src = operands[1];
2896 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2897 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2898 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2899 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2901 emit_insn (gen_bswapsi2 (dest1, src2));
2902 emit_insn (gen_bswapsi2 (dest2, src1));
2907 (define_insn "mul<mode>3"
2908 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2909 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2910 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2915 [(set_attr "type" "mul")
2917 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2919 (match_operand:GPR 2 "short_cint_operand")
2920 (const_string "16")]
2921 (const_string "<bits>")))])
2923 (define_insn_and_split "*mul<mode>3_dot"
2924 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2925 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2926 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2928 (clobber (match_scratch:GPR 0 "=r,r"))]
2929 "<MODE>mode == Pmode"
2933 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2935 (mult:GPR (match_dup 1)
2938 (compare:CC (match_dup 0)
2941 [(set_attr "type" "mul")
2942 (set_attr "size" "<bits>")
2943 (set_attr "dot" "yes")
2944 (set_attr "length" "4,8")])
2946 (define_insn_and_split "*mul<mode>3_dot2"
2947 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2948 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2949 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2951 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2952 (mult:GPR (match_dup 1)
2954 "<MODE>mode == Pmode"
2958 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2960 (mult:GPR (match_dup 1)
2963 (compare:CC (match_dup 0)
2966 [(set_attr "type" "mul")
2967 (set_attr "size" "<bits>")
2968 (set_attr "dot" "yes")
2969 (set_attr "length" "4,8")])
2972 (define_expand "<su>mul<mode>3_highpart"
2973 [(set (match_operand:GPR 0 "gpc_reg_operand")
2975 (mult:<DMODE> (any_extend:<DMODE>
2976 (match_operand:GPR 1 "gpc_reg_operand"))
2978 (match_operand:GPR 2 "gpc_reg_operand")))
2982 if (<MODE>mode == SImode && TARGET_POWERPC64)
2984 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2989 if (!WORDS_BIG_ENDIAN)
2991 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2997 (define_insn "*<su>mul<mode>3_highpart"
2998 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3000 (mult:<DMODE> (any_extend:<DMODE>
3001 (match_operand:GPR 1 "gpc_reg_operand" "r"))
3003 (match_operand:GPR 2 "gpc_reg_operand" "r")))
3005 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
3006 "mulh<wd><u> %0,%1,%2"
3007 [(set_attr "type" "mul")
3008 (set_attr "size" "<bits>")])
3010 (define_insn "<su>mulsi3_highpart_le"
3011 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3013 (mult:DI (any_extend:DI
3014 (match_operand:SI 1 "gpc_reg_operand" "r"))
3016 (match_operand:SI 2 "gpc_reg_operand" "r")))
3018 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
3020 [(set_attr "type" "mul")])
3022 (define_insn "<su>muldi3_highpart_le"
3023 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3025 (mult:TI (any_extend:TI
3026 (match_operand:DI 1 "gpc_reg_operand" "r"))
3028 (match_operand:DI 2 "gpc_reg_operand" "r")))
3030 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
3032 [(set_attr "type" "mul")
3033 (set_attr "size" "64")])
3035 (define_insn "<su>mulsi3_highpart_64"
3036 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3039 (mult:DI (any_extend:DI
3040 (match_operand:SI 1 "gpc_reg_operand" "r"))
3042 (match_operand:SI 2 "gpc_reg_operand" "r")))
3046 [(set_attr "type" "mul")])
3048 (define_expand "<u>mul<mode><dmode>3"
3049 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3050 (mult:<DMODE> (any_extend:<DMODE>
3051 (match_operand:GPR 1 "gpc_reg_operand"))
3053 (match_operand:GPR 2 "gpc_reg_operand"))))]
3054 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3056 rtx l = gen_reg_rtx (<MODE>mode);
3057 rtx h = gen_reg_rtx (<MODE>mode);
3058 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3059 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3060 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3061 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3065 (define_insn "*maddld<mode>4"
3066 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3067 (plus:GPR (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3068 (match_operand:GPR 2 "gpc_reg_operand" "r"))
3069 (match_operand:GPR 3 "gpc_reg_operand" "r")))]
3071 "maddld %0,%1,%2,%3"
3072 [(set_attr "type" "mul")])
3074 (define_insn "udiv<mode>3"
3075 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3076 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3077 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3080 [(set_attr "type" "div")
3081 (set_attr "size" "<bits>")])
3084 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3085 ;; modulus. If it isn't a power of two, force operands into register and do
3087 (define_expand "div<mode>3"
3088 [(set (match_operand:GPR 0 "gpc_reg_operand")
3089 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3090 (match_operand:GPR 2 "reg_or_cint_operand")))]
3093 if (CONST_INT_P (operands[2])
3094 && INTVAL (operands[2]) > 0
3095 && exact_log2 (INTVAL (operands[2])) >= 0)
3097 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3101 operands[2] = force_reg (<MODE>mode, operands[2]);
3104 (define_insn "*div<mode>3"
3105 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3106 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3107 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3110 [(set_attr "type" "div")
3111 (set_attr "size" "<bits>")])
3113 (define_insn "div<mode>3_sra"
3114 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3115 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3116 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3117 (clobber (reg:GPR CA_REGNO))]
3119 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3120 [(set_attr "type" "two")
3121 (set_attr "length" "8")])
3123 (define_insn_and_split "*div<mode>3_sra_dot"
3124 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3125 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3126 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3128 (clobber (match_scratch:GPR 0 "=r,r"))
3129 (clobber (reg:GPR CA_REGNO))]
3130 "<MODE>mode == Pmode"
3132 sra<wd>i %0,%1,%p2\;addze. %0,%0
3134 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3135 [(parallel [(set (match_dup 0)
3136 (div:GPR (match_dup 1)
3138 (clobber (reg:GPR CA_REGNO))])
3140 (compare:CC (match_dup 0)
3143 [(set_attr "type" "two")
3144 (set_attr "length" "8,12")
3145 (set_attr "cell_micro" "not")])
3147 (define_insn_and_split "*div<mode>3_sra_dot2"
3148 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3149 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3150 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3152 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3153 (div:GPR (match_dup 1)
3155 (clobber (reg:GPR CA_REGNO))]
3156 "<MODE>mode == Pmode"
3158 sra<wd>i %0,%1,%p2\;addze. %0,%0
3160 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3161 [(parallel [(set (match_dup 0)
3162 (div:GPR (match_dup 1)
3164 (clobber (reg:GPR CA_REGNO))])
3166 (compare:CC (match_dup 0)
3169 [(set_attr "type" "two")
3170 (set_attr "length" "8,12")
3171 (set_attr "cell_micro" "not")])
3173 (define_expand "mod<mode>3"
3174 [(set (match_operand:GPR 0 "gpc_reg_operand")
3175 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3176 (match_operand:GPR 2 "reg_or_cint_operand")))]
3183 if (!CONST_INT_P (operands[2])
3184 || INTVAL (operands[2]) <= 0
3185 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3190 operands[2] = force_reg (<MODE>mode, operands[2]);
3194 temp1 = gen_reg_rtx (<MODE>mode);
3195 temp2 = gen_reg_rtx (<MODE>mode);
3197 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3198 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3199 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3204 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3205 ;; mod, prefer putting the result of mod into a different register
3206 (define_insn "*mod<mode>3"
3207 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3208 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3209 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3212 [(set_attr "type" "div")
3213 (set_attr "size" "<bits>")])
3216 (define_insn "umod<mode>3"
3217 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3218 (umod: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 ;; On machines with modulo support, do a combined div/mod the old fashioned
3226 ;; method, since the multiply/subtract is faster than doing the mod instruction
3230 [(set (match_operand:GPR 0 "gpc_reg_operand")
3231 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3232 (match_operand:GPR 2 "gpc_reg_operand")))
3233 (set (match_operand:GPR 3 "gpc_reg_operand")
3234 (mod:GPR (match_dup 1)
3237 && ! reg_mentioned_p (operands[0], operands[1])
3238 && ! reg_mentioned_p (operands[0], operands[2])
3239 && ! reg_mentioned_p (operands[3], operands[1])
3240 && ! reg_mentioned_p (operands[3], operands[2])"
3242 (div:GPR (match_dup 1)
3245 (mult:GPR (match_dup 0)
3248 (minus:GPR (match_dup 1)
3252 [(set (match_operand:GPR 0 "gpc_reg_operand")
3253 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3254 (match_operand:GPR 2 "gpc_reg_operand")))
3255 (set (match_operand:GPR 3 "gpc_reg_operand")
3256 (umod:GPR (match_dup 1)
3259 && ! reg_mentioned_p (operands[0], operands[1])
3260 && ! reg_mentioned_p (operands[0], operands[2])
3261 && ! reg_mentioned_p (operands[3], operands[1])
3262 && ! reg_mentioned_p (operands[3], operands[2])"
3264 (udiv:GPR (match_dup 1)
3267 (mult:GPR (match_dup 0)
3270 (minus:GPR (match_dup 1)
3274 ;; Logical instructions
3275 ;; The logical instructions are mostly combined by using match_operator,
3276 ;; but the plain AND insns are somewhat different because there is no
3277 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3278 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3280 (define_expand "and<mode>3"
3281 [(set (match_operand:SDI 0 "gpc_reg_operand")
3282 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3283 (match_operand:SDI 2 "reg_or_cint_operand")))]
3286 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3288 rs6000_split_logical (operands, AND, false, false, false);
3292 if (CONST_INT_P (operands[2]))
3294 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3296 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3300 if (logical_const_operand (operands[2], <MODE>mode))
3302 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3306 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3308 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3312 operands[2] = force_reg (<MODE>mode, operands[2]);
3317 (define_insn "and<mode>3_imm"
3318 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3319 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3320 (match_operand:GPR 2 "logical_const_operand" "n")))
3321 (clobber (match_scratch:CC 3 "=x"))]
3322 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3323 "andi%e2. %0,%1,%u2"
3324 [(set_attr "type" "logical")
3325 (set_attr "dot" "yes")])
3327 (define_insn_and_split "*and<mode>3_imm_dot"
3328 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3329 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3330 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3332 (clobber (match_scratch:GPR 0 "=r,r"))
3333 (clobber (match_scratch:CC 4 "=X,x"))]
3334 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3335 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3339 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3340 [(parallel [(set (match_dup 0)
3341 (and:GPR (match_dup 1)
3343 (clobber (match_dup 4))])
3345 (compare:CC (match_dup 0)
3348 [(set_attr "type" "logical")
3349 (set_attr "dot" "yes")
3350 (set_attr "length" "4,8")])
3352 (define_insn_and_split "*and<mode>3_imm_dot2"
3353 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3354 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3355 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3357 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3358 (and:GPR (match_dup 1)
3360 (clobber (match_scratch:CC 4 "=X,x"))]
3361 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3362 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3366 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3367 [(parallel [(set (match_dup 0)
3368 (and:GPR (match_dup 1)
3370 (clobber (match_dup 4))])
3372 (compare:CC (match_dup 0)
3375 [(set_attr "type" "logical")
3376 (set_attr "dot" "yes")
3377 (set_attr "length" "4,8")])
3379 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3380 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3381 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3382 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3384 (clobber (match_scratch:GPR 0 "=r,r"))]
3385 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3386 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3390 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3392 (and:GPR (match_dup 1)
3395 (compare:CC (match_dup 0)
3398 [(set_attr "type" "logical")
3399 (set_attr "dot" "yes")
3400 (set_attr "length" "4,8")])
3402 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3403 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3404 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3405 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3407 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3408 (and:GPR (match_dup 1)
3410 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3411 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3415 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3417 (and:GPR (match_dup 1)
3420 (compare:CC (match_dup 0)
3423 [(set_attr "type" "logical")
3424 (set_attr "dot" "yes")
3425 (set_attr "length" "4,8")])
3427 (define_insn "*and<mode>3_imm_dot_shifted"
3428 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3431 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3432 (match_operand:SI 4 "const_int_operand" "n"))
3433 (match_operand:GPR 2 "const_int_operand" "n"))
3435 (clobber (match_scratch:GPR 0 "=r"))]
3436 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3437 << INTVAL (operands[4])),
3439 && (<MODE>mode == Pmode
3440 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3442 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3443 return "andi%e2. %0,%1,%u2";
3445 [(set_attr "type" "logical")
3446 (set_attr "dot" "yes")])
3449 (define_insn "and<mode>3_mask"
3450 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3451 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3452 (match_operand:GPR 2 "const_int_operand" "n")))]
3453 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3455 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3457 [(set_attr "type" "shift")])
3459 (define_insn_and_split "*and<mode>3_mask_dot"
3460 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3461 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3462 (match_operand:GPR 2 "const_int_operand" "n,n"))
3464 (clobber (match_scratch:GPR 0 "=r,r"))]
3465 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3466 && !logical_const_operand (operands[2], <MODE>mode)
3467 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3469 if (which_alternative == 0)
3470 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3474 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3476 (and:GPR (match_dup 1)
3479 (compare:CC (match_dup 0)
3482 [(set_attr "type" "shift")
3483 (set_attr "dot" "yes")
3484 (set_attr "length" "4,8")])
3486 (define_insn_and_split "*and<mode>3_mask_dot2"
3487 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3488 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3489 (match_operand:GPR 2 "const_int_operand" "n,n"))
3491 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3492 (and:GPR (match_dup 1)
3494 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3495 && !logical_const_operand (operands[2], <MODE>mode)
3496 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3498 if (which_alternative == 0)
3499 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3503 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3505 (and:GPR (match_dup 1)
3508 (compare:CC (match_dup 0)
3511 [(set_attr "type" "shift")
3512 (set_attr "dot" "yes")
3513 (set_attr "length" "4,8")])
3516 (define_insn_and_split "*and<mode>3_2insn"
3517 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3518 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3519 (match_operand:GPR 2 "const_int_operand" "n")))]
3520 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3521 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3522 || logical_const_operand (operands[2], <MODE>mode))"
3527 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3530 [(set_attr "type" "shift")
3531 (set_attr "length" "8")])
3533 (define_insn_and_split "*and<mode>3_2insn_dot"
3534 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3535 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3536 (match_operand:GPR 2 "const_int_operand" "n,n"))
3538 (clobber (match_scratch:GPR 0 "=r,r"))]
3539 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3540 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3541 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3542 || logical_const_operand (operands[2], <MODE>mode))"
3544 "&& reload_completed"
3547 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3550 [(set_attr "type" "shift")
3551 (set_attr "dot" "yes")
3552 (set_attr "length" "8,12")])
3554 (define_insn_and_split "*and<mode>3_2insn_dot2"
3555 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3556 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3557 (match_operand:GPR 2 "const_int_operand" "n,n"))
3559 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3560 (and:GPR (match_dup 1)
3562 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3563 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3564 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3565 || logical_const_operand (operands[2], <MODE>mode))"
3567 "&& reload_completed"
3570 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3573 [(set_attr "type" "shift")
3574 (set_attr "dot" "yes")
3575 (set_attr "length" "8,12")])
3578 (define_expand "<code><mode>3"
3579 [(set (match_operand:SDI 0 "gpc_reg_operand")
3580 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3581 (match_operand:SDI 2 "reg_or_cint_operand")))]
3584 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3586 rs6000_split_logical (operands, <CODE>, false, false, false);
3590 if (non_logical_cint_operand (operands[2], <MODE>mode))
3592 rtx tmp = ((!can_create_pseudo_p ()
3593 || rtx_equal_p (operands[0], operands[1]))
3594 ? operands[0] : gen_reg_rtx (<MODE>mode));
3596 HOST_WIDE_INT value = INTVAL (operands[2]);
3597 HOST_WIDE_INT lo = value & 0xffff;
3598 HOST_WIDE_INT hi = value - lo;
3600 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3601 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3605 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3606 operands[2] = force_reg (<MODE>mode, operands[2]);
3610 [(set (match_operand:GPR 0 "gpc_reg_operand")
3611 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3612 (match_operand:GPR 2 "non_logical_cint_operand")))]
3615 (iorxor:GPR (match_dup 1)
3618 (iorxor:GPR (match_dup 3)
3621 operands[3] = ((!can_create_pseudo_p ()
3622 || rtx_equal_p (operands[0], operands[1]))
3623 ? operands[0] : gen_reg_rtx (<MODE>mode));
3625 HOST_WIDE_INT value = INTVAL (operands[2]);
3626 HOST_WIDE_INT lo = value & 0xffff;
3627 HOST_WIDE_INT hi = value - lo;
3629 operands[4] = GEN_INT (hi);
3630 operands[5] = GEN_INT (lo);
3633 (define_insn "*bool<mode>3_imm"
3634 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3635 (match_operator:GPR 3 "boolean_or_operator"
3636 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3637 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3640 [(set_attr "type" "logical")])
3642 (define_insn "*bool<mode>3"
3643 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3644 (match_operator:GPR 3 "boolean_operator"
3645 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3646 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3649 [(set_attr "type" "logical")])
3651 (define_insn_and_split "*bool<mode>3_dot"
3652 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3653 (compare:CC (match_operator:GPR 3 "boolean_operator"
3654 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3655 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3657 (clobber (match_scratch:GPR 0 "=r,r"))]
3658 "<MODE>mode == Pmode"
3662 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3666 (compare:CC (match_dup 0)
3669 [(set_attr "type" "logical")
3670 (set_attr "dot" "yes")
3671 (set_attr "length" "4,8")])
3673 (define_insn_and_split "*bool<mode>3_dot2"
3674 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3675 (compare:CC (match_operator:GPR 3 "boolean_operator"
3676 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3677 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3679 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3681 "<MODE>mode == Pmode"
3685 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3689 (compare:CC (match_dup 0)
3692 [(set_attr "type" "logical")
3693 (set_attr "dot" "yes")
3694 (set_attr "length" "4,8")])
3697 (define_insn "*boolc<mode>3"
3698 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3699 (match_operator:GPR 3 "boolean_operator"
3700 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3701 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3704 [(set_attr "type" "logical")])
3706 (define_insn_and_split "*boolc<mode>3_dot"
3707 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3708 (compare:CC (match_operator:GPR 3 "boolean_operator"
3709 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3710 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3712 (clobber (match_scratch:GPR 0 "=r,r"))]
3713 "<MODE>mode == Pmode"
3717 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3721 (compare:CC (match_dup 0)
3724 [(set_attr "type" "logical")
3725 (set_attr "dot" "yes")
3726 (set_attr "length" "4,8")])
3728 (define_insn_and_split "*boolc<mode>3_dot2"
3729 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3730 (compare:CC (match_operator:GPR 3 "boolean_operator"
3731 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3732 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3734 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3736 "<MODE>mode == Pmode"
3740 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3744 (compare:CC (match_dup 0)
3747 [(set_attr "type" "logical")
3748 (set_attr "dot" "yes")
3749 (set_attr "length" "4,8")])
3752 (define_insn "*boolcc<mode>3"
3753 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3754 (match_operator:GPR 3 "boolean_operator"
3755 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3756 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3759 [(set_attr "type" "logical")])
3761 (define_insn_and_split "*boolcc<mode>3_dot"
3762 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3763 (compare:CC (match_operator:GPR 3 "boolean_operator"
3764 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3765 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3767 (clobber (match_scratch:GPR 0 "=r,r"))]
3768 "<MODE>mode == Pmode"
3772 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3776 (compare:CC (match_dup 0)
3779 [(set_attr "type" "logical")
3780 (set_attr "dot" "yes")
3781 (set_attr "length" "4,8")])
3783 (define_insn_and_split "*boolcc<mode>3_dot2"
3784 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3785 (compare:CC (match_operator:GPR 3 "boolean_operator"
3786 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3787 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3789 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3791 "<MODE>mode == Pmode"
3795 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3799 (compare:CC (match_dup 0)
3802 [(set_attr "type" "logical")
3803 (set_attr "dot" "yes")
3804 (set_attr "length" "4,8")])
3807 ;; TODO: Should have dots of this as well.
3808 (define_insn "*eqv<mode>3"
3809 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3810 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3811 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3814 [(set_attr "type" "logical")])
3816 ;; Rotate-and-mask and insert.
3818 (define_insn "*rotl<mode>3_mask"
3819 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3820 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3821 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3822 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3823 (match_operand:GPR 3 "const_int_operand" "n")))]
3824 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3826 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3828 [(set_attr "type" "shift")
3829 (set_attr "maybe_var_shift" "yes")])
3831 (define_insn_and_split "*rotl<mode>3_mask_dot"
3832 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3834 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3835 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3836 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3837 (match_operand:GPR 3 "const_int_operand" "n,n"))
3839 (clobber (match_scratch:GPR 0 "=r,r"))]
3840 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3841 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3843 if (which_alternative == 0)
3844 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3848 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3850 (and:GPR (match_dup 4)
3853 (compare:CC (match_dup 0)
3856 [(set_attr "type" "shift")
3857 (set_attr "maybe_var_shift" "yes")
3858 (set_attr "dot" "yes")
3859 (set_attr "length" "4,8")])
3861 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3862 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3864 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3865 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3866 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3867 (match_operand:GPR 3 "const_int_operand" "n,n"))
3869 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3870 (and:GPR (match_dup 4)
3872 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3873 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3875 if (which_alternative == 0)
3876 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3880 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3882 (and:GPR (match_dup 4)
3885 (compare:CC (match_dup 0)
3888 [(set_attr "type" "shift")
3889 (set_attr "maybe_var_shift" "yes")
3890 (set_attr "dot" "yes")
3891 (set_attr "length" "4,8")])
3893 ; Special case for less-than-0. We can do it with just one machine
3894 ; instruction, but the generic optimizers do not realise it is cheap.
3895 (define_insn "*lt0_<mode>di"
3896 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3897 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3901 [(set_attr "type" "shift")])
3903 (define_insn "*lt0_<mode>si"
3904 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3905 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3908 "rlwinm %0,%1,1,31,31"
3909 [(set_attr "type" "shift")])
3913 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3914 ; both are an AND so are the same precedence).
3915 (define_insn "*rotl<mode>3_insert"
3916 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3917 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3918 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3919 (match_operand:SI 2 "const_int_operand" "n")])
3920 (match_operand:GPR 3 "const_int_operand" "n"))
3921 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3922 (match_operand:GPR 6 "const_int_operand" "n"))))]
3923 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3924 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3926 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3928 [(set_attr "type" "insert")])
3929 ; FIXME: this needs an attr "size", so that the scheduler can see the
3930 ; difference between rlwimi and rldimi. We also might want dot forms,
3931 ; but not for rlwimi on POWER4 and similar processors.
3933 (define_insn "*rotl<mode>3_insert_2"
3934 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3935 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3936 (match_operand:GPR 6 "const_int_operand" "n"))
3937 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3938 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3939 (match_operand:SI 2 "const_int_operand" "n")])
3940 (match_operand:GPR 3 "const_int_operand" "n"))))]
3941 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3942 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3944 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3946 [(set_attr "type" "insert")])
3948 ; There are also some forms without one of the ANDs.
3949 (define_insn "*rotl<mode>3_insert_3"
3950 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3951 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3952 (match_operand:GPR 4 "const_int_operand" "n"))
3953 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3954 (match_operand:SI 2 "const_int_operand" "n"))))]
3955 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3957 if (<MODE>mode == SImode)
3958 return "rlwimi %0,%1,%h2,0,31-%h2";
3960 return "rldimi %0,%1,%H2,0";
3962 [(set_attr "type" "insert")])
3964 (define_insn "*rotl<mode>3_insert_4"
3965 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3966 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3967 (match_operand:GPR 4 "const_int_operand" "n"))
3968 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3969 (match_operand:SI 2 "const_int_operand" "n"))))]
3970 "<MODE>mode == SImode &&
3971 GET_MODE_PRECISION (<MODE>mode)
3972 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3974 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3975 - INTVAL (operands[2]));
3976 if (<MODE>mode == SImode)
3977 return "rlwimi %0,%1,%h2,32-%h2,31";
3979 return "rldimi %0,%1,%H2,64-%H2";
3981 [(set_attr "type" "insert")])
3983 (define_insn "*rotlsi3_insert_5"
3984 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3985 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3986 (match_operand:SI 2 "const_int_operand" "n,n"))
3987 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3988 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3989 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3990 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3991 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3995 [(set_attr "type" "insert")])
3997 (define_insn "*rotldi3_insert_6"
3998 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3999 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4000 (match_operand:DI 2 "const_int_operand" "n"))
4001 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4002 (match_operand:DI 4 "const_int_operand" "n"))))]
4003 "exact_log2 (-UINTVAL (operands[2])) > 0
4004 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4006 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4007 return "rldimi %0,%3,0,%5";
4009 [(set_attr "type" "insert")
4010 (set_attr "size" "64")])
4012 (define_insn "*rotldi3_insert_7"
4013 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4014 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
4015 (match_operand:DI 4 "const_int_operand" "n"))
4016 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
4017 (match_operand:DI 2 "const_int_operand" "n"))))]
4018 "exact_log2 (-UINTVAL (operands[2])) > 0
4019 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
4021 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
4022 return "rldimi %0,%3,0,%5";
4024 [(set_attr "type" "insert")
4025 (set_attr "size" "64")])
4028 ; This handles the important case of multiple-precision shifts. There is
4029 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
4031 [(set (match_operand:GPR 0 "gpc_reg_operand")
4032 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4033 (match_operand:SI 3 "const_int_operand"))
4034 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4035 (match_operand:SI 4 "const_int_operand"))))]
4036 "can_create_pseudo_p ()
4037 && INTVAL (operands[3]) + INTVAL (operands[4])
4038 >= GET_MODE_PRECISION (<MODE>mode)"
4040 (lshiftrt:GPR (match_dup 2)
4043 (ior:GPR (and:GPR (match_dup 5)
4045 (ashift:GPR (match_dup 1)
4048 unsigned HOST_WIDE_INT mask = 1;
4049 mask = (mask << INTVAL (operands[3])) - 1;
4050 operands[5] = gen_reg_rtx (<MODE>mode);
4051 operands[6] = GEN_INT (mask);
4055 [(set (match_operand:GPR 0 "gpc_reg_operand")
4056 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4057 (match_operand:SI 4 "const_int_operand"))
4058 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4059 (match_operand:SI 3 "const_int_operand"))))]
4060 "can_create_pseudo_p ()
4061 && INTVAL (operands[3]) + INTVAL (operands[4])
4062 >= GET_MODE_PRECISION (<MODE>mode)"
4064 (lshiftrt:GPR (match_dup 2)
4067 (ior:GPR (and:GPR (match_dup 5)
4069 (ashift:GPR (match_dup 1)
4072 unsigned HOST_WIDE_INT mask = 1;
4073 mask = (mask << INTVAL (operands[3])) - 1;
4074 operands[5] = gen_reg_rtx (<MODE>mode);
4075 operands[6] = GEN_INT (mask);
4079 ; Another important case is setting some bits to 1; we can do that with
4080 ; an insert instruction, in many cases.
4081 (define_insn_and_split "*ior<mode>_mask"
4082 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4083 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4084 (match_operand:GPR 2 "const_int_operand" "n")))
4085 (clobber (match_scratch:GPR 3 "=r"))]
4086 "!logical_const_operand (operands[2], <MODE>mode)
4087 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4093 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4096 (and:GPR (match_dup 1)
4100 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4101 if (GET_CODE (operands[3]) == SCRATCH)
4102 operands[3] = gen_reg_rtx (<MODE>mode);
4103 operands[4] = GEN_INT (ne);
4104 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4106 [(set_attr "type" "two")
4107 (set_attr "length" "8")])
4110 ; Yet another case is an rldimi with the second value coming from memory.
4111 ; The zero_extend that should become part of the rldimi is merged into the
4112 ; load from memory instead. Split things properly again.
4114 [(set (match_operand:DI 0 "gpc_reg_operand")
4115 (ior:DI (ashift:DI (match_operand:DI 1 "gpc_reg_operand")
4116 (match_operand:SI 2 "const_int_operand"))
4117 (zero_extend:DI (match_operand:QHSI 3 "memory_operand"))))]
4118 "INTVAL (operands[2]) == <bits>"
4120 (zero_extend:DI (match_dup 3)))
4122 (ior:DI (and:DI (match_dup 4)
4124 (ashift:DI (match_dup 1)
4127 operands[4] = gen_reg_rtx (DImode);
4128 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4133 [(set (match_operand:SI 0 "gpc_reg_operand")
4134 (ior:SI (ashift:SI (match_operand:SI 1 "gpc_reg_operand")
4135 (match_operand:SI 2 "const_int_operand"))
4136 (zero_extend:SI (match_operand:QHI 3 "memory_operand"))))]
4137 "INTVAL (operands[2]) == <bits>"
4139 (zero_extend:SI (match_dup 3)))
4141 (ior:SI (and:SI (match_dup 4)
4143 (ashift:SI (match_dup 1)
4146 operands[4] = gen_reg_rtx (SImode);
4147 operands[5] = GEN_INT ((HOST_WIDE_INT_1U << <bits>) - 1);
4151 ;; Now the simple shifts.
4153 (define_insn "rotl<mode>3"
4154 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4155 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4156 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4158 "rotl<wd>%I2 %0,%1,%<hH>2"
4159 [(set_attr "type" "shift")
4160 (set_attr "maybe_var_shift" "yes")])
4162 (define_insn "*rotlsi3_64"
4163 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4165 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4166 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4168 "rotlw%I2 %0,%1,%h2"
4169 [(set_attr "type" "shift")
4170 (set_attr "maybe_var_shift" "yes")])
4172 (define_insn_and_split "*rotl<mode>3_dot"
4173 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4174 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4175 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4177 (clobber (match_scratch:GPR 0 "=r,r"))]
4178 "<MODE>mode == Pmode"
4180 rotl<wd>%I2. %0,%1,%<hH>2
4182 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4184 (rotate:GPR (match_dup 1)
4187 (compare:CC (match_dup 0)
4190 [(set_attr "type" "shift")
4191 (set_attr "maybe_var_shift" "yes")
4192 (set_attr "dot" "yes")
4193 (set_attr "length" "4,8")])
4195 (define_insn_and_split "*rotl<mode>3_dot2"
4196 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4197 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4198 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4200 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4201 (rotate:GPR (match_dup 1)
4203 "<MODE>mode == Pmode"
4205 rotl<wd>%I2. %0,%1,%<hH>2
4207 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4209 (rotate:GPR (match_dup 1)
4212 (compare:CC (match_dup 0)
4215 [(set_attr "type" "shift")
4216 (set_attr "maybe_var_shift" "yes")
4217 (set_attr "dot" "yes")
4218 (set_attr "length" "4,8")])
4221 (define_insn "ashl<mode>3"
4222 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4223 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4224 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4226 "sl<wd>%I2 %0,%1,%<hH>2"
4227 [(set_attr "type" "shift")
4228 (set_attr "maybe_var_shift" "yes")])
4230 (define_insn "*ashlsi3_64"
4231 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4233 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4234 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4237 [(set_attr "type" "shift")
4238 (set_attr "maybe_var_shift" "yes")])
4240 (define_insn_and_split "*ashl<mode>3_dot"
4241 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4242 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4243 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4245 (clobber (match_scratch:GPR 0 "=r,r"))]
4246 "<MODE>mode == Pmode"
4248 sl<wd>%I2. %0,%1,%<hH>2
4250 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4252 (ashift:GPR (match_dup 1)
4255 (compare:CC (match_dup 0)
4258 [(set_attr "type" "shift")
4259 (set_attr "maybe_var_shift" "yes")
4260 (set_attr "dot" "yes")
4261 (set_attr "length" "4,8")])
4263 (define_insn_and_split "*ashl<mode>3_dot2"
4264 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4265 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4266 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4268 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4269 (ashift:GPR (match_dup 1)
4271 "<MODE>mode == Pmode"
4273 sl<wd>%I2. %0,%1,%<hH>2
4275 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4277 (ashift:GPR (match_dup 1)
4280 (compare:CC (match_dup 0)
4283 [(set_attr "type" "shift")
4284 (set_attr "maybe_var_shift" "yes")
4285 (set_attr "dot" "yes")
4286 (set_attr "length" "4,8")])
4288 ;; Pretend we have a memory form of extswsli until register allocation is done
4289 ;; so that we use LWZ to load the value from memory, instead of LWA.
4290 (define_insn_and_split "ashdi3_extswsli"
4291 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4293 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4294 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4299 "&& reload_completed && MEM_P (operands[1])"
4303 (ashift:DI (sign_extend:DI (match_dup 3))
4306 operands[3] = gen_lowpart (SImode, operands[0]);
4308 [(set_attr "type" "shift")
4309 (set_attr "maybe_var_shift" "no")])
4312 (define_insn_and_split "ashdi3_extswsli_dot"
4313 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4316 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4317 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4319 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4326 "&& reload_completed
4327 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4328 || memory_operand (operands[1], SImode))"
4331 rtx dest = operands[0];
4332 rtx src = operands[1];
4333 rtx shift = operands[2];
4334 rtx cr = operands[3];
4341 src2 = gen_lowpart (SImode, dest);
4342 emit_move_insn (src2, src);
4345 if (REGNO (cr) == CR0_REGNO)
4347 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4351 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4352 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4355 [(set_attr "type" "shift")
4356 (set_attr "maybe_var_shift" "no")
4357 (set_attr "dot" "yes")
4358 (set_attr "length" "4,8,8,12")])
4360 (define_insn_and_split "ashdi3_extswsli_dot2"
4361 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4364 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4365 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4367 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4368 (ashift:DI (sign_extend:DI (match_dup 1))
4376 "&& reload_completed
4377 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4378 || memory_operand (operands[1], SImode))"
4381 rtx dest = operands[0];
4382 rtx src = operands[1];
4383 rtx shift = operands[2];
4384 rtx cr = operands[3];
4391 src2 = gen_lowpart (SImode, dest);
4392 emit_move_insn (src2, src);
4395 if (REGNO (cr) == CR0_REGNO)
4397 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4401 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4402 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4405 [(set_attr "type" "shift")
4406 (set_attr "maybe_var_shift" "no")
4407 (set_attr "dot" "yes")
4408 (set_attr "length" "4,8,8,12")])
4410 (define_insn "lshr<mode>3"
4411 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4412 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4413 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4415 "sr<wd>%I2 %0,%1,%<hH>2"
4416 [(set_attr "type" "shift")
4417 (set_attr "maybe_var_shift" "yes")])
4419 (define_insn "*lshrsi3_64"
4420 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4422 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4423 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4426 [(set_attr "type" "shift")
4427 (set_attr "maybe_var_shift" "yes")])
4429 (define_insn_and_split "*lshr<mode>3_dot"
4430 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4431 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4432 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4434 (clobber (match_scratch:GPR 0 "=r,r"))]
4435 "<MODE>mode == Pmode"
4437 sr<wd>%I2. %0,%1,%<hH>2
4439 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4441 (lshiftrt:GPR (match_dup 1)
4444 (compare:CC (match_dup 0)
4447 [(set_attr "type" "shift")
4448 (set_attr "maybe_var_shift" "yes")
4449 (set_attr "dot" "yes")
4450 (set_attr "length" "4,8")])
4452 (define_insn_and_split "*lshr<mode>3_dot2"
4453 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4454 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4455 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4457 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4458 (lshiftrt:GPR (match_dup 1)
4460 "<MODE>mode == Pmode"
4462 sr<wd>%I2. %0,%1,%<hH>2
4464 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4466 (lshiftrt:GPR (match_dup 1)
4469 (compare:CC (match_dup 0)
4472 [(set_attr "type" "shift")
4473 (set_attr "maybe_var_shift" "yes")
4474 (set_attr "dot" "yes")
4475 (set_attr "length" "4,8")])
4478 (define_insn "ashr<mode>3"
4479 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4480 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4481 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4482 (clobber (reg:GPR CA_REGNO))]
4484 "sra<wd>%I2 %0,%1,%<hH>2"
4485 [(set_attr "type" "shift")
4486 (set_attr "maybe_var_shift" "yes")])
4488 (define_insn "*ashrsi3_64"
4489 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4491 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4492 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4493 (clobber (reg:SI CA_REGNO))]
4496 [(set_attr "type" "shift")
4497 (set_attr "maybe_var_shift" "yes")])
4499 (define_insn_and_split "*ashr<mode>3_dot"
4500 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4501 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4502 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4504 (clobber (match_scratch:GPR 0 "=r,r"))
4505 (clobber (reg:GPR CA_REGNO))]
4506 "<MODE>mode == Pmode"
4508 sra<wd>%I2. %0,%1,%<hH>2
4510 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4511 [(parallel [(set (match_dup 0)
4512 (ashiftrt:GPR (match_dup 1)
4514 (clobber (reg:GPR CA_REGNO))])
4516 (compare:CC (match_dup 0)
4519 [(set_attr "type" "shift")
4520 (set_attr "maybe_var_shift" "yes")
4521 (set_attr "dot" "yes")
4522 (set_attr "length" "4,8")])
4524 (define_insn_and_split "*ashr<mode>3_dot2"
4525 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4526 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4527 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4529 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4530 (ashiftrt:GPR (match_dup 1)
4532 (clobber (reg:GPR CA_REGNO))]
4533 "<MODE>mode == Pmode"
4535 sra<wd>%I2. %0,%1,%<hH>2
4537 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4538 [(parallel [(set (match_dup 0)
4539 (ashiftrt:GPR (match_dup 1)
4541 (clobber (reg:GPR CA_REGNO))])
4543 (compare:CC (match_dup 0)
4546 [(set_attr "type" "shift")
4547 (set_attr "maybe_var_shift" "yes")
4548 (set_attr "dot" "yes")
4549 (set_attr "length" "4,8")])
4551 ;; Builtins to replace a division to generate FRE reciprocal estimate
4552 ;; instructions and the necessary fixup instructions
4553 (define_expand "recip<mode>3"
4554 [(match_operand:RECIPF 0 "gpc_reg_operand")
4555 (match_operand:RECIPF 1 "gpc_reg_operand")
4556 (match_operand:RECIPF 2 "gpc_reg_operand")]
4557 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4559 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4563 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4564 ;; hardware division. This is only done before register allocation and with
4565 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4566 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4567 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4569 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4570 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4571 (match_operand 2 "gpc_reg_operand")))]
4572 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4573 && can_create_pseudo_p () && flag_finite_math_only
4574 && !flag_trapping_math && flag_reciprocal_math"
4577 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4581 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4582 ;; appropriate fixup.
4583 (define_expand "rsqrt<mode>2"
4584 [(match_operand:RECIPF 0 "gpc_reg_operand")
4585 (match_operand:RECIPF 1 "gpc_reg_operand")]
4586 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4588 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4592 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4593 ;; modes here, and also add in conditional vsx/power8-vector support to access
4594 ;; values in the traditional Altivec registers if the appropriate
4595 ;; -mupper-regs-{df,sf} option is enabled.
4597 (define_expand "abs<mode>2"
4598 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4599 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4603 (define_insn "*abs<mode>2_fpr"
4604 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4605 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4610 [(set_attr "type" "fpsimple")])
4612 (define_insn "*nabs<mode>2_fpr"
4613 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4616 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4621 [(set_attr "type" "fpsimple")])
4623 (define_expand "neg<mode>2"
4624 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4625 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4629 (define_insn "*neg<mode>2_fpr"
4630 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4631 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4636 [(set_attr "type" "fpsimple")])
4638 (define_expand "add<mode>3"
4639 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4640 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4641 (match_operand:SFDF 2 "gpc_reg_operand")))]
4645 (define_insn "*add<mode>3_fpr"
4646 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4647 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4648 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4652 xsadd<sd>p %x0,%x1,%x2"
4653 [(set_attr "type" "fp")
4654 (set_attr "isa" "*,<Fisa>")])
4656 (define_expand "sub<mode>3"
4657 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4658 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4659 (match_operand:SFDF 2 "gpc_reg_operand")))]
4663 (define_insn "*sub<mode>3_fpr"
4664 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4665 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4666 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4670 xssub<sd>p %x0,%x1,%x2"
4671 [(set_attr "type" "fp")
4672 (set_attr "isa" "*,<Fisa>")])
4674 (define_expand "mul<mode>3"
4675 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4676 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4677 (match_operand:SFDF 2 "gpc_reg_operand")))]
4681 (define_insn "*mul<mode>3_fpr"
4682 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4683 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa")
4684 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4688 xsmul<sd>p %x0,%x1,%x2"
4689 [(set_attr "type" "dmul")
4690 (set_attr "isa" "*,<Fisa>")])
4692 (define_expand "div<mode>3"
4693 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4694 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4695 (match_operand:SFDF 2 "gpc_reg_operand")))]
4698 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4699 && can_create_pseudo_p () && flag_finite_math_only
4700 && !flag_trapping_math && flag_reciprocal_math)
4702 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4707 (define_insn "*div<mode>3_fpr"
4708 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4709 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4710 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4714 xsdiv<sd>p %x0,%x1,%x2"
4715 [(set_attr "type" "<sd>div")
4716 (set_attr "isa" "*,<Fisa>")])
4718 (define_insn "*sqrt<mode>2_internal"
4719 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4720 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")))]
4721 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4724 xssqrt<sd>p %x0,%x1"
4725 [(set_attr "type" "<sd>sqrt")
4726 (set_attr "isa" "*,<Fisa>")])
4728 (define_expand "sqrt<mode>2"
4729 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4730 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4731 "TARGET_HARD_FLOAT && TARGET_PPC_GPOPT"
4733 if (<MODE>mode == SFmode
4734 && TARGET_RECIP_PRECISION
4735 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4736 && !optimize_function_for_size_p (cfun)
4737 && flag_finite_math_only && !flag_trapping_math
4738 && flag_unsafe_math_optimizations)
4740 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4745 ;; Floating point reciprocal approximation
4746 (define_insn "fre<sd>"
4747 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4748 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4754 [(set_attr "type" "fp")
4755 (set_attr "isa" "*,<Fisa>")])
4757 (define_insn "*rsqrt<mode>2"
4758 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa")
4759 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")]
4761 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4764 xsrsqrte<sd>p %x0,%x1"
4765 [(set_attr "type" "fp")
4766 (set_attr "isa" "*,<Fisa>")])
4768 ;; Floating point comparisons
4769 (define_insn "*cmp<mode>_fpr"
4770 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4771 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa")
4772 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa")))]
4776 xscmpudp %0,%x1,%x2"
4777 [(set_attr "type" "fpcompare")
4778 (set_attr "isa" "*,<Fisa>")])
4780 ;; Floating point conversions
4781 (define_expand "extendsfdf2"
4782 [(set (match_operand:DF 0 "gpc_reg_operand")
4783 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4786 if (HONOR_SNANS (SFmode))
4787 operands[1] = force_reg (SFmode, operands[1]);
4790 (define_insn_and_split "*extendsfdf2_fpr"
4791 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,wa,?wa,wa,v")
4792 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wa,Z,wY")))]
4793 "TARGET_HARD_FLOAT && !HONOR_SNANS (SFmode)"
4799 xscpsgndp %x0,%x1,%x1
4802 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4805 emit_note (NOTE_INSN_DELETED);
4808 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")
4809 (set_attr "isa" "*,*,*,*,p8v,p8v,p9v")])
4811 (define_insn "*extendsfdf2_snan"
4812 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
4813 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wa")))]
4814 "TARGET_HARD_FLOAT && HONOR_SNANS (SFmode)"
4818 [(set_attr "type" "fp")
4819 (set_attr "isa" "*,p8v")])
4821 (define_expand "truncdfsf2"
4822 [(set (match_operand:SF 0 "gpc_reg_operand")
4823 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4827 (define_insn "*truncdfsf2_fpr"
4828 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
4829 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,wa")))]
4834 [(set_attr "type" "fp")
4835 (set_attr "isa" "*,p8v")])
4837 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4838 ;; builtins.c and optabs.c that are not correct for IBM long double
4839 ;; when little-endian.
4840 (define_expand "signbit<mode>2"
4842 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4844 (subreg:DI (match_dup 2) 0))
4847 (set (match_operand:SI 0 "gpc_reg_operand")
4850 && (!FLOAT128_IEEE_P (<MODE>mode)
4851 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4853 if (FLOAT128_IEEE_P (<MODE>mode))
4855 rtx dest = operands[0];
4856 rtx src = operands[1];
4857 rtx tmp = gen_reg_rtx (DImode);
4858 rtx dest_di = gen_lowpart (DImode, dest);
4860 emit_insn (gen_signbit2_dm (<MODE>mode, tmp, src));
4861 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4864 operands[2] = gen_reg_rtx (DFmode);
4865 operands[3] = gen_reg_rtx (DImode);
4866 if (TARGET_POWERPC64)
4868 operands[4] = gen_reg_rtx (DImode);
4869 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4870 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4871 WORDS_BIG_ENDIAN ? 4 : 0);
4875 operands[4] = gen_reg_rtx (SImode);
4876 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4877 WORDS_BIG_ENDIAN ? 0 : 4);
4878 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4882 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4883 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4884 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4885 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4887 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4888 ;; split allows the post reload phases to eliminate the move, and do the shift
4889 ;; directly with the register that contains the signbit.
4890 (define_insn_and_split "@signbit<mode>2_dm"
4891 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4892 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4894 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4898 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4902 operands[2] = gen_highpart (DImode, operands[1]);
4904 [(set_attr "type" "mftgpr,*")])
4906 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4907 ;; register and then doing a direct move if the value comes from memory. On
4908 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4909 (define_insn_and_split "*signbit<mode>2_dm_mem"
4910 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4911 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4913 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4919 rtx dest = operands[0];
4920 rtx src = operands[1];
4921 rtx addr = XEXP (src, 0);
4923 if (WORDS_BIG_ENDIAN)
4924 operands[2] = adjust_address (src, DImode, 0);
4926 else if (REG_P (addr) || SUBREG_P (addr))
4927 operands[2] = adjust_address (src, DImode, 8);
4929 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4930 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4931 operands[2] = adjust_address (src, DImode, 8);
4935 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4936 emit_insn (gen_rtx_SET (tmp, addr));
4937 operands[2] = change_address (src, DImode,
4938 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4942 (define_expand "copysign<mode>3"
4944 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4946 (neg:SFDF (abs:SFDF (match_dup 1))))
4947 (set (match_operand:SFDF 0 "gpc_reg_operand")
4948 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4953 && ((TARGET_PPC_GFXOPT
4954 && !HONOR_NANS (<MODE>mode)
4955 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4957 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4959 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4961 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4966 operands[3] = gen_reg_rtx (<MODE>mode);
4967 operands[4] = gen_reg_rtx (<MODE>mode);
4968 operands[5] = CONST0_RTX (<MODE>mode);
4971 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4972 ;; compiler from optimizing -0.0
4973 (define_insn "copysign<mode>3_fcpsgn"
4974 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4975 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4976 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4978 "TARGET_HARD_FLOAT && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4981 xscpsgndp %x0,%x2,%x1"
4982 [(set_attr "type" "fpsimple")])
4984 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4985 ;; fsel instruction and some auxiliary computations. Then we just have a
4986 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4988 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4989 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4990 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4991 ;; define_splits to make them if made by combine. On VSX machines we have the
4992 ;; min/max instructions.
4994 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4995 ;; to allow either DF/SF to use only traditional registers.
4997 (define_expand "s<minmax><mode>3"
4998 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4999 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5000 (match_operand:SFDF 2 "gpc_reg_operand")))]
5003 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5007 (define_insn "*s<minmax><mode>3_vsx"
5008 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5009 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
5010 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
5011 "TARGET_VSX && TARGET_HARD_FLOAT"
5013 return (TARGET_P9_MINMAX
5014 ? "xs<minmax>cdp %x0,%x1,%x2"
5015 : "xs<minmax>dp %x0,%x1,%x2");
5017 [(set_attr "type" "fp")])
5019 ;; The conditional move instructions allow us to perform max and min operations
5020 ;; even when we don't have the appropriate max/min instruction using the FSEL
5023 (define_insn_and_split "*s<minmax><mode>3_fpr"
5024 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5025 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
5026 (match_operand:SFDF 2 "gpc_reg_operand")))]
5027 "!TARGET_VSX && TARGET_MINMAX"
5032 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
5036 (define_expand "mov<mode>cc"
5037 [(set (match_operand:GPR 0 "gpc_reg_operand")
5038 (if_then_else:GPR (match_operand 1 "comparison_operator")
5039 (match_operand:GPR 2 "gpc_reg_operand")
5040 (match_operand:GPR 3 "gpc_reg_operand")))]
5043 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5049 ;; We use the BASE_REGS for the isel input operands because, if rA is
5050 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
5051 ;; because we may switch the operands and rB may end up being rA.
5053 ;; We need 2 patterns: an unsigned and a signed pattern. We could
5054 ;; leave out the mode in operand 4 and use one pattern, but reload can
5055 ;; change the mode underneath our feet and then gets confused trying
5056 ;; to reload the value.
5057 (define_mode_iterator CCEITHER [CC CCUNS])
5058 (define_mode_attr un [(CC "") (CCUNS "un")])
5059 (define_insn "isel_<un>signed_<GPR:mode>"
5060 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5062 (match_operator 1 "scc_comparison_operator"
5063 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5065 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5066 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5069 [(set_attr "type" "isel")])
5071 ;; These patterns can be useful for combine; they let combine know that
5072 ;; isel can handle reversed comparisons so long as the operands are
5075 (define_insn "*isel_reversed_<un>signed_<GPR:mode>"
5076 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5078 (match_operator 1 "scc_rev_comparison_operator"
5079 [(match_operand:CCEITHER 4 "cc_reg_operand" "y,y")
5081 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5082 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5085 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5086 return "isel %0,%3,%2,%j1";
5088 [(set_attr "type" "isel")])
5090 ;; Floating point conditional move
5091 (define_expand "mov<mode>cc"
5092 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5093 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5094 (match_operand:SFDF 2 "gpc_reg_operand")
5095 (match_operand:SFDF 3 "gpc_reg_operand")))]
5096 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5098 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5104 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5105 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5107 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5108 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5109 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5110 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5111 "TARGET_HARD_FLOAT && TARGET_PPC_GFXOPT"
5113 [(set_attr "type" "fp")])
5115 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5116 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5118 (match_operator:CCFP 1 "fpmask_comparison_operator"
5119 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5120 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5121 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5122 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5123 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5128 (if_then_else:V2DI (match_dup 1)
5132 (if_then_else:SFDF (ne (match_dup 6)
5137 if (GET_CODE (operands[6]) == SCRATCH)
5138 operands[6] = gen_reg_rtx (V2DImode);
5140 operands[7] = CONSTM1_RTX (V2DImode);
5141 operands[8] = CONST0_RTX (V2DImode);
5143 [(set_attr "length" "8")
5144 (set_attr "type" "vecperm")])
5146 ;; Handle inverting the fpmask comparisons.
5147 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5148 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5150 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5151 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5152 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5153 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5154 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5155 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5160 (if_then_else:V2DI (match_dup 9)
5164 (if_then_else:SFDF (ne (match_dup 6)
5169 rtx op1 = operands[1];
5170 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5172 if (GET_CODE (operands[6]) == SCRATCH)
5173 operands[6] = gen_reg_rtx (V2DImode);
5175 operands[7] = CONSTM1_RTX (V2DImode);
5176 operands[8] = CONST0_RTX (V2DImode);
5178 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5180 [(set_attr "length" "8")
5181 (set_attr "type" "vecperm")])
5183 (define_insn "*fpmask<mode>"
5184 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5186 (match_operator:CCFP 1 "fpmask_comparison_operator"
5187 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5188 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5189 (match_operand:V2DI 4 "all_ones_constant" "")
5190 (match_operand:V2DI 5 "zero_constant" "")))]
5192 "xscmp%V1dp %x0,%x2,%x3"
5193 [(set_attr "type" "fpcompare")])
5195 (define_insn "*xxsel<mode>"
5196 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5197 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5198 (match_operand:V2DI 2 "zero_constant" ""))
5199 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5200 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5202 "xxsel %x0,%x4,%x3,%x1"
5203 [(set_attr "type" "vecmove")])
5206 ;; Conversions to and from floating-point.
5208 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5209 ; don't want to support putting SImode in FPR registers.
5210 (define_insn "lfiwax"
5211 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,v")
5212 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,v")]
5214 "TARGET_HARD_FLOAT && TARGET_LFIWAX"
5220 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")
5221 (set_attr "isa" "*,p8v,p8v,p9v")])
5223 ; This split must be run before register allocation because it allocates the
5224 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5225 ; it earlier to allow for the combiner to merge insns together where it might
5226 ; not be needed and also in case the insns are deleted as dead code.
5228 (define_insn_and_split "floatsi<mode>2_lfiwax"
5229 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5230 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5231 (clobber (match_scratch:DI 2 "=d,wa"))]
5232 "TARGET_HARD_FLOAT && TARGET_LFIWAX
5233 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5238 rtx dest = operands[0];
5239 rtx src = operands[1];
5242 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5243 tmp = convert_to_mode (DImode, src, false);
5247 if (GET_CODE (tmp) == SCRATCH)
5248 tmp = gen_reg_rtx (DImode);
5251 src = rs6000_force_indexed_or_indirect_mem (src);
5252 emit_insn (gen_lfiwax (tmp, src));
5256 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5257 emit_move_insn (stack, src);
5258 emit_insn (gen_lfiwax (tmp, stack));
5261 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5264 [(set_attr "length" "12")
5265 (set_attr "type" "fpload")])
5267 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5268 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5271 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5272 (clobber (match_scratch:DI 2 "=d,wa"))]
5273 "TARGET_HARD_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5278 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5279 if (GET_CODE (operands[2]) == SCRATCH)
5280 operands[2] = gen_reg_rtx (DImode);
5281 if (TARGET_P8_VECTOR)
5282 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5284 emit_insn (gen_lfiwax (operands[2], operands[1]));
5285 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5288 [(set_attr "length" "8")
5289 (set_attr "type" "fpload")])
5291 (define_insn "lfiwzx"
5292 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa,wa,wa")
5293 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wa")]
5295 "TARGET_HARD_FLOAT && TARGET_LFIWZX"
5300 xxextractuw %x0,%x1,4"
5301 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")
5302 (set_attr "isa" "*,p8v,p8v,p9v")])
5304 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5305 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5306 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r,r")))
5307 (clobber (match_scratch:DI 2 "=d,wa"))]
5308 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5313 rtx dest = operands[0];
5314 rtx src = operands[1];
5317 if (!MEM_P (src) && TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5318 tmp = convert_to_mode (DImode, src, true);
5322 if (GET_CODE (tmp) == SCRATCH)
5323 tmp = gen_reg_rtx (DImode);
5326 src = rs6000_force_indexed_or_indirect_mem (src);
5327 emit_insn (gen_lfiwzx (tmp, src));
5331 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5332 emit_move_insn (stack, src);
5333 emit_insn (gen_lfiwzx (tmp, stack));
5336 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5339 [(set_attr "length" "12")
5340 (set_attr "type" "fpload")])
5342 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5343 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d,<Fv>")
5344 (unsigned_float:SFDF
5346 (match_operand:SI 1 "indexed_or_indirect_operand" "Z,Z"))))
5347 (clobber (match_scratch:DI 2 "=d,wa"))]
5348 "TARGET_HARD_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5353 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5354 if (GET_CODE (operands[2]) == SCRATCH)
5355 operands[2] = gen_reg_rtx (DImode);
5356 if (TARGET_P8_VECTOR)
5357 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5359 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5360 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5363 [(set_attr "length" "8")
5364 (set_attr "type" "fpload")])
5366 ; For each of these conversions, there is a define_expand, a define_insn
5367 ; with a '#' template, and a define_split (with C code). The idea is
5368 ; to allow constant folding with the template of the define_insn,
5369 ; then to have the insns split later (between sched1 and final).
5371 (define_expand "floatsidf2"
5372 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5373 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5376 (clobber (match_dup 4))
5377 (clobber (match_dup 5))
5378 (clobber (match_dup 6))])]
5381 if (TARGET_LFIWAX && TARGET_FCFID)
5383 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5386 else if (TARGET_FCFID)
5388 rtx dreg = operands[1];
5390 dreg = force_reg (SImode, dreg);
5391 dreg = convert_to_mode (DImode, dreg, false);
5392 emit_insn (gen_floatdidf2 (operands[0], dreg));
5396 if (!REG_P (operands[1]))
5397 operands[1] = force_reg (SImode, operands[1]);
5398 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5399 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5400 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5401 operands[5] = gen_reg_rtx (DFmode);
5402 operands[6] = gen_reg_rtx (SImode);
5405 (define_insn_and_split "*floatsidf2_internal"
5406 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5407 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5408 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5409 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5410 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5411 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5412 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5413 "!TARGET_FCFID && TARGET_HARD_FLOAT"
5418 rtx lowword, highword;
5419 gcc_assert (MEM_P (operands[4]));
5420 highword = adjust_address (operands[4], SImode, 0);
5421 lowword = adjust_address (operands[4], SImode, 4);
5422 if (! WORDS_BIG_ENDIAN)
5423 std::swap (lowword, highword);
5425 emit_insn (gen_xorsi3 (operands[6], operands[1],
5426 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5427 emit_move_insn (lowword, operands[6]);
5428 emit_move_insn (highword, operands[2]);
5429 emit_move_insn (operands[5], operands[4]);
5430 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5433 [(set_attr "length" "24")
5434 (set_attr "type" "fp")])
5436 ;; If we don't have a direct conversion to single precision, don't enable this
5437 ;; conversion for 32-bit without fast math, because we don't have the insn to
5438 ;; generate the fixup swizzle to avoid double rounding problems.
5439 (define_expand "floatunssisf2"
5440 [(set (match_operand:SF 0 "gpc_reg_operand")
5441 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5443 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5445 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5447 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5449 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5454 rtx dreg = operands[1];
5456 dreg = force_reg (SImode, dreg);
5457 dreg = convert_to_mode (DImode, dreg, true);
5458 emit_insn (gen_floatdisf2 (operands[0], dreg));
5463 (define_expand "floatunssidf2"
5464 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5465 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5468 (clobber (match_dup 4))
5469 (clobber (match_dup 5))])]
5472 if (TARGET_LFIWZX && TARGET_FCFID)
5474 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5477 else if (TARGET_FCFID)
5479 rtx dreg = operands[1];
5481 dreg = force_reg (SImode, dreg);
5482 dreg = convert_to_mode (DImode, dreg, true);
5483 emit_insn (gen_floatdidf2 (operands[0], dreg));
5487 if (!REG_P (operands[1]))
5488 operands[1] = force_reg (SImode, operands[1]);
5489 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5490 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5491 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5492 operands[5] = gen_reg_rtx (DFmode);
5495 (define_insn_and_split "*floatunssidf2_internal"
5496 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5497 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5498 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5499 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5500 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5501 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5502 "!TARGET_FCFIDU && TARGET_HARD_FLOAT
5503 && !(TARGET_FCFID && TARGET_POWERPC64)"
5508 rtx lowword, highword;
5509 gcc_assert (MEM_P (operands[4]));
5510 highword = adjust_address (operands[4], SImode, 0);
5511 lowword = adjust_address (operands[4], SImode, 4);
5512 if (! WORDS_BIG_ENDIAN)
5513 std::swap (lowword, highword);
5515 emit_move_insn (lowword, operands[1]);
5516 emit_move_insn (highword, operands[2]);
5517 emit_move_insn (operands[5], operands[4]);
5518 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5521 [(set_attr "length" "20")
5522 (set_attr "type" "fp")])
5524 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5525 ;; vector registers. These insns favor doing the sign/zero extension in
5526 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5527 ;; extension and then a direct move.
5529 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5530 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5532 (match_operand:QHI 1 "input_operand")))
5533 (clobber (match_scratch:DI 2))
5534 (clobber (match_scratch:DI 3))
5535 (clobber (match_scratch:<QHI:MODE> 4))])]
5536 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5538 if (MEM_P (operands[1]))
5539 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5542 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5543 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5545 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5546 (clobber (match_scratch:DI 2 "=v,wa,v"))
5547 (clobber (match_scratch:DI 3 "=X,r,X"))
5548 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,v"))]
5549 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5551 "&& reload_completed"
5554 rtx result = operands[0];
5555 rtx input = operands[1];
5556 rtx di = operands[2];
5560 rtx tmp = operands[3];
5561 if (altivec_register_operand (input, <QHI:MODE>mode))
5562 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5563 else if (GET_CODE (tmp) == SCRATCH)
5564 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5567 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5568 emit_move_insn (di, tmp);
5573 rtx tmp = operands[4];
5574 emit_move_insn (tmp, input);
5575 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5578 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5581 [(set_attr "isa" "p9v,*,p9v")])
5583 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5584 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5585 (unsigned_float:FP_ISA3
5586 (match_operand:QHI 1 "input_operand")))
5587 (clobber (match_scratch:DI 2))
5588 (clobber (match_scratch:DI 3))])]
5589 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5591 if (MEM_P (operands[1]))
5592 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
5595 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5596 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5597 (unsigned_float:FP_ISA3
5598 (match_operand:QHI 1 "reg_or_indexed_operand" "v,r,Z")))
5599 (clobber (match_scratch:DI 2 "=v,wa,wa"))
5600 (clobber (match_scratch:DI 3 "=X,r,X"))]
5601 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5603 "&& reload_completed"
5606 rtx result = operands[0];
5607 rtx input = operands[1];
5608 rtx di = operands[2];
5610 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5611 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5614 rtx tmp = operands[3];
5615 if (GET_CODE (tmp) == SCRATCH)
5616 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5619 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5620 emit_move_insn (di, tmp);
5624 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5627 [(set_attr "isa" "p9v,*,p9v")])
5629 (define_expand "fix_trunc<mode>si2"
5630 [(set (match_operand:SI 0 "gpc_reg_operand")
5631 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5634 if (!(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE))
5636 rtx src = force_reg (<MODE>mode, operands[1]);
5639 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5642 rtx tmp = gen_reg_rtx (DImode);
5643 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5644 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5651 ; Like the convert to float patterns, this insn must be split before
5652 ; register allocation so that it can allocate the memory slot if it
5654 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5655 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5656 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5657 (clobber (match_scratch:DI 2 "=d"))]
5658 "TARGET_HARD_FLOAT && TARGET_STFIWX && can_create_pseudo_p ()
5659 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5664 rtx dest = operands[0];
5665 rtx src = operands[1];
5666 rtx tmp = operands[2];
5668 if (GET_CODE (tmp) == SCRATCH)
5669 tmp = gen_reg_rtx (DImode);
5671 emit_insn (gen_fctiwz_<mode> (tmp, src));
5672 if (MEM_P (dest) && (TARGET_MFCRF || MEM_ALIGN (dest) >= 32))
5674 dest = rs6000_force_indexed_or_indirect_mem (dest);
5675 emit_insn (gen_stfiwx (dest, tmp));
5678 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE && !MEM_P (dest))
5680 dest = gen_lowpart (DImode, dest);
5681 emit_move_insn (dest, tmp);
5686 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5687 emit_insn (gen_stfiwx (stack, tmp));
5688 emit_move_insn (dest, stack);
5692 [(set_attr "length" "12")
5693 (set_attr "type" "fp")])
5695 (define_insn_and_split "fix_trunc<mode>si2_internal"
5696 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5697 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5698 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5699 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5701 && !(TARGET_P8_VECTOR && TARGET_DIRECT_MOVE)"
5707 gcc_assert (MEM_P (operands[3]));
5708 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5710 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5711 emit_move_insn (operands[3], operands[2]);
5712 emit_move_insn (operands[0], lowword);
5715 [(set_attr "length" "16")
5716 (set_attr "type" "fp")])
5718 (define_expand "fix_trunc<mode>di2"
5719 [(set (match_operand:DI 0 "gpc_reg_operand")
5720 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5721 "TARGET_HARD_FLOAT && TARGET_FCFID"
5724 (define_insn "*fix_trunc<mode>di2_fctidz"
5725 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5726 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5727 "TARGET_HARD_FLOAT && TARGET_FCFID"
5731 [(set_attr "type" "fp")])
5733 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5734 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5735 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5736 ;; values can go in VSX registers. Keeping the direct move part through
5737 ;; register allocation prevents the register allocator from doing a direct move
5738 ;; of the SImode value to a GPR, and then a store/load.
5739 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5740 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=d,wa,r")
5741 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa,wa")))
5742 (clobber (match_scratch:SI 2 "=X,X,wa"))]
5743 "TARGET_DIRECT_MOVE"
5746 xscvdp<su>xws %x0,%x1
5748 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5750 (any_fix:SI (match_dup 1)))
5754 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5756 [(set_attr "type" "fp")
5757 (set_attr "length" "4,4,8")
5758 (set_attr "isa" "p9v,p9v,*")])
5760 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5761 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5762 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5763 "TARGET_DIRECT_MOVE"
5766 xscvdp<su>xws %x0,%x1"
5767 [(set_attr "type" "fp")])
5769 ;; Keep the convert and store together through register allocation to prevent
5770 ;; the register allocator from getting clever and doing a direct move to a GPR
5771 ;; and then store for reg+offset stores.
5772 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5773 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5774 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5775 (clobber (match_scratch:SI 2 "=wa"))]
5776 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5778 "&& reload_completed"
5780 (any_fix:SI (match_dup 1)))
5784 operands[3] = (<QHSI:MODE>mode == SImode
5786 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5789 (define_expand "fixuns_trunc<mode>si2"
5790 [(set (match_operand:SI 0 "gpc_reg_operand")
5791 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5792 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ && TARGET_STFIWX"
5794 if (!TARGET_P8_VECTOR)
5796 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5801 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5802 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5803 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5804 (clobber (match_scratch:DI 2 "=d"))]
5805 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ
5806 && TARGET_STFIWX && can_create_pseudo_p ()
5807 && !TARGET_P8_VECTOR"
5812 rtx dest = operands[0];
5813 rtx src = operands[1];
5814 rtx tmp = operands[2];
5816 if (GET_CODE (tmp) == SCRATCH)
5817 tmp = gen_reg_rtx (DImode);
5819 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5822 dest = rs6000_force_indexed_or_indirect_mem (dest);
5823 emit_insn (gen_stfiwx (dest, tmp));
5826 else if (TARGET_POWERPC64 && TARGET_DIRECT_MOVE)
5828 dest = gen_lowpart (DImode, dest);
5829 emit_move_insn (dest, tmp);
5834 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5835 emit_insn (gen_stfiwx (stack, tmp));
5836 emit_move_insn (dest, stack);
5840 [(set_attr "length" "12")
5841 (set_attr "type" "fp")])
5843 (define_insn "fixuns_trunc<mode>di2"
5844 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5845 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5846 "TARGET_HARD_FLOAT && TARGET_FCTIDUZ"
5850 [(set_attr "type" "fp")])
5852 (define_insn "rs6000_mtfsb0"
5853 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5857 [(set_attr "type" "fp")])
5859 (define_insn "rs6000_mtfsb1"
5860 [(unspec_volatile [(match_operand:SI 0 "u5bit_cint_operand" "n")]
5864 [(set_attr "type" "fp")])
5866 (define_insn "rs6000_mffscrn"
5867 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5868 (unspec_volatile:DF [(match_operand:DF 1 "gpc_reg_operand" "d")]
5872 [(set_attr "type" "fp")])
5874 (define_insn "rs6000_mffscdrn"
5875 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
5876 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSCDRN))
5877 (use (match_operand:DF 1 "gpc_reg_operand" "d"))]
5880 [(set_attr "type" "fp")])
5882 (define_expand "rs6000_set_fpscr_rn"
5883 [(match_operand:DI 0 "reg_or_cint_operand")]
5886 rtx tmp_df = gen_reg_rtx (DFmode);
5888 /* The floating point rounding control bits are FPSCR[62:63]. Put the
5889 new rounding mode bits from operands[0][62:63] into FPSCR[62:63]. */
5892 rtx src_df = force_reg (DImode, operands[0]);
5893 src_df = simplify_gen_subreg (DFmode, src_df, DImode, 0);
5894 emit_insn (gen_rs6000_mffscrn (tmp_df, src_df));
5898 if (CONST_INT_P (operands[0]))
5900 if ((INTVAL (operands[0]) & 0x1) == 0x1)
5901 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (31)));
5903 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (31)));
5905 if ((INTVAL (operands[0]) & 0x2) == 0x2)
5906 emit_insn (gen_rs6000_mtfsb1 (GEN_INT (30)));
5908 emit_insn (gen_rs6000_mtfsb0 (GEN_INT (30)));
5912 rtx tmp_rn = gen_reg_rtx (DImode);
5913 rtx tmp_di = gen_reg_rtx (DImode);
5915 /* Extract new RN mode from operand. */
5916 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x3)));
5918 /* Insert new RN mode into FSCPR. */
5919 emit_insn (gen_rs6000_mffs (tmp_df));
5920 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5921 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (-4)));
5922 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5924 /* Need to write to field k=15. The fields are [0:15]. Hence with
5925 L=0, W=0, FLM_i must be equal to 8, 16 = i + 8*(1-W). FLM is an
5926 8-bit field[0:7]. Need to set the bit that corresponds to the
5927 value of i that you want [0:7]. */
5928 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5929 emit_insn (gen_rs6000_mtfsf (GEN_INT (0x01), tmp_df));
5934 (define_expand "rs6000_set_fpscr_drn"
5935 [(match_operand:DI 0 "gpc_reg_operand")]
5938 rtx tmp_df = gen_reg_rtx (DFmode);
5940 /* The decimal floating point rounding control bits are FPSCR[29:31]. Put the
5941 new rounding mode bits from operands[0][61:63] into FPSCR[29:31]. */
5944 rtx src_df = gen_reg_rtx (DFmode);
5946 emit_insn (gen_ashldi3 (operands[0], operands[0], GEN_INT (32)));
5947 src_df = simplify_gen_subreg (DFmode, operands[0], DImode, 0);
5948 emit_insn (gen_rs6000_mffscdrn (tmp_df, src_df));
5952 rtx tmp_rn = gen_reg_rtx (DImode);
5953 rtx tmp_di = gen_reg_rtx (DImode);
5955 /* Extract new DRN mode from operand. */
5956 emit_insn (gen_anddi3 (tmp_rn, operands[0], GEN_INT (0x7)));
5957 emit_insn (gen_ashldi3 (tmp_rn, tmp_rn, GEN_INT (32)));
5959 /* Insert new RN mode into FSCPR. */
5960 emit_insn (gen_rs6000_mffs (tmp_df));
5961 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
5962 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0xFFFFFFF8FFFFFFFF)));
5963 emit_insn (gen_iordi3 (tmp_di, tmp_di, tmp_rn));
5965 /* Need to write to field 7. The fields are [0:15]. The equation to
5966 select the field is i + 8*(1-W). Hence with L=0 and W=1, need to set
5967 i to 0x1 to get field 7 where i selects the field. */
5968 tmp_df = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
5969 emit_insn (gen_rs6000_mtfsf_hi (GEN_INT (0x01), tmp_df));
5974 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5975 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5976 ;; because the first makes it clear that operand 0 is not live
5977 ;; before the instruction.
5978 (define_insn "fctiwz_<mode>"
5979 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5981 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5987 [(set_attr "type" "fp")])
5989 (define_insn "fctiwuz_<mode>"
5990 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wa")
5991 (unspec:DI [(unsigned_fix:SI
5992 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5994 "TARGET_HARD_FLOAT && TARGET_FCTIWUZ"
5998 [(set_attr "type" "fp")])
6000 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
6001 ;; since the friz instruction does not truncate the value if the floating
6002 ;; point value is < LONG_MIN or > LONG_MAX.
6003 (define_insn "*friz"
6004 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6005 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,wa"))))]
6006 "TARGET_HARD_FLOAT && TARGET_FPRND
6007 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
6011 [(set_attr "type" "fp")])
6013 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
6014 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
6015 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
6016 ;; extend it, store it back on the stack from the GPR, load it back into the
6017 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
6018 ;; disable using store and load to sign/zero extend the value.
6019 (define_insn_and_split "*round32<mode>2_fprs"
6020 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6022 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6023 (clobber (match_scratch:DI 2 "=d"))
6024 (clobber (match_scratch:DI 3 "=d"))]
6026 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
6027 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
6032 rtx dest = operands[0];
6033 rtx src = operands[1];
6034 rtx tmp1 = operands[2];
6035 rtx tmp2 = operands[3];
6036 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6038 if (GET_CODE (tmp1) == SCRATCH)
6039 tmp1 = gen_reg_rtx (DImode);
6040 if (GET_CODE (tmp2) == SCRATCH)
6041 tmp2 = gen_reg_rtx (DImode);
6043 emit_insn (gen_fctiwz_<mode> (tmp1, src));
6044 emit_insn (gen_stfiwx (stack, tmp1));
6045 emit_insn (gen_lfiwax (tmp2, stack));
6046 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6049 [(set_attr "type" "fpload")
6050 (set_attr "length" "16")])
6052 (define_insn_and_split "*roundu32<mode>2_fprs"
6053 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
6054 (unsigned_float:SFDF
6055 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
6056 (clobber (match_scratch:DI 2 "=d"))
6057 (clobber (match_scratch:DI 3 "=d"))]
6059 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
6060 && can_create_pseudo_p ()"
6065 rtx dest = operands[0];
6066 rtx src = operands[1];
6067 rtx tmp1 = operands[2];
6068 rtx tmp2 = operands[3];
6069 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
6071 if (GET_CODE (tmp1) == SCRATCH)
6072 tmp1 = gen_reg_rtx (DImode);
6073 if (GET_CODE (tmp2) == SCRATCH)
6074 tmp2 = gen_reg_rtx (DImode);
6076 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
6077 emit_insn (gen_stfiwx (stack, tmp1));
6078 emit_insn (gen_lfiwzx (tmp2, stack));
6079 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
6082 [(set_attr "type" "fpload")
6083 (set_attr "length" "16")])
6085 ;; No VSX equivalent to fctid
6086 (define_insn "lrint<mode>di2"
6087 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
6088 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6090 "TARGET_HARD_FLOAT && TARGET_FPRND"
6092 [(set_attr "type" "fp")])
6094 (define_insn "btrunc<mode>2"
6095 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6096 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6098 "TARGET_HARD_FLOAT && TARGET_FPRND"
6102 [(set_attr "type" "fp")])
6104 (define_insn "ceil<mode>2"
6105 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6106 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6108 "TARGET_HARD_FLOAT && TARGET_FPRND"
6112 [(set_attr "type" "fp")])
6114 (define_insn "floor<mode>2"
6115 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6116 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6118 "TARGET_HARD_FLOAT && TARGET_FPRND"
6122 [(set_attr "type" "fp")])
6124 ;; No VSX equivalent to frin
6125 (define_insn "round<mode>2"
6126 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6127 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6129 "TARGET_HARD_FLOAT && TARGET_FPRND"
6131 [(set_attr "type" "fp")])
6133 (define_insn "*xsrdpi<mode>2"
6134 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6135 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6137 "TARGET_HARD_FLOAT && TARGET_VSX"
6139 [(set_attr "type" "fp")])
6141 (define_expand "lround<mode>di2"
6143 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
6145 (set (match_operand:DI 0 "gpc_reg_operand")
6146 (unspec:DI [(match_dup 2)]
6148 "TARGET_HARD_FLOAT && TARGET_VSX && TARGET_FPRND"
6150 operands[2] = gen_reg_rtx (<MODE>mode);
6153 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6154 (define_insn "stfiwx"
6155 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6156 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wa")]
6162 [(set_attr "type" "fpstore")
6163 (set_attr "isa" "*,p8v")])
6165 ;; If we don't have a direct conversion to single precision, don't enable this
6166 ;; conversion for 32-bit without fast math, because we don't have the insn to
6167 ;; generate the fixup swizzle to avoid double rounding problems.
6168 (define_expand "floatsisf2"
6169 [(set (match_operand:SF 0 "gpc_reg_operand")
6170 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6172 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6174 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6176 if (TARGET_FCFIDS && TARGET_LFIWAX)
6178 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6181 else if (TARGET_FCFID && TARGET_LFIWAX)
6183 rtx dfreg = gen_reg_rtx (DFmode);
6184 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6185 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6190 rtx dreg = operands[1];
6192 dreg = force_reg (SImode, dreg);
6193 dreg = convert_to_mode (DImode, dreg, false);
6194 emit_insn (gen_floatdisf2 (operands[0], dreg));
6199 (define_insn "floatdidf2"
6200 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6201 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6202 "TARGET_FCFID && TARGET_HARD_FLOAT"
6206 [(set_attr "type" "fp")])
6208 ; Allow the combiner to merge source memory operands to the conversion so that
6209 ; the optimizer/register allocator doesn't try to load the value too early in a
6210 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6211 ; hit. We will split after reload to avoid the trip through the GPRs
6213 (define_insn_and_split "*floatdidf2_mem"
6214 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6215 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6216 (clobber (match_scratch:DI 2 "=d,wa"))]
6217 "TARGET_HARD_FLOAT && TARGET_FCFID"
6219 "&& reload_completed"
6220 [(set (match_dup 2) (match_dup 1))
6221 (set (match_dup 0) (float:DF (match_dup 2)))]
6223 [(set_attr "length" "8")
6224 (set_attr "type" "fpload")])
6226 (define_expand "floatunsdidf2"
6227 [(set (match_operand:DF 0 "gpc_reg_operand")
6229 (match_operand:DI 1 "gpc_reg_operand")))]
6230 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6233 (define_insn "*floatunsdidf2_fcfidu"
6234 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6235 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6236 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6240 [(set_attr "type" "fp")])
6242 (define_insn_and_split "*floatunsdidf2_mem"
6243 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,wa")
6244 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6245 (clobber (match_scratch:DI 2 "=d,wa"))]
6246 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6248 "&& reload_completed"
6249 [(set (match_dup 2) (match_dup 1))
6250 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6252 [(set_attr "length" "8")
6253 (set_attr "type" "fpload")])
6255 (define_expand "floatdisf2"
6256 [(set (match_operand:SF 0 "gpc_reg_operand")
6257 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6258 "TARGET_FCFID && TARGET_HARD_FLOAT
6259 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6263 rtx val = operands[1];
6264 if (!flag_unsafe_math_optimizations)
6266 rtx label = gen_label_rtx ();
6267 val = gen_reg_rtx (DImode);
6268 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6271 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6276 (define_insn "floatdisf2_fcfids"
6277 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6278 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6279 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6283 [(set_attr "type" "fp")
6284 (set_attr "isa" "*,p8v")])
6286 (define_insn_and_split "*floatdisf2_mem"
6287 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6288 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6289 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6290 "TARGET_HARD_FLOAT && TARGET_FCFIDS"
6292 "&& reload_completed"
6295 emit_move_insn (operands[2], operands[1]);
6296 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6299 [(set_attr "length" "8")
6300 (set_attr "isa" "*,p8v,p8v")])
6302 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6303 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6304 ;; from double rounding.
6305 ;; Instead of creating a new cpu type for two FP operations, just use fp
6306 (define_insn_and_split "floatdisf2_internal1"
6307 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6308 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6309 (clobber (match_scratch:DF 2 "=d"))]
6310 "TARGET_FCFID && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6312 "&& reload_completed"
6314 (float:DF (match_dup 1)))
6316 (float_truncate:SF (match_dup 2)))]
6318 [(set_attr "length" "8")
6319 (set_attr "type" "fp")])
6321 ;; Twiddles bits to avoid double rounding.
6322 ;; Bits that might be truncated when converting to DFmode are replaced
6323 ;; by a bit that won't be lost at that stage, but is below the SFmode
6324 ;; rounding position.
6325 (define_expand "floatdisf2_internal2"
6326 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6328 (clobber (reg:DI CA_REGNO))])
6329 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6331 (set (match_dup 3) (plus:DI (match_dup 3)
6333 (set (match_dup 0) (plus:DI (match_dup 0)
6335 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6337 (set (match_dup 0) (ior:DI (match_dup 0)
6339 (set (match_dup 0) (and:DI (match_dup 0)
6341 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6342 (label_ref (match_operand:DI 2 ""))
6344 (set (match_dup 0) (match_dup 1))]
6345 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && !TARGET_FCFIDS"
6347 operands[3] = gen_reg_rtx (DImode);
6348 operands[4] = gen_reg_rtx (CCUNSmode);
6351 (define_expand "floatunsdisf2"
6352 [(set (match_operand:SF 0 "gpc_reg_operand")
6353 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6354 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6357 (define_insn "floatunsdisf2_fcfidus"
6358 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa")
6359 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wa")))]
6360 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6364 [(set_attr "type" "fp")
6365 (set_attr "isa" "*,p8v")])
6367 (define_insn_and_split "*floatunsdisf2_mem"
6368 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wa,wa")
6369 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6370 (clobber (match_scratch:DI 2 "=d,d,wa"))]
6371 "TARGET_HARD_FLOAT && TARGET_FCFIDUS"
6373 "&& reload_completed"
6376 emit_move_insn (operands[2], operands[1]);
6377 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6380 [(set_attr "type" "fpload")
6381 (set_attr "length" "8")
6382 (set_attr "isa" "*,p8v,p8v")])
6384 ;; Define the TImode operations that can be done in a small number
6385 ;; of instructions. The & constraints are to prevent the register
6386 ;; allocator from allocating registers that overlap with the inputs
6387 ;; (for example, having an input in 7,8 and an output in 6,7). We
6388 ;; also allow for the output being the same as one of the inputs.
6390 (define_expand "addti3"
6391 [(set (match_operand:TI 0 "gpc_reg_operand")
6392 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6393 (match_operand:TI 2 "reg_or_short_operand")))]
6396 rtx lo0 = gen_lowpart (DImode, operands[0]);
6397 rtx lo1 = gen_lowpart (DImode, operands[1]);
6398 rtx lo2 = gen_lowpart (DImode, operands[2]);
6399 rtx hi0 = gen_highpart (DImode, operands[0]);
6400 rtx hi1 = gen_highpart (DImode, operands[1]);
6401 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6403 if (!reg_or_short_operand (lo2, DImode))
6404 lo2 = force_reg (DImode, lo2);
6405 if (!adde_operand (hi2, DImode))
6406 hi2 = force_reg (DImode, hi2);
6408 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6409 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6413 (define_expand "subti3"
6414 [(set (match_operand:TI 0 "gpc_reg_operand")
6415 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6416 (match_operand:TI 2 "gpc_reg_operand")))]
6419 rtx lo0 = gen_lowpart (DImode, operands[0]);
6420 rtx lo1 = gen_lowpart (DImode, operands[1]);
6421 rtx lo2 = gen_lowpart (DImode, operands[2]);
6422 rtx hi0 = gen_highpart (DImode, operands[0]);
6423 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6424 rtx hi2 = gen_highpart (DImode, operands[2]);
6426 if (!reg_or_short_operand (lo1, DImode))
6427 lo1 = force_reg (DImode, lo1);
6428 if (!adde_operand (hi1, DImode))
6429 hi1 = force_reg (DImode, hi1);
6431 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6432 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6436 ;; 128-bit logical operations expanders
6438 (define_expand "and<mode>3"
6439 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6440 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6441 (match_operand:BOOL_128 2 "vlogical_operand")))]
6445 (define_expand "ior<mode>3"
6446 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6447 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6448 (match_operand:BOOL_128 2 "vlogical_operand")))]
6452 (define_expand "xor<mode>3"
6453 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6454 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6455 (match_operand:BOOL_128 2 "vlogical_operand")))]
6459 (define_expand "one_cmpl<mode>2"
6460 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6461 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6465 (define_expand "nor<mode>3"
6466 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6468 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6469 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6473 (define_expand "andc<mode>3"
6474 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6476 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6477 (match_operand:BOOL_128 1 "vlogical_operand")))]
6481 ;; Power8 vector logical instructions.
6482 (define_expand "eqv<mode>3"
6483 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6485 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6486 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6487 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6490 ;; Rewrite nand into canonical form
6491 (define_expand "nand<mode>3"
6492 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6494 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6495 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6496 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6499 ;; The canonical form is to have the negated element first, so we need to
6500 ;; reverse arguments.
6501 (define_expand "orc<mode>3"
6502 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6504 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6505 (match_operand:BOOL_128 1 "vlogical_operand")))]
6506 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6509 ;; 128-bit logical operations insns and split operations
6510 (define_insn_and_split "*and<mode>3_internal"
6511 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6513 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6514 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6517 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6518 return "xxland %x0,%x1,%x2";
6520 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6521 return "vand %0,%1,%2";
6525 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6528 rs6000_split_logical (operands, AND, false, false, false);
6533 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6534 (const_string "veclogical")
6535 (const_string "integer")))
6536 (set (attr "length")
6538 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6541 (match_test "TARGET_POWERPC64")
6543 (const_string "16"))))])
6546 (define_insn_and_split "*bool<mode>3_internal"
6547 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6548 (match_operator:BOOL_128 3 "boolean_or_operator"
6549 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6550 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6553 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6554 return "xxl%q3 %x0,%x1,%x2";
6556 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6557 return "v%q3 %0,%1,%2";
6561 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6564 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6569 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6570 (const_string "veclogical")
6571 (const_string "integer")))
6572 (set (attr "length")
6574 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6577 (match_test "TARGET_POWERPC64")
6579 (const_string "16"))))])
6582 (define_insn_and_split "*boolc<mode>3_internal1"
6583 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6584 (match_operator:BOOL_128 3 "boolean_operator"
6586 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6587 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6588 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6590 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6591 return "xxl%q3 %x0,%x1,%x2";
6593 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6594 return "v%q3 %0,%1,%2";
6598 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6599 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6602 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6607 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6608 (const_string "veclogical")
6609 (const_string "integer")))
6610 (set (attr "length")
6612 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6615 (match_test "TARGET_POWERPC64")
6617 (const_string "16"))))])
6619 (define_insn_and_split "*boolc<mode>3_internal2"
6620 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6621 (match_operator:TI2 3 "boolean_operator"
6623 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6624 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6625 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6627 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6630 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6633 [(set_attr "type" "integer")
6634 (set (attr "length")
6636 (match_test "TARGET_POWERPC64")
6638 (const_string "16")))])
6641 (define_insn_and_split "*boolcc<mode>3_internal1"
6642 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6643 (match_operator:BOOL_128 3 "boolean_operator"
6645 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6647 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6648 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6650 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6651 return "xxl%q3 %x0,%x1,%x2";
6653 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6654 return "v%q3 %0,%1,%2";
6658 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6659 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6662 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6667 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6668 (const_string "veclogical")
6669 (const_string "integer")))
6670 (set (attr "length")
6672 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6675 (match_test "TARGET_POWERPC64")
6677 (const_string "16"))))])
6679 (define_insn_and_split "*boolcc<mode>3_internal2"
6680 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6681 (match_operator:TI2 3 "boolean_operator"
6683 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6685 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6686 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6688 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6691 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6694 [(set_attr "type" "integer")
6695 (set (attr "length")
6697 (match_test "TARGET_POWERPC64")
6699 (const_string "16")))])
6703 (define_insn_and_split "*eqv<mode>3_internal1"
6704 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6707 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6708 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6711 if (vsx_register_operand (operands[0], <MODE>mode))
6712 return "xxleqv %x0,%x1,%x2";
6716 "TARGET_P8_VECTOR && reload_completed
6717 && int_reg_operand (operands[0], <MODE>mode)"
6720 rs6000_split_logical (operands, XOR, true, false, false);
6725 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6726 (const_string "veclogical")
6727 (const_string "integer")))
6728 (set (attr "length")
6730 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6733 (match_test "TARGET_POWERPC64")
6735 (const_string "16"))))])
6737 (define_insn_and_split "*eqv<mode>3_internal2"
6738 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6741 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6742 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6745 "reload_completed && !TARGET_P8_VECTOR"
6748 rs6000_split_logical (operands, XOR, true, false, false);
6751 [(set_attr "type" "integer")
6752 (set (attr "length")
6754 (match_test "TARGET_POWERPC64")
6756 (const_string "16")))])
6758 ;; 128-bit one's complement
6759 (define_insn_and_split "*one_cmpl<mode>3_internal"
6760 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6762 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6765 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6766 return "xxlnor %x0,%x1,%x1";
6768 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6769 return "vnor %0,%1,%1";
6773 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6776 rs6000_split_logical (operands, NOT, false, false, false);
6781 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6782 (const_string "veclogical")
6783 (const_string "integer")))
6784 (set (attr "length")
6786 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6789 (match_test "TARGET_POWERPC64")
6791 (const_string "16"))))])
6794 ;; Now define ways of moving data around.
6796 ;; Set up a register with a value from the GOT table
6798 (define_expand "movsi_got"
6799 [(set (match_operand:SI 0 "gpc_reg_operand")
6800 (unspec:SI [(match_operand:SI 1 "got_operand")
6801 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6802 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6804 if (GET_CODE (operands[1]) == CONST)
6806 rtx offset = const0_rtx;
6807 HOST_WIDE_INT value;
6809 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6810 value = INTVAL (offset);
6813 rtx tmp = (!can_create_pseudo_p ()
6815 : gen_reg_rtx (Pmode));
6816 emit_insn (gen_movsi_got (tmp, operands[1]));
6817 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6822 operands[2] = rs6000_got_register (operands[1]);
6825 (define_insn "*movsi_got_internal"
6826 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6827 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6828 (match_operand:SI 2 "gpc_reg_operand" "b")]
6830 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6831 "lwz %0,%a1@got(%2)"
6832 [(set_attr "type" "load")])
6834 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6835 ;; didn't get allocated to a hard register.
6837 [(set (match_operand:SI 0 "gpc_reg_operand")
6838 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6839 (match_operand:SI 2 "memory_operand")]
6841 "DEFAULT_ABI == ABI_V4
6843 && reload_completed"
6844 [(set (match_dup 0) (match_dup 2))
6845 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6849 ;; For SI, we special-case integers that can't be loaded in one insn. We
6850 ;; do the load 16-bits at a time. We could do this by loading from memory,
6851 ;; and this is even supposed to be faster, but it is simpler not to get
6852 ;; integers in the TOC.
6853 (define_insn "movsi_low"
6854 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6855 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6856 (match_operand 2 "" ""))))]
6857 "TARGET_MACHO && ! TARGET_64BIT"
6858 "lwz %0,lo16(%2)(%1)"
6859 [(set_attr "type" "load")])
6861 ;; MR LA LWZ LFIWZX LXSIWZX
6862 ;; STW STFIWX STXSIWX LI LIS
6863 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6864 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6866 (define_insn "*movsi_internal1"
6867 [(set (match_operand:SI 0 "nonimmediate_operand"
6873 (match_operand:SI 1 "input_operand"
6879 "gpc_reg_operand (operands[0], SImode)
6880 || gpc_reg_operand (operands[1], SImode)"
6906 "*, *, load, fpload, fpload,
6907 store, fpstore, fpstore, *, *,
6908 *, veclogical, vecsimple, vecsimple, vecsimple,
6909 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6920 *, p8v, p9v, p9v, p8v,
6921 p9v, p8v, p9v, p8v, p8v,
6924 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6925 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6927 ;; Because SF values are actually stored as DF values within the vector
6928 ;; registers, we need to convert the value to the vector SF format when
6929 ;; we need to use the bits in a union or similar cases. We only need
6930 ;; to do this transformation when the value is a vector register. Loads,
6931 ;; stores, and transfers within GPRs are assumed to be safe.
6933 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6934 ;; no alternatives, because the call is created as part of secondary_reload,
6935 ;; and operand #2's register class is used to allocate the temporary register.
6936 ;; This function is called before reload, and it creates the temporary as
6939 ;; MR LWZ LFIWZX LXSIWZX STW
6940 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6943 (define_insn_and_split "movsi_from_sf"
6944 [(set (match_operand:SI 0 "nonimmediate_operand"
6945 "=r, r, ?*d, ?*v, m,
6948 (unspec:SI [(match_operand:SF 1 "input_operand"
6953 (clobber (match_scratch:V4SF 2
6957 "TARGET_NO_SF_SUBREG
6958 && (register_operand (operands[0], SImode)
6959 || register_operand (operands[1], SFmode))"
6972 "&& reload_completed
6973 && int_reg_operand (operands[0], SImode)
6974 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6977 rtx op0 = operands[0];
6978 rtx op1 = operands[1];
6979 rtx op2 = operands[2];
6980 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6981 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6983 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6984 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6988 "*, load, fpload, fpload, store,
6989 fpstore, fpstore, fpstore, mftgpr, fp,
6997 *, p9v, p8v, p8v, p8v,
7000 ;; movsi_from_sf with zero extension
7002 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
7005 (define_insn_and_split "*movdi_from_sf_zero_ext"
7006 [(set (match_operand:DI 0 "gpc_reg_operand"
7007 "=r, r, ?*d, ?*v, r,
7010 (unspec:SI [(match_operand:SF 1 "input_operand"
7013 UNSPEC_SI_FROM_SF)))
7014 (clobber (match_scratch:V4SF 2
7017 "TARGET_DIRECT_MOVE_64BIT
7018 && (register_operand (operands[0], DImode)
7019 || register_operand (operands[1], SImode))"
7028 "&& reload_completed
7029 && register_operand (operands[0], DImode)
7030 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
7033 rtx op0 = operands[0];
7034 rtx op1 = operands[1];
7035 rtx op2 = operands[2];
7036 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
7038 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
7039 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
7043 "*, load, fpload, fpload, two,
7049 "*, *, p8v, p8v, p8v,
7052 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
7053 ;; moving it to SImode. We cannot do a SFmode store without having to do the
7054 ;; conversion explicitly since that doesn't work in most cases if the input
7055 ;; isn't representable as SF. Use XSCVDPSP instead of XSCVDPSPN, since the
7056 ;; former handles cases where the input will not fit in a SFmode, and the
7057 ;; latter assumes the value has already been rounded.
7058 (define_insn "*movsi_from_df"
7059 [(set (match_operand:SI 0 "gpc_reg_operand" "=wa")
7060 (unspec:SI [(float_truncate:SF
7061 (match_operand:DF 1 "gpc_reg_operand" "wa"))]
7062 UNSPEC_SI_FROM_SF))]
7063 "TARGET_NO_SF_SUBREG"
7065 [(set_attr "type" "fp")])
7067 ;; Split a load of a large constant into the appropriate two-insn
7071 [(set (match_operand:SI 0 "gpc_reg_operand")
7072 (match_operand:SI 1 "const_int_operand"))]
7073 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
7074 && (INTVAL (operands[1]) & 0xffff) != 0"
7078 (ior:SI (match_dup 0)
7081 if (rs6000_emit_set_const (operands[0], operands[1]))
7087 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7089 [(set (match_operand:DI 0 "altivec_register_operand")
7090 (match_operand:DI 1 "xxspltib_constant_split"))]
7091 "TARGET_P9_VECTOR && reload_completed"
7094 rtx op0 = operands[0];
7095 rtx op1 = operands[1];
7096 int r = REGNO (op0);
7097 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7099 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7100 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7104 (define_insn "*mov<mode>_internal2"
7105 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7106 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7108 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7114 [(set_attr "type" "cmp,logical,cmp")
7115 (set_attr "dot" "yes")
7116 (set_attr "length" "4,4,8")])
7119 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7120 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7122 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7124 [(set (match_dup 0) (match_dup 1))
7126 (compare:CC (match_dup 0)
7130 (define_expand "mov<mode>"
7131 [(set (match_operand:INT 0 "general_operand")
7132 (match_operand:INT 1 "any_operand"))]
7135 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7139 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7140 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7141 ;; MTVSRWZ MF%1 MT%1 NOP
7142 (define_insn "*mov<mode>_internal"
7143 [(set (match_operand:QHI 0 "nonimmediate_operand"
7144 "=r, r, wa, m, Z, r,
7145 wa, wa, wa, v, ?v, r,
7147 (match_operand:QHI 1 "input_operand"
7149 wa, O, wM, wB, wS, wa,
7151 "gpc_reg_operand (operands[0], <MODE>mode)
7152 || gpc_reg_operand (operands[1], <MODE>mode)"
7171 "*, load, fpload, store, fpstore, *,
7172 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7173 mffgpr, mfjmpr, mtjmpr, *")
7179 "*, *, p9v, *, p9v, *,
7180 p9v, p9v, p9v, p9v, p9v, p9v,
7184 ;; Here is how to move condition codes around. When we store CC data in
7185 ;; an integer register or memory, we store just the high-order 4 bits.
7186 ;; This lets us not shift in the most common case of CR0.
7187 (define_expand "movcc"
7188 [(set (match_operand:CC 0 "nonimmediate_operand")
7189 (match_operand:CC 1 "nonimmediate_operand"))]
7193 (define_insn "*movcc_internal1"
7194 [(set (match_operand:CC 0 "nonimmediate_operand"
7195 "=y,x,?y,y,r,r,r,r, r,*c*l,r,m")
7196 (match_operand:CC 1 "general_operand"
7197 " y,r, r,O,x,y,r,I,*h, r,m,r"))]
7198 "register_operand (operands[0], CCmode)
7199 || register_operand (operands[1], CCmode)"
7203 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7206 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7213 [(set_attr_alternative "type"
7214 [(const_string "cr_logical")
7215 (const_string "mtcr")
7216 (const_string "mtcr")
7217 (const_string "cr_logical")
7218 (if_then_else (match_test "TARGET_MFCRF")
7219 (const_string "mfcrf") (const_string "mfcr"))
7220 (if_then_else (match_test "TARGET_MFCRF")
7221 (const_string "mfcrf") (const_string "mfcr"))
7222 (const_string "integer")
7223 (const_string "integer")
7224 (const_string "mfjmpr")
7225 (const_string "mtjmpr")
7226 (const_string "load")
7227 (const_string "store")])
7228 (set_attr "length" "*,*,12,*,*,8,*,*,*,*,*,*")])
7230 ;; For floating-point, we normally deal with the floating-point registers
7231 ;; unless -msoft-float is used. The sole exception is that parameter passing
7232 ;; can produce floating-point values in fixed-point registers. Unless the
7233 ;; value is a simple constant or already in memory, we deal with this by
7234 ;; allocating memory and copying the value explicitly via that memory location.
7236 ;; Move 32-bit binary/decimal floating point
7237 (define_expand "mov<mode>"
7238 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7239 (match_operand:FMOVE32 1 "any_operand"))]
7242 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7247 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7248 (match_operand:FMOVE32 1 "const_double_operand"))]
7250 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7251 || (SUBREG_P (operands[0])
7252 && REG_P (SUBREG_REG (operands[0]))
7253 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7254 [(set (match_dup 2) (match_dup 3))]
7258 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7260 if (! TARGET_POWERPC64)
7261 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7263 operands[2] = gen_lowpart (SImode, operands[0]);
7265 operands[3] = gen_int_mode (l, SImode);
7268 ;; Originally, we tried to keep movsf and movsd common, but the differences
7269 ;; addressing was making it rather difficult to hide with mode attributes. In
7270 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7271 ;; before the VSX stores meant that the register allocator would tend to do a
7272 ;; direct move to the GPR (which involves conversion from scalar to
7273 ;; vector/memory formats) to save values in the traditional Altivec registers,
7274 ;; while SDmode had problems on power6 if the GPR store was not first due to
7275 ;; the power6 not having an integer store operation.
7277 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7278 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7279 ;; MR MT<x> MF<x> NOP
7281 (define_insn "movsf_hardfloat"
7282 [(set (match_operand:SF 0 "nonimmediate_operand"
7283 "=!r, f, v, wa, m, wY,
7284 Z, m, wa, !r, f, wa,
7286 (match_operand:SF 1 "input_operand"
7290 "(register_operand (operands[0], SFmode)
7291 || register_operand (operands[1], SFmode))
7292 && TARGET_HARD_FLOAT
7293 && (TARGET_ALLOW_SF_SUBREG
7294 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7307 xscpsgndp %x0,%x1,%x1
7313 "load, fpload, fpload, fpload, fpstore, fpstore,
7314 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7315 *, mtjmpr, mfjmpr, *")
7317 "*, *, p9v, p8v, *, p9v,
7321 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7322 ;; FMR MR MT%0 MF%1 NOP
7323 (define_insn "movsd_hardfloat"
7324 [(set (match_operand:SD 0 "nonimmediate_operand"
7325 "=!r, d, m, Z, ?d, ?r,
7326 f, !r, *c*l, !r, *h")
7327 (match_operand:SD 1 "input_operand"
7330 "(register_operand (operands[0], SDmode)
7331 || register_operand (operands[1], SDmode))
7332 && TARGET_HARD_FLOAT"
7346 "load, fpload, store, fpstore, mffgpr, mftgpr,
7347 fpsimple, *, mtjmpr, mfjmpr, *")
7349 "*, p7, *, *, p8v, p8v,
7352 ;; MR MT%0 MF%0 LWZ STW LI
7353 ;; LIS G-const. F/n-const NOP
7354 (define_insn "*mov<mode>_softfloat"
7355 [(set (match_operand:FMOVE32 0 "nonimmediate_operand"
7356 "=r, *c*l, r, r, m, r,
7359 (match_operand:FMOVE32 1 "input_operand"
7363 "(gpc_reg_operand (operands[0], <MODE>mode)
7364 || gpc_reg_operand (operands[1], <MODE>mode))
7365 && TARGET_SOFT_FLOAT"
7378 "*, mtjmpr, mfjmpr, load, store, *,
7385 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7386 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7388 ;; Because SF values are actually stored as DF values within the vector
7389 ;; registers, we need to convert the value to the vector SF format when
7390 ;; we need to use the bits in a union or similar cases. We only need
7391 ;; to do this transformation when the value is a vector register. Loads,
7392 ;; stores, and transfers within GPRs are assumed to be safe.
7394 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7395 ;; no alternatives, because the call is created as part of secondary_reload,
7396 ;; and operand #2's register class is used to allocate the temporary register.
7397 ;; This function is called before reload, and it creates the temporary as
7400 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7401 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7402 (define_insn_and_split "movsf_from_si"
7403 [(set (match_operand:SF 0 "nonimmediate_operand"
7404 "=!r, f, v, wa, m, Z,
7406 (unspec:SF [(match_operand:SI 1 "input_operand"
7410 (clobber (match_scratch:DI 2
7413 "TARGET_NO_SF_SUBREG
7414 && (register_operand (operands[0], SFmode)
7415 || register_operand (operands[1], SImode))"
7428 "&& reload_completed
7429 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7430 && int_reg_operand_not_pseudo (operands[1], SImode)"
7433 rtx op0 = operands[0];
7434 rtx op1 = operands[1];
7435 rtx op2 = operands[2];
7436 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7438 /* Move SF value to upper 32-bits for xscvspdpn. */
7439 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7440 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7441 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7448 "load, fpload, fpload, fpload, store, fpstore,
7449 fpstore, vecfloat, mffgpr, *")
7451 "*, *, p9v, p8v, *, *,
7452 p8v, p8v, p8v, *")])
7455 ;; Move 64-bit binary/decimal floating point
7456 (define_expand "mov<mode>"
7457 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7458 (match_operand:FMOVE64 1 "any_operand"))]
7461 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7466 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7467 (match_operand:FMOVE64 1 "const_int_operand"))]
7468 "! TARGET_POWERPC64 && reload_completed
7469 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7470 || (SUBREG_P (operands[0])
7471 && REG_P (SUBREG_REG (operands[0]))
7472 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7473 [(set (match_dup 2) (match_dup 4))
7474 (set (match_dup 3) (match_dup 1))]
7476 int endian = (WORDS_BIG_ENDIAN == 0);
7477 HOST_WIDE_INT value = INTVAL (operands[1]);
7479 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7480 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7481 operands[4] = GEN_INT (value >> 32);
7482 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7486 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7487 (match_operand:FMOVE64 1 "const_double_operand"))]
7488 "! TARGET_POWERPC64 && reload_completed
7489 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7490 || (SUBREG_P (operands[0])
7491 && REG_P (SUBREG_REG (operands[0]))
7492 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7493 [(set (match_dup 2) (match_dup 4))
7494 (set (match_dup 3) (match_dup 5))]
7496 int endian = (WORDS_BIG_ENDIAN == 0);
7499 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7501 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7502 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7503 operands[4] = gen_int_mode (l[endian], SImode);
7504 operands[5] = gen_int_mode (l[1 - endian], SImode);
7508 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7509 (match_operand:FMOVE64 1 "const_double_operand"))]
7510 "TARGET_POWERPC64 && reload_completed
7511 && ((REG_P (operands[0]) && REGNO (operands[0]) <= 31)
7512 || (SUBREG_P (operands[0])
7513 && REG_P (SUBREG_REG (operands[0]))
7514 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7515 [(set (match_dup 2) (match_dup 3))]
7517 int endian = (WORDS_BIG_ENDIAN == 0);
7521 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7523 operands[2] = gen_lowpart (DImode, operands[0]);
7524 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7525 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7526 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7528 operands[3] = gen_int_mode (val, DImode);
7531 ;; Don't have reload use general registers to load a constant. It is
7532 ;; less efficient than loading the constant into an FP register, since
7533 ;; it will probably be used there.
7535 ;; The move constraints are ordered to prefer floating point registers before
7536 ;; general purpose registers to avoid doing a store and a load to get the value
7537 ;; into a floating point register when it is needed for a floating point
7538 ;; operation. Prefer traditional floating point registers over VSX registers,
7539 ;; since the D-form version of the memory instructions does not need a GPR for
7540 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7543 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7544 ;; except for 0.0 which can be created on VSX with an xor instruction.
7546 ;; STFD LFD FMR LXSD STXSD
7547 ;; LXSD STXSD XXLOR XXLXOR GPR<-0
7551 (define_insn "*mov<mode>_hardfloat32"
7552 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7553 "=m, d, d, <f64_p9>, wY,
7554 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7556 (match_operand:FMOVE64 1 "input_operand"
7557 "d, m, d, wY, <f64_p9>,
7558 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7560 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT
7561 && (gpc_reg_operand (operands[0], <MODE>mode)
7562 || gpc_reg_operand (operands[1], <MODE>mode))"
7578 "fpstore, fpload, fpsimple, fpload, fpstore,
7579 fpload, fpstore, veclogical, veclogical, two,
7581 (set_attr "size" "64")
7591 ;; STW LWZ MR G-const H-const F-const
7593 (define_insn "*mov<mode>_softfloat32"
7594 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7595 "=Y, r, r, r, r, r")
7597 (match_operand:FMOVE64 1 "input_operand"
7598 "r, Y, r, G, H, F"))]
7601 && (gpc_reg_operand (operands[0], <MODE>mode)
7602 || gpc_reg_operand (operands[1], <MODE>mode))"
7605 "store, load, two, *, *, *")
7608 "8, 8, 8, 8, 12, 16")])
7610 ; ld/std require word-aligned displacements -> 'Y' constraint.
7611 ; List Y->r and r->Y before r->r for reload.
7613 ;; STFD LFD FMR LXSD STXSD
7614 ;; LXSDX STXSDX XXLOR XXLXOR LI 0
7615 ;; STD LD MR MT{CTR,LR} MF{CTR,LR}
7616 ;; NOP MFVSRD MTVSRD
7618 (define_insn "*mov<mode>_hardfloat64"
7619 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7620 "=m, d, d, <f64_p9>, wY,
7621 <f64_av>, Z, <f64_vsx>, <f64_vsx>, !r,
7622 YZ, r, !r, *c*l, !r,
7624 (match_operand:FMOVE64 1 "input_operand"
7625 "d, m, d, wY, <f64_p9>,
7626 Z, <f64_av>, <f64_vsx>, <zero_fp>, <zero_fp>,
7629 "TARGET_POWERPC64 && TARGET_HARD_FLOAT
7630 && (gpc_reg_operand (operands[0], <MODE>mode)
7631 || gpc_reg_operand (operands[1], <MODE>mode))"
7652 "fpstore, fpload, fpsimple, fpload, fpstore,
7653 fpload, fpstore, veclogical, veclogical, integer,
7654 store, load, *, mtjmpr, mfjmpr,
7656 (set_attr "size" "64")
7663 ;; STD LD MR MT<SPR> MF<SPR> G-const
7664 ;; H-const F-const Special
7666 (define_insn "*mov<mode>_softfloat64"
7667 [(set (match_operand:FMOVE64 0 "nonimmediate_operand"
7668 "=Y, r, r, *c*l, r, r,
7671 (match_operand:FMOVE64 1 "input_operand"
7675 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7676 && (gpc_reg_operand (operands[0], <MODE>mode)
7677 || gpc_reg_operand (operands[1], <MODE>mode))"
7689 "store, load, *, mtjmpr, mfjmpr, *,
7696 (define_expand "mov<mode>"
7697 [(set (match_operand:FMOVE128 0 "general_operand")
7698 (match_operand:FMOVE128 1 "any_operand"))]
7701 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7705 ;; It's important to list Y->r and r->Y before r->r because otherwise
7706 ;; reload, given m->r, will try to pick r->r and reload it, which
7707 ;; doesn't make progress.
7709 ;; We can't split little endian direct moves of TDmode, because the words are
7710 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7711 ;; problematical. Don't allow direct move for this case.
7713 (define_insn_and_split "*mov<mode>_64bit_dm"
7714 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,d")
7715 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,d,r"))]
7716 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7717 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7718 && (gpc_reg_operand (operands[0], <MODE>mode)
7719 || gpc_reg_operand (operands[1], <MODE>mode))"
7721 "&& reload_completed"
7723 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7724 [(set_attr "length" "8,8,8,8,12,12,8,8,8")
7725 (set_attr "isa" "*,*,*,*,*,*,*,p8v,p8v")])
7727 (define_insn_and_split "*movtd_64bit_nodm"
7728 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7729 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7730 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7731 && (gpc_reg_operand (operands[0], TDmode)
7732 || gpc_reg_operand (operands[1], TDmode))"
7734 "&& reload_completed"
7736 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7737 [(set_attr "length" "8,8,8,12,12,8")])
7739 (define_insn_and_split "*mov<mode>_32bit"
7740 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7741 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7742 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7743 && (FLOAT128_2REG_P (<MODE>mode)
7744 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7745 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7746 && (gpc_reg_operand (operands[0], <MODE>mode)
7747 || gpc_reg_operand (operands[1], <MODE>mode))"
7749 "&& reload_completed"
7751 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7752 [(set_attr "length" "8,8,8,8,20,20,16")])
7754 (define_insn_and_split "*mov<mode>_softfloat"
7755 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r,r")
7756 (match_operand:FMOVE128 1 "input_operand" "r,Y,F,r"))]
7758 && (gpc_reg_operand (operands[0], <MODE>mode)
7759 || gpc_reg_operand (operands[1], <MODE>mode))"
7761 "&& reload_completed"
7763 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7764 [(set_attr_alternative "length"
7765 [(if_then_else (match_test "TARGET_POWERPC64")
7767 (const_string "16"))
7768 (if_then_else (match_test "TARGET_POWERPC64")
7770 (const_string "16"))
7771 (if_then_else (match_test "TARGET_POWERPC64")
7773 (const_string "32"))
7774 (if_then_else (match_test "TARGET_POWERPC64")
7776 (const_string "16"))])])
7778 (define_expand "@extenddf<mode>2"
7779 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7780 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7781 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7783 if (FLOAT128_IEEE_P (<MODE>mode))
7784 rs6000_expand_float128_convert (operands[0], operands[1], false);
7785 else if (TARGET_VSX)
7786 emit_insn (gen_extenddf2_vsx (<MODE>mode, operands[0], operands[1]));
7789 rtx zero = gen_reg_rtx (DFmode);
7790 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7792 emit_insn (gen_extenddf2_fprs (<MODE>mode,
7793 operands[0], operands[1], zero));
7798 ;; Allow memory operands for the source to be created by the combiner.
7799 (define_insn_and_split "@extenddf<mode>2_fprs"
7800 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7801 (float_extend:IBM128
7802 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7803 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7804 "!TARGET_VSX && TARGET_HARD_FLOAT
7805 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7807 "&& reload_completed"
7808 [(set (match_dup 3) (match_dup 1))
7809 (set (match_dup 4) (match_dup 2))]
7811 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7812 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7814 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7815 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7818 (define_insn_and_split "@extenddf<mode>2_vsx"
7819 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7820 (float_extend:IBM128
7821 (match_operand:DF 1 "nonimmediate_operand" "wa,m")))]
7822 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7824 "&& reload_completed"
7825 [(set (match_dup 2) (match_dup 1))
7826 (set (match_dup 3) (match_dup 4))]
7828 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7829 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7831 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7832 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7833 operands[4] = CONST0_RTX (DFmode);
7836 (define_expand "extendsf<mode>2"
7837 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7838 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7839 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7841 if (FLOAT128_IEEE_P (<MODE>mode))
7842 rs6000_expand_float128_convert (operands[0], operands[1], false);
7845 rtx tmp = gen_reg_rtx (DFmode);
7846 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7847 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7852 (define_expand "trunc<mode>df2"
7853 [(set (match_operand:DF 0 "gpc_reg_operand")
7854 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7855 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7857 if (FLOAT128_IEEE_P (<MODE>mode))
7859 rs6000_expand_float128_convert (operands[0], operands[1], false);
7864 (define_insn_and_split "trunc<mode>df2_internal1"
7865 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7867 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7868 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7869 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7873 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7876 emit_note (NOTE_INSN_DELETED);
7879 [(set_attr "type" "fpsimple")])
7881 (define_insn "trunc<mode>df2_internal2"
7882 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7883 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7884 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7885 && TARGET_LONG_DOUBLE_128"
7887 [(set_attr "type" "fp")])
7889 (define_expand "trunc<mode>sf2"
7890 [(set (match_operand:SF 0 "gpc_reg_operand")
7891 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7892 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7894 if (FLOAT128_IEEE_P (<MODE>mode))
7895 rs6000_expand_float128_convert (operands[0], operands[1], false);
7898 rtx tmp = gen_reg_rtx (DFmode);
7899 emit_insn (gen_trunc<mode>df2 (tmp, operands[1]));
7900 emit_insn (gen_truncdfsf2 (operands[0], tmp));
7905 (define_expand "floatsi<mode>2"
7906 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7907 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7908 (clobber (match_scratch:DI 2))])]
7909 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7911 rtx op0 = operands[0];
7912 rtx op1 = operands[1];
7914 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7916 else if (FLOAT128_IEEE_P (<MODE>mode))
7918 rs6000_expand_float128_convert (op0, op1, false);
7923 rtx tmp = gen_reg_rtx (DFmode);
7924 expand_float (tmp, op1, false);
7925 emit_insn (gen_extenddf2 (<MODE>mode, op0, tmp));
7930 ; fadd, but rounding towards zero.
7931 ; This is probably not the optimal code sequence.
7932 (define_insn "fix_trunc_helper<mode>"
7933 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7934 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7935 UNSPEC_FIX_TRUNC_TF))
7936 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7937 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7938 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7939 [(set_attr "type" "fp")
7940 (set_attr "length" "20")])
7942 (define_expand "fix_trunc<mode>si2"
7943 [(set (match_operand:SI 0 "gpc_reg_operand")
7944 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7945 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7947 rtx op0 = operands[0];
7948 rtx op1 = operands[1];
7950 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7954 if (FLOAT128_IEEE_P (<MODE>mode))
7955 rs6000_expand_float128_convert (op0, op1, false);
7957 emit_insn (gen_fix_truncsi2_fprs (<MODE>mode, op0, op1));
7962 (define_expand "@fix_trunc<mode>si2_fprs"
7963 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7964 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7965 (clobber (match_dup 2))
7966 (clobber (match_dup 3))
7967 (clobber (match_dup 4))
7968 (clobber (match_dup 5))])]
7969 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7971 operands[2] = gen_reg_rtx (DFmode);
7972 operands[3] = gen_reg_rtx (DFmode);
7973 operands[4] = gen_reg_rtx (DImode);
7974 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7977 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7978 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7979 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7980 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7981 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7982 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7983 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7984 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7990 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7993 gcc_assert (MEM_P (operands[5]));
7994 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7996 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7997 emit_move_insn (operands[5], operands[4]);
7998 emit_move_insn (operands[0], lowword);
8002 (define_expand "fix_trunc<mode>di2"
8003 [(set (match_operand:DI 0 "gpc_reg_operand")
8004 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8005 "TARGET_FLOAT128_TYPE"
8007 if (!TARGET_FLOAT128_HW)
8009 rs6000_expand_float128_convert (operands[0], operands[1], false);
8014 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
8015 [(set (match_operand:SDI 0 "gpc_reg_operand")
8016 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
8017 "TARGET_FLOAT128_TYPE"
8019 rs6000_expand_float128_convert (operands[0], operands[1], true);
8023 (define_expand "floatdi<mode>2"
8024 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8025 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8026 "TARGET_FLOAT128_TYPE"
8028 if (!TARGET_FLOAT128_HW)
8030 rs6000_expand_float128_convert (operands[0], operands[1], false);
8035 (define_expand "floatunsdi<IEEE128:mode>2"
8036 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8037 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
8038 "TARGET_FLOAT128_TYPE"
8040 if (!TARGET_FLOAT128_HW)
8042 rs6000_expand_float128_convert (operands[0], operands[1], true);
8047 (define_expand "floatuns<IEEE128:mode>2"
8048 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
8049 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
8050 "TARGET_FLOAT128_TYPE"
8052 rtx op0 = operands[0];
8053 rtx op1 = operands[1];
8055 if (TARGET_FLOAT128_HW)
8056 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
8058 rs6000_expand_float128_convert (op0, op1, true);
8062 (define_expand "neg<mode>2"
8063 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8064 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8065 "FLOAT128_IEEE_P (<MODE>mode)
8066 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8068 if (FLOAT128_IEEE_P (<MODE>mode))
8070 if (TARGET_FLOAT128_HW)
8071 emit_insn (gen_neg2_hw (<MODE>mode, operands[0], operands[1]));
8072 else if (TARGET_FLOAT128_TYPE)
8073 emit_insn (gen_ieee_128bit_vsx_neg2 (<MODE>mode,
8074 operands[0], operands[1]));
8077 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
8078 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
8080 operands[1], <MODE>mode);
8082 if (target && !rtx_equal_p (target, operands[0]))
8083 emit_move_insn (operands[0], target);
8089 (define_insn "neg<mode>2_internal"
8090 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
8091 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
8092 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
8094 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
8095 return "fneg %L0,%L1\;fneg %0,%1";
8097 return "fneg %0,%1\;fneg %L0,%L1";
8099 [(set_attr "type" "fpsimple")
8100 (set_attr "length" "8")])
8102 (define_expand "abs<mode>2"
8103 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
8104 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
8105 "FLOAT128_IEEE_P (<MODE>mode)
8106 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
8110 if (FLOAT128_IEEE_P (<MODE>mode))
8112 if (TARGET_FLOAT128_HW)
8114 emit_insn (gen_abs2_hw (<MODE>mode, operands[0], operands[1]));
8117 else if (TARGET_FLOAT128_TYPE)
8119 emit_insn (gen_ieee_128bit_vsx_abs2 (<MODE>mode,
8120 operands[0], operands[1]));
8127 label = gen_label_rtx ();
8128 emit_insn (gen_abs2_internal (<MODE>mode, operands[0], operands[1], label));
8133 (define_expand "@abs<mode>2_internal"
8134 [(set (match_operand:IBM128 0 "gpc_reg_operand")
8135 (match_operand:IBM128 1 "gpc_reg_operand"))
8136 (set (match_dup 3) (match_dup 5))
8137 (set (match_dup 5) (abs:DF (match_dup 5)))
8138 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8139 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8140 (label_ref (match_operand 2 ""))
8142 (set (match_dup 6) (neg:DF (match_dup 6)))]
8143 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
8145 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8146 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8147 operands[3] = gen_reg_rtx (DFmode);
8148 operands[4] = gen_reg_rtx (CCFPmode);
8149 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8150 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8154 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8157 (define_expand "ieee_128bit_negative_zero"
8158 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
8159 "TARGET_FLOAT128_TYPE"
8161 rtvec v = rtvec_alloc (16);
8164 for (i = 0; i < 16; i++)
8165 RTVEC_ELT (v, i) = const0_rtx;
8167 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8168 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8170 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8174 ;; IEEE 128-bit negate
8176 ;; We have 2 insns here for negate and absolute value. The first uses
8177 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8178 ;; insns, and second insn after the first split pass loads up the bit to
8179 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8180 ;; neg/abs to create the constant just once.
8182 (define_insn_and_split "@ieee_128bit_vsx_neg<mode>2"
8183 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8184 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8185 (clobber (match_scratch:V16QI 2 "=v"))]
8186 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8189 [(parallel [(set (match_dup 0)
8190 (neg:IEEE128 (match_dup 1)))
8191 (use (match_dup 2))])]
8193 if (GET_CODE (operands[2]) == SCRATCH)
8194 operands[2] = gen_reg_rtx (V16QImode);
8196 operands[3] = gen_reg_rtx (V16QImode);
8197 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8199 [(set_attr "length" "8")
8200 (set_attr "type" "vecsimple")])
8202 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8203 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8204 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8205 (use (match_operand:V16QI 2 "register_operand" "v"))]
8206 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8207 "xxlxor %x0,%x1,%x2"
8208 [(set_attr "type" "veclogical")])
8210 ;; IEEE 128-bit absolute value
8211 (define_insn_and_split "@ieee_128bit_vsx_abs<mode>2"
8212 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8213 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8214 (clobber (match_scratch:V16QI 2 "=v"))]
8215 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8218 [(parallel [(set (match_dup 0)
8219 (abs:IEEE128 (match_dup 1)))
8220 (use (match_dup 2))])]
8222 if (GET_CODE (operands[2]) == SCRATCH)
8223 operands[2] = gen_reg_rtx (V16QImode);
8225 operands[3] = gen_reg_rtx (V16QImode);
8226 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8228 [(set_attr "length" "8")
8229 (set_attr "type" "vecsimple")])
8231 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8232 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8233 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8234 (use (match_operand:V16QI 2 "register_operand" "v"))]
8235 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8236 "xxlandc %x0,%x1,%x2"
8237 [(set_attr "type" "veclogical")])
8239 ;; IEEE 128-bit negative absolute value
8240 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8241 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8244 (match_operand:IEEE128 1 "register_operand" "wa"))))
8245 (clobber (match_scratch:V16QI 2 "=v"))]
8246 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8247 && FLOAT128_IEEE_P (<MODE>mode)"
8250 [(parallel [(set (match_dup 0)
8251 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8252 (use (match_dup 2))])]
8254 if (GET_CODE (operands[2]) == SCRATCH)
8255 operands[2] = gen_reg_rtx (V16QImode);
8257 operands[3] = gen_reg_rtx (V16QImode);
8258 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8260 [(set_attr "length" "8")
8261 (set_attr "type" "vecsimple")])
8263 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8264 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8267 (match_operand:IEEE128 1 "register_operand" "wa"))))
8268 (use (match_operand:V16QI 2 "register_operand" "v"))]
8269 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8271 [(set_attr "type" "veclogical")])
8273 ;; Float128 conversion functions. These expand to library function calls.
8274 ;; We use expand to convert from IBM double double to IEEE 128-bit
8275 ;; and trunc for the opposite.
8276 (define_expand "extendiftf2"
8277 [(set (match_operand:TF 0 "gpc_reg_operand")
8278 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8279 "TARGET_FLOAT128_TYPE"
8281 rs6000_expand_float128_convert (operands[0], operands[1], false);
8285 (define_expand "extendifkf2"
8286 [(set (match_operand:KF 0 "gpc_reg_operand")
8287 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8288 "TARGET_FLOAT128_TYPE"
8290 rs6000_expand_float128_convert (operands[0], operands[1], false);
8294 (define_expand "extendtfkf2"
8295 [(set (match_operand:KF 0 "gpc_reg_operand")
8296 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8297 "TARGET_FLOAT128_TYPE"
8299 rs6000_expand_float128_convert (operands[0], operands[1], false);
8303 (define_expand "extendtfif2"
8304 [(set (match_operand:IF 0 "gpc_reg_operand")
8305 (float_extend:IF (match_operand:TF 1 "gpc_reg_operand")))]
8306 "TARGET_FLOAT128_TYPE"
8308 rs6000_expand_float128_convert (operands[0], operands[1], false);
8312 (define_expand "trunciftf2"
8313 [(set (match_operand:TF 0 "gpc_reg_operand")
8314 (float_truncate:TF (match_operand:IF 1 "gpc_reg_operand")))]
8315 "TARGET_FLOAT128_TYPE"
8317 rs6000_expand_float128_convert (operands[0], operands[1], false);
8321 (define_expand "truncifkf2"
8322 [(set (match_operand:KF 0 "gpc_reg_operand")
8323 (float_truncate:KF (match_operand:IF 1 "gpc_reg_operand")))]
8324 "TARGET_FLOAT128_TYPE"
8326 rs6000_expand_float128_convert (operands[0], operands[1], false);
8330 (define_expand "trunckftf2"
8331 [(set (match_operand:TF 0 "gpc_reg_operand")
8332 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8333 "TARGET_FLOAT128_TYPE"
8335 rs6000_expand_float128_convert (operands[0], operands[1], false);
8339 (define_expand "trunctfif2"
8340 [(set (match_operand:IF 0 "gpc_reg_operand")
8341 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8342 "TARGET_FLOAT128_TYPE"
8344 rs6000_expand_float128_convert (operands[0], operands[1], false);
8348 (define_insn_and_split "*extend<mode>tf2_internal"
8349 [(set (match_operand:TF 0 "gpc_reg_operand" "=<IFKF_reg>")
8351 (match_operand:IFKF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8352 "TARGET_FLOAT128_TYPE
8353 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8355 "&& reload_completed"
8356 [(set (match_dup 0) (match_dup 2))]
8358 operands[2] = gen_rtx_REG (TFmode, REGNO (operands[1]));
8361 (define_insn_and_split "*extendtf<mode>2_internal"
8362 [(set (match_operand:IFKF 0 "gpc_reg_operand" "=<IFKF_reg>")
8364 (match_operand:TF 1 "gpc_reg_operand" "<IFKF_reg>")))]
8365 "TARGET_FLOAT128_TYPE
8366 && FLOAT128_IBM_P (TFmode) == FLOAT128_IBM_P (<MODE>mode)"
8368 "&& reload_completed"
8369 [(set (match_dup 0) (match_dup 2))]
8371 operands[2] = gen_rtx_REG (<MODE>mode, REGNO (operands[1]));
8375 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8376 ;; must have 3 arguments, and scratch register constraint must be a single
8379 ;; Reload patterns to support gpr load/store with misaligned mem.
8380 ;; and multiple gpr load/store at offset >= 0xfffc
8381 (define_expand "reload_<mode>_store"
8382 [(parallel [(match_operand 0 "memory_operand" "=m")
8383 (match_operand 1 "gpc_reg_operand" "r")
8384 (match_operand:GPR 2 "register_operand" "=&b")])]
8387 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8391 (define_expand "reload_<mode>_load"
8392 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8393 (match_operand 1 "memory_operand" "m")
8394 (match_operand:GPR 2 "register_operand" "=b")])]
8397 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8402 ;; Reload patterns for various types using the vector registers. We may need
8403 ;; an additional base register to convert the reg+offset addressing to reg+reg
8404 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8405 ;; index register for gpr registers.
8406 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8407 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8408 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8409 (match_operand:P 2 "register_operand" "=b")])]
8412 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8416 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8417 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8418 (match_operand:RELOAD 1 "memory_operand" "m")
8419 (match_operand:P 2 "register_operand" "=b")])]
8422 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8427 ;; Reload sometimes tries to move the address to a GPR, and can generate
8428 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8429 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8431 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8432 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8433 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8434 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8436 "TARGET_ALTIVEC && reload_completed"
8438 "&& reload_completed"
8440 (plus:P (match_dup 1)
8443 (and:P (match_dup 0)
8446 ;; Power8 merge instructions to allow direct move to/from floating point
8447 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8448 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8449 ;; value, since it is allocated in reload and not all of the flow information
8450 ;; is setup for it. We have two patterns to do the two moves between gprs and
8451 ;; fprs. There isn't a dependancy between the two, but we could potentially
8452 ;; schedule other instructions between the two instructions.
8454 (define_insn "p8_fmrgow_<mode>"
8455 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8457 (match_operand:DF 1 "register_operand" "d")
8458 (match_operand:DF 2 "register_operand" "d")]
8459 UNSPEC_P8V_FMRGOW))]
8460 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8462 [(set_attr "type" "fpsimple")])
8464 (define_insn "p8_mtvsrwz"
8465 [(set (match_operand:DF 0 "register_operand" "=d")
8466 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8467 UNSPEC_P8V_MTVSRWZ))]
8468 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8470 [(set_attr "type" "mftgpr")])
8472 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8473 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8474 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8475 UNSPEC_P8V_RELOAD_FROM_GPR))
8476 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8477 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8479 "&& reload_completed"
8482 rtx dest = operands[0];
8483 rtx src = operands[1];
8484 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8485 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8486 rtx gpr_hi_reg = gen_highpart (SImode, src);
8487 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8489 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8490 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8491 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8494 [(set_attr "length" "12")
8495 (set_attr "type" "three")])
8497 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8498 (define_insn "p8_mtvsrd_df"
8499 [(set (match_operand:DF 0 "register_operand" "=wa")
8500 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8501 UNSPEC_P8V_MTVSRD))]
8502 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8504 [(set_attr "type" "mftgpr")])
8506 (define_insn "p8_xxpermdi_<mode>"
8507 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8508 (unspec:FMOVE128_GPR [
8509 (match_operand:DF 1 "register_operand" "wa")
8510 (match_operand:DF 2 "register_operand" "wa")]
8511 UNSPEC_P8V_XXPERMDI))]
8512 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8513 "xxpermdi %x0,%x1,%x2,0"
8514 [(set_attr "type" "vecperm")])
8516 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8517 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8518 (unspec:FMOVE128_GPR
8519 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8520 UNSPEC_P8V_RELOAD_FROM_GPR))
8521 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8522 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8524 "&& reload_completed"
8527 rtx dest = operands[0];
8528 rtx src = operands[1];
8529 /* You might think that we could use op0 as one temp and a DF clobber
8530 as op2, but you'd be wrong. Secondary reload move patterns don't
8531 check for overlap of the clobber and the destination. */
8532 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8533 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8534 rtx gpr_hi_reg = gen_highpart (DImode, src);
8535 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8537 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8538 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8539 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8542 [(set_attr "length" "12")
8543 (set_attr "type" "three")])
8546 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8547 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8549 && (int_reg_operand (operands[0], <MODE>mode)
8550 || int_reg_operand (operands[1], <MODE>mode))
8551 && (!TARGET_DIRECT_MOVE_128
8552 || (!vsx_register_operand (operands[0], <MODE>mode)
8553 && !vsx_register_operand (operands[1], <MODE>mode)))"
8555 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8557 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8558 ;; type is stored internally as double precision in the VSX registers, we have
8559 ;; to convert it from the vector format.
8560 (define_insn "p8_mtvsrd_sf"
8561 [(set (match_operand:SF 0 "register_operand" "=wa")
8562 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8563 UNSPEC_P8V_MTVSRD))]
8564 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8566 [(set_attr "type" "mftgpr")])
8568 (define_insn_and_split "reload_vsx_from_gprsf"
8569 [(set (match_operand:SF 0 "register_operand" "=wa")
8570 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8571 UNSPEC_P8V_RELOAD_FROM_GPR))
8572 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8573 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8575 "&& reload_completed"
8578 rtx op0 = operands[0];
8579 rtx op1 = operands[1];
8580 rtx op2 = operands[2];
8581 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8583 /* Move SF value to upper 32-bits for xscvspdpn. */
8584 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8585 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8586 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8589 [(set_attr "length" "8")
8590 (set_attr "type" "two")])
8592 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8593 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8594 ;; and then doing a move of that.
8595 (define_insn "p8_mfvsrd_3_<mode>"
8596 [(set (match_operand:DF 0 "register_operand" "=r")
8597 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8598 UNSPEC_P8V_RELOAD_FROM_VSX))]
8599 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8601 [(set_attr "type" "mftgpr")])
8603 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8604 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8605 (unspec:FMOVE128_GPR
8606 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8607 UNSPEC_P8V_RELOAD_FROM_VSX))
8608 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8609 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8611 "&& reload_completed"
8614 rtx dest = operands[0];
8615 rtx src = operands[1];
8616 rtx tmp = operands[2];
8617 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8618 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8620 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8621 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8622 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8625 [(set_attr "length" "12")
8626 (set_attr "type" "three")])
8628 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8629 ;; type is stored internally as double precision, we have to convert it to the
8632 (define_insn_and_split "reload_gpr_from_vsxsf"
8633 [(set (match_operand:SF 0 "register_operand" "=r")
8634 (unspec:SF [(match_operand:SF 1 "register_operand" "wa")]
8635 UNSPEC_P8V_RELOAD_FROM_VSX))
8636 (clobber (match_operand:V4SF 2 "register_operand" "=wa"))]
8637 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8639 "&& reload_completed"
8642 rtx op0 = operands[0];
8643 rtx op1 = operands[1];
8644 rtx op2 = operands[2];
8645 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8646 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8648 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8649 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8652 [(set_attr "length" "8")
8653 (set_attr "type" "two")
8654 (set_attr "isa" "p8v")])
8656 ;; Next come the multi-word integer load and store and the load and store
8659 ;; List r->r after r->Y, otherwise reload will try to reload a
8660 ;; non-offsettable address by using r->r which won't make progress.
8661 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8662 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8664 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8665 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8666 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8669 (define_insn "*movdi_internal32"
8670 [(set (match_operand:DI 0 "nonimmediate_operand"
8671 "=Y, r, r, m, ^d, ^d,
8672 r, wY, Z, ^v, $v, ^wa,
8673 wa, wa, v, wa, *i, v,
8675 (match_operand:DI 1 "input_operand"
8676 "r, Y, r, ^d, m, ^d,
8677 IJKnF, ^v, $v, wY, Z, ^wa,
8678 Oj, wM, OjwM, Oj, wM, wS,
8681 && (gpc_reg_operand (operands[0], DImode)
8682 || gpc_reg_operand (operands[1], DImode))"
8704 "store, load, *, fpstore, fpload, fpsimple,
8705 *, fpstore, fpstore, fpload, fpload, veclogical,
8706 vecsimple, vecsimple, vecsimple, veclogical,veclogical,vecsimple,
8708 (set_attr "size" "64")
8716 *, p9v, p7v, p9v, p7v, *,
8717 p9v, p9v, p7v, *, *, p7v,
8721 [(set (match_operand:DI 0 "gpc_reg_operand")
8722 (match_operand:DI 1 "const_int_operand"))]
8723 "! TARGET_POWERPC64 && reload_completed
8724 && gpr_or_gpr_p (operands[0], operands[1])
8725 && !direct_move_p (operands[0], operands[1])"
8726 [(set (match_dup 2) (match_dup 4))
8727 (set (match_dup 3) (match_dup 1))]
8729 HOST_WIDE_INT value = INTVAL (operands[1]);
8730 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8732 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8734 operands[4] = GEN_INT (value >> 32);
8735 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8739 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8740 (match_operand:DIFD 1 "input_operand"))]
8741 "reload_completed && !TARGET_POWERPC64
8742 && gpr_or_gpr_p (operands[0], operands[1])
8743 && !direct_move_p (operands[0], operands[1])"
8745 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8747 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8748 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8749 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8750 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8751 ;; VSX->GPR GPR->VSX
8752 (define_insn "*movdi_internal64"
8753 [(set (match_operand:DI 0 "nonimmediate_operand"
8754 "=YZ, r, r, r, r, r,
8755 m, ^d, ^d, wY, Z, $v,
8756 $v, ^wa, wa, wa, v, wa,
8757 wa, v, v, r, *h, *h,
8759 (match_operand:DI 1 "input_operand"
8760 "r, YZ, r, I, L, nF,
8761 ^d, m, ^d, ^v, $v, wY,
8762 Z, ^wa, Oj, wM, OjwM, Oj,
8763 wM, wS, wB, *h, r, 0,
8766 && (gpc_reg_operand (operands[0], DImode)
8767 || gpc_reg_operand (operands[1], DImode))"
8796 "store, load, *, *, *, *,
8797 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8798 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8799 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8801 (set_attr "size" "64")
8810 *, *, *, p9v, p7v, p9v,
8811 p7v, *, p9v, p9v, p7v, *,
8812 *, p7v, p7v, *, *, *,
8815 ; Some DImode loads are best done as a load of -1 followed by a mask
8818 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8819 (match_operand:DI 1 "const_int_operand"))]
8821 && num_insns_constant (operands[1], DImode) > 1
8822 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8823 && rs6000_is_valid_and_mask (operands[1], DImode)"
8827 (and:DI (match_dup 0)
8831 ;; Split a load of a large constant into the appropriate five-instruction
8832 ;; sequence. Handle anything in a constant number of insns.
8833 ;; When non-easy constants can go in the TOC, this should use
8834 ;; easy_fp_constant predicate.
8836 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8837 (match_operand:DI 1 "const_int_operand"))]
8838 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8839 [(set (match_dup 0) (match_dup 2))
8840 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8842 if (rs6000_emit_set_const (operands[0], operands[1]))
8849 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8850 (match_operand:DI 1 "const_scalar_int_operand"))]
8851 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8852 [(set (match_dup 0) (match_dup 2))
8853 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8855 if (rs6000_emit_set_const (operands[0], operands[1]))
8862 [(set (match_operand:DI 0 "altivec_register_operand")
8863 (match_operand:DI 1 "s5bit_cint_operand"))]
8864 "TARGET_VSX && reload_completed"
8867 rtx op0 = operands[0];
8868 rtx op1 = operands[1];
8869 int r = REGNO (op0);
8870 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8872 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8873 if (op1 != const0_rtx && op1 != constm1_rtx)
8875 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8876 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8881 ;; Split integer constants that can be loaded with XXSPLTIB and a
8882 ;; sign extend operation.
8884 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8885 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8886 "TARGET_P9_VECTOR && reload_completed"
8889 rtx op0 = operands[0];
8890 rtx op1 = operands[1];
8891 int r = REGNO (op0);
8892 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8894 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8895 if (<MODE>mode == DImode)
8896 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8897 else if (<MODE>mode == SImode)
8898 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8899 else if (<MODE>mode == HImode)
8901 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8902 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8908 ;; TImode/PTImode is similar, except that we usually want to compute the
8909 ;; address into a register and use lsi/stsi (the exception is during reload).
8911 (define_insn "*mov<mode>_string"
8912 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8913 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8915 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8916 && (gpc_reg_operand (operands[0], <MODE>mode)
8917 || gpc_reg_operand (operands[1], <MODE>mode))"
8919 [(set_attr "type" "store,store,load,load,*,*")
8920 (set_attr "update" "yes")
8921 (set_attr "indexed" "yes")
8922 (set_attr "cell_micro" "conditional")])
8924 (define_insn "*mov<mode>_ppc64"
8925 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8926 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8927 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8928 && (gpc_reg_operand (operands[0], <MODE>mode)
8929 || gpc_reg_operand (operands[1], <MODE>mode)))"
8931 return rs6000_output_move_128bit (operands);
8933 [(set_attr "type" "store,store,load,load,*,*")
8934 (set_attr "length" "8")])
8937 [(set (match_operand:TI2 0 "int_reg_operand")
8938 (match_operand:TI2 1 "const_scalar_int_operand"))]
8940 && (VECTOR_MEM_NONE_P (<MODE>mode)
8941 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8942 [(set (match_dup 2) (match_dup 4))
8943 (set (match_dup 3) (match_dup 5))]
8945 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8947 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8949 if (CONST_WIDE_INT_P (operands[1]))
8951 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8952 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8954 else if (CONST_INT_P (operands[1]))
8956 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8957 operands[5] = operands[1];
8964 [(set (match_operand:TI2 0 "nonimmediate_operand")
8965 (match_operand:TI2 1 "input_operand"))]
8967 && gpr_or_gpr_p (operands[0], operands[1])
8968 && !direct_move_p (operands[0], operands[1])
8969 && !quad_load_store_p (operands[0], operands[1])"
8971 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8973 (define_expand "setmemsi"
8974 [(parallel [(set (match_operand:BLK 0 "")
8975 (match_operand 2 "const_int_operand"))
8976 (use (match_operand:SI 1 ""))
8977 (use (match_operand:SI 3 ""))])]
8980 /* If value to set is not zero, use the library routine. */
8981 if (operands[2] != const0_rtx)
8984 if (expand_block_clear (operands))
8990 ;; String compare N insn.
8991 ;; Argument 0 is the target (result)
8992 ;; Argument 1 is the destination
8993 ;; Argument 2 is the source
8994 ;; Argument 3 is the length
8995 ;; Argument 4 is the alignment
8997 (define_expand "cmpstrnsi"
8998 [(parallel [(set (match_operand:SI 0)
8999 (compare:SI (match_operand:BLK 1)
9000 (match_operand:BLK 2)))
9001 (use (match_operand:SI 3))
9002 (use (match_operand:SI 4))])]
9003 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9005 if (optimize_insn_for_size_p ())
9008 if (expand_strn_compare (operands, 0))
9014 ;; String compare insn.
9015 ;; Argument 0 is the target (result)
9016 ;; Argument 1 is the destination
9017 ;; Argument 2 is the source
9018 ;; Argument 3 is the alignment
9020 (define_expand "cmpstrsi"
9021 [(parallel [(set (match_operand:SI 0)
9022 (compare:SI (match_operand:BLK 1)
9023 (match_operand:BLK 2)))
9024 (use (match_operand:SI 3))])]
9025 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9027 if (optimize_insn_for_size_p ())
9030 if (expand_strn_compare (operands, 1))
9036 ;; Block compare insn.
9037 ;; Argument 0 is the target (result)
9038 ;; Argument 1 is the destination
9039 ;; Argument 2 is the source
9040 ;; Argument 3 is the length
9041 ;; Argument 4 is the alignment
9043 (define_expand "cmpmemsi"
9044 [(parallel [(set (match_operand:SI 0)
9045 (compare:SI (match_operand:BLK 1)
9046 (match_operand:BLK 2)))
9047 (use (match_operand:SI 3))
9048 (use (match_operand:SI 4))])]
9051 if (expand_block_compare (operands))
9057 ;; String/block move insn.
9058 ;; Argument 0 is the destination
9059 ;; Argument 1 is the source
9060 ;; Argument 2 is the length
9061 ;; Argument 3 is the alignment
9063 (define_expand "cpymemsi"
9064 [(parallel [(set (match_operand:BLK 0 "")
9065 (match_operand:BLK 1 ""))
9066 (use (match_operand:SI 2 ""))
9067 (use (match_operand:SI 3 ""))])]
9070 if (expand_block_move (operands))
9076 ;; Define insns that do load or store with update. Some of these we can
9077 ;; get by using pre-decrement or pre-increment, but the hardware can also
9078 ;; do cases where the increment is not the size of the object.
9080 ;; In all these cases, we use operands 0 and 1 for the register being
9081 ;; incremented because those are the operands that local-alloc will
9082 ;; tie and these are the pair most likely to be tieable (and the ones
9083 ;; that will benefit the most).
9085 (define_insn "*movdi_update1"
9086 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9087 (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9088 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I"))))
9089 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9090 (plus:P (match_dup 1) (match_dup 2)))]
9091 "TARGET_POWERPC64 && TARGET_UPDATE
9092 && (!avoiding_indexed_address_p (DImode)
9093 || !gpc_reg_operand (operands[2], Pmode))"
9097 [(set_attr "type" "load")
9098 (set_attr "update" "yes")
9099 (set_attr "indexed" "yes,no")])
9101 (define_insn "movdi_<mode>_update"
9102 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9103 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9104 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9105 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9106 (plus:P (match_dup 1) (match_dup 2)))]
9107 "TARGET_POWERPC64 && TARGET_UPDATE
9108 && (!avoiding_indexed_address_p (DImode)
9109 || !gpc_reg_operand (operands[2], Pmode)
9110 || (REG_P (operands[0])
9111 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9115 [(set_attr "type" "store")
9116 (set_attr "update" "yes")
9117 (set_attr "indexed" "yes,no")])
9119 ;; This pattern is only conditional on TARGET_64BIT, as it is
9120 ;; needed for stack allocation, even if the user passes -mno-update.
9121 (define_insn "movdi_update_stack"
9122 [(set (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9123 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I")))
9124 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9125 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9126 (plus:DI (match_dup 1) (match_dup 2)))]
9131 [(set_attr "type" "store")
9132 (set_attr "update" "yes")
9133 (set_attr "indexed" "yes,no")])
9135 (define_insn "*movsi_update1"
9136 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9137 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9138 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9139 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9140 (plus:P (match_dup 1) (match_dup 2)))]
9142 && (!avoiding_indexed_address_p (SImode)
9143 || !gpc_reg_operand (operands[2], Pmode))"
9147 [(set_attr "type" "load")
9148 (set_attr "update" "yes")
9149 (set_attr "indexed" "yes,no")])
9151 (define_insn "*movsi_update2"
9152 [(set (match_operand:EXTSI 3 "gpc_reg_operand" "=r")
9154 (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0")
9155 (match_operand:P 2 "gpc_reg_operand" "r")))))
9156 (set (match_operand:P 0 "gpc_reg_operand" "=b")
9157 (plus:P (match_dup 1) (match_dup 2)))]
9158 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9160 [(set_attr "type" "load")
9161 (set_attr "sign_extend" "yes")
9162 (set_attr "update" "yes")
9163 (set_attr "indexed" "yes")])
9165 (define_insn "movsi_<mode>_update"
9166 [(set (mem:SI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9167 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9168 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9169 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9170 (plus:P (match_dup 1) (match_dup 2)))]
9172 && (!avoiding_indexed_address_p (SImode)
9173 || !gpc_reg_operand (operands[2], Pmode)
9174 || (REG_P (operands[0])
9175 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9179 [(set_attr "type" "store")
9180 (set_attr "update" "yes")
9181 (set_attr "indexed" "yes,no")])
9183 ;; This is an unconditional pattern; needed for stack allocation, even
9184 ;; if the user passes -mno-update.
9185 (define_insn "movsi_update_stack"
9186 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9187 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9188 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9189 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9190 (plus:SI (match_dup 1) (match_dup 2)))]
9195 [(set_attr "type" "store")
9196 (set_attr "update" "yes")
9197 (set_attr "indexed" "yes,no")])
9199 (define_insn "*movhi_update1"
9200 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9201 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9202 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9203 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9204 (plus:P (match_dup 1) (match_dup 2)))]
9206 && (!avoiding_indexed_address_p (HImode)
9207 || !gpc_reg_operand (operands[2], SImode))"
9211 [(set_attr "type" "load")
9212 (set_attr "update" "yes")
9213 (set_attr "indexed" "yes,no")])
9215 (define_insn "*movhi_update2"
9216 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9218 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9219 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9220 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9221 (plus:P (match_dup 1) (match_dup 2)))]
9223 && (!avoiding_indexed_address_p (HImode)
9224 || !gpc_reg_operand (operands[2], Pmode))"
9228 [(set_attr "type" "load")
9229 (set_attr "update" "yes")
9230 (set_attr "indexed" "yes,no")])
9232 (define_insn "*movhi_update3"
9233 [(set (match_operand:EXTHI 3 "gpc_reg_operand" "=r,r")
9235 (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9236 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9237 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9238 (plus:P (match_dup 1) (match_dup 2)))]
9240 && !(avoiding_indexed_address_p (HImode)
9241 && gpc_reg_operand (operands[2], Pmode))"
9245 [(set_attr "type" "load")
9246 (set_attr "sign_extend" "yes")
9247 (set_attr "update" "yes")
9248 (set_attr "indexed" "yes,no")])
9250 (define_insn "*movhi_update4"
9251 [(set (mem:HI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9252 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9253 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9254 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9255 (plus:P (match_dup 1) (match_dup 2)))]
9257 && (!avoiding_indexed_address_p (HImode)
9258 || !gpc_reg_operand (operands[2], Pmode))"
9262 [(set_attr "type" "store")
9263 (set_attr "update" "yes")
9264 (set_attr "indexed" "yes,no")])
9266 (define_insn "*movqi_update1"
9267 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9268 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9269 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9270 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9271 (plus:P (match_dup 1) (match_dup 2)))]
9273 && (!avoiding_indexed_address_p (QImode)
9274 || !gpc_reg_operand (operands[2], Pmode))"
9278 [(set_attr "type" "load")
9279 (set_attr "update" "yes")
9280 (set_attr "indexed" "yes,no")])
9282 (define_insn "*movqi_update2"
9283 [(set (match_operand:EXTQI 3 "gpc_reg_operand" "=r,r")
9285 (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9286 (match_operand:P 2 "reg_or_short_operand" "r,I")))))
9287 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9288 (plus:P (match_dup 1) (match_dup 2)))]
9290 && (!avoiding_indexed_address_p (QImode)
9291 || !gpc_reg_operand (operands[2], Pmode))"
9295 [(set_attr "type" "load")
9296 (set_attr "update" "yes")
9297 (set_attr "indexed" "yes,no")])
9299 (define_insn "*movqi_update3"
9300 [(set (mem:QI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9301 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9302 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9303 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9304 (plus:P (match_dup 1) (match_dup 2)))]
9306 && (!avoiding_indexed_address_p (QImode)
9307 || !gpc_reg_operand (operands[2], Pmode))"
9311 [(set_attr "type" "store")
9312 (set_attr "update" "yes")
9313 (set_attr "indexed" "yes,no")])
9315 (define_insn "*mov<mode>_update1"
9316 [(set (match_operand:SFDF 3 "gpc_reg_operand" "=<Ff>,<Ff>")
9317 (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9318 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9319 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9320 (plus:P (match_dup 1) (match_dup 2)))]
9321 "TARGET_HARD_FLOAT && TARGET_UPDATE
9322 && (!avoiding_indexed_address_p (<MODE>mode)
9323 || !gpc_reg_operand (operands[2], Pmode))"
9327 [(set_attr "type" "fpload")
9328 (set_attr "update" "yes")
9329 (set_attr "indexed" "yes,no")
9330 (set_attr "size" "<bits>")])
9332 (define_insn "*mov<mode>_update2"
9333 [(set (mem:SFDF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9334 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9335 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,<Ff>"))
9336 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9337 (plus:P (match_dup 1) (match_dup 2)))]
9338 "TARGET_HARD_FLOAT && TARGET_UPDATE
9339 && (!avoiding_indexed_address_p (<MODE>mode)
9340 || !gpc_reg_operand (operands[2], Pmode))"
9344 [(set_attr "type" "fpstore")
9345 (set_attr "update" "yes")
9346 (set_attr "indexed" "yes,no")
9347 (set_attr "size" "<bits>")])
9349 (define_insn "*movsf_update3"
9350 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9351 (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9352 (match_operand:P 2 "reg_or_short_operand" "r,I"))))
9353 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9354 (plus:P (match_dup 1) (match_dup 2)))]
9355 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9356 && (!avoiding_indexed_address_p (SFmode)
9357 || !gpc_reg_operand (operands[2], Pmode))"
9361 [(set_attr "type" "load")
9362 (set_attr "update" "yes")
9363 (set_attr "indexed" "yes,no")])
9365 (define_insn "*movsf_update4"
9366 [(set (mem:SF (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9367 (match_operand:P 2 "reg_or_short_operand" "r,I")))
9368 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9369 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9370 (plus:P (match_dup 1) (match_dup 2)))]
9371 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9372 && (!avoiding_indexed_address_p (SFmode)
9373 || !gpc_reg_operand (operands[2], Pmode))"
9377 [(set_attr "type" "store")
9378 (set_attr "update" "yes")
9379 (set_attr "indexed" "yes,no")])
9382 ;; After inserting conditional returns we can sometimes have
9383 ;; unnecessary register moves. Unfortunately we cannot have a
9384 ;; modeless peephole here, because some single SImode sets have early
9385 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9386 ;; sequences, using get_attr_length here will smash the operands
9387 ;; array. Neither is there an early_cobbler_p predicate.
9388 ;; Also this optimization interferes with scalars going into
9389 ;; altivec registers (the code does reloading through the FPRs).
9391 [(set (match_operand:DF 0 "gpc_reg_operand")
9392 (match_operand:DF 1 "any_operand"))
9393 (set (match_operand:DF 2 "gpc_reg_operand")
9396 && peep2_reg_dead_p (2, operands[0])"
9397 [(set (match_dup 2) (match_dup 1))])
9400 [(set (match_operand:SF 0 "gpc_reg_operand")
9401 (match_operand:SF 1 "any_operand"))
9402 (set (match_operand:SF 2 "gpc_reg_operand")
9405 && peep2_reg_dead_p (2, operands[0])"
9406 [(set (match_dup 2) (match_dup 1))])
9411 (define_insn_and_split "*tls_gd<bits>"
9412 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9413 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9414 (match_operand:P 2 "gpc_reg_operand" "b")]
9416 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9417 "addi %0,%2,%1@got@tlsgd"
9418 "&& TARGET_CMODEL != CMODEL_SMALL"
9421 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9423 (lo_sum:P (match_dup 3)
9424 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9426 operands[3] = gen_reg_rtx (<MODE>mode);
9428 [(set (attr "length")
9429 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9433 (define_insn "*tls_gd_high<bits>"
9434 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9436 (unspec:P [(match_operand:P 1 "rs6000_tls_symbol_ref" "")
9437 (match_operand:P 2 "gpc_reg_operand" "b")]
9439 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9440 "addis %0,%2,%1@got@tlsgd@ha")
9442 (define_insn "*tls_gd_low<bits>"
9443 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9444 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9445 (unspec:P [(match_operand:P 2 "rs6000_tls_symbol_ref" "")
9446 (match_operand:P 3 "gpc_reg_operand" "b")]
9448 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9449 "addi %0,%1,%2@got@tlsgd@l")
9451 (define_insn_and_split "*tls_ld<bits>"
9452 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9453 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9455 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9456 "addi %0,%1,%&@got@tlsld"
9457 "&& TARGET_CMODEL != CMODEL_SMALL"
9460 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))
9462 (lo_sum:P (match_dup 2)
9463 (unspec:P [(match_dup 1)] UNSPEC_TLSLD)))]
9465 operands[2] = gen_reg_rtx (<MODE>mode);
9467 [(set (attr "length")
9468 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9472 (define_insn "*tls_ld_high<bits>"
9473 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9475 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")]
9477 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9478 "addis %0,%1,%&@got@tlsld@ha")
9480 (define_insn "*tls_ld_low<bits>"
9481 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9482 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9483 (unspec:P [(match_operand:P 2 "gpc_reg_operand" "b")]
9485 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9486 "addi %0,%1,%&@got@tlsld@l")
9488 (define_insn "tls_dtprel_<bits>"
9489 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9490 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9491 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9494 "addi %0,%1,%2@dtprel")
9496 (define_insn "tls_dtprel_ha_<bits>"
9497 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9498 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9499 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9500 UNSPEC_TLSDTPRELHA))]
9502 "addis %0,%1,%2@dtprel@ha")
9504 (define_insn "tls_dtprel_lo_<bits>"
9505 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9506 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9507 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9508 UNSPEC_TLSDTPRELLO))]
9510 "addi %0,%1,%2@dtprel@l")
9512 (define_insn_and_split "tls_got_dtprel_<bits>"
9513 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9514 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9515 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9516 UNSPEC_TLSGOTDTPREL))]
9518 "<ptrload> %0,%2@got@dtprel(%1)"
9519 "&& TARGET_CMODEL != CMODEL_SMALL"
9522 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9524 (lo_sum:P (match_dup 3)
9525 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9527 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9529 [(set (attr "length")
9530 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9534 (define_insn "*tls_got_dtprel_high<bits>"
9535 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9537 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9538 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9539 UNSPEC_TLSGOTDTPREL)))]
9540 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9541 "addis %0,%1,%2@got@dtprel@ha")
9543 (define_insn "*tls_got_dtprel_low<bits>"
9544 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9545 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9546 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9547 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9548 UNSPEC_TLSGOTDTPREL)))]
9549 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9550 "<ptrload> %0,%2@got@dtprel@l(%1)")
9552 (define_insn "tls_tprel_<bits>"
9553 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9554 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9555 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9558 "addi %0,%1,%2@tprel")
9560 (define_insn "tls_tprel_ha_<bits>"
9561 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9562 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9563 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9564 UNSPEC_TLSTPRELHA))]
9566 "addis %0,%1,%2@tprel@ha")
9568 (define_insn "tls_tprel_lo_<bits>"
9569 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9570 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9571 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9572 UNSPEC_TLSTPRELLO))]
9574 "addi %0,%1,%2@tprel@l")
9576 ;; "b" output constraint here and on tls_tls input to support linker tls
9577 ;; optimization. The linker may edit the instructions emitted by a
9578 ;; tls_got_tprel/tls_tls pair to addis,addi.
9579 (define_insn_and_split "tls_got_tprel_<bits>"
9580 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9581 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9582 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9583 UNSPEC_TLSGOTTPREL))]
9585 "<ptrload> %0,%2@got@tprel(%1)"
9586 "&& TARGET_CMODEL != CMODEL_SMALL"
9589 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9591 (lo_sum:P (match_dup 3)
9592 (unspec:P [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9594 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9596 [(set (attr "length")
9597 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9601 (define_insn "*tls_got_tprel_high<bits>"
9602 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
9604 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9605 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9606 UNSPEC_TLSGOTTPREL)))]
9607 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9608 "addis %0,%1,%2@got@tprel@ha")
9610 (define_insn "*tls_got_tprel_low<bits>"
9611 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9612 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
9613 (unspec:P [(match_operand:P 3 "gpc_reg_operand" "b")
9614 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9615 UNSPEC_TLSGOTTPREL)))]
9616 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9617 "<ptrload> %0,%2@got@tprel@l(%1)")
9619 (define_insn "tls_tls_<bits>"
9620 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
9621 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
9622 (match_operand:P 2 "rs6000_tls_symbol_ref" "")]
9624 "TARGET_ELF && HAVE_AS_TLS"
9627 (define_expand "tls_get_tpointer"
9628 [(set (match_operand:SI 0 "gpc_reg_operand")
9629 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9630 "TARGET_XCOFF && HAVE_AS_TLS"
9632 emit_insn (gen_tls_get_tpointer_internal ());
9633 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9637 (define_insn "tls_get_tpointer_internal"
9639 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9640 (clobber (reg:SI LR_REGNO))]
9641 "TARGET_XCOFF && HAVE_AS_TLS"
9642 "bla __get_tpointer")
9644 (define_expand "tls_get_addr<mode>"
9645 [(set (match_operand:P 0 "gpc_reg_operand")
9646 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9647 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9648 "TARGET_XCOFF && HAVE_AS_TLS"
9650 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9651 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9652 emit_insn (gen_tls_get_addr_internal<mode> ());
9653 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9657 (define_insn "tls_get_addr_internal<mode>"
9659 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9663 (clobber (reg:P 11))
9664 (clobber (reg:CC CR0_REGNO))
9665 (clobber (reg:P LR_REGNO))]
9666 "TARGET_XCOFF && HAVE_AS_TLS"
9667 "bla __tls_get_addr")
9669 ;; Next come insns related to the calling sequence.
9671 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9672 ;; We move the back-chain and decrement the stack pointer.
9674 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9675 ;; constant alloca, using that predicate will force the generic code to put
9676 ;; the constant size into a register before calling the expander.
9678 ;; As a result the expander would not have the constant size information
9679 ;; in those cases and would have to generate less efficient code.
9681 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9682 ;; the constant size. The value is forced into a register if necessary.
9684 (define_expand "allocate_stack"
9685 [(set (match_operand 0 "gpc_reg_operand")
9686 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9688 (minus (reg 1) (match_dup 1)))]
9691 rtx chain = gen_reg_rtx (Pmode);
9692 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9694 rtx insn, par, set, mem;
9696 /* By allowing reg_or_cint_operand as the predicate we can get
9697 better code for stack-clash-protection because we do not lose
9698 size information. But the rest of the code expects the operand
9699 to be reg_or_short_operand. If it isn't, then force it into
9701 rtx orig_op1 = operands[1];
9702 if (!reg_or_short_operand (operands[1], Pmode))
9703 operands[1] = force_reg (Pmode, operands[1]);
9705 emit_move_insn (chain, stack_bot);
9707 /* Check stack bounds if necessary. */
9708 if (crtl->limit_stack)
9711 available = expand_binop (Pmode, sub_optab,
9712 stack_pointer_rtx, stack_limit_rtx,
9713 NULL_RTX, 1, OPTAB_WIDEN);
9714 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9717 /* Allocate and probe if requested.
9718 This may look similar to the loop we use for prologue allocations,
9719 but it is critically different. For the former we know the loop
9720 will iterate, but do not know that generally here. The former
9721 uses that knowledge to rotate the loop. Combining them would be
9722 possible with some performance cost. */
9723 if (flag_stack_clash_protection)
9725 rtx rounded_size, last_addr, residual;
9726 HOST_WIDE_INT probe_interval;
9727 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9728 &residual, &probe_interval,
9731 /* We do occasionally get in here with constant sizes, we might
9732 as well do a reasonable job when we obviously can. */
9733 if (rounded_size != const0_rtx)
9735 rtx loop_lab, end_loop;
9736 bool rotated = CONST_INT_P (rounded_size);
9737 rtx update = GEN_INT (-probe_interval);
9738 if (probe_interval > 32768)
9739 update = force_reg (Pmode, update);
9741 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9742 last_addr, rotated);
9745 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9749 emit_insn (gen_movdi_update_stack (stack_pointer_rtx,
9752 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9753 last_addr, rotated);
9756 /* Now handle residuals. We just have to set operands[1] correctly
9757 and let the rest of the expander run. */
9758 operands[1] = residual;
9761 if (!(CONST_INT_P (operands[1])
9762 && IN_RANGE (INTVAL (operands[1]), -32767, 32768)))
9764 operands[1] = force_reg (Pmode, operands[1]);
9765 neg_op0 = gen_reg_rtx (Pmode);
9766 emit_insn (gen_neg2 (Pmode, neg_op0, operands[1]));
9769 neg_op0 = GEN_INT (-INTVAL (operands[1]));
9771 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9772 : gen_movdi_update_stack))
9773 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9775 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9776 it now and set the alias set/attributes. The above gen_*_update
9777 calls will generate a PARALLEL with the MEM set being the first
9779 par = PATTERN (insn);
9780 gcc_assert (GET_CODE (par) == PARALLEL);
9781 set = XVECEXP (par, 0, 0);
9782 gcc_assert (GET_CODE (set) == SET);
9783 mem = SET_DEST (set);
9784 gcc_assert (MEM_P (mem));
9785 MEM_NOTRAP_P (mem) = 1;
9786 set_mem_alias_set (mem, get_frame_alias_set ());
9788 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9792 ;; These patterns say how to save and restore the stack pointer. We need not
9793 ;; save the stack pointer at function level since we are careful to
9794 ;; preserve the backchain. At block level, we have to restore the backchain
9795 ;; when we restore the stack pointer.
9797 ;; For nonlocal gotos, we must save both the stack pointer and its
9798 ;; backchain and restore both. Note that in the nonlocal case, the
9799 ;; save area is a memory location.
9801 (define_expand "save_stack_function"
9802 [(match_operand 0 "any_operand")
9803 (match_operand 1 "any_operand")]
9807 (define_expand "restore_stack_function"
9808 [(match_operand 0 "any_operand")
9809 (match_operand 1 "any_operand")]
9813 ;; Adjust stack pointer (op0) to a new value (op1).
9814 ;; First copy old stack backchain to new location, and ensure that the
9815 ;; scheduler won't reorder the sp assignment before the backchain write.
9816 (define_expand "restore_stack_block"
9817 [(set (match_dup 2) (match_dup 3))
9818 (set (match_dup 4) (match_dup 2))
9820 (set (match_operand 0 "register_operand")
9821 (match_operand 1 "register_operand"))]
9826 operands[1] = force_reg (Pmode, operands[1]);
9827 operands[2] = gen_reg_rtx (Pmode);
9828 operands[3] = gen_frame_mem (Pmode, operands[0]);
9829 operands[4] = gen_frame_mem (Pmode, operands[1]);
9830 p = rtvec_alloc (1);
9831 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9833 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9836 (define_expand "save_stack_nonlocal"
9837 [(set (match_dup 3) (match_dup 4))
9838 (set (match_operand 0 "memory_operand") (match_dup 3))
9839 (set (match_dup 2) (match_operand 1 "register_operand"))]
9842 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9844 /* Copy the backchain to the first word, sp to the second. */
9845 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9846 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9847 operands[3] = gen_reg_rtx (Pmode);
9848 operands[4] = gen_frame_mem (Pmode, operands[1]);
9851 (define_expand "restore_stack_nonlocal"
9852 [(set (match_dup 2) (match_operand 1 "memory_operand"))
9853 (set (match_dup 3) (match_dup 4))
9854 (set (match_dup 5) (match_dup 2))
9856 (set (match_operand 0 "register_operand") (match_dup 3))]
9859 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9862 /* Restore the backchain from the first word, sp from the second. */
9863 operands[2] = gen_reg_rtx (Pmode);
9864 operands[3] = gen_reg_rtx (Pmode);
9865 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9866 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9867 operands[5] = gen_frame_mem (Pmode, operands[3]);
9868 p = rtvec_alloc (1);
9869 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9871 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9874 ;; TOC register handling.
9876 ;; Code to initialize the TOC register...
9878 (define_insn "load_toc_aix_si"
9879 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9880 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9882 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9885 extern int need_toc_init;
9887 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9888 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9889 operands[2] = gen_rtx_REG (Pmode, 2);
9890 return "lwz %0,%1(%2)";
9892 [(set_attr "type" "load")
9893 (set_attr "update" "no")
9894 (set_attr "indexed" "no")])
9896 (define_insn "load_toc_aix_di"
9897 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9898 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9900 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9903 extern int need_toc_init;
9905 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9906 !TARGET_ELF || !TARGET_MINIMAL_TOC);
9908 strcat (buf, "@toc");
9909 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9910 operands[2] = gen_rtx_REG (Pmode, 2);
9911 return "ld %0,%1(%2)";
9913 [(set_attr "type" "load")
9914 (set_attr "update" "no")
9915 (set_attr "indexed" "no")])
9917 (define_insn "load_toc_v4_pic_si"
9918 [(set (reg:SI LR_REGNO)
9919 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9920 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9921 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9922 [(set_attr "type" "branch")])
9924 (define_expand "load_toc_v4_PIC_1"
9925 [(parallel [(set (reg:SI LR_REGNO)
9926 (match_operand:SI 0 "immediate_operand" "s"))
9927 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9928 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9929 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9932 (define_insn "load_toc_v4_PIC_1_normal"
9933 [(set (reg:SI LR_REGNO)
9934 (match_operand:SI 0 "immediate_operand" "s"))
9935 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9936 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9937 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9939 [(set_attr "type" "branch")
9940 (set_attr "cannot_copy" "yes")])
9942 (define_insn "load_toc_v4_PIC_1_476"
9943 [(set (reg:SI LR_REGNO)
9944 (match_operand:SI 0 "immediate_operand" "s"))
9945 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9946 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9947 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9950 static char templ[32];
9952 get_ppc476_thunk_name (name);
9953 sprintf (templ, "bl %s\n%%0:", name);
9956 [(set_attr "type" "branch")
9957 (set_attr "cannot_copy" "yes")])
9959 (define_expand "load_toc_v4_PIC_1b"
9960 [(parallel [(set (reg:SI LR_REGNO)
9961 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9962 (label_ref (match_operand 1 ""))]
9965 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9968 (define_insn "load_toc_v4_PIC_1b_normal"
9969 [(set (reg:SI LR_REGNO)
9970 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9971 (label_ref (match_operand 1 "" ""))]
9974 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9975 "bcl 20,31,$+8\;.long %0-$"
9976 [(set_attr "type" "branch")
9977 (set_attr "length" "8")])
9979 (define_insn "load_toc_v4_PIC_1b_476"
9980 [(set (reg:SI LR_REGNO)
9981 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
9982 (label_ref (match_operand 1 "" ""))]
9985 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
9988 static char templ[32];
9990 get_ppc476_thunk_name (name);
9991 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
9994 [(set_attr "type" "branch")
9995 (set_attr "length" "16")])
9997 (define_insn "load_toc_v4_PIC_2"
9998 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10000 (match_operand:SI 1 "gpc_reg_operand" "b")
10002 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10003 (match_operand:SI 3 "immediate_operand" "s"))))))]
10004 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10006 [(set_attr "type" "load")])
10008 (define_insn "load_toc_v4_PIC_3b"
10009 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10011 (match_operand:SI 1 "gpc_reg_operand" "b")
10014 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10015 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10016 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10017 "addis %0,%1,%2-%3@ha")
10019 (define_insn "load_toc_v4_PIC_3c"
10020 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10022 (match_operand:SI 1 "gpc_reg_operand" "b")
10024 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10025 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10026 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10027 "addi %0,%1,%2-%3@l")
10029 ;; If the TOC is shared over a translation unit, as happens with all
10030 ;; the kinds of PIC that we support, we need to restore the TOC
10031 ;; pointer only when jumping over units of translation.
10032 ;; On Darwin, we need to reload the picbase.
10034 (define_expand "builtin_setjmp_receiver"
10035 [(use (label_ref (match_operand 0 "")))]
10036 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10037 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10038 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10041 if (DEFAULT_ABI == ABI_DARWIN)
10043 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10044 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10048 crtl->uses_pic_offset_table = 1;
10049 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10050 CODE_LABEL_NUMBER (operands[0]));
10051 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10053 emit_insn (gen_load_macho_picbase (tmplabrtx));
10054 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10055 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10059 rs6000_emit_load_toc_table (FALSE);
10063 ;; Largetoc support
10064 (define_insn "*largetoc_high"
10065 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10067 (unspec [(match_operand:DI 1 "" "")
10068 (match_operand:DI 2 "gpc_reg_operand" "b")]
10070 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10071 "addis %0,%2,%1@toc@ha")
10073 (define_insn "*largetoc_high_aix<mode>"
10074 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10076 (unspec [(match_operand:P 1 "" "")
10077 (match_operand:P 2 "gpc_reg_operand" "b")]
10079 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10080 "addis %0,%1@u(%2)")
10082 (define_insn "*largetoc_high_plus"
10083 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10086 (unspec [(match_operand:DI 1 "" "")
10087 (match_operand:DI 2 "gpc_reg_operand" "b")]
10089 (match_operand:DI 3 "add_cint_operand" "n"))))]
10090 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10091 "addis %0,%2,%1+%3@toc@ha")
10093 (define_insn "*largetoc_high_plus_aix<mode>"
10094 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10097 (unspec [(match_operand:P 1 "" "")
10098 (match_operand:P 2 "gpc_reg_operand" "b")]
10100 (match_operand:P 3 "add_cint_operand" "n"))))]
10101 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10102 "addis %0,%1+%3@u(%2)")
10104 (define_insn "*largetoc_low"
10105 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10106 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10107 (match_operand:DI 2 "" "")))]
10108 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10111 (define_insn "*largetoc_low_aix<mode>"
10112 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10113 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10114 (match_operand:P 2 "" "")))]
10115 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10118 (define_insn_and_split "*tocref<mode>"
10119 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10120 (match_operand:P 1 "small_toc_ref" "R"))]
10123 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10124 [(set (match_dup 0) (high:P (match_dup 1)))
10125 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10127 ;; Elf specific ways of loading addresses for non-PIC code.
10128 ;; The output of this could be r0, but we make a very strong
10129 ;; preference for a base register because it will usually
10130 ;; be needed there.
10131 (define_insn "elf_high"
10132 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10133 (high:SI (match_operand 1 "" "")))]
10134 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10137 (define_insn "elf_low"
10138 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10139 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10140 (match_operand 2 "" "")))]
10141 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10144 (define_insn "*pltseq_tocsave_<mode>"
10145 [(set (match_operand:P 0 "memory_operand" "=m")
10146 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10147 (match_operand:P 2 "symbol_ref_operand" "s")
10148 (match_operand:P 3 "" "")]
10151 && DEFAULT_ABI == ABI_ELFv2"
10153 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_TOCSAVE);
10156 (define_insn "*pltseq_plt16_ha_<mode>"
10157 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10158 (unspec:P [(match_operand:P 1 "" "")
10159 (match_operand:P 2 "symbol_ref_operand" "s")
10160 (match_operand:P 3 "" "")]
10164 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_HA);
10167 (define_insn "*pltseq_plt16_lo_<mode>"
10168 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10169 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "b")
10170 (match_operand:P 2 "symbol_ref_operand" "s")
10171 (match_operand:P 3 "" "")]
10175 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT16_LO);
10177 [(set_attr "type" "load")])
10179 (define_insn "*pltseq_mtctr_<mode>"
10180 [(set (match_operand:P 0 "register_operand" "=c")
10181 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
10182 (match_operand:P 2 "symbol_ref_operand" "s")
10183 (match_operand:P 3 "" "")]
10187 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_MTCTR);
10190 (define_insn "*pltseq_plt_pcrel<mode>"
10191 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10192 (unspec:P [(match_operand:P 1 "" "")
10193 (match_operand:P 2 "symbol_ref_operand" "s")
10194 (match_operand:P 3 "" "")]
10195 UNSPEC_PLT_PCREL))]
10196 "HAVE_AS_PLTSEQ && TARGET_TLS_MARKERS
10197 && rs6000_pcrel_p (cfun)"
10199 return rs6000_pltseq_template (operands, RS6000_PLTSEQ_PLT_PCREL34);
10201 [(set_attr "type" "load")
10202 (set_attr "length" "12")])
10204 ;; Call and call_value insns
10205 ;; For the purposes of expanding calls, Darwin is very similar to SYSV.
10206 (define_expand "call"
10207 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10208 (match_operand 1 ""))
10209 (use (match_operand 2 ""))
10210 (clobber (reg:SI LR_REGNO))])]
10214 if (MACHOPIC_INDIRECT)
10215 operands[0] = machopic_indirect_call_target (operands[0]);
10218 gcc_assert (MEM_P (operands[0]));
10220 operands[0] = XEXP (operands[0], 0);
10222 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10223 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10224 else if (DEFAULT_ABI == ABI_V4)
10225 rs6000_call_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10226 else if (DEFAULT_ABI == ABI_DARWIN)
10227 rs6000_call_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10229 gcc_unreachable ();
10234 (define_expand "call_value"
10235 [(parallel [(set (match_operand 0 "")
10236 (call (mem:SI (match_operand 1 "address_operand"))
10237 (match_operand 2 "")))
10238 (use (match_operand 3 ""))
10239 (clobber (reg:SI LR_REGNO))])]
10243 if (MACHOPIC_INDIRECT)
10244 operands[1] = machopic_indirect_call_target (operands[1]);
10247 gcc_assert (MEM_P (operands[1]));
10249 operands[1] = XEXP (operands[1], 0);
10251 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10252 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10253 else if (DEFAULT_ABI == ABI_V4)
10254 rs6000_call_sysv (operands[0], operands[1], operands[2], operands[3]);
10255 else if (DEFAULT_ABI == ABI_DARWIN)
10256 rs6000_call_darwin (operands[0], operands[1], operands[2], operands[3]);
10258 gcc_unreachable ();
10263 ;; Call to function in current module. No TOC pointer reload needed.
10264 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10265 ;; either the function was not prototyped, or it was prototyped as a
10266 ;; variable argument function. It is > 0 if FP registers were passed
10267 ;; and < 0 if they were not.
10269 (define_insn "*call_local32"
10270 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10272 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10273 (clobber (reg:SI LR_REGNO))]
10274 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10276 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10277 output_asm_insn ("crxor 6,6,6", operands);
10279 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10280 output_asm_insn ("creqv 6,6,6", operands);
10282 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10284 [(set_attr "type" "branch")
10285 (set_attr "length" "4,8")])
10287 (define_insn "*call_local64"
10288 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10290 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10291 (clobber (reg:DI LR_REGNO))]
10292 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10294 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10295 output_asm_insn ("crxor 6,6,6", operands);
10297 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10298 output_asm_insn ("creqv 6,6,6", operands);
10300 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10302 [(set_attr "type" "branch")
10303 (set_attr "length" "4,8")])
10305 (define_insn "*call_value_local32"
10306 [(set (match_operand 0 "" "")
10307 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10308 (match_operand 2)))
10309 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10310 (clobber (reg:SI LR_REGNO))]
10311 "(INTVAL (operands[3]) & CALL_LONG) == 0
10312 && !IS_NOMARK_TLSGETADDR (operands[2])"
10314 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10315 output_asm_insn ("crxor 6,6,6", operands);
10317 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10318 output_asm_insn ("creqv 6,6,6", operands);
10320 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10322 [(set_attr "type" "branch")
10323 (set_attr "length" "4,8")])
10326 (define_insn "*call_value_local64"
10327 [(set (match_operand 0 "" "")
10328 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10329 (match_operand 2)))
10330 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10331 (clobber (reg:DI LR_REGNO))]
10332 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0
10333 && !IS_NOMARK_TLSGETADDR (operands[2])"
10335 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10336 output_asm_insn ("crxor 6,6,6", operands);
10338 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10339 output_asm_insn ("creqv 6,6,6", operands);
10341 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10343 [(set_attr "type" "branch")
10344 (set_attr "length" "4,8")])
10347 ;; A function pointer under System V is just a normal pointer
10348 ;; operands[0] is the function pointer
10349 ;; operands[1] is the tls call arg
10350 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10351 ;; which indicates how to set cr1
10353 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10354 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10356 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10357 (clobber (reg:P LR_REGNO))]
10358 "DEFAULT_ABI == ABI_V4
10359 || DEFAULT_ABI == ABI_DARWIN"
10361 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10362 output_asm_insn ("crxor 6,6,6", operands);
10364 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10365 output_asm_insn ("creqv 6,6,6", operands);
10367 return rs6000_indirect_call_template (operands, 0);
10369 [(set_attr "type" "jmpreg")
10370 (set (attr "length")
10371 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10372 (match_test "which_alternative != 1"))
10373 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10374 (const_string "12")
10375 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10376 (match_test "which_alternative != 1"))
10377 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10378 (const_string "8")]
10379 (const_string "4")))])
10381 (define_insn "*call_nonlocal_sysv<mode>"
10382 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10384 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10385 (clobber (reg:P LR_REGNO))]
10386 "(DEFAULT_ABI == ABI_DARWIN
10387 || (DEFAULT_ABI == ABI_V4
10388 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10390 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10391 output_asm_insn ("crxor 6,6,6", operands);
10393 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10394 output_asm_insn ("creqv 6,6,6", operands);
10396 return rs6000_call_template (operands, 0);
10398 [(set_attr "type" "branch,branch")
10399 (set_attr "length" "4,8")])
10401 (define_insn "*call_nonlocal_sysv_secure<mode>"
10402 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10404 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10405 (use (match_operand:SI 3 "register_operand" "r,r"))
10406 (clobber (reg:P LR_REGNO))]
10407 "(DEFAULT_ABI == ABI_V4
10408 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10409 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10411 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10412 output_asm_insn ("crxor 6,6,6", operands);
10414 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10415 output_asm_insn ("creqv 6,6,6", operands);
10417 return rs6000_call_template (operands, 0);
10419 [(set_attr "type" "branch,branch")
10420 (set_attr "length" "4,8")])
10422 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10423 [(set (match_operand 0 "" "")
10424 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10425 (match_operand:P 2 "unspec_tls" "")))
10426 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10427 (clobber (reg:P LR_REGNO))]
10428 "DEFAULT_ABI == ABI_V4
10429 || DEFAULT_ABI == ABI_DARWIN"
10431 if (IS_NOMARK_TLSGETADDR (operands[2]))
10432 rs6000_output_tlsargs (operands);
10434 else if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10435 output_asm_insn ("crxor 6,6,6", operands);
10437 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10438 output_asm_insn ("creqv 6,6,6", operands);
10440 return rs6000_indirect_call_template (operands, 1);
10442 [(set_attr "type" "jmpreg")
10443 (set (attr "length")
10445 (if_then_else (ior (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10446 (match_test "IS_V4_FP_ARGS (operands[3])"))
10449 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10450 (match_test "which_alternative != 1"))
10454 (define_insn "*call_value_nonlocal_sysv<mode>"
10455 [(set (match_operand 0 "" "")
10456 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10457 (match_operand:P 2 "unspec_tls" "")))
10458 (use (match_operand:SI 3 "immediate_operand" "n"))
10459 (clobber (reg:P LR_REGNO))]
10460 "(DEFAULT_ABI == ABI_DARWIN
10461 || (DEFAULT_ABI == ABI_V4
10462 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10464 if (IS_NOMARK_TLSGETADDR (operands[2]))
10465 rs6000_output_tlsargs (operands);
10467 else if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10468 output_asm_insn ("crxor 6,6,6", operands);
10470 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10471 output_asm_insn ("creqv 6,6,6", operands);
10473 return rs6000_call_template (operands, 1);
10475 [(set_attr "type" "branch")
10476 (set (attr "length")
10477 (if_then_else (ior (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10478 (match_test "IS_V4_FP_ARGS (operands[3])"))
10482 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10483 [(set (match_operand 0 "" "")
10484 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10485 (match_operand:P 2 "unspec_tls" "")))
10486 (use (match_operand:SI 3 "immediate_operand" "n"))
10487 (use (match_operand:SI 4 "register_operand" "r"))
10488 (clobber (reg:P LR_REGNO))]
10489 "(DEFAULT_ABI == ABI_V4
10490 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10491 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10493 if (IS_NOMARK_TLSGETADDR (operands[2]))
10494 rs6000_output_tlsargs (operands);
10496 else if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10497 output_asm_insn ("crxor 6,6,6", operands);
10499 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10500 output_asm_insn ("creqv 6,6,6", operands);
10502 return rs6000_call_template (operands, 1);
10504 [(set_attr "type" "branch")
10505 (set (attr "length")
10506 (if_then_else (ior (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10507 (match_test "IS_V4_FP_ARGS (operands[3])"))
10511 ;; Call to AIX abi function in the same module.
10513 (define_insn "*call_local_aix<mode>"
10514 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10516 (clobber (reg:P LR_REGNO))]
10517 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10519 if (rs6000_pcrel_p (cfun))
10520 return "bl %z0@notoc";
10523 [(set_attr "type" "branch")])
10525 (define_insn "*call_value_local_aix<mode>"
10526 [(set (match_operand 0 "" "")
10527 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10528 (match_operand 2)))
10529 (clobber (reg:P LR_REGNO))]
10530 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10531 && !IS_NOMARK_TLSGETADDR (operands[2])"
10533 if (rs6000_pcrel_p (cfun))
10534 return "bl %z1@notoc";
10537 [(set_attr "type" "branch")])
10539 ;; Call to AIX abi function which may be in another module.
10540 ;; Restore the TOC pointer (r2) after the call.
10542 (define_insn "*call_nonlocal_aix<mode>"
10543 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10545 (clobber (reg:P LR_REGNO))]
10546 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10548 return rs6000_call_template (operands, 0);
10550 [(set_attr "type" "branch")
10551 (set (attr "length")
10552 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10556 (define_insn "*call_value_nonlocal_aix<mode>"
10557 [(set (match_operand 0 "" "")
10558 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10559 (match_operand:P 2 "unspec_tls" "")))
10560 (clobber (reg:P LR_REGNO))]
10561 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10563 if (IS_NOMARK_TLSGETADDR (operands[2]))
10564 rs6000_output_tlsargs (operands);
10566 return rs6000_call_template (operands, 1);
10568 [(set_attr "type" "branch")
10569 (set (attr "length")
10570 (plus (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10571 (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10575 (if_then_else (match_test "rs6000_pcrel_p (cfun)")
10579 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10580 ;; Operand0 is the addresss of the function to call
10581 ;; Operand2 is the location in the function descriptor to load r2 from
10582 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10584 (define_insn "*call_indirect_aix<mode>"
10585 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10587 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10588 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10589 (clobber (reg:P LR_REGNO))]
10590 "DEFAULT_ABI == ABI_AIX"
10592 return rs6000_indirect_call_template (operands, 0);
10594 [(set_attr "type" "jmpreg")
10595 (set (attr "length")
10596 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10597 (match_test "which_alternative != 1"))
10598 (const_string "16")
10599 (const_string "12")))])
10601 (define_insn "*call_value_indirect_aix<mode>"
10602 [(set (match_operand 0 "" "")
10603 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10604 (match_operand:P 2 "unspec_tls" "")))
10605 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>,<ptrm>"))
10606 (set (reg:P TOC_REGNUM)
10607 (unspec:P [(match_operand:P 4 "const_int_operand" "n,n,n")]
10609 (clobber (reg:P LR_REGNO))]
10610 "DEFAULT_ABI == ABI_AIX"
10612 if (IS_NOMARK_TLSGETADDR (operands[2]))
10613 rs6000_output_tlsargs (operands);
10615 return rs6000_indirect_call_template (operands, 1);
10617 [(set_attr "type" "jmpreg")
10618 (set (attr "length")
10620 (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10621 (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10625 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10626 (match_test "which_alternative != 1"))
10627 (const_string "16")
10628 (const_string "12"))))])
10630 ;; Call to indirect functions with the ELFv2 ABI.
10631 ;; Operand0 is the addresss of the function to call
10632 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10634 (define_insn "*call_indirect_elfv2<mode>"
10635 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10637 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n,n")] UNSPEC_TOCSLOT))
10638 (clobber (reg:P LR_REGNO))]
10639 "DEFAULT_ABI == ABI_ELFv2"
10641 return rs6000_indirect_call_template (operands, 0);
10643 [(set_attr "type" "jmpreg")
10644 (set (attr "length")
10645 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10646 (match_test "which_alternative != 1"))
10647 (const_string "12")
10648 (const_string "8")))])
10650 (define_insn "*call_indirect_pcrel<mode>"
10651 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10653 (clobber (reg:P LR_REGNO))]
10654 "rs6000_pcrel_p (cfun)"
10656 return rs6000_indirect_call_template (operands, 0);
10658 [(set_attr "type" "jmpreg")
10659 (set (attr "length")
10660 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10661 (match_test "which_alternative != 1"))
10663 (const_string "4")))])
10665 (define_insn "*call_value_indirect_elfv2<mode>"
10666 [(set (match_operand 0 "" "")
10667 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10668 (match_operand:P 2 "unspec_tls" "")))
10669 (set (reg:P TOC_REGNUM)
10670 (unspec:P [(match_operand:P 3 "const_int_operand" "n,n,n")]
10672 (clobber (reg:P LR_REGNO))]
10673 "DEFAULT_ABI == ABI_ELFv2"
10675 if (IS_NOMARK_TLSGETADDR (operands[2]))
10676 rs6000_output_tlsargs (operands);
10678 return rs6000_indirect_call_template (operands, 1);
10680 [(set_attr "type" "jmpreg")
10681 (set (attr "length")
10683 (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10684 (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10688 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10689 (match_test "which_alternative != 1"))
10690 (const_string "12")
10691 (const_string "8"))))])
10693 (define_insn "*call_value_indirect_pcrel<mode>"
10694 [(set (match_operand 0 "" "")
10695 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10696 (match_operand:P 2 "unspec_tls" "")))
10697 (clobber (reg:P LR_REGNO))]
10698 "rs6000_pcrel_p (cfun)"
10700 if (IS_NOMARK_TLSGETADDR (operands[2]))
10701 rs6000_output_tlsargs (operands);
10703 return rs6000_indirect_call_template (operands, 1);
10705 [(set_attr "type" "jmpreg")
10706 (set (attr "length")
10708 (if_then_else (match_test "IS_NOMARK_TLSGETADDR (operands[2])")
10709 (if_then_else (match_test "TARGET_CMODEL != CMODEL_SMALL")
10713 (if_then_else (and (match_test "!rs6000_speculate_indirect_jumps")
10714 (match_test "which_alternative != 1"))
10716 (const_string "4"))))])
10718 ;; Call subroutine returning any type.
10719 (define_expand "untyped_call"
10720 [(parallel [(call (match_operand 0 "")
10722 (match_operand 1 "")
10723 (match_operand 2 "")])]
10728 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10730 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10732 rtx set = XVECEXP (operands[2], 0, i);
10733 emit_move_insn (SET_DEST (set), SET_SRC (set));
10736 /* The optimizer does not know that the call sets the function value
10737 registers we stored in the result block. We avoid problems by
10738 claiming that all hard registers are used and clobbered at this
10740 emit_insn (gen_blockage ());
10745 ;; sibling call patterns
10746 (define_expand "sibcall"
10747 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10748 (match_operand 1 ""))
10749 (use (match_operand 2 ""))
10754 if (MACHOPIC_INDIRECT)
10755 operands[0] = machopic_indirect_call_target (operands[0]);
10758 gcc_assert (MEM_P (operands[0]));
10759 gcc_assert (CONST_INT_P (operands[1]));
10761 operands[0] = XEXP (operands[0], 0);
10763 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10764 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10765 else if (DEFAULT_ABI == ABI_V4)
10766 rs6000_sibcall_sysv (NULL_RTX, operands[0], operands[1], operands[2]);
10767 else if (DEFAULT_ABI == ABI_DARWIN)
10768 rs6000_sibcall_darwin (NULL_RTX, operands[0], operands[1], operands[2]);
10770 gcc_unreachable ();
10775 (define_expand "sibcall_value"
10776 [(parallel [(set (match_operand 0 "register_operand")
10777 (call (mem:SI (match_operand 1 "address_operand"))
10778 (match_operand 2 "")))
10779 (use (match_operand 3 ""))
10784 if (MACHOPIC_INDIRECT)
10785 operands[1] = machopic_indirect_call_target (operands[1]);
10788 gcc_assert (MEM_P (operands[1]));
10789 gcc_assert (CONST_INT_P (operands[2]));
10791 operands[1] = XEXP (operands[1], 0);
10793 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10794 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10795 else if (DEFAULT_ABI == ABI_V4)
10796 rs6000_sibcall_sysv (operands[0], operands[1], operands[2], operands[3]);
10797 else if (DEFAULT_ABI == ABI_DARWIN)
10798 rs6000_sibcall_darwin (operands[0], operands[1], operands[2], operands[3]);
10800 gcc_unreachable ();
10805 (define_insn "*sibcall_local32"
10806 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10808 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10810 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10812 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10813 output_asm_insn ("crxor 6,6,6", operands);
10815 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10816 output_asm_insn ("creqv 6,6,6", operands);
10818 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10820 [(set_attr "type" "branch")
10821 (set_attr "length" "4,8")])
10823 (define_insn "*sibcall_local64"
10824 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10826 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10828 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10830 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10831 output_asm_insn ("crxor 6,6,6", operands);
10833 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10834 output_asm_insn ("creqv 6,6,6", operands);
10836 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10838 [(set_attr "type" "branch")
10839 (set_attr "length" "4,8")])
10841 (define_insn "*sibcall_value_local32"
10842 [(set (match_operand 0 "" "")
10843 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10844 (match_operand 2)))
10845 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10847 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10849 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10850 output_asm_insn ("crxor 6,6,6", operands);
10852 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10853 output_asm_insn ("creqv 6,6,6", operands);
10855 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10857 [(set_attr "type" "branch")
10858 (set_attr "length" "4,8")])
10860 (define_insn "*sibcall_value_local64"
10861 [(set (match_operand 0 "" "")
10862 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10863 (match_operand 2)))
10864 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10866 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10868 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10869 output_asm_insn ("crxor 6,6,6", operands);
10871 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10872 output_asm_insn ("creqv 6,6,6", operands);
10874 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10876 [(set_attr "type" "branch")
10877 (set_attr "length" "4,8")])
10879 (define_insn "*sibcall_indirect_nonlocal_sysv<mode>"
10880 [(call (mem:SI (match_operand:P 0 "indirect_call_operand" "c,*l,X"))
10882 (use (match_operand:SI 2 "immediate_operand" "n,n,n"))
10884 "DEFAULT_ABI == ABI_V4
10885 || DEFAULT_ABI == ABI_DARWIN"
10887 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10888 output_asm_insn ("crxor 6,6,6", operands);
10890 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10891 output_asm_insn ("creqv 6,6,6", operands);
10893 return rs6000_indirect_sibcall_template (operands, 0);
10895 [(set_attr "type" "jmpreg")
10896 (set (attr "length")
10897 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10898 (match_test "which_alternative != 1"))
10899 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10900 (const_string "12")
10901 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10902 (match_test "which_alternative != 1"))
10903 (match_test "(INTVAL (operands[2]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10904 (const_string "8")]
10905 (const_string "4")))])
10907 (define_insn "*sibcall_nonlocal_sysv<mode>"
10908 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10910 (use (match_operand 2 "immediate_operand" "O,n"))
10912 "(DEFAULT_ABI == ABI_DARWIN
10913 || DEFAULT_ABI == ABI_V4)
10914 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10916 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10917 output_asm_insn ("crxor 6,6,6", operands);
10919 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10920 output_asm_insn ("creqv 6,6,6", operands);
10922 return rs6000_sibcall_template (operands, 0);
10924 [(set_attr "type" "branch")
10925 (set_attr "length" "4,8")])
10927 (define_insn "*sibcall_value_indirect_nonlocal_sysv<mode>"
10928 [(set (match_operand 0 "" "")
10929 (call (mem:SI (match_operand:P 1 "indirect_call_operand" "c,*l,X"))
10930 (match_operand 2)))
10931 (use (match_operand:SI 3 "immediate_operand" "n,n,n"))
10933 "DEFAULT_ABI == ABI_V4
10934 || DEFAULT_ABI == ABI_DARWIN"
10936 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10937 output_asm_insn ("crxor 6,6,6", operands);
10939 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10940 output_asm_insn ("creqv 6,6,6", operands);
10942 return rs6000_indirect_sibcall_template (operands, 1);
10944 [(set_attr "type" "jmpreg")
10945 (set (attr "length")
10946 (cond [(and (and (match_test "!rs6000_speculate_indirect_jumps")
10947 (match_test "which_alternative != 1"))
10948 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10949 (const_string "12")
10950 (ior (and (match_test "!rs6000_speculate_indirect_jumps")
10951 (match_test "which_alternative != 1"))
10952 (match_test "(INTVAL (operands[3]) & (CALL_V4_SET_FP_ARGS | CALL_V4_CLEAR_FP_ARGS))"))
10953 (const_string "8")]
10954 (const_string "4")))])
10956 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10957 [(set (match_operand 0 "" "")
10958 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10959 (match_operand 2)))
10960 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10962 "(DEFAULT_ABI == ABI_DARWIN
10963 || DEFAULT_ABI == ABI_V4)
10964 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10966 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10967 output_asm_insn ("crxor 6,6,6", operands);
10969 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10970 output_asm_insn ("creqv 6,6,6", operands);
10972 return rs6000_sibcall_template (operands, 1);
10974 [(set_attr "type" "branch")
10975 (set_attr "length" "4,8")])
10977 ;; AIX ABI sibling call patterns.
10979 (define_insn "*sibcall_aix<mode>"
10980 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10983 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10985 if (which_alternative == 0)
10986 return rs6000_sibcall_template (operands, 0);
10990 [(set_attr "type" "branch")])
10992 (define_insn "*sibcall_value_aix<mode>"
10993 [(set (match_operand 0 "" "")
10994 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10995 (match_operand 2)))
10997 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10999 if (which_alternative == 0)
11000 return rs6000_sibcall_template (operands, 1);
11004 [(set_attr "type" "branch")])
11006 (define_expand "sibcall_epilogue"
11007 [(use (const_int 0))]
11010 if (!TARGET_SCHED_PROLOG)
11011 emit_insn (gen_blockage ());
11012 rs6000_emit_epilogue (EPILOGUE_TYPE_SIBCALL);
11016 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11017 ;; all of memory. This blocks insns from being moved across this point.
11019 (define_insn "blockage"
11020 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11023 [(set_attr "length" "0")])
11025 (define_expand "probe_stack_address"
11026 [(use (match_operand 0 "address_operand"))]
11029 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11030 MEM_VOLATILE_P (operands[0]) = 1;
11033 emit_insn (gen_probe_stack_di (operands[0]));
11035 emit_insn (gen_probe_stack_si (operands[0]));
11039 (define_insn "probe_stack_<mode>"
11040 [(set (match_operand:P 0 "memory_operand" "=m")
11041 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11044 operands[1] = gen_rtx_REG (Pmode, 0);
11045 return "st<wd>%U0%X0 %1,%0";
11047 [(set_attr "type" "store")
11048 (set (attr "update")
11049 (if_then_else (match_operand 0 "update_address_mem")
11050 (const_string "yes")
11051 (const_string "no")))
11052 (set (attr "indexed")
11053 (if_then_else (match_operand 0 "indexed_address_mem")
11054 (const_string "yes")
11055 (const_string "no")))])
11057 (define_insn "probe_stack_range<P:mode>"
11058 [(set (match_operand:P 0 "register_operand" "=&r")
11059 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11060 (match_operand:P 2 "register_operand" "r")
11061 (match_operand:P 3 "register_operand" "r")]
11062 UNSPECV_PROBE_STACK_RANGE))]
11064 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11065 [(set_attr "type" "three")])
11067 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11068 ;; signed & unsigned, and one type of branch.
11070 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11071 ;; insns, and branches.
11073 (define_expand "cbranch<mode>4"
11074 [(use (match_operator 0 "comparison_operator"
11075 [(match_operand:GPR 1 "gpc_reg_operand")
11076 (match_operand:GPR 2 "reg_or_short_operand")]))
11077 (use (match_operand 3))]
11080 /* Take care of the possibility that operands[2] might be negative but
11081 this might be a logical operation. That insn doesn't exist. */
11082 if (CONST_INT_P (operands[2])
11083 && INTVAL (operands[2]) < 0)
11085 operands[2] = force_reg (<MODE>mode, operands[2]);
11086 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11087 GET_MODE (operands[0]),
11088 operands[1], operands[2]);
11091 rs6000_emit_cbranch (<MODE>mode, operands);
11095 (define_expand "cbranch<mode>4"
11096 [(use (match_operator 0 "comparison_operator"
11097 [(match_operand:FP 1 "gpc_reg_operand")
11098 (match_operand:FP 2 "gpc_reg_operand")]))
11099 (use (match_operand 3))]
11102 rs6000_emit_cbranch (<MODE>mode, operands);
11106 (define_expand "cstore<mode>4_signed"
11107 [(use (match_operator 1 "signed_comparison_operator"
11108 [(match_operand:P 2 "gpc_reg_operand")
11109 (match_operand:P 3 "gpc_reg_operand")]))
11110 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11113 enum rtx_code cond_code = GET_CODE (operands[1]);
11115 rtx op0 = operands[0];
11116 rtx op1 = operands[2];
11117 rtx op2 = operands[3];
11119 if (cond_code == GE || cond_code == LT)
11121 cond_code = swap_condition (cond_code);
11122 std::swap (op1, op2);
11125 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11126 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11127 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11129 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11130 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11131 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11133 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11135 if (cond_code == LE)
11136 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11139 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11140 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11141 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11147 (define_expand "cstore<mode>4_unsigned"
11148 [(use (match_operator 1 "unsigned_comparison_operator"
11149 [(match_operand:P 2 "gpc_reg_operand")
11150 (match_operand:P 3 "reg_or_short_operand")]))
11151 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11154 enum rtx_code cond_code = GET_CODE (operands[1]);
11156 rtx op0 = operands[0];
11157 rtx op1 = operands[2];
11158 rtx op2 = operands[3];
11160 if (cond_code == GEU || cond_code == LTU)
11162 cond_code = swap_condition (cond_code);
11163 std::swap (op1, op2);
11166 if (!gpc_reg_operand (op1, <MODE>mode))
11167 op1 = force_reg (<MODE>mode, op1);
11168 if (!reg_or_short_operand (op2, <MODE>mode))
11169 op2 = force_reg (<MODE>mode, op2);
11171 rtx tmp = gen_reg_rtx (<MODE>mode);
11172 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11174 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11175 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11177 if (cond_code == LEU)
11178 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11180 emit_insn (gen_neg<mode>2 (op0, tmp2));
11185 (define_expand "cstore_si_as_di"
11186 [(use (match_operator 1 "unsigned_comparison_operator"
11187 [(match_operand:SI 2 "gpc_reg_operand")
11188 (match_operand:SI 3 "reg_or_short_operand")]))
11189 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11192 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11193 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11195 operands[2] = force_reg (SImode, operands[2]);
11196 operands[3] = force_reg (SImode, operands[3]);
11197 rtx op1 = gen_reg_rtx (DImode);
11198 rtx op2 = gen_reg_rtx (DImode);
11199 convert_move (op1, operands[2], uns_flag);
11200 convert_move (op2, operands[3], uns_flag);
11202 if (cond_code == GT || cond_code == LE)
11204 cond_code = swap_condition (cond_code);
11205 std::swap (op1, op2);
11208 rtx tmp = gen_reg_rtx (DImode);
11209 rtx tmp2 = gen_reg_rtx (DImode);
11210 emit_insn (gen_subdi3 (tmp, op1, op2));
11211 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11217 gcc_unreachable ();
11222 tmp3 = gen_reg_rtx (DImode);
11223 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11227 convert_move (operands[0], tmp3, 1);
11232 (define_expand "cstore<mode>4_signed_imm"
11233 [(use (match_operator 1 "signed_comparison_operator"
11234 [(match_operand:GPR 2 "gpc_reg_operand")
11235 (match_operand:GPR 3 "immediate_operand")]))
11236 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11239 bool invert = false;
11241 enum rtx_code cond_code = GET_CODE (operands[1]);
11243 rtx op0 = operands[0];
11244 rtx op1 = operands[2];
11245 HOST_WIDE_INT val = INTVAL (operands[3]);
11247 if (cond_code == GE || cond_code == GT)
11249 cond_code = reverse_condition (cond_code);
11253 if (cond_code == LE)
11256 rtx tmp = gen_reg_rtx (<MODE>mode);
11257 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11258 rtx x = gen_reg_rtx (<MODE>mode);
11260 emit_insn (gen_and<mode>3 (x, op1, tmp));
11262 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11266 rtx tmp = gen_reg_rtx (<MODE>mode);
11267 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11271 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11272 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11277 (define_expand "cstore<mode>4_unsigned_imm"
11278 [(use (match_operator 1 "unsigned_comparison_operator"
11279 [(match_operand:GPR 2 "gpc_reg_operand")
11280 (match_operand:GPR 3 "immediate_operand")]))
11281 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11284 bool invert = false;
11286 enum rtx_code cond_code = GET_CODE (operands[1]);
11288 rtx op0 = operands[0];
11289 rtx op1 = operands[2];
11290 HOST_WIDE_INT val = INTVAL (operands[3]);
11292 if (cond_code == GEU || cond_code == GTU)
11294 cond_code = reverse_condition (cond_code);
11298 if (cond_code == LEU)
11301 rtx tmp = gen_reg_rtx (<MODE>mode);
11302 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11303 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11304 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11305 rtx x = gen_reg_rtx (<MODE>mode);
11307 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11309 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11313 rtx tmp = gen_reg_rtx (<MODE>mode);
11314 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11318 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11319 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11324 (define_expand "cstore<mode>4"
11325 [(use (match_operator 1 "comparison_operator"
11326 [(match_operand:GPR 2 "gpc_reg_operand")
11327 (match_operand:GPR 3 "reg_or_short_operand")]))
11328 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11331 /* Expanding EQ and NE directly to some machine instructions does not help
11332 but does hurt combine. So don't. */
11333 if (GET_CODE (operands[1]) == EQ)
11334 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11335 else if (<MODE>mode == Pmode
11336 && GET_CODE (operands[1]) == NE)
11337 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11338 else if (GET_CODE (operands[1]) == NE)
11340 rtx tmp = gen_reg_rtx (<MODE>mode);
11341 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11342 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11345 /* If ISEL is fast, expand to it. */
11346 else if (TARGET_ISEL)
11347 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11349 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11350 etc. combinations magically work out just right. */
11351 else if (<MODE>mode == Pmode
11352 && unsigned_comparison_operator (operands[1], VOIDmode))
11353 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11354 operands[2], operands[3]));
11356 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11357 else if (<MODE>mode == SImode && Pmode == DImode)
11358 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11359 operands[2], operands[3]));
11361 /* For signed comparisons against a constant, we can do some simple
11363 else if (signed_comparison_operator (operands[1], VOIDmode)
11364 && CONST_INT_P (operands[3]))
11365 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11366 operands[2], operands[3]));
11368 /* And similarly for unsigned comparisons. */
11369 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11370 && CONST_INT_P (operands[3]))
11371 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11372 operands[2], operands[3]));
11374 /* We also do not want to use mfcr for signed comparisons. */
11375 else if (<MODE>mode == Pmode
11376 && signed_comparison_operator (operands[1], VOIDmode))
11377 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11378 operands[2], operands[3]));
11380 /* Everything else, use the mfcr brute force. */
11382 rs6000_emit_sCOND (<MODE>mode, operands);
11387 (define_expand "cstore<mode>4"
11388 [(use (match_operator 1 "comparison_operator"
11389 [(match_operand:FP 2 "gpc_reg_operand")
11390 (match_operand:FP 3 "gpc_reg_operand")]))
11391 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11394 rs6000_emit_sCOND (<MODE>mode, operands);
11399 (define_expand "stack_protect_set"
11400 [(match_operand 0 "memory_operand")
11401 (match_operand 1 "memory_operand")]
11404 if (rs6000_stack_protector_guard == SSP_TLS)
11406 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11407 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11408 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11409 operands[1] = gen_rtx_MEM (Pmode, addr);
11413 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11415 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11420 (define_insn "stack_protect_setsi"
11421 [(set (match_operand:SI 0 "memory_operand" "=m")
11422 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11423 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11425 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11426 [(set_attr "type" "three")
11427 (set_attr "length" "12")])
11429 (define_insn "stack_protect_setdi"
11430 [(set (match_operand:DI 0 "memory_operand" "=Y")
11431 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11432 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11434 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11435 [(set_attr "type" "three")
11436 (set_attr "length" "12")])
11438 (define_expand "stack_protect_test"
11439 [(match_operand 0 "memory_operand")
11440 (match_operand 1 "memory_operand")
11441 (match_operand 2 "")]
11444 rtx guard = operands[1];
11446 if (rs6000_stack_protector_guard == SSP_TLS)
11448 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11449 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11450 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11451 guard = gen_rtx_MEM (Pmode, addr);
11454 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11455 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11456 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11457 emit_jump_insn (jump);
11462 (define_insn "stack_protect_testsi"
11463 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11464 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11465 (match_operand:SI 2 "memory_operand" "m,m")]
11467 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11468 (clobber (match_scratch:SI 3 "=&r,&r"))]
11471 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11472 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11473 [(set_attr "length" "16,20")])
11475 (define_insn "stack_protect_testdi"
11476 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11477 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11478 (match_operand:DI 2 "memory_operand" "Y,Y")]
11480 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11481 (clobber (match_scratch:DI 3 "=&r,&r"))]
11484 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11485 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11486 [(set_attr "length" "16,20")])
11489 ;; Here are the actual compare insns.
11490 (define_insn "*cmp<mode>_signed"
11491 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11492 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11493 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11495 "cmp<wd>%I2 %0,%1,%2"
11496 [(set_attr "type" "cmp")])
11498 (define_insn "*cmp<mode>_unsigned"
11499 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11500 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11501 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11503 "cmpl<wd>%I2 %0,%1,%2"
11504 [(set_attr "type" "cmp")])
11506 ;; If we are comparing a register for equality with a large constant,
11507 ;; we can do this with an XOR followed by a compare. But this is profitable
11508 ;; only if the large constant is only used for the comparison (and in this
11509 ;; case we already have a register to reuse as scratch).
11511 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11512 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11515 [(set (match_operand:SI 0 "register_operand")
11516 (match_operand:SI 1 "logical_const_operand"))
11517 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11519 (match_operand:SI 2 "logical_const_operand")]))
11520 (set (match_operand:CC 4 "cc_reg_operand")
11521 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11524 (if_then_else (match_operator 6 "equality_operator"
11525 [(match_dup 4) (const_int 0)])
11526 (match_operand 7 "")
11527 (match_operand 8 "")))]
11528 "peep2_reg_dead_p (3, operands[0])
11529 && peep2_reg_dead_p (4, operands[4])
11530 && REGNO (operands[0]) != REGNO (operands[5])"
11531 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11532 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11533 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11536 /* Get the constant we are comparing against, and see what it looks like
11537 when sign-extended from 16 to 32 bits. Then see what constant we could
11538 XOR with SEXTC to get the sign-extended value. */
11539 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11541 operands[1], operands[2]);
11542 HOST_WIDE_INT c = INTVAL (cnst);
11543 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11544 HOST_WIDE_INT xorv = c ^ sextc;
11546 operands[9] = GEN_INT (xorv);
11547 operands[10] = GEN_INT (sextc);
11550 ;; Only need to compare second words if first words equal
11551 (define_insn "*cmp<mode>_internal1"
11552 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11553 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11554 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11555 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11556 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11557 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11558 [(set_attr "type" "fpcompare")
11559 (set_attr "length" "12")])
11561 (define_insn_and_split "*cmp<mode>_internal2"
11562 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11563 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11564 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11565 (clobber (match_scratch:DF 3 "=d"))
11566 (clobber (match_scratch:DF 4 "=d"))
11567 (clobber (match_scratch:DF 5 "=d"))
11568 (clobber (match_scratch:DF 6 "=d"))
11569 (clobber (match_scratch:DF 7 "=d"))
11570 (clobber (match_scratch:DF 8 "=d"))
11571 (clobber (match_scratch:DF 9 "=d"))
11572 (clobber (match_scratch:DF 10 "=d"))
11573 (clobber (match_scratch:GPR 11 "=b"))]
11574 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11575 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
11577 "&& reload_completed"
11578 [(set (match_dup 3) (match_dup 14))
11579 (set (match_dup 4) (match_dup 15))
11580 (set (match_dup 9) (abs:DF (match_dup 5)))
11581 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11582 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11583 (label_ref (match_dup 12))
11585 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11586 (set (pc) (label_ref (match_dup 13)))
11588 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11589 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11590 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11591 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11594 REAL_VALUE_TYPE rv;
11595 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11596 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11598 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11599 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11600 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11601 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11602 operands[12] = gen_label_rtx ();
11603 operands[13] = gen_label_rtx ();
11605 operands[14] = force_const_mem (DFmode,
11606 const_double_from_real_value (rv, DFmode));
11607 operands[15] = force_const_mem (DFmode,
11608 const_double_from_real_value (dconst0,
11613 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11614 operands[14] = gen_const_mem (DFmode, tocref);
11615 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11616 operands[15] = gen_const_mem (DFmode, tocref);
11617 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11618 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11622 ;; Now we have the scc insns. We can do some combinations because of the
11623 ;; way the machine works.
11625 ;; Note that this is probably faster if we can put an insn between the
11626 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11627 ;; cases the insns below which don't use an intermediate CR field will
11628 ;; be used instead.
11630 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11631 (match_operator:GPR 1 "scc_comparison_operator"
11632 [(match_operand 2 "cc_reg_operand" "y")
11635 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11636 [(set (attr "type")
11637 (cond [(match_test "TARGET_MFCRF")
11638 (const_string "mfcrf")
11640 (const_string "mfcr")))
11641 (set_attr "length" "8")])
11643 (define_insn_and_split ""
11644 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11645 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11646 [(match_operand 2 "cc_reg_operand" "y,y")
11649 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11650 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11653 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11655 "&& reload_completed"
11656 [(set (match_dup 3)
11657 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11659 (compare:CC (match_dup 3)
11662 [(set_attr "type" "shift")
11663 (set_attr "dot" "yes")
11664 (set_attr "length" "8,16")])
11667 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11668 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11669 [(match_operand 2 "cc_reg_operand" "y")
11671 (match_operand:SI 3 "const_int_operand" "n")))]
11674 int is_bit = ccr_bit (operands[1], 1);
11675 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11678 gcc_assert (is_bit != -1);
11679 if (is_bit >= put_bit)
11680 count = is_bit - put_bit;
11682 count = 32 - (put_bit - is_bit);
11684 operands[4] = GEN_INT (count);
11685 operands[5] = GEN_INT (put_bit);
11687 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11689 [(set (attr "type")
11690 (cond [(match_test "TARGET_MFCRF")
11691 (const_string "mfcrf")
11693 (const_string "mfcr")))
11694 (set_attr "length" "8")])
11697 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11699 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11700 [(match_operand 2 "cc_reg_operand" "y,y")
11702 (match_operand:SI 3 "const_int_operand" "n,n"))
11704 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11705 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11709 int is_bit = ccr_bit (operands[1], 1);
11710 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11713 gcc_assert (is_bit != -1);
11714 /* Force split for non-cc0 compare. */
11715 if (which_alternative == 1)
11718 if (is_bit >= put_bit)
11719 count = is_bit - put_bit;
11721 count = 32 - (put_bit - is_bit);
11723 operands[5] = GEN_INT (count);
11724 operands[6] = GEN_INT (put_bit);
11726 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11728 [(set_attr "type" "shift")
11729 (set_attr "dot" "yes")
11730 (set_attr "length" "8,16")])
11733 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11735 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11736 [(match_operand 2 "cc_reg_operand")
11738 (match_operand:SI 3 "const_int_operand"))
11740 (set (match_operand:SI 4 "gpc_reg_operand")
11741 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11744 [(set (match_dup 4)
11745 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11748 (compare:CC (match_dup 4)
11753 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11754 (define_code_attr UNS [(eq "CC")
11756 (lt "CC") (ltu "CCUNS")
11757 (gt "CC") (gtu "CCUNS")
11758 (le "CC") (leu "CCUNS")
11759 (ge "CC") (geu "CCUNS")])
11760 (define_code_attr UNSu_ [(eq "")
11765 (ge "") (geu "u_")])
11766 (define_code_attr UNSIK [(eq "I")
11771 (ge "I") (geu "K")])
11773 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11774 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11775 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11776 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11777 (clobber (match_scratch:GPR 3 "=r"))
11778 (clobber (match_scratch:GPR 4 "=r"))
11779 (clobber (match_scratch:<UNS> 5 "=y"))]
11781 && !(<CODE> == EQ && operands[2] == const0_rtx)
11782 && !(<CODE> == NE && operands[2] == const0_rtx
11783 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11788 rtx_code code = <CODE>;
11789 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11791 HOST_WIDE_INT val = INTVAL (operands[2]);
11792 if (code == LT && val != -0x8000)
11797 if (code == GT && val != 0x7fff)
11802 if (code == LTU && val != 0)
11807 if (code == GTU && val != 0xffff)
11812 operands[2] = GEN_INT (val);
11815 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11816 operands[3] = const0_rtx;
11819 if (GET_CODE (operands[3]) == SCRATCH)
11820 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11821 emit_move_insn (operands[3], const0_rtx);
11824 if (GET_CODE (operands[4]) == SCRATCH)
11825 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11826 emit_move_insn (operands[4], const1_rtx);
11828 if (GET_CODE (operands[5]) == SCRATCH)
11829 operands[5] = gen_reg_rtx (<UNS>mode);
11831 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11832 emit_insn (gen_rtx_SET (operands[5], c1));
11834 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11835 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11836 emit_move_insn (operands[0], x);
11840 [(set (attr "cost")
11841 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11843 || <CODE> == LE || <CODE> == GE
11844 || <CODE> == LEU || <CODE> == GEU")
11846 (const_string "10")))])
11848 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11851 (define_expand "eq<mode>3"
11853 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11854 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11855 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11856 (clobber (match_scratch:GPR 3 "=r"))
11857 (clobber (match_scratch:GPR 4 "=r"))])]
11860 if (TARGET_ISEL && operands[2] != const0_rtx)
11862 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11868 (define_insn_and_split "*eq<mode>3"
11869 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11870 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11871 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11872 (clobber (match_scratch:GPR 3 "=r"))
11873 (clobber (match_scratch:GPR 4 "=r"))]
11874 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11877 [(set (match_dup 4)
11878 (clz:GPR (match_dup 3)))
11880 (lshiftrt:GPR (match_dup 4)
11883 operands[3] = rs6000_emit_eqne (<MODE>mode,
11884 operands[1], operands[2], operands[3]);
11886 if (GET_CODE (operands[4]) == SCRATCH)
11887 operands[4] = gen_reg_rtx (<MODE>mode);
11889 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11891 [(set (attr "length")
11892 (if_then_else (match_test "operands[2] == const0_rtx")
11894 (const_string "12")))])
11896 (define_expand "ne<mode>3"
11898 (set (match_operand:P 0 "gpc_reg_operand" "=r")
11899 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11900 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11901 (clobber (match_scratch:P 3 "=r"))
11902 (clobber (match_scratch:P 4 "=r"))
11903 (clobber (reg:P CA_REGNO))])]
11906 if (TARGET_ISEL && operands[2] != const0_rtx)
11908 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11914 (define_insn_and_split "*ne<mode>3"
11915 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11916 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11917 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11918 (clobber (match_scratch:P 3 "=r"))
11919 (clobber (match_scratch:P 4 "=r"))
11920 (clobber (reg:P CA_REGNO))]
11921 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11924 [(parallel [(set (match_dup 4)
11925 (plus:P (match_dup 3)
11927 (set (reg:P CA_REGNO)
11928 (ne:P (match_dup 3)
11930 (parallel [(set (match_dup 0)
11931 (plus:P (plus:P (not:P (match_dup 4))
11934 (clobber (reg:P CA_REGNO))])]
11936 operands[3] = rs6000_emit_eqne (<MODE>mode,
11937 operands[1], operands[2], operands[3]);
11939 if (GET_CODE (operands[4]) == SCRATCH)
11940 operands[4] = gen_reg_rtx (<MODE>mode);
11942 [(set (attr "length")
11943 (if_then_else (match_test "operands[2] == const0_rtx")
11945 (const_string "12")))])
11947 (define_insn_and_split "*neg_eq_<mode>"
11948 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11949 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
11950 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11951 (clobber (match_scratch:P 3 "=r"))
11952 (clobber (match_scratch:P 4 "=r"))
11953 (clobber (reg:P CA_REGNO))]
11957 [(parallel [(set (match_dup 4)
11958 (plus:P (match_dup 3)
11960 (set (reg:P CA_REGNO)
11961 (ne:P (match_dup 3)
11963 (parallel [(set (match_dup 0)
11964 (plus:P (reg:P CA_REGNO)
11966 (clobber (reg:P CA_REGNO))])]
11968 operands[3] = rs6000_emit_eqne (<MODE>mode,
11969 operands[1], operands[2], operands[3]);
11971 if (GET_CODE (operands[4]) == SCRATCH)
11972 operands[4] = gen_reg_rtx (<MODE>mode);
11974 [(set (attr "length")
11975 (if_then_else (match_test "operands[2] == const0_rtx")
11977 (const_string "12")))])
11979 (define_insn_and_split "*neg_ne_<mode>"
11980 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11981 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11982 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
11983 (clobber (match_scratch:P 3 "=r"))
11984 (clobber (match_scratch:P 4 "=r"))
11985 (clobber (reg:P CA_REGNO))]
11989 [(parallel [(set (match_dup 4)
11990 (neg:P (match_dup 3)))
11991 (set (reg:P CA_REGNO)
11992 (eq:P (match_dup 3)
11994 (parallel [(set (match_dup 0)
11995 (plus:P (reg:P CA_REGNO)
11997 (clobber (reg:P CA_REGNO))])]
11999 operands[3] = rs6000_emit_eqne (<MODE>mode,
12000 operands[1], operands[2], operands[3]);
12002 if (GET_CODE (operands[4]) == SCRATCH)
12003 operands[4] = gen_reg_rtx (<MODE>mode);
12005 [(set (attr "length")
12006 (if_then_else (match_test "operands[2] == const0_rtx")
12008 (const_string "12")))])
12010 (define_insn_and_split "*plus_eq_<mode>"
12011 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12012 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12013 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12014 (match_operand:P 3 "gpc_reg_operand" "r")))
12015 (clobber (match_scratch:P 4 "=r"))
12016 (clobber (match_scratch:P 5 "=r"))
12017 (clobber (reg:P CA_REGNO))]
12021 [(parallel [(set (match_dup 5)
12022 (neg:P (match_dup 4)))
12023 (set (reg:P CA_REGNO)
12024 (eq:P (match_dup 4)
12026 (parallel [(set (match_dup 0)
12027 (plus:P (match_dup 3)
12029 (clobber (reg:P CA_REGNO))])]
12031 operands[4] = rs6000_emit_eqne (<MODE>mode,
12032 operands[1], operands[2], operands[4]);
12034 if (GET_CODE (operands[5]) == SCRATCH)
12035 operands[5] = gen_reg_rtx (<MODE>mode);
12037 [(set (attr "length")
12038 (if_then_else (match_test "operands[2] == const0_rtx")
12040 (const_string "12")))])
12042 (define_insn_and_split "*plus_ne_<mode>"
12043 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12044 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12045 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12046 (match_operand:P 3 "gpc_reg_operand" "r")))
12047 (clobber (match_scratch:P 4 "=r"))
12048 (clobber (match_scratch:P 5 "=r"))
12049 (clobber (reg:P CA_REGNO))]
12053 [(parallel [(set (match_dup 5)
12054 (plus:P (match_dup 4)
12056 (set (reg:P CA_REGNO)
12057 (ne:P (match_dup 4)
12059 (parallel [(set (match_dup 0)
12060 (plus:P (match_dup 3)
12062 (clobber (reg:P CA_REGNO))])]
12064 operands[4] = rs6000_emit_eqne (<MODE>mode,
12065 operands[1], operands[2], operands[4]);
12067 if (GET_CODE (operands[5]) == SCRATCH)
12068 operands[5] = gen_reg_rtx (<MODE>mode);
12070 [(set (attr "length")
12071 (if_then_else (match_test "operands[2] == const0_rtx")
12073 (const_string "12")))])
12075 (define_insn_and_split "*minus_eq_<mode>"
12076 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12077 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12078 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12079 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12080 (clobber (match_scratch:P 4 "=r"))
12081 (clobber (match_scratch:P 5 "=r"))
12082 (clobber (reg:P CA_REGNO))]
12086 [(parallel [(set (match_dup 5)
12087 (plus:P (match_dup 4)
12089 (set (reg:P CA_REGNO)
12090 (ne:P (match_dup 4)
12092 (parallel [(set (match_dup 0)
12093 (plus:P (plus:P (match_dup 3)
12096 (clobber (reg:P CA_REGNO))])]
12098 operands[4] = rs6000_emit_eqne (<MODE>mode,
12099 operands[1], operands[2], operands[4]);
12101 if (GET_CODE (operands[5]) == SCRATCH)
12102 operands[5] = gen_reg_rtx (<MODE>mode);
12104 [(set (attr "length")
12105 (if_then_else (match_test "operands[2] == const0_rtx")
12107 (const_string "12")))])
12109 (define_insn_and_split "*minus_ne_<mode>"
12110 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12111 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12112 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12113 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12114 (clobber (match_scratch:P 4 "=r"))
12115 (clobber (match_scratch:P 5 "=r"))
12116 (clobber (reg:P CA_REGNO))]
12120 [(parallel [(set (match_dup 5)
12121 (neg:P (match_dup 4)))
12122 (set (reg:P CA_REGNO)
12123 (eq:P (match_dup 4)
12125 (parallel [(set (match_dup 0)
12126 (plus:P (plus:P (match_dup 3)
12129 (clobber (reg:P CA_REGNO))])]
12131 operands[4] = rs6000_emit_eqne (<MODE>mode,
12132 operands[1], operands[2], operands[4]);
12134 if (GET_CODE (operands[5]) == SCRATCH)
12135 operands[5] = gen_reg_rtx (<MODE>mode);
12137 [(set (attr "length")
12138 (if_then_else (match_test "operands[2] == const0_rtx")
12140 (const_string "12")))])
12142 (define_insn_and_split "*eqsi3_ext<mode>"
12143 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12144 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12145 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12146 (clobber (match_scratch:SI 3 "=r"))
12147 (clobber (match_scratch:SI 4 "=r"))]
12151 [(set (match_dup 4)
12152 (clz:SI (match_dup 3)))
12155 (lshiftrt:SI (match_dup 4)
12158 operands[3] = rs6000_emit_eqne (SImode,
12159 operands[1], operands[2], operands[3]);
12161 if (GET_CODE (operands[4]) == SCRATCH)
12162 operands[4] = gen_reg_rtx (SImode);
12164 [(set (attr "length")
12165 (if_then_else (match_test "operands[2] == const0_rtx")
12167 (const_string "12")))])
12169 (define_insn_and_split "*nesi3_ext<mode>"
12170 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12171 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12172 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12173 (clobber (match_scratch:SI 3 "=r"))
12174 (clobber (match_scratch:SI 4 "=r"))
12175 (clobber (match_scratch:EXTSI 5 "=r"))]
12179 [(set (match_dup 4)
12180 (clz:SI (match_dup 3)))
12183 (lshiftrt:SI (match_dup 4)
12186 (xor:EXTSI (match_dup 5)
12189 operands[3] = rs6000_emit_eqne (SImode,
12190 operands[1], operands[2], operands[3]);
12192 if (GET_CODE (operands[4]) == SCRATCH)
12193 operands[4] = gen_reg_rtx (SImode);
12194 if (GET_CODE (operands[5]) == SCRATCH)
12195 operands[5] = gen_reg_rtx (<MODE>mode);
12197 [(set (attr "length")
12198 (if_then_else (match_test "operands[2] == const0_rtx")
12199 (const_string "12")
12200 (const_string "16")))])
12202 ;; Conditional branches.
12203 ;; These either are a single bc insn, or a bc around a b.
12205 (define_insn "*cbranch"
12207 (if_then_else (match_operator 1 "branch_comparison_operator"
12208 [(match_operand 2 "cc_reg_operand" "y")
12210 (label_ref (match_operand 0))
12214 return output_cbranch (operands[1], "%l0", 0, insn);
12216 [(set_attr "type" "branch")
12217 (set (attr "length")
12218 (if_then_else (and (ge (minus (match_dup 0) (pc))
12219 (const_int -32768))
12220 (lt (minus (match_dup 0) (pc))
12221 (const_int 32764)))
12225 ;; Conditional return.
12226 (define_insn "*creturn"
12228 (if_then_else (match_operator 0 "branch_comparison_operator"
12229 [(match_operand 1 "cc_reg_operand" "y")
12235 return output_cbranch (operands[0], NULL, 0, insn);
12237 [(set_attr "type" "jmpreg")])
12239 ;; Logic on condition register values.
12241 ; This pattern matches things like
12242 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12243 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12245 ; which are generated by the branch logic.
12246 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12248 (define_insn "cceq_ior_compare"
12249 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12250 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12251 [(match_operator:SI 2
12252 "branch_positive_comparison_operator"
12254 "cc_reg_operand" "y,y")
12256 (match_operator:SI 4
12257 "branch_positive_comparison_operator"
12259 "cc_reg_operand" "0,y")
12263 "cr%q1 %E0,%j2,%j4"
12264 [(set_attr "type" "cr_logical")
12265 (set_attr "cr_logical_3op" "no,yes")])
12267 ; Why is the constant -1 here, but 1 in the previous pattern?
12268 ; Because ~1 has all but the low bit set.
12269 (define_insn "cceq_ior_compare_complement"
12270 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12271 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12272 [(not:SI (match_operator:SI 2
12273 "branch_positive_comparison_operator"
12275 "cc_reg_operand" "y,y")
12277 (match_operator:SI 4
12278 "branch_positive_comparison_operator"
12280 "cc_reg_operand" "0,y")
12284 "cr%q1 %E0,%j2,%j4"
12285 [(set_attr "type" "cr_logical")
12286 (set_attr "cr_logical_3op" "no,yes")])
12288 (define_insn "*cceq_rev_compare"
12289 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12290 (compare:CCEQ (match_operator:SI 1
12291 "branch_positive_comparison_operator"
12293 "cc_reg_operand" "0,y")
12298 [(set_attr "type" "cr_logical")
12299 (set_attr "cr_logical_3op" "no,yes")])
12301 ;; If we are comparing the result of two comparisons, this can be done
12302 ;; using creqv or crxor.
12304 (define_insn_and_split ""
12305 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12306 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12307 [(match_operand 2 "cc_reg_operand" "y")
12309 (match_operator 3 "branch_comparison_operator"
12310 [(match_operand 4 "cc_reg_operand" "y")
12315 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12318 int positive_1, positive_2;
12320 positive_1 = branch_positive_comparison_operator (operands[1],
12321 GET_MODE (operands[1]));
12322 positive_2 = branch_positive_comparison_operator (operands[3],
12323 GET_MODE (operands[3]));
12326 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12327 GET_CODE (operands[1])),
12329 operands[2], const0_rtx);
12330 else if (GET_MODE (operands[1]) != SImode)
12331 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12332 operands[2], const0_rtx);
12335 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12336 GET_CODE (operands[3])),
12338 operands[4], const0_rtx);
12339 else if (GET_MODE (operands[3]) != SImode)
12340 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12341 operands[4], const0_rtx);
12343 if (positive_1 == positive_2)
12345 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12346 operands[5] = constm1_rtx;
12350 operands[5] = const1_rtx;
12354 ;; Unconditional branch and return.
12356 (define_insn "jump"
12358 (label_ref (match_operand 0)))]
12361 [(set_attr "type" "branch")])
12363 (define_insn "<return_str>return"
12367 [(set_attr "type" "jmpreg")])
12369 (define_expand "indirect_jump"
12370 [(set (pc) (match_operand 0 "register_operand"))]
12373 if (!rs6000_speculate_indirect_jumps) {
12374 rtx ccreg = gen_reg_rtx (CCmode);
12375 emit_jump_insn (gen_indirect_jump_nospec (Pmode, operands[0], ccreg));
12380 (define_insn "*indirect_jump<mode>"
12382 (match_operand:P 0 "register_operand" "c,*l"))]
12383 "rs6000_speculate_indirect_jumps"
12385 [(set_attr "type" "jmpreg")])
12387 (define_insn "@indirect_jump<mode>_nospec"
12388 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12389 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12390 "!rs6000_speculate_indirect_jumps"
12391 "crset %E1\;beq%T0- %1\;b $"
12392 [(set_attr "type" "jmpreg")
12393 (set_attr "length" "12")])
12395 ;; Table jump for switch statements:
12396 (define_expand "tablejump"
12397 [(use (match_operand 0))
12398 (use (label_ref (match_operand 1)))]
12401 if (rs6000_speculate_indirect_jumps)
12404 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12406 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12410 rtx ccreg = gen_reg_rtx (CCmode);
12413 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12415 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12416 emit_jump_insn (jump);
12421 (define_expand "tablejumpsi"
12422 [(set (match_dup 3)
12423 (plus:SI (match_operand:SI 0)
12425 (parallel [(set (pc)
12427 (use (label_ref (match_operand 1)))])]
12428 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12430 operands[0] = force_reg (SImode, operands[0]);
12431 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12432 operands[3] = gen_reg_rtx (SImode);
12435 (define_expand "tablejumpsi_nospec"
12436 [(set (match_dup 4)
12437 (plus:SI (match_operand:SI 0)
12439 (parallel [(set (pc)
12441 (use (label_ref (match_operand 1)))
12442 (clobber (match_operand 2))])]
12443 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12445 operands[0] = force_reg (SImode, operands[0]);
12446 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12447 operands[4] = gen_reg_rtx (SImode);
12450 (define_expand "tablejumpdi"
12451 [(set (match_dup 4)
12452 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12454 (plus:DI (match_dup 4)
12456 (parallel [(set (pc)
12458 (use (label_ref (match_operand 1)))])]
12459 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12461 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12462 operands[3] = gen_reg_rtx (DImode);
12463 operands[4] = gen_reg_rtx (DImode);
12466 (define_expand "tablejumpdi_nospec"
12467 [(set (match_dup 5)
12468 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12470 (plus:DI (match_dup 5)
12472 (parallel [(set (pc)
12474 (use (label_ref (match_operand 1)))
12475 (clobber (match_operand 2))])]
12476 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12478 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12479 operands[4] = gen_reg_rtx (DImode);
12480 operands[5] = gen_reg_rtx (DImode);
12483 (define_insn "*tablejump<mode>_internal1"
12485 (match_operand:P 0 "register_operand" "c,*l"))
12486 (use (label_ref (match_operand 1)))]
12487 "rs6000_speculate_indirect_jumps"
12489 [(set_attr "type" "jmpreg")])
12491 (define_insn "*tablejump<mode>_internal1_nospec"
12493 (match_operand:P 0 "register_operand" "c,*l"))
12494 (use (label_ref (match_operand 1)))
12495 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12496 "!rs6000_speculate_indirect_jumps"
12497 "crset %E2\;beq%T0- %2\;b $"
12498 [(set_attr "type" "jmpreg")
12499 (set_attr "length" "12")])
12502 [(unspec [(const_int 0)] UNSPEC_NOP)]
12506 (define_insn "group_ending_nop"
12507 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12510 operands[0] = gen_rtx_REG (Pmode,
12511 rs6000_tune == PROCESSOR_POWER6 ? 1 : 2);
12512 return "ori %0,%0,0";
12515 (define_insn "speculation_barrier"
12516 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12519 operands[0] = gen_rtx_REG (Pmode, 31);
12520 return "ori %0,%0,0";
12523 ;; Define the subtract-one-and-jump insns, starting with the template
12524 ;; so loop.c knows what to generate.
12526 (define_expand "doloop_end"
12527 [(use (match_operand 0)) ; loop pseudo
12528 (use (match_operand 1))] ; label
12531 if (GET_MODE (operands[0]) != Pmode)
12534 emit_jump_insn (gen_ctr (Pmode, operands[0], operands[1]));
12538 (define_expand "@ctr<mode>"
12539 [(parallel [(set (pc)
12540 (if_then_else (ne (match_operand:P 0 "register_operand")
12542 (label_ref (match_operand 1))
12545 (plus:P (match_dup 0)
12547 (clobber (match_scratch:CC 2))
12548 (clobber (match_scratch:P 3))])]
12552 ;; We need to be able to do this for any operand, including MEM, or we
12553 ;; will cause reload to blow up since we don't allow output reloads on
12555 ;; For the length attribute to be calculated correctly, the
12556 ;; label MUST be operand 0.
12557 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12558 ;; the ctr<mode> insns.
12560 (define_code_iterator eqne [eq ne])
12561 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12562 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12564 (define_insn "<bd>_<mode>"
12566 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12568 (label_ref (match_operand 0))
12570 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12571 (plus:P (match_dup 1)
12573 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12574 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12577 if (which_alternative != 0)
12579 else if (get_attr_length (insn) == 4)
12582 return "<bd_neg> $+8\;b %l0";
12584 [(set_attr "type" "branch")
12585 (set_attr_alternative "length"
12586 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12587 (const_int -32768))
12588 (lt (minus (match_dup 0) (pc))
12589 (const_int 32764)))
12592 (const_string "16")
12593 (const_string "20")
12594 (const_string "20")])])
12596 ;; Now the splitter if we could not allocate the CTR register
12599 (if_then_else (match_operator 2 "comparison_operator"
12600 [(match_operand:P 1 "gpc_reg_operand")
12603 (match_operand 6)))
12604 (set (match_operand:P 0 "nonimmediate_operand")
12605 (plus:P (match_dup 1)
12607 (clobber (match_scratch:CC 3))
12608 (clobber (match_scratch:P 4))]
12611 (if_then_else (match_dup 7)
12615 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12617 emit_insn (gen_rtx_SET (operands[3],
12618 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12619 if (int_reg_operand (operands[0], <MODE>mode))
12620 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12623 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12624 emit_move_insn (operands[0], operands[4]);
12626 /* No DONE so branch comes from the pattern. */
12629 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12630 ;; Note that in the case of long branches we have to decompose this into
12631 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12632 ;; and the CR bit, which means there is no way to conveniently invert the
12633 ;; comparison as is done with plain bdnz/bdz.
12635 (define_insn "<bd>tf_<mode>"
12639 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12641 (match_operator 3 "branch_comparison_operator"
12642 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12644 (label_ref (match_operand 0))
12646 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wa*c*l")
12647 (plus:P (match_dup 1)
12649 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12650 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12651 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12654 if (which_alternative != 0)
12656 else if (get_attr_length (insn) == 4)
12658 if (branch_positive_comparison_operator (operands[3],
12659 GET_MODE (operands[3])))
12660 return "<bd>t %j3,%l0";
12662 return "<bd>f %j3,%l0";
12666 static char seq[96];
12667 char *bcs = output_cbranch (operands[3], ".Lshort%=", 1, insn);
12668 sprintf(seq, "<bd_neg> .Lshort%%=\;%s\;b %%l0\;.Lshort%%=:", bcs);
12672 [(set_attr "type" "branch")
12673 (set_attr_alternative "length"
12674 [(if_then_else (and (ge (minus (match_dup 0) (pc))
12675 (const_int -32768))
12676 (lt (minus (match_dup 0) (pc))
12677 (const_int 32764)))
12680 (const_string "16")
12681 (const_string "20")
12682 (const_string "20")])])
12684 ;; Now the splitter if we could not allocate the CTR register
12689 (match_operator 1 "comparison_operator"
12690 [(match_operand:P 0 "gpc_reg_operand")
12692 (match_operator 3 "branch_comparison_operator"
12693 [(match_operand 2 "cc_reg_operand")
12696 (match_operand 5)))
12697 (set (match_operand:P 6 "nonimmediate_operand")
12698 (plus:P (match_dup 0)
12700 (clobber (match_scratch:P 7))
12701 (clobber (match_scratch:CC 8))
12702 (clobber (match_scratch:CCEQ 9))]
12706 rtx ctr = operands[0];
12707 rtx ctrcmp = operands[1];
12708 rtx ccin = operands[2];
12709 rtx cccmp = operands[3];
12710 rtx dst1 = operands[4];
12711 rtx dst2 = operands[5];
12712 rtx ctrout = operands[6];
12713 rtx ctrtmp = operands[7];
12714 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12715 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12717 cmpcode = reverse_condition (cmpcode);
12718 /* Generate crand/crandc here. */
12719 emit_insn (gen_rtx_SET (operands[8],
12720 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12721 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12723 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12725 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12726 operands[8], cccmp, ccin));
12728 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12729 operands[8], cccmp, ccin));
12730 if (int_reg_operand (ctrout, <MODE>mode))
12731 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12734 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12735 emit_move_insn (ctrout, ctrtmp);
12737 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12738 emit_jump_insn (gen_rtx_SET (pc_rtx,
12739 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12745 (define_insn "trap"
12746 [(trap_if (const_int 1) (const_int 0))]
12749 [(set_attr "type" "trap")])
12751 (define_expand "ctrap<mode>4"
12752 [(trap_if (match_operator 0 "ordered_comparison_operator"
12753 [(match_operand:GPR 1 "register_operand")
12754 (match_operand:GPR 2 "reg_or_short_operand")])
12755 (match_operand 3 "zero_constant" ""))]
12760 [(trap_if (match_operator 0 "ordered_comparison_operator"
12761 [(match_operand:GPR 1 "register_operand" "r")
12762 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12765 "t<wd>%V0%I2 %1,%2"
12766 [(set_attr "type" "trap")])
12768 ;; Insns related to generating the function prologue and epilogue.
12770 (define_expand "prologue"
12771 [(use (const_int 0))]
12774 rs6000_emit_prologue ();
12775 if (!TARGET_SCHED_PROLOG)
12776 emit_insn (gen_blockage ());
12780 (define_insn "*movesi_from_cr_one"
12781 [(match_parallel 0 "mfcr_operation"
12782 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12783 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12784 (match_operand 3 "immediate_operand" "n")]
12785 UNSPEC_MOVESI_FROM_CR))])]
12790 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12792 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12793 operands[4] = GEN_INT (mask);
12794 output_asm_insn ("mfcr %1,%4", operands);
12798 [(set_attr "type" "mfcrf")])
12800 ;; Don't include the volatile CRs since their values are not used wrt CR save
12801 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12802 ;; prologue past an insn (early exit test) that defines a register used in the
12804 (define_insn "prologue_movesi_from_cr"
12805 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12806 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12807 (reg:CC CR4_REGNO)]
12808 UNSPEC_MOVESI_FROM_CR))]
12811 [(set_attr "type" "mfcr")])
12813 (define_insn "*crsave"
12814 [(match_parallel 0 "crsave_operation"
12815 [(set (match_operand:SI 1 "memory_operand" "=m")
12816 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12819 [(set_attr "type" "store")])
12821 (define_insn "*stmw"
12822 [(match_parallel 0 "stmw_operation"
12823 [(set (match_operand:SI 1 "memory_operand" "=m")
12824 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12827 [(set_attr "type" "store")
12828 (set_attr "update" "yes")
12829 (set_attr "indexed" "yes")])
12831 ; The following comment applies to:
12835 ; return_and_restore_gpregs*
12836 ; return_and_restore_fpregs*
12837 ; return_and_restore_fpregs_aix*
12839 ; The out-of-line save / restore functions expects one input argument.
12840 ; Since those are not standard call_insn's, we must avoid using
12841 ; MATCH_OPERAND for that argument. That way the register rename
12842 ; optimization will not try to rename this register.
12843 ; Each pattern is repeated for each possible register number used in
12844 ; various ABIs (r11, r1, and for some functions r12)
12846 (define_insn "*save_gpregs_<mode>_r11"
12847 [(match_parallel 0 "any_parallel_operand"
12848 [(clobber (reg:P LR_REGNO))
12849 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12851 (set (match_operand:P 2 "memory_operand" "=m")
12852 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12855 [(set_attr "type" "branch")])
12857 (define_insn "*save_gpregs_<mode>_r12"
12858 [(match_parallel 0 "any_parallel_operand"
12859 [(clobber (reg:P LR_REGNO))
12860 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12862 (set (match_operand:P 2 "memory_operand" "=m")
12863 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12866 [(set_attr "type" "branch")])
12868 (define_insn "*save_gpregs_<mode>_r1"
12869 [(match_parallel 0 "any_parallel_operand"
12870 [(clobber (reg:P LR_REGNO))
12871 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12873 (set (match_operand:P 2 "memory_operand" "=m")
12874 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12877 [(set_attr "type" "branch")])
12879 (define_insn "*save_fpregs_<mode>_r11"
12880 [(match_parallel 0 "any_parallel_operand"
12881 [(clobber (reg:P LR_REGNO))
12882 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12884 (set (match_operand:DF 2 "memory_operand" "=m")
12885 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12888 [(set_attr "type" "branch")])
12890 (define_insn "*save_fpregs_<mode>_r12"
12891 [(match_parallel 0 "any_parallel_operand"
12892 [(clobber (reg:P LR_REGNO))
12893 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12895 (set (match_operand:DF 2 "memory_operand" "=m")
12896 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12899 [(set_attr "type" "branch")])
12901 (define_insn "*save_fpregs_<mode>_r1"
12902 [(match_parallel 0 "any_parallel_operand"
12903 [(clobber (reg:P LR_REGNO))
12904 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12906 (set (match_operand:DF 2 "memory_operand" "=m")
12907 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12910 [(set_attr "type" "branch")])
12912 ; This is to explain that changes to the stack pointer should
12913 ; not be moved over loads from or stores to stack memory.
12914 (define_insn "stack_tie"
12915 [(match_parallel 0 "tie_operand"
12916 [(set (mem:BLK (reg 1)) (const_int 0))])]
12919 [(set_attr "length" "0")])
12921 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12922 ; stay behind all restores from the stack, it cannot be reordered to before
12923 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
12924 (define_insn "stack_restore_tie"
12925 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12926 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12927 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12928 (set (mem:BLK (scratch)) (const_int 0))]
12933 [(set_attr "type" "*,add")])
12935 (define_expand "epilogue"
12936 [(use (const_int 0))]
12939 if (!TARGET_SCHED_PROLOG)
12940 emit_insn (gen_blockage ());
12941 rs6000_emit_epilogue (EPILOGUE_TYPE_NORMAL);
12945 ; On some processors, doing the mtcrf one CC register at a time is
12946 ; faster (like on the 604e). On others, doing them all at once is
12947 ; faster; for instance, on the 601 and 750.
12949 (define_expand "movsi_to_cr_one"
12950 [(set (match_operand:CC 0 "cc_reg_operand")
12951 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
12952 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
12954 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
12956 (define_insn "*movsi_to_cr"
12957 [(match_parallel 0 "mtcrf_operation"
12958 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
12959 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
12960 (match_operand 3 "immediate_operand" "n")]
12961 UNSPEC_MOVESI_TO_CR))])]
12966 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12967 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12968 operands[4] = GEN_INT (mask);
12969 return "mtcrf %4,%2";
12971 [(set_attr "type" "mtcr")])
12973 (define_insn "*mtcrfsi"
12974 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
12975 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
12976 (match_operand 2 "immediate_operand" "n")]
12977 UNSPEC_MOVESI_TO_CR))]
12978 "REG_P (operands[0])
12979 && CR_REGNO_P (REGNO (operands[0]))
12980 && CONST_INT_P (operands[2])
12981 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
12983 [(set_attr "type" "mtcr")])
12985 ; The load-multiple instructions have similar properties.
12986 ; Note that "load_multiple" is a name known to the machine-independent
12987 ; code that actually corresponds to the PowerPC load-string.
12989 (define_insn "*lmw"
12990 [(match_parallel 0 "lmw_operation"
12991 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12992 (match_operand:SI 2 "memory_operand" "m"))])]
12995 [(set_attr "type" "load")
12996 (set_attr "update" "yes")
12997 (set_attr "indexed" "yes")
12998 (set_attr "cell_micro" "always")])
13000 ; FIXME: "any_parallel_operand" is a bit flexible...
13002 ; The following comment applies to:
13006 ; return_and_restore_gpregs*
13007 ; return_and_restore_fpregs*
13008 ; return_and_restore_fpregs_aix*
13010 ; The out-of-line save / restore functions expects one input argument.
13011 ; Since those are not standard call_insn's, we must avoid using
13012 ; MATCH_OPERAND for that argument. That way the register rename
13013 ; optimization will not try to rename this register.
13014 ; Each pattern is repeated for each possible register number used in
13015 ; various ABIs (r11, r1, and for some functions r12)
13017 (define_insn "*restore_gpregs_<mode>_r11"
13018 [(match_parallel 0 "any_parallel_operand"
13019 [(clobber (reg:P LR_REGNO))
13020 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13022 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13023 (match_operand:P 3 "memory_operand" "m"))])]
13026 [(set_attr "type" "branch")])
13028 (define_insn "*restore_gpregs_<mode>_r12"
13029 [(match_parallel 0 "any_parallel_operand"
13030 [(clobber (reg:P LR_REGNO))
13031 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13033 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13034 (match_operand:P 3 "memory_operand" "m"))])]
13037 [(set_attr "type" "branch")])
13039 (define_insn "*restore_gpregs_<mode>_r1"
13040 [(match_parallel 0 "any_parallel_operand"
13041 [(clobber (reg:P LR_REGNO))
13042 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13044 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13045 (match_operand:P 3 "memory_operand" "m"))])]
13048 [(set_attr "type" "branch")])
13050 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13051 [(match_parallel 0 "any_parallel_operand"
13053 (clobber (reg:P LR_REGNO))
13054 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13056 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13057 (match_operand:P 3 "memory_operand" "m"))])]
13060 [(set_attr "type" "branch")])
13062 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13063 [(match_parallel 0 "any_parallel_operand"
13065 (clobber (reg:P LR_REGNO))
13066 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13068 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13069 (match_operand:P 3 "memory_operand" "m"))])]
13072 [(set_attr "type" "branch")])
13074 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13075 [(match_parallel 0 "any_parallel_operand"
13077 (clobber (reg:P LR_REGNO))
13078 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13080 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13081 (match_operand:P 3 "memory_operand" "m"))])]
13084 [(set_attr "type" "branch")])
13086 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13087 [(match_parallel 0 "any_parallel_operand"
13089 (clobber (reg:P LR_REGNO))
13090 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13092 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13093 (match_operand:DF 3 "memory_operand" "m"))])]
13096 [(set_attr "type" "branch")])
13098 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13099 [(match_parallel 0 "any_parallel_operand"
13101 (clobber (reg:P LR_REGNO))
13102 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13104 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13105 (match_operand:DF 3 "memory_operand" "m"))])]
13108 [(set_attr "type" "branch")])
13110 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13111 [(match_parallel 0 "any_parallel_operand"
13113 (clobber (reg:P LR_REGNO))
13114 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13116 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13117 (match_operand:DF 3 "memory_operand" "m"))])]
13120 [(set_attr "type" "branch")])
13122 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13123 [(match_parallel 0 "any_parallel_operand"
13125 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13127 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13128 (match_operand:DF 3 "memory_operand" "m"))])]
13131 [(set_attr "type" "branch")])
13133 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13134 [(match_parallel 0 "any_parallel_operand"
13136 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13138 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13139 (match_operand:DF 3 "memory_operand" "m"))])]
13142 [(set_attr "type" "branch")])
13144 ; This is used in compiling the unwind routines.
13145 (define_expand "eh_return"
13146 [(use (match_operand 0 "general_operand"))]
13149 emit_insn (gen_eh_set_lr (Pmode, operands[0]));
13153 ; We can't expand this before we know where the link register is stored.
13154 (define_insn_and_split "@eh_set_lr_<mode>"
13155 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")] UNSPECV_EH_RR)
13156 (clobber (match_scratch:P 1 "=&b"))]
13162 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13166 (define_insn "prefetch"
13167 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13168 (match_operand:SI 1 "const_int_operand" "n")
13169 (match_operand:SI 2 "const_int_operand" "n"))]
13174 /* dcbtstt, dcbtt and TH=0b10000 support starts with ISA 2.06 (Power7).
13175 AIX does not support the dcbtstt and dcbtt extended mnemonics.
13176 The AIX assembler does not support the three operand form of dcbt
13177 and dcbtst on Power 7 (-mpwr7). */
13178 int inst_select = INTVAL (operands[2]) || !TARGET_DIRECT_MOVE;
13180 if (REG_P (operands[0]))
13182 if (INTVAL (operands[1]) == 0)
13183 return inst_select ? "dcbt 0,%0" : "dcbt 0,%0,16";
13185 return inst_select ? "dcbtst 0,%0" : "dcbtst 0,%0,16";
13189 if (INTVAL (operands[1]) == 0)
13190 return inst_select ? "dcbt %a0" : "dcbt %a0,16";
13192 return inst_select ? "dcbtst %a0" : "dcbtst %a0,16";
13195 [(set_attr "type" "load")])
13197 ;; Handle -fsplit-stack.
13199 (define_expand "split_stack_prologue"
13203 rs6000_expand_split_stack_prologue ();
13207 (define_expand "load_split_stack_limit"
13208 [(set (match_operand 0)
13209 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13212 emit_insn (gen_rtx_SET (operands[0],
13213 gen_rtx_UNSPEC (Pmode,
13214 gen_rtvec (1, const0_rtx),
13215 UNSPEC_STACK_CHECK)));
13219 (define_insn "load_split_stack_limit_di"
13220 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13221 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13223 "ld %0,-0x7040(13)"
13224 [(set_attr "type" "load")
13225 (set_attr "update" "no")
13226 (set_attr "indexed" "no")])
13228 (define_insn "load_split_stack_limit_si"
13229 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13230 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13232 "lwz %0,-0x7020(2)"
13233 [(set_attr "type" "load")
13234 (set_attr "update" "no")
13235 (set_attr "indexed" "no")])
13237 ;; A return instruction which the middle-end doesn't see.
13238 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13239 ;; after the call to __morestack.
13240 (define_insn "split_stack_return"
13241 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13244 [(set_attr "type" "jmpreg")])
13246 ;; If there are operand 0 bytes available on the stack, jump to
13248 (define_expand "split_stack_space_check"
13249 [(set (match_dup 2)
13250 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13252 (minus (reg STACK_POINTER_REGNUM)
13253 (match_operand 0)))
13254 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13255 (set (pc) (if_then_else
13256 (geu (match_dup 4) (const_int 0))
13257 (label_ref (match_operand 1))
13261 rs6000_split_stack_space_check (operands[0], operands[1]);
13265 (define_insn "bpermd_<mode>"
13266 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13267 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13268 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13271 [(set_attr "type" "popcnt")])
13274 ;; Builtin fma support. Handle
13275 ;; Note that the conditions for expansion are in the FMA_F iterator.
13277 (define_expand "fma<mode>4"
13278 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13280 (match_operand:FMA_F 1 "gpc_reg_operand")
13281 (match_operand:FMA_F 2 "gpc_reg_operand")
13282 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13286 (define_insn "*fma<mode>4_fpr"
13287 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13289 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,wa,wa")
13290 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13291 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))]
13292 "TARGET_HARD_FLOAT"
13294 fmadd<s> %0,%1,%2,%3
13295 xsmadda<sd>p %x0,%x1,%x2
13296 xsmaddm<sd>p %x0,%x1,%x3"
13297 [(set_attr "type" "fp")
13298 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13300 ; Altivec only has fma and nfms.
13301 (define_expand "fms<mode>4"
13302 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13304 (match_operand:FMA_F 1 "gpc_reg_operand")
13305 (match_operand:FMA_F 2 "gpc_reg_operand")
13306 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13307 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13310 (define_insn "*fms<mode>4_fpr"
13311 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13313 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13314 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13315 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13316 "TARGET_HARD_FLOAT"
13318 fmsub<s> %0,%1,%2,%3
13319 xsmsuba<sd>p %x0,%x1,%x2
13320 xsmsubm<sd>p %x0,%x1,%x3"
13321 [(set_attr "type" "fp")
13322 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13324 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13325 (define_expand "fnma<mode>4"
13326 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13329 (match_operand:FMA_F 1 "gpc_reg_operand")
13330 (match_operand:FMA_F 2 "gpc_reg_operand")
13331 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13332 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13335 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13336 (define_expand "fnms<mode>4"
13337 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13340 (match_operand:FMA_F 1 "gpc_reg_operand")
13341 (match_operand:FMA_F 2 "gpc_reg_operand")
13342 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13343 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13346 ; Not an official optab name, but used from builtins.
13347 (define_expand "nfma<mode>4"
13348 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13351 (match_operand:FMA_F 1 "gpc_reg_operand")
13352 (match_operand:FMA_F 2 "gpc_reg_operand")
13353 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13354 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13357 (define_insn "*nfma<mode>4_fpr"
13358 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13361 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13362 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13363 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa"))))]
13364 "TARGET_HARD_FLOAT"
13366 fnmadd<s> %0,%1,%2,%3
13367 xsnmadda<sd>p %x0,%x1,%x2
13368 xsnmaddm<sd>p %x0,%x1,%x3"
13369 [(set_attr "type" "fp")
13370 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13372 ; Not an official optab name, but used from builtins.
13373 (define_expand "nfms<mode>4"
13374 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13377 (match_operand:FMA_F 1 "gpc_reg_operand")
13378 (match_operand:FMA_F 2 "gpc_reg_operand")
13379 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13383 (define_insn "*nfmssf4_fpr"
13384 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,wa,wa")
13387 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,wa,wa")
13388 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,wa,0")
13390 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,wa")))))]
13391 "TARGET_HARD_FLOAT"
13393 fnmsub<s> %0,%1,%2,%3
13394 xsnmsuba<sd>p %x0,%x1,%x2
13395 xsnmsubm<sd>p %x0,%x1,%x3"
13396 [(set_attr "type" "fp")
13397 (set_attr "isa" "*,<Fisa>,<Fisa>")])
13399 (define_expand "rs6000_get_timebase"
13400 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13403 if (TARGET_POWERPC64)
13404 emit_insn (gen_rs6000_mftb_di (operands[0]));
13406 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13410 (define_insn "rs6000_get_timebase_ppc32"
13411 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13412 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13413 (clobber (match_scratch:SI 1 "=r"))
13414 (clobber (match_scratch:CC 2 "=y"))]
13415 "!TARGET_POWERPC64"
13417 if (WORDS_BIG_ENDIAN)
13420 return "mfspr %0,269\;"
13428 return "mftbu %0\;"
13437 return "mfspr %L0,269\;"
13445 return "mftbu %L0\;"
13452 [(set_attr "length" "20")])
13454 (define_insn "rs6000_mftb_<mode>"
13455 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13456 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13460 return "mfspr %0,268";
13466 ;; The ISA 3.0 mffsl instruction is a lower latency instruction
13467 ;; for reading bits [29:31], [45:51] and [56:63] of the FPSCR.
13468 (define_insn "rs6000_mffsl_hw"
13469 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13470 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13471 "TARGET_HARD_FLOAT"
13474 (define_expand "rs6000_mffsl"
13475 [(set (match_operand:DF 0 "gpc_reg_operand")
13476 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFSL))]
13477 "TARGET_HARD_FLOAT"
13479 /* If the low latency mffsl instruction (ISA 3.0) is available use it,
13480 otherwise fall back to the older mffs instruction to emulate the mffsl
13483 if (!TARGET_P9_MISC)
13485 rtx tmp_di = gen_reg_rtx (DImode);
13486 rtx tmp_df = gen_reg_rtx (DFmode);
13488 /* The mffs instruction reads the entire FPSCR. Emulate the mffsl
13489 instruction using the mffs instruction and masking off the bits
13490 the mmsl instruciton actually reads. */
13491 emit_insn (gen_rs6000_mffs (tmp_df));
13492 tmp_di = simplify_gen_subreg (DImode, tmp_df, DFmode, 0);
13493 emit_insn (gen_anddi3 (tmp_di, tmp_di, GEN_INT (0x70007f0ffLL)));
13495 operands[0] = simplify_gen_subreg (DFmode, tmp_di, DImode, 0);
13499 emit_insn (gen_rs6000_mffsl_hw (operands[0]));
13503 (define_insn "rs6000_mffs"
13504 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13505 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13506 "TARGET_HARD_FLOAT"
13509 (define_insn "rs6000_mtfsf"
13510 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13511 (match_operand:DF 1 "gpc_reg_operand" "d")]
13513 "TARGET_HARD_FLOAT"
13516 (define_insn "rs6000_mtfsf_hi"
13517 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "n")
13518 (match_operand:DF 1 "gpc_reg_operand" "d")]
13520 "TARGET_HARD_FLOAT"
13524 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13525 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13526 ;; register that is being loaded. The fused ops must be physically adjacent.
13528 ;; On Power8 GPR loads, we try to use the register that is being load. The
13529 ;; peephole2 then gathers any other fused possibilities that it can find after
13530 ;; register allocation. If power9 fusion is selected, we also fuse floating
13531 ;; point loads/stores.
13533 ;; Find cases where the addis that feeds into a load instruction is either used
13534 ;; once or is the same as the target register, and replace it with the fusion
13538 [(set (match_operand:P 0 "base_reg_operand")
13539 (match_operand:P 1 "fusion_gpr_addis"))
13540 (set (match_operand:INT1 2 "base_reg_operand")
13541 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13543 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13547 expand_fusion_gpr_load (operands);
13551 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13554 (define_insn "*fusion_gpr_load_<mode>"
13555 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13556 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13557 UNSPEC_FUSION_GPR))]
13560 return emit_fusion_gpr_load (operands[0], operands[1]);
13562 [(set_attr "type" "load")
13563 (set_attr "length" "8")])
13566 ;; Optimize cases where we want to do a D-form load (register+offset) on
13567 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13572 ;; and we change this to:
13577 [(match_scratch:P 0 "b")
13578 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13579 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13580 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13582 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13583 [(set (match_dup 0)
13588 rtx tmp_reg = operands[0];
13589 rtx mem = operands[2];
13590 rtx addr = XEXP (mem, 0);
13591 rtx add_op0, add_op1, new_addr;
13593 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13594 add_op0 = XEXP (addr, 0);
13595 add_op1 = XEXP (addr, 1);
13596 gcc_assert (REG_P (add_op0));
13597 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13599 operands[4] = add_op1;
13600 operands[5] = change_address (mem, <MODE>mode, new_addr);
13603 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13604 ;; Altivec register, and the register allocator has generated:
13608 ;; and we change this to:
13613 [(match_scratch:P 0 "b")
13614 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13615 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13616 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13618 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13619 [(set (match_dup 0)
13624 rtx tmp_reg = operands[0];
13625 rtx mem = operands[3];
13626 rtx addr = XEXP (mem, 0);
13627 rtx add_op0, add_op1, new_addr;
13629 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13630 add_op0 = XEXP (addr, 0);
13631 add_op1 = XEXP (addr, 1);
13632 gcc_assert (REG_P (add_op0));
13633 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13635 operands[4] = add_op1;
13636 operands[5] = change_address (mem, <MODE>mode, new_addr);
13640 ;; Miscellaneous ISA 2.06 (power7) instructions
13641 (define_insn "addg6s"
13642 [(set (match_operand:SI 0 "register_operand" "=r")
13643 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13644 (match_operand:SI 2 "register_operand" "r")]
13648 [(set_attr "type" "integer")])
13650 (define_insn "cdtbcd"
13651 [(set (match_operand:SI 0 "register_operand" "=r")
13652 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13656 [(set_attr "type" "integer")])
13658 (define_insn "cbcdtd"
13659 [(set (match_operand:SI 0 "register_operand" "=r")
13660 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13664 [(set_attr "type" "integer")])
13666 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13669 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13670 (UNSPEC_DIVEU "eu")])
13672 (define_insn "div<div_extend>_<mode>"
13673 [(set (match_operand:GPR 0 "register_operand" "=r")
13674 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13675 (match_operand:GPR 2 "register_operand" "r")]
13676 UNSPEC_DIV_EXTEND))]
13678 "div<wd><div_extend> %0,%1,%2"
13679 [(set_attr "type" "div")
13680 (set_attr "size" "<bits>")])
13683 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13685 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13686 (define_mode_attr FP128_64 [(TF "DF")
13691 (define_expand "unpack<mode>"
13692 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13694 [(match_operand:FMOVE128 1 "register_operand")
13695 (match_operand:QI 2 "const_0_to_1_operand")]
13696 UNSPEC_UNPACK_128BIT))]
13697 "FLOAT128_2REG_P (<MODE>mode)"
13700 (define_insn_and_split "unpack<mode>_dm"
13701 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13703 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13704 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13705 UNSPEC_UNPACK_128BIT))]
13706 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13708 "&& reload_completed"
13709 [(set (match_dup 0) (match_dup 3))]
13711 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13713 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13715 emit_note (NOTE_INSN_DELETED);
13719 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13721 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")])
13723 (define_insn_and_split "unpack<mode>_nodm"
13724 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13726 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13727 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13728 UNSPEC_UNPACK_128BIT))]
13729 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13731 "&& reload_completed"
13732 [(set (match_dup 0) (match_dup 3))]
13734 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13736 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13738 emit_note (NOTE_INSN_DELETED);
13742 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13744 [(set_attr "type" "fp,fpstore")])
13746 (define_insn_and_split "pack<mode>"
13747 [(set (match_operand:FMOVE128 0 "register_operand" "=&d")
13749 [(match_operand:<FP128_64> 1 "register_operand" "d")
13750 (match_operand:<FP128_64> 2 "register_operand" "d")]
13751 UNSPEC_PACK_128BIT))]
13752 "FLOAT128_2REG_P (<MODE>mode)"
13754 "&& reload_completed"
13755 [(set (match_dup 3) (match_dup 1))
13756 (set (match_dup 4) (match_dup 2))]
13758 unsigned dest_hi = REGNO (operands[0]);
13759 unsigned dest_lo = dest_hi + 1;
13761 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13762 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13764 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13765 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13767 [(set_attr "type" "fp")
13768 (set_attr "length" "8")])
13770 (define_insn "unpack<mode>"
13771 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13772 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13773 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13774 UNSPEC_UNPACK_128BIT))]
13775 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13777 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13778 return ASM_COMMENT_START " xxpermdi to same register";
13780 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13781 return "xxpermdi %x0,%x1,%x1,%3";
13783 [(set_attr "type" "vecperm")])
13785 (define_insn "pack<mode>"
13786 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13787 (unspec:FMOVE128_VSX
13788 [(match_operand:DI 1 "register_operand" "wa")
13789 (match_operand:DI 2 "register_operand" "wa")]
13790 UNSPEC_PACK_128BIT))]
13792 "xxpermdi %x0,%x1,%x2,0"
13793 [(set_attr "type" "vecperm")])
13797 ;; ISA 2.08 IEEE 128-bit floating point support.
13799 (define_insn "add<mode>3"
13800 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13802 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13803 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13804 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13806 [(set_attr "type" "vecfloat")
13807 (set_attr "size" "128")])
13809 (define_insn "sub<mode>3"
13810 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13812 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13813 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13814 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13816 [(set_attr "type" "vecfloat")
13817 (set_attr "size" "128")])
13819 (define_insn "mul<mode>3"
13820 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13822 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13823 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13824 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13826 [(set_attr "type" "qmul")
13827 (set_attr "size" "128")])
13829 (define_insn "div<mode>3"
13830 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13832 (match_operand:IEEE128 1 "altivec_register_operand" "v")
13833 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
13834 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13836 [(set_attr "type" "vecdiv")
13837 (set_attr "size" "128")])
13839 (define_insn "sqrt<mode>2"
13840 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13842 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13843 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13845 [(set_attr "type" "vecdiv")
13846 (set_attr "size" "128")])
13848 (define_expand "copysign<mode>3"
13849 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
13850 (use (match_operand:IEEE128 1 "altivec_register_operand"))
13851 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
13852 "FLOAT128_IEEE_P (<MODE>mode)"
13854 if (TARGET_FLOAT128_HW)
13855 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
13858 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
13863 (define_insn "copysign<mode>3_hard"
13864 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13866 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13867 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13869 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13870 "xscpsgnqp %0,%2,%1"
13871 [(set_attr "type" "vecmove")
13872 (set_attr "size" "128")])
13874 (define_insn "copysign<mode>3_soft"
13875 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13877 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
13878 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
13880 (clobber (match_scratch:IEEE128 3 "=&v"))]
13881 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13882 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
13883 [(set_attr "type" "veccomplex")
13884 (set_attr "length" "8")])
13886 (define_insn "@neg<mode>2_hw"
13887 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13889 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13890 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13892 [(set_attr "type" "vecmove")
13893 (set_attr "size" "128")])
13896 (define_insn "@abs<mode>2_hw"
13897 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13899 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
13900 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13902 [(set_attr "type" "vecmove")
13903 (set_attr "size" "128")])
13906 (define_insn "*nabs<mode>2_hw"
13907 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13910 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
13911 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13913 [(set_attr "type" "vecmove")
13914 (set_attr "size" "128")])
13916 ;; Initially don't worry about doing fusion
13917 (define_insn "fma<mode>4_hw"
13918 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13920 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13921 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13922 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
13923 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13924 "xsmaddqp %0,%1,%2"
13925 [(set_attr "type" "qmul")
13926 (set_attr "size" "128")])
13928 (define_insn "*fms<mode>4_hw"
13929 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13931 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13932 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13934 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13935 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13936 "xsmsubqp %0,%1,%2"
13937 [(set_attr "type" "qmul")
13938 (set_attr "size" "128")])
13940 (define_insn "*nfma<mode>4_hw"
13941 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13944 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13945 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13946 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
13947 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13948 "xsnmaddqp %0,%1,%2"
13949 [(set_attr "type" "qmul")
13950 (set_attr "size" "128")])
13952 (define_insn "*nfms<mode>4_hw"
13953 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13956 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
13957 (match_operand:IEEE128 2 "altivec_register_operand" "v")
13959 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
13960 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
13961 "xsnmsubqp %0,%1,%2"
13962 [(set_attr "type" "qmul")
13963 (set_attr "size" "128")])
13965 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
13966 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
13967 (float_extend:IEEE128
13968 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
13969 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
13971 [(set_attr "type" "vecfloat")
13972 (set_attr "size" "128")])
13974 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
13975 ;; point is a simple copy.
13976 (define_insn_and_split "extendkftf2"
13977 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
13978 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
13979 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13983 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
13986 emit_note (NOTE_INSN_DELETED);
13989 [(set_attr "type" "*,veclogical")
13990 (set_attr "length" "0,4")])
13992 (define_insn_and_split "trunctfkf2"
13993 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
13994 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
13995 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
13999 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14002 emit_note (NOTE_INSN_DELETED);
14005 [(set_attr "type" "*,veclogical")
14006 (set_attr "length" "0,4")])
14008 (define_insn "trunc<mode>df2_hw"
14009 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14011 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14012 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14014 [(set_attr "type" "vecfloat")
14015 (set_attr "size" "128")])
14017 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14018 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14020 (define_insn_and_split "trunc<mode>sf2_hw"
14021 [(set (match_operand:SF 0 "vsx_register_operand" "=wa")
14023 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14024 (clobber (match_scratch:DF 2 "=v"))]
14025 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14028 [(set (match_dup 2)
14029 (unspec:DF [(match_dup 1)]
14030 UNSPEC_TRUNC_ROUND_TO_ODD))
14032 (float_truncate:SF (match_dup 2)))]
14034 if (GET_CODE (operands[2]) == SCRATCH)
14035 operands[2] = gen_reg_rtx (DFmode);
14037 [(set_attr "type" "vecfloat")
14038 (set_attr "length" "8")
14039 (set_attr "isa" "p8v")])
14041 ;; Conversion between IEEE 128-bit and integer types
14043 ;; The fix function for DImode and SImode was declared earlier as a
14044 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14045 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14046 ;; unless we have the IEEE 128-bit hardware.
14048 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14049 ;; to provide a GPR target that used direct move and a conversion in the GPR
14050 ;; which works around QImode/HImode not being allowed in vector registers in
14051 ;; ISA 2.07 (power8).
14052 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14053 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14054 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14055 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14056 "xscvqp<su><wd>z %0,%1"
14057 [(set_attr "type" "vecfloat")
14058 (set_attr "size" "128")])
14060 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14061 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14063 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14064 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14065 "xscvqp<su>wz %0,%1"
14066 [(set_attr "type" "vecfloat")
14067 (set_attr "size" "128")])
14069 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14070 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14071 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14072 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14074 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14075 (clobber (match_scratch:QHSI 2 "=v"))]
14076 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14078 "&& reload_completed"
14079 [(set (match_dup 2)
14080 (any_fix:QHSI (match_dup 1)))
14084 (define_insn "float_<mode>di2_hw"
14085 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14086 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14087 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14089 [(set_attr "type" "vecfloat")
14090 (set_attr "size" "128")])
14092 (define_insn_and_split "float_<mode>si2_hw"
14093 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14094 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14095 (clobber (match_scratch:DI 2 "=v"))]
14096 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14099 [(set (match_dup 2)
14100 (sign_extend:DI (match_dup 1)))
14102 (float:IEEE128 (match_dup 2)))]
14104 if (GET_CODE (operands[2]) == SCRATCH)
14105 operands[2] = gen_reg_rtx (DImode);
14107 if (MEM_P (operands[1]))
14108 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14111 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14112 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14113 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14114 (clobber (match_scratch:DI 2 "=X,r,X"))]
14115 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14117 "&& reload_completed"
14120 rtx dest = operands[0];
14121 rtx src = operands[1];
14122 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14124 if (altivec_register_operand (src, <QHI:MODE>mode))
14125 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14126 else if (int_reg_operand (src, <QHI:MODE>mode))
14128 rtx ext_di = operands[2];
14129 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14130 emit_move_insn (dest_di, ext_di);
14132 else if (MEM_P (src))
14134 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14135 emit_move_insn (dest_qhi, src);
14136 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14139 gcc_unreachable ();
14141 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14144 [(set_attr "length" "8,12,12")
14145 (set_attr "type" "vecfloat")
14146 (set_attr "size" "128")])
14148 (define_insn "floatuns_<mode>di2_hw"
14149 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14150 (unsigned_float:IEEE128
14151 (match_operand:DI 1 "altivec_register_operand" "v")))]
14152 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14154 [(set_attr "type" "vecfloat")
14155 (set_attr "size" "128")])
14157 (define_insn_and_split "floatuns_<mode>si2_hw"
14158 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14159 (unsigned_float:IEEE128
14160 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14161 (clobber (match_scratch:DI 2 "=v"))]
14162 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14165 [(set (match_dup 2)
14166 (zero_extend:DI (match_dup 1)))
14168 (float:IEEE128 (match_dup 2)))]
14170 if (GET_CODE (operands[2]) == SCRATCH)
14171 operands[2] = gen_reg_rtx (DImode);
14173 if (MEM_P (operands[1]))
14174 operands[1] = rs6000_force_indexed_or_indirect_mem (operands[1]);
14177 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14178 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14179 (unsigned_float:IEEE128
14180 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14181 (clobber (match_scratch:DI 2 "=X,r,X"))]
14182 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14184 "&& reload_completed"
14187 rtx dest = operands[0];
14188 rtx src = operands[1];
14189 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14191 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14192 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14193 else if (int_reg_operand (src, <QHI:MODE>mode))
14195 rtx ext_di = operands[2];
14196 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14197 emit_move_insn (dest_di, ext_di);
14200 gcc_unreachable ();
14202 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14205 [(set_attr "length" "8,12,8")
14206 (set_attr "type" "vecfloat")
14207 (set_attr "size" "128")])
14209 ;; IEEE 128-bit round to integer built-in functions
14210 (define_insn "floor<mode>2"
14211 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14213 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14215 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14217 [(set_attr "type" "vecfloat")
14218 (set_attr "size" "128")])
14220 (define_insn "ceil<mode>2"
14221 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14223 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14225 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14227 [(set_attr "type" "vecfloat")
14228 (set_attr "size" "128")])
14230 (define_insn "btrunc<mode>2"
14231 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14233 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14235 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14237 [(set_attr "type" "vecfloat")
14238 (set_attr "size" "128")])
14240 (define_insn "round<mode>2"
14241 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14243 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14245 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14247 [(set_attr "type" "vecfloat")
14248 (set_attr "size" "128")])
14250 ;; IEEE 128-bit instructions with round to odd semantics
14251 (define_insn "add<mode>3_odd"
14252 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14254 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14255 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14256 UNSPEC_ADD_ROUND_TO_ODD))]
14257 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14258 "xsaddqpo %0,%1,%2"
14259 [(set_attr "type" "vecfloat")
14260 (set_attr "size" "128")])
14262 (define_insn "sub<mode>3_odd"
14263 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14265 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14266 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14267 UNSPEC_SUB_ROUND_TO_ODD))]
14268 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14269 "xssubqpo %0,%1,%2"
14270 [(set_attr "type" "vecfloat")
14271 (set_attr "size" "128")])
14273 (define_insn "mul<mode>3_odd"
14274 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14276 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14277 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14278 UNSPEC_MUL_ROUND_TO_ODD))]
14279 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14280 "xsmulqpo %0,%1,%2"
14281 [(set_attr "type" "qmul")
14282 (set_attr "size" "128")])
14284 (define_insn "div<mode>3_odd"
14285 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14287 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14288 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14289 UNSPEC_DIV_ROUND_TO_ODD))]
14290 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14291 "xsdivqpo %0,%1,%2"
14292 [(set_attr "type" "vecdiv")
14293 (set_attr "size" "128")])
14295 (define_insn "sqrt<mode>2_odd"
14296 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14298 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14299 UNSPEC_SQRT_ROUND_TO_ODD))]
14300 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14302 [(set_attr "type" "vecdiv")
14303 (set_attr "size" "128")])
14305 (define_insn "fma<mode>4_odd"
14306 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14308 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14309 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14310 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14311 UNSPEC_FMA_ROUND_TO_ODD))]
14312 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14313 "xsmaddqpo %0,%1,%2"
14314 [(set_attr "type" "qmul")
14315 (set_attr "size" "128")])
14317 (define_insn "*fms<mode>4_odd"
14318 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14320 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14321 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14323 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14324 UNSPEC_FMA_ROUND_TO_ODD))]
14325 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14326 "xsmsubqpo %0,%1,%2"
14327 [(set_attr "type" "qmul")
14328 (set_attr "size" "128")])
14330 (define_insn "*nfma<mode>4_odd"
14331 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14334 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14335 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14336 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14337 UNSPEC_FMA_ROUND_TO_ODD)))]
14338 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14339 "xsnmaddqpo %0,%1,%2"
14340 [(set_attr "type" "qmul")
14341 (set_attr "size" "128")])
14343 (define_insn "*nfms<mode>4_odd"
14344 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14347 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14348 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14350 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14351 UNSPEC_FMA_ROUND_TO_ODD)))]
14352 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14353 "xsnmsubqpo %0,%1,%2"
14354 [(set_attr "type" "qmul")
14355 (set_attr "size" "128")])
14357 (define_insn "trunc<mode>df2_odd"
14358 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14359 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14360 UNSPEC_TRUNC_ROUND_TO_ODD))]
14361 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14363 [(set_attr "type" "vecfloat")
14364 (set_attr "size" "128")])
14366 ;; IEEE 128-bit comparisons
14367 (define_insn "*cmp<mode>_hw"
14368 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14369 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14370 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14371 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14372 "xscmpuqp %0,%1,%2"
14373 [(set_attr "type" "veccmp")
14374 (set_attr "size" "128")])
14378 (include "sync.md")
14379 (include "vector.md")
14381 (include "altivec.md")
14383 (include "crypto.md")