1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2018 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)
38 (ARG_POINTER_REGNUM 67)
49 (FIRST_ALTIVEC_REGNO 77)
50 (LAST_ALTIVEC_REGNO 108)
53 (FRAME_POINTER_REGNUM 111)
63 (define_c_enum "unspec"
64 [UNSPEC_FRSP ; frsp for POWER machines
65 UNSPEC_PROBE_STACK ; probe stack memory reference
66 UNSPEC_TOCPTR ; address of a word pointing to the TOC
67 UNSPEC_TOC ; address of the TOC (more-or-less)
68 UNSPEC_TOCSLOT ; offset from r1 of toc pointer save slot
70 UNSPEC_MV_CR_OV ; move_from_CR_ov_bit
77 UNSPEC_LD_MPIC ; load_macho_picbase
78 UNSPEC_RELD_MPIC ; re-load_macho_picbase
79 UNSPEC_MPIC_CORRECT ; macho_correct_pic
93 UNSPEC_FIX_TRUNC_TF ; fadd, rounding towards zero
111 UNSPEC_MACHOPIC_OFFSET
125 UNSPEC_P8V_RELOAD_FROM_GPR
128 UNSPEC_P8V_RELOAD_FROM_VSX
141 UNSPEC_ADD_ROUND_TO_ODD
142 UNSPEC_SUB_ROUND_TO_ODD
143 UNSPEC_MUL_ROUND_TO_ODD
144 UNSPEC_DIV_ROUND_TO_ODD
145 UNSPEC_FMA_ROUND_TO_ODD
146 UNSPEC_SQRT_ROUND_TO_ODD
147 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_MTFSF ; Move to FPSCR Fields
168 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
169 UNSPECV_SPEC_BARRIER ; Speculation barrier
173 ;; Define an insn type attribute. This is used in function unit delay
177 add,logical,shift,insert,
179 exts,cntlz,popcnt,isel,
180 load,store,fpload,fpstore,vecload,vecstore,
182 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
183 cr_logical,mfcr,mfcrf,mtcr,
184 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
185 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
186 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
187 veclogical,veccmpfx,vecexts,vecmove,
189 (const_string "integer"))
191 ;; What data size does this instruction work on?
192 ;; This is used for insert, mul and others as necessary.
193 (define_attr "size" "8,16,32,64,128" (const_string "32"))
195 ;; What is the insn_cost for this insn? The target hook can still override
196 ;; this. For optimizing for size the "length" attribute is used instead.
197 (define_attr "cost" "" (const_int 0))
199 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
200 ;; This is used for add, logical, shift, exts, mul.
201 (define_attr "dot" "no,yes" (const_string "no"))
203 ;; Does this instruction sign-extend its result?
204 ;; This is used for load insns.
205 (define_attr "sign_extend" "no,yes" (const_string "no"))
207 ;; Does this cr_logical instruction have three operands? That is, BT != BB.
208 (define_attr "cr_logical_3op" "no,yes" (const_string "no"))
210 ;; Does this instruction use indexed (that is, reg+reg) addressing?
211 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
212 ;; it is automatically set based on that. If a load or store instruction
213 ;; has fewer than two operands it needs to set this attribute manually
214 ;; or the compiler will crash.
215 (define_attr "indexed" "no,yes"
216 (if_then_else (ior (match_operand 0 "indexed_address_mem")
217 (match_operand 1 "indexed_address_mem"))
219 (const_string "no")))
221 ;; Does this instruction use update addressing?
222 ;; This is used for load and store insns. See the comments for "indexed".
223 (define_attr "update" "no,yes"
224 (if_then_else (ior (match_operand 0 "update_address_mem")
225 (match_operand 1 "update_address_mem"))
227 (const_string "no")))
229 ;; Is this instruction using operands[2] as shift amount, and can that be a
231 ;; This is used for shift insns.
232 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
234 ;; Is this instruction using a shift amount from a register?
235 ;; This is used for shift insns.
236 (define_attr "var_shift" "no,yes"
237 (if_then_else (and (eq_attr "type" "shift")
238 (eq_attr "maybe_var_shift" "yes"))
239 (if_then_else (match_operand 2 "gpc_reg_operand")
242 (const_string "no")))
244 ;; Is copying of this instruction disallowed?
245 (define_attr "cannot_copy" "no,yes" (const_string "no"))
247 ;; Define floating point instruction sub-types for use with Xfpu.md
248 (define_attr "fp_type" "fp_default,fp_addsub_s,fp_addsub_d,fp_mul_s,fp_mul_d,fp_div_s,fp_div_d,fp_maddsub_s,fp_maddsub_d,fp_sqrt_s,fp_sqrt_d" (const_string "fp_default"))
250 ;; Length (in bytes).
251 ; '(pc)' in the following doesn't include the instruction itself; it is
252 ; calculated as if the instruction had zero size.
253 (define_attr "length" ""
254 (if_then_else (eq_attr "type" "branch")
255 (if_then_else (and (ge (minus (match_dup 0) (pc))
257 (lt (minus (match_dup 0) (pc))
263 ;; Processor type -- this attribute must exactly match the processor_type
264 ;; enumeration in rs6000-opts.h.
266 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
267 ppc750,ppc7400,ppc7450,
268 ppc403,ppc405,ppc440,ppc476,
269 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
270 power4,power5,power6,power7,power8,power9,
271 rs64a,mpccore,cell,ppca2,titan"
272 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
275 ;; If this instruction is microcoded on the CELL processor
276 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
277 (define_attr "cell_micro" "not,conditional,always"
278 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
279 (eq_attr "dot" "yes"))
280 (and (eq_attr "type" "load")
281 (eq_attr "sign_extend" "yes"))
282 (and (eq_attr "type" "shift")
283 (eq_attr "var_shift" "yes")))
284 (const_string "always")
285 (const_string "not")))
287 (automata_option "ndfa")
300 (include "e300c2c3.md")
301 (include "e500mc.md")
302 (include "e500mc64.md")
305 (include "power4.md")
306 (include "power5.md")
307 (include "power6.md")
308 (include "power7.md")
309 (include "power8.md")
310 (include "power9.md")
316 (include "predicates.md")
317 (include "constraints.md")
319 (include "darwin.md")
324 ; This mode iterator allows :GPR to be used to indicate the allowable size
325 ; of whole values in GPRs.
326 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
328 ; And again, for patterns that need two (potentially) different integer modes.
329 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
331 ; Any supported integer mode.
332 (define_mode_iterator INT [QI HI SI DI TI PTI])
334 ; Any supported integer mode that fits in one register.
335 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
337 ; Integer modes supported in VSX registers with ISA 3.0 instructions
338 (define_mode_iterator INT_ISA3 [QI HI SI DI])
340 ; Everything we can extend QImode to.
341 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
343 ; Everything we can extend HImode to.
344 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
346 ; Everything we can extend SImode to.
347 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
349 ; QImode or HImode for small integer moves and small atomic ops
350 (define_mode_iterator QHI [QI HI])
352 ; QImode, HImode, SImode for fused ops only for GPR loads
353 (define_mode_iterator QHSI [QI HI SI])
355 ; HImode or SImode for sign extended fusion ops
356 (define_mode_iterator HSI [HI SI])
358 ; SImode or DImode, even if DImode doesn't fit in GPRs.
359 (define_mode_iterator SDI [SI DI])
361 ; Types that can be fused with an ADDIS instruction to load or store a GPR
362 ; register that has reg+offset addressing.
363 (define_mode_iterator GPR_FUSION [QI
366 (DI "TARGET_POWERPC64")
368 (DF "TARGET_POWERPC64")])
370 ; Types that can be fused with an ADDIS instruction to load or store a FPR
371 ; register that has reg+offset addressing.
372 (define_mode_iterator FPR_FUSION [DI SF DF])
374 ; The size of a pointer. Also, the size of the value that a record-condition
375 ; (one with a '.') will compare; and the size used for arithmetic carries.
376 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
378 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
379 ; PTImode is GPR only)
380 (define_mode_iterator TI2 [TI PTI])
382 ; Any hardware-supported floating-point mode
383 (define_mode_iterator FP [
384 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
385 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
386 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
387 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
388 (KF "TARGET_FLOAT128_TYPE")
392 ; Any fma capable floating-point mode.
393 (define_mode_iterator FMA_F [
394 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
395 (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
396 || VECTOR_UNIT_VSX_P (DFmode)")
397 (V2SF "TARGET_PAIRED_FLOAT")
398 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
399 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
400 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
401 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
404 ; Floating point move iterators to combine binary and decimal moves
405 (define_mode_iterator FMOVE32 [SF SD])
406 (define_mode_iterator FMOVE64 [DF DD])
407 (define_mode_iterator FMOVE64X [DI DF DD])
408 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
409 (IF "FLOAT128_IBM_P (IFmode)")
410 (TD "TARGET_HARD_FLOAT")])
412 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
413 (IF "FLOAT128_2REG_P (IFmode)")
414 (TD "TARGET_HARD_FLOAT")])
416 ; Iterators for 128 bit types for direct move
417 (define_mode_iterator FMOVE128_GPR [TI
425 (KF "FLOAT128_VECTOR_P (KFmode)")
426 (TF "FLOAT128_VECTOR_P (TFmode)")])
428 ; Iterator for 128-bit VSX types for pack/unpack
429 (define_mode_iterator FMOVE128_VSX [V1TI KF])
431 ; Whether a floating point move is ok, don't allow SD without hardware FP
432 (define_mode_attr fmove_ok [(SF "")
434 (SD "TARGET_HARD_FLOAT")
437 ; Convert REAL_VALUE to the appropriate bits
438 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
439 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
440 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
441 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
443 ; Whether 0.0 has an all-zero bit pattern
444 (define_mode_attr zero_fp [(SF "j")
453 ; Definitions for 64-bit VSX
454 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
456 ; Definitions for 64-bit direct move
457 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
459 ; Definitions for 64-bit use of altivec registers
460 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
462 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
463 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
465 ; These modes do not fit in integer registers in 32-bit mode.
466 (define_mode_iterator DIFD [DI DF DD])
468 ; Iterator for reciprocal estimate instructions
469 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
471 ; Iterator for just SF/DF
472 (define_mode_iterator SFDF [SF DF])
474 ; Like SFDF, but a different name to match conditional move where the
475 ; comparison operands may be a different mode than the input operands.
476 (define_mode_iterator SFDF2 [SF DF])
478 ; Iterator for 128-bit floating point that uses the IBM double-double format
479 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
480 (TF "FLOAT128_IBM_P (TFmode)")])
482 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
483 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
484 (TF "FLOAT128_IEEE_P (TFmode)")])
486 ; Iterator for 128-bit floating point
487 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
488 (IF "TARGET_FLOAT128_TYPE")
489 (TF "TARGET_LONG_DOUBLE_128")])
491 ; Iterator for signbit on 64-bit machines with direct move
492 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
493 (TF "FLOAT128_VECTOR_P (TFmode)")])
495 ; Iterator for ISA 3.0 supported floating point types
496 (define_mode_iterator FP_ISA3 [SF DF])
498 ; SF/DF suffix for traditional floating instructions
499 (define_mode_attr Ftrad [(SF "s") (DF "")])
501 ; SF/DF suffix for VSX instructions
502 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
504 ; SF/DF constraint for arithmetic on traditional floating point registers
505 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
507 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
508 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
509 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
511 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
513 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
514 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
515 ; instructions added in ISA 2.07 (power8)
516 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
518 ; SF/DF constraint for arithmetic on altivec registers
519 (define_mode_attr Fa [(SF "wu") (DF "wv")])
521 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
522 (define_mode_attr Fs [(SF "s") (DF "d")])
525 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
526 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
528 ; Conditional returns.
529 (define_code_iterator any_return [return simple_return])
530 (define_code_attr return_pred [(return "direct_return ()")
531 (simple_return "1")])
532 (define_code_attr return_str [(return "") (simple_return "simple_")])
535 (define_code_iterator iorxor [ior xor])
536 (define_code_iterator and_ior_xor [and ior xor])
538 ; Signed/unsigned variants of ops.
539 (define_code_iterator any_extend [sign_extend zero_extend])
540 (define_code_iterator any_fix [fix unsigned_fix])
541 (define_code_iterator any_float [float unsigned_float])
543 (define_code_attr u [(sign_extend "")
548 (define_code_attr su [(sign_extend "s")
553 (unsigned_float "u")])
555 (define_code_attr az [(sign_extend "a")
560 (unsigned_float "z")])
562 (define_code_attr uns [(fix "")
565 (unsigned_float "uns")])
567 ; Various instructions that come in SI and DI forms.
568 ; A generic w/d attribute, for things like cmpw/cmpd.
569 (define_mode_attr wd [(QI "b")
580 ;; How many bits in this mode?
581 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
584 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
586 ;; Bitmask for shift instructions
587 (define_mode_attr hH [(SI "h") (DI "H")])
589 ;; A mode twice the size of the given mode
590 (define_mode_attr dmode [(SI "di") (DI "ti")])
591 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
593 ;; Suffix for reload patterns
594 (define_mode_attr ptrsize [(SI "32bit")
597 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
598 (DI "TARGET_64BIT")])
600 (define_mode_attr mptrsize [(SI "si")
603 (define_mode_attr ptrload [(SI "lwz")
606 (define_mode_attr ptrm [(SI "m")
609 (define_mode_attr rreg [(SF "f")
616 (define_mode_attr rreg2 [(SF "f")
619 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
620 (DF "TARGET_FCFID")])
622 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
623 (DF "TARGET_DOUBLE_FLOAT")])
625 ;; Mode iterator for logical operations on 128-bit types
626 (define_mode_iterator BOOL_128 [TI
628 (V16QI "TARGET_ALTIVEC")
629 (V8HI "TARGET_ALTIVEC")
630 (V4SI "TARGET_ALTIVEC")
631 (V4SF "TARGET_ALTIVEC")
632 (V2DI "TARGET_ALTIVEC")
633 (V2DF "TARGET_ALTIVEC")
634 (V1TI "TARGET_ALTIVEC")])
636 ;; For the GPRs we use 3 constraints for register outputs, two that are the
637 ;; same as the output register, and a third where the output register is an
638 ;; early clobber, so we don't have to deal with register overlaps. For the
639 ;; vector types, we prefer to use the vector registers. For TI mode, allow
642 ;; Mode attribute for boolean operation register constraints for output
643 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
645 (V16QI "wa,v,&?r,?r,?r")
646 (V8HI "wa,v,&?r,?r,?r")
647 (V4SI "wa,v,&?r,?r,?r")
648 (V4SF "wa,v,&?r,?r,?r")
649 (V2DI "wa,v,&?r,?r,?r")
650 (V2DF "wa,v,&?r,?r,?r")
651 (V1TI "wa,v,&?r,?r,?r")])
653 ;; Mode attribute for boolean operation register constraints for operand1
654 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
662 (V1TI "wa,v,r,0,r")])
664 ;; Mode attribute for boolean operation register constraints for operand2
665 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
673 (V1TI "wa,v,r,r,0")])
675 ;; Mode attribute for boolean operation register constraints for operand1
676 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
677 ;; is used for operand1 or operand2
678 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
686 (V1TI "wa,v,r,0,0")])
688 ;; Reload iterator for creating the function to allocate a base register to
689 ;; supplement addressing modes.
690 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
691 SF SD SI DF DD DI TI PTI KF IF TF])
693 ;; Iterate over smin, smax
694 (define_code_iterator fp_minmax [smin smax])
696 (define_code_attr minmax [(smin "min")
699 (define_code_attr SMINMAX [(smin "SMIN")
702 ;; Iterator to optimize the following cases:
703 ;; D-form load to FPR register & move to Altivec register
704 ;; Move Altivec register to FPR register and store
705 (define_mode_iterator ALTIVEC_DFORM [DF
706 (SF "TARGET_P8_VECTOR")
707 (DI "TARGET_POWERPC64")])
710 ;; Start with fixed-point load and store insns. Here we put only the more
711 ;; complex forms. Basic data transfer is done later.
713 (define_insn "zero_extendqi<mode>2"
714 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
715 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
722 [(set_attr "type" "load,shift,fpload,vecperm")])
724 (define_insn_and_split "*zero_extendqi<mode>2_dot"
725 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
726 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
728 (clobber (match_scratch:EXTQI 0 "=r,r"))]
733 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
735 (zero_extend:EXTQI (match_dup 1)))
737 (compare:CC (match_dup 0)
740 [(set_attr "type" "logical")
741 (set_attr "dot" "yes")
742 (set_attr "length" "4,8")])
744 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
745 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
746 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
748 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
749 (zero_extend:EXTQI (match_dup 1)))]
754 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
756 (zero_extend:EXTQI (match_dup 1)))
758 (compare:CC (match_dup 0)
761 [(set_attr "type" "logical")
762 (set_attr "dot" "yes")
763 (set_attr "length" "4,8")])
766 (define_insn "zero_extendhi<mode>2"
767 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
768 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
772 rlwinm %0,%1,0,0xffff
775 [(set_attr "type" "load,shift,fpload,vecperm")])
777 (define_insn_and_split "*zero_extendhi<mode>2_dot"
778 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
779 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
781 (clobber (match_scratch:EXTHI 0 "=r,r"))]
786 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
788 (zero_extend:EXTHI (match_dup 1)))
790 (compare:CC (match_dup 0)
793 [(set_attr "type" "logical")
794 (set_attr "dot" "yes")
795 (set_attr "length" "4,8")])
797 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
798 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
799 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
801 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
802 (zero_extend:EXTHI (match_dup 1)))]
807 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
809 (zero_extend:EXTHI (match_dup 1)))
811 (compare:CC (match_dup 0)
814 [(set_attr "type" "logical")
815 (set_attr "dot" "yes")
816 (set_attr "length" "4,8")])
819 (define_insn "zero_extendsi<mode>2"
820 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
821 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
830 xxextractuw %x0,%x1,4"
831 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
833 (define_insn_and_split "*zero_extendsi<mode>2_dot"
834 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
835 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
837 (clobber (match_scratch:EXTSI 0 "=r,r"))]
842 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
844 (zero_extend:DI (match_dup 1)))
846 (compare:CC (match_dup 0)
849 [(set_attr "type" "shift")
850 (set_attr "dot" "yes")
851 (set_attr "length" "4,8")])
853 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
854 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
855 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
857 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
858 (zero_extend:EXTSI (match_dup 1)))]
863 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
865 (zero_extend:EXTSI (match_dup 1)))
867 (compare:CC (match_dup 0)
870 [(set_attr "type" "shift")
871 (set_attr "dot" "yes")
872 (set_attr "length" "4,8")])
875 (define_insn "extendqi<mode>2"
876 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
877 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
882 [(set_attr "type" "exts,vecperm")])
884 (define_insn_and_split "*extendqi<mode>2_dot"
885 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
886 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
888 (clobber (match_scratch:EXTQI 0 "=r,r"))]
893 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
895 (sign_extend:EXTQI (match_dup 1)))
897 (compare:CC (match_dup 0)
900 [(set_attr "type" "exts")
901 (set_attr "dot" "yes")
902 (set_attr "length" "4,8")])
904 (define_insn_and_split "*extendqi<mode>2_dot2"
905 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
906 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
908 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
909 (sign_extend:EXTQI (match_dup 1)))]
914 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
916 (sign_extend:EXTQI (match_dup 1)))
918 (compare:CC (match_dup 0)
921 [(set_attr "type" "exts")
922 (set_attr "dot" "yes")
923 (set_attr "length" "4,8")])
926 (define_expand "extendhi<mode>2"
927 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
928 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
932 (define_insn "*extendhi<mode>2"
933 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
934 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
941 [(set_attr "type" "load,exts,fpload,vecperm")
942 (set_attr "sign_extend" "yes")
943 (set_attr "length" "4,4,8,4")])
946 [(set (match_operand:EXTHI 0 "altivec_register_operand")
948 (match_operand:HI 1 "indexed_or_indirect_operand")))]
949 "TARGET_P9_VECTOR && reload_completed"
953 (sign_extend:EXTHI (match_dup 2)))]
955 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
958 (define_insn_and_split "*extendhi<mode>2_dot"
959 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
960 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
962 (clobber (match_scratch:EXTHI 0 "=r,r"))]
967 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
969 (sign_extend:EXTHI (match_dup 1)))
971 (compare:CC (match_dup 0)
974 [(set_attr "type" "exts")
975 (set_attr "dot" "yes")
976 (set_attr "length" "4,8")])
978 (define_insn_and_split "*extendhi<mode>2_dot2"
979 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
980 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
982 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
983 (sign_extend:EXTHI (match_dup 1)))]
988 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
990 (sign_extend:EXTHI (match_dup 1)))
992 (compare:CC (match_dup 0)
995 [(set_attr "type" "exts")
996 (set_attr "dot" "yes")
997 (set_attr "length" "4,8")])
1000 (define_insn "extendsi<mode>2"
1001 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1002 "=r, r, wl, wu, wj, wK, wH, wr")
1004 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1005 "Y, r, Z, Z, r, wK, wH, ?wIwH")))]
1016 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1017 (set_attr "sign_extend" "yes")
1018 (set_attr "length" "4,4,4,4,4,4,8,8")])
1021 [(set (match_operand:EXTSI 0 "int_reg_operand")
1022 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1023 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1027 (sign_extend:DI (match_dup 2)))]
1029 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1033 [(set (match_operand:DI 0 "altivec_register_operand")
1034 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1035 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1038 rtx dest = operands[0];
1039 rtx src = operands[1];
1040 int dest_regno = REGNO (dest);
1041 int src_regno = REGNO (src);
1042 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1043 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1045 if (VECTOR_ELT_ORDER_BIG)
1047 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1048 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1052 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1053 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1058 (define_insn_and_split "*extendsi<mode>2_dot"
1059 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1060 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1062 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1067 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1069 (sign_extend:EXTSI (match_dup 1)))
1071 (compare:CC (match_dup 0)
1074 [(set_attr "type" "exts")
1075 (set_attr "dot" "yes")
1076 (set_attr "length" "4,8")])
1078 (define_insn_and_split "*extendsi<mode>2_dot2"
1079 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1080 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1082 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1083 (sign_extend:EXTSI (match_dup 1)))]
1088 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1090 (sign_extend:EXTSI (match_dup 1)))
1092 (compare:CC (match_dup 0)
1095 [(set_attr "type" "exts")
1096 (set_attr "dot" "yes")
1097 (set_attr "length" "4,8")])
1099 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1101 (define_insn "*macchwc"
1102 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1103 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1104 (match_operand:SI 2 "gpc_reg_operand" "r")
1107 (match_operand:HI 1 "gpc_reg_operand" "r")))
1108 (match_operand:SI 4 "gpc_reg_operand" "0"))
1110 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1111 (plus:SI (mult:SI (ashiftrt:SI
1119 [(set_attr "type" "halfmul")])
1121 (define_insn "*macchw"
1122 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1123 (plus:SI (mult:SI (ashiftrt:SI
1124 (match_operand:SI 2 "gpc_reg_operand" "r")
1127 (match_operand:HI 1 "gpc_reg_operand" "r")))
1128 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1131 [(set_attr "type" "halfmul")])
1133 (define_insn "*macchwuc"
1134 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1135 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1136 (match_operand:SI 2 "gpc_reg_operand" "r")
1139 (match_operand:HI 1 "gpc_reg_operand" "r")))
1140 (match_operand:SI 4 "gpc_reg_operand" "0"))
1142 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1143 (plus:SI (mult:SI (lshiftrt:SI
1151 [(set_attr "type" "halfmul")])
1153 (define_insn "*macchwu"
1154 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1155 (plus:SI (mult:SI (lshiftrt:SI
1156 (match_operand:SI 2 "gpc_reg_operand" "r")
1159 (match_operand:HI 1 "gpc_reg_operand" "r")))
1160 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1163 [(set_attr "type" "halfmul")])
1165 (define_insn "*machhwc"
1166 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1167 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1168 (match_operand:SI 1 "gpc_reg_operand" "%r")
1171 (match_operand:SI 2 "gpc_reg_operand" "r")
1173 (match_operand:SI 4 "gpc_reg_operand" "0"))
1175 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1176 (plus:SI (mult:SI (ashiftrt:SI
1185 [(set_attr "type" "halfmul")])
1187 (define_insn "*machhw"
1188 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1189 (plus:SI (mult:SI (ashiftrt:SI
1190 (match_operand:SI 1 "gpc_reg_operand" "%r")
1193 (match_operand:SI 2 "gpc_reg_operand" "r")
1195 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1198 [(set_attr "type" "halfmul")])
1200 (define_insn "*machhwuc"
1201 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1202 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1203 (match_operand:SI 1 "gpc_reg_operand" "%r")
1206 (match_operand:SI 2 "gpc_reg_operand" "r")
1208 (match_operand:SI 4 "gpc_reg_operand" "0"))
1210 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1211 (plus:SI (mult:SI (lshiftrt:SI
1220 [(set_attr "type" "halfmul")])
1222 (define_insn "*machhwu"
1223 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1224 (plus:SI (mult:SI (lshiftrt:SI
1225 (match_operand:SI 1 "gpc_reg_operand" "%r")
1228 (match_operand:SI 2 "gpc_reg_operand" "r")
1230 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1233 [(set_attr "type" "halfmul")])
1235 (define_insn "*maclhwc"
1236 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1237 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1238 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1240 (match_operand:HI 2 "gpc_reg_operand" "r")))
1241 (match_operand:SI 4 "gpc_reg_operand" "0"))
1243 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1244 (plus:SI (mult:SI (sign_extend:SI
1251 [(set_attr "type" "halfmul")])
1253 (define_insn "*maclhw"
1254 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1255 (plus:SI (mult:SI (sign_extend:SI
1256 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1258 (match_operand:HI 2 "gpc_reg_operand" "r")))
1259 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1262 [(set_attr "type" "halfmul")])
1264 (define_insn "*maclhwuc"
1265 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1266 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1267 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1269 (match_operand:HI 2 "gpc_reg_operand" "r")))
1270 (match_operand:SI 4 "gpc_reg_operand" "0"))
1272 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1273 (plus:SI (mult:SI (zero_extend:SI
1280 [(set_attr "type" "halfmul")])
1282 (define_insn "*maclhwu"
1283 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1284 (plus:SI (mult:SI (zero_extend:SI
1285 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1287 (match_operand:HI 2 "gpc_reg_operand" "r")))
1288 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1291 [(set_attr "type" "halfmul")])
1293 (define_insn "*nmacchwc"
1294 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1295 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1296 (mult:SI (ashiftrt:SI
1297 (match_operand:SI 2 "gpc_reg_operand" "r")
1300 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1302 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1303 (minus:SI (match_dup 4)
1304 (mult:SI (ashiftrt:SI
1311 [(set_attr "type" "halfmul")])
1313 (define_insn "*nmacchw"
1314 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1315 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1316 (mult:SI (ashiftrt:SI
1317 (match_operand:SI 2 "gpc_reg_operand" "r")
1320 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1323 [(set_attr "type" "halfmul")])
1325 (define_insn "*nmachhwc"
1326 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1327 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1328 (mult:SI (ashiftrt:SI
1329 (match_operand:SI 1 "gpc_reg_operand" "%r")
1332 (match_operand:SI 2 "gpc_reg_operand" "r")
1335 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1336 (minus:SI (match_dup 4)
1337 (mult:SI (ashiftrt:SI
1345 [(set_attr "type" "halfmul")])
1347 (define_insn "*nmachhw"
1348 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1349 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1350 (mult:SI (ashiftrt:SI
1351 (match_operand:SI 1 "gpc_reg_operand" "%r")
1354 (match_operand:SI 2 "gpc_reg_operand" "r")
1358 [(set_attr "type" "halfmul")])
1360 (define_insn "*nmaclhwc"
1361 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1362 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1363 (mult:SI (sign_extend:SI
1364 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1366 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1368 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1369 (minus:SI (match_dup 4)
1370 (mult:SI (sign_extend:SI
1376 [(set_attr "type" "halfmul")])
1378 (define_insn "*nmaclhw"
1379 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1380 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1381 (mult:SI (sign_extend:SI
1382 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1384 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1387 [(set_attr "type" "halfmul")])
1389 (define_insn "*mulchwc"
1390 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1391 (compare:CC (mult:SI (ashiftrt:SI
1392 (match_operand:SI 2 "gpc_reg_operand" "r")
1395 (match_operand:HI 1 "gpc_reg_operand" "r")))
1397 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1398 (mult:SI (ashiftrt:SI
1405 [(set_attr "type" "halfmul")])
1407 (define_insn "*mulchw"
1408 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1409 (mult:SI (ashiftrt:SI
1410 (match_operand:SI 2 "gpc_reg_operand" "r")
1413 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1416 [(set_attr "type" "halfmul")])
1418 (define_insn "*mulchwuc"
1419 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1420 (compare:CC (mult:SI (lshiftrt:SI
1421 (match_operand:SI 2 "gpc_reg_operand" "r")
1424 (match_operand:HI 1 "gpc_reg_operand" "r")))
1426 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1427 (mult:SI (lshiftrt:SI
1434 [(set_attr "type" "halfmul")])
1436 (define_insn "*mulchwu"
1437 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1438 (mult:SI (lshiftrt:SI
1439 (match_operand:SI 2 "gpc_reg_operand" "r")
1442 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1445 [(set_attr "type" "halfmul")])
1447 (define_insn "*mulhhwc"
1448 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1449 (compare:CC (mult:SI (ashiftrt:SI
1450 (match_operand:SI 1 "gpc_reg_operand" "%r")
1453 (match_operand:SI 2 "gpc_reg_operand" "r")
1456 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1457 (mult:SI (ashiftrt:SI
1465 [(set_attr "type" "halfmul")])
1467 (define_insn "*mulhhw"
1468 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1469 (mult:SI (ashiftrt:SI
1470 (match_operand:SI 1 "gpc_reg_operand" "%r")
1473 (match_operand:SI 2 "gpc_reg_operand" "r")
1477 [(set_attr "type" "halfmul")])
1479 (define_insn "*mulhhwuc"
1480 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1481 (compare:CC (mult:SI (lshiftrt:SI
1482 (match_operand:SI 1 "gpc_reg_operand" "%r")
1485 (match_operand:SI 2 "gpc_reg_operand" "r")
1488 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1489 (mult:SI (lshiftrt:SI
1497 [(set_attr "type" "halfmul")])
1499 (define_insn "*mulhhwu"
1500 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1501 (mult:SI (lshiftrt:SI
1502 (match_operand:SI 1 "gpc_reg_operand" "%r")
1505 (match_operand:SI 2 "gpc_reg_operand" "r")
1509 [(set_attr "type" "halfmul")])
1511 (define_insn "*mullhwc"
1512 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1513 (compare:CC (mult:SI (sign_extend:SI
1514 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1516 (match_operand:HI 2 "gpc_reg_operand" "r")))
1518 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1519 (mult:SI (sign_extend:SI
1525 [(set_attr "type" "halfmul")])
1527 (define_insn "*mullhw"
1528 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1529 (mult:SI (sign_extend:SI
1530 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1532 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1535 [(set_attr "type" "halfmul")])
1537 (define_insn "*mullhwuc"
1538 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1539 (compare:CC (mult:SI (zero_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 (zero_extend:SI
1551 [(set_attr "type" "halfmul")])
1553 (define_insn "*mullhwu"
1554 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1555 (mult:SI (zero_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 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1564 (define_insn "dlmzb"
1565 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1566 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1567 (match_operand:SI 2 "gpc_reg_operand" "r")]
1569 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1570 (unspec:SI [(match_dup 1)
1576 (define_expand "strlensi"
1577 [(set (match_operand:SI 0 "gpc_reg_operand")
1578 (unspec:SI [(match_operand:BLK 1 "general_operand")
1579 (match_operand:QI 2 "const_int_operand")
1580 (match_operand 3 "const_int_operand")]
1581 UNSPEC_DLMZB_STRLEN))
1582 (clobber (match_scratch:CC 4))]
1583 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1585 rtx result = operands[0];
1586 rtx src = operands[1];
1587 rtx search_char = operands[2];
1588 rtx align = operands[3];
1589 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1590 rtx loop_label, end_label, mem, cr0, cond;
1591 if (search_char != const0_rtx
1592 || GET_CODE (align) != CONST_INT
1593 || INTVAL (align) < 8)
1595 word1 = gen_reg_rtx (SImode);
1596 word2 = gen_reg_rtx (SImode);
1597 scratch_dlmzb = gen_reg_rtx (SImode);
1598 scratch_string = gen_reg_rtx (Pmode);
1599 loop_label = gen_label_rtx ();
1600 end_label = gen_label_rtx ();
1601 addr = force_reg (Pmode, XEXP (src, 0));
1602 emit_move_insn (scratch_string, addr);
1603 emit_label (loop_label);
1604 mem = change_address (src, SImode, scratch_string);
1605 emit_move_insn (word1, mem);
1606 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1607 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1608 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1609 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1610 emit_jump_insn (gen_rtx_SET (pc_rtx,
1611 gen_rtx_IF_THEN_ELSE (VOIDmode,
1617 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1618 emit_jump_insn (gen_rtx_SET (pc_rtx,
1619 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1621 emit_label (end_label);
1622 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1623 emit_insn (gen_subsi3 (result, scratch_string, addr));
1624 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1628 ;; Fixed-point arithmetic insns.
1630 (define_expand "add<mode>3"
1631 [(set (match_operand:SDI 0 "gpc_reg_operand")
1632 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand")
1633 (match_operand:SDI 2 "reg_or_add_cint_operand")))]
1636 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1638 rtx lo0 = gen_lowpart (SImode, operands[0]);
1639 rtx lo1 = gen_lowpart (SImode, operands[1]);
1640 rtx lo2 = gen_lowpart (SImode, operands[2]);
1641 rtx hi0 = gen_highpart (SImode, operands[0]);
1642 rtx hi1 = gen_highpart (SImode, operands[1]);
1643 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1645 if (!reg_or_short_operand (lo2, SImode))
1646 lo2 = force_reg (SImode, lo2);
1647 if (!adde_operand (hi2, SImode))
1648 hi2 = force_reg (SImode, hi2);
1650 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1651 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1655 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1657 rtx tmp = ((!can_create_pseudo_p ()
1658 || rtx_equal_p (operands[0], operands[1]))
1659 ? operands[0] : gen_reg_rtx (<MODE>mode));
1661 /* Adding a constant to r0 is not a valid insn, so use a different
1662 strategy in that case. */
1663 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1665 if (operands[0] == operands[1])
1667 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1668 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1672 HOST_WIDE_INT val = INTVAL (operands[2]);
1673 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1674 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1676 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1679 /* The ordering here is important for the prolog expander.
1680 When space is allocated from the stack, adding 'low' first may
1681 produce a temporary deallocation (which would be bad). */
1682 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1683 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1688 (define_insn "*add<mode>3"
1689 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1690 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1691 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1697 [(set_attr "type" "add")])
1699 (define_insn "addsi3_high"
1700 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1701 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1702 (high:SI (match_operand 2 "" ""))))]
1703 "TARGET_MACHO && !TARGET_64BIT"
1704 "addis %0,%1,ha16(%2)"
1705 [(set_attr "type" "add")])
1707 (define_insn_and_split "*add<mode>3_dot"
1708 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1709 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1710 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1712 (clobber (match_scratch:GPR 0 "=r,r"))]
1713 "<MODE>mode == Pmode"
1717 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1719 (plus:GPR (match_dup 1)
1722 (compare:CC (match_dup 0)
1725 [(set_attr "type" "add")
1726 (set_attr "dot" "yes")
1727 (set_attr "length" "4,8")])
1729 (define_insn_and_split "*add<mode>3_dot2"
1730 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1731 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1732 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1734 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1735 (plus:GPR (match_dup 1)
1737 "<MODE>mode == Pmode"
1741 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1743 (plus:GPR (match_dup 1)
1746 (compare:CC (match_dup 0)
1749 [(set_attr "type" "add")
1750 (set_attr "dot" "yes")
1751 (set_attr "length" "4,8")])
1753 (define_insn_and_split "*add<mode>3_imm_dot"
1754 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1755 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1756 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1758 (clobber (match_scratch:GPR 0 "=r,r"))
1759 (clobber (reg:GPR CA_REGNO))]
1760 "<MODE>mode == Pmode"
1764 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1766 (plus:GPR (match_dup 1)
1769 (compare:CC (match_dup 0)
1772 [(set_attr "type" "add")
1773 (set_attr "dot" "yes")
1774 (set_attr "length" "4,8")])
1776 (define_insn_and_split "*add<mode>3_imm_dot2"
1777 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1778 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1779 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1781 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1782 (plus:GPR (match_dup 1)
1784 (clobber (reg:GPR CA_REGNO))]
1785 "<MODE>mode == Pmode"
1789 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1791 (plus:GPR (match_dup 1)
1794 (compare:CC (match_dup 0)
1797 [(set_attr "type" "add")
1798 (set_attr "dot" "yes")
1799 (set_attr "length" "4,8")])
1801 ;; Split an add that we can't do in one insn into two insns, each of which
1802 ;; does one 16-bit part. This is used by combine. Note that the low-order
1803 ;; add should be last in case the result gets used in an address.
1806 [(set (match_operand:GPR 0 "gpc_reg_operand")
1807 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1808 (match_operand:GPR 2 "non_add_cint_operand")))]
1810 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1811 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1813 HOST_WIDE_INT val = INTVAL (operands[2]);
1814 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1815 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1817 operands[4] = GEN_INT (low);
1818 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1819 operands[3] = GEN_INT (rest);
1820 else if (can_create_pseudo_p ())
1822 operands[3] = gen_reg_rtx (DImode);
1823 emit_move_insn (operands[3], operands[2]);
1824 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1832 (define_insn "add<mode>3_carry"
1833 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1834 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1835 (match_operand:P 2 "reg_or_short_operand" "rI")))
1836 (set (reg:P CA_REGNO)
1837 (ltu:P (plus:P (match_dup 1)
1842 [(set_attr "type" "add")])
1844 (define_insn "*add<mode>3_imm_carry_pos"
1845 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1846 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1847 (match_operand:P 2 "short_cint_operand" "n")))
1848 (set (reg:P CA_REGNO)
1849 (geu:P (match_dup 1)
1850 (match_operand:P 3 "const_int_operand" "n")))]
1851 "INTVAL (operands[2]) > 0
1852 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1854 [(set_attr "type" "add")])
1856 (define_insn "*add<mode>3_imm_carry_0"
1857 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1858 (match_operand:P 1 "gpc_reg_operand" "r"))
1859 (set (reg:P CA_REGNO)
1863 [(set_attr "type" "add")])
1865 (define_insn "*add<mode>3_imm_carry_m1"
1866 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1867 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1869 (set (reg:P CA_REGNO)
1874 [(set_attr "type" "add")])
1876 (define_insn "*add<mode>3_imm_carry_neg"
1877 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1878 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1879 (match_operand:P 2 "short_cint_operand" "n")))
1880 (set (reg:P CA_REGNO)
1881 (gtu:P (match_dup 1)
1882 (match_operand:P 3 "const_int_operand" "n")))]
1883 "INTVAL (operands[2]) < 0
1884 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1886 [(set_attr "type" "add")])
1889 (define_expand "add<mode>3_carry_in"
1891 (set (match_operand:GPR 0 "gpc_reg_operand")
1892 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1893 (match_operand:GPR 2 "adde_operand"))
1894 (reg:GPR CA_REGNO)))
1895 (clobber (reg:GPR CA_REGNO))])]
1898 if (operands[2] == const0_rtx)
1900 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1903 if (operands[2] == constm1_rtx)
1905 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1910 (define_insn "*add<mode>3_carry_in_internal"
1911 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1912 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1913 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1914 (reg:GPR CA_REGNO)))
1915 (clobber (reg:GPR CA_REGNO))]
1918 [(set_attr "type" "add")])
1920 (define_insn "*add<mode>3_carry_in_internal2"
1921 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1922 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1924 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1925 (clobber (reg:GPR CA_REGNO))]
1928 [(set_attr "type" "add")])
1930 (define_insn "add<mode>3_carry_in_0"
1931 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1932 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1933 (reg:GPR CA_REGNO)))
1934 (clobber (reg:GPR CA_REGNO))]
1937 [(set_attr "type" "add")])
1939 (define_insn "add<mode>3_carry_in_m1"
1940 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1941 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1944 (clobber (reg:GPR CA_REGNO))]
1947 [(set_attr "type" "add")])
1950 (define_expand "one_cmpl<mode>2"
1951 [(set (match_operand:SDI 0 "gpc_reg_operand")
1952 (not:SDI (match_operand:SDI 1 "gpc_reg_operand")))]
1955 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1957 rs6000_split_logical (operands, NOT, false, false, false);
1962 (define_insn "*one_cmpl<mode>2"
1963 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1964 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1968 (define_insn_and_split "*one_cmpl<mode>2_dot"
1969 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1970 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1972 (clobber (match_scratch:GPR 0 "=r,r"))]
1973 "<MODE>mode == Pmode"
1977 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1979 (not:GPR (match_dup 1)))
1981 (compare:CC (match_dup 0)
1984 [(set_attr "type" "logical")
1985 (set_attr "dot" "yes")
1986 (set_attr "length" "4,8")])
1988 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1989 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1990 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1992 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1993 (not:GPR (match_dup 1)))]
1994 "<MODE>mode == Pmode"
1998 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2000 (not:GPR (match_dup 1)))
2002 (compare:CC (match_dup 0)
2005 [(set_attr "type" "logical")
2006 (set_attr "dot" "yes")
2007 (set_attr "length" "4,8")])
2010 (define_expand "sub<mode>3"
2011 [(set (match_operand:SDI 0 "gpc_reg_operand")
2012 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand")
2013 (match_operand:SDI 2 "gpc_reg_operand")))]
2016 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2018 rtx lo0 = gen_lowpart (SImode, operands[0]);
2019 rtx lo1 = gen_lowpart (SImode, operands[1]);
2020 rtx lo2 = gen_lowpart (SImode, operands[2]);
2021 rtx hi0 = gen_highpart (SImode, operands[0]);
2022 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2023 rtx hi2 = gen_highpart (SImode, operands[2]);
2025 if (!reg_or_short_operand (lo1, SImode))
2026 lo1 = force_reg (SImode, lo1);
2027 if (!adde_operand (hi1, SImode))
2028 hi1 = force_reg (SImode, hi1);
2030 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2031 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2035 if (short_cint_operand (operands[1], <MODE>mode))
2037 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2042 (define_insn "*subf<mode>3"
2043 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2044 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2045 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2048 [(set_attr "type" "add")])
2050 (define_insn_and_split "*subf<mode>3_dot"
2051 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2052 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2053 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2055 (clobber (match_scratch:GPR 0 "=r,r"))]
2056 "<MODE>mode == Pmode"
2060 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2062 (minus:GPR (match_dup 2)
2065 (compare:CC (match_dup 0)
2068 [(set_attr "type" "add")
2069 (set_attr "dot" "yes")
2070 (set_attr "length" "4,8")])
2072 (define_insn_and_split "*subf<mode>3_dot2"
2073 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2074 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2075 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2077 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2078 (minus:GPR (match_dup 2)
2080 "<MODE>mode == Pmode"
2084 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2086 (minus:GPR (match_dup 2)
2089 (compare:CC (match_dup 0)
2092 [(set_attr "type" "add")
2093 (set_attr "dot" "yes")
2094 (set_attr "length" "4,8")])
2096 (define_insn "subf<mode>3_imm"
2097 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2098 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2099 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2100 (clobber (reg:GPR CA_REGNO))]
2103 [(set_attr "type" "add")])
2105 (define_insn_and_split "subf<mode>3_carry_dot2"
2106 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2107 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2108 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2110 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2111 (minus:P (match_dup 2)
2113 (set (reg:P CA_REGNO)
2114 (leu:P (match_dup 1)
2116 "<MODE>mode == Pmode"
2120 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2121 [(parallel [(set (match_dup 0)
2122 (minus:P (match_dup 2)
2124 (set (reg:P CA_REGNO)
2125 (leu:P (match_dup 1)
2128 (compare:CC (match_dup 0)
2131 [(set_attr "type" "add")
2132 (set_attr "dot" "yes")
2133 (set_attr "length" "4,8")])
2135 (define_insn "subf<mode>3_carry"
2136 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2137 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2138 (match_operand:P 1 "gpc_reg_operand" "r")))
2139 (set (reg:P CA_REGNO)
2140 (leu:P (match_dup 1)
2144 [(set_attr "type" "add")])
2146 (define_insn "*subf<mode>3_imm_carry_0"
2147 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2148 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2149 (set (reg:P CA_REGNO)
2154 [(set_attr "type" "add")])
2156 (define_insn "*subf<mode>3_imm_carry_m1"
2157 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2158 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2159 (set (reg:P CA_REGNO)
2163 [(set_attr "type" "add")])
2166 (define_expand "subf<mode>3_carry_in"
2168 (set (match_operand:GPR 0 "gpc_reg_operand")
2169 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2171 (match_operand:GPR 2 "adde_operand")))
2172 (clobber (reg:GPR CA_REGNO))])]
2175 if (operands[2] == const0_rtx)
2177 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2180 if (operands[2] == constm1_rtx)
2182 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2187 (define_insn "*subf<mode>3_carry_in_internal"
2188 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2189 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2191 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2192 (clobber (reg:GPR CA_REGNO))]
2195 [(set_attr "type" "add")])
2197 (define_insn "subf<mode>3_carry_in_0"
2198 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2199 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2200 (reg:GPR CA_REGNO)))
2201 (clobber (reg:GPR CA_REGNO))]
2204 [(set_attr "type" "add")])
2206 (define_insn "subf<mode>3_carry_in_m1"
2207 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2208 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2209 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2211 (clobber (reg:GPR CA_REGNO))]
2214 [(set_attr "type" "add")])
2216 (define_insn "subf<mode>3_carry_in_xx"
2217 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2218 (plus:GPR (reg:GPR CA_REGNO)
2220 (clobber (reg:GPR CA_REGNO))]
2223 [(set_attr "type" "add")])
2226 (define_insn "neg<mode>2"
2227 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2228 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2231 [(set_attr "type" "add")])
2233 (define_insn_and_split "*neg<mode>2_dot"
2234 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2235 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2237 (clobber (match_scratch:GPR 0 "=r,r"))]
2238 "<MODE>mode == Pmode"
2242 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2244 (neg:GPR (match_dup 1)))
2246 (compare:CC (match_dup 0)
2249 [(set_attr "type" "add")
2250 (set_attr "dot" "yes")
2251 (set_attr "length" "4,8")])
2253 (define_insn_and_split "*neg<mode>2_dot2"
2254 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2255 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2257 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2258 (neg:GPR (match_dup 1)))]
2259 "<MODE>mode == Pmode"
2263 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2265 (neg:GPR (match_dup 1)))
2267 (compare:CC (match_dup 0)
2270 [(set_attr "type" "add")
2271 (set_attr "dot" "yes")
2272 (set_attr "length" "4,8")])
2275 (define_insn "clz<mode>2"
2276 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2277 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2280 [(set_attr "type" "cntlz")])
2282 (define_expand "ctz<mode>2"
2283 [(set (match_operand:GPR 0 "gpc_reg_operand")
2284 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2289 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2293 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2294 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2295 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2299 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2300 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2301 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2302 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2306 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2307 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2308 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2309 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2315 (define_insn "ctz<mode>2_hw"
2316 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2317 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2320 [(set_attr "type" "cntlz")])
2322 (define_expand "ffs<mode>2"
2323 [(set (match_operand:GPR 0 "gpc_reg_operand")
2324 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2327 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2328 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2329 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2330 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2331 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2332 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2333 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2338 (define_expand "popcount<mode>2"
2339 [(set (match_operand:GPR 0 "gpc_reg_operand")
2340 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2341 "TARGET_POPCNTB || TARGET_POPCNTD"
2343 rs6000_emit_popcount (operands[0], operands[1]);
2347 (define_insn "popcntb<mode>2"
2348 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2349 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2353 [(set_attr "type" "popcnt")])
2355 (define_insn "popcntd<mode>2"
2356 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2357 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2360 [(set_attr "type" "popcnt")])
2363 (define_expand "parity<mode>2"
2364 [(set (match_operand:GPR 0 "gpc_reg_operand")
2365 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2368 rs6000_emit_parity (operands[0], operands[1]);
2372 (define_insn "parity<mode>2_cmpb"
2373 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2374 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2375 "TARGET_CMPB && TARGET_POPCNTB"
2377 [(set_attr "type" "popcnt")])
2379 (define_insn "cmpb<mode>3"
2380 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2381 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2382 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2385 [(set_attr "type" "cmp")])
2387 ;; Since the hardware zeros the upper part of the register, save generating the
2388 ;; AND immediate if we are converting to unsigned
2389 (define_insn "*bswap<mode>2_extenddi"
2390 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2392 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2395 [(set_attr "length" "4")
2396 (set_attr "type" "load")])
2398 (define_insn "*bswaphi2_extendsi"
2399 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2401 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2404 [(set_attr "length" "4")
2405 (set_attr "type" "load")])
2407 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2408 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2409 ;; load with byte swap, which can be slower than doing it in the registers. It
2410 ;; also prevents certain failures with the RELOAD register allocator.
2412 (define_expand "bswap<mode>2"
2413 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2414 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2417 rtx dest = operands[0];
2418 rtx src = operands[1];
2420 if (!REG_P (dest) && !REG_P (src))
2421 src = force_reg (<MODE>mode, src);
2424 emit_insn (gen_bswap<mode>2_load (dest, src));
2425 else if (MEM_P (dest))
2426 emit_insn (gen_bswap<mode>2_store (dest, src));
2428 emit_insn (gen_bswap<mode>2_reg (dest, src));
2432 (define_insn "bswap<mode>2_load"
2433 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2434 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2437 [(set_attr "type" "load")])
2439 (define_insn "bswap<mode>2_store"
2440 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2441 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2444 [(set_attr "type" "store")])
2446 (define_insn_and_split "bswaphi2_reg"
2447 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2449 (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2450 (clobber (match_scratch:SI 2 "=&r,X"))]
2455 "reload_completed && int_reg_operand (operands[0], HImode)"
2457 (and:SI (lshiftrt:SI (match_dup 4)
2461 (and:SI (ashift:SI (match_dup 4)
2463 (const_int 65280))) ;; 0xff00
2465 (ior:SI (match_dup 3)
2468 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2469 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2471 [(set_attr "length" "12,4")
2472 (set_attr "type" "*,vecperm")])
2474 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2475 ;; zero_extract insns do not change for -mlittle.
2476 (define_insn_and_split "bswapsi2_reg"
2477 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2479 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2484 "reload_completed && int_reg_operand (operands[0], SImode)"
2485 [(set (match_dup 0) ; DABC
2486 (rotate:SI (match_dup 1)
2488 (set (match_dup 0) ; DCBC
2489 (ior:SI (and:SI (ashift:SI (match_dup 1)
2491 (const_int 16711680))
2492 (and:SI (match_dup 0)
2493 (const_int -16711681))))
2494 (set (match_dup 0) ; DCBA
2495 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2498 (and:SI (match_dup 0)
2499 (const_int -256))))]
2501 [(set_attr "length" "12,4")
2502 (set_attr "type" "*,vecperm")])
2504 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2505 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2508 (define_expand "bswapdi2"
2509 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand")
2511 (match_operand:DI 1 "reg_or_mem_operand")))
2512 (clobber (match_scratch:DI 2))
2513 (clobber (match_scratch:DI 3))])]
2516 rtx dest = operands[0];
2517 rtx src = operands[1];
2519 if (!REG_P (dest) && !REG_P (src))
2520 operands[1] = src = force_reg (DImode, src);
2522 if (TARGET_POWERPC64 && TARGET_LDBRX)
2525 emit_insn (gen_bswapdi2_load (dest, src));
2526 else if (MEM_P (dest))
2527 emit_insn (gen_bswapdi2_store (dest, src));
2528 else if (TARGET_P9_VECTOR)
2529 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2531 emit_insn (gen_bswapdi2_reg (dest, src));
2535 if (!TARGET_POWERPC64)
2537 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2538 that uses 64-bit registers needs the same scratch registers as 64-bit
2540 emit_insn (gen_bswapdi2_32bit (dest, src));
2545 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2546 (define_insn "bswapdi2_load"
2547 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2548 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2549 "TARGET_POWERPC64 && TARGET_LDBRX"
2551 [(set_attr "type" "load")])
2553 (define_insn "bswapdi2_store"
2554 [(set (match_operand:DI 0 "memory_operand" "=Z")
2555 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2556 "TARGET_POWERPC64 && TARGET_LDBRX"
2558 [(set_attr "type" "store")])
2560 (define_insn "bswapdi2_xxbrd"
2561 [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2562 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2565 [(set_attr "type" "vecperm")])
2567 (define_insn "bswapdi2_reg"
2568 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2569 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2570 (clobber (match_scratch:DI 2 "=&r"))
2571 (clobber (match_scratch:DI 3 "=&r"))]
2572 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2574 [(set_attr "length" "36")])
2576 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2577 (define_insn "*bswapdi2_64bit"
2578 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2579 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2580 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2581 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2582 "TARGET_POWERPC64 && !TARGET_LDBRX
2583 && (REG_P (operands[0]) || REG_P (operands[1]))
2584 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2585 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2587 [(set_attr "length" "16,12,36")])
2590 [(set (match_operand:DI 0 "gpc_reg_operand")
2591 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2592 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2593 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2594 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2597 rtx dest = operands[0];
2598 rtx src = operands[1];
2599 rtx op2 = operands[2];
2600 rtx op3 = operands[3];
2601 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2602 BYTES_BIG_ENDIAN ? 4 : 0);
2603 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2604 BYTES_BIG_ENDIAN ? 4 : 0);
2610 addr1 = XEXP (src, 0);
2611 if (GET_CODE (addr1) == PLUS)
2613 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2614 if (TARGET_AVOID_XFORM)
2616 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2620 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2622 else if (TARGET_AVOID_XFORM)
2624 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2629 emit_move_insn (op2, GEN_INT (4));
2630 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2633 word1 = change_address (src, SImode, addr1);
2634 word2 = change_address (src, SImode, addr2);
2636 if (BYTES_BIG_ENDIAN)
2638 emit_insn (gen_bswapsi2 (op3_32, word2));
2639 emit_insn (gen_bswapsi2 (dest_32, word1));
2643 emit_insn (gen_bswapsi2 (op3_32, word1));
2644 emit_insn (gen_bswapsi2 (dest_32, word2));
2647 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2648 emit_insn (gen_iordi3 (dest, dest, op3));
2653 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2654 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2655 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2656 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2657 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2660 rtx dest = operands[0];
2661 rtx src = operands[1];
2662 rtx op2 = operands[2];
2663 rtx op3 = operands[3];
2664 rtx src_si = simplify_gen_subreg (SImode, src, DImode,
2665 BYTES_BIG_ENDIAN ? 4 : 0);
2666 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode,
2667 BYTES_BIG_ENDIAN ? 4 : 0);
2673 addr1 = XEXP (dest, 0);
2674 if (GET_CODE (addr1) == PLUS)
2676 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2677 if (TARGET_AVOID_XFORM)
2679 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2683 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2685 else if (TARGET_AVOID_XFORM)
2687 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2692 emit_move_insn (op2, GEN_INT (4));
2693 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2696 word1 = change_address (dest, SImode, addr1);
2697 word2 = change_address (dest, SImode, addr2);
2699 emit_insn (gen_lshrdi3 (op3, src, GEN_INT (32)));
2701 if (BYTES_BIG_ENDIAN)
2703 emit_insn (gen_bswapsi2 (word1, src_si));
2704 emit_insn (gen_bswapsi2 (word2, op3_si));
2708 emit_insn (gen_bswapsi2 (word2, src_si));
2709 emit_insn (gen_bswapsi2 (word1, op3_si));
2715 [(set (match_operand:DI 0 "gpc_reg_operand")
2716 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2717 (clobber (match_operand:DI 2 "gpc_reg_operand"))
2718 (clobber (match_operand:DI 3 "gpc_reg_operand"))]
2719 "TARGET_POWERPC64 && !TARGET_P9_VECTOR && reload_completed"
2722 rtx dest = operands[0];
2723 rtx src = operands[1];
2724 rtx op2 = operands[2];
2725 rtx op3 = operands[3];
2726 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2727 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2728 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2729 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2730 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2732 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2733 emit_insn (gen_bswapsi2 (dest_si, src_si));
2734 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2735 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2736 emit_insn (gen_iordi3 (dest, dest, op3));
2740 (define_insn "bswapdi2_32bit"
2741 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2742 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2743 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2744 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2746 [(set_attr "length" "16,12,36")])
2749 [(set (match_operand:DI 0 "gpc_reg_operand")
2750 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand")))
2751 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2752 "!TARGET_POWERPC64 && reload_completed"
2755 rtx dest = operands[0];
2756 rtx src = operands[1];
2757 rtx op2 = operands[2];
2758 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2759 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2765 addr1 = XEXP (src, 0);
2766 if (GET_CODE (addr1) == PLUS)
2768 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2769 if (TARGET_AVOID_XFORM
2770 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2772 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2776 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2778 else if (TARGET_AVOID_XFORM
2779 || REGNO (addr1) == REGNO (dest2))
2781 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2786 emit_move_insn (op2, GEN_INT (4));
2787 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2790 word1 = change_address (src, SImode, addr1);
2791 word2 = change_address (src, SImode, addr2);
2793 emit_insn (gen_bswapsi2 (dest2, word1));
2794 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2795 thus allowing us to omit an early clobber on the output. */
2796 emit_insn (gen_bswapsi2 (dest1, word2));
2801 [(set (match_operand:DI 0 "indexed_or_indirect_operand")
2802 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2803 (clobber (match_operand:SI 2 "gpc_reg_operand"))]
2804 "!TARGET_POWERPC64 && reload_completed"
2807 rtx dest = operands[0];
2808 rtx src = operands[1];
2809 rtx op2 = operands[2];
2810 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2811 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2817 addr1 = XEXP (dest, 0);
2818 if (GET_CODE (addr1) == PLUS)
2820 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2821 if (TARGET_AVOID_XFORM)
2823 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2827 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2829 else if (TARGET_AVOID_XFORM)
2831 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2836 emit_move_insn (op2, GEN_INT (4));
2837 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2840 word1 = change_address (dest, SImode, addr1);
2841 word2 = change_address (dest, SImode, addr2);
2843 emit_insn (gen_bswapsi2 (word2, src1));
2844 emit_insn (gen_bswapsi2 (word1, src2));
2849 [(set (match_operand:DI 0 "gpc_reg_operand")
2850 (bswap:DI (match_operand:DI 1 "gpc_reg_operand")))
2851 (clobber (match_operand:SI 2 ""))]
2852 "!TARGET_POWERPC64 && reload_completed"
2855 rtx dest = operands[0];
2856 rtx src = operands[1];
2857 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2858 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2859 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2860 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2862 emit_insn (gen_bswapsi2 (dest1, src2));
2863 emit_insn (gen_bswapsi2 (dest2, src1));
2868 (define_insn "mul<mode>3"
2869 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2870 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2871 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2876 [(set_attr "type" "mul")
2878 (cond [(match_operand:GPR 2 "s8bit_cint_operand")
2880 (match_operand:GPR 2 "short_cint_operand")
2881 (const_string "16")]
2882 (const_string "<bits>")))])
2884 (define_insn_and_split "*mul<mode>3_dot"
2885 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2886 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2887 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2889 (clobber (match_scratch:GPR 0 "=r,r"))]
2890 "<MODE>mode == Pmode"
2894 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2896 (mult:GPR (match_dup 1)
2899 (compare:CC (match_dup 0)
2902 [(set_attr "type" "mul")
2903 (set_attr "size" "<bits>")
2904 (set_attr "dot" "yes")
2905 (set_attr "length" "4,8")])
2907 (define_insn_and_split "*mul<mode>3_dot2"
2908 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2909 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2910 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2912 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2913 (mult:GPR (match_dup 1)
2915 "<MODE>mode == Pmode"
2919 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2921 (mult:GPR (match_dup 1)
2924 (compare:CC (match_dup 0)
2927 [(set_attr "type" "mul")
2928 (set_attr "size" "<bits>")
2929 (set_attr "dot" "yes")
2930 (set_attr "length" "4,8")])
2933 (define_expand "<su>mul<mode>3_highpart"
2934 [(set (match_operand:GPR 0 "gpc_reg_operand")
2936 (mult:<DMODE> (any_extend:<DMODE>
2937 (match_operand:GPR 1 "gpc_reg_operand"))
2939 (match_operand:GPR 2 "gpc_reg_operand")))
2943 if (<MODE>mode == SImode && TARGET_POWERPC64)
2945 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2950 if (!WORDS_BIG_ENDIAN)
2952 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2958 (define_insn "*<su>mul<mode>3_highpart"
2959 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2961 (mult:<DMODE> (any_extend:<DMODE>
2962 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2964 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2966 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2967 "mulh<wd><u> %0,%1,%2"
2968 [(set_attr "type" "mul")
2969 (set_attr "size" "<bits>")])
2971 (define_insn "<su>mulsi3_highpart_le"
2972 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2974 (mult:DI (any_extend:DI
2975 (match_operand:SI 1 "gpc_reg_operand" "r"))
2977 (match_operand:SI 2 "gpc_reg_operand" "r")))
2979 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2981 [(set_attr "type" "mul")])
2983 (define_insn "<su>muldi3_highpart_le"
2984 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2986 (mult:TI (any_extend:TI
2987 (match_operand:DI 1 "gpc_reg_operand" "r"))
2989 (match_operand:DI 2 "gpc_reg_operand" "r")))
2991 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2993 [(set_attr "type" "mul")
2994 (set_attr "size" "64")])
2996 (define_insn "<su>mulsi3_highpart_64"
2997 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3000 (mult:DI (any_extend:DI
3001 (match_operand:SI 1 "gpc_reg_operand" "r"))
3003 (match_operand:SI 2 "gpc_reg_operand" "r")))
3007 [(set_attr "type" "mul")])
3009 (define_expand "<u>mul<mode><dmode>3"
3010 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3011 (mult:<DMODE> (any_extend:<DMODE>
3012 (match_operand:GPR 1 "gpc_reg_operand"))
3014 (match_operand:GPR 2 "gpc_reg_operand"))))]
3015 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3017 rtx l = gen_reg_rtx (<MODE>mode);
3018 rtx h = gen_reg_rtx (<MODE>mode);
3019 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3020 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3021 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3022 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3026 (define_insn "*maddld4"
3027 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3028 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3029 (match_operand:DI 2 "gpc_reg_operand" "r"))
3030 (match_operand:DI 3 "gpc_reg_operand" "r")))]
3032 "maddld %0,%1,%2,%3"
3033 [(set_attr "type" "mul")])
3035 (define_insn "udiv<mode>3"
3036 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3037 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3038 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3041 [(set_attr "type" "div")
3042 (set_attr "size" "<bits>")])
3045 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3046 ;; modulus. If it isn't a power of two, force operands into register and do
3048 (define_expand "div<mode>3"
3049 [(set (match_operand:GPR 0 "gpc_reg_operand")
3050 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3051 (match_operand:GPR 2 "reg_or_cint_operand")))]
3054 if (CONST_INT_P (operands[2])
3055 && INTVAL (operands[2]) > 0
3056 && exact_log2 (INTVAL (operands[2])) >= 0)
3058 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3062 operands[2] = force_reg (<MODE>mode, operands[2]);
3065 (define_insn "*div<mode>3"
3066 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3067 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3068 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3071 [(set_attr "type" "div")
3072 (set_attr "size" "<bits>")])
3074 (define_insn "div<mode>3_sra"
3075 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3076 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3077 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3078 (clobber (reg:GPR CA_REGNO))]
3080 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3081 [(set_attr "type" "two")
3082 (set_attr "length" "8")])
3084 (define_insn_and_split "*div<mode>3_sra_dot"
3085 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3086 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3087 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3089 (clobber (match_scratch:GPR 0 "=r,r"))
3090 (clobber (reg:GPR CA_REGNO))]
3091 "<MODE>mode == Pmode"
3093 sra<wd>i %0,%1,%p2\;addze. %0,%0
3095 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3096 [(parallel [(set (match_dup 0)
3097 (div:GPR (match_dup 1)
3099 (clobber (reg:GPR CA_REGNO))])
3101 (compare:CC (match_dup 0)
3104 [(set_attr "type" "two")
3105 (set_attr "length" "8,12")
3106 (set_attr "cell_micro" "not")])
3108 (define_insn_and_split "*div<mode>3_sra_dot2"
3109 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3110 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3111 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3113 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3114 (div:GPR (match_dup 1)
3116 (clobber (reg:GPR CA_REGNO))]
3117 "<MODE>mode == Pmode"
3119 sra<wd>i %0,%1,%p2\;addze. %0,%0
3121 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3122 [(parallel [(set (match_dup 0)
3123 (div:GPR (match_dup 1)
3125 (clobber (reg:GPR CA_REGNO))])
3127 (compare:CC (match_dup 0)
3130 [(set_attr "type" "two")
3131 (set_attr "length" "8,12")
3132 (set_attr "cell_micro" "not")])
3134 (define_expand "mod<mode>3"
3135 [(set (match_operand:GPR 0 "gpc_reg_operand")
3136 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3137 (match_operand:GPR 2 "reg_or_cint_operand")))]
3144 if (GET_CODE (operands[2]) != CONST_INT
3145 || INTVAL (operands[2]) <= 0
3146 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3151 operands[2] = force_reg (<MODE>mode, operands[2]);
3155 temp1 = gen_reg_rtx (<MODE>mode);
3156 temp2 = gen_reg_rtx (<MODE>mode);
3158 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3159 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3160 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3165 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3166 ;; mod, prefer putting the result of mod into a different register
3167 (define_insn "*mod<mode>3"
3168 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3169 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3170 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3173 [(set_attr "type" "div")
3174 (set_attr "size" "<bits>")])
3177 (define_insn "umod<mode>3"
3178 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3179 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3180 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3183 [(set_attr "type" "div")
3184 (set_attr "size" "<bits>")])
3186 ;; On machines with modulo support, do a combined div/mod the old fashioned
3187 ;; method, since the multiply/subtract is faster than doing the mod instruction
3191 [(set (match_operand:GPR 0 "gpc_reg_operand")
3192 (div:GPR (match_operand:GPR 1 "gpc_reg_operand")
3193 (match_operand:GPR 2 "gpc_reg_operand")))
3194 (set (match_operand:GPR 3 "gpc_reg_operand")
3195 (mod:GPR (match_dup 1)
3198 && ! reg_mentioned_p (operands[0], operands[1])
3199 && ! reg_mentioned_p (operands[0], operands[2])
3200 && ! reg_mentioned_p (operands[3], operands[1])
3201 && ! reg_mentioned_p (operands[3], operands[2])"
3203 (div:GPR (match_dup 1)
3206 (mult:GPR (match_dup 0)
3209 (minus:GPR (match_dup 1)
3213 [(set (match_operand:GPR 0 "gpc_reg_operand")
3214 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand")
3215 (match_operand:GPR 2 "gpc_reg_operand")))
3216 (set (match_operand:GPR 3 "gpc_reg_operand")
3217 (umod:GPR (match_dup 1)
3220 && ! reg_mentioned_p (operands[0], operands[1])
3221 && ! reg_mentioned_p (operands[0], operands[2])
3222 && ! reg_mentioned_p (operands[3], operands[1])
3223 && ! reg_mentioned_p (operands[3], operands[2])"
3225 (udiv:GPR (match_dup 1)
3228 (mult:GPR (match_dup 0)
3231 (minus:GPR (match_dup 1)
3235 ;; Logical instructions
3236 ;; The logical instructions are mostly combined by using match_operator,
3237 ;; but the plain AND insns are somewhat different because there is no
3238 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3239 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3241 (define_expand "and<mode>3"
3242 [(set (match_operand:SDI 0 "gpc_reg_operand")
3243 (and:SDI (match_operand:SDI 1 "gpc_reg_operand")
3244 (match_operand:SDI 2 "reg_or_cint_operand")))]
3247 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3249 rs6000_split_logical (operands, AND, false, false, false);
3253 if (CONST_INT_P (operands[2]))
3255 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3257 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3261 if (logical_const_operand (operands[2], <MODE>mode))
3263 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3267 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3269 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3273 operands[2] = force_reg (<MODE>mode, operands[2]);
3278 (define_insn "and<mode>3_imm"
3279 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3280 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3281 (match_operand:GPR 2 "logical_const_operand" "n")))
3282 (clobber (match_scratch:CC 3 "=x"))]
3283 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3284 "andi%e2. %0,%1,%u2"
3285 [(set_attr "type" "logical")
3286 (set_attr "dot" "yes")])
3288 (define_insn_and_split "*and<mode>3_imm_dot"
3289 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3290 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3291 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3293 (clobber (match_scratch:GPR 0 "=r,r"))
3294 (clobber (match_scratch:CC 4 "=X,x"))]
3295 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3296 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3300 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3301 [(parallel [(set (match_dup 0)
3302 (and:GPR (match_dup 1)
3304 (clobber (match_dup 4))])
3306 (compare:CC (match_dup 0)
3309 [(set_attr "type" "logical")
3310 (set_attr "dot" "yes")
3311 (set_attr "length" "4,8")])
3313 (define_insn_and_split "*and<mode>3_imm_dot2"
3314 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3315 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3316 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3318 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3319 (and:GPR (match_dup 1)
3321 (clobber (match_scratch:CC 4 "=X,x"))]
3322 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3323 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3327 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3328 [(parallel [(set (match_dup 0)
3329 (and:GPR (match_dup 1)
3331 (clobber (match_dup 4))])
3333 (compare:CC (match_dup 0)
3336 [(set_attr "type" "logical")
3337 (set_attr "dot" "yes")
3338 (set_attr "length" "4,8")])
3340 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3341 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3342 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3343 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3345 (clobber (match_scratch:GPR 0 "=r,r"))]
3346 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3347 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3351 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3353 (and:GPR (match_dup 1)
3356 (compare:CC (match_dup 0)
3359 [(set_attr "type" "logical")
3360 (set_attr "dot" "yes")
3361 (set_attr "length" "4,8")])
3363 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3364 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3365 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3366 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3368 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3369 (and:GPR (match_dup 1)
3371 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3372 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3376 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3378 (and:GPR (match_dup 1)
3381 (compare:CC (match_dup 0)
3384 [(set_attr "type" "logical")
3385 (set_attr "dot" "yes")
3386 (set_attr "length" "4,8")])
3388 (define_insn "*and<mode>3_imm_dot_shifted"
3389 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3392 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3393 (match_operand:SI 4 "const_int_operand" "n"))
3394 (match_operand:GPR 2 "const_int_operand" "n"))
3396 (clobber (match_scratch:GPR 0 "=r"))]
3397 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3398 << INTVAL (operands[4])),
3400 && (<MODE>mode == Pmode
3401 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3403 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3404 return "andi%e2. %0,%1,%u2";
3406 [(set_attr "type" "logical")
3407 (set_attr "dot" "yes")])
3410 (define_insn "and<mode>3_mask"
3411 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3412 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3413 (match_operand:GPR 2 "const_int_operand" "n")))]
3414 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3416 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3418 [(set_attr "type" "shift")])
3420 (define_insn_and_split "*and<mode>3_mask_dot"
3421 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3422 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3423 (match_operand:GPR 2 "const_int_operand" "n,n"))
3425 (clobber (match_scratch:GPR 0 "=r,r"))]
3426 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3427 && !logical_const_operand (operands[2], <MODE>mode)
3428 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3430 if (which_alternative == 0)
3431 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3435 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3437 (and:GPR (match_dup 1)
3440 (compare:CC (match_dup 0)
3443 [(set_attr "type" "shift")
3444 (set_attr "dot" "yes")
3445 (set_attr "length" "4,8")])
3447 (define_insn_and_split "*and<mode>3_mask_dot2"
3448 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3449 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3450 (match_operand:GPR 2 "const_int_operand" "n,n"))
3452 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3453 (and:GPR (match_dup 1)
3455 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3456 && !logical_const_operand (operands[2], <MODE>mode)
3457 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3459 if (which_alternative == 0)
3460 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3464 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3466 (and:GPR (match_dup 1)
3469 (compare:CC (match_dup 0)
3472 [(set_attr "type" "shift")
3473 (set_attr "dot" "yes")
3474 (set_attr "length" "4,8")])
3477 (define_insn_and_split "*and<mode>3_2insn"
3478 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3479 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3480 (match_operand:GPR 2 "const_int_operand" "n")))]
3481 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3482 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3483 || logical_const_operand (operands[2], <MODE>mode))"
3488 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3491 [(set_attr "type" "shift")
3492 (set_attr "length" "8")])
3494 (define_insn_and_split "*and<mode>3_2insn_dot"
3495 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3496 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3497 (match_operand:GPR 2 "const_int_operand" "n,n"))
3499 (clobber (match_scratch:GPR 0 "=r,r"))]
3500 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3501 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3502 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3503 || logical_const_operand (operands[2], <MODE>mode))"
3505 "&& reload_completed"
3508 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3511 [(set_attr "type" "shift")
3512 (set_attr "dot" "yes")
3513 (set_attr "length" "8,12")])
3515 (define_insn_and_split "*and<mode>3_2insn_dot2"
3516 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3517 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3518 (match_operand:GPR 2 "const_int_operand" "n,n"))
3520 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3521 (and:GPR (match_dup 1)
3523 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3524 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3525 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3526 || logical_const_operand (operands[2], <MODE>mode))"
3528 "&& reload_completed"
3531 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3534 [(set_attr "type" "shift")
3535 (set_attr "dot" "yes")
3536 (set_attr "length" "8,12")])
3539 (define_expand "<code><mode>3"
3540 [(set (match_operand:SDI 0 "gpc_reg_operand")
3541 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand")
3542 (match_operand:SDI 2 "reg_or_cint_operand")))]
3545 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3547 rs6000_split_logical (operands, <CODE>, false, false, false);
3551 if (non_logical_cint_operand (operands[2], <MODE>mode))
3553 rtx tmp = ((!can_create_pseudo_p ()
3554 || rtx_equal_p (operands[0], operands[1]))
3555 ? operands[0] : gen_reg_rtx (<MODE>mode));
3557 HOST_WIDE_INT value = INTVAL (operands[2]);
3558 HOST_WIDE_INT lo = value & 0xffff;
3559 HOST_WIDE_INT hi = value - lo;
3561 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3562 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3566 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3567 operands[2] = force_reg (<MODE>mode, operands[2]);
3571 [(set (match_operand:GPR 0 "gpc_reg_operand")
3572 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand")
3573 (match_operand:GPR 2 "non_logical_cint_operand")))]
3576 (iorxor:GPR (match_dup 1)
3579 (iorxor:GPR (match_dup 3)
3582 operands[3] = ((!can_create_pseudo_p ()
3583 || rtx_equal_p (operands[0], operands[1]))
3584 ? operands[0] : gen_reg_rtx (<MODE>mode));
3586 HOST_WIDE_INT value = INTVAL (operands[2]);
3587 HOST_WIDE_INT lo = value & 0xffff;
3588 HOST_WIDE_INT hi = value - lo;
3590 operands[4] = GEN_INT (hi);
3591 operands[5] = GEN_INT (lo);
3594 (define_insn "*bool<mode>3_imm"
3595 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3596 (match_operator:GPR 3 "boolean_or_operator"
3597 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3598 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3601 [(set_attr "type" "logical")])
3603 (define_insn "*bool<mode>3"
3604 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3605 (match_operator:GPR 3 "boolean_operator"
3606 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3607 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3610 [(set_attr "type" "logical")])
3612 (define_insn_and_split "*bool<mode>3_dot"
3613 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3614 (compare:CC (match_operator:GPR 3 "boolean_operator"
3615 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3616 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3618 (clobber (match_scratch:GPR 0 "=r,r"))]
3619 "<MODE>mode == Pmode"
3623 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3627 (compare:CC (match_dup 0)
3630 [(set_attr "type" "logical")
3631 (set_attr "dot" "yes")
3632 (set_attr "length" "4,8")])
3634 (define_insn_and_split "*bool<mode>3_dot2"
3635 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3636 (compare:CC (match_operator:GPR 3 "boolean_operator"
3637 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3638 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3640 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3642 "<MODE>mode == Pmode"
3646 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3650 (compare:CC (match_dup 0)
3653 [(set_attr "type" "logical")
3654 (set_attr "dot" "yes")
3655 (set_attr "length" "4,8")])
3658 (define_insn "*boolc<mode>3"
3659 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3660 (match_operator:GPR 3 "boolean_operator"
3661 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3662 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3665 [(set_attr "type" "logical")])
3667 (define_insn_and_split "*boolc<mode>3_dot"
3668 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3669 (compare:CC (match_operator:GPR 3 "boolean_operator"
3670 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3671 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3673 (clobber (match_scratch:GPR 0 "=r,r"))]
3674 "<MODE>mode == Pmode"
3678 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3682 (compare:CC (match_dup 0)
3685 [(set_attr "type" "logical")
3686 (set_attr "dot" "yes")
3687 (set_attr "length" "4,8")])
3689 (define_insn_and_split "*boolc<mode>3_dot2"
3690 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3691 (compare:CC (match_operator:GPR 3 "boolean_operator"
3692 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3693 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3695 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3697 "<MODE>mode == Pmode"
3701 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3705 (compare:CC (match_dup 0)
3708 [(set_attr "type" "logical")
3709 (set_attr "dot" "yes")
3710 (set_attr "length" "4,8")])
3713 (define_insn "*boolcc<mode>3"
3714 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3715 (match_operator:GPR 3 "boolean_operator"
3716 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3717 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3720 [(set_attr "type" "logical")])
3722 (define_insn_and_split "*boolcc<mode>3_dot"
3723 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3724 (compare:CC (match_operator:GPR 3 "boolean_operator"
3725 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3726 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3728 (clobber (match_scratch:GPR 0 "=r,r"))]
3729 "<MODE>mode == Pmode"
3733 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3737 (compare:CC (match_dup 0)
3740 [(set_attr "type" "logical")
3741 (set_attr "dot" "yes")
3742 (set_attr "length" "4,8")])
3744 (define_insn_and_split "*boolcc<mode>3_dot2"
3745 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3746 (compare:CC (match_operator:GPR 3 "boolean_operator"
3747 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3748 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3750 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3752 "<MODE>mode == Pmode"
3756 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3760 (compare:CC (match_dup 0)
3763 [(set_attr "type" "logical")
3764 (set_attr "dot" "yes")
3765 (set_attr "length" "4,8")])
3768 ;; TODO: Should have dots of this as well.
3769 (define_insn "*eqv<mode>3"
3770 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3771 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3772 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3775 [(set_attr "type" "logical")])
3777 ;; Rotate-and-mask and insert.
3779 (define_insn "*rotl<mode>3_mask"
3780 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3781 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3782 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3783 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3784 (match_operand:GPR 3 "const_int_operand" "n")))]
3785 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3787 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3789 [(set_attr "type" "shift")
3790 (set_attr "maybe_var_shift" "yes")])
3792 (define_insn_and_split "*rotl<mode>3_mask_dot"
3793 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3795 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3796 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3797 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3798 (match_operand:GPR 3 "const_int_operand" "n,n"))
3800 (clobber (match_scratch:GPR 0 "=r,r"))]
3801 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3802 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3804 if (which_alternative == 0)
3805 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3809 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3811 (and:GPR (match_dup 4)
3814 (compare:CC (match_dup 0)
3817 [(set_attr "type" "shift")
3818 (set_attr "maybe_var_shift" "yes")
3819 (set_attr "dot" "yes")
3820 (set_attr "length" "4,8")])
3822 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3823 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3825 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3826 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3827 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3828 (match_operand:GPR 3 "const_int_operand" "n,n"))
3830 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3831 (and:GPR (match_dup 4)
3833 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3834 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3836 if (which_alternative == 0)
3837 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3841 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3843 (and:GPR (match_dup 4)
3846 (compare:CC (match_dup 0)
3849 [(set_attr "type" "shift")
3850 (set_attr "maybe_var_shift" "yes")
3851 (set_attr "dot" "yes")
3852 (set_attr "length" "4,8")])
3854 ; Special case for less-than-0. We can do it with just one machine
3855 ; instruction, but the generic optimizers do not realise it is cheap.
3856 (define_insn "*lt0_<mode>di"
3857 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3858 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3862 [(set_attr "type" "shift")])
3864 (define_insn "*lt0_<mode>si"
3865 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3866 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3869 "rlwinm %0,%1,1,31,31"
3870 [(set_attr "type" "shift")])
3874 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3875 ; both are an AND so are the same precedence).
3876 (define_insn "*rotl<mode>3_insert"
3877 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3878 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3879 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3880 (match_operand:SI 2 "const_int_operand" "n")])
3881 (match_operand:GPR 3 "const_int_operand" "n"))
3882 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3883 (match_operand:GPR 6 "const_int_operand" "n"))))]
3884 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3885 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3887 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3889 [(set_attr "type" "insert")])
3890 ; FIXME: this needs an attr "size", so that the scheduler can see the
3891 ; difference between rlwimi and rldimi. We also might want dot forms,
3892 ; but not for rlwimi on POWER4 and similar processors.
3894 (define_insn "*rotl<mode>3_insert_2"
3895 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3896 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3897 (match_operand:GPR 6 "const_int_operand" "n"))
3898 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3899 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3900 (match_operand:SI 2 "const_int_operand" "n")])
3901 (match_operand:GPR 3 "const_int_operand" "n"))))]
3902 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3903 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3905 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3907 [(set_attr "type" "insert")])
3909 ; There are also some forms without one of the ANDs.
3910 (define_insn "*rotl<mode>3_insert_3"
3911 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3912 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3913 (match_operand:GPR 4 "const_int_operand" "n"))
3914 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3915 (match_operand:SI 2 "const_int_operand" "n"))))]
3916 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3918 if (<MODE>mode == SImode)
3919 return "rlwimi %0,%1,%h2,0,31-%h2";
3921 return "rldimi %0,%1,%H2,0";
3923 [(set_attr "type" "insert")])
3925 (define_insn "*rotl<mode>3_insert_4"
3926 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3927 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3928 (match_operand:GPR 4 "const_int_operand" "n"))
3929 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3930 (match_operand:SI 2 "const_int_operand" "n"))))]
3931 "<MODE>mode == SImode &&
3932 GET_MODE_PRECISION (<MODE>mode)
3933 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3935 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3936 - INTVAL (operands[2]));
3937 if (<MODE>mode == SImode)
3938 return "rlwimi %0,%1,%h2,32-%h2,31";
3940 return "rldimi %0,%1,%H2,64-%H2";
3942 [(set_attr "type" "insert")])
3944 (define_insn "*rotlsi3_insert_5"
3945 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3946 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3947 (match_operand:SI 2 "const_int_operand" "n,n"))
3948 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3949 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3950 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3951 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3952 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3956 [(set_attr "type" "insert")])
3958 (define_insn "*rotldi3_insert_6"
3959 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3960 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3961 (match_operand:DI 2 "const_int_operand" "n"))
3962 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3963 (match_operand:DI 4 "const_int_operand" "n"))))]
3964 "exact_log2 (-UINTVAL (operands[2])) > 0
3965 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3967 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3968 return "rldimi %0,%3,0,%5";
3970 [(set_attr "type" "insert")
3971 (set_attr "size" "64")])
3973 (define_insn "*rotldi3_insert_7"
3974 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3975 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3976 (match_operand:DI 4 "const_int_operand" "n"))
3977 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3978 (match_operand:DI 2 "const_int_operand" "n"))))]
3979 "exact_log2 (-UINTVAL (operands[2])) > 0
3980 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3982 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3983 return "rldimi %0,%3,0,%5";
3985 [(set_attr "type" "insert")
3986 (set_attr "size" "64")])
3989 ; This handles the important case of multiple-precision shifts. There is
3990 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3992 [(set (match_operand:GPR 0 "gpc_reg_operand")
3993 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3994 (match_operand:SI 3 "const_int_operand"))
3995 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
3996 (match_operand:SI 4 "const_int_operand"))))]
3997 "can_create_pseudo_p ()
3998 && INTVAL (operands[3]) + INTVAL (operands[4])
3999 >= GET_MODE_PRECISION (<MODE>mode)"
4001 (lshiftrt:GPR (match_dup 2)
4004 (ior:GPR (and:GPR (match_dup 5)
4006 (ashift:GPR (match_dup 1)
4009 unsigned HOST_WIDE_INT mask = 1;
4010 mask = (mask << INTVAL (operands[3])) - 1;
4011 operands[5] = gen_reg_rtx (<MODE>mode);
4012 operands[6] = GEN_INT (mask);
4016 [(set (match_operand:GPR 0 "gpc_reg_operand")
4017 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4018 (match_operand:SI 4 "const_int_operand"))
4019 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4020 (match_operand:SI 3 "const_int_operand"))))]
4021 "can_create_pseudo_p ()
4022 && INTVAL (operands[3]) + INTVAL (operands[4])
4023 >= GET_MODE_PRECISION (<MODE>mode)"
4025 (lshiftrt:GPR (match_dup 2)
4028 (ior:GPR (and:GPR (match_dup 5)
4030 (ashift:GPR (match_dup 1)
4033 unsigned HOST_WIDE_INT mask = 1;
4034 mask = (mask << INTVAL (operands[3])) - 1;
4035 operands[5] = gen_reg_rtx (<MODE>mode);
4036 operands[6] = GEN_INT (mask);
4040 ; Another important case is setting some bits to 1; we can do that with
4041 ; an insert instruction, in many cases.
4042 (define_insn_and_split "*ior<mode>_mask"
4043 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4044 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4045 (match_operand:GPR 2 "const_int_operand" "n")))
4046 (clobber (match_scratch:GPR 3 "=r"))]
4047 "!logical_const_operand (operands[2], <MODE>mode)
4048 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4054 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4057 (and:GPR (match_dup 1)
4061 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4062 if (GET_CODE (operands[3]) == SCRATCH)
4063 operands[3] = gen_reg_rtx (<MODE>mode);
4064 operands[4] = GEN_INT (ne);
4065 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4067 [(set_attr "type" "two")
4068 (set_attr "length" "8")])
4071 ;; Now the simple shifts.
4073 (define_insn "rotl<mode>3"
4074 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4075 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4076 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4078 "rotl<wd>%I2 %0,%1,%<hH>2"
4079 [(set_attr "type" "shift")
4080 (set_attr "maybe_var_shift" "yes")])
4082 (define_insn "*rotlsi3_64"
4083 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4085 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4086 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4088 "rotlw%I2 %0,%1,%h2"
4089 [(set_attr "type" "shift")
4090 (set_attr "maybe_var_shift" "yes")])
4092 (define_insn_and_split "*rotl<mode>3_dot"
4093 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4094 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4095 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4097 (clobber (match_scratch:GPR 0 "=r,r"))]
4098 "<MODE>mode == Pmode"
4100 rotl<wd>%I2. %0,%1,%<hH>2
4102 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4104 (rotate:GPR (match_dup 1)
4107 (compare:CC (match_dup 0)
4110 [(set_attr "type" "shift")
4111 (set_attr "maybe_var_shift" "yes")
4112 (set_attr "dot" "yes")
4113 (set_attr "length" "4,8")])
4115 (define_insn_and_split "*rotl<mode>3_dot2"
4116 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4117 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4118 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4120 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4121 (rotate:GPR (match_dup 1)
4123 "<MODE>mode == Pmode"
4125 rotl<wd>%I2. %0,%1,%<hH>2
4127 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4129 (rotate:GPR (match_dup 1)
4132 (compare:CC (match_dup 0)
4135 [(set_attr "type" "shift")
4136 (set_attr "maybe_var_shift" "yes")
4137 (set_attr "dot" "yes")
4138 (set_attr "length" "4,8")])
4141 (define_insn "ashl<mode>3"
4142 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4143 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4144 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4146 "sl<wd>%I2 %0,%1,%<hH>2"
4147 [(set_attr "type" "shift")
4148 (set_attr "maybe_var_shift" "yes")])
4150 (define_insn "*ashlsi3_64"
4151 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4153 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4154 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4157 [(set_attr "type" "shift")
4158 (set_attr "maybe_var_shift" "yes")])
4160 (define_insn_and_split "*ashl<mode>3_dot"
4161 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4162 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4163 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4165 (clobber (match_scratch:GPR 0 "=r,r"))]
4166 "<MODE>mode == Pmode"
4168 sl<wd>%I2. %0,%1,%<hH>2
4170 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4172 (ashift:GPR (match_dup 1)
4175 (compare:CC (match_dup 0)
4178 [(set_attr "type" "shift")
4179 (set_attr "maybe_var_shift" "yes")
4180 (set_attr "dot" "yes")
4181 (set_attr "length" "4,8")])
4183 (define_insn_and_split "*ashl<mode>3_dot2"
4184 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4185 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4186 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4188 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4189 (ashift:GPR (match_dup 1)
4191 "<MODE>mode == Pmode"
4193 sl<wd>%I2. %0,%1,%<hH>2
4195 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4197 (ashift:GPR (match_dup 1)
4200 (compare:CC (match_dup 0)
4203 [(set_attr "type" "shift")
4204 (set_attr "maybe_var_shift" "yes")
4205 (set_attr "dot" "yes")
4206 (set_attr "length" "4,8")])
4208 ;; Pretend we have a memory form of extswsli until register allocation is done
4209 ;; so that we use LWZ to load the value from memory, instead of LWA.
4210 (define_insn_and_split "ashdi3_extswsli"
4211 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4213 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4214 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4219 "&& reload_completed && MEM_P (operands[1])"
4223 (ashift:DI (sign_extend:DI (match_dup 3))
4226 operands[3] = gen_lowpart (SImode, operands[0]);
4228 [(set_attr "type" "shift")
4229 (set_attr "maybe_var_shift" "no")])
4232 (define_insn_and_split "ashdi3_extswsli_dot"
4233 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4236 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4237 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4239 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4246 "&& reload_completed
4247 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4248 || memory_operand (operands[1], SImode))"
4251 rtx dest = operands[0];
4252 rtx src = operands[1];
4253 rtx shift = operands[2];
4254 rtx cr = operands[3];
4261 src2 = gen_lowpart (SImode, dest);
4262 emit_move_insn (src2, src);
4265 if (REGNO (cr) == CR0_REGNO)
4267 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4271 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4272 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4275 [(set_attr "type" "shift")
4276 (set_attr "maybe_var_shift" "no")
4277 (set_attr "dot" "yes")
4278 (set_attr "length" "4,8,8,12")])
4280 (define_insn_and_split "ashdi3_extswsli_dot2"
4281 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4284 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4285 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4287 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4288 (ashift:DI (sign_extend:DI (match_dup 1))
4296 "&& reload_completed
4297 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4298 || memory_operand (operands[1], SImode))"
4301 rtx dest = operands[0];
4302 rtx src = operands[1];
4303 rtx shift = operands[2];
4304 rtx cr = operands[3];
4311 src2 = gen_lowpart (SImode, dest);
4312 emit_move_insn (src2, src);
4315 if (REGNO (cr) == CR0_REGNO)
4317 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4321 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4322 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4325 [(set_attr "type" "shift")
4326 (set_attr "maybe_var_shift" "no")
4327 (set_attr "dot" "yes")
4328 (set_attr "length" "4,8,8,12")])
4330 (define_insn "lshr<mode>3"
4331 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4332 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4333 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4335 "sr<wd>%I2 %0,%1,%<hH>2"
4336 [(set_attr "type" "shift")
4337 (set_attr "maybe_var_shift" "yes")])
4339 (define_insn "*lshrsi3_64"
4340 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4342 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4343 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4346 [(set_attr "type" "shift")
4347 (set_attr "maybe_var_shift" "yes")])
4349 (define_insn_and_split "*lshr<mode>3_dot"
4350 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4351 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4352 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4354 (clobber (match_scratch:GPR 0 "=r,r"))]
4355 "<MODE>mode == Pmode"
4357 sr<wd>%I2. %0,%1,%<hH>2
4359 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4361 (lshiftrt:GPR (match_dup 1)
4364 (compare:CC (match_dup 0)
4367 [(set_attr "type" "shift")
4368 (set_attr "maybe_var_shift" "yes")
4369 (set_attr "dot" "yes")
4370 (set_attr "length" "4,8")])
4372 (define_insn_and_split "*lshr<mode>3_dot2"
4373 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4374 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4375 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4377 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4378 (lshiftrt:GPR (match_dup 1)
4380 "<MODE>mode == Pmode"
4382 sr<wd>%I2. %0,%1,%<hH>2
4384 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4386 (lshiftrt:GPR (match_dup 1)
4389 (compare:CC (match_dup 0)
4392 [(set_attr "type" "shift")
4393 (set_attr "maybe_var_shift" "yes")
4394 (set_attr "dot" "yes")
4395 (set_attr "length" "4,8")])
4398 (define_insn "ashr<mode>3"
4399 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4400 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4401 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4402 (clobber (reg:GPR CA_REGNO))]
4404 "sra<wd>%I2 %0,%1,%<hH>2"
4405 [(set_attr "type" "shift")
4406 (set_attr "maybe_var_shift" "yes")])
4408 (define_insn "*ashrsi3_64"
4409 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4411 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4412 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4413 (clobber (reg:SI CA_REGNO))]
4416 [(set_attr "type" "shift")
4417 (set_attr "maybe_var_shift" "yes")])
4419 (define_insn_and_split "*ashr<mode>3_dot"
4420 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4421 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4422 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4424 (clobber (match_scratch:GPR 0 "=r,r"))
4425 (clobber (reg:GPR CA_REGNO))]
4426 "<MODE>mode == Pmode"
4428 sra<wd>%I2. %0,%1,%<hH>2
4430 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4431 [(parallel [(set (match_dup 0)
4432 (ashiftrt:GPR (match_dup 1)
4434 (clobber (reg:GPR CA_REGNO))])
4436 (compare:CC (match_dup 0)
4439 [(set_attr "type" "shift")
4440 (set_attr "maybe_var_shift" "yes")
4441 (set_attr "dot" "yes")
4442 (set_attr "length" "4,8")])
4444 (define_insn_and_split "*ashr<mode>3_dot2"
4445 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4446 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4447 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4449 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4450 (ashiftrt:GPR (match_dup 1)
4452 (clobber (reg:GPR CA_REGNO))]
4453 "<MODE>mode == Pmode"
4455 sra<wd>%I2. %0,%1,%<hH>2
4457 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4458 [(parallel [(set (match_dup 0)
4459 (ashiftrt:GPR (match_dup 1)
4461 (clobber (reg:GPR CA_REGNO))])
4463 (compare:CC (match_dup 0)
4466 [(set_attr "type" "shift")
4467 (set_attr "maybe_var_shift" "yes")
4468 (set_attr "dot" "yes")
4469 (set_attr "length" "4,8")])
4471 ;; Builtins to replace a division to generate FRE reciprocal estimate
4472 ;; instructions and the necessary fixup instructions
4473 (define_expand "recip<mode>3"
4474 [(match_operand:RECIPF 0 "gpc_reg_operand")
4475 (match_operand:RECIPF 1 "gpc_reg_operand")
4476 (match_operand:RECIPF 2 "gpc_reg_operand")]
4477 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4479 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4483 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4484 ;; hardware division. This is only done before register allocation and with
4485 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4486 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4487 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4489 [(set (match_operand:RECIPF 0 "gpc_reg_operand")
4490 (div:RECIPF (match_operand 1 "gpc_reg_operand")
4491 (match_operand 2 "gpc_reg_operand")))]
4492 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4493 && can_create_pseudo_p () && flag_finite_math_only
4494 && !flag_trapping_math && flag_reciprocal_math"
4497 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4501 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4502 ;; appropriate fixup.
4503 (define_expand "rsqrt<mode>2"
4504 [(match_operand:RECIPF 0 "gpc_reg_operand")
4505 (match_operand:RECIPF 1 "gpc_reg_operand")]
4506 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4508 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4512 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4513 ;; modes here, and also add in conditional vsx/power8-vector support to access
4514 ;; values in the traditional Altivec registers if the appropriate
4515 ;; -mupper-regs-{df,sf} option is enabled.
4517 (define_expand "abs<mode>2"
4518 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4519 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4520 "TARGET_<MODE>_INSN"
4523 (define_insn "*abs<mode>2_fpr"
4524 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4525 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4530 [(set_attr "type" "fpsimple")
4531 (set_attr "fp_type" "fp_addsub_<Fs>")])
4533 (define_insn "*nabs<mode>2_fpr"
4534 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4537 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4542 [(set_attr "type" "fpsimple")
4543 (set_attr "fp_type" "fp_addsub_<Fs>")])
4545 (define_expand "neg<mode>2"
4546 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4547 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4548 "TARGET_<MODE>_INSN"
4551 (define_insn "*neg<mode>2_fpr"
4552 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4553 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4558 [(set_attr "type" "fpsimple")
4559 (set_attr "fp_type" "fp_addsub_<Fs>")])
4561 (define_expand "add<mode>3"
4562 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4563 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4564 (match_operand:SFDF 2 "gpc_reg_operand")))]
4565 "TARGET_<MODE>_INSN"
4568 (define_insn "*add<mode>3_fpr"
4569 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4570 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4571 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4574 fadd<Ftrad> %0,%1,%2
4575 xsadd<Fvsx> %x0,%x1,%x2"
4576 [(set_attr "type" "fp")
4577 (set_attr "fp_type" "fp_addsub_<Fs>")])
4579 (define_expand "sub<mode>3"
4580 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4581 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4582 (match_operand:SFDF 2 "gpc_reg_operand")))]
4583 "TARGET_<MODE>_INSN"
4586 (define_insn "*sub<mode>3_fpr"
4587 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4588 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4589 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4592 fsub<Ftrad> %0,%1,%2
4593 xssub<Fvsx> %x0,%x1,%x2"
4594 [(set_attr "type" "fp")
4595 (set_attr "fp_type" "fp_addsub_<Fs>")])
4597 (define_expand "mul<mode>3"
4598 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4599 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4600 (match_operand:SFDF 2 "gpc_reg_operand")))]
4601 "TARGET_<MODE>_INSN"
4604 (define_insn "*mul<mode>3_fpr"
4605 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4606 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4607 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4610 fmul<Ftrad> %0,%1,%2
4611 xsmul<Fvsx> %x0,%x1,%x2"
4612 [(set_attr "type" "dmul")
4613 (set_attr "fp_type" "fp_mul_<Fs>")])
4615 (define_expand "div<mode>3"
4616 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4617 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4618 (match_operand:SFDF 2 "gpc_reg_operand")))]
4619 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4621 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4622 && can_create_pseudo_p () && flag_finite_math_only
4623 && !flag_trapping_math && flag_reciprocal_math)
4625 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4630 (define_insn "*div<mode>3_fpr"
4631 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4632 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4633 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4634 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4636 fdiv<Ftrad> %0,%1,%2
4637 xsdiv<Fvsx> %x0,%x1,%x2"
4638 [(set_attr "type" "<Fs>div")
4639 (set_attr "fp_type" "fp_div_<Fs>")])
4641 (define_insn "*sqrt<mode>2_internal"
4642 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4643 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4644 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4645 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4648 xssqrt<Fvsx> %x0,%x1"
4649 [(set_attr "type" "<Fs>sqrt")
4650 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4652 (define_expand "sqrt<mode>2"
4653 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4654 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))]
4655 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4656 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4658 if (<MODE>mode == SFmode
4659 && TARGET_RECIP_PRECISION
4660 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4661 && !optimize_function_for_size_p (cfun)
4662 && flag_finite_math_only && !flag_trapping_math
4663 && flag_unsafe_math_optimizations)
4665 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4670 ;; Floating point reciprocal approximation
4671 (define_insn "fre<Fs>"
4672 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4673 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4679 [(set_attr "type" "fp")])
4681 (define_insn "*rsqrt<mode>2"
4682 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4683 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4685 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4687 frsqrte<Ftrad> %0,%1
4688 xsrsqrte<Fvsx> %x0,%x1"
4689 [(set_attr "type" "fp")])
4691 ;; Floating point comparisons
4692 (define_insn "*cmp<mode>_fpr"
4693 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4694 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4695 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4699 xscmpudp %0,%x1,%x2"
4700 [(set_attr "type" "fpcompare")])
4702 ;; Floating point conversions
4703 (define_expand "extendsfdf2"
4704 [(set (match_operand:DF 0 "gpc_reg_operand")
4705 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4706 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4708 if (HONOR_SNANS (SFmode))
4709 operands[1] = force_reg (SFmode, operands[1]);
4712 (define_insn_and_split "*extendsfdf2_fpr"
4713 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4714 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4715 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4721 xscpsgndp %x0,%x1,%x1
4724 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4727 emit_note (NOTE_INSN_DELETED);
4730 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4732 (define_insn "*extendsfdf2_snan"
4733 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4734 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4735 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4739 [(set_attr "type" "fp")])
4741 (define_expand "truncdfsf2"
4742 [(set (match_operand:SF 0 "gpc_reg_operand")
4743 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand")))]
4744 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4747 (define_insn "*truncdfsf2_fpr"
4748 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4749 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4750 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4754 [(set_attr "type" "fp")])
4756 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4757 ;; builtins.c and optabs.c that are not correct for IBM long double
4758 ;; when little-endian.
4759 (define_expand "signbit<mode>2"
4761 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))
4763 (subreg:DI (match_dup 2) 0))
4766 (set (match_operand:SI 0 "gpc_reg_operand")
4769 && (!FLOAT128_IEEE_P (<MODE>mode)
4770 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4772 if (FLOAT128_IEEE_P (<MODE>mode))
4774 rtx dest = operands[0];
4775 rtx src = operands[1];
4776 rtx tmp = gen_reg_rtx (DImode);
4777 rtx dest_di = gen_lowpart (DImode, dest);
4779 if (<MODE>mode == KFmode)
4780 emit_insn (gen_signbitkf2_dm (tmp, src));
4781 else if (<MODE>mode == TFmode)
4782 emit_insn (gen_signbittf2_dm (tmp, src));
4786 emit_insn (gen_lshrdi3 (dest_di, tmp, GEN_INT (63)));
4789 operands[2] = gen_reg_rtx (DFmode);
4790 operands[3] = gen_reg_rtx (DImode);
4791 if (TARGET_POWERPC64)
4793 operands[4] = gen_reg_rtx (DImode);
4794 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4795 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4796 WORDS_BIG_ENDIAN ? 4 : 0);
4800 operands[4] = gen_reg_rtx (SImode);
4801 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4802 WORDS_BIG_ENDIAN ? 0 : 4);
4803 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4807 ;; Optimize IEEE 128-bit signbit on 64-bit systems with direct move to avoid
4808 ;; multiple direct moves. If we used a SUBREG:DI of the Floa128 type, the
4809 ;; register allocator would typically move the entire _Float128 item to GPRs (2
4810 ;; instructions on ISA 3.0, 3-4 instructions on ISA 2.07).
4812 ;; After register allocation, if the _Float128 had originally been in GPRs, the
4813 ;; split allows the post reload phases to eliminate the move, and do the shift
4814 ;; directly with the register that contains the signbit.
4815 (define_insn_and_split "signbit<mode>2_dm"
4816 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4817 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa,r")]
4819 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4823 "&& reload_completed && int_reg_operand (operands[1], <MODE>mode)"
4827 operands[2] = gen_highpart (DImode, operands[1]);
4829 [(set_attr "type" "mftgpr,*")])
4831 ;; Optimize IEEE 128-bit signbit on to avoid loading the value into a vector
4832 ;; register and then doing a direct move if the value comes from memory. On
4833 ;; little endian, we have to load the 2nd double-word to get the sign bit.
4834 (define_insn_and_split "*signbit<mode>2_dm_mem"
4835 [(set (match_operand:DI 0 "gpc_reg_operand" "=b")
4836 (unspec:DI [(match_operand:SIGNBIT 1 "memory_operand" "m")]
4838 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4844 rtx dest = operands[0];
4845 rtx src = operands[1];
4846 rtx addr = XEXP (src, 0);
4848 if (WORDS_BIG_ENDIAN)
4849 operands[2] = adjust_address (src, DImode, 0);
4851 else if (REG_P (addr) || SUBREG_P (addr))
4852 operands[2] = adjust_address (src, DImode, 8);
4854 else if (GET_CODE (addr) == PLUS && REG_P (XEXP (addr, 0))
4855 && CONST_INT_P (XEXP (addr, 1)) && mem_operand_gpr (src, DImode))
4856 operands[2] = adjust_address (src, DImode, 8);
4860 rtx tmp = can_create_pseudo_p () ? gen_reg_rtx (DImode) : dest;
4861 emit_insn (gen_rtx_SET (tmp, addr));
4862 operands[2] = change_address (src, DImode,
4863 gen_rtx_PLUS (DImode, tmp, GEN_INT (8)));
4867 (define_expand "copysign<mode>3"
4869 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand")))
4871 (neg:SFDF (abs:SFDF (match_dup 1))))
4872 (set (match_operand:SFDF 0 "gpc_reg_operand")
4873 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand")
4877 "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4878 && ((TARGET_PPC_GFXOPT
4879 && !HONOR_NANS (<MODE>mode)
4880 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4882 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4884 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4886 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4891 operands[3] = gen_reg_rtx (<MODE>mode);
4892 operands[4] = gen_reg_rtx (<MODE>mode);
4893 operands[5] = CONST0_RTX (<MODE>mode);
4896 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4897 ;; compiler from optimizing -0.0
4898 (define_insn "copysign<mode>3_fcpsgn"
4899 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4900 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4901 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4903 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4906 xscpsgndp %x0,%x2,%x1"
4907 [(set_attr "type" "fpsimple")])
4909 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4910 ;; fsel instruction and some auxiliary computations. Then we just have a
4911 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4913 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4914 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4915 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4916 ;; define_splits to make them if made by combine. On VSX machines we have the
4917 ;; min/max instructions.
4919 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4920 ;; to allow either DF/SF to use only traditional registers.
4922 (define_expand "s<minmax><mode>3"
4923 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4924 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4925 (match_operand:SFDF 2 "gpc_reg_operand")))]
4926 "TARGET_MINMAX_<MODE>"
4928 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4932 (define_insn "*s<minmax><mode>3_vsx"
4933 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4934 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4935 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4936 "TARGET_VSX && TARGET_<MODE>_FPR"
4938 return (TARGET_P9_MINMAX
4939 ? "xs<minmax>cdp %x0,%x1,%x2"
4940 : "xs<minmax>dp %x0,%x1,%x2");
4942 [(set_attr "type" "fp")])
4944 ;; The conditional move instructions allow us to perform max and min operations
4945 ;; even when we don't have the appropriate max/min instruction using the FSEL
4948 (define_insn_and_split "*s<minmax><mode>3_fpr"
4949 [(set (match_operand:SFDF 0 "gpc_reg_operand")
4950 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand")
4951 (match_operand:SFDF 2 "gpc_reg_operand")))]
4952 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4957 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4961 (define_expand "mov<mode>cc"
4962 [(set (match_operand:GPR 0 "gpc_reg_operand")
4963 (if_then_else:GPR (match_operand 1 "comparison_operator")
4964 (match_operand:GPR 2 "gpc_reg_operand")
4965 (match_operand:GPR 3 "gpc_reg_operand")))]
4968 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4974 ;; We use the BASE_REGS for the isel input operands because, if rA is
4975 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4976 ;; because we may switch the operands and rB may end up being rA.
4978 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4979 ;; leave out the mode in operand 4 and use one pattern, but reload can
4980 ;; change the mode underneath our feet and then gets confused trying
4981 ;; to reload the value.
4982 (define_insn "isel_signed_<mode>"
4983 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4985 (match_operator 1 "scc_comparison_operator"
4986 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4988 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4989 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4992 [(set_attr "type" "isel")])
4994 (define_insn "isel_unsigned_<mode>"
4995 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4997 (match_operator 1 "scc_comparison_operator"
4998 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5000 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
5001 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
5004 [(set_attr "type" "isel")])
5006 ;; These patterns can be useful for combine; they let combine know that
5007 ;; isel can handle reversed comparisons so long as the operands are
5010 (define_insn "*isel_reversed_signed_<mode>"
5011 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5013 (match_operator 1 "scc_rev_comparison_operator"
5014 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5016 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5017 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5020 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5021 return "isel %0,%3,%2,%j1";
5023 [(set_attr "type" "isel")])
5025 (define_insn "*isel_reversed_unsigned_<mode>"
5026 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5028 (match_operator 1 "scc_rev_comparison_operator"
5029 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5031 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5032 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5035 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5036 return "isel %0,%3,%2,%j1";
5038 [(set_attr "type" "isel")])
5040 ;; Floating point conditional move
5041 (define_expand "mov<mode>cc"
5042 [(set (match_operand:SFDF 0 "gpc_reg_operand")
5043 (if_then_else:SFDF (match_operand 1 "comparison_operator")
5044 (match_operand:SFDF 2 "gpc_reg_operand")
5045 (match_operand:SFDF 3 "gpc_reg_operand")))]
5046 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5048 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5054 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5055 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5057 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5058 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5059 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5060 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5061 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5063 [(set_attr "type" "fp")])
5065 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5066 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5068 (match_operator:CCFP 1 "fpmask_comparison_operator"
5069 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5070 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5071 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5072 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5073 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5078 (if_then_else:V2DI (match_dup 1)
5082 (if_then_else:SFDF (ne (match_dup 6)
5087 if (GET_CODE (operands[6]) == SCRATCH)
5088 operands[6] = gen_reg_rtx (V2DImode);
5090 operands[7] = CONSTM1_RTX (V2DImode);
5091 operands[8] = CONST0_RTX (V2DImode);
5093 [(set_attr "length" "8")
5094 (set_attr "type" "vecperm")])
5096 ;; Handle inverting the fpmask comparisons.
5097 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5098 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5100 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5101 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5102 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5103 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5104 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5105 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5110 (if_then_else:V2DI (match_dup 9)
5114 (if_then_else:SFDF (ne (match_dup 6)
5119 rtx op1 = operands[1];
5120 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5122 if (GET_CODE (operands[6]) == SCRATCH)
5123 operands[6] = gen_reg_rtx (V2DImode);
5125 operands[7] = CONSTM1_RTX (V2DImode);
5126 operands[8] = CONST0_RTX (V2DImode);
5128 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5130 [(set_attr "length" "8")
5131 (set_attr "type" "vecperm")])
5133 (define_insn "*fpmask<mode>"
5134 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5136 (match_operator:CCFP 1 "fpmask_comparison_operator"
5137 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5138 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5139 (match_operand:V2DI 4 "all_ones_constant" "")
5140 (match_operand:V2DI 5 "zero_constant" "")))]
5142 "xscmp%V1dp %x0,%x2,%x3"
5143 [(set_attr "type" "fpcompare")])
5145 (define_insn "*xxsel<mode>"
5146 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5147 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5148 (match_operand:V2DI 2 "zero_constant" ""))
5149 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5150 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5152 "xxsel %x0,%x4,%x3,%x1"
5153 [(set_attr "type" "vecmove")])
5156 ;; Conversions to and from floating-point.
5158 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5159 ; don't want to support putting SImode in FPR registers.
5160 (define_insn "lfiwax"
5161 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5162 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5164 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5170 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5172 ; This split must be run before register allocation because it allocates the
5173 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5174 ; it earlier to allow for the combiner to merge insns together where it might
5175 ; not be needed and also in case the insns are deleted as dead code.
5177 (define_insn_and_split "floatsi<mode>2_lfiwax"
5178 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5179 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5180 (clobber (match_scratch:DI 2 "=wi"))]
5181 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5182 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5187 rtx dest = operands[0];
5188 rtx src = operands[1];
5191 if (!MEM_P (src) && TARGET_POWERPC64
5192 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5193 tmp = convert_to_mode (DImode, src, false);
5197 if (GET_CODE (tmp) == SCRATCH)
5198 tmp = gen_reg_rtx (DImode);
5201 src = rs6000_address_for_fpconvert (src);
5202 emit_insn (gen_lfiwax (tmp, src));
5206 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5207 emit_move_insn (stack, src);
5208 emit_insn (gen_lfiwax (tmp, stack));
5211 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5214 [(set_attr "length" "12")
5215 (set_attr "type" "fpload")])
5217 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5218 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5221 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5222 (clobber (match_scratch:DI 2 "=wi"))]
5223 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5228 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5229 if (GET_CODE (operands[2]) == SCRATCH)
5230 operands[2] = gen_reg_rtx (DImode);
5231 if (TARGET_P8_VECTOR)
5232 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5234 emit_insn (gen_lfiwax (operands[2], operands[1]));
5235 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5238 [(set_attr "length" "8")
5239 (set_attr "type" "fpload")])
5241 (define_insn "lfiwzx"
5242 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5243 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5245 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5250 xxextractuw %x0,%x1,4"
5251 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5253 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5254 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5255 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5256 (clobber (match_scratch:DI 2 "=wi"))]
5257 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5262 rtx dest = operands[0];
5263 rtx src = operands[1];
5266 if (!MEM_P (src) && TARGET_POWERPC64
5267 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5268 tmp = convert_to_mode (DImode, src, true);
5272 if (GET_CODE (tmp) == SCRATCH)
5273 tmp = gen_reg_rtx (DImode);
5276 src = rs6000_address_for_fpconvert (src);
5277 emit_insn (gen_lfiwzx (tmp, src));
5281 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5282 emit_move_insn (stack, src);
5283 emit_insn (gen_lfiwzx (tmp, stack));
5286 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5289 [(set_attr "length" "12")
5290 (set_attr "type" "fpload")])
5292 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5293 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5294 (unsigned_float:SFDF
5296 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5297 (clobber (match_scratch:DI 2 "=wi"))]
5298 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5303 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5304 if (GET_CODE (operands[2]) == SCRATCH)
5305 operands[2] = gen_reg_rtx (DImode);
5306 if (TARGET_P8_VECTOR)
5307 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5309 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5310 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5313 [(set_attr "length" "8")
5314 (set_attr "type" "fpload")])
5316 ; For each of these conversions, there is a define_expand, a define_insn
5317 ; with a '#' template, and a define_split (with C code). The idea is
5318 ; to allow constant folding with the template of the define_insn,
5319 ; then to have the insns split later (between sched1 and final).
5321 (define_expand "floatsidf2"
5322 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5323 (float:DF (match_operand:SI 1 "nonimmediate_operand")))
5326 (clobber (match_dup 4))
5327 (clobber (match_dup 5))
5328 (clobber (match_dup 6))])]
5329 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5331 if (TARGET_LFIWAX && TARGET_FCFID)
5333 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5336 else if (TARGET_FCFID)
5338 rtx dreg = operands[1];
5340 dreg = force_reg (SImode, dreg);
5341 dreg = convert_to_mode (DImode, dreg, false);
5342 emit_insn (gen_floatdidf2 (operands[0], dreg));
5346 if (!REG_P (operands[1]))
5347 operands[1] = force_reg (SImode, operands[1]);
5348 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5349 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5350 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5351 operands[5] = gen_reg_rtx (DFmode);
5352 operands[6] = gen_reg_rtx (SImode);
5355 (define_insn_and_split "*floatsidf2_internal"
5356 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5357 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5358 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5359 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5360 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5361 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5362 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5363 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5368 rtx lowword, highword;
5369 gcc_assert (MEM_P (operands[4]));
5370 highword = adjust_address (operands[4], SImode, 0);
5371 lowword = adjust_address (operands[4], SImode, 4);
5372 if (! WORDS_BIG_ENDIAN)
5373 std::swap (lowword, highword);
5375 emit_insn (gen_xorsi3 (operands[6], operands[1],
5376 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5377 emit_move_insn (lowword, operands[6]);
5378 emit_move_insn (highword, operands[2]);
5379 emit_move_insn (operands[5], operands[4]);
5380 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5383 [(set_attr "length" "24")
5384 (set_attr "type" "fp")])
5386 ;; If we don't have a direct conversion to single precision, don't enable this
5387 ;; conversion for 32-bit without fast math, because we don't have the insn to
5388 ;; generate the fixup swizzle to avoid double rounding problems.
5389 (define_expand "floatunssisf2"
5390 [(set (match_operand:SF 0 "gpc_reg_operand")
5391 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand")))]
5392 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5393 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5394 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5395 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5397 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5399 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5404 rtx dreg = operands[1];
5406 dreg = force_reg (SImode, dreg);
5407 dreg = convert_to_mode (DImode, dreg, true);
5408 emit_insn (gen_floatdisf2 (operands[0], dreg));
5413 (define_expand "floatunssidf2"
5414 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand")
5415 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand")))
5418 (clobber (match_dup 4))
5419 (clobber (match_dup 5))])]
5420 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5422 if (TARGET_LFIWZX && TARGET_FCFID)
5424 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5427 else if (TARGET_FCFID)
5429 rtx dreg = operands[1];
5431 dreg = force_reg (SImode, dreg);
5432 dreg = convert_to_mode (DImode, dreg, true);
5433 emit_insn (gen_floatdidf2 (operands[0], dreg));
5437 if (!REG_P (operands[1]))
5438 operands[1] = force_reg (SImode, operands[1]);
5439 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5440 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5441 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5442 operands[5] = gen_reg_rtx (DFmode);
5445 (define_insn_and_split "*floatunssidf2_internal"
5446 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5447 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5448 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5449 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5450 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5451 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5452 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5453 && !(TARGET_FCFID && TARGET_POWERPC64)"
5458 rtx lowword, highword;
5459 gcc_assert (MEM_P (operands[4]));
5460 highword = adjust_address (operands[4], SImode, 0);
5461 lowword = adjust_address (operands[4], SImode, 4);
5462 if (! WORDS_BIG_ENDIAN)
5463 std::swap (lowword, highword);
5465 emit_move_insn (lowword, operands[1]);
5466 emit_move_insn (highword, operands[2]);
5467 emit_move_insn (operands[5], operands[4]);
5468 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5471 [(set_attr "length" "20")
5472 (set_attr "type" "fp")])
5474 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5475 ;; vector registers. These insns favor doing the sign/zero extension in
5476 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5477 ;; extension and then a direct move.
5479 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5480 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5482 (match_operand:QHI 1 "input_operand")))
5483 (clobber (match_scratch:DI 2))
5484 (clobber (match_scratch:DI 3))
5485 (clobber (match_scratch:<QHI:MODE> 4))])]
5486 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5488 if (MEM_P (operands[1]))
5489 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5492 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5493 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5495 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5496 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5497 (clobber (match_scratch:DI 3 "=X,r,X"))
5498 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5499 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5501 "&& reload_completed"
5504 rtx result = operands[0];
5505 rtx input = operands[1];
5506 rtx di = operands[2];
5510 rtx tmp = operands[3];
5511 if (altivec_register_operand (input, <QHI:MODE>mode))
5512 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5513 else if (GET_CODE (tmp) == SCRATCH)
5514 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5517 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5518 emit_move_insn (di, tmp);
5523 rtx tmp = operands[4];
5524 emit_move_insn (tmp, input);
5525 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5528 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5532 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5533 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5534 (unsigned_float:FP_ISA3
5535 (match_operand:QHI 1 "input_operand")))
5536 (clobber (match_scratch:DI 2))
5537 (clobber (match_scratch:DI 3))])]
5538 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5540 if (MEM_P (operands[1]))
5541 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5544 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5545 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5546 (unsigned_float:FP_ISA3
5547 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5548 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5549 (clobber (match_scratch:DI 3 "=X,r,X"))]
5550 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5552 "&& reload_completed"
5555 rtx result = operands[0];
5556 rtx input = operands[1];
5557 rtx di = operands[2];
5559 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5560 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5563 rtx tmp = operands[3];
5564 if (GET_CODE (tmp) == SCRATCH)
5565 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5568 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5569 emit_move_insn (di, tmp);
5573 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5577 (define_expand "fix_trunc<mode>si2"
5578 [(set (match_operand:SI 0 "gpc_reg_operand")
5579 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5580 "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5582 if (!TARGET_P8_VECTOR)
5584 rtx src = force_reg (<MODE>mode, operands[1]);
5587 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5590 rtx tmp = gen_reg_rtx (DImode);
5591 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5592 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5599 ; Like the convert to float patterns, this insn must be split before
5600 ; register allocation so that it can allocate the memory slot if it
5602 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5603 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5604 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5605 (clobber (match_scratch:DI 2 "=d"))]
5606 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5607 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5608 && TARGET_STFIWX && can_create_pseudo_p ()
5609 && !TARGET_P8_VECTOR"
5614 rtx dest = operands[0];
5615 rtx src = operands[1];
5616 rtx tmp = operands[2];
5618 if (GET_CODE (tmp) == SCRATCH)
5619 tmp = gen_reg_rtx (DImode);
5621 emit_insn (gen_fctiwz_<mode> (tmp, src));
5624 dest = rs6000_address_for_fpconvert (dest);
5625 emit_insn (gen_stfiwx (dest, tmp));
5628 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5630 dest = gen_lowpart (DImode, dest);
5631 emit_move_insn (dest, tmp);
5636 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5637 emit_insn (gen_stfiwx (stack, tmp));
5638 emit_move_insn (dest, stack);
5642 [(set_attr "length" "12")
5643 (set_attr "type" "fp")])
5645 (define_insn_and_split "fix_trunc<mode>si2_internal"
5646 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5647 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5648 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5649 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5650 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
5656 gcc_assert (MEM_P (operands[3]));
5657 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5659 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5660 emit_move_insn (operands[3], operands[2]);
5661 emit_move_insn (operands[0], lowword);
5664 [(set_attr "length" "16")
5665 (set_attr "type" "fp")])
5667 (define_expand "fix_trunc<mode>di2"
5668 [(set (match_operand:DI 0 "gpc_reg_operand")
5669 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand")))]
5670 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5673 (define_insn "*fix_trunc<mode>di2_fctidz"
5674 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5675 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5676 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5680 [(set_attr "type" "fp")])
5682 ;; If we have ISA 3.0, QI/HImode values can go in both VSX registers and GPR
5683 ;; registers. If we have ISA 2.07, we don't allow QI/HImode values in the
5684 ;; vector registers, so we need to do direct moves to the GPRs, but SImode
5685 ;; values can go in VSX registers. Keeping the direct move part through
5686 ;; register allocation prevents the register allocator from doing a direct move
5687 ;; of the SImode value to a GPR, and then a store/load.
5688 (define_insn_and_split "fix<uns>_trunc<SFDF:mode><QHI:mode>2"
5689 [(set (match_operand:<QHI:MODE> 0 "gpc_reg_operand" "=wJ,wJwK,r")
5690 (any_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand" "wJ,wJwK,wa")))
5691 (clobber (match_scratch:SI 2 "=X,X,wi"))]
5692 "TARGET_DIRECT_MOVE"
5695 xscvdp<su>xws %x0,%x1
5697 "&& reload_completed && int_reg_operand (operands[0], <QHI:MODE>mode)"
5699 (any_fix:SI (match_dup 1)))
5703 operands[3] = gen_rtx_REG (SImode, REGNO (operands[0]));
5705 [(set_attr "length" "4,4,8")
5706 (set_attr "type" "fp")])
5708 (define_insn "*fix<uns>_trunc<SFDF:mode>si2_p8"
5709 [(set (match_operand:SI 0 "gpc_reg_operand" "=d,wa")
5710 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,wa")))]
5711 "TARGET_DIRECT_MOVE"
5714 xscvdp<su>xws %x0,%x1"
5715 [(set_attr "type" "fp")])
5717 ;; Keep the convert and store together through register allocation to prevent
5718 ;; the register allocator from getting clever and doing a direct move to a GPR
5719 ;; and then store for reg+offset stores.
5720 (define_insn_and_split "*fix<uns>_trunc<SFDF:mode><QHSI:mode>2_mem"
5721 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
5722 (any_fix:QHSI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5723 (clobber (match_scratch:SI 2 "=wa"))]
5724 "(<QHSI:MODE>mode == SImode && TARGET_P8_VECTOR) || TARGET_P9_VECTOR"
5726 "&& reload_completed"
5728 (any_fix:SI (match_dup 1)))
5732 operands[3] = (<QHSI:MODE>mode == SImode
5734 : gen_rtx_REG (<QHSI:MODE>mode, REGNO (operands[2])));
5737 (define_expand "fixuns_trunc<mode>si2"
5738 [(set (match_operand:SI 0 "gpc_reg_operand")
5739 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand")))]
5740 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5742 if (!TARGET_P8_VECTOR)
5744 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5749 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5750 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5751 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5752 (clobber (match_scratch:DI 2 "=d"))]
5753 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5754 && TARGET_STFIWX && can_create_pseudo_p ()
5755 && !TARGET_P8_VECTOR"
5760 rtx dest = operands[0];
5761 rtx src = operands[1];
5762 rtx tmp = operands[2];
5764 if (GET_CODE (tmp) == SCRATCH)
5765 tmp = gen_reg_rtx (DImode);
5767 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5770 dest = rs6000_address_for_fpconvert (dest);
5771 emit_insn (gen_stfiwx (dest, tmp));
5774 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5776 dest = gen_lowpart (DImode, dest);
5777 emit_move_insn (dest, tmp);
5782 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5783 emit_insn (gen_stfiwx (stack, tmp));
5784 emit_move_insn (dest, stack);
5788 [(set_attr "length" "12")
5789 (set_attr "type" "fp")])
5791 (define_insn "fixuns_trunc<mode>di2"
5792 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5793 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5794 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5798 [(set_attr "type" "fp")])
5800 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5801 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5802 ;; because the first makes it clear that operand 0 is not live
5803 ;; before the instruction.
5804 (define_insn "fctiwz_<mode>"
5805 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5807 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5809 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5813 [(set_attr "type" "fp")])
5815 (define_insn "fctiwuz_<mode>"
5816 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5817 (unspec:DI [(unsigned_fix:SI
5818 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5820 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5824 [(set_attr "type" "fp")])
5826 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5827 ;; since the friz instruction does not truncate the value if the floating
5828 ;; point value is < LONG_MIN or > LONG_MAX.
5829 (define_insn "*friz"
5830 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5831 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5832 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5833 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5837 [(set_attr "type" "fp")])
5839 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5840 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5841 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5842 ;; extend it, store it back on the stack from the GPR, load it back into the
5843 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5844 ;; disable using store and load to sign/zero extend the value.
5845 (define_insn_and_split "*round32<mode>2_fprs"
5846 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5848 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5849 (clobber (match_scratch:DI 2 "=d"))
5850 (clobber (match_scratch:DI 3 "=d"))]
5851 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5852 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5853 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5858 rtx dest = operands[0];
5859 rtx src = operands[1];
5860 rtx tmp1 = operands[2];
5861 rtx tmp2 = operands[3];
5862 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5864 if (GET_CODE (tmp1) == SCRATCH)
5865 tmp1 = gen_reg_rtx (DImode);
5866 if (GET_CODE (tmp2) == SCRATCH)
5867 tmp2 = gen_reg_rtx (DImode);
5869 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5870 emit_insn (gen_stfiwx (stack, tmp1));
5871 emit_insn (gen_lfiwax (tmp2, stack));
5872 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5875 [(set_attr "type" "fpload")
5876 (set_attr "length" "16")])
5878 (define_insn_and_split "*roundu32<mode>2_fprs"
5879 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5880 (unsigned_float:SFDF
5881 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5882 (clobber (match_scratch:DI 2 "=d"))
5883 (clobber (match_scratch:DI 3 "=d"))]
5884 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5885 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5886 && can_create_pseudo_p ()"
5891 rtx dest = operands[0];
5892 rtx src = operands[1];
5893 rtx tmp1 = operands[2];
5894 rtx tmp2 = operands[3];
5895 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5897 if (GET_CODE (tmp1) == SCRATCH)
5898 tmp1 = gen_reg_rtx (DImode);
5899 if (GET_CODE (tmp2) == SCRATCH)
5900 tmp2 = gen_reg_rtx (DImode);
5902 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5903 emit_insn (gen_stfiwx (stack, tmp1));
5904 emit_insn (gen_lfiwzx (tmp2, stack));
5905 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5908 [(set_attr "type" "fpload")
5909 (set_attr "length" "16")])
5911 (define_insn "lrintsfsi2"
5912 [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
5913 (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")]
5915 "TARGET_SF_FPR && TARGET_FPRND"
5917 [(set_attr "type" "fp")])
5919 ;; No VSX equivalent to fctid
5920 (define_insn "lrint<mode>di2"
5921 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5922 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5924 "TARGET_<MODE>_FPR && TARGET_FPRND"
5926 [(set_attr "type" "fp")])
5928 (define_insn "btrunc<mode>2"
5929 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5930 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5932 "TARGET_<MODE>_FPR && TARGET_FPRND"
5936 [(set_attr "type" "fp")
5937 (set_attr "fp_type" "fp_addsub_<Fs>")])
5939 (define_insn "ceil<mode>2"
5940 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5941 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5943 "TARGET_<MODE>_FPR && TARGET_FPRND"
5947 [(set_attr "type" "fp")
5948 (set_attr "fp_type" "fp_addsub_<Fs>")])
5950 (define_insn "floor<mode>2"
5951 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5952 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5954 "TARGET_<MODE>_FPR && TARGET_FPRND"
5958 [(set_attr "type" "fp")
5959 (set_attr "fp_type" "fp_addsub_<Fs>")])
5961 ;; No VSX equivalent to frin
5962 (define_insn "round<mode>2"
5963 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
5964 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5966 "TARGET_<MODE>_FPR && TARGET_FPRND"
5968 [(set_attr "type" "fp")
5969 (set_attr "fp_type" "fp_addsub_<Fs>")])
5971 (define_insn "*xsrdpi<mode>2"
5972 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5973 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
5975 "TARGET_<MODE>_FPR && TARGET_VSX"
5977 [(set_attr "type" "fp")
5978 (set_attr "fp_type" "fp_addsub_<Fs>")])
5980 (define_expand "lround<mode>di2"
5982 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand")]
5984 (set (match_operand:DI 0 "gpc_reg_operand")
5985 (unspec:DI [(match_dup 2)]
5987 "TARGET_<MODE>_FPR && TARGET_VSX"
5989 operands[2] = gen_reg_rtx (<MODE>mode);
5992 ; An UNSPEC is used so we don't have to support SImode in FP registers.
5993 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
5994 ; is only generated for Power8 or later.
5995 (define_insn "stfiwx"
5996 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
5997 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6003 [(set_attr "type" "fpstore")])
6005 ;; If we don't have a direct conversion to single precision, don't enable this
6006 ;; conversion for 32-bit without fast math, because we don't have the insn to
6007 ;; generate the fixup swizzle to avoid double rounding problems.
6008 (define_expand "floatsisf2"
6009 [(set (match_operand:SF 0 "gpc_reg_operand")
6010 (float:SF (match_operand:SI 1 "nonimmediate_operand")))]
6011 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6012 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6013 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6014 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6016 if (TARGET_FCFIDS && TARGET_LFIWAX)
6018 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6021 else if (TARGET_FCFID && TARGET_LFIWAX)
6023 rtx dfreg = gen_reg_rtx (DFmode);
6024 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6025 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6030 rtx dreg = operands[1];
6032 dreg = force_reg (SImode, dreg);
6033 dreg = convert_to_mode (DImode, dreg, false);
6034 emit_insn (gen_floatdisf2 (operands[0], dreg));
6039 (define_insn "floatdidf2"
6040 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6041 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6042 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6046 [(set_attr "type" "fp")])
6048 ; Allow the combiner to merge source memory operands to the conversion so that
6049 ; the optimizer/register allocator doesn't try to load the value too early in a
6050 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6051 ; hit. We will split after reload to avoid the trip through the GPRs
6053 (define_insn_and_split "*floatdidf2_mem"
6054 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6055 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6056 (clobber (match_scratch:DI 2 "=d,wi"))]
6057 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6059 "&& reload_completed"
6060 [(set (match_dup 2) (match_dup 1))
6061 (set (match_dup 0) (float:DF (match_dup 2)))]
6063 [(set_attr "length" "8")
6064 (set_attr "type" "fpload")])
6066 (define_expand "floatunsdidf2"
6067 [(set (match_operand:DF 0 "gpc_reg_operand")
6069 (match_operand:DI 1 "gpc_reg_operand")))]
6070 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6073 (define_insn "*floatunsdidf2_fcfidu"
6074 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6075 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6076 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6080 [(set_attr "type" "fp")
6081 (set_attr "length" "4")])
6083 (define_insn_and_split "*floatunsdidf2_mem"
6084 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6085 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6086 (clobber (match_scratch:DI 2 "=d,wi"))]
6087 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6089 "&& reload_completed"
6090 [(set (match_dup 2) (match_dup 1))
6091 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6093 [(set_attr "length" "8")
6094 (set_attr "type" "fpload")])
6096 (define_expand "floatdisf2"
6097 [(set (match_operand:SF 0 "gpc_reg_operand")
6098 (float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6099 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6100 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6104 rtx val = operands[1];
6105 if (!flag_unsafe_math_optimizations)
6107 rtx label = gen_label_rtx ();
6108 val = gen_reg_rtx (DImode);
6109 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6112 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6117 (define_insn "floatdisf2_fcfids"
6118 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6119 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6120 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6121 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6125 [(set_attr "type" "fp")])
6127 (define_insn_and_split "*floatdisf2_mem"
6128 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6129 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6130 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6131 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6132 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6134 "&& reload_completed"
6137 emit_move_insn (operands[2], operands[1]);
6138 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6141 [(set_attr "length" "8")])
6143 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6144 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6145 ;; from double rounding.
6146 ;; Instead of creating a new cpu type for two FP operations, just use fp
6147 (define_insn_and_split "floatdisf2_internal1"
6148 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6149 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6150 (clobber (match_scratch:DF 2 "=d"))]
6151 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6153 "&& reload_completed"
6155 (float:DF (match_dup 1)))
6157 (float_truncate:SF (match_dup 2)))]
6159 [(set_attr "length" "8")
6160 (set_attr "type" "fp")])
6162 ;; Twiddles bits to avoid double rounding.
6163 ;; Bits that might be truncated when converting to DFmode are replaced
6164 ;; by a bit that won't be lost at that stage, but is below the SFmode
6165 ;; rounding position.
6166 (define_expand "floatdisf2_internal2"
6167 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "")
6169 (clobber (reg:DI CA_REGNO))])
6170 (set (match_operand:DI 0 "") (and:DI (match_dup 1)
6172 (set (match_dup 3) (plus:DI (match_dup 3)
6174 (set (match_dup 0) (plus:DI (match_dup 0)
6176 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6178 (set (match_dup 0) (ior:DI (match_dup 0)
6180 (set (match_dup 0) (and:DI (match_dup 0)
6182 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6183 (label_ref (match_operand:DI 2 ""))
6185 (set (match_dup 0) (match_dup 1))]
6186 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6189 operands[3] = gen_reg_rtx (DImode);
6190 operands[4] = gen_reg_rtx (CCUNSmode);
6193 (define_expand "floatunsdisf2"
6194 [(set (match_operand:SF 0 "gpc_reg_operand")
6195 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand")))]
6196 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6197 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6200 (define_insn "floatunsdisf2_fcfidus"
6201 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6202 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6203 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6204 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6208 [(set_attr "type" "fp")])
6210 (define_insn_and_split "*floatunsdisf2_mem"
6211 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6212 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6213 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6214 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6215 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6217 "&& reload_completed"
6220 emit_move_insn (operands[2], operands[1]);
6221 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6224 [(set_attr "length" "8")
6225 (set_attr "type" "fpload")])
6227 ;; Define the TImode operations that can be done in a small number
6228 ;; of instructions. The & constraints are to prevent the register
6229 ;; allocator from allocating registers that overlap with the inputs
6230 ;; (for example, having an input in 7,8 and an output in 6,7). We
6231 ;; also allow for the output being the same as one of the inputs.
6233 (define_expand "addti3"
6234 [(set (match_operand:TI 0 "gpc_reg_operand")
6235 (plus:TI (match_operand:TI 1 "gpc_reg_operand")
6236 (match_operand:TI 2 "reg_or_short_operand")))]
6239 rtx lo0 = gen_lowpart (DImode, operands[0]);
6240 rtx lo1 = gen_lowpart (DImode, operands[1]);
6241 rtx lo2 = gen_lowpart (DImode, operands[2]);
6242 rtx hi0 = gen_highpart (DImode, operands[0]);
6243 rtx hi1 = gen_highpart (DImode, operands[1]);
6244 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6246 if (!reg_or_short_operand (lo2, DImode))
6247 lo2 = force_reg (DImode, lo2);
6248 if (!adde_operand (hi2, DImode))
6249 hi2 = force_reg (DImode, hi2);
6251 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6252 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6256 (define_expand "subti3"
6257 [(set (match_operand:TI 0 "gpc_reg_operand")
6258 (minus:TI (match_operand:TI 1 "reg_or_short_operand")
6259 (match_operand:TI 2 "gpc_reg_operand")))]
6262 rtx lo0 = gen_lowpart (DImode, operands[0]);
6263 rtx lo1 = gen_lowpart (DImode, operands[1]);
6264 rtx lo2 = gen_lowpart (DImode, operands[2]);
6265 rtx hi0 = gen_highpart (DImode, operands[0]);
6266 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6267 rtx hi2 = gen_highpart (DImode, operands[2]);
6269 if (!reg_or_short_operand (lo1, DImode))
6270 lo1 = force_reg (DImode, lo1);
6271 if (!adde_operand (hi1, DImode))
6272 hi1 = force_reg (DImode, hi1);
6274 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6275 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6279 ;; 128-bit logical operations expanders
6281 (define_expand "and<mode>3"
6282 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6283 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6284 (match_operand:BOOL_128 2 "vlogical_operand")))]
6288 (define_expand "ior<mode>3"
6289 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6290 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6291 (match_operand:BOOL_128 2 "vlogical_operand")))]
6295 (define_expand "xor<mode>3"
6296 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6297 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6298 (match_operand:BOOL_128 2 "vlogical_operand")))]
6302 (define_expand "one_cmpl<mode>2"
6303 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6304 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")))]
6308 (define_expand "nor<mode>3"
6309 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6311 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6312 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6316 (define_expand "andc<mode>3"
6317 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6319 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6320 (match_operand:BOOL_128 1 "vlogical_operand")))]
6324 ;; Power8 vector logical instructions.
6325 (define_expand "eqv<mode>3"
6326 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6328 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand")
6329 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6330 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6333 ;; Rewrite nand into canonical form
6334 (define_expand "nand<mode>3"
6335 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6337 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand"))
6338 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))))]
6339 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6342 ;; The canonical form is to have the negated element first, so we need to
6343 ;; reverse arguments.
6344 (define_expand "orc<mode>3"
6345 [(set (match_operand:BOOL_128 0 "vlogical_operand")
6347 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand"))
6348 (match_operand:BOOL_128 1 "vlogical_operand")))]
6349 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6352 ;; 128-bit logical operations insns and split operations
6353 (define_insn_and_split "*and<mode>3_internal"
6354 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6356 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6357 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6360 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6361 return "xxland %x0,%x1,%x2";
6363 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6364 return "vand %0,%1,%2";
6368 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6371 rs6000_split_logical (operands, AND, false, false, false);
6376 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6377 (const_string "veclogical")
6378 (const_string "integer")))
6379 (set (attr "length")
6381 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6384 (match_test "TARGET_POWERPC64")
6386 (const_string "16"))))])
6389 (define_insn_and_split "*bool<mode>3_internal"
6390 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6391 (match_operator:BOOL_128 3 "boolean_or_operator"
6392 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6393 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6396 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6397 return "xxl%q3 %x0,%x1,%x2";
6399 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6400 return "v%q3 %0,%1,%2";
6404 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6407 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6412 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6413 (const_string "veclogical")
6414 (const_string "integer")))
6415 (set (attr "length")
6417 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6420 (match_test "TARGET_POWERPC64")
6422 (const_string "16"))))])
6425 (define_insn_and_split "*boolc<mode>3_internal1"
6426 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6427 (match_operator:BOOL_128 3 "boolean_operator"
6429 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6430 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6431 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6433 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6434 return "xxl%q3 %x0,%x1,%x2";
6436 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6437 return "v%q3 %0,%1,%2";
6441 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6442 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6445 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6450 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6451 (const_string "veclogical")
6452 (const_string "integer")))
6453 (set (attr "length")
6455 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6458 (match_test "TARGET_POWERPC64")
6460 (const_string "16"))))])
6462 (define_insn_and_split "*boolc<mode>3_internal2"
6463 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6464 (match_operator:TI2 3 "boolean_operator"
6466 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6467 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6468 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6470 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6473 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6476 [(set_attr "type" "integer")
6477 (set (attr "length")
6479 (match_test "TARGET_POWERPC64")
6481 (const_string "16")))])
6484 (define_insn_and_split "*boolcc<mode>3_internal1"
6485 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6486 (match_operator:BOOL_128 3 "boolean_operator"
6488 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6490 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6491 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6493 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6494 return "xxl%q3 %x0,%x1,%x2";
6496 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6497 return "v%q3 %0,%1,%2";
6501 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6502 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6505 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6510 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6511 (const_string "veclogical")
6512 (const_string "integer")))
6513 (set (attr "length")
6515 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6518 (match_test "TARGET_POWERPC64")
6520 (const_string "16"))))])
6522 (define_insn_and_split "*boolcc<mode>3_internal2"
6523 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6524 (match_operator:TI2 3 "boolean_operator"
6526 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6528 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6529 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6531 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6534 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6537 [(set_attr "type" "integer")
6538 (set (attr "length")
6540 (match_test "TARGET_POWERPC64")
6542 (const_string "16")))])
6546 (define_insn_and_split "*eqv<mode>3_internal1"
6547 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6550 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6551 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6554 if (vsx_register_operand (operands[0], <MODE>mode))
6555 return "xxleqv %x0,%x1,%x2";
6559 "TARGET_P8_VECTOR && reload_completed
6560 && int_reg_operand (operands[0], <MODE>mode)"
6563 rs6000_split_logical (operands, XOR, true, false, false);
6568 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6569 (const_string "veclogical")
6570 (const_string "integer")))
6571 (set (attr "length")
6573 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6576 (match_test "TARGET_POWERPC64")
6578 (const_string "16"))))])
6580 (define_insn_and_split "*eqv<mode>3_internal2"
6581 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6584 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6585 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6588 "reload_completed && !TARGET_P8_VECTOR"
6591 rs6000_split_logical (operands, XOR, true, false, false);
6594 [(set_attr "type" "integer")
6595 (set (attr "length")
6597 (match_test "TARGET_POWERPC64")
6599 (const_string "16")))])
6601 ;; 128-bit one's complement
6602 (define_insn_and_split "*one_cmpl<mode>3_internal"
6603 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6605 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6608 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6609 return "xxlnor %x0,%x1,%x1";
6611 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6612 return "vnor %0,%1,%1";
6616 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6619 rs6000_split_logical (operands, NOT, false, false, false);
6624 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6625 (const_string "veclogical")
6626 (const_string "integer")))
6627 (set (attr "length")
6629 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6632 (match_test "TARGET_POWERPC64")
6634 (const_string "16"))))])
6637 ;; Now define ways of moving data around.
6639 ;; Set up a register with a value from the GOT table
6641 (define_expand "movsi_got"
6642 [(set (match_operand:SI 0 "gpc_reg_operand")
6643 (unspec:SI [(match_operand:SI 1 "got_operand")
6644 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6645 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6647 if (GET_CODE (operands[1]) == CONST)
6649 rtx offset = const0_rtx;
6650 HOST_WIDE_INT value;
6652 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6653 value = INTVAL (offset);
6656 rtx tmp = (!can_create_pseudo_p ()
6658 : gen_reg_rtx (Pmode));
6659 emit_insn (gen_movsi_got (tmp, operands[1]));
6660 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6665 operands[2] = rs6000_got_register (operands[1]);
6668 (define_insn "*movsi_got_internal"
6669 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6670 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6671 (match_operand:SI 2 "gpc_reg_operand" "b")]
6673 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6674 "lwz %0,%a1@got(%2)"
6675 [(set_attr "type" "load")])
6677 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6678 ;; didn't get allocated to a hard register.
6680 [(set (match_operand:SI 0 "gpc_reg_operand")
6681 (unspec:SI [(match_operand:SI 1 "got_no_const_operand")
6682 (match_operand:SI 2 "memory_operand")]
6684 "DEFAULT_ABI == ABI_V4
6686 && reload_completed"
6687 [(set (match_dup 0) (match_dup 2))
6688 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6692 ;; For SI, we special-case integers that can't be loaded in one insn. We
6693 ;; do the load 16-bits at a time. We could do this by loading from memory,
6694 ;; and this is even supposed to be faster, but it is simpler not to get
6695 ;; integers in the TOC.
6696 (define_insn "movsi_low"
6697 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6698 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6699 (match_operand 2 "" ""))))]
6700 "TARGET_MACHO && ! TARGET_64BIT"
6701 "lwz %0,lo16(%2)(%1)"
6702 [(set_attr "type" "load")
6703 (set_attr "length" "4")])
6705 ;; MR LA LWZ LFIWZX LXSIWZX
6706 ;; STW STFIWX STXSIWX LI LIS
6707 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6708 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6709 ;; MF%1 MT%0 MT%0 NOP
6710 (define_insn "*movsi_internal1"
6711 [(set (match_operand:SI 0 "nonimmediate_operand"
6712 "=r, r, r, ?*wI, ?*wH,
6714 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6715 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6718 (match_operand:SI 1 "input_operand"
6725 "!TARGET_SINGLE_FPU &&
6726 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6753 "*, *, load, fpload, fpload,
6754 store, fpstore, fpstore, *, *,
6755 *, veclogical, vecsimple, vecsimple, vecsimple,
6756 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6766 (define_insn "*movsi_internal1_single"
6767 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6768 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6769 "TARGET_SINGLE_FPU &&
6770 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6785 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6786 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6788 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6789 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6791 ;; Because SF values are actually stored as DF values within the vector
6792 ;; registers, we need to convert the value to the vector SF format when
6793 ;; we need to use the bits in a union or similar cases. We only need
6794 ;; to do this transformation when the value is a vector register. Loads,
6795 ;; stores, and transfers within GPRs are assumed to be safe.
6797 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6798 ;; no alternatives, because the call is created as part of secondary_reload,
6799 ;; and operand #2's register class is used to allocate the temporary register.
6800 ;; This function is called before reload, and it creates the temporary as
6803 ;; MR LWZ LFIWZX LXSIWZX STW
6804 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6807 (define_insn_and_split "movsi_from_sf"
6808 [(set (match_operand:SI 0 "nonimmediate_operand"
6809 "=r, r, ?*wI, ?*wH, m,
6810 m, wY, Z, r, ?*wIwH,
6813 (unspec:SI [(match_operand:SF 1 "input_operand"
6815 f, wb, wu, wIwH, wIwH,
6819 (clobber (match_scratch:V4SF 2
6824 "TARGET_NO_SF_SUBREG
6825 && (register_operand (operands[0], SImode)
6826 || register_operand (operands[1], SFmode))"
6839 "&& reload_completed
6840 && int_reg_operand (operands[0], SImode)
6841 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6844 rtx op0 = operands[0];
6845 rtx op1 = operands[1];
6846 rtx op2 = operands[2];
6847 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6848 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6850 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6851 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6855 "*, load, fpload, fpload, store,
6856 fpstore, fpstore, fpstore, mftgpr, fp,
6864 ;; movsi_from_sf with zero extension
6866 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6869 (define_insn_and_split "*movdi_from_sf_zero_ext"
6870 [(set (match_operand:DI 0 "gpc_reg_operand"
6871 "=r, r, ?*wI, ?*wH, r,
6875 (unspec:SI [(match_operand:SF 1 "input_operand"
6878 UNSPEC_SI_FROM_SF)))
6880 (clobber (match_scratch:V4SF 2
6884 "TARGET_DIRECT_MOVE_64BIT
6885 && (register_operand (operands[0], DImode)
6886 || register_operand (operands[1], SImode))"
6895 "&& reload_completed
6896 && register_operand (operands[0], DImode)
6897 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6900 rtx op0 = operands[0];
6901 rtx op1 = operands[1];
6902 rtx op2 = operands[2];
6903 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6905 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6906 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6910 "*, load, fpload, fpload, two,
6917 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6918 ;; moving it to SImode. We can do a SFmode store without having to do the
6919 ;; conversion explicitly. If we are doing a register->register conversion, use
6920 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6921 ;; input will not fit in a SFmode, and the later assumes the value has already
6923 (define_insn "*movsi_from_df"
6924 [(set (match_operand:SI 0 "nonimmediate_operand" "=wa,m,wY,Z")
6925 (unspec:SI [(float_truncate:SF
6926 (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6927 UNSPEC_SI_FROM_SF))]
6929 "TARGET_NO_SF_SUBREG"
6935 [(set_attr "type" "fp,fpstore,fpstore,fpstore")])
6937 ;; Split a load of a large constant into the appropriate two-insn
6941 [(set (match_operand:SI 0 "gpc_reg_operand")
6942 (match_operand:SI 1 "const_int_operand"))]
6943 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6944 && (INTVAL (operands[1]) & 0xffff) != 0"
6948 (ior:SI (match_dup 0)
6951 if (rs6000_emit_set_const (operands[0], operands[1]))
6957 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
6959 [(set (match_operand:DI 0 "altivec_register_operand")
6960 (match_operand:DI 1 "xxspltib_constant_split"))]
6961 "TARGET_P9_VECTOR && reload_completed"
6964 rtx op0 = operands[0];
6965 rtx op1 = operands[1];
6966 int r = REGNO (op0);
6967 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
6969 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
6970 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
6974 (define_insn "*mov<mode>_internal2"
6975 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
6976 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
6978 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
6984 [(set_attr "type" "cmp,logical,cmp")
6985 (set_attr "dot" "yes")
6986 (set_attr "length" "4,4,8")])
6989 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
6990 (compare:CC (match_operand:P 1 "gpc_reg_operand")
6992 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
6994 [(set (match_dup 0) (match_dup 1))
6996 (compare:CC (match_dup 0)
7000 (define_expand "mov<mode>"
7001 [(set (match_operand:INT 0 "general_operand")
7002 (match_operand:INT 1 "any_operand"))]
7005 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7009 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7010 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7011 ;; MTVSRWZ MF%1 MT%1 NOP
7012 (define_insn "*mov<mode>_internal"
7013 [(set (match_operand:QHI 0 "nonimmediate_operand"
7014 "=r, r, ?*wJwK, m, Z, r,
7015 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7016 ?*wJwK, r, *c*l, *h")
7018 (match_operand:QHI 1 "input_operand"
7019 "r, m, Z, r, wJwK, i,
7020 wJwK, O, wM, wB, wS, ?*wJwK,
7023 "gpc_reg_operand (operands[0], <MODE>mode)
7024 || gpc_reg_operand (operands[1], <MODE>mode)"
7043 "*, load, fpload, store, fpstore, *,
7044 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7045 mffgpr, mfjmpr, mtjmpr, *")
7053 ;; Here is how to move condition codes around. When we store CC data in
7054 ;; an integer register or memory, we store just the high-order 4 bits.
7055 ;; This lets us not shift in the most common case of CR0.
7056 (define_expand "movcc"
7057 [(set (match_operand:CC 0 "nonimmediate_operand")
7058 (match_operand:CC 1 "nonimmediate_operand"))]
7062 (define_insn "*movcc_internal1"
7063 [(set (match_operand:CC 0 "nonimmediate_operand"
7064 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7065 (match_operand:CC 1 "general_operand"
7066 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7067 "register_operand (operands[0], CCmode)
7068 || register_operand (operands[1], CCmode)"
7072 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7075 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7083 (cond [(eq_attr "alternative" "0,3")
7084 (const_string "cr_logical")
7085 (eq_attr "alternative" "1,2")
7086 (const_string "mtcr")
7087 (eq_attr "alternative" "6,7")
7088 (const_string "integer")
7089 (eq_attr "alternative" "8")
7090 (const_string "mfjmpr")
7091 (eq_attr "alternative" "9")
7092 (const_string "mtjmpr")
7093 (eq_attr "alternative" "10")
7094 (const_string "load")
7095 (eq_attr "alternative" "11")
7096 (const_string "store")
7097 (match_test "TARGET_MFCRF")
7098 (const_string "mfcrf")
7100 (const_string "mfcr")))
7101 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7103 ;; For floating-point, we normally deal with the floating-point registers
7104 ;; unless -msoft-float is used. The sole exception is that parameter passing
7105 ;; can produce floating-point values in fixed-point registers. Unless the
7106 ;; value is a simple constant or already in memory, we deal with this by
7107 ;; allocating memory and copying the value explicitly via that memory location.
7109 ;; Move 32-bit binary/decimal floating point
7110 (define_expand "mov<mode>"
7111 [(set (match_operand:FMOVE32 0 "nonimmediate_operand")
7112 (match_operand:FMOVE32 1 "any_operand"))]
7115 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7120 [(set (match_operand:FMOVE32 0 "gpc_reg_operand")
7121 (match_operand:FMOVE32 1 "const_double_operand"))]
7123 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7124 || (GET_CODE (operands[0]) == SUBREG
7125 && GET_CODE (SUBREG_REG (operands[0])) == REG
7126 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7127 [(set (match_dup 2) (match_dup 3))]
7131 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7133 if (! TARGET_POWERPC64)
7134 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7136 operands[2] = gen_lowpart (SImode, operands[0]);
7138 operands[3] = gen_int_mode (l, SImode);
7141 ;; Originally, we tried to keep movsf and movsd common, but the differences
7142 ;; addressing was making it rather difficult to hide with mode attributes. In
7143 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7144 ;; before the VSX stores meant that the register allocator would tend to do a
7145 ;; direct move to the GPR (which involves conversion from scalar to
7146 ;; vector/memory formats) to save values in the traditional Altivec registers,
7147 ;; while SDmode had problems on power6 if the GPR store was not first due to
7148 ;; the power6 not having an integer store operation.
7150 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7151 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7152 ;; MR MT<x> MF<x> NOP
7154 (define_insn "movsf_hardfloat"
7155 [(set (match_operand:SF 0 "nonimmediate_operand"
7156 "=!r, f, wb, wu, m, wY,
7157 Z, m, ww, !r, f, ww,
7159 (match_operand:SF 1 "input_operand"
7160 "m, m, wY, Z, f, wb,
7163 "(register_operand (operands[0], SFmode)
7164 || register_operand (operands[1], SFmode))
7165 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7166 && (TARGET_ALLOW_SF_SUBREG
7167 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7180 xscpsgndp %x0,%x1,%x1
7186 "load, fpload, fpload, fpload, fpstore, fpstore,
7187 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7188 *, mtjmpr, mfjmpr, *")])
7190 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7191 ;; FMR MR MT%0 MF%1 NOP
7192 (define_insn "movsd_hardfloat"
7193 [(set (match_operand:SD 0 "nonimmediate_operand"
7194 "=!r, wz, m, Z, ?wh, ?r,
7195 f, !r, *c*l, !r, *h")
7196 (match_operand:SD 1 "input_operand"
7197 "m, Z, r, wx, r, wh,
7199 "(register_operand (operands[0], SDmode)
7200 || register_operand (operands[1], SDmode))
7201 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7215 "load, fpload, store, fpstore, mffgpr, mftgpr,
7216 fpsimple, *, mtjmpr, mfjmpr, *")])
7218 (define_insn "*mov<mode>_softfloat"
7219 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7220 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7221 "(gpc_reg_operand (operands[0], <MODE>mode)
7222 || gpc_reg_operand (operands[1], <MODE>mode))
7223 && TARGET_SOFT_FLOAT"
7235 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7236 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7238 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7239 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7241 ;; Because SF values are actually stored as DF values within the vector
7242 ;; registers, we need to convert the value to the vector SF format when
7243 ;; we need to use the bits in a union or similar cases. We only need
7244 ;; to do this transformation when the value is a vector register. Loads,
7245 ;; stores, and transfers within GPRs are assumed to be safe.
7247 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7248 ;; no alternatives, because the call is created as part of secondary_reload,
7249 ;; and operand #2's register class is used to allocate the temporary register.
7250 ;; This function is called before reload, and it creates the temporary as
7253 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7254 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7255 (define_insn_and_split "movsf_from_si"
7256 [(set (match_operand:SF 0 "nonimmediate_operand"
7257 "=!r, f, wb, wu, m, Z,
7260 (unspec:SF [(match_operand:SI 1 "input_operand"
7265 (clobber (match_scratch:DI 2
7269 "TARGET_NO_SF_SUBREG
7270 && (register_operand (operands[0], SFmode)
7271 || register_operand (operands[1], SImode))"
7284 "&& reload_completed
7285 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7286 && int_reg_operand_not_pseudo (operands[1], SImode)"
7289 rtx op0 = operands[0];
7290 rtx op1 = operands[1];
7291 rtx op2 = operands[2];
7292 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7294 /* Move SF value to upper 32-bits for xscvspdpn. */
7295 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7296 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7297 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7304 "load, fpload, fpload, fpload, store, fpstore,
7305 fpstore, vecfloat, mffgpr, *")])
7308 ;; Move 64-bit binary/decimal floating point
7309 (define_expand "mov<mode>"
7310 [(set (match_operand:FMOVE64 0 "nonimmediate_operand")
7311 (match_operand:FMOVE64 1 "any_operand"))]
7314 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7319 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7320 (match_operand:FMOVE64 1 "const_int_operand"))]
7321 "! TARGET_POWERPC64 && reload_completed
7322 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7323 || (GET_CODE (operands[0]) == SUBREG
7324 && GET_CODE (SUBREG_REG (operands[0])) == REG
7325 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7326 [(set (match_dup 2) (match_dup 4))
7327 (set (match_dup 3) (match_dup 1))]
7329 int endian = (WORDS_BIG_ENDIAN == 0);
7330 HOST_WIDE_INT value = INTVAL (operands[1]);
7332 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7333 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7334 operands[4] = GEN_INT (value >> 32);
7335 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7339 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7340 (match_operand:FMOVE64 1 "const_double_operand"))]
7341 "! TARGET_POWERPC64 && reload_completed
7342 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7343 || (GET_CODE (operands[0]) == SUBREG
7344 && GET_CODE (SUBREG_REG (operands[0])) == REG
7345 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7346 [(set (match_dup 2) (match_dup 4))
7347 (set (match_dup 3) (match_dup 5))]
7349 int endian = (WORDS_BIG_ENDIAN == 0);
7352 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7354 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7355 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7356 operands[4] = gen_int_mode (l[endian], SImode);
7357 operands[5] = gen_int_mode (l[1 - endian], SImode);
7361 [(set (match_operand:FMOVE64 0 "gpc_reg_operand")
7362 (match_operand:FMOVE64 1 "const_double_operand"))]
7363 "TARGET_POWERPC64 && reload_completed
7364 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7365 || (GET_CODE (operands[0]) == SUBREG
7366 && GET_CODE (SUBREG_REG (operands[0])) == REG
7367 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7368 [(set (match_dup 2) (match_dup 3))]
7370 int endian = (WORDS_BIG_ENDIAN == 0);
7374 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7376 operands[2] = gen_lowpart (DImode, operands[0]);
7377 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7378 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7379 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7381 operands[3] = gen_int_mode (val, DImode);
7384 ;; Don't have reload use general registers to load a constant. It is
7385 ;; less efficient than loading the constant into an FP register, since
7386 ;; it will probably be used there.
7388 ;; The move constraints are ordered to prefer floating point registers before
7389 ;; general purpose registers to avoid doing a store and a load to get the value
7390 ;; into a floating point register when it is needed for a floating point
7391 ;; operation. Prefer traditional floating point registers over VSX registers,
7392 ;; since the D-form version of the memory instructions does not need a GPR for
7393 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7396 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7397 ;; except for 0.0 which can be created on VSX with an xor instruction.
7399 (define_insn "*mov<mode>_hardfloat32"
7400 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7401 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7402 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7403 && (gpc_reg_operand (operands[0], <MODE>mode)
7404 || gpc_reg_operand (operands[1], <MODE>mode))"
7419 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7420 (set_attr "size" "64")
7421 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7423 (define_insn "*mov<mode>_softfloat32"
7424 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7425 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7427 && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7428 && (gpc_reg_operand (operands[0], <MODE>mode)
7429 || gpc_reg_operand (operands[1], <MODE>mode))"
7431 [(set_attr "type" "store,load,two,*,*,*")
7432 (set_attr "length" "8,8,8,8,12,16")])
7434 ; ld/std require word-aligned displacements -> 'Y' constraint.
7435 ; List Y->r and r->Y before r->r for reload.
7436 (define_insn "*mov<mode>_hardfloat64"
7437 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r,*c*l,!r,*h,r,wg,r,<f64_dm>")
7438 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r,r,h,0,wg,r,<f64_dm>,r"))]
7439 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7440 && (gpc_reg_operand (operands[0], <MODE>mode)
7441 || gpc_reg_operand (operands[1], <MODE>mode))"
7463 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7464 (set_attr "size" "64")
7465 (set_attr "length" "4")])
7467 (define_insn "*mov<mode>_softfloat64"
7468 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7469 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7470 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7471 && (gpc_reg_operand (operands[0], <MODE>mode)
7472 || gpc_reg_operand (operands[1], <MODE>mode))"
7483 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7484 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7486 (define_expand "mov<mode>"
7487 [(set (match_operand:FMOVE128 0 "general_operand")
7488 (match_operand:FMOVE128 1 "any_operand"))]
7491 rs6000_emit_move (operands[0], operands[1], <MODE>mode);
7495 ;; It's important to list Y->r and r->Y before r->r because otherwise
7496 ;; reload, given m->r, will try to pick r->r and reload it, which
7497 ;; doesn't make progress.
7499 ;; We can't split little endian direct moves of TDmode, because the words are
7500 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7501 ;; problematical. Don't allow direct move for this case.
7503 (define_insn_and_split "*mov<mode>_64bit_dm"
7504 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7505 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7506 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7507 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7508 && (gpc_reg_operand (operands[0], <MODE>mode)
7509 || gpc_reg_operand (operands[1], <MODE>mode))"
7511 "&& reload_completed"
7513 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7514 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7516 (define_insn_and_split "*movtd_64bit_nodm"
7517 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7518 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7519 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7520 && (gpc_reg_operand (operands[0], TDmode)
7521 || gpc_reg_operand (operands[1], TDmode))"
7523 "&& reload_completed"
7525 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7526 [(set_attr "length" "8,8,8,12,12,8")])
7528 (define_insn_and_split "*mov<mode>_32bit"
7529 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7530 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7531 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7532 && (FLOAT128_2REG_P (<MODE>mode)
7533 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7534 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7535 && (gpc_reg_operand (operands[0], <MODE>mode)
7536 || gpc_reg_operand (operands[1], <MODE>mode))"
7538 "&& reload_completed"
7540 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7541 [(set_attr "length" "8,8,8,8,20,20,16")])
7543 (define_insn_and_split "*mov<mode>_softfloat"
7544 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7545 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7547 && (gpc_reg_operand (operands[0], <MODE>mode)
7548 || gpc_reg_operand (operands[1], <MODE>mode))"
7550 "&& reload_completed"
7552 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7553 [(set_attr "length" "20,20,16")])
7555 (define_expand "extenddf<mode>2"
7556 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7557 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand")))]
7558 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7560 if (FLOAT128_IEEE_P (<MODE>mode))
7561 rs6000_expand_float128_convert (operands[0], operands[1], false);
7562 else if (TARGET_VSX)
7564 if (<MODE>mode == TFmode)
7565 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7566 else if (<MODE>mode == IFmode)
7567 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7573 rtx zero = gen_reg_rtx (DFmode);
7574 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7576 if (<MODE>mode == TFmode)
7577 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7578 else if (<MODE>mode == IFmode)
7579 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7586 ;; Allow memory operands for the source to be created by the combiner.
7587 (define_insn_and_split "extenddf<mode>2_fprs"
7588 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7589 (float_extend:IBM128
7590 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7591 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7592 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7593 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7595 "&& reload_completed"
7596 [(set (match_dup 3) (match_dup 1))
7597 (set (match_dup 4) (match_dup 2))]
7599 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7600 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7602 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7603 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7606 (define_insn_and_split "extenddf<mode>2_vsx"
7607 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7608 (float_extend:IBM128
7609 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7610 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7612 "&& reload_completed"
7613 [(set (match_dup 2) (match_dup 1))
7614 (set (match_dup 3) (match_dup 4))]
7616 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7617 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7619 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7620 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7621 operands[4] = CONST0_RTX (DFmode);
7624 (define_expand "extendsf<mode>2"
7625 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7626 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand")))]
7627 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7629 if (FLOAT128_IEEE_P (<MODE>mode))
7630 rs6000_expand_float128_convert (operands[0], operands[1], false);
7633 rtx tmp = gen_reg_rtx (DFmode);
7634 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7635 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7640 (define_expand "trunc<mode>df2"
7641 [(set (match_operand:DF 0 "gpc_reg_operand")
7642 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7643 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7645 if (FLOAT128_IEEE_P (<MODE>mode))
7647 rs6000_expand_float128_convert (operands[0], operands[1], false);
7652 (define_insn_and_split "trunc<mode>df2_internal1"
7653 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7655 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7656 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7657 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7661 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7664 emit_note (NOTE_INSN_DELETED);
7667 [(set_attr "type" "fpsimple")])
7669 (define_insn "trunc<mode>df2_internal2"
7670 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7671 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7672 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7673 && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7675 [(set_attr "type" "fp")
7676 (set_attr "fp_type" "fp_addsub_d")])
7678 (define_expand "trunc<mode>sf2"
7679 [(set (match_operand:SF 0 "gpc_reg_operand")
7680 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7681 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7683 if (FLOAT128_IEEE_P (<MODE>mode))
7684 rs6000_expand_float128_convert (operands[0], operands[1], false);
7685 else if (<MODE>mode == TFmode)
7686 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7687 else if (<MODE>mode == IFmode)
7688 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7694 (define_insn_and_split "trunc<mode>sf2_fprs"
7695 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7696 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7697 (clobber (match_scratch:DF 2 "=d"))]
7698 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7699 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7701 "&& reload_completed"
7703 (float_truncate:DF (match_dup 1)))
7705 (float_truncate:SF (match_dup 2)))]
7708 (define_expand "floatsi<mode>2"
7709 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7710 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7711 (clobber (match_scratch:DI 2))])]
7712 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7714 rtx op0 = operands[0];
7715 rtx op1 = operands[1];
7717 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7719 else if (FLOAT128_IEEE_P (<MODE>mode))
7721 rs6000_expand_float128_convert (op0, op1, false);
7726 rtx tmp = gen_reg_rtx (DFmode);
7727 expand_float (tmp, op1, false);
7728 if (<MODE>mode == TFmode)
7729 emit_insn (gen_extenddftf2 (op0, tmp));
7730 else if (<MODE>mode == IFmode)
7731 emit_insn (gen_extenddfif2 (op0, tmp));
7738 ; fadd, but rounding towards zero.
7739 ; This is probably not the optimal code sequence.
7740 (define_insn "fix_trunc_helper<mode>"
7741 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7742 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7743 UNSPEC_FIX_TRUNC_TF))
7744 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7745 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7746 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7747 [(set_attr "type" "fp")
7748 (set_attr "length" "20")])
7750 (define_expand "fix_trunc<mode>si2"
7751 [(set (match_operand:SI 0 "gpc_reg_operand")
7752 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7753 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7755 rtx op0 = operands[0];
7756 rtx op1 = operands[1];
7758 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7762 if (FLOAT128_IEEE_P (<MODE>mode))
7763 rs6000_expand_float128_convert (op0, op1, false);
7764 else if (<MODE>mode == TFmode)
7765 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7766 else if (<MODE>mode == IFmode)
7767 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7774 (define_expand "fix_trunc<mode>si2_fprs"
7775 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand")
7776 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand")))
7777 (clobber (match_dup 2))
7778 (clobber (match_dup 3))
7779 (clobber (match_dup 4))
7780 (clobber (match_dup 5))])]
7781 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7783 operands[2] = gen_reg_rtx (DFmode);
7784 operands[3] = gen_reg_rtx (DFmode);
7785 operands[4] = gen_reg_rtx (DImode);
7786 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7789 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7790 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7791 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7792 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7793 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7794 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7795 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7796 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7802 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7805 gcc_assert (MEM_P (operands[5]));
7806 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7808 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7809 emit_move_insn (operands[5], operands[4]);
7810 emit_move_insn (operands[0], lowword);
7814 (define_expand "fix_trunc<mode>di2"
7815 [(set (match_operand:DI 0 "gpc_reg_operand")
7816 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7817 "TARGET_FLOAT128_TYPE"
7819 if (!TARGET_FLOAT128_HW)
7821 rs6000_expand_float128_convert (operands[0], operands[1], false);
7826 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7827 [(set (match_operand:SDI 0 "gpc_reg_operand")
7828 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand")))]
7829 "TARGET_FLOAT128_TYPE"
7831 rs6000_expand_float128_convert (operands[0], operands[1], true);
7835 (define_expand "floatdi<mode>2"
7836 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7837 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7838 "TARGET_FLOAT128_TYPE"
7840 if (!TARGET_FLOAT128_HW)
7842 rs6000_expand_float128_convert (operands[0], operands[1], false);
7847 (define_expand "floatunsdi<IEEE128:mode>2"
7848 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7849 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand")))]
7850 "TARGET_FLOAT128_TYPE"
7852 if (!TARGET_FLOAT128_HW)
7854 rs6000_expand_float128_convert (operands[0], operands[1], true);
7859 (define_expand "floatuns<IEEE128:mode>2"
7860 [(set (match_operand:IEEE128 0 "gpc_reg_operand")
7861 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand")))]
7862 "TARGET_FLOAT128_TYPE"
7864 rtx op0 = operands[0];
7865 rtx op1 = operands[1];
7867 if (TARGET_FLOAT128_HW)
7868 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7870 rs6000_expand_float128_convert (op0, op1, true);
7874 (define_expand "neg<mode>2"
7875 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7876 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7877 "FLOAT128_IEEE_P (<MODE>mode)
7878 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7880 if (FLOAT128_IEEE_P (<MODE>mode))
7882 if (TARGET_FLOAT128_HW)
7884 if (<MODE>mode == TFmode)
7885 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7886 else if (<MODE>mode == KFmode)
7887 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7891 else if (TARGET_FLOAT128_TYPE)
7893 if (<MODE>mode == TFmode)
7894 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7895 else if (<MODE>mode == KFmode)
7896 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7902 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7903 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7905 operands[1], <MODE>mode);
7907 if (target && !rtx_equal_p (target, operands[0]))
7908 emit_move_insn (operands[0], target);
7914 (define_insn "neg<mode>2_internal"
7915 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7916 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7917 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7919 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7920 return "fneg %L0,%L1\;fneg %0,%1";
7922 return "fneg %0,%1\;fneg %L0,%L1";
7924 [(set_attr "type" "fpsimple")
7925 (set_attr "length" "8")])
7927 (define_expand "abs<mode>2"
7928 [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7929 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand")))]
7930 "FLOAT128_IEEE_P (<MODE>mode)
7931 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7935 if (FLOAT128_IEEE_P (<MODE>mode))
7937 if (TARGET_FLOAT128_HW)
7939 if (<MODE>mode == TFmode)
7940 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7941 else if (<MODE>mode == KFmode)
7942 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7947 else if (TARGET_FLOAT128_TYPE)
7949 if (<MODE>mode == TFmode)
7950 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
7951 else if (<MODE>mode == KFmode)
7952 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
7961 label = gen_label_rtx ();
7962 if (<MODE>mode == TFmode)
7963 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
7964 else if (<MODE>mode == TFmode)
7965 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
7972 (define_expand "abs<mode>2_internal"
7973 [(set (match_operand:IBM128 0 "gpc_reg_operand")
7974 (match_operand:IBM128 1 "gpc_reg_operand"))
7975 (set (match_dup 3) (match_dup 5))
7976 (set (match_dup 5) (abs:DF (match_dup 5)))
7977 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
7978 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
7979 (label_ref (match_operand 2 ""))
7981 (set (match_dup 6) (neg:DF (match_dup 6)))]
7982 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7984 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7985 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7986 operands[3] = gen_reg_rtx (DFmode);
7987 operands[4] = gen_reg_rtx (CCFPmode);
7988 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7989 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7993 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
7996 (define_expand "ieee_128bit_negative_zero"
7997 [(set (match_operand:V16QI 0 "register_operand") (match_dup 1))]
7998 "TARGET_FLOAT128_TYPE"
8000 rtvec v = rtvec_alloc (16);
8003 for (i = 0; i < 16; i++)
8004 RTVEC_ELT (v, i) = const0_rtx;
8006 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8007 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8009 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8013 ;; IEEE 128-bit negate
8015 ;; We have 2 insns here for negate and absolute value. The first uses
8016 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8017 ;; insns, and second insn after the first split pass loads up the bit to
8018 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8019 ;; neg/abs to create the constant just once.
8021 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8022 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8023 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8024 (clobber (match_scratch:V16QI 2 "=v"))]
8025 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8028 [(parallel [(set (match_dup 0)
8029 (neg:IEEE128 (match_dup 1)))
8030 (use (match_dup 2))])]
8032 if (GET_CODE (operands[2]) == SCRATCH)
8033 operands[2] = gen_reg_rtx (V16QImode);
8035 operands[3] = gen_reg_rtx (V16QImode);
8036 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8038 [(set_attr "length" "8")
8039 (set_attr "type" "vecsimple")])
8041 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8042 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8043 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8044 (use (match_operand:V16QI 2 "register_operand" "v"))]
8045 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8046 "xxlxor %x0,%x1,%x2"
8047 [(set_attr "type" "veclogical")])
8049 ;; IEEE 128-bit absolute value
8050 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8051 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8052 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8053 (clobber (match_scratch:V16QI 2 "=v"))]
8054 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8057 [(parallel [(set (match_dup 0)
8058 (abs:IEEE128 (match_dup 1)))
8059 (use (match_dup 2))])]
8061 if (GET_CODE (operands[2]) == SCRATCH)
8062 operands[2] = gen_reg_rtx (V16QImode);
8064 operands[3] = gen_reg_rtx (V16QImode);
8065 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8067 [(set_attr "length" "8")
8068 (set_attr "type" "vecsimple")])
8070 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8071 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8072 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8073 (use (match_operand:V16QI 2 "register_operand" "v"))]
8074 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8075 "xxlandc %x0,%x1,%x2"
8076 [(set_attr "type" "veclogical")])
8078 ;; IEEE 128-bit negative absolute value
8079 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8080 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8083 (match_operand:IEEE128 1 "register_operand" "wa"))))
8084 (clobber (match_scratch:V16QI 2 "=v"))]
8085 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8086 && FLOAT128_IEEE_P (<MODE>mode)"
8089 [(parallel [(set (match_dup 0)
8090 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8091 (use (match_dup 2))])]
8093 if (GET_CODE (operands[2]) == SCRATCH)
8094 operands[2] = gen_reg_rtx (V16QImode);
8096 operands[3] = gen_reg_rtx (V16QImode);
8097 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8099 [(set_attr "length" "8")
8100 (set_attr "type" "vecsimple")])
8102 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8103 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8106 (match_operand:IEEE128 1 "register_operand" "wa"))))
8107 (use (match_operand:V16QI 2 "register_operand" "v"))]
8108 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8110 [(set_attr "type" "veclogical")])
8112 ;; Float128 conversion functions. These expand to library function calls.
8113 ;; We use expand to convert from IBM double double to IEEE 128-bit
8114 ;; and trunc for the opposite.
8115 (define_expand "extendiftf2"
8116 [(set (match_operand:TF 0 "gpc_reg_operand")
8117 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand")))]
8118 "TARGET_FLOAT128_TYPE"
8120 rs6000_expand_float128_convert (operands[0], operands[1], false);
8124 (define_expand "extendifkf2"
8125 [(set (match_operand:KF 0 "gpc_reg_operand")
8126 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand")))]
8127 "TARGET_FLOAT128_TYPE"
8129 rs6000_expand_float128_convert (operands[0], operands[1], false);
8133 (define_expand "extendtfkf2"
8134 [(set (match_operand:KF 0 "gpc_reg_operand")
8135 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand")))]
8136 "TARGET_FLOAT128_TYPE"
8138 rs6000_expand_float128_convert (operands[0], operands[1], false);
8142 (define_expand "trunciftf2"
8143 [(set (match_operand:IF 0 "gpc_reg_operand")
8144 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8145 "TARGET_FLOAT128_TYPE"
8147 rs6000_expand_float128_convert (operands[0], operands[1], false);
8151 (define_expand "truncifkf2"
8152 [(set (match_operand:IF 0 "gpc_reg_operand")
8153 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand")))]
8154 "TARGET_FLOAT128_TYPE"
8156 rs6000_expand_float128_convert (operands[0], operands[1], false);
8160 (define_expand "trunckftf2"
8161 [(set (match_operand:TF 0 "gpc_reg_operand")
8162 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand")))]
8163 "TARGET_FLOAT128_TYPE"
8165 rs6000_expand_float128_convert (operands[0], operands[1], false);
8169 (define_expand "trunctfif2"
8170 [(set (match_operand:IF 0 "gpc_reg_operand")
8171 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand")))]
8172 "TARGET_FLOAT128_TYPE"
8174 rs6000_expand_float128_convert (operands[0], operands[1], false);
8179 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8180 ;; must have 3 arguments, and scratch register constraint must be a single
8183 ;; Reload patterns to support gpr load/store with misaligned mem.
8184 ;; and multiple gpr load/store at offset >= 0xfffc
8185 (define_expand "reload_<mode>_store"
8186 [(parallel [(match_operand 0 "memory_operand" "=m")
8187 (match_operand 1 "gpc_reg_operand" "r")
8188 (match_operand:GPR 2 "register_operand" "=&b")])]
8191 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8195 (define_expand "reload_<mode>_load"
8196 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8197 (match_operand 1 "memory_operand" "m")
8198 (match_operand:GPR 2 "register_operand" "=b")])]
8201 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8206 ;; Reload patterns for various types using the vector registers. We may need
8207 ;; an additional base register to convert the reg+offset addressing to reg+reg
8208 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8209 ;; index register for gpr registers.
8210 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8211 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8212 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8213 (match_operand:P 2 "register_operand" "=b")])]
8216 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8220 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8221 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8222 (match_operand:RELOAD 1 "memory_operand" "m")
8223 (match_operand:P 2 "register_operand" "=b")])]
8226 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8231 ;; Reload sometimes tries to move the address to a GPR, and can generate
8232 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8233 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8235 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8236 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8237 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8238 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8240 "TARGET_ALTIVEC && reload_completed"
8242 "&& reload_completed"
8244 (plus:P (match_dup 1)
8247 (and:P (match_dup 0)
8250 ;; Power8 merge instructions to allow direct move to/from floating point
8251 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8252 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8253 ;; value, since it is allocated in reload and not all of the flow information
8254 ;; is setup for it. We have two patterns to do the two moves between gprs and
8255 ;; fprs. There isn't a dependancy between the two, but we could potentially
8256 ;; schedule other instructions between the two instructions.
8258 (define_insn "p8_fmrgow_<mode>"
8259 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8261 (match_operand:DF 1 "register_operand" "d")
8262 (match_operand:DF 2 "register_operand" "d")]
8263 UNSPEC_P8V_FMRGOW))]
8264 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8266 [(set_attr "type" "fpsimple")])
8268 (define_insn "p8_mtvsrwz"
8269 [(set (match_operand:DF 0 "register_operand" "=d")
8270 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8271 UNSPEC_P8V_MTVSRWZ))]
8272 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8274 [(set_attr "type" "mftgpr")])
8276 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8277 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8278 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8279 UNSPEC_P8V_RELOAD_FROM_GPR))
8280 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8281 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8283 "&& reload_completed"
8286 rtx dest = operands[0];
8287 rtx src = operands[1];
8288 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8289 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8290 rtx gpr_hi_reg = gen_highpart (SImode, src);
8291 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8293 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8294 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8295 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8298 [(set_attr "length" "12")
8299 (set_attr "type" "three")])
8301 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8302 (define_insn "p8_mtvsrd_df"
8303 [(set (match_operand:DF 0 "register_operand" "=wa")
8304 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8305 UNSPEC_P8V_MTVSRD))]
8306 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8308 [(set_attr "type" "mftgpr")])
8310 (define_insn "p8_xxpermdi_<mode>"
8311 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8312 (unspec:FMOVE128_GPR [
8313 (match_operand:DF 1 "register_operand" "wa")
8314 (match_operand:DF 2 "register_operand" "wa")]
8315 UNSPEC_P8V_XXPERMDI))]
8316 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8317 "xxpermdi %x0,%x1,%x2,0"
8318 [(set_attr "type" "vecperm")])
8320 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8321 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8322 (unspec:FMOVE128_GPR
8323 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8324 UNSPEC_P8V_RELOAD_FROM_GPR))
8325 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8326 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8328 "&& reload_completed"
8331 rtx dest = operands[0];
8332 rtx src = operands[1];
8333 /* You might think that we could use op0 as one temp and a DF clobber
8334 as op2, but you'd be wrong. Secondary reload move patterns don't
8335 check for overlap of the clobber and the destination. */
8336 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8337 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8338 rtx gpr_hi_reg = gen_highpart (DImode, src);
8339 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8341 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8342 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8343 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8346 [(set_attr "length" "12")
8347 (set_attr "type" "three")])
8350 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand")
8351 (match_operand:FMOVE128_GPR 1 "input_operand"))]
8353 && (int_reg_operand (operands[0], <MODE>mode)
8354 || int_reg_operand (operands[1], <MODE>mode))
8355 && (!TARGET_DIRECT_MOVE_128
8356 || (!vsx_register_operand (operands[0], <MODE>mode)
8357 && !vsx_register_operand (operands[1], <MODE>mode)))"
8359 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8361 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8362 ;; type is stored internally as double precision in the VSX registers, we have
8363 ;; to convert it from the vector format.
8364 (define_insn "p8_mtvsrd_sf"
8365 [(set (match_operand:SF 0 "register_operand" "=wa")
8366 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8367 UNSPEC_P8V_MTVSRD))]
8368 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8370 [(set_attr "type" "mftgpr")])
8372 (define_insn_and_split "reload_vsx_from_gprsf"
8373 [(set (match_operand:SF 0 "register_operand" "=wa")
8374 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8375 UNSPEC_P8V_RELOAD_FROM_GPR))
8376 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8377 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8379 "&& reload_completed"
8382 rtx op0 = operands[0];
8383 rtx op1 = operands[1];
8384 rtx op2 = operands[2];
8385 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8387 /* Move SF value to upper 32-bits for xscvspdpn. */
8388 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8389 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8390 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8393 [(set_attr "length" "8")
8394 (set_attr "type" "two")])
8396 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8397 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8398 ;; and then doing a move of that.
8399 (define_insn "p8_mfvsrd_3_<mode>"
8400 [(set (match_operand:DF 0 "register_operand" "=r")
8401 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8402 UNSPEC_P8V_RELOAD_FROM_VSX))]
8403 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8405 [(set_attr "type" "mftgpr")])
8407 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8408 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8409 (unspec:FMOVE128_GPR
8410 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8411 UNSPEC_P8V_RELOAD_FROM_VSX))
8412 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8413 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8415 "&& reload_completed"
8418 rtx dest = operands[0];
8419 rtx src = operands[1];
8420 rtx tmp = operands[2];
8421 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8422 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8424 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8425 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8426 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8429 [(set_attr "length" "12")
8430 (set_attr "type" "three")])
8432 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8433 ;; type is stored internally as double precision, we have to convert it to the
8436 (define_insn_and_split "reload_gpr_from_vsxsf"
8437 [(set (match_operand:SF 0 "register_operand" "=r")
8438 (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8439 UNSPEC_P8V_RELOAD_FROM_VSX))
8440 (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8441 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8443 "&& reload_completed"
8446 rtx op0 = operands[0];
8447 rtx op1 = operands[1];
8448 rtx op2 = operands[2];
8449 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8450 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8452 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8453 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8456 [(set_attr "length" "8")
8457 (set_attr "type" "two")])
8460 ;; Next come the multi-word integer load and store and the load and store
8463 ;; List r->r after r->Y, otherwise reload will try to reload a
8464 ;; non-offsettable address by using r->r which won't make progress.
8465 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8466 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8468 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8469 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8470 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8473 (define_insn "*movdi_internal32"
8474 [(set (match_operand:DI 0 "nonimmediate_operand"
8475 "=Y, r, r, ^m, ^d, ^d,
8476 r, ^wY, $Z, ^wb, $wv, ^wi,
8477 *wo, *wo, *wv, *wi, *wi, *wv,
8480 (match_operand:DI 1 "input_operand"
8482 IJKnGHF, wb, wv, wY, Z, wi,
8483 Oj, wM, OjwM, Oj, wM, wS,
8487 && (gpc_reg_operand (operands[0], DImode)
8488 || gpc_reg_operand (operands[1], DImode))"
8510 "store, load, *, fpstore, fpload, fpsimple,
8511 *, fpstore, fpstore, fpload, fpload, veclogical,
8512 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8514 (set_attr "size" "64")])
8517 [(set (match_operand:DI 0 "gpc_reg_operand")
8518 (match_operand:DI 1 "const_int_operand"))]
8519 "! TARGET_POWERPC64 && reload_completed
8520 && gpr_or_gpr_p (operands[0], operands[1])
8521 && !direct_move_p (operands[0], operands[1])"
8522 [(set (match_dup 2) (match_dup 4))
8523 (set (match_dup 3) (match_dup 1))]
8525 HOST_WIDE_INT value = INTVAL (operands[1]);
8526 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8528 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8530 operands[4] = GEN_INT (value >> 32);
8531 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8535 [(set (match_operand:DIFD 0 "nonimmediate_operand")
8536 (match_operand:DIFD 1 "input_operand"))]
8537 "reload_completed && !TARGET_POWERPC64
8538 && gpr_or_gpr_p (operands[0], operands[1])
8539 && !direct_move_p (operands[0], operands[1])"
8541 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8543 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8544 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8545 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8546 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8547 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8548 (define_insn "*movdi_internal64"
8549 [(set (match_operand:DI 0 "nonimmediate_operand"
8550 "=YZ, r, r, r, r, r,
8551 ^m, ^d, ^d, ^wY, $Z, $wb,
8552 $wv, ^wi, *wo, *wo, *wv, *wi,
8553 *wi, *wv, *wv, r, *h, *h,
8554 ?*r, ?*wg, ?*r, ?*wj")
8556 (match_operand:DI 1 "input_operand"
8557 "r, YZ, r, I, L, nF,
8558 d, m, d, wb, wv, wY,
8559 Z, wi, Oj, wM, OjwM, Oj,
8560 wM, wS, wB, *h, r, 0,
8564 && (gpc_reg_operand (operands[0], DImode)
8565 || gpc_reg_operand (operands[1], DImode))"
8596 "store, load, *, *, *, *,
8597 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8598 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8599 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8600 mftgpr, mffgpr, mftgpr, mffgpr")
8602 (set_attr "size" "64")
8610 ; Some DImode loads are best done as a load of -1 followed by a mask
8613 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8614 (match_operand:DI 1 "const_int_operand"))]
8616 && num_insns_constant (operands[1], DImode) > 1
8617 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8618 && rs6000_is_valid_and_mask (operands[1], DImode)"
8622 (and:DI (match_dup 0)
8626 ;; Split a load of a large constant into the appropriate five-instruction
8627 ;; sequence. Handle anything in a constant number of insns.
8628 ;; When non-easy constants can go in the TOC, this should use
8629 ;; easy_fp_constant predicate.
8631 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8632 (match_operand:DI 1 "const_int_operand"))]
8633 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8634 [(set (match_dup 0) (match_dup 2))
8635 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8637 if (rs6000_emit_set_const (operands[0], operands[1]))
8644 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8645 (match_operand:DI 1 "const_scalar_int_operand"))]
8646 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8647 [(set (match_dup 0) (match_dup 2))
8648 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8650 if (rs6000_emit_set_const (operands[0], operands[1]))
8657 [(set (match_operand:DI 0 "altivec_register_operand")
8658 (match_operand:DI 1 "s5bit_cint_operand"))]
8659 "TARGET_VSX && reload_completed"
8662 rtx op0 = operands[0];
8663 rtx op1 = operands[1];
8664 int r = REGNO (op0);
8665 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8667 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8668 if (op1 != const0_rtx && op1 != constm1_rtx)
8670 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8671 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8676 ;; Split integer constants that can be loaded with XXSPLTIB and a
8677 ;; sign extend operation.
8679 [(set (match_operand:INT_ISA3 0 "altivec_register_operand")
8680 (match_operand:INT_ISA3 1 "xxspltib_constant_split"))]
8681 "TARGET_P9_VECTOR && reload_completed"
8684 rtx op0 = operands[0];
8685 rtx op1 = operands[1];
8686 int r = REGNO (op0);
8687 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8689 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8690 if (<MODE>mode == DImode)
8691 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8692 else if (<MODE>mode == SImode)
8693 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8694 else if (<MODE>mode == HImode)
8696 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8697 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8703 ;; TImode/PTImode is similar, except that we usually want to compute the
8704 ;; address into a register and use lsi/stsi (the exception is during reload).
8706 (define_insn "*mov<mode>_string"
8707 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8708 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8710 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8711 && (gpc_reg_operand (operands[0], <MODE>mode)
8712 || gpc_reg_operand (operands[1], <MODE>mode))"
8714 [(set_attr "type" "store,store,load,load,*,*")
8715 (set_attr "update" "yes")
8716 (set_attr "indexed" "yes")
8717 (set_attr "cell_micro" "conditional")])
8719 (define_insn "*mov<mode>_ppc64"
8720 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8721 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8722 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8723 && (gpc_reg_operand (operands[0], <MODE>mode)
8724 || gpc_reg_operand (operands[1], <MODE>mode)))"
8726 return rs6000_output_move_128bit (operands);
8728 [(set_attr "type" "store,store,load,load,*,*")
8729 (set_attr "length" "8")])
8732 [(set (match_operand:TI2 0 "int_reg_operand")
8733 (match_operand:TI2 1 "const_scalar_int_operand"))]
8735 && (VECTOR_MEM_NONE_P (<MODE>mode)
8736 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8737 [(set (match_dup 2) (match_dup 4))
8738 (set (match_dup 3) (match_dup 5))]
8740 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8742 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8744 if (CONST_WIDE_INT_P (operands[1]))
8746 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8747 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8749 else if (CONST_INT_P (operands[1]))
8751 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8752 operands[5] = operands[1];
8759 [(set (match_operand:TI2 0 "nonimmediate_operand")
8760 (match_operand:TI2 1 "input_operand"))]
8762 && gpr_or_gpr_p (operands[0], operands[1])
8763 && !direct_move_p (operands[0], operands[1])
8764 && !quad_load_store_p (operands[0], operands[1])"
8766 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8768 (define_expand "setmemsi"
8769 [(parallel [(set (match_operand:BLK 0 "")
8770 (match_operand 2 "const_int_operand"))
8771 (use (match_operand:SI 1 ""))
8772 (use (match_operand:SI 3 ""))])]
8775 /* If value to set is not zero, use the library routine. */
8776 if (operands[2] != const0_rtx)
8779 if (expand_block_clear (operands))
8785 ;; String compare N insn.
8786 ;; Argument 0 is the target (result)
8787 ;; Argument 1 is the destination
8788 ;; Argument 2 is the source
8789 ;; Argument 3 is the length
8790 ;; Argument 4 is the alignment
8792 (define_expand "cmpstrnsi"
8793 [(parallel [(set (match_operand:SI 0)
8794 (compare:SI (match_operand:BLK 1)
8795 (match_operand:BLK 2)))
8796 (use (match_operand:SI 3))
8797 (use (match_operand:SI 4))])]
8798 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8800 if (optimize_insn_for_size_p ())
8803 if (expand_strn_compare (operands, 0))
8809 ;; String compare insn.
8810 ;; Argument 0 is the target (result)
8811 ;; Argument 1 is the destination
8812 ;; Argument 2 is the source
8813 ;; Argument 3 is the alignment
8815 (define_expand "cmpstrsi"
8816 [(parallel [(set (match_operand:SI 0)
8817 (compare:SI (match_operand:BLK 1)
8818 (match_operand:BLK 2)))
8819 (use (match_operand:SI 3))])]
8820 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
8822 if (optimize_insn_for_size_p ())
8825 if (expand_strn_compare (operands, 1))
8831 ;; Block compare insn.
8832 ;; Argument 0 is the target (result)
8833 ;; Argument 1 is the destination
8834 ;; Argument 2 is the source
8835 ;; Argument 3 is the length
8836 ;; Argument 4 is the alignment
8838 (define_expand "cmpmemsi"
8839 [(parallel [(set (match_operand:SI 0)
8840 (compare:SI (match_operand:BLK 1)
8841 (match_operand:BLK 2)))
8842 (use (match_operand:SI 3))
8843 (use (match_operand:SI 4))])]
8846 if (expand_block_compare (operands))
8852 ;; String/block move insn.
8853 ;; Argument 0 is the destination
8854 ;; Argument 1 is the source
8855 ;; Argument 2 is the length
8856 ;; Argument 3 is the alignment
8858 (define_expand "movmemsi"
8859 [(parallel [(set (match_operand:BLK 0 "")
8860 (match_operand:BLK 1 ""))
8861 (use (match_operand:SI 2 ""))
8862 (use (match_operand:SI 3 ""))])]
8865 if (expand_block_move (operands))
8871 ;; Define insns that do load or store with update. Some of these we can
8872 ;; get by using pre-decrement or pre-increment, but the hardware can also
8873 ;; do cases where the increment is not the size of the object.
8875 ;; In all these cases, we use operands 0 and 1 for the register being
8876 ;; incremented because those are the operands that local-alloc will
8877 ;; tie and these are the pair most likely to be tieable (and the ones
8878 ;; that will benefit the most).
8880 (define_insn "*movdi_update1"
8881 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
8882 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
8883 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
8884 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
8885 (plus:DI (match_dup 1) (match_dup 2)))]
8886 "TARGET_POWERPC64 && TARGET_UPDATE
8887 && (!avoiding_indexed_address_p (DImode)
8888 || !gpc_reg_operand (operands[2], DImode))"
8892 [(set_attr "type" "load")
8893 (set_attr "update" "yes")
8894 (set_attr "indexed" "yes,no")])
8896 (define_insn "movdi_<mode>_update"
8897 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8898 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8899 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8900 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8901 (plus:P (match_dup 1) (match_dup 2)))]
8902 "TARGET_POWERPC64 && TARGET_UPDATE
8903 && (!avoiding_indexed_address_p (Pmode)
8904 || !gpc_reg_operand (operands[2], Pmode)
8905 || (REG_P (operands[0])
8906 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8910 [(set_attr "type" "store")
8911 (set_attr "update" "yes")
8912 (set_attr "indexed" "yes,no")])
8914 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
8915 ;; needed for stack allocation, even if the user passes -mno-update.
8916 (define_insn "movdi_<mode>_update_stack"
8917 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
8918 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
8919 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
8920 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
8921 (plus:P (match_dup 1) (match_dup 2)))]
8926 [(set_attr "type" "store")
8927 (set_attr "update" "yes")
8928 (set_attr "indexed" "yes,no")])
8930 (define_insn "*movsi_update1"
8931 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
8932 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8933 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8934 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8935 (plus:SI (match_dup 1) (match_dup 2)))]
8937 && (!avoiding_indexed_address_p (SImode)
8938 || !gpc_reg_operand (operands[2], SImode))"
8942 [(set_attr "type" "load")
8943 (set_attr "update" "yes")
8944 (set_attr "indexed" "yes,no")])
8946 (define_insn "*movsi_update2"
8947 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
8949 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
8950 (match_operand:DI 2 "gpc_reg_operand" "r")))))
8951 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
8952 (plus:DI (match_dup 1) (match_dup 2)))]
8953 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
8955 [(set_attr "type" "load")
8956 (set_attr "sign_extend" "yes")
8957 (set_attr "update" "yes")
8958 (set_attr "indexed" "yes")])
8960 (define_insn "movsi_update"
8961 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8962 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8963 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8964 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8965 (plus:SI (match_dup 1) (match_dup 2)))]
8967 && (!avoiding_indexed_address_p (SImode)
8968 || !gpc_reg_operand (operands[2], SImode)
8969 || (REG_P (operands[0])
8970 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
8974 [(set_attr "type" "store")
8975 (set_attr "update" "yes")
8976 (set_attr "indexed" "yes,no")])
8978 ;; This is an unconditional pattern; needed for stack allocation, even
8979 ;; if the user passes -mno-update.
8980 (define_insn "movsi_update_stack"
8981 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8982 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
8983 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
8984 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8985 (plus:SI (match_dup 1) (match_dup 2)))]
8990 [(set_attr "type" "store")
8991 (set_attr "update" "yes")
8992 (set_attr "indexed" "yes,no")])
8994 (define_insn "*movhi_update1"
8995 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
8996 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
8997 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
8998 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
8999 (plus:SI (match_dup 1) (match_dup 2)))]
9001 && (!avoiding_indexed_address_p (SImode)
9002 || !gpc_reg_operand (operands[2], SImode))"
9006 [(set_attr "type" "load")
9007 (set_attr "update" "yes")
9008 (set_attr "indexed" "yes,no")])
9010 (define_insn "*movhi_update2"
9011 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9013 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9014 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9015 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9016 (plus:SI (match_dup 1) (match_dup 2)))]
9018 && (!avoiding_indexed_address_p (SImode)
9019 || !gpc_reg_operand (operands[2], SImode))"
9023 [(set_attr "type" "load")
9024 (set_attr "update" "yes")
9025 (set_attr "indexed" "yes,no")])
9027 (define_insn "*movhi_update3"
9028 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9030 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9031 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9032 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9033 (plus:SI (match_dup 1) (match_dup 2)))]
9035 && !(avoiding_indexed_address_p (SImode)
9036 && gpc_reg_operand (operands[2], SImode))"
9040 [(set_attr "type" "load")
9041 (set_attr "sign_extend" "yes")
9042 (set_attr "update" "yes")
9043 (set_attr "indexed" "yes,no")])
9045 (define_insn "*movhi_update4"
9046 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9047 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9048 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9049 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9050 (plus:SI (match_dup 1) (match_dup 2)))]
9052 && (!avoiding_indexed_address_p (SImode)
9053 || !gpc_reg_operand (operands[2], SImode))"
9057 [(set_attr "type" "store")
9058 (set_attr "update" "yes")
9059 (set_attr "indexed" "yes,no")])
9061 (define_insn "*movqi_update1"
9062 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9063 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9064 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9065 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9066 (plus:SI (match_dup 1) (match_dup 2)))]
9068 && (!avoiding_indexed_address_p (SImode)
9069 || !gpc_reg_operand (operands[2], SImode))"
9073 [(set_attr "type" "load")
9074 (set_attr "update" "yes")
9075 (set_attr "indexed" "yes,no")])
9077 (define_insn "*movqi_update2"
9078 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9080 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9081 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9082 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9083 (plus:SI (match_dup 1) (match_dup 2)))]
9085 && (!avoiding_indexed_address_p (SImode)
9086 || !gpc_reg_operand (operands[2], SImode))"
9090 [(set_attr "type" "load")
9091 (set_attr "update" "yes")
9092 (set_attr "indexed" "yes,no")])
9094 (define_insn "*movqi_update3"
9095 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9096 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9097 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9098 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9099 (plus:SI (match_dup 1) (match_dup 2)))]
9101 && (!avoiding_indexed_address_p (SImode)
9102 || !gpc_reg_operand (operands[2], SImode))"
9106 [(set_attr "type" "store")
9107 (set_attr "update" "yes")
9108 (set_attr "indexed" "yes,no")])
9110 (define_insn "*movsf_update1"
9111 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9112 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9113 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9114 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9115 (plus:SI (match_dup 1) (match_dup 2)))]
9116 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9117 && (!avoiding_indexed_address_p (SImode)
9118 || !gpc_reg_operand (operands[2], SImode))"
9122 [(set_attr "type" "fpload")
9123 (set_attr "update" "yes")
9124 (set_attr "indexed" "yes,no")])
9126 (define_insn "*movsf_update2"
9127 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9128 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9129 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9130 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9131 (plus:SI (match_dup 1) (match_dup 2)))]
9132 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9133 && (!avoiding_indexed_address_p (SImode)
9134 || !gpc_reg_operand (operands[2], SImode))"
9138 [(set_attr "type" "fpstore")
9139 (set_attr "update" "yes")
9140 (set_attr "indexed" "yes,no")])
9142 (define_insn "*movsf_update3"
9143 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9144 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9145 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9146 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9147 (plus:SI (match_dup 1) (match_dup 2)))]
9148 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9149 && (!avoiding_indexed_address_p (SImode)
9150 || !gpc_reg_operand (operands[2], SImode))"
9154 [(set_attr "type" "load")
9155 (set_attr "update" "yes")
9156 (set_attr "indexed" "yes,no")])
9158 (define_insn "*movsf_update4"
9159 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9160 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9161 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9162 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9163 (plus:SI (match_dup 1) (match_dup 2)))]
9164 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9165 && (!avoiding_indexed_address_p (SImode)
9166 || !gpc_reg_operand (operands[2], SImode))"
9170 [(set_attr "type" "store")
9171 (set_attr "update" "yes")
9172 (set_attr "indexed" "yes,no")])
9174 (define_insn "*movdf_update1"
9175 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9176 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9177 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9178 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9179 (plus:SI (match_dup 1) (match_dup 2)))]
9180 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9181 && (!avoiding_indexed_address_p (SImode)
9182 || !gpc_reg_operand (operands[2], SImode))"
9186 [(set_attr "type" "fpload")
9187 (set_attr "update" "yes")
9188 (set_attr "indexed" "yes,no")
9189 (set_attr "size" "64")])
9191 (define_insn "*movdf_update2"
9192 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9193 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9194 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9195 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9196 (plus:SI (match_dup 1) (match_dup 2)))]
9197 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9198 && (!avoiding_indexed_address_p (SImode)
9199 || !gpc_reg_operand (operands[2], SImode))"
9203 [(set_attr "type" "fpstore")
9204 (set_attr "update" "yes")
9205 (set_attr "indexed" "yes,no")])
9208 ;; After inserting conditional returns we can sometimes have
9209 ;; unnecessary register moves. Unfortunately we cannot have a
9210 ;; modeless peephole here, because some single SImode sets have early
9211 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9212 ;; sequences, using get_attr_length here will smash the operands
9213 ;; array. Neither is there an early_cobbler_p predicate.
9214 ;; Also this optimization interferes with scalars going into
9215 ;; altivec registers (the code does reloading through the FPRs).
9217 [(set (match_operand:DF 0 "gpc_reg_operand")
9218 (match_operand:DF 1 "any_operand"))
9219 (set (match_operand:DF 2 "gpc_reg_operand")
9222 && peep2_reg_dead_p (2, operands[0])"
9223 [(set (match_dup 2) (match_dup 1))])
9226 [(set (match_operand:SF 0 "gpc_reg_operand")
9227 (match_operand:SF 1 "any_operand"))
9228 (set (match_operand:SF 2 "gpc_reg_operand")
9231 && peep2_reg_dead_p (2, operands[0])"
9232 [(set (match_dup 2) (match_dup 1))])
9237 ;; Mode attributes for different ABIs.
9238 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9239 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9240 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9241 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9243 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9244 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9245 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9246 (match_operand 4 "" "g")))
9247 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9248 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9250 (clobber (reg:SI LR_REGNO))]
9251 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9253 if (TARGET_CMODEL != CMODEL_SMALL)
9254 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9257 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9259 "&& TARGET_TLS_MARKERS"
9261 (unspec:TLSmode [(match_dup 1)
9264 (parallel [(set (match_dup 0)
9265 (call (mem:TLSmode (match_dup 3))
9267 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9268 (clobber (reg:SI LR_REGNO))])]
9270 [(set_attr "type" "two")
9271 (set (attr "length")
9272 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9276 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9277 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9278 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9279 (match_operand 4 "" "g")))
9280 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9281 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9283 (clobber (reg:SI LR_REGNO))]
9284 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9288 if (TARGET_SECURE_PLT && flag_pic == 2)
9289 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9291 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9294 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9296 "&& TARGET_TLS_MARKERS"
9298 (unspec:TLSmode [(match_dup 1)
9301 (parallel [(set (match_dup 0)
9302 (call (mem:TLSmode (match_dup 3))
9304 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9305 (clobber (reg:SI LR_REGNO))])]
9307 [(set_attr "type" "two")
9308 (set_attr "length" "8")])
9310 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9311 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9312 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9313 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9315 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9316 "addi %0,%1,%2@got@tlsgd"
9317 "&& TARGET_CMODEL != CMODEL_SMALL"
9320 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9322 (lo_sum:TLSmode (match_dup 3)
9323 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9325 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9327 [(set (attr "length")
9328 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9332 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9333 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9335 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9336 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9338 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9339 "addis %0,%1,%2@got@tlsgd@ha"
9340 [(set_attr "length" "4")])
9342 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9343 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9344 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9345 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9346 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9348 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9349 "addi %0,%1,%2@got@tlsgd@l"
9350 [(set_attr "length" "4")])
9352 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9353 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9354 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9355 (match_operand 2 "" "g")))
9356 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9358 (clobber (reg:SI LR_REGNO))]
9359 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9360 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9361 "bl %z1(%3@tlsgd)\;nop"
9362 [(set_attr "type" "branch")
9363 (set_attr "length" "8")])
9365 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9366 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9367 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9368 (match_operand 2 "" "g")))
9369 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9371 (clobber (reg:SI LR_REGNO))]
9372 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9376 if (TARGET_SECURE_PLT && flag_pic == 2)
9377 return "bl %z1+32768(%3@tlsgd)@plt";
9378 return "bl %z1(%3@tlsgd)@plt";
9380 return "bl %z1(%3@tlsgd)";
9382 [(set_attr "type" "branch")
9383 (set_attr "length" "4")])
9385 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9386 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9387 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9388 (match_operand 3 "" "g")))
9389 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9391 (clobber (reg:SI LR_REGNO))]
9392 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9394 if (TARGET_CMODEL != CMODEL_SMALL)
9395 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9398 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9400 "&& TARGET_TLS_MARKERS"
9402 (unspec:TLSmode [(match_dup 1)]
9404 (parallel [(set (match_dup 0)
9405 (call (mem:TLSmode (match_dup 2))
9407 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9408 (clobber (reg:SI LR_REGNO))])]
9410 [(set_attr "type" "two")
9411 (set (attr "length")
9412 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9416 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
9417 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9418 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9419 (match_operand 3 "" "g")))
9420 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9422 (clobber (reg:SI LR_REGNO))]
9423 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9427 if (TARGET_SECURE_PLT && flag_pic == 2)
9428 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
9430 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
9433 return "addi %0,%1,%&@got@tlsld\;bl %z2";
9435 "&& TARGET_TLS_MARKERS"
9437 (unspec:TLSmode [(match_dup 1)]
9439 (parallel [(set (match_dup 0)
9440 (call (mem:TLSmode (match_dup 2))
9442 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9443 (clobber (reg:SI LR_REGNO))])]
9445 [(set_attr "length" "8")])
9447 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
9448 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9449 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9451 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9452 "addi %0,%1,%&@got@tlsld"
9453 "&& TARGET_CMODEL != CMODEL_SMALL"
9456 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
9458 (lo_sum:TLSmode (match_dup 2)
9459 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
9461 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9463 [(set (attr "length")
9464 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9468 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
9469 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9471 (unspec:TLSmode [(const_int 0)
9472 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9474 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9475 "addis %0,%1,%&@got@tlsld@ha"
9476 [(set_attr "length" "4")])
9478 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
9479 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9480 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9481 (unspec:TLSmode [(const_int 0)
9482 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
9484 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9485 "addi %0,%1,%&@got@tlsld@l"
9486 [(set_attr "length" "4")])
9488 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
9489 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9490 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9491 (match_operand 2 "" "g")))
9492 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9493 (clobber (reg:SI LR_REGNO))]
9494 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9495 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9496 "bl %z1(%&@tlsld)\;nop"
9497 [(set_attr "type" "branch")
9498 (set_attr "length" "8")])
9500 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
9501 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9502 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9503 (match_operand 2 "" "g")))
9504 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
9505 (clobber (reg:SI LR_REGNO))]
9506 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9510 if (TARGET_SECURE_PLT && flag_pic == 2)
9511 return "bl %z1+32768(%&@tlsld)@plt";
9512 return "bl %z1(%&@tlsld)@plt";
9514 return "bl %z1(%&@tlsld)";
9516 [(set_attr "type" "branch")
9517 (set_attr "length" "4")])
9519 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
9520 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9521 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9522 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9525 "addi %0,%1,%2@dtprel")
9527 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
9528 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9529 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9530 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9531 UNSPEC_TLSDTPRELHA))]
9533 "addis %0,%1,%2@dtprel@ha")
9535 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
9536 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9537 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9538 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9539 UNSPEC_TLSDTPRELLO))]
9541 "addi %0,%1,%2@dtprel@l")
9543 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
9544 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9545 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9546 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9547 UNSPEC_TLSGOTDTPREL))]
9549 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
9550 "&& TARGET_CMODEL != CMODEL_SMALL"
9553 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
9555 (lo_sum:TLSmode (match_dup 3)
9556 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
9558 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9560 [(set (attr "length")
9561 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9565 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
9566 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9568 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9569 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9570 UNSPEC_TLSGOTDTPREL)))]
9571 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9572 "addis %0,%1,%2@got@dtprel@ha"
9573 [(set_attr "length" "4")])
9575 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
9576 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9577 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9578 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9579 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9580 UNSPEC_TLSGOTDTPREL)))]
9581 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9582 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
9583 [(set_attr "length" "4")])
9585 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
9586 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9587 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9588 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9591 "addi %0,%1,%2@tprel")
9593 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
9594 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9595 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9596 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9597 UNSPEC_TLSTPRELHA))]
9599 "addis %0,%1,%2@tprel@ha")
9601 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
9602 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9603 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9604 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9605 UNSPEC_TLSTPRELLO))]
9607 "addi %0,%1,%2@tprel@l")
9609 ;; "b" output constraint here and on tls_tls input to support linker tls
9610 ;; optimization. The linker may edit the instructions emitted by a
9611 ;; tls_got_tprel/tls_tls pair to addis,addi.
9612 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
9613 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9614 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9615 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9616 UNSPEC_TLSGOTTPREL))]
9618 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
9619 "&& TARGET_CMODEL != CMODEL_SMALL"
9622 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
9624 (lo_sum:TLSmode (match_dup 3)
9625 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
9627 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9629 [(set (attr "length")
9630 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9634 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
9635 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9637 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9638 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9639 UNSPEC_TLSGOTTPREL)))]
9640 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9641 "addis %0,%1,%2@got@tprel@ha"
9642 [(set_attr "length" "4")])
9644 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
9645 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9646 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9647 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9648 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9649 UNSPEC_TLSGOTTPREL)))]
9650 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
9651 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
9652 [(set_attr "length" "4")])
9654 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
9655 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
9656 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9657 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9659 "TARGET_ELF && HAVE_AS_TLS"
9662 (define_expand "tls_get_tpointer"
9663 [(set (match_operand:SI 0 "gpc_reg_operand")
9664 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
9665 "TARGET_XCOFF && HAVE_AS_TLS"
9667 emit_insn (gen_tls_get_tpointer_internal ());
9668 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
9672 (define_insn "tls_get_tpointer_internal"
9674 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
9675 (clobber (reg:SI LR_REGNO))]
9676 "TARGET_XCOFF && HAVE_AS_TLS"
9677 "bla __get_tpointer")
9679 (define_expand "tls_get_addr<mode>"
9680 [(set (match_operand:P 0 "gpc_reg_operand")
9681 (unspec:P [(match_operand:P 1 "gpc_reg_operand")
9682 (match_operand:P 2 "gpc_reg_operand")] UNSPEC_TLSTLS))]
9683 "TARGET_XCOFF && HAVE_AS_TLS"
9685 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
9686 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
9687 emit_insn (gen_tls_get_addr_internal<mode> ());
9688 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
9692 (define_insn "tls_get_addr_internal<mode>"
9694 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
9698 (clobber (reg:P 11))
9699 (clobber (reg:CC CR0_REGNO))
9700 (clobber (reg:P LR_REGNO))]
9701 "TARGET_XCOFF && HAVE_AS_TLS"
9702 "bla __tls_get_addr")
9704 ;; Next come insns related to the calling sequence.
9706 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
9707 ;; We move the back-chain and decrement the stack pointer.
9709 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
9710 ;; constant alloca, using that predicate will force the generic code to put
9711 ;; the constant size into a register before calling the expander.
9713 ;; As a result the expander would not have the constant size information
9714 ;; in those cases and would have to generate less efficient code.
9716 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
9717 ;; the constant size. The value is forced into a register if necessary.
9719 (define_expand "allocate_stack"
9720 [(set (match_operand 0 "gpc_reg_operand")
9721 (minus (reg 1) (match_operand 1 "reg_or_cint_operand")))
9723 (minus (reg 1) (match_dup 1)))]
9726 rtx chain = gen_reg_rtx (Pmode);
9727 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
9729 rtx insn, par, set, mem;
9731 /* By allowing reg_or_cint_operand as the predicate we can get
9732 better code for stack-clash-protection because we do not lose
9733 size information. But the rest of the code expects the operand
9734 to be reg_or_short_operand. If it isn't, then force it into
9736 rtx orig_op1 = operands[1];
9737 if (!reg_or_short_operand (operands[1], Pmode))
9738 operands[1] = force_reg (Pmode, operands[1]);
9740 emit_move_insn (chain, stack_bot);
9742 /* Check stack bounds if necessary. */
9743 if (crtl->limit_stack)
9746 available = expand_binop (Pmode, sub_optab,
9747 stack_pointer_rtx, stack_limit_rtx,
9748 NULL_RTX, 1, OPTAB_WIDEN);
9749 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
9752 /* Allocate and probe if requested.
9753 This may look similar to the loop we use for prologue allocations,
9754 but it is critically different. For the former we know the loop
9755 will iterate, but do not know that generally here. The former
9756 uses that knowledge to rotate the loop. Combining them would be
9757 possible with some performance cost. */
9758 if (flag_stack_clash_protection)
9760 rtx rounded_size, last_addr, residual;
9761 HOST_WIDE_INT probe_interval;
9762 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
9763 &residual, &probe_interval,
9766 /* We do occasionally get in here with constant sizes, we might
9767 as well do a reasonable job when we obviously can. */
9768 if (rounded_size != const0_rtx)
9770 rtx loop_lab, end_loop;
9771 bool rotated = CONST_INT_P (rounded_size);
9772 rtx update = GEN_INT (-probe_interval);
9773 if (probe_interval > 32768)
9774 update = force_reg (Pmode, update);
9776 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
9777 last_addr, rotated);
9779 if (Pmode == SImode)
9780 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
9784 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
9787 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
9788 last_addr, rotated);
9791 /* Now handle residuals. We just have to set operands[1] correctly
9792 and let the rest of the expander run. */
9793 operands[1] = residual;
9794 if (!CONST_INT_P (residual))
9795 operands[1] = force_reg (Pmode, operands[1]);
9798 if (GET_CODE (operands[1]) != CONST_INT
9799 || INTVAL (operands[1]) < -32767
9800 || INTVAL (operands[1]) > 32768)
9802 neg_op0 = gen_reg_rtx (Pmode);
9804 emit_insn (gen_negsi2 (neg_op0, operands[1]));
9806 emit_insn (gen_negdi2 (neg_op0, operands[1]));
9809 neg_op0 = GEN_INT (- INTVAL (operands[1]));
9811 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
9812 : gen_movdi_di_update_stack))
9813 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
9815 /* Since we didn't use gen_frame_mem to generate the MEM, grab
9816 it now and set the alias set/attributes. The above gen_*_update
9817 calls will generate a PARALLEL with the MEM set being the first
9819 par = PATTERN (insn);
9820 gcc_assert (GET_CODE (par) == PARALLEL);
9821 set = XVECEXP (par, 0, 0);
9822 gcc_assert (GET_CODE (set) == SET);
9823 mem = SET_DEST (set);
9824 gcc_assert (MEM_P (mem));
9825 MEM_NOTRAP_P (mem) = 1;
9826 set_mem_alias_set (mem, get_frame_alias_set ());
9828 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
9832 ;; These patterns say how to save and restore the stack pointer. We need not
9833 ;; save the stack pointer at function level since we are careful to
9834 ;; preserve the backchain. At block level, we have to restore the backchain
9835 ;; when we restore the stack pointer.
9837 ;; For nonlocal gotos, we must save both the stack pointer and its
9838 ;; backchain and restore both. Note that in the nonlocal case, the
9839 ;; save area is a memory location.
9841 (define_expand "save_stack_function"
9842 [(match_operand 0 "any_operand")
9843 (match_operand 1 "any_operand")]
9847 (define_expand "restore_stack_function"
9848 [(match_operand 0 "any_operand")
9849 (match_operand 1 "any_operand")]
9853 ;; Adjust stack pointer (op0) to a new value (op1).
9854 ;; First copy old stack backchain to new location, and ensure that the
9855 ;; scheduler won't reorder the sp assignment before the backchain write.
9856 (define_expand "restore_stack_block"
9857 [(set (match_dup 2) (match_dup 3))
9858 (set (match_dup 4) (match_dup 2))
9860 (set (match_operand 0 "register_operand")
9861 (match_operand 1 "register_operand"))]
9866 operands[1] = force_reg (Pmode, operands[1]);
9867 operands[2] = gen_reg_rtx (Pmode);
9868 operands[3] = gen_frame_mem (Pmode, operands[0]);
9869 operands[4] = gen_frame_mem (Pmode, operands[1]);
9870 p = rtvec_alloc (1);
9871 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9873 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
9876 (define_expand "save_stack_nonlocal"
9877 [(set (match_dup 3) (match_dup 4))
9878 (set (match_operand 0 "memory_operand") (match_dup 3))
9879 (set (match_dup 2) (match_operand 1 "register_operand"))]
9882 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9884 /* Copy the backchain to the first word, sp to the second. */
9885 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
9886 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
9887 operands[3] = gen_reg_rtx (Pmode);
9888 operands[4] = gen_frame_mem (Pmode, operands[1]);
9891 (define_expand "restore_stack_nonlocal"
9892 [(set (match_dup 2) (match_operand 1 "memory_operand"))
9893 (set (match_dup 3) (match_dup 4))
9894 (set (match_dup 5) (match_dup 2))
9896 (set (match_operand 0 "register_operand") (match_dup 3))]
9899 int units_per_word = (TARGET_32BIT) ? 4 : 8;
9902 /* Restore the backchain from the first word, sp from the second. */
9903 operands[2] = gen_reg_rtx (Pmode);
9904 operands[3] = gen_reg_rtx (Pmode);
9905 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
9906 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
9907 operands[5] = gen_frame_mem (Pmode, operands[3]);
9908 p = rtvec_alloc (1);
9909 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
9911 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
9914 ;; TOC register handling.
9916 ;; Code to initialize the TOC register...
9918 (define_insn "load_toc_aix_si"
9919 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
9920 (unspec:SI [(const_int 0)] UNSPEC_TOC))
9922 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
9925 extern int need_toc_init;
9927 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC", 1);
9928 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9929 operands[2] = gen_rtx_REG (Pmode, 2);
9930 return "lwz %0,%1(%2)";
9932 [(set_attr "type" "load")
9933 (set_attr "update" "no")
9934 (set_attr "indexed" "no")])
9936 (define_insn "load_toc_aix_di"
9937 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
9938 (unspec:DI [(const_int 0)] UNSPEC_TOC))
9940 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
9943 extern int need_toc_init;
9945 ASM_GENERATE_INTERNAL_LABEL (buf, "LCTOC",
9946 !TARGET_ELF || !TARGET_MINIMAL_TOC);
9948 strcat (buf, "@toc");
9949 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
9950 operands[2] = gen_rtx_REG (Pmode, 2);
9951 return "ld %0,%1(%2)";
9953 [(set_attr "type" "load")
9954 (set_attr "update" "no")
9955 (set_attr "indexed" "no")])
9957 (define_insn "load_toc_v4_pic_si"
9958 [(set (reg:SI LR_REGNO)
9959 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
9960 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
9961 "bl _GLOBAL_OFFSET_TABLE_@local-4"
9962 [(set_attr "type" "branch")
9963 (set_attr "length" "4")])
9965 (define_expand "load_toc_v4_PIC_1"
9966 [(parallel [(set (reg:SI LR_REGNO)
9967 (match_operand:SI 0 "immediate_operand" "s"))
9968 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
9969 "TARGET_ELF && DEFAULT_ABI == ABI_V4
9970 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9973 (define_insn "load_toc_v4_PIC_1_normal"
9974 [(set (reg:SI LR_REGNO)
9975 (match_operand:SI 0 "immediate_operand" "s"))
9976 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9977 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9978 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9980 [(set_attr "type" "branch")
9981 (set_attr "length" "4")
9982 (set_attr "cannot_copy" "yes")])
9984 (define_insn "load_toc_v4_PIC_1_476"
9985 [(set (reg:SI LR_REGNO)
9986 (match_operand:SI 0 "immediate_operand" "s"))
9987 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
9988 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
9989 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
9992 static char templ[32];
9994 get_ppc476_thunk_name (name);
9995 sprintf (templ, "bl %s\n%%0:", name);
9998 [(set_attr "type" "branch")
9999 (set_attr "length" "4")
10000 (set_attr "cannot_copy" "yes")])
10002 (define_expand "load_toc_v4_PIC_1b"
10003 [(parallel [(set (reg:SI LR_REGNO)
10004 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10005 (label_ref (match_operand 1 ""))]
10008 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10011 (define_insn "load_toc_v4_PIC_1b_normal"
10012 [(set (reg:SI LR_REGNO)
10013 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10014 (label_ref (match_operand 1 "" ""))]
10017 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10018 "bcl 20,31,$+8\;.long %0-$"
10019 [(set_attr "type" "branch")
10020 (set_attr "length" "8")])
10022 (define_insn "load_toc_v4_PIC_1b_476"
10023 [(set (reg:SI LR_REGNO)
10024 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10025 (label_ref (match_operand 1 "" ""))]
10028 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10031 static char templ[32];
10033 get_ppc476_thunk_name (name);
10034 sprintf (templ, "bl %s\;b $+8\;.long %%0-$", name);
10037 [(set_attr "type" "branch")
10038 (set_attr "length" "16")])
10040 (define_insn "load_toc_v4_PIC_2"
10041 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10043 (match_operand:SI 1 "gpc_reg_operand" "b")
10045 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10046 (match_operand:SI 3 "immediate_operand" "s"))))))]
10047 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10049 [(set_attr "type" "load")])
10051 (define_insn "load_toc_v4_PIC_3b"
10052 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10054 (match_operand:SI 1 "gpc_reg_operand" "b")
10057 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10058 (match_operand:SI 3 "symbol_ref_operand" "s"))))))]
10059 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10060 "addis %0,%1,%2-%3@ha")
10062 (define_insn "load_toc_v4_PIC_3c"
10063 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10065 (match_operand:SI 1 "gpc_reg_operand" "b")
10067 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10068 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10069 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10070 "addi %0,%1,%2-%3@l")
10072 ;; If the TOC is shared over a translation unit, as happens with all
10073 ;; the kinds of PIC that we support, we need to restore the TOC
10074 ;; pointer only when jumping over units of translation.
10075 ;; On Darwin, we need to reload the picbase.
10077 (define_expand "builtin_setjmp_receiver"
10078 [(use (label_ref (match_operand 0 "")))]
10079 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10080 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10081 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10084 if (DEFAULT_ABI == ABI_DARWIN)
10086 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10087 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10091 crtl->uses_pic_offset_table = 1;
10092 ASM_GENERATE_INTERNAL_LABEL(tmplab, "LSJR",
10093 CODE_LABEL_NUMBER (operands[0]));
10094 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10096 emit_insn (gen_load_macho_picbase (tmplabrtx));
10097 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10098 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10102 rs6000_emit_load_toc_table (FALSE);
10106 ;; Largetoc support
10107 (define_insn "*largetoc_high"
10108 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10110 (unspec [(match_operand:DI 1 "" "")
10111 (match_operand:DI 2 "gpc_reg_operand" "b")]
10113 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10114 "addis %0,%2,%1@toc@ha")
10116 (define_insn "*largetoc_high_aix<mode>"
10117 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10119 (unspec [(match_operand:P 1 "" "")
10120 (match_operand:P 2 "gpc_reg_operand" "b")]
10122 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10123 "addis %0,%1@u(%2)")
10125 (define_insn "*largetoc_high_plus"
10126 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10129 (unspec [(match_operand:DI 1 "" "")
10130 (match_operand:DI 2 "gpc_reg_operand" "b")]
10132 (match_operand:DI 3 "add_cint_operand" "n"))))]
10133 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10134 "addis %0,%2,%1+%3@toc@ha")
10136 (define_insn "*largetoc_high_plus_aix<mode>"
10137 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10140 (unspec [(match_operand:P 1 "" "")
10141 (match_operand:P 2 "gpc_reg_operand" "b")]
10143 (match_operand:P 3 "add_cint_operand" "n"))))]
10144 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10145 "addis %0,%1+%3@u(%2)")
10147 (define_insn "*largetoc_low"
10148 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10149 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10150 (match_operand:DI 2 "" "")))]
10151 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10154 (define_insn "*largetoc_low_aix<mode>"
10155 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10156 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10157 (match_operand:P 2 "" "")))]
10158 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10161 (define_insn_and_split "*tocref<mode>"
10162 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10163 (match_operand:P 1 "small_toc_ref" "R"))]
10166 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10167 [(set (match_dup 0) (high:P (match_dup 1)))
10168 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10170 ;; Elf specific ways of loading addresses for non-PIC code.
10171 ;; The output of this could be r0, but we make a very strong
10172 ;; preference for a base register because it will usually
10173 ;; be needed there.
10174 (define_insn "elf_high"
10175 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10176 (high:SI (match_operand 1 "" "")))]
10177 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10180 (define_insn "elf_low"
10181 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10182 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10183 (match_operand 2 "" "")))]
10184 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10187 ;; Call and call_value insns
10188 (define_expand "call"
10189 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10190 (match_operand 1 ""))
10191 (use (match_operand 2 ""))
10192 (clobber (reg:SI LR_REGNO))])]
10196 if (MACHOPIC_INDIRECT)
10197 operands[0] = machopic_indirect_call_target (operands[0]);
10200 gcc_assert (GET_CODE (operands[0]) == MEM);
10201 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10203 operands[0] = XEXP (operands[0], 0);
10205 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10207 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10211 if (GET_CODE (operands[0]) != SYMBOL_REF
10212 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10214 if (INTVAL (operands[2]) & CALL_LONG)
10215 operands[0] = rs6000_longcall_ref (operands[0]);
10217 switch (DEFAULT_ABI)
10221 operands[0] = force_reg (Pmode, operands[0]);
10225 gcc_unreachable ();
10230 (define_expand "call_value"
10231 [(parallel [(set (match_operand 0 "")
10232 (call (mem:SI (match_operand 1 "address_operand"))
10233 (match_operand 2 "")))
10234 (use (match_operand 3 ""))
10235 (clobber (reg:SI LR_REGNO))])]
10239 if (MACHOPIC_INDIRECT)
10240 operands[1] = machopic_indirect_call_target (operands[1]);
10243 gcc_assert (GET_CODE (operands[1]) == MEM);
10244 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10246 operands[1] = XEXP (operands[1], 0);
10248 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10250 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10254 if (GET_CODE (operands[1]) != SYMBOL_REF
10255 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10257 if (INTVAL (operands[3]) & CALL_LONG)
10258 operands[1] = rs6000_longcall_ref (operands[1]);
10260 switch (DEFAULT_ABI)
10264 operands[1] = force_reg (Pmode, operands[1]);
10268 gcc_unreachable ();
10273 ;; Call to function in current module. No TOC pointer reload needed.
10274 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10275 ;; either the function was not prototyped, or it was prototyped as a
10276 ;; variable argument function. It is > 0 if FP registers were passed
10277 ;; and < 0 if they were not.
10279 (define_insn "*call_local32"
10280 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10281 (match_operand 1 "" "g,g"))
10282 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10283 (clobber (reg:SI LR_REGNO))]
10284 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10286 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10287 output_asm_insn ("crxor 6,6,6", operands);
10289 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10290 output_asm_insn ("creqv 6,6,6", operands);
10292 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10294 [(set_attr "type" "branch")
10295 (set_attr "length" "4,8")])
10297 (define_insn "*call_local64"
10298 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10299 (match_operand 1 "" "g,g"))
10300 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10301 (clobber (reg:SI LR_REGNO))]
10302 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10304 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10305 output_asm_insn ("crxor 6,6,6", operands);
10307 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10308 output_asm_insn ("creqv 6,6,6", operands);
10310 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z0@local" : "bl %z0";
10312 [(set_attr "type" "branch")
10313 (set_attr "length" "4,8")])
10315 (define_insn "*call_value_local32"
10316 [(set (match_operand 0 "" "")
10317 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10318 (match_operand 2 "" "g,g")))
10319 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10320 (clobber (reg:SI LR_REGNO))]
10321 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10323 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10324 output_asm_insn ("crxor 6,6,6", operands);
10326 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10327 output_asm_insn ("creqv 6,6,6", operands);
10329 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10331 [(set_attr "type" "branch")
10332 (set_attr "length" "4,8")])
10335 (define_insn "*call_value_local64"
10336 [(set (match_operand 0 "" "")
10337 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10338 (match_operand 2 "" "g,g")))
10339 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10340 (clobber (reg:SI LR_REGNO))]
10341 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10343 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10344 output_asm_insn ("crxor 6,6,6", operands);
10346 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10347 output_asm_insn ("creqv 6,6,6", operands);
10349 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "bl %z1@local" : "bl %z1";
10351 [(set_attr "type" "branch")
10352 (set_attr "length" "4,8")])
10355 ;; A function pointer under System V is just a normal pointer
10356 ;; operands[0] is the function pointer
10357 ;; operands[1] is the stack size to clean up
10358 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10359 ;; which indicates how to set cr1
10361 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10362 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10363 (match_operand 1 "" "g,g,g,g"))
10364 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10365 (clobber (reg:SI LR_REGNO))]
10366 "DEFAULT_ABI == ABI_V4
10367 || DEFAULT_ABI == ABI_DARWIN"
10369 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10370 output_asm_insn ("crxor 6,6,6", operands);
10372 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10373 output_asm_insn ("creqv 6,6,6", operands);
10375 if (rs6000_speculate_indirect_jumps
10376 || which_alternative == 1 || which_alternative == 3)
10379 return "crset 2\;beq%T0l-";
10381 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10382 (set (attr "length")
10383 (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10384 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10387 (and (eq (symbol_ref "which_alternative") (const_int 2))
10388 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10391 (and (eq (symbol_ref "which_alternative") (const_int 2))
10392 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10394 (const_string "12")
10395 (eq (symbol_ref "which_alternative") (const_int 3))
10396 (const_string "8")]
10397 (const_string "4")))])
10399 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10400 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10401 (match_operand 1 "" "g,g"))
10402 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10403 (clobber (reg:SI LR_REGNO))]
10404 "(DEFAULT_ABI == ABI_DARWIN
10405 || (DEFAULT_ABI == ABI_V4
10406 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10408 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10409 output_asm_insn ("crxor 6,6,6", operands);
10411 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10412 output_asm_insn ("creqv 6,6,6", operands);
10415 return output_call(insn, operands, 0, 2);
10417 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10419 gcc_assert (!TARGET_SECURE_PLT);
10420 return "bl %z0@plt";
10426 "DEFAULT_ABI == ABI_V4
10427 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10428 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10429 [(parallel [(call (mem:SI (match_dup 0))
10431 (use (match_dup 2))
10432 (use (match_dup 3))
10433 (clobber (reg:SI LR_REGNO))])]
10435 operands[3] = pic_offset_table_rtx;
10437 [(set_attr "type" "branch,branch")
10438 (set_attr "length" "4,8")])
10440 (define_insn "*call_nonlocal_sysv_secure<mode>"
10441 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10442 (match_operand 1 "" "g,g"))
10443 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10444 (use (match_operand:SI 3 "register_operand" "r,r"))
10445 (clobber (reg:SI LR_REGNO))]
10446 "(DEFAULT_ABI == ABI_V4
10447 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
10448 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
10450 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10451 output_asm_insn ("crxor 6,6,6", operands);
10453 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10454 output_asm_insn ("creqv 6,6,6", operands);
10457 /* The magic 32768 offset here and in the other sysv call insns
10458 corresponds to the offset of r30 in .got2, as given by LCTOC1.
10459 See sysv4.h:toc_section. */
10460 return "bl %z0+32768@plt";
10462 return "bl %z0@plt";
10464 [(set_attr "type" "branch,branch")
10465 (set_attr "length" "4,8")])
10467 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
10468 [(set (match_operand 0 "" "")
10469 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
10470 (match_operand 2 "" "g,g,g,g")))
10471 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
10472 (clobber (reg:SI LR_REGNO))]
10473 "DEFAULT_ABI == ABI_V4
10474 || DEFAULT_ABI == ABI_DARWIN"
10476 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10477 output_asm_insn ("crxor 6,6,6", operands);
10479 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10480 output_asm_insn ("creqv 6,6,6", operands);
10482 if (rs6000_speculate_indirect_jumps
10483 || which_alternative == 1 || which_alternative == 3)
10486 return "crset 2\;beq%T1l-";
10488 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10489 (set (attr "length")
10490 (cond [(and (eq (symbol_ref "which_alternative") (const_int 0))
10491 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10494 (and (eq (symbol_ref "which_alternative") (const_int 2))
10495 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10498 (and (eq (symbol_ref "which_alternative") (const_int 2))
10499 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10501 (const_string "12")
10502 (eq (symbol_ref "which_alternative") (const_int 3))
10503 (const_string "8")]
10504 (const_string "4")))])
10506 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
10507 [(set (match_operand 0 "" "")
10508 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10509 (match_operand 2 "" "g,g")))
10510 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10511 (clobber (reg:SI LR_REGNO))]
10512 "(DEFAULT_ABI == ABI_DARWIN
10513 || (DEFAULT_ABI == ABI_V4
10514 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
10516 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10517 output_asm_insn ("crxor 6,6,6", operands);
10519 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10520 output_asm_insn ("creqv 6,6,6", operands);
10523 return output_call(insn, operands, 1, 3);
10525 if (DEFAULT_ABI == ABI_V4 && flag_pic)
10527 gcc_assert (!TARGET_SECURE_PLT);
10528 return "bl %z1@plt";
10534 "DEFAULT_ABI == ABI_V4
10535 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10536 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10537 [(parallel [(set (match_dup 0)
10538 (call (mem:SI (match_dup 1))
10540 (use (match_dup 3))
10541 (use (match_dup 4))
10542 (clobber (reg:SI LR_REGNO))])]
10544 operands[4] = pic_offset_table_rtx;
10546 [(set_attr "type" "branch,branch")
10547 (set_attr "length" "4,8")])
10549 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
10550 [(set (match_operand 0 "" "")
10551 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
10552 (match_operand 2 "" "g,g")))
10553 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10554 (use (match_operand:SI 4 "register_operand" "r,r"))
10555 (clobber (reg:SI LR_REGNO))]
10556 "(DEFAULT_ABI == ABI_V4
10557 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
10558 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
10560 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10561 output_asm_insn ("crxor 6,6,6", operands);
10563 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10564 output_asm_insn ("creqv 6,6,6", operands);
10567 return "bl %z1+32768@plt";
10569 return "bl %z1@plt";
10571 [(set_attr "type" "branch,branch")
10572 (set_attr "length" "4,8")])
10575 ;; Call to AIX abi function in the same module.
10577 (define_insn "*call_local_aix<mode>"
10578 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
10579 (match_operand 1 "" "g"))
10580 (clobber (reg:P LR_REGNO))]
10581 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10583 [(set_attr "type" "branch")
10584 (set_attr "length" "4")])
10586 (define_insn "*call_value_local_aix<mode>"
10587 [(set (match_operand 0 "" "")
10588 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
10589 (match_operand 2 "" "g")))
10590 (clobber (reg:P LR_REGNO))]
10591 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10593 [(set_attr "type" "branch")
10594 (set_attr "length" "4")])
10596 ;; Call to AIX abi function which may be in another module.
10597 ;; Restore the TOC pointer (r2) after the call.
10599 (define_insn "*call_nonlocal_aix<mode>"
10600 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
10601 (match_operand 1 "" "g"))
10602 (clobber (reg:P LR_REGNO))]
10603 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10605 [(set_attr "type" "branch")
10606 (set_attr "length" "8")])
10608 (define_insn "*call_value_nonlocal_aix<mode>"
10609 [(set (match_operand 0 "" "")
10610 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
10611 (match_operand 2 "" "g")))
10612 (clobber (reg:P LR_REGNO))]
10613 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10615 [(set_attr "type" "branch")
10616 (set_attr "length" "8")])
10618 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
10619 ;; Operand0 is the addresss of the function to call
10620 ;; Operand2 is the location in the function descriptor to load r2 from
10621 ;; Operand3 is the offset of the stack location holding the current TOC pointer
10623 (define_insn "*call_indirect_aix<mode>"
10624 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10625 (match_operand 1 "" "g,g"))
10626 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10627 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10628 (clobber (reg:P LR_REGNO))]
10629 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10630 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
10631 [(set_attr "type" "jmpreg")
10632 (set_attr "length" "12")])
10634 (define_insn "*call_indirect_aix<mode>_nospec"
10635 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10636 (match_operand 1 "" "g,g"))
10637 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
10638 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10639 (clobber (reg:P LR_REGNO))]
10640 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10641 "crset 2\;<ptrload> 2,%2\;beq%T0l-\;<ptrload> 2,%3(1)"
10642 [(set_attr "type" "jmpreg")
10643 (set_attr "length" "16")])
10645 (define_insn "*call_value_indirect_aix<mode>"
10646 [(set (match_operand 0 "" "")
10647 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10648 (match_operand 2 "" "g,g")))
10649 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10650 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10651 (clobber (reg:P LR_REGNO))]
10652 "DEFAULT_ABI == ABI_AIX && rs6000_speculate_indirect_jumps"
10653 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
10654 [(set_attr "type" "jmpreg")
10655 (set_attr "length" "12")])
10657 (define_insn "*call_value_indirect_aix<mode>_nospec"
10658 [(set (match_operand 0 "" "")
10659 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10660 (match_operand 2 "" "g,g")))
10661 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
10662 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10663 (clobber (reg:P LR_REGNO))]
10664 "DEFAULT_ABI == ABI_AIX && !rs6000_speculate_indirect_jumps"
10665 "crset 2\;<ptrload> 2,%3\;beq%T1l-\;<ptrload> 2,%4(1)"
10666 [(set_attr "type" "jmpreg")
10667 (set_attr "length" "16")])
10669 ;; Call to indirect functions with the ELFv2 ABI.
10670 ;; Operand0 is the addresss of the function to call
10671 ;; Operand2 is the offset of the stack location holding the current TOC pointer
10673 (define_insn "*call_indirect_elfv2<mode>"
10674 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10675 (match_operand 1 "" "g,g"))
10676 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10677 (clobber (reg:P LR_REGNO))]
10678 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10679 "b%T0l\;<ptrload> 2,%2(1)"
10680 [(set_attr "type" "jmpreg")
10681 (set_attr "length" "8")])
10683 ;; Variant with deliberate misprediction.
10684 (define_insn "*call_indirect_elfv2<mode>_nospec"
10685 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
10686 (match_operand 1 "" "g,g"))
10687 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10688 (clobber (reg:P LR_REGNO))]
10689 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10690 "crset 2\;beq%T0l-\;<ptrload> 2,%2(1)"
10691 [(set_attr "type" "jmpreg")
10692 (set_attr "length" "12")])
10694 (define_insn "*call_value_indirect_elfv2<mode>"
10695 [(set (match_operand 0 "" "")
10696 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10697 (match_operand 2 "" "g,g")))
10698 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10699 (clobber (reg:P LR_REGNO))]
10700 "DEFAULT_ABI == ABI_ELFv2 && rs6000_speculate_indirect_jumps"
10701 "b%T1l\;<ptrload> 2,%3(1)"
10702 [(set_attr "type" "jmpreg")
10703 (set_attr "length" "8")])
10705 ; Variant with deliberate misprediction.
10706 (define_insn "*call_value_indirect_elfv2<mode>_nospec"
10707 [(set (match_operand 0 "" "")
10708 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
10709 (match_operand 2 "" "g,g")))
10710 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
10711 (clobber (reg:P LR_REGNO))]
10712 "DEFAULT_ABI == ABI_ELFv2 && !rs6000_speculate_indirect_jumps"
10713 "crset 2\;beq%T1l-\;<ptrload> 2,%3(1)"
10714 [(set_attr "type" "jmpreg")
10715 (set_attr "length" "12")])
10717 ;; Call subroutine returning any type.
10718 (define_expand "untyped_call"
10719 [(parallel [(call (match_operand 0 "")
10721 (match_operand 1 "")
10722 (match_operand 2 "")])]
10727 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
10729 for (i = 0; i < XVECLEN (operands[2], 0); i++)
10731 rtx set = XVECEXP (operands[2], 0, i);
10732 emit_move_insn (SET_DEST (set), SET_SRC (set));
10735 /* The optimizer does not know that the call sets the function value
10736 registers we stored in the result block. We avoid problems by
10737 claiming that all hard registers are used and clobbered at this
10739 emit_insn (gen_blockage ());
10744 ;; sibling call patterns
10745 (define_expand "sibcall"
10746 [(parallel [(call (mem:SI (match_operand 0 "address_operand"))
10747 (match_operand 1 ""))
10748 (use (match_operand 2 ""))
10753 if (MACHOPIC_INDIRECT)
10754 operands[0] = machopic_indirect_call_target (operands[0]);
10757 gcc_assert (GET_CODE (operands[0]) == MEM);
10758 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10760 operands[0] = XEXP (operands[0], 0);
10762 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10764 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10769 (define_expand "sibcall_value"
10770 [(parallel [(set (match_operand 0 "register_operand")
10771 (call (mem:SI (match_operand 1 "address_operand"))
10772 (match_operand 2 "")))
10773 (use (match_operand 3 ""))
10778 if (MACHOPIC_INDIRECT)
10779 operands[1] = machopic_indirect_call_target (operands[1]);
10782 gcc_assert (GET_CODE (operands[1]) == MEM);
10783 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10785 operands[1] = XEXP (operands[1], 0);
10787 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10789 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
10794 (define_insn "*sibcall_local32"
10795 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10796 (match_operand 1 "" "g,g"))
10797 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10799 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10801 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10802 output_asm_insn ("crxor 6,6,6", operands);
10804 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10805 output_asm_insn ("creqv 6,6,6", operands);
10807 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10809 [(set_attr "type" "branch")
10810 (set_attr "length" "4,8")])
10812 (define_insn "*sibcall_local64"
10813 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10814 (match_operand 1 "" "g,g"))
10815 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10817 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10819 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10820 output_asm_insn ("crxor 6,6,6", operands);
10822 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10823 output_asm_insn ("creqv 6,6,6", operands);
10825 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z0@local" : "b %z0";
10827 [(set_attr "type" "branch")
10828 (set_attr "length" "4,8")])
10830 (define_insn "*sibcall_value_local32"
10831 [(set (match_operand 0 "" "")
10832 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10833 (match_operand 2 "" "g,g")))
10834 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10836 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10838 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10839 output_asm_insn ("crxor 6,6,6", operands);
10841 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10842 output_asm_insn ("creqv 6,6,6", operands);
10844 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10846 [(set_attr "type" "branch")
10847 (set_attr "length" "4,8")])
10849 (define_insn "*sibcall_value_local64"
10850 [(set (match_operand 0 "" "")
10851 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10852 (match_operand 2 "" "g,g")))
10853 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10855 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10857 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10858 output_asm_insn ("crxor 6,6,6", operands);
10860 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10861 output_asm_insn ("creqv 6,6,6", operands);
10863 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? "b %z1@local" : "b %z1";
10865 [(set_attr "type" "branch")
10866 (set_attr "length" "4,8")])
10868 (define_insn "*sibcall_nonlocal_sysv<mode>"
10869 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
10870 (match_operand 1 "" ""))
10871 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
10873 "(DEFAULT_ABI == ABI_DARWIN
10874 || DEFAULT_ABI == ABI_V4)
10875 && (INTVAL (operands[2]) & CALL_LONG) == 0"
10877 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10878 output_asm_insn ("crxor 6,6,6", operands);
10880 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10881 output_asm_insn ("creqv 6,6,6", operands);
10883 if (which_alternative >= 2)
10885 if (rs6000_speculate_indirect_jumps)
10888 /* Can use CR0 since it is volatile across sibcalls. */
10889 return "crset 2\;beq%T0-\;b $";
10891 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10893 gcc_assert (!TARGET_SECURE_PLT);
10894 return "b %z0@plt";
10899 [(set_attr "type" "branch")
10900 (set (attr "length")
10901 (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10903 (and (eq (symbol_ref "which_alternative") (const_int 2))
10904 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10906 (const_string "12")
10907 (and (eq (symbol_ref "which_alternative") (const_int 3))
10908 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10911 (and (eq (symbol_ref "which_alternative") (const_int 3))
10912 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10914 (const_string "16")]
10915 (const_string "4")))])
10917 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
10918 [(set (match_operand 0 "" "")
10919 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
10920 (match_operand 2 "" "")))
10921 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
10923 "(DEFAULT_ABI == ABI_DARWIN
10924 || DEFAULT_ABI == ABI_V4)
10925 && (INTVAL (operands[3]) & CALL_LONG) == 0"
10927 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10928 output_asm_insn ("crxor 6,6,6", operands);
10930 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10931 output_asm_insn ("creqv 6,6,6", operands);
10933 if (which_alternative >= 2)
10935 if (rs6000_speculate_indirect_jumps)
10938 /* Can use CR0 since it is volatile across sibcalls. */
10939 return "crset 2\;beq%T1-\;b $";
10941 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
10943 gcc_assert (!TARGET_SECURE_PLT);
10944 return "b %z1@plt";
10949 [(set_attr "type" "branch")
10950 (set (attr "length")
10951 (cond [(eq (symbol_ref "which_alternative") (const_int 1))
10953 (and (eq (symbol_ref "which_alternative") (const_int 2))
10954 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10956 (const_string "12")
10957 (and (eq (symbol_ref "which_alternative") (const_int 3))
10958 (ne (symbol_ref "rs6000_speculate_indirect_jumps")
10961 (and (eq (symbol_ref "which_alternative") (const_int 3))
10962 (eq (symbol_ref "rs6000_speculate_indirect_jumps")
10964 (const_string "16")]
10965 (const_string "4")))])
10967 ;; AIX ABI sibling call patterns.
10969 (define_insn "*sibcall_aix<mode>"
10970 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
10971 (match_operand 1 "" "g,g"))
10973 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10977 [(set_attr "type" "branch")
10978 (set_attr "length" "4")])
10980 (define_insn "*sibcall_value_aix<mode>"
10981 [(set (match_operand 0 "" "")
10982 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
10983 (match_operand 2 "" "g,g")))
10985 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
10989 [(set_attr "type" "branch")
10990 (set_attr "length" "4")])
10992 (define_expand "sibcall_epilogue"
10993 [(use (const_int 0))]
10996 if (!TARGET_SCHED_PROLOG)
10997 emit_insn (gen_blockage ());
10998 rs6000_emit_epilogue (TRUE);
11002 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11003 ;; all of memory. This blocks insns from being moved across this point.
11005 (define_insn "blockage"
11006 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11009 [(set_attr "length" "0")])
11011 (define_expand "probe_stack_address"
11012 [(use (match_operand 0 "address_operand"))]
11015 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11016 MEM_VOLATILE_P (operands[0]) = 1;
11019 emit_insn (gen_probe_stack_di (operands[0]));
11021 emit_insn (gen_probe_stack_si (operands[0]));
11025 (define_insn "probe_stack_<mode>"
11026 [(set (match_operand:P 0 "memory_operand" "=m")
11027 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11030 operands[1] = gen_rtx_REG (Pmode, 0);
11031 return "st<wd>%U0%X0 %1,%0";
11033 [(set_attr "type" "store")
11034 (set (attr "update")
11035 (if_then_else (match_operand 0 "update_address_mem")
11036 (const_string "yes")
11037 (const_string "no")))
11038 (set (attr "indexed")
11039 (if_then_else (match_operand 0 "indexed_address_mem")
11040 (const_string "yes")
11041 (const_string "no")))
11042 (set_attr "length" "4")])
11044 (define_insn "probe_stack_range<P:mode>"
11045 [(set (match_operand:P 0 "register_operand" "=&r")
11046 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11047 (match_operand:P 2 "register_operand" "r")
11048 (match_operand:P 3 "register_operand" "r")]
11049 UNSPECV_PROBE_STACK_RANGE))]
11051 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11052 [(set_attr "type" "three")])
11054 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11055 ;; signed & unsigned, and one type of branch.
11057 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11058 ;; insns, and branches.
11060 (define_expand "cbranch<mode>4"
11061 [(use (match_operator 0 "comparison_operator"
11062 [(match_operand:GPR 1 "gpc_reg_operand")
11063 (match_operand:GPR 2 "reg_or_short_operand")]))
11064 (use (match_operand 3))]
11067 /* Take care of the possibility that operands[2] might be negative but
11068 this might be a logical operation. That insn doesn't exist. */
11069 if (GET_CODE (operands[2]) == CONST_INT
11070 && INTVAL (operands[2]) < 0)
11072 operands[2] = force_reg (<MODE>mode, operands[2]);
11073 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11074 GET_MODE (operands[0]),
11075 operands[1], operands[2]);
11078 rs6000_emit_cbranch (<MODE>mode, operands);
11082 (define_expand "cbranch<mode>4"
11083 [(use (match_operator 0 "comparison_operator"
11084 [(match_operand:FP 1 "gpc_reg_operand")
11085 (match_operand:FP 2 "gpc_reg_operand")]))
11086 (use (match_operand 3))]
11089 rs6000_emit_cbranch (<MODE>mode, operands);
11093 (define_expand "cstore<mode>4_signed"
11094 [(use (match_operator 1 "signed_comparison_operator"
11095 [(match_operand:P 2 "gpc_reg_operand")
11096 (match_operand:P 3 "gpc_reg_operand")]))
11097 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11100 enum rtx_code cond_code = GET_CODE (operands[1]);
11102 rtx op0 = operands[0];
11103 rtx op1 = operands[2];
11104 rtx op2 = operands[3];
11106 if (cond_code == GE || cond_code == LT)
11108 cond_code = swap_condition (cond_code);
11109 std::swap (op1, op2);
11112 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11113 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11114 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11116 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11117 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11118 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11120 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11122 if (cond_code == LE)
11123 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11126 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11127 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11128 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11134 (define_expand "cstore<mode>4_unsigned"
11135 [(use (match_operator 1 "unsigned_comparison_operator"
11136 [(match_operand:P 2 "gpc_reg_operand")
11137 (match_operand:P 3 "reg_or_short_operand")]))
11138 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11141 enum rtx_code cond_code = GET_CODE (operands[1]);
11143 rtx op0 = operands[0];
11144 rtx op1 = operands[2];
11145 rtx op2 = operands[3];
11147 if (cond_code == GEU || cond_code == LTU)
11149 cond_code = swap_condition (cond_code);
11150 std::swap (op1, op2);
11153 if (!gpc_reg_operand (op1, <MODE>mode))
11154 op1 = force_reg (<MODE>mode, op1);
11155 if (!reg_or_short_operand (op2, <MODE>mode))
11156 op2 = force_reg (<MODE>mode, op2);
11158 rtx tmp = gen_reg_rtx (<MODE>mode);
11159 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11161 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11162 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11164 if (cond_code == LEU)
11165 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11167 emit_insn (gen_neg<mode>2 (op0, tmp2));
11172 (define_expand "cstore_si_as_di"
11173 [(use (match_operator 1 "unsigned_comparison_operator"
11174 [(match_operand:SI 2 "gpc_reg_operand")
11175 (match_operand:SI 3 "reg_or_short_operand")]))
11176 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11179 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11180 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11182 operands[2] = force_reg (SImode, operands[2]);
11183 operands[3] = force_reg (SImode, operands[3]);
11184 rtx op1 = gen_reg_rtx (DImode);
11185 rtx op2 = gen_reg_rtx (DImode);
11186 convert_move (op1, operands[2], uns_flag);
11187 convert_move (op2, operands[3], uns_flag);
11189 if (cond_code == GT || cond_code == LE)
11191 cond_code = swap_condition (cond_code);
11192 std::swap (op1, op2);
11195 rtx tmp = gen_reg_rtx (DImode);
11196 rtx tmp2 = gen_reg_rtx (DImode);
11197 emit_insn (gen_subdi3 (tmp, op1, op2));
11198 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11204 gcc_unreachable ();
11209 tmp3 = gen_reg_rtx (DImode);
11210 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11214 convert_move (operands[0], tmp3, 1);
11219 (define_expand "cstore<mode>4_signed_imm"
11220 [(use (match_operator 1 "signed_comparison_operator"
11221 [(match_operand:GPR 2 "gpc_reg_operand")
11222 (match_operand:GPR 3 "immediate_operand")]))
11223 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11226 bool invert = false;
11228 enum rtx_code cond_code = GET_CODE (operands[1]);
11230 rtx op0 = operands[0];
11231 rtx op1 = operands[2];
11232 HOST_WIDE_INT val = INTVAL (operands[3]);
11234 if (cond_code == GE || cond_code == GT)
11236 cond_code = reverse_condition (cond_code);
11240 if (cond_code == LE)
11243 rtx tmp = gen_reg_rtx (<MODE>mode);
11244 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11245 rtx x = gen_reg_rtx (<MODE>mode);
11247 emit_insn (gen_and<mode>3 (x, op1, tmp));
11249 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11253 rtx tmp = gen_reg_rtx (<MODE>mode);
11254 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11258 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11259 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11264 (define_expand "cstore<mode>4_unsigned_imm"
11265 [(use (match_operator 1 "unsigned_comparison_operator"
11266 [(match_operand:GPR 2 "gpc_reg_operand")
11267 (match_operand:GPR 3 "immediate_operand")]))
11268 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11271 bool invert = false;
11273 enum rtx_code cond_code = GET_CODE (operands[1]);
11275 rtx op0 = operands[0];
11276 rtx op1 = operands[2];
11277 HOST_WIDE_INT val = INTVAL (operands[3]);
11279 if (cond_code == GEU || cond_code == GTU)
11281 cond_code = reverse_condition (cond_code);
11285 if (cond_code == LEU)
11288 rtx tmp = gen_reg_rtx (<MODE>mode);
11289 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11290 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11291 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11292 rtx x = gen_reg_rtx (<MODE>mode);
11294 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11296 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11300 rtx tmp = gen_reg_rtx (<MODE>mode);
11301 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11305 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11306 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11311 (define_expand "cstore<mode>4"
11312 [(use (match_operator 1 "comparison_operator"
11313 [(match_operand:GPR 2 "gpc_reg_operand")
11314 (match_operand:GPR 3 "reg_or_short_operand")]))
11315 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11318 /* Expanding EQ and NE directly to some machine instructions does not help
11319 but does hurt combine. So don't. */
11320 if (GET_CODE (operands[1]) == EQ)
11321 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11322 else if (<MODE>mode == Pmode
11323 && GET_CODE (operands[1]) == NE)
11324 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11325 else if (GET_CODE (operands[1]) == NE)
11327 rtx tmp = gen_reg_rtx (<MODE>mode);
11328 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11329 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11332 /* If ISEL is fast, expand to it. */
11333 else if (TARGET_ISEL)
11334 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11336 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11337 etc. combinations magically work out just right. */
11338 else if (<MODE>mode == Pmode
11339 && unsigned_comparison_operator (operands[1], VOIDmode))
11340 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11341 operands[2], operands[3]));
11343 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11344 else if (<MODE>mode == SImode && Pmode == DImode)
11345 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11346 operands[2], operands[3]));
11348 /* For signed comparisons against a constant, we can do some simple
11350 else if (signed_comparison_operator (operands[1], VOIDmode)
11351 && CONST_INT_P (operands[3]))
11352 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11353 operands[2], operands[3]));
11355 /* And similarly for unsigned comparisons. */
11356 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11357 && CONST_INT_P (operands[3]))
11358 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11359 operands[2], operands[3]));
11361 /* We also do not want to use mfcr for signed comparisons. */
11362 else if (<MODE>mode == Pmode
11363 && signed_comparison_operator (operands[1], VOIDmode))
11364 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11365 operands[2], operands[3]));
11367 /* Everything else, use the mfcr brute force. */
11369 rs6000_emit_sCOND (<MODE>mode, operands);
11374 (define_expand "cstore<mode>4"
11375 [(use (match_operator 1 "comparison_operator"
11376 [(match_operand:FP 2 "gpc_reg_operand")
11377 (match_operand:FP 3 "gpc_reg_operand")]))
11378 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11381 rs6000_emit_sCOND (<MODE>mode, operands);
11386 (define_expand "stack_protect_set"
11387 [(match_operand 0 "memory_operand")
11388 (match_operand 1 "memory_operand")]
11391 if (rs6000_stack_protector_guard == SSP_TLS)
11393 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11394 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11395 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11396 operands[1] = gen_rtx_MEM (Pmode, addr);
11400 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11402 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11407 (define_insn "stack_protect_setsi"
11408 [(set (match_operand:SI 0 "memory_operand" "=m")
11409 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11410 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11412 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11413 [(set_attr "type" "three")
11414 (set_attr "length" "12")])
11416 (define_insn "stack_protect_setdi"
11417 [(set (match_operand:DI 0 "memory_operand" "=Y")
11418 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11419 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11421 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11422 [(set_attr "type" "three")
11423 (set_attr "length" "12")])
11425 (define_expand "stack_protect_test"
11426 [(match_operand 0 "memory_operand")
11427 (match_operand 1 "memory_operand")
11428 (match_operand 2 "")]
11431 rtx guard = operands[1];
11433 if (rs6000_stack_protector_guard == SSP_TLS)
11435 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11436 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11437 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11438 guard = gen_rtx_MEM (Pmode, addr);
11441 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11442 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11443 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11444 emit_jump_insn (jump);
11449 (define_insn "stack_protect_testsi"
11450 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11451 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11452 (match_operand:SI 2 "memory_operand" "m,m")]
11454 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11455 (clobber (match_scratch:SI 3 "=&r,&r"))]
11458 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11459 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11460 [(set_attr "length" "16,20")])
11462 (define_insn "stack_protect_testdi"
11463 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11464 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11465 (match_operand:DI 2 "memory_operand" "Y,Y")]
11467 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11468 (clobber (match_scratch:DI 3 "=&r,&r"))]
11471 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11472 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11473 [(set_attr "length" "16,20")])
11476 ;; Here are the actual compare insns.
11477 (define_insn "*cmp<mode>_signed"
11478 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11479 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11480 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11482 "cmp<wd>%I2 %0,%1,%2"
11483 [(set_attr "type" "cmp")])
11485 (define_insn "*cmp<mode>_unsigned"
11486 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11487 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11488 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11490 "cmpl<wd>%I2 %0,%1,%2"
11491 [(set_attr "type" "cmp")])
11493 ;; If we are comparing a register for equality with a large constant,
11494 ;; we can do this with an XOR followed by a compare. But this is profitable
11495 ;; only if the large constant is only used for the comparison (and in this
11496 ;; case we already have a register to reuse as scratch).
11498 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11499 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11502 [(set (match_operand:SI 0 "register_operand")
11503 (match_operand:SI 1 "logical_const_operand"))
11504 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11506 (match_operand:SI 2 "logical_const_operand")]))
11507 (set (match_operand:CC 4 "cc_reg_operand")
11508 (compare:CC (match_operand:SI 5 "gpc_reg_operand")
11511 (if_then_else (match_operator 6 "equality_operator"
11512 [(match_dup 4) (const_int 0)])
11513 (match_operand 7 "")
11514 (match_operand 8 "")))]
11515 "peep2_reg_dead_p (3, operands[0])
11516 && peep2_reg_dead_p (4, operands[4])
11517 && REGNO (operands[0]) != REGNO (operands[5])"
11518 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
11519 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
11520 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
11523 /* Get the constant we are comparing against, and see what it looks like
11524 when sign-extended from 16 to 32 bits. Then see what constant we could
11525 XOR with SEXTC to get the sign-extended value. */
11526 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
11528 operands[1], operands[2]);
11529 HOST_WIDE_INT c = INTVAL (cnst);
11530 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
11531 HOST_WIDE_INT xorv = c ^ sextc;
11533 operands[9] = GEN_INT (xorv);
11534 operands[10] = GEN_INT (sextc);
11537 ;; The following two insns don't exist as single insns, but if we provide
11538 ;; them, we can swap an add and compare, which will enable us to overlap more
11539 ;; of the required delay between a compare and branch. We generate code for
11540 ;; them by splitting.
11543 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
11544 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
11545 (match_operand:SI 2 "short_cint_operand" "i")))
11546 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11547 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11550 [(set_attr "length" "8")])
11553 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
11554 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
11555 (match_operand:SI 2 "u_short_cint_operand" "i")))
11556 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
11557 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
11560 [(set_attr "length" "8")])
11563 [(set (match_operand:CC 3 "cc_reg_operand")
11564 (compare:CC (match_operand:SI 1 "gpc_reg_operand")
11565 (match_operand:SI 2 "short_cint_operand")))
11566 (set (match_operand:SI 0 "gpc_reg_operand")
11567 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11569 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
11570 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11573 [(set (match_operand:CCUNS 3 "cc_reg_operand")
11574 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand")
11575 (match_operand:SI 2 "u_short_cint_operand")))
11576 (set (match_operand:SI 0 "gpc_reg_operand")
11577 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand")))]
11579 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
11580 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
11582 ;; Only need to compare second words if first words equal
11583 (define_insn "*cmp<mode>_internal1"
11584 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11585 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11586 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
11587 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11588 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11589 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
11590 [(set_attr "type" "fpcompare")
11591 (set_attr "length" "12")])
11593 (define_insn_and_split "*cmp<mode>_internal2"
11594 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
11595 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
11596 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
11597 (clobber (match_scratch:DF 3 "=d"))
11598 (clobber (match_scratch:DF 4 "=d"))
11599 (clobber (match_scratch:DF 5 "=d"))
11600 (clobber (match_scratch:DF 6 "=d"))
11601 (clobber (match_scratch:DF 7 "=d"))
11602 (clobber (match_scratch:DF 8 "=d"))
11603 (clobber (match_scratch:DF 9 "=d"))
11604 (clobber (match_scratch:DF 10 "=d"))
11605 (clobber (match_scratch:GPR 11 "=b"))]
11606 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
11607 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
11609 "&& reload_completed"
11610 [(set (match_dup 3) (match_dup 14))
11611 (set (match_dup 4) (match_dup 15))
11612 (set (match_dup 9) (abs:DF (match_dup 5)))
11613 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
11614 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
11615 (label_ref (match_dup 12))
11617 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
11618 (set (pc) (label_ref (match_dup 13)))
11620 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
11621 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
11622 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
11623 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
11626 REAL_VALUE_TYPE rv;
11627 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
11628 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
11630 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
11631 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
11632 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
11633 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
11634 operands[12] = gen_label_rtx ();
11635 operands[13] = gen_label_rtx ();
11637 operands[14] = force_const_mem (DFmode,
11638 const_double_from_real_value (rv, DFmode));
11639 operands[15] = force_const_mem (DFmode,
11640 const_double_from_real_value (dconst0,
11645 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
11646 operands[14] = gen_const_mem (DFmode, tocref);
11647 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
11648 operands[15] = gen_const_mem (DFmode, tocref);
11649 set_mem_alias_set (operands[14], get_TOC_alias_set ());
11650 set_mem_alias_set (operands[15], get_TOC_alias_set ());
11654 ;; Now we have the scc insns. We can do some combinations because of the
11655 ;; way the machine works.
11657 ;; Note that this is probably faster if we can put an insn between the
11658 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
11659 ;; cases the insns below which don't use an intermediate CR field will
11660 ;; be used instead.
11662 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11663 (match_operator:SI 1 "scc_comparison_operator"
11664 [(match_operand 2 "cc_reg_operand" "y")
11667 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11668 [(set (attr "type")
11669 (cond [(match_test "TARGET_MFCRF")
11670 (const_string "mfcrf")
11672 (const_string "mfcr")))
11673 (set_attr "length" "8")])
11675 ;; Same as above, but get the OV/ORDERED bit.
11676 (define_insn "move_from_CR_ov_bit"
11677 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11678 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
11680 "TARGET_PAIRED_FLOAT"
11681 "mfcr %0\;rlwinm %0,%0,%t1,1"
11682 [(set_attr "type" "mfcr")
11683 (set_attr "length" "8")])
11686 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
11687 (match_operator:DI 1 "scc_comparison_operator"
11688 [(match_operand 2 "cc_reg_operand" "y")
11691 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
11692 [(set (attr "type")
11693 (cond [(match_test "TARGET_MFCRF")
11694 (const_string "mfcrf")
11696 (const_string "mfcr")))
11697 (set_attr "length" "8")])
11700 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11701 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11702 [(match_operand 2 "cc_reg_operand" "y,y")
11705 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
11706 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11709 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
11711 [(set_attr "type" "shift")
11712 (set_attr "dot" "yes")
11713 (set_attr "length" "8,16")])
11716 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11717 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
11718 [(match_operand 2 "cc_reg_operand")
11721 (set (match_operand:SI 3 "gpc_reg_operand")
11722 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
11723 "TARGET_32BIT && reload_completed"
11724 [(set (match_dup 3)
11725 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
11727 (compare:CC (match_dup 3)
11732 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
11733 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11734 [(match_operand 2 "cc_reg_operand" "y")
11736 (match_operand:SI 3 "const_int_operand" "n")))]
11739 int is_bit = ccr_bit (operands[1], 1);
11740 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11743 if (is_bit >= put_bit)
11744 count = is_bit - put_bit;
11746 count = 32 - (put_bit - is_bit);
11748 operands[4] = GEN_INT (count);
11749 operands[5] = GEN_INT (put_bit);
11751 return "mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5";
11753 [(set (attr "type")
11754 (cond [(match_test "TARGET_MFCRF")
11755 (const_string "mfcrf")
11757 (const_string "mfcr")))
11758 (set_attr "length" "8")])
11761 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
11763 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11764 [(match_operand 2 "cc_reg_operand" "y,y")
11766 (match_operand:SI 3 "const_int_operand" "n,n"))
11768 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
11769 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11773 int is_bit = ccr_bit (operands[1], 1);
11774 int put_bit = 31 - (INTVAL (operands[3]) & 31);
11777 /* Force split for non-cc0 compare. */
11778 if (which_alternative == 1)
11781 if (is_bit >= put_bit)
11782 count = is_bit - put_bit;
11784 count = 32 - (put_bit - is_bit);
11786 operands[5] = GEN_INT (count);
11787 operands[6] = GEN_INT (put_bit);
11789 return "mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6";
11791 [(set_attr "type" "shift")
11792 (set_attr "dot" "yes")
11793 (set_attr "length" "8,16")])
11796 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
11798 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
11799 [(match_operand 2 "cc_reg_operand")
11801 (match_operand:SI 3 "const_int_operand"))
11803 (set (match_operand:SI 4 "gpc_reg_operand")
11804 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11807 [(set (match_dup 4)
11808 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
11811 (compare:CC (match_dup 4)
11816 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
11817 (define_code_attr UNS [(eq "CC")
11819 (lt "CC") (ltu "CCUNS")
11820 (gt "CC") (gtu "CCUNS")
11821 (le "CC") (leu "CCUNS")
11822 (ge "CC") (geu "CCUNS")])
11823 (define_code_attr UNSu_ [(eq "")
11828 (ge "") (geu "u_")])
11829 (define_code_attr UNSIK [(eq "I")
11834 (ge "I") (geu "K")])
11836 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
11837 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11838 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
11839 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
11840 (clobber (match_scratch:GPR 3 "=r"))
11841 (clobber (match_scratch:GPR 4 "=r"))
11842 (clobber (match_scratch:<UNS> 5 "=y"))]
11844 && !(<CODE> == EQ && operands[2] == const0_rtx)
11845 && !(<CODE> == NE && operands[2] == const0_rtx
11846 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
11851 rtx_code code = <CODE>;
11852 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
11854 HOST_WIDE_INT val = INTVAL (operands[2]);
11855 if (code == LT && val != -0x8000)
11860 if (code == GT && val != 0x7fff)
11865 if (code == LTU && val != 0)
11870 if (code == GTU && val != 0xffff)
11875 operands[2] = GEN_INT (val);
11878 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
11879 operands[3] = const0_rtx;
11882 if (GET_CODE (operands[3]) == SCRATCH)
11883 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
11884 emit_move_insn (operands[3], const0_rtx);
11887 if (GET_CODE (operands[4]) == SCRATCH)
11888 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
11889 emit_move_insn (operands[4], const1_rtx);
11891 if (GET_CODE (operands[5]) == SCRATCH)
11892 operands[5] = gen_reg_rtx (<UNS>mode);
11894 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
11895 emit_insn (gen_rtx_SET (operands[5], c1));
11897 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
11898 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
11899 emit_move_insn (operands[0], x);
11903 [(set (attr "cost")
11904 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
11906 || <CODE> == LE || <CODE> == GE
11907 || <CODE> == LEU || <CODE> == GEU")
11909 (const_string "10")))])
11911 (define_mode_attr scc_eq_op2 [(SI "rKLI")
11914 (define_expand "eq<mode>3"
11916 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11917 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11918 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11919 (clobber (match_scratch:GPR 3 "=r"))
11920 (clobber (match_scratch:GPR 4 "=r"))])]
11923 if (TARGET_ISEL && operands[2] != const0_rtx)
11925 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
11931 (define_insn_and_split "*eq<mode>3"
11932 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
11933 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
11934 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
11935 (clobber (match_scratch:GPR 3 "=r"))
11936 (clobber (match_scratch:GPR 4 "=r"))]
11937 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11940 [(set (match_dup 4)
11941 (clz:GPR (match_dup 3)))
11943 (lshiftrt:GPR (match_dup 4)
11946 operands[3] = rs6000_emit_eqne (<MODE>mode,
11947 operands[1], operands[2], operands[3]);
11949 if (GET_CODE (operands[4]) == SCRATCH)
11950 operands[4] = gen_reg_rtx (<MODE>mode);
11952 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
11954 [(set (attr "length")
11955 (if_then_else (match_test "operands[2] == const0_rtx")
11957 (const_string "12")))])
11959 (define_expand "ne<mode>3"
11961 (set (match_operand:P 0 "gpc_reg_operand" "=r")
11962 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11963 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11964 (clobber (match_scratch:P 3 "=r"))
11965 (clobber (match_scratch:P 4 "=r"))
11966 (clobber (reg:P CA_REGNO))])]
11969 if (TARGET_ISEL && operands[2] != const0_rtx)
11971 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
11977 (define_insn_and_split "*ne<mode>3"
11978 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
11979 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
11980 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
11981 (clobber (match_scratch:P 3 "=r"))
11982 (clobber (match_scratch:P 4 "=r"))
11983 (clobber (reg:P CA_REGNO))]
11984 "!(TARGET_ISEL && operands[2] != const0_rtx)"
11987 [(parallel [(set (match_dup 4)
11988 (plus:P (match_dup 3)
11990 (set (reg:P CA_REGNO)
11991 (ne:P (match_dup 3)
11993 (parallel [(set (match_dup 0)
11994 (plus:P (plus:P (not:P (match_dup 4))
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 "*neg_eq_<mode>"
12011 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12012 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12013 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12014 (clobber (match_scratch:P 3 "=r"))
12015 (clobber (match_scratch:P 4 "=r"))
12016 (clobber (reg:P CA_REGNO))]
12020 [(parallel [(set (match_dup 4)
12021 (plus:P (match_dup 3)
12023 (set (reg:P CA_REGNO)
12024 (ne:P (match_dup 3)
12026 (parallel [(set (match_dup 0)
12027 (plus:P (reg:P CA_REGNO)
12029 (clobber (reg:P CA_REGNO))])]
12031 operands[3] = rs6000_emit_eqne (<MODE>mode,
12032 operands[1], operands[2], operands[3]);
12034 if (GET_CODE (operands[4]) == SCRATCH)
12035 operands[4] = 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 "*neg_ne_<mode>"
12043 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12044 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12045 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12046 (clobber (match_scratch:P 3 "=r"))
12047 (clobber (match_scratch:P 4 "=r"))
12048 (clobber (reg:P CA_REGNO))]
12052 [(parallel [(set (match_dup 4)
12053 (neg:P (match_dup 3)))
12054 (set (reg:P CA_REGNO)
12055 (eq:P (match_dup 3)
12057 (parallel [(set (match_dup 0)
12058 (plus:P (reg:P CA_REGNO)
12060 (clobber (reg:P CA_REGNO))])]
12062 operands[3] = rs6000_emit_eqne (<MODE>mode,
12063 operands[1], operands[2], operands[3]);
12065 if (GET_CODE (operands[4]) == SCRATCH)
12066 operands[4] = gen_reg_rtx (<MODE>mode);
12068 [(set (attr "length")
12069 (if_then_else (match_test "operands[2] == const0_rtx")
12071 (const_string "12")))])
12073 (define_insn_and_split "*plus_eq_<mode>"
12074 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12075 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12076 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12077 (match_operand:P 3 "gpc_reg_operand" "r")))
12078 (clobber (match_scratch:P 4 "=r"))
12079 (clobber (match_scratch:P 5 "=r"))
12080 (clobber (reg:P CA_REGNO))]
12084 [(parallel [(set (match_dup 5)
12085 (neg:P (match_dup 4)))
12086 (set (reg:P CA_REGNO)
12087 (eq:P (match_dup 4)
12089 (parallel [(set (match_dup 0)
12090 (plus:P (match_dup 3)
12092 (clobber (reg:P CA_REGNO))])]
12094 operands[4] = rs6000_emit_eqne (<MODE>mode,
12095 operands[1], operands[2], operands[4]);
12097 if (GET_CODE (operands[5]) == SCRATCH)
12098 operands[5] = gen_reg_rtx (<MODE>mode);
12100 [(set (attr "length")
12101 (if_then_else (match_test "operands[2] == const0_rtx")
12103 (const_string "12")))])
12105 (define_insn_and_split "*plus_ne_<mode>"
12106 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12107 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12108 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12109 (match_operand:P 3 "gpc_reg_operand" "r")))
12110 (clobber (match_scratch:P 4 "=r"))
12111 (clobber (match_scratch:P 5 "=r"))
12112 (clobber (reg:P CA_REGNO))]
12116 [(parallel [(set (match_dup 5)
12117 (plus:P (match_dup 4)
12119 (set (reg:P CA_REGNO)
12120 (ne:P (match_dup 4)
12122 (parallel [(set (match_dup 0)
12123 (plus:P (match_dup 3)
12125 (clobber (reg:P CA_REGNO))])]
12127 operands[4] = rs6000_emit_eqne (<MODE>mode,
12128 operands[1], operands[2], operands[4]);
12130 if (GET_CODE (operands[5]) == SCRATCH)
12131 operands[5] = gen_reg_rtx (<MODE>mode);
12133 [(set (attr "length")
12134 (if_then_else (match_test "operands[2] == const0_rtx")
12136 (const_string "12")))])
12138 (define_insn_and_split "*minus_eq_<mode>"
12139 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12140 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12141 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12142 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12143 (clobber (match_scratch:P 4 "=r"))
12144 (clobber (match_scratch:P 5 "=r"))
12145 (clobber (reg:P CA_REGNO))]
12149 [(parallel [(set (match_dup 5)
12150 (plus:P (match_dup 4)
12152 (set (reg:P CA_REGNO)
12153 (ne:P (match_dup 4)
12155 (parallel [(set (match_dup 0)
12156 (plus:P (plus:P (match_dup 3)
12159 (clobber (reg:P CA_REGNO))])]
12161 operands[4] = rs6000_emit_eqne (<MODE>mode,
12162 operands[1], operands[2], operands[4]);
12164 if (GET_CODE (operands[5]) == SCRATCH)
12165 operands[5] = gen_reg_rtx (<MODE>mode);
12167 [(set (attr "length")
12168 (if_then_else (match_test "operands[2] == const0_rtx")
12170 (const_string "12")))])
12172 (define_insn_and_split "*minus_ne_<mode>"
12173 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12174 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12175 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12176 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12177 (clobber (match_scratch:P 4 "=r"))
12178 (clobber (match_scratch:P 5 "=r"))
12179 (clobber (reg:P CA_REGNO))]
12183 [(parallel [(set (match_dup 5)
12184 (neg:P (match_dup 4)))
12185 (set (reg:P CA_REGNO)
12186 (eq:P (match_dup 4)
12188 (parallel [(set (match_dup 0)
12189 (plus:P (plus:P (match_dup 3)
12192 (clobber (reg:P CA_REGNO))])]
12194 operands[4] = rs6000_emit_eqne (<MODE>mode,
12195 operands[1], operands[2], operands[4]);
12197 if (GET_CODE (operands[5]) == SCRATCH)
12198 operands[5] = gen_reg_rtx (<MODE>mode);
12200 [(set (attr "length")
12201 (if_then_else (match_test "operands[2] == const0_rtx")
12203 (const_string "12")))])
12205 (define_insn_and_split "*eqsi3_ext<mode>"
12206 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12207 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12208 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12209 (clobber (match_scratch:SI 3 "=r"))
12210 (clobber (match_scratch:SI 4 "=r"))]
12214 [(set (match_dup 4)
12215 (clz:SI (match_dup 3)))
12218 (lshiftrt:SI (match_dup 4)
12221 operands[3] = rs6000_emit_eqne (SImode,
12222 operands[1], operands[2], operands[3]);
12224 if (GET_CODE (operands[4]) == SCRATCH)
12225 operands[4] = gen_reg_rtx (SImode);
12227 [(set (attr "length")
12228 (if_then_else (match_test "operands[2] == const0_rtx")
12230 (const_string "12")))])
12232 (define_insn_and_split "*nesi3_ext<mode>"
12233 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12234 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12235 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12236 (clobber (match_scratch:SI 3 "=r"))
12237 (clobber (match_scratch:SI 4 "=r"))
12238 (clobber (match_scratch:EXTSI 5 "=r"))]
12242 [(set (match_dup 4)
12243 (clz:SI (match_dup 3)))
12246 (lshiftrt:SI (match_dup 4)
12249 (xor:EXTSI (match_dup 5)
12252 operands[3] = rs6000_emit_eqne (SImode,
12253 operands[1], operands[2], operands[3]);
12255 if (GET_CODE (operands[4]) == SCRATCH)
12256 operands[4] = gen_reg_rtx (SImode);
12257 if (GET_CODE (operands[5]) == SCRATCH)
12258 operands[5] = gen_reg_rtx (<MODE>mode);
12260 [(set (attr "length")
12261 (if_then_else (match_test "operands[2] == const0_rtx")
12262 (const_string "12")
12263 (const_string "16")))])
12265 ;; Define both directions of branch and return. If we need a reload
12266 ;; register, we'd rather use CR0 since it is much easier to copy a
12267 ;; register CC value to there.
12271 (if_then_else (match_operator 1 "branch_comparison_operator"
12272 [(match_operand 2 "cc_reg_operand" "y")
12274 (label_ref (match_operand 0))
12278 return output_cbranch (operands[1], "%l0", 0, insn);
12280 [(set_attr "type" "branch")])
12284 (if_then_else (match_operator 0 "branch_comparison_operator"
12285 [(match_operand 1 "cc_reg_operand" "y")
12291 return output_cbranch (operands[0], NULL, 0, insn);
12293 [(set_attr "type" "jmpreg")
12294 (set_attr "length" "4")])
12296 ;; Logic on condition register values.
12298 ; This pattern matches things like
12299 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12300 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12302 ; which are generated by the branch logic.
12303 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12305 (define_insn "cceq_ior_compare"
12306 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12307 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12308 [(match_operator:SI 2
12309 "branch_positive_comparison_operator"
12311 "cc_reg_operand" "y,y")
12313 (match_operator:SI 4
12314 "branch_positive_comparison_operator"
12316 "cc_reg_operand" "0,y")
12320 "cr%q1 %E0,%j2,%j4"
12321 [(set_attr "type" "cr_logical")
12322 (set_attr "cr_logical_3op" "no,yes")])
12324 ; Why is the constant -1 here, but 1 in the previous pattern?
12325 ; Because ~1 has all but the low bit set.
12326 (define_insn "cceq_ior_compare_complement"
12327 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12328 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12329 [(not:SI (match_operator:SI 2
12330 "branch_positive_comparison_operator"
12332 "cc_reg_operand" "y,y")
12334 (match_operator:SI 4
12335 "branch_positive_comparison_operator"
12337 "cc_reg_operand" "0,y")
12341 "cr%q1 %E0,%j2,%j4"
12342 [(set_attr "type" "cr_logical")
12343 (set_attr "cr_logical_3op" "no,yes")])
12345 (define_insn "*cceq_rev_compare"
12346 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12347 (compare:CCEQ (match_operator:SI 1
12348 "branch_positive_comparison_operator"
12350 "cc_reg_operand" "0,y")
12355 [(set_attr "type" "cr_logical")
12356 (set_attr "cr_logical_3op" "no,yes")])
12358 ;; If we are comparing the result of two comparisons, this can be done
12359 ;; using creqv or crxor.
12361 (define_insn_and_split ""
12362 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12363 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12364 [(match_operand 2 "cc_reg_operand" "y")
12366 (match_operator 3 "branch_comparison_operator"
12367 [(match_operand 4 "cc_reg_operand" "y")
12372 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12375 int positive_1, positive_2;
12377 positive_1 = branch_positive_comparison_operator (operands[1],
12378 GET_MODE (operands[1]));
12379 positive_2 = branch_positive_comparison_operator (operands[3],
12380 GET_MODE (operands[3]));
12383 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12384 GET_CODE (operands[1])),
12386 operands[2], const0_rtx);
12387 else if (GET_MODE (operands[1]) != SImode)
12388 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12389 operands[2], const0_rtx);
12392 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12393 GET_CODE (operands[3])),
12395 operands[4], const0_rtx);
12396 else if (GET_MODE (operands[3]) != SImode)
12397 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12398 operands[4], const0_rtx);
12400 if (positive_1 == positive_2)
12402 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12403 operands[5] = constm1_rtx;
12407 operands[5] = const1_rtx;
12411 ;; Unconditional branch and return.
12413 (define_insn "jump"
12415 (label_ref (match_operand 0)))]
12418 [(set_attr "type" "branch")])
12420 (define_insn "<return_str>return"
12424 [(set_attr "type" "jmpreg")])
12426 (define_expand "indirect_jump"
12427 [(set (pc) (match_operand 0 "register_operand"))]
12430 if (!rs6000_speculate_indirect_jumps) {
12431 rtx ccreg = gen_reg_rtx (CCmode);
12432 if (Pmode == DImode)
12433 emit_jump_insn (gen_indirect_jumpdi_nospec (operands[0], ccreg));
12435 emit_jump_insn (gen_indirect_jumpsi_nospec (operands[0], ccreg));
12440 (define_insn "*indirect_jump<mode>"
12442 (match_operand:P 0 "register_operand" "c,*l"))]
12443 "rs6000_speculate_indirect_jumps"
12445 [(set_attr "type" "jmpreg")])
12447 (define_insn "indirect_jump<mode>_nospec"
12448 [(set (pc) (match_operand:P 0 "register_operand" "c,*l"))
12449 (clobber (match_operand:CC 1 "cc_reg_operand" "=y,y"))]
12450 "!rs6000_speculate_indirect_jumps"
12451 "crset %E1\;beq%T0- %1\;b $"
12452 [(set_attr "type" "jmpreg")
12453 (set_attr "length" "12")])
12455 ;; Table jump for switch statements:
12456 (define_expand "tablejump"
12457 [(use (match_operand 0))
12458 (use (label_ref (match_operand 1)))]
12461 if (rs6000_speculate_indirect_jumps)
12464 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12466 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12470 rtx ccreg = gen_reg_rtx (CCmode);
12473 jump = gen_tablejumpsi_nospec (operands[0], operands[1], ccreg);
12475 jump = gen_tablejumpdi_nospec (operands[0], operands[1], ccreg);
12476 emit_jump_insn (jump);
12481 (define_expand "tablejumpsi"
12482 [(set (match_dup 3)
12483 (plus:SI (match_operand:SI 0)
12485 (parallel [(set (pc)
12487 (use (label_ref (match_operand 1)))])]
12488 "TARGET_32BIT && rs6000_speculate_indirect_jumps"
12490 operands[0] = force_reg (SImode, operands[0]);
12491 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12492 operands[3] = gen_reg_rtx (SImode);
12495 (define_expand "tablejumpsi_nospec"
12496 [(set (match_dup 4)
12497 (plus:SI (match_operand:SI 0)
12499 (parallel [(set (pc)
12501 (use (label_ref (match_operand 1)))
12502 (clobber (match_operand 2))])]
12503 "TARGET_32BIT && !rs6000_speculate_indirect_jumps"
12505 operands[0] = force_reg (SImode, operands[0]);
12506 operands[3] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12507 operands[4] = gen_reg_rtx (SImode);
12510 (define_expand "tablejumpdi"
12511 [(set (match_dup 4)
12512 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12514 (plus:DI (match_dup 4)
12516 (parallel [(set (pc)
12518 (use (label_ref (match_operand 1)))])]
12519 "TARGET_64BIT && rs6000_speculate_indirect_jumps"
12521 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12522 operands[3] = gen_reg_rtx (DImode);
12523 operands[4] = gen_reg_rtx (DImode);
12526 (define_expand "tablejumpdi_nospec"
12527 [(set (match_dup 5)
12528 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12530 (plus:DI (match_dup 5)
12532 (parallel [(set (pc)
12534 (use (label_ref (match_operand 1)))
12535 (clobber (match_operand 2))])]
12536 "TARGET_64BIT && !rs6000_speculate_indirect_jumps"
12538 operands[3] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12539 operands[4] = gen_reg_rtx (DImode);
12540 operands[5] = gen_reg_rtx (DImode);
12543 (define_insn "*tablejump<mode>_internal1"
12545 (match_operand:P 0 "register_operand" "c,*l"))
12546 (use (label_ref (match_operand 1)))]
12547 "rs6000_speculate_indirect_jumps"
12549 [(set_attr "type" "jmpreg")])
12551 (define_insn "*tablejump<mode>_internal1_nospec"
12553 (match_operand:P 0 "register_operand" "c,*l"))
12554 (use (label_ref (match_operand 1)))
12555 (clobber (match_operand:CC 2 "cc_reg_operand" "=y,y"))]
12556 "!rs6000_speculate_indirect_jumps"
12557 "crset %E2\;beq%T0- %2\;b $"
12558 [(set_attr "type" "jmpreg")
12559 (set_attr "length" "12")])
12562 [(unspec [(const_int 0)] UNSPEC_NOP)]
12566 (define_insn "group_ending_nop"
12567 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12570 if (rs6000_tune == PROCESSOR_POWER6)
12571 return "ori 1,1,0";
12572 return "ori 2,2,0";
12575 (define_insn "rs6000_speculation_barrier"
12576 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_SPEC_BARRIER)]
12580 ;; Define the subtract-one-and-jump insns, starting with the template
12581 ;; so loop.c knows what to generate.
12583 (define_expand "doloop_end"
12584 [(use (match_operand 0)) ; loop pseudo
12585 (use (match_operand 1))] ; label
12590 if (GET_MODE (operands[0]) != DImode)
12592 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
12596 if (GET_MODE (operands[0]) != SImode)
12598 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
12603 (define_expand "ctr<mode>"
12604 [(parallel [(set (pc)
12605 (if_then_else (ne (match_operand:P 0 "register_operand")
12607 (label_ref (match_operand 1))
12610 (plus:P (match_dup 0)
12612 (clobber (match_scratch:CC 2))
12613 (clobber (match_scratch:P 3))])]
12617 ;; We need to be able to do this for any operand, including MEM, or we
12618 ;; will cause reload to blow up since we don't allow output reloads on
12620 ;; For the length attribute to be calculated correctly, the
12621 ;; label MUST be operand 0.
12622 ;; rs6000_legitimate_combined_insn prevents combine creating any of
12623 ;; the ctr<mode> insns.
12625 (define_code_iterator eqne [eq ne])
12626 (define_code_attr bd [(eq "bdz") (ne "bdnz")])
12627 (define_code_attr bd_neg [(eq "bdnz") (ne "bdz")])
12629 (define_insn "<bd>_<mode>"
12631 (if_then_else (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12633 (label_ref (match_operand 0))
12635 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12636 (plus:P (match_dup 1)
12638 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
12639 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
12642 if (which_alternative != 0)
12644 else if (get_attr_length (insn) == 4)
12647 return "<bd_neg> $+8\;b %l0";
12649 [(set_attr "type" "branch")
12650 (set_attr "length" "*,16,20,20")])
12652 ;; Now the splitter if we could not allocate the CTR register
12655 (if_then_else (match_operator 2 "comparison_operator"
12656 [(match_operand:P 1 "gpc_reg_operand")
12659 (match_operand 6)))
12660 (set (match_operand:P 0 "nonimmediate_operand")
12661 (plus:P (match_dup 1)
12663 (clobber (match_scratch:CC 3))
12664 (clobber (match_scratch:P 4))]
12667 (if_then_else (match_dup 7)
12671 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
12673 emit_insn (gen_rtx_SET (operands[3],
12674 gen_rtx_COMPARE (CCmode, operands[1], const1_rtx)));
12675 if (gpc_reg_operand (operands[0], <MODE>mode))
12676 emit_insn (gen_add<mode>3 (operands[0], operands[1], constm1_rtx));
12679 emit_insn (gen_add<mode>3 (operands[4], operands[1], constm1_rtx));
12680 emit_move_insn (operands[0], operands[4]);
12682 /* No DONE so branch comes from the pattern. */
12685 ;; patterns for bdnzt/bdnzf/bdzt/bdzf
12686 ;; Note that in the case of long branches we have to decompose this into
12687 ;; bdnz+bc. This is because bdnzt has an implied AND between the ctr condition
12688 ;; and the CR bit, which means there is no way to conveniently invert the
12689 ;; comparison as is done with plain bdnz/bdz.
12691 (define_insn "<bd>tf_<mode>"
12695 (eqne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
12697 (match_operator 3 "branch_comparison_operator"
12698 [(match_operand 4 "cc_reg_operand" "y,y,y,y")
12700 (label_ref (match_operand 0))
12702 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
12703 (plus:P (match_dup 1)
12705 (clobber (match_scratch:P 5 "=X,X,&r,r"))
12706 (clobber (match_scratch:CC 6 "=X,&y,&y,&y"))
12707 (clobber (match_scratch:CCEQ 7 "=X,&y,&y,&y"))]
12710 if (which_alternative != 0)
12712 else if (get_attr_length (insn) == 4)
12714 if (branch_positive_comparison_operator (operands[3],
12715 GET_MODE (operands[3])))
12716 return "<bd>t %j3,%l0";
12718 return "<bd>f %j3,%l0";
12722 static char seq[96];
12723 char *bcs = output_cbranch (operands[3], "$+8", 1, insn);
12724 sprintf(seq, "<bd_neg> $+12\;%s;b %%l0", bcs);
12728 [(set_attr "type" "branch")
12729 (set_attr "length" "*,16,20,20")])
12731 ;; Now the splitter if we could not allocate the CTR register
12736 (match_operator 1 "comparison_operator"
12737 [(match_operand:P 0 "gpc_reg_operand")
12739 (match_operator 3 "branch_comparison_operator"
12740 [(match_operand 2 "cc_reg_operand")
12743 (match_operand 5)))
12744 (set (match_operand:P 6 "int_reg_operand")
12745 (plus:P (match_dup 0)
12747 (clobber (match_scratch:P 7))
12748 (clobber (match_scratch:CC 8))
12749 (clobber (match_scratch:CCEQ 9))]
12753 rtx ctr = operands[0];
12754 rtx ctrcmp = operands[1];
12755 rtx ccin = operands[2];
12756 rtx cccmp = operands[3];
12757 rtx dst1 = operands[4];
12758 rtx dst2 = operands[5];
12759 rtx ctrout = operands[6];
12760 rtx ctrtmp = operands[7];
12761 enum rtx_code cmpcode = GET_CODE (ctrcmp);
12762 bool ispos = branch_positive_comparison_operator (ctrcmp, GET_MODE (ctrcmp));
12764 cmpcode = reverse_condition (cmpcode);
12765 /* Generate crand/crandc here. */
12766 emit_insn (gen_rtx_SET (operands[8],
12767 gen_rtx_COMPARE (CCmode, ctr, const1_rtx)));
12768 rtx ctrcmpcc = gen_rtx_fmt_ee (cmpcode, SImode, operands[8], const0_rtx);
12770 rtx andexpr = gen_rtx_AND (SImode, ctrcmpcc, cccmp);
12772 emit_insn (gen_cceq_ior_compare (operands[9], andexpr, ctrcmpcc,
12773 operands[8], cccmp, ccin));
12775 emit_insn (gen_cceq_ior_compare_complement (operands[9], andexpr, ctrcmpcc,
12776 operands[8], cccmp, ccin));
12777 if (gpc_reg_operand (operands[0], <MODE>mode))
12778 emit_insn (gen_add<mode>3 (ctrout, ctr, constm1_rtx));
12781 emit_insn (gen_add<mode>3 (ctrtmp, ctr, constm1_rtx));
12782 emit_move_insn (ctrout, ctrtmp);
12784 rtx cmp = gen_rtx_EQ (CCEQmode, operands[9], const0_rtx);
12785 emit_jump_insn (gen_rtx_SET (pc_rtx,
12786 gen_rtx_IF_THEN_ELSE (VOIDmode, cmp,
12792 (define_insn "trap"
12793 [(trap_if (const_int 1) (const_int 0))]
12796 [(set_attr "type" "trap")])
12798 (define_expand "ctrap<mode>4"
12799 [(trap_if (match_operator 0 "ordered_comparison_operator"
12800 [(match_operand:GPR 1 "register_operand")
12801 (match_operand:GPR 2 "reg_or_short_operand")])
12802 (match_operand 3 "zero_constant" ""))]
12807 [(trap_if (match_operator 0 "ordered_comparison_operator"
12808 [(match_operand:GPR 1 "register_operand" "r")
12809 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
12812 "t<wd>%V0%I2 %1,%2"
12813 [(set_attr "type" "trap")])
12815 ;; Insns related to generating the function prologue and epilogue.
12817 (define_expand "prologue"
12818 [(use (const_int 0))]
12821 rs6000_emit_prologue ();
12822 if (!TARGET_SCHED_PROLOG)
12823 emit_insn (gen_blockage ());
12827 (define_insn "*movesi_from_cr_one"
12828 [(match_parallel 0 "mfcr_operation"
12829 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
12830 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
12831 (match_operand 3 "immediate_operand" "n")]
12832 UNSPEC_MOVESI_FROM_CR))])]
12837 for (i = 0; i < XVECLEN (operands[0], 0); i++)
12839 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
12840 operands[4] = GEN_INT (mask);
12841 output_asm_insn ("mfcr %1,%4", operands);
12845 [(set_attr "type" "mfcrf")])
12847 ;; Don't include the volatile CRs since their values are not used wrt CR save
12848 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
12849 ;; prologue past an insn (early exit test) that defines a register used in the
12851 (define_insn "prologue_movesi_from_cr"
12852 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12853 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
12854 (reg:CC CR4_REGNO)]
12855 UNSPEC_MOVESI_FROM_CR))]
12858 [(set_attr "type" "mfcr")])
12860 (define_insn "*crsave"
12861 [(match_parallel 0 "crsave_operation"
12862 [(set (match_operand:SI 1 "memory_operand" "=m")
12863 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12866 [(set_attr "type" "store")])
12868 (define_insn "*stmw"
12869 [(match_parallel 0 "stmw_operation"
12870 [(set (match_operand:SI 1 "memory_operand" "=m")
12871 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
12874 [(set_attr "type" "store")
12875 (set_attr "update" "yes")
12876 (set_attr "indexed" "yes")])
12878 ; The following comment applies to:
12882 ; return_and_restore_gpregs*
12883 ; return_and_restore_fpregs*
12884 ; return_and_restore_fpregs_aix*
12886 ; The out-of-line save / restore functions expects one input argument.
12887 ; Since those are not standard call_insn's, we must avoid using
12888 ; MATCH_OPERAND for that argument. That way the register rename
12889 ; optimization will not try to rename this register.
12890 ; Each pattern is repeated for each possible register number used in
12891 ; various ABIs (r11, r1, and for some functions r12)
12893 (define_insn "*save_gpregs_<mode>_r11"
12894 [(match_parallel 0 "any_parallel_operand"
12895 [(clobber (reg:P LR_REGNO))
12896 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12898 (set (match_operand:P 2 "memory_operand" "=m")
12899 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12902 [(set_attr "type" "branch")
12903 (set_attr "length" "4")])
12905 (define_insn "*save_gpregs_<mode>_r12"
12906 [(match_parallel 0 "any_parallel_operand"
12907 [(clobber (reg:P LR_REGNO))
12908 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12910 (set (match_operand:P 2 "memory_operand" "=m")
12911 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12914 [(set_attr "type" "branch")
12915 (set_attr "length" "4")])
12917 (define_insn "*save_gpregs_<mode>_r1"
12918 [(match_parallel 0 "any_parallel_operand"
12919 [(clobber (reg:P LR_REGNO))
12920 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12922 (set (match_operand:P 2 "memory_operand" "=m")
12923 (match_operand:P 3 "gpc_reg_operand" "r"))])]
12926 [(set_attr "type" "branch")
12927 (set_attr "length" "4")])
12929 (define_insn "*save_fpregs_<mode>_r11"
12930 [(match_parallel 0 "any_parallel_operand"
12931 [(clobber (reg:P LR_REGNO))
12932 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12934 (set (match_operand:DF 2 "memory_operand" "=m")
12935 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12938 [(set_attr "type" "branch")
12939 (set_attr "length" "4")])
12941 (define_insn "*save_fpregs_<mode>_r12"
12942 [(match_parallel 0 "any_parallel_operand"
12943 [(clobber (reg:P LR_REGNO))
12944 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12946 (set (match_operand:DF 2 "memory_operand" "=m")
12947 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12950 [(set_attr "type" "branch")
12951 (set_attr "length" "4")])
12953 (define_insn "*save_fpregs_<mode>_r1"
12954 [(match_parallel 0 "any_parallel_operand"
12955 [(clobber (reg:P LR_REGNO))
12956 (use (match_operand:P 1 "symbol_ref_operand" "s"))
12958 (set (match_operand:DF 2 "memory_operand" "=m")
12959 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
12962 [(set_attr "type" "branch")
12963 (set_attr "length" "4")])
12965 ; This is to explain that changes to the stack pointer should
12966 ; not be moved over loads from or stores to stack memory.
12967 (define_insn "stack_tie"
12968 [(match_parallel 0 "tie_operand"
12969 [(set (mem:BLK (reg 1)) (const_int 0))])]
12972 [(set_attr "length" "0")])
12974 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
12975 ; stay behind all restores from the stack, it cannot be reordered to before
12976 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
12977 (define_insn "stack_restore_tie"
12978 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
12979 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
12980 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
12981 (set (mem:BLK (scratch)) (const_int 0))]
12986 [(set_attr "type" "*,add")])
12988 (define_expand "epilogue"
12989 [(use (const_int 0))]
12992 if (!TARGET_SCHED_PROLOG)
12993 emit_insn (gen_blockage ());
12994 rs6000_emit_epilogue (FALSE);
12998 ; On some processors, doing the mtcrf one CC register at a time is
12999 ; faster (like on the 604e). On others, doing them all at once is
13000 ; faster; for instance, on the 601 and 750.
13002 (define_expand "movsi_to_cr_one"
13003 [(set (match_operand:CC 0 "cc_reg_operand")
13004 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand")
13005 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13007 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13009 (define_insn "*movsi_to_cr"
13010 [(match_parallel 0 "mtcrf_operation"
13011 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13012 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13013 (match_operand 3 "immediate_operand" "n")]
13014 UNSPEC_MOVESI_TO_CR))])]
13019 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13020 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13021 operands[4] = GEN_INT (mask);
13022 return "mtcrf %4,%2";
13024 [(set_attr "type" "mtcr")])
13026 (define_insn "*mtcrfsi"
13027 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13028 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13029 (match_operand 2 "immediate_operand" "n")]
13030 UNSPEC_MOVESI_TO_CR))]
13031 "GET_CODE (operands[0]) == REG
13032 && CR_REGNO_P (REGNO (operands[0]))
13033 && GET_CODE (operands[2]) == CONST_INT
13034 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13036 [(set_attr "type" "mtcr")])
13038 ; The load-multiple instructions have similar properties.
13039 ; Note that "load_multiple" is a name known to the machine-independent
13040 ; code that actually corresponds to the PowerPC load-string.
13042 (define_insn "*lmw"
13043 [(match_parallel 0 "lmw_operation"
13044 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13045 (match_operand:SI 2 "memory_operand" "m"))])]
13048 [(set_attr "type" "load")
13049 (set_attr "update" "yes")
13050 (set_attr "indexed" "yes")
13051 (set_attr "cell_micro" "always")])
13053 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13054 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13056 ; The following comment applies to:
13060 ; return_and_restore_gpregs*
13061 ; return_and_restore_fpregs*
13062 ; return_and_restore_fpregs_aix*
13064 ; The out-of-line save / restore functions expects one input argument.
13065 ; Since those are not standard call_insn's, we must avoid using
13066 ; MATCH_OPERAND for that argument. That way the register rename
13067 ; optimization will not try to rename this register.
13068 ; Each pattern is repeated for each possible register number used in
13069 ; various ABIs (r11, r1, and for some functions r12)
13071 (define_insn "*restore_gpregs_<mode>_r11"
13072 [(match_parallel 0 "any_parallel_operand"
13073 [(clobber (reg:P LR_REGNO))
13074 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13076 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13077 (match_operand:P 3 "memory_operand" "m"))])]
13080 [(set_attr "type" "branch")
13081 (set_attr "length" "4")])
13083 (define_insn "*restore_gpregs_<mode>_r12"
13084 [(match_parallel 0 "any_parallel_operand"
13085 [(clobber (reg:P LR_REGNO))
13086 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13088 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13089 (match_operand:P 3 "memory_operand" "m"))])]
13092 [(set_attr "type" "branch")
13093 (set_attr "length" "4")])
13095 (define_insn "*restore_gpregs_<mode>_r1"
13096 [(match_parallel 0 "any_parallel_operand"
13097 [(clobber (reg:P LR_REGNO))
13098 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13100 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13101 (match_operand:P 3 "memory_operand" "m"))])]
13104 [(set_attr "type" "branch")
13105 (set_attr "length" "4")])
13107 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13108 [(match_parallel 0 "any_parallel_operand"
13110 (clobber (reg:P LR_REGNO))
13111 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13113 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13114 (match_operand:P 3 "memory_operand" "m"))])]
13117 [(set_attr "type" "branch")
13118 (set_attr "length" "4")])
13120 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13121 [(match_parallel 0 "any_parallel_operand"
13123 (clobber (reg:P LR_REGNO))
13124 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13126 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13127 (match_operand:P 3 "memory_operand" "m"))])]
13130 [(set_attr "type" "branch")
13131 (set_attr "length" "4")])
13133 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13134 [(match_parallel 0 "any_parallel_operand"
13136 (clobber (reg:P LR_REGNO))
13137 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13139 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13140 (match_operand:P 3 "memory_operand" "m"))])]
13143 [(set_attr "type" "branch")
13144 (set_attr "length" "4")])
13146 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13147 [(match_parallel 0 "any_parallel_operand"
13149 (clobber (reg:P LR_REGNO))
13150 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13152 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13153 (match_operand:DF 3 "memory_operand" "m"))])]
13156 [(set_attr "type" "branch")
13157 (set_attr "length" "4")])
13159 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13160 [(match_parallel 0 "any_parallel_operand"
13162 (clobber (reg:P LR_REGNO))
13163 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13165 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13166 (match_operand:DF 3 "memory_operand" "m"))])]
13169 [(set_attr "type" "branch")
13170 (set_attr "length" "4")])
13172 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13173 [(match_parallel 0 "any_parallel_operand"
13175 (clobber (reg:P LR_REGNO))
13176 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13178 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13179 (match_operand:DF 3 "memory_operand" "m"))])]
13182 [(set_attr "type" "branch")
13183 (set_attr "length" "4")])
13185 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13186 [(match_parallel 0 "any_parallel_operand"
13188 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13190 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13191 (match_operand:DF 3 "memory_operand" "m"))])]
13194 [(set_attr "type" "branch")
13195 (set_attr "length" "4")])
13197 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13198 [(match_parallel 0 "any_parallel_operand"
13200 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13202 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13203 (match_operand:DF 3 "memory_operand" "m"))])]
13206 [(set_attr "type" "branch")
13207 (set_attr "length" "4")])
13209 ; This is used in compiling the unwind routines.
13210 (define_expand "eh_return"
13211 [(use (match_operand 0 "general_operand"))]
13215 emit_insn (gen_eh_set_lr_si (operands[0]));
13217 emit_insn (gen_eh_set_lr_di (operands[0]));
13221 ; We can't expand this before we know where the link register is stored.
13222 (define_insn "eh_set_lr_<mode>"
13223 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13225 (clobber (match_scratch:P 1 "=&b"))]
13230 [(unspec_volatile [(match_operand 0 "register_operand")] UNSPECV_EH_RR)
13231 (clobber (match_scratch 1))]
13235 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13239 (define_insn "prefetch"
13240 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13241 (match_operand:SI 1 "const_int_operand" "n")
13242 (match_operand:SI 2 "const_int_operand" "n"))]
13245 if (GET_CODE (operands[0]) == REG)
13246 return INTVAL (operands[1]) ? "dcbtst 0,%0" : "dcbt 0,%0";
13247 return INTVAL (operands[1]) ? "dcbtst %a0" : "dcbt %a0";
13249 [(set_attr "type" "load")])
13251 ;; Handle -fsplit-stack.
13253 (define_expand "split_stack_prologue"
13257 rs6000_expand_split_stack_prologue ();
13261 (define_expand "load_split_stack_limit"
13262 [(set (match_operand 0)
13263 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13266 emit_insn (gen_rtx_SET (operands[0],
13267 gen_rtx_UNSPEC (Pmode,
13268 gen_rtvec (1, const0_rtx),
13269 UNSPEC_STACK_CHECK)));
13273 (define_insn "load_split_stack_limit_di"
13274 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13275 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13277 "ld %0,-0x7040(13)"
13278 [(set_attr "type" "load")
13279 (set_attr "update" "no")
13280 (set_attr "indexed" "no")])
13282 (define_insn "load_split_stack_limit_si"
13283 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13284 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13286 "lwz %0,-0x7020(2)"
13287 [(set_attr "type" "load")
13288 (set_attr "update" "no")
13289 (set_attr "indexed" "no")])
13291 ;; A return instruction which the middle-end doesn't see.
13292 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13293 ;; after the call to __morestack.
13294 (define_insn "split_stack_return"
13295 [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)]
13298 [(set_attr "type" "jmpreg")])
13300 ;; If there are operand 0 bytes available on the stack, jump to
13302 (define_expand "split_stack_space_check"
13303 [(set (match_dup 2)
13304 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13306 (minus (reg STACK_POINTER_REGNUM)
13307 (match_operand 0)))
13308 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13309 (set (pc) (if_then_else
13310 (geu (match_dup 4) (const_int 0))
13311 (label_ref (match_operand 1))
13315 rs6000_split_stack_space_check (operands[0], operands[1]);
13319 (define_insn "bpermd_<mode>"
13320 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13321 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13322 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13325 [(set_attr "type" "popcnt")])
13328 ;; Builtin fma support. Handle
13329 ;; Note that the conditions for expansion are in the FMA_F iterator.
13331 (define_expand "fma<mode>4"
13332 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13334 (match_operand:FMA_F 1 "gpc_reg_operand")
13335 (match_operand:FMA_F 2 "gpc_reg_operand")
13336 (match_operand:FMA_F 3 "gpc_reg_operand")))]
13340 (define_insn "*fma<mode>4_fpr"
13341 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13343 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13344 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13345 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13346 "TARGET_<MODE>_FPR"
13348 fmadd<Ftrad> %0,%1,%2,%3
13349 xsmadda<Fvsx> %x0,%x1,%x2
13350 xsmaddm<Fvsx> %x0,%x1,%x3"
13351 [(set_attr "type" "fp")
13352 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13354 ; Altivec only has fma and nfms.
13355 (define_expand "fms<mode>4"
13356 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13358 (match_operand:FMA_F 1 "gpc_reg_operand")
13359 (match_operand:FMA_F 2 "gpc_reg_operand")
13360 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13361 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13364 (define_insn "*fms<mode>4_fpr"
13365 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13367 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13368 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13369 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13370 "TARGET_<MODE>_FPR"
13372 fmsub<Ftrad> %0,%1,%2,%3
13373 xsmsuba<Fvsx> %x0,%x1,%x2
13374 xsmsubm<Fvsx> %x0,%x1,%x3"
13375 [(set_attr "type" "fp")
13376 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13378 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13379 (define_expand "fnma<mode>4"
13380 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13383 (match_operand:FMA_F 1 "gpc_reg_operand")
13384 (match_operand:FMA_F 2 "gpc_reg_operand")
13385 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13386 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13389 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13390 (define_expand "fnms<mode>4"
13391 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13394 (match_operand:FMA_F 1 "gpc_reg_operand")
13395 (match_operand:FMA_F 2 "gpc_reg_operand")
13396 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13397 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13400 ; Not an official optab name, but used from builtins.
13401 (define_expand "nfma<mode>4"
13402 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13405 (match_operand:FMA_F 1 "gpc_reg_operand")
13406 (match_operand:FMA_F 2 "gpc_reg_operand")
13407 (match_operand:FMA_F 3 "gpc_reg_operand"))))]
13408 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13411 (define_insn "*nfma<mode>4_fpr"
13412 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13415 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13416 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13417 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13418 "TARGET_<MODE>_FPR"
13420 fnmadd<Ftrad> %0,%1,%2,%3
13421 xsnmadda<Fvsx> %x0,%x1,%x2
13422 xsnmaddm<Fvsx> %x0,%x1,%x3"
13423 [(set_attr "type" "fp")
13424 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13426 ; Not an official optab name, but used from builtins.
13427 (define_expand "nfms<mode>4"
13428 [(set (match_operand:FMA_F 0 "gpc_reg_operand")
13431 (match_operand:FMA_F 1 "gpc_reg_operand")
13432 (match_operand:FMA_F 2 "gpc_reg_operand")
13433 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand")))))]
13437 (define_insn "*nfmssf4_fpr"
13438 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13441 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13442 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13444 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13445 "TARGET_<MODE>_FPR"
13447 fnmsub<Ftrad> %0,%1,%2,%3
13448 xsnmsuba<Fvsx> %x0,%x1,%x2
13449 xsnmsubm<Fvsx> %x0,%x1,%x3"
13450 [(set_attr "type" "fp")
13451 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13454 (define_expand "rs6000_get_timebase"
13455 [(use (match_operand:DI 0 "gpc_reg_operand"))]
13458 if (TARGET_POWERPC64)
13459 emit_insn (gen_rs6000_mftb_di (operands[0]));
13461 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13465 (define_insn "rs6000_get_timebase_ppc32"
13466 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13467 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13468 (clobber (match_scratch:SI 1 "=r"))
13469 (clobber (match_scratch:CC 2 "=y"))]
13470 "!TARGET_POWERPC64"
13472 if (WORDS_BIG_ENDIAN)
13475 return "mfspr %0,269\;"
13483 return "mftbu %0\;"
13492 return "mfspr %L0,269\;"
13500 return "mftbu %L0\;"
13507 [(set_attr "length" "20")])
13509 (define_insn "rs6000_mftb_<mode>"
13510 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13511 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13515 return "mfspr %0,268";
13521 (define_insn "rs6000_mffs"
13522 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13523 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13524 "TARGET_HARD_FLOAT"
13527 (define_insn "rs6000_mtfsf"
13528 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13529 (match_operand:DF 1 "gpc_reg_operand" "d")]
13531 "TARGET_HARD_FLOAT"
13535 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13536 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13537 ;; register that is being loaded. The fused ops must be physically adjacent.
13539 ;; There are two parts to addis fusion. The support for fused TOCs occur
13540 ;; before register allocation, and is meant to reduce the lifetime for the
13541 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13542 ;; to use the register that is being load. The peephole2 then gathers any
13543 ;; other fused possibilities that it can find after register allocation. If
13544 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13546 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13547 ;; before register allocation, so that we can avoid allocating a temporary base
13548 ;; register that won't be used, and that we try to load into base registers,
13549 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13550 ;; (addis followed by load) even on power8.
13553 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand")
13554 (match_operand:INT1 1 "toc_fusion_mem_raw"))]
13555 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13556 [(parallel [(set (match_dup 0) (match_dup 2))
13557 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13558 (use (match_dup 3))
13559 (clobber (scratch:DI))])]
13561 operands[2] = fusion_wrap_memory_address (operands[1]);
13562 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13565 (define_insn "*toc_fusionload_<mode>"
13566 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13567 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13568 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13569 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13570 (clobber (match_scratch:DI 3 "=X,&b"))]
13571 "TARGET_TOC_FUSION_INT"
13573 if (base_reg_operand (operands[0], <MODE>mode))
13574 return emit_fusion_gpr_load (operands[0], operands[1]);
13576 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13578 [(set_attr "type" "load")
13579 (set_attr "length" "8")])
13581 (define_insn "*toc_fusionload_di"
13582 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13583 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13584 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13585 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13586 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13587 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13588 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13590 if (base_reg_operand (operands[0], DImode))
13591 return emit_fusion_gpr_load (operands[0], operands[1]);
13593 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13595 [(set_attr "type" "load")
13596 (set_attr "length" "8")])
13599 ;; Find cases where the addis that feeds into a load instruction is either used
13600 ;; once or is the same as the target register, and replace it with the fusion
13604 [(set (match_operand:P 0 "base_reg_operand")
13605 (match_operand:P 1 "fusion_gpr_addis"))
13606 (set (match_operand:INT1 2 "base_reg_operand")
13607 (match_operand:INT1 3 "fusion_gpr_mem_load"))]
13609 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13613 expand_fusion_gpr_load (operands);
13617 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13620 (define_insn "fusion_gpr_load_<mode>"
13621 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13622 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13623 UNSPEC_FUSION_GPR))]
13626 return emit_fusion_gpr_load (operands[0], operands[1]);
13628 [(set_attr "type" "load")
13629 (set_attr "length" "8")])
13632 ;; ISA 3.0 (power9) fusion support
13633 ;; Merge addis with floating load/store to FPRs (or GPRs).
13635 [(set (match_operand:P 0 "base_reg_operand")
13636 (match_operand:P 1 "fusion_gpr_addis"))
13637 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand")
13638 (match_operand:SFDF 3 "fusion_offsettable_mem_operand"))]
13639 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13640 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
13643 expand_fusion_p9_load (operands);
13648 [(set (match_operand:P 0 "base_reg_operand")
13649 (match_operand:P 1 "fusion_gpr_addis"))
13650 (set (match_operand:SFDF 2 "offsettable_mem_operand")
13651 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand"))]
13652 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
13653 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
13654 && !rtx_equal_p (operands[0], operands[3])"
13657 expand_fusion_p9_store (operands);
13662 [(set (match_operand:SDI 0 "int_reg_operand")
13663 (match_operand:SDI 1 "upper16_cint_operand"))
13665 (ior:SDI (match_dup 0)
13666 (match_operand:SDI 2 "u_short_cint_operand")))]
13668 [(set (match_dup 0)
13669 (unspec:SDI [(match_dup 1)
13670 (match_dup 2)] UNSPEC_FUSION_P9))])
13673 [(set (match_operand:SDI 0 "int_reg_operand")
13674 (match_operand:SDI 1 "upper16_cint_operand"))
13675 (set (match_operand:SDI 2 "int_reg_operand")
13676 (ior:SDI (match_dup 0)
13677 (match_operand:SDI 3 "u_short_cint_operand")))]
13679 && !rtx_equal_p (operands[0], operands[2])
13680 && peep2_reg_dead_p (2, operands[0])"
13681 [(set (match_dup 2)
13682 (unspec:SDI [(match_dup 1)
13683 (match_dup 3)] UNSPEC_FUSION_P9))])
13685 ;; Fusion insns, created by the define_peephole2 above (and eventually by
13686 ;; reload). Because we want to eventually have secondary_reload generate
13687 ;; these, they have to have a single alternative that gives the register
13688 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
13689 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
13690 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
13692 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13694 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13697 /* This insn is a secondary reload insn, which cannot have alternatives.
13698 If we are not loading up register 0, use the power8 fusion instead. */
13699 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
13700 return emit_fusion_gpr_load (operands[0], operands[1]);
13702 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13704 [(set_attr "type" "load")
13705 (set_attr "length" "8")])
13707 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
13708 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13710 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
13712 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13715 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13717 [(set_attr "type" "store")
13718 (set_attr "length" "8")])
13720 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
13721 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
13723 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
13725 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13728 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
13730 [(set_attr "type" "fpload")
13731 (set_attr "length" "8")])
13733 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
13734 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
13736 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
13738 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
13741 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
13743 [(set_attr "type" "fpstore")
13744 (set_attr "length" "8")])
13746 (define_insn "*fusion_p9_<mode>_constant"
13747 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
13748 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
13749 (match_operand:SDI 2 "u_short_cint_operand" "K")]
13750 UNSPEC_FUSION_P9))]
13753 emit_fusion_addis (operands[0], operands[1]);
13754 return "ori %0,%0,%2";
13756 [(set_attr "type" "two")
13757 (set_attr "length" "8")])
13760 ;; Optimize cases where we want to do a D-form load (register+offset) on
13761 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
13766 ;; and we change this to:
13771 [(match_scratch:P 0 "b")
13772 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13773 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
13774 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
13776 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13777 [(set (match_dup 0)
13782 rtx tmp_reg = operands[0];
13783 rtx mem = operands[2];
13784 rtx addr = XEXP (mem, 0);
13785 rtx add_op0, add_op1, new_addr;
13787 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13788 add_op0 = XEXP (addr, 0);
13789 add_op1 = XEXP (addr, 1);
13790 gcc_assert (REG_P (add_op0));
13791 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13793 operands[4] = add_op1;
13794 operands[5] = change_address (mem, <MODE>mode, new_addr);
13797 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
13798 ;; Altivec register, and the register allocator has generated:
13802 ;; and we change this to:
13807 [(match_scratch:P 0 "b")
13808 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
13809 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
13810 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
13812 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
13813 [(set (match_dup 0)
13818 rtx tmp_reg = operands[0];
13819 rtx mem = operands[3];
13820 rtx addr = XEXP (mem, 0);
13821 rtx add_op0, add_op1, new_addr;
13823 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
13824 add_op0 = XEXP (addr, 0);
13825 add_op1 = XEXP (addr, 1);
13826 gcc_assert (REG_P (add_op0));
13827 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
13829 operands[4] = add_op1;
13830 operands[5] = change_address (mem, <MODE>mode, new_addr);
13834 ;; Miscellaneous ISA 2.06 (power7) instructions
13835 (define_insn "addg6s"
13836 [(set (match_operand:SI 0 "register_operand" "=r")
13837 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
13838 (match_operand:SI 2 "register_operand" "r")]
13842 [(set_attr "type" "integer")
13843 (set_attr "length" "4")])
13845 (define_insn "cdtbcd"
13846 [(set (match_operand:SI 0 "register_operand" "=r")
13847 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13851 [(set_attr "type" "integer")
13852 (set_attr "length" "4")])
13854 (define_insn "cbcdtd"
13855 [(set (match_operand:SI 0 "register_operand" "=r")
13856 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
13860 [(set_attr "type" "integer")
13861 (set_attr "length" "4")])
13863 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
13866 (define_int_attr div_extend [(UNSPEC_DIVE "e")
13867 (UNSPEC_DIVEU "eu")])
13869 (define_insn "div<div_extend>_<mode>"
13870 [(set (match_operand:GPR 0 "register_operand" "=r")
13871 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
13872 (match_operand:GPR 2 "register_operand" "r")]
13873 UNSPEC_DIV_EXTEND))]
13875 "div<wd><div_extend> %0,%1,%2"
13876 [(set_attr "type" "div")
13877 (set_attr "size" "<bits>")])
13880 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
13882 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
13883 (define_mode_attr FP128_64 [(TF "DF")
13888 (define_expand "unpack<mode>"
13889 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand")
13891 [(match_operand:FMOVE128 1 "register_operand")
13892 (match_operand:QI 2 "const_0_to_1_operand")]
13893 UNSPEC_UNPACK_128BIT))]
13894 "FLOAT128_2REG_P (<MODE>mode)"
13897 (define_insn_and_split "unpack<mode>_dm"
13898 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
13900 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
13901 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
13902 UNSPEC_UNPACK_128BIT))]
13903 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
13905 "&& reload_completed"
13906 [(set (match_dup 0) (match_dup 3))]
13908 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13910 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13912 emit_note (NOTE_INSN_DELETED);
13916 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13918 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
13919 (set_attr "length" "4")])
13921 (define_insn_and_split "unpack<mode>_nodm"
13922 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
13924 [(match_operand:FMOVE128 1 "register_operand" "d,d")
13925 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
13926 UNSPEC_UNPACK_128BIT))]
13927 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
13929 "&& reload_completed"
13930 [(set (match_dup 0) (match_dup 3))]
13932 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
13934 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
13936 emit_note (NOTE_INSN_DELETED);
13940 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
13942 [(set_attr "type" "fp,fpstore")
13943 (set_attr "length" "4")])
13945 (define_insn_and_split "pack<mode>"
13946 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
13948 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
13949 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
13950 UNSPEC_PACK_128BIT))]
13951 "FLOAT128_2REG_P (<MODE>mode)"
13955 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
13956 [(set (match_dup 3) (match_dup 1))
13957 (set (match_dup 4) (match_dup 2))]
13959 unsigned dest_hi = REGNO (operands[0]);
13960 unsigned dest_lo = dest_hi + 1;
13962 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
13963 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
13965 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
13966 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
13968 [(set_attr "type" "fpsimple,fp")
13969 (set_attr "length" "4,8")])
13971 (define_insn "unpack<mode>"
13972 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
13973 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
13974 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
13975 UNSPEC_UNPACK_128BIT))]
13976 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
13978 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
13979 return ASM_COMMENT_START " xxpermdi to same register";
13981 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
13982 return "xxpermdi %x0,%x1,%x1,%3";
13984 [(set_attr "type" "vecperm")])
13986 (define_insn "pack<mode>"
13987 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
13988 (unspec:FMOVE128_VSX
13989 [(match_operand:DI 1 "register_operand" "wa")
13990 (match_operand:DI 2 "register_operand" "wa")]
13991 UNSPEC_PACK_128BIT))]
13993 "xxpermdi %x0,%x1,%x2,0"
13994 [(set_attr "type" "vecperm")])
13998 ;; ISA 2.08 IEEE 128-bit floating point support.
14000 (define_insn "add<mode>3"
14001 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14003 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14004 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14005 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14007 [(set_attr "type" "vecfloat")
14008 (set_attr "size" "128")])
14010 (define_insn "sub<mode>3"
14011 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14013 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14014 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14015 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14017 [(set_attr "type" "vecfloat")
14018 (set_attr "size" "128")])
14020 (define_insn "mul<mode>3"
14021 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14023 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14024 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14025 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14027 [(set_attr "type" "qmul")
14028 (set_attr "size" "128")])
14030 (define_insn "div<mode>3"
14031 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14033 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14034 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14035 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14037 [(set_attr "type" "vecdiv")
14038 (set_attr "size" "128")])
14040 (define_insn "sqrt<mode>2"
14041 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14043 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14044 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14046 [(set_attr "type" "vecdiv")
14047 (set_attr "size" "128")])
14049 (define_expand "copysign<mode>3"
14050 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14051 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14052 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14053 "FLOAT128_IEEE_P (<MODE>mode)"
14055 if (TARGET_FLOAT128_HW)
14056 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14060 rtx tmp = gen_reg_rtx (<MODE>mode);
14061 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14062 operands[2], tmp));
14067 (define_insn "copysign<mode>3_hard"
14068 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14070 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14071 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14073 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14074 "xscpsgnqp %0,%2,%1"
14075 [(set_attr "type" "vecmove")
14076 (set_attr "size" "128")])
14078 (define_insn "copysign<mode>3_soft"
14079 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14081 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14082 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14083 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14085 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14086 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14087 [(set_attr "type" "veccomplex")
14088 (set_attr "length" "8")])
14090 (define_insn "neg<mode>2_hw"
14091 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14093 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14094 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14096 [(set_attr "type" "vecmove")
14097 (set_attr "size" "128")])
14100 (define_insn "abs<mode>2_hw"
14101 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14103 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14104 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14106 [(set_attr "type" "vecmove")
14107 (set_attr "size" "128")])
14110 (define_insn "*nabs<mode>2_hw"
14111 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14114 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14115 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14117 [(set_attr "type" "vecmove")
14118 (set_attr "size" "128")])
14120 ;; Initially don't worry about doing fusion
14121 (define_insn "fma<mode>4_hw"
14122 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14124 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14125 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14126 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14127 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14128 "xsmaddqp %0,%1,%2"
14129 [(set_attr "type" "qmul")
14130 (set_attr "size" "128")])
14132 (define_insn "*fms<mode>4_hw"
14133 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14135 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14136 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14138 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14139 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14140 "xsmsubqp %0,%1,%2"
14141 [(set_attr "type" "qmul")
14142 (set_attr "size" "128")])
14144 (define_insn "*nfma<mode>4_hw"
14145 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14148 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14149 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14150 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14151 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14152 "xsnmaddqp %0,%1,%2"
14153 [(set_attr "type" "qmul")
14154 (set_attr "size" "128")])
14156 (define_insn "*nfms<mode>4_hw"
14157 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14160 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14161 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14163 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14164 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14165 "xsnmsubqp %0,%1,%2"
14166 [(set_attr "type" "qmul")
14167 (set_attr "size" "128")])
14169 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14170 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14171 (float_extend:IEEE128
14172 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14173 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14175 [(set_attr "type" "vecfloat")
14176 (set_attr "size" "128")])
14178 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14179 ;; point is a simple copy.
14180 (define_insn_and_split "extendkftf2"
14181 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14182 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14183 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14187 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14190 emit_note (NOTE_INSN_DELETED);
14193 [(set_attr "type" "*,veclogical")
14194 (set_attr "length" "0,4")])
14196 (define_insn_and_split "trunctfkf2"
14197 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14198 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14199 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14203 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14206 emit_note (NOTE_INSN_DELETED);
14209 [(set_attr "type" "*,veclogical")
14210 (set_attr "length" "0,4")])
14212 (define_insn "trunc<mode>df2_hw"
14213 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14215 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14216 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14218 [(set_attr "type" "vecfloat")
14219 (set_attr "size" "128")])
14221 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14222 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14224 (define_insn_and_split "trunc<mode>sf2_hw"
14225 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14227 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14228 (clobber (match_scratch:DF 2 "=v"))]
14229 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14232 [(set (match_dup 2)
14233 (unspec:DF [(match_dup 1)]
14234 UNSPEC_TRUNC_ROUND_TO_ODD))
14236 (float_truncate:SF (match_dup 2)))]
14238 if (GET_CODE (operands[2]) == SCRATCH)
14239 operands[2] = gen_reg_rtx (DFmode);
14241 [(set_attr "type" "vecfloat")
14242 (set_attr "length" "8")])
14244 ;; Conversion between IEEE 128-bit and integer types
14246 ;; The fix function for DImode and SImode was declared earlier as a
14247 ;; define_expand. It calls into rs6000_expand_float128_convert if we don't
14248 ;; have IEEE 128-bit hardware support. QImode and HImode are not provided
14249 ;; unless we have the IEEE 128-bit hardware.
14251 ;; Unlike the code for converting SFmode/DFmode to QImode/HImode, we don't have
14252 ;; to provide a GPR target that used direct move and a conversion in the GPR
14253 ;; which works around QImode/HImode not being allowed in vector registers in
14254 ;; ISA 2.07 (power8).
14255 (define_insn "fix<uns>_<IEEE128:mode><SDI:mode>2_hw"
14256 [(set (match_operand:SDI 0 "altivec_register_operand" "=v")
14257 (any_fix:SDI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14258 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14259 "xscvqp<su><wd>z %0,%1"
14260 [(set_attr "type" "vecfloat")
14261 (set_attr "size" "128")])
14263 (define_insn "fix<uns>_trunc<IEEE128:mode><QHI:mode>2"
14264 [(set (match_operand:QHI 0 "altivec_register_operand" "=v")
14266 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14267 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14268 "xscvqp<su>wz %0,%1"
14269 [(set_attr "type" "vecfloat")
14270 (set_attr "size" "128")])
14272 ;; Combiner patterns to prevent moving the result of converting an IEEE 128-bit
14273 ;; floating point value to 8/16/32-bit integer to GPR in order to save it.
14274 (define_insn_and_split "*fix<uns>_trunc<IEEE128:mode><QHSI:mode>2_mem"
14275 [(set (match_operand:QHSI 0 "memory_operand" "=Z")
14277 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14278 (clobber (match_scratch:QHSI 2 "=v"))]
14279 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14281 "&& reload_completed"
14282 [(set (match_dup 2)
14283 (any_fix:QHSI (match_dup 1)))
14287 (define_insn "float_<mode>di2_hw"
14288 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14289 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14290 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14292 [(set_attr "type" "vecfloat")
14293 (set_attr "size" "128")])
14295 (define_insn_and_split "float_<mode>si2_hw"
14296 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14297 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14298 (clobber (match_scratch:DI 2 "=v"))]
14299 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14302 [(set (match_dup 2)
14303 (sign_extend:DI (match_dup 1)))
14305 (float:IEEE128 (match_dup 2)))]
14307 if (GET_CODE (operands[2]) == SCRATCH)
14308 operands[2] = gen_reg_rtx (DImode);
14310 if (MEM_P (operands[1]))
14311 operands[1] = rs6000_address_for_fpconvert (operands[1]);
14314 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14315 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14316 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14317 (clobber (match_scratch:DI 2 "=X,r,X"))]
14318 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14320 "&& reload_completed"
14323 rtx dest = operands[0];
14324 rtx src = operands[1];
14325 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14327 if (altivec_register_operand (src, <QHI:MODE>mode))
14328 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14329 else if (int_reg_operand (src, <QHI:MODE>mode))
14331 rtx ext_di = operands[2];
14332 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14333 emit_move_insn (dest_di, ext_di);
14335 else if (MEM_P (src))
14337 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14338 emit_move_insn (dest_qhi, src);
14339 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14342 gcc_unreachable ();
14344 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14347 [(set_attr "length" "8,12,12")
14348 (set_attr "type" "vecfloat")
14349 (set_attr "size" "128")])
14351 (define_insn "floatuns_<mode>di2_hw"
14352 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14353 (unsigned_float:IEEE128
14354 (match_operand:DI 1 "altivec_register_operand" "v")))]
14355 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14357 [(set_attr "type" "vecfloat")
14358 (set_attr "size" "128")])
14360 (define_insn_and_split "floatuns_<mode>si2_hw"
14361 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14362 (unsigned_float:IEEE128
14363 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14364 (clobber (match_scratch:DI 2 "=v"))]
14365 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14368 [(set (match_dup 2)
14369 (zero_extend:DI (match_dup 1)))
14371 (float:IEEE128 (match_dup 2)))]
14373 if (GET_CODE (operands[2]) == SCRATCH)
14374 operands[2] = gen_reg_rtx (DImode);
14376 if (MEM_P (operands[1]))
14377 operands[1] = rs6000_address_for_fpconvert (operands[1]);
14380 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14381 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14382 (unsigned_float:IEEE128
14383 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14384 (clobber (match_scratch:DI 2 "=X,r,X"))]
14385 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14387 "&& reload_completed"
14390 rtx dest = operands[0];
14391 rtx src = operands[1];
14392 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14394 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14395 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14396 else if (int_reg_operand (src, <QHI:MODE>mode))
14398 rtx ext_di = operands[2];
14399 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14400 emit_move_insn (dest_di, ext_di);
14403 gcc_unreachable ();
14405 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14408 [(set_attr "length" "8,12,8")
14409 (set_attr "type" "vecfloat")
14410 (set_attr "size" "128")])
14412 ;; IEEE 128-bit round to integer built-in functions
14413 (define_insn "floor<mode>2"
14414 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14416 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14418 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14420 [(set_attr "type" "vecfloat")
14421 (set_attr "size" "128")])
14423 (define_insn "ceil<mode>2"
14424 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14426 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14428 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14430 [(set_attr "type" "vecfloat")
14431 (set_attr "size" "128")])
14433 (define_insn "btrunc<mode>2"
14434 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14436 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14438 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14440 [(set_attr "type" "vecfloat")
14441 (set_attr "size" "128")])
14443 (define_insn "round<mode>2"
14444 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14446 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14448 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14450 [(set_attr "type" "vecfloat")
14451 (set_attr "size" "128")])
14453 ;; IEEE 128-bit instructions with round to odd semantics
14454 (define_insn "add<mode>3_odd"
14455 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14457 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14458 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14459 UNSPEC_ADD_ROUND_TO_ODD))]
14460 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14461 "xsaddqpo %0,%1,%2"
14462 [(set_attr "type" "vecfloat")
14463 (set_attr "size" "128")])
14465 (define_insn "sub<mode>3_odd"
14466 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14468 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14469 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14470 UNSPEC_SUB_ROUND_TO_ODD))]
14471 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14472 "xssubqpo %0,%1,%2"
14473 [(set_attr "type" "vecfloat")
14474 (set_attr "size" "128")])
14476 (define_insn "mul<mode>3_odd"
14477 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14479 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14480 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14481 UNSPEC_MUL_ROUND_TO_ODD))]
14482 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14483 "xsmulqpo %0,%1,%2"
14484 [(set_attr "type" "qmul")
14485 (set_attr "size" "128")])
14487 (define_insn "div<mode>3_odd"
14488 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14490 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14491 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14492 UNSPEC_DIV_ROUND_TO_ODD))]
14493 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14494 "xsdivqpo %0,%1,%2"
14495 [(set_attr "type" "vecdiv")
14496 (set_attr "size" "128")])
14498 (define_insn "sqrt<mode>2_odd"
14499 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14501 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14502 UNSPEC_SQRT_ROUND_TO_ODD))]
14503 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14505 [(set_attr "type" "vecdiv")
14506 (set_attr "size" "128")])
14508 (define_insn "fma<mode>4_odd"
14509 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14511 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14512 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14513 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14514 UNSPEC_FMA_ROUND_TO_ODD))]
14515 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14516 "xsmaddqpo %0,%1,%2"
14517 [(set_attr "type" "qmul")
14518 (set_attr "size" "128")])
14520 (define_insn "*fms<mode>4_odd"
14521 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14523 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14524 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14526 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14527 UNSPEC_FMA_ROUND_TO_ODD))]
14528 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14529 "xsmsubqpo %0,%1,%2"
14530 [(set_attr "type" "qmul")
14531 (set_attr "size" "128")])
14533 (define_insn "*nfma<mode>4_odd"
14534 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14537 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14538 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14539 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14540 UNSPEC_FMA_ROUND_TO_ODD)))]
14541 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14542 "xsnmaddqpo %0,%1,%2"
14543 [(set_attr "type" "qmul")
14544 (set_attr "size" "128")])
14546 (define_insn "*nfms<mode>4_odd"
14547 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14550 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14551 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14553 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14554 UNSPEC_FMA_ROUND_TO_ODD)))]
14555 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14556 "xsnmsubqpo %0,%1,%2"
14557 [(set_attr "type" "qmul")
14558 (set_attr "size" "128")])
14560 (define_insn "trunc<mode>df2_odd"
14561 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14562 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14563 UNSPEC_TRUNC_ROUND_TO_ODD))]
14564 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14566 [(set_attr "type" "vecfloat")
14567 (set_attr "size" "128")])
14569 ;; IEEE 128-bit comparisons
14570 (define_insn "*cmp<mode>_hw"
14571 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14572 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14573 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14574 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14575 "xscmpuqp %0,%1,%2"
14576 [(set_attr "type" "veccmp")
14577 (set_attr "size" "128")])
14581 (include "sync.md")
14582 (include "vector.md")
14584 (include "altivec.md")
14586 (include "paired.md")
14587 (include "crypto.md")