1 ;; Machine description for IBM RISC System 6000 (POWER) for GNU C compiler
2 ;; Copyright (C) 1990-2017 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
143 UNSPEC_ADD_ROUND_TO_ODD
144 UNSPEC_SUB_ROUND_TO_ODD
145 UNSPEC_MUL_ROUND_TO_ODD
146 UNSPEC_DIV_ROUND_TO_ODD
147 UNSPEC_FMA_ROUND_TO_ODD
148 UNSPEC_SQRT_ROUND_TO_ODD
149 UNSPEC_TRUNC_ROUND_TO_ODD
156 ;; UNSPEC_VOLATILE usage
159 (define_c_enum "unspecv"
161 UNSPECV_LL ; load-locked
162 UNSPECV_SC ; store-conditional
163 UNSPECV_PROBE_STACK_RANGE ; probe range of stack addresses
164 UNSPECV_EH_RR ; eh_reg_restore
165 UNSPECV_ISYNC ; isync instruction
166 UNSPECV_MFTB ; move from time base
167 UNSPECV_NLGR ; non-local goto receiver
168 UNSPECV_MFFS ; Move from FPSCR
169 UNSPECV_MTFSF ; Move to FPSCR Fields
170 UNSPECV_SPLIT_STACK_RETURN ; A camouflaged return
174 ;; Define an insn type attribute. This is used in function unit delay
178 add,logical,shift,insert,
180 exts,cntlz,popcnt,isel,
181 load,store,fpload,fpstore,vecload,vecstore,
183 branch,jmpreg,mfjmpr,mtjmpr,trap,isync,sync,load_l,store_c,
184 cr_logical,delayed_cr,mfcr,mfcrf,mtcr,
185 fpcompare,fp,fpsimple,dmul,qmul,sdiv,ddiv,ssqrt,dsqrt,
186 vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,
187 vecfloat,vecfdiv,vecdouble,mffgpr,mftgpr,crypto,
188 veclogical,veccmpfx,vecexts,vecmove,
190 (const_string "integer"))
192 ;; What data size does this instruction work on?
193 ;; This is used for insert, mul and others as necessary.
194 (define_attr "size" "8,16,32,64,128" (const_string "32"))
196 ;; What is the insn_cost for this insn? The target hook can still override
197 ;; this. For optimizing for size the "length" attribute is used instead.
198 (define_attr "cost" "" (const_int 0))
200 ;; Is this instruction record form ("dot", signed compare to 0, writing CR0)?
201 ;; This is used for add, logical, shift, exts, mul.
202 (define_attr "dot" "no,yes" (const_string "no"))
204 ;; Does this instruction sign-extend its result?
205 ;; This is used for load insns.
206 (define_attr "sign_extend" "no,yes" (const_string "no"))
208 ;; Does this instruction use indexed (that is, reg+reg) addressing?
209 ;; This is used for load and store insns. If operand 0 or 1 is a MEM
210 ;; it is automatically set based on that. If a load or store instruction
211 ;; has fewer than two operands it needs to set this attribute manually
212 ;; or the compiler will crash.
213 (define_attr "indexed" "no,yes"
214 (if_then_else (ior (match_operand 0 "indexed_address_mem")
215 (match_operand 1 "indexed_address_mem"))
217 (const_string "no")))
219 ;; Does this instruction use update addressing?
220 ;; This is used for load and store insns. See the comments for "indexed".
221 (define_attr "update" "no,yes"
222 (if_then_else (ior (match_operand 0 "update_address_mem")
223 (match_operand 1 "update_address_mem"))
225 (const_string "no")))
227 ;; Is this instruction using operands[2] as shift amount, and can that be a
229 ;; This is used for shift insns.
230 (define_attr "maybe_var_shift" "no,yes" (const_string "no"))
232 ;; Is this instruction using a shift amount from a register?
233 ;; This is used for shift insns.
234 (define_attr "var_shift" "no,yes"
235 (if_then_else (and (eq_attr "type" "shift")
236 (eq_attr "maybe_var_shift" "yes"))
237 (if_then_else (match_operand 2 "gpc_reg_operand")
240 (const_string "no")))
242 ;; Is copying of this instruction disallowed?
243 (define_attr "cannot_copy" "no,yes" (const_string "no"))
245 ;; Define floating point instruction sub-types for use with Xfpu.md
246 (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"))
248 ;; Length (in bytes).
249 ; '(pc)' in the following doesn't include the instruction itself; it is
250 ; calculated as if the instruction had zero size.
251 (define_attr "length" ""
252 (if_then_else (eq_attr "type" "branch")
253 (if_then_else (and (ge (minus (match_dup 0) (pc))
255 (lt (minus (match_dup 0) (pc))
261 ;; Processor type -- this attribute must exactly match the processor_type
262 ;; enumeration in rs6000-opts.h.
264 "ppc601,ppc603,ppc604,ppc604e,ppc620,ppc630,
265 ppc750,ppc7400,ppc7450,
266 ppc403,ppc405,ppc440,ppc476,
267 ppc8540,ppc8548,ppce300c2,ppce300c3,ppce500mc,ppce500mc64,ppce5500,ppce6500,
268 power4,power5,power6,power7,power8,power9,
269 rs64a,mpccore,cell,ppca2,titan"
270 (const (symbol_ref "(enum attr_cpu) rs6000_tune")))
273 ;; If this instruction is microcoded on the CELL processor
274 ; The default for load extended, the recorded instructions and rotate/shifts by a variable is always microcoded
275 (define_attr "cell_micro" "not,conditional,always"
276 (if_then_else (ior (and (eq_attr "type" "shift,exts,mul")
277 (eq_attr "dot" "yes"))
278 (and (eq_attr "type" "load")
279 (eq_attr "sign_extend" "yes"))
280 (and (eq_attr "type" "shift")
281 (eq_attr "var_shift" "yes")))
282 (const_string "always")
283 (const_string "not")))
285 (automata_option "ndfa")
298 (include "e300c2c3.md")
299 (include "e500mc.md")
300 (include "e500mc64.md")
303 (include "power4.md")
304 (include "power5.md")
305 (include "power6.md")
306 (include "power7.md")
307 (include "power8.md")
308 (include "power9.md")
314 (include "predicates.md")
315 (include "constraints.md")
317 (include "darwin.md")
322 ; This mode iterator allows :GPR to be used to indicate the allowable size
323 ; of whole values in GPRs.
324 (define_mode_iterator GPR [SI (DI "TARGET_POWERPC64")])
326 ; And again, for patterns that need two (potentially) different integer modes.
327 (define_mode_iterator GPR2 [SI (DI "TARGET_POWERPC64")])
329 ; Any supported integer mode.
330 (define_mode_iterator INT [QI HI SI DI TI PTI])
332 ; Any supported integer mode that fits in one register.
333 (define_mode_iterator INT1 [QI HI SI (DI "TARGET_POWERPC64")])
335 ; Integer modes supported in VSX registers with ISA 3.0 instructions
336 (define_mode_iterator INT_ISA3 [QI HI SI DI])
338 ; Everything we can extend QImode to.
339 (define_mode_iterator EXTQI [SI (DI "TARGET_POWERPC64")])
341 ; Everything we can extend HImode to.
342 (define_mode_iterator EXTHI [SI (DI "TARGET_POWERPC64")])
344 ; Everything we can extend SImode to.
345 (define_mode_iterator EXTSI [(DI "TARGET_POWERPC64")])
347 ; QImode or HImode for small integer moves and small atomic ops
348 (define_mode_iterator QHI [QI HI])
350 ; QImode, HImode, SImode for fused ops only for GPR loads
351 (define_mode_iterator QHSI [QI HI SI])
353 ; HImode or SImode for sign extended fusion ops
354 (define_mode_iterator HSI [HI SI])
356 ; SImode or DImode, even if DImode doesn't fit in GPRs.
357 (define_mode_iterator SDI [SI DI])
359 ; Types that can be fused with an ADDIS instruction to load or store a GPR
360 ; register that has reg+offset addressing.
361 (define_mode_iterator GPR_FUSION [QI
364 (DI "TARGET_POWERPC64")
366 (DF "TARGET_POWERPC64")])
368 ; Types that can be fused with an ADDIS instruction to load or store a FPR
369 ; register that has reg+offset addressing.
370 (define_mode_iterator FPR_FUSION [DI SF DF])
372 ; The size of a pointer. Also, the size of the value that a record-condition
373 ; (one with a '.') will compare; and the size used for arithmetic carries.
374 (define_mode_iterator P [(SI "TARGET_32BIT") (DI "TARGET_64BIT")])
376 ; Iterator to add PTImode along with TImode (TImode can go in VSX registers,
377 ; PTImode is GPR only)
378 (define_mode_iterator TI2 [TI PTI])
380 ; Any hardware-supported floating-point mode
381 (define_mode_iterator FP [
382 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
383 (DF "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT")
384 (TF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
385 (IF "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128")
386 (KF "TARGET_FLOAT128_TYPE")
390 ; Any fma capable floating-point mode.
391 (define_mode_iterator FMA_F [
392 (SF "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT")
393 (DF "(TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT)
394 || VECTOR_UNIT_VSX_P (DFmode)")
395 (V2SF "TARGET_PAIRED_FLOAT")
396 (V4SF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V4SFmode)")
397 (V2DF "VECTOR_UNIT_ALTIVEC_OR_VSX_P (V2DFmode)")
398 (KF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (KFmode)")
399 (TF "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (TFmode)")
402 ; Floating point move iterators to combine binary and decimal moves
403 (define_mode_iterator FMOVE32 [SF SD])
404 (define_mode_iterator FMOVE64 [DF DD])
405 (define_mode_iterator FMOVE64X [DI DF DD])
406 (define_mode_iterator FMOVE128 [(TF "TARGET_LONG_DOUBLE_128")
407 (IF "FLOAT128_IBM_P (IFmode)")
408 (TD "TARGET_HARD_FLOAT")])
410 (define_mode_iterator FMOVE128_FPR [(TF "FLOAT128_2REG_P (TFmode)")
411 (IF "FLOAT128_2REG_P (IFmode)")
412 (TD "TARGET_HARD_FLOAT")])
414 ; Iterators for 128 bit types for direct move
415 (define_mode_iterator FMOVE128_GPR [TI
423 (KF "FLOAT128_VECTOR_P (KFmode)")
424 (TF "FLOAT128_VECTOR_P (TFmode)")])
426 ; Iterator for 128-bit VSX types for pack/unpack
427 (define_mode_iterator FMOVE128_VSX [V1TI KF])
429 ; Whether a floating point move is ok, don't allow SD without hardware FP
430 (define_mode_attr fmove_ok [(SF "")
432 (SD "TARGET_HARD_FLOAT")
435 ; Convert REAL_VALUE to the appropriate bits
436 (define_mode_attr real_value_to_target [(SF "REAL_VALUE_TO_TARGET_SINGLE")
437 (DF "REAL_VALUE_TO_TARGET_DOUBLE")
438 (SD "REAL_VALUE_TO_TARGET_DECIMAL32")
439 (DD "REAL_VALUE_TO_TARGET_DECIMAL64")])
441 ; Whether 0.0 has an all-zero bit pattern
442 (define_mode_attr zero_fp [(SF "j")
451 ; Definitions for 64-bit VSX
452 (define_mode_attr f64_vsx [(DF "ws") (DD "wn")])
454 ; Definitions for 64-bit direct move
455 (define_mode_attr f64_dm [(DF "wk") (DD "wh")])
457 ; Definitions for 64-bit use of altivec registers
458 (define_mode_attr f64_av [(DF "wv") (DD "wn")])
460 ; Definitions for 64-bit access to ISA 3.0 (power9) vector
461 (define_mode_attr f64_p9 [(DF "wb") (DD "wn")])
463 ; These modes do not fit in integer registers in 32-bit mode.
464 (define_mode_iterator DIFD [DI DF DD])
466 ; Iterator for reciprocal estimate instructions
467 (define_mode_iterator RECIPF [SF DF V4SF V2DF])
469 ; Iterator for just SF/DF
470 (define_mode_iterator SFDF [SF DF])
472 ; Like SFDF, but a different name to match conditional move where the
473 ; comparison operands may be a different mode than the input operands.
474 (define_mode_iterator SFDF2 [SF DF])
476 ; Iterator for 128-bit floating point that uses the IBM double-double format
477 (define_mode_iterator IBM128 [(IF "FLOAT128_IBM_P (IFmode)")
478 (TF "FLOAT128_IBM_P (TFmode)")])
480 ; Iterator for 128-bit floating point that uses IEEE 128-bit float
481 (define_mode_iterator IEEE128 [(KF "FLOAT128_IEEE_P (KFmode)")
482 (TF "FLOAT128_IEEE_P (TFmode)")])
484 ; Iterator for 128-bit floating point
485 (define_mode_iterator FLOAT128 [(KF "TARGET_FLOAT128_TYPE")
486 (IF "TARGET_FLOAT128_TYPE")
487 (TF "TARGET_LONG_DOUBLE_128")])
489 ; Iterator for signbit on 64-bit machines with direct move
490 (define_mode_iterator SIGNBIT [(KF "FLOAT128_VECTOR_P (KFmode)")
491 (TF "FLOAT128_VECTOR_P (TFmode)")])
493 ; Iterator for ISA 3.0 supported floating point types
494 (define_mode_iterator FP_ISA3 [SF DF])
496 ; SF/DF suffix for traditional floating instructions
497 (define_mode_attr Ftrad [(SF "s") (DF "")])
499 ; SF/DF suffix for VSX instructions
500 (define_mode_attr Fvsx [(SF "sp") (DF "dp")])
502 ; SF/DF constraint for arithmetic on traditional floating point registers
503 (define_mode_attr Ff [(SF "f") (DF "d") (DI "d")])
505 ; SF/DF constraint for arithmetic on VSX registers using instructions added in
506 ; ISA 2.06 (power7). This includes instructions that normally target DF mode,
507 ; but are used on SFmode, since internally SFmode values are kept in the DFmode
509 (define_mode_attr Fv [(SF "ww") (DF "ws") (DI "wi")])
511 ; SF/DF constraint for arithmetic on VSX registers. This is intended to be
512 ; used for DFmode instructions added in ISA 2.06 (power7) and SFmode
513 ; instructions added in ISA 2.07 (power8)
514 (define_mode_attr Fv2 [(SF "wy") (DF "ws") (DI "wi")])
516 ; SF/DF constraint for arithmetic on altivec registers
517 (define_mode_attr Fa [(SF "wu") (DF "wv")])
519 ; s/d suffix for things like fp_addsub_s/fp_addsub_d
520 (define_mode_attr Fs [(SF "s") (DF "d")])
523 (define_mode_attr Ffre [(SF "fres") (DF "fre")])
524 (define_mode_attr FFRE [(SF "FRES") (DF "FRE")])
526 ; Conditional returns.
527 (define_code_iterator any_return [return simple_return])
528 (define_code_attr return_pred [(return "direct_return ()")
529 (simple_return "1")])
530 (define_code_attr return_str [(return "") (simple_return "simple_")])
533 (define_code_iterator iorxor [ior xor])
534 (define_code_iterator and_ior_xor [and ior xor])
536 ; Signed/unsigned variants of ops.
537 (define_code_iterator any_extend [sign_extend zero_extend])
538 (define_code_iterator any_fix [fix unsigned_fix])
539 (define_code_iterator any_float [float unsigned_float])
541 (define_code_attr u [(sign_extend "")
546 (define_code_attr su [(sign_extend "s")
551 (unsigned_float "u")])
553 (define_code_attr az [(sign_extend "a")
558 (unsigned_float "z")])
560 (define_code_attr uns [(fix "")
563 (unsigned_float "uns")])
565 ; Various instructions that come in SI and DI forms.
566 ; A generic w/d attribute, for things like cmpw/cmpd.
567 (define_mode_attr wd [(QI "b")
578 ;; How many bits in this mode?
579 (define_mode_attr bits [(QI "8") (HI "16") (SI "32") (DI "64")])
582 (define_mode_attr dbits [(QI "56") (HI "48") (SI "32")])
584 ;; Bitmask for shift instructions
585 (define_mode_attr hH [(SI "h") (DI "H")])
587 ;; A mode twice the size of the given mode
588 (define_mode_attr dmode [(SI "di") (DI "ti")])
589 (define_mode_attr DMODE [(SI "DI") (DI "TI")])
591 ;; Suffix for reload patterns
592 (define_mode_attr ptrsize [(SI "32bit")
595 (define_mode_attr tptrsize [(SI "TARGET_32BIT")
596 (DI "TARGET_64BIT")])
598 (define_mode_attr mptrsize [(SI "si")
601 (define_mode_attr ptrload [(SI "lwz")
604 (define_mode_attr ptrm [(SI "m")
607 (define_mode_attr rreg [(SF "f")
614 (define_mode_attr rreg2 [(SF "f")
617 (define_mode_attr SI_CONVERT_FP [(SF "TARGET_FCFIDS")
618 (DF "TARGET_FCFID")])
620 (define_mode_attr TARGET_FLOAT [(SF "TARGET_SINGLE_FLOAT")
621 (DF "TARGET_DOUBLE_FLOAT")])
623 ;; Mode iterator for logical operations on 128-bit types
624 (define_mode_iterator BOOL_128 [TI
626 (V16QI "TARGET_ALTIVEC")
627 (V8HI "TARGET_ALTIVEC")
628 (V4SI "TARGET_ALTIVEC")
629 (V4SF "TARGET_ALTIVEC")
630 (V2DI "TARGET_ALTIVEC")
631 (V2DF "TARGET_ALTIVEC")
632 (V1TI "TARGET_ALTIVEC")])
634 ;; For the GPRs we use 3 constraints for register outputs, two that are the
635 ;; same as the output register, and a third where the output register is an
636 ;; early clobber, so we don't have to deal with register overlaps. For the
637 ;; vector types, we prefer to use the vector registers. For TI mode, allow
640 ;; Mode attribute for boolean operation register constraints for output
641 (define_mode_attr BOOL_REGS_OUTPUT [(TI "&r,r,r,wt,v")
643 (V16QI "wa,v,&?r,?r,?r")
644 (V8HI "wa,v,&?r,?r,?r")
645 (V4SI "wa,v,&?r,?r,?r")
646 (V4SF "wa,v,&?r,?r,?r")
647 (V2DI "wa,v,&?r,?r,?r")
648 (V2DF "wa,v,&?r,?r,?r")
649 (V1TI "wa,v,&?r,?r,?r")])
651 ;; Mode attribute for boolean operation register constraints for operand1
652 (define_mode_attr BOOL_REGS_OP1 [(TI "r,0,r,wt,v")
660 (V1TI "wa,v,r,0,r")])
662 ;; Mode attribute for boolean operation register constraints for operand2
663 (define_mode_attr BOOL_REGS_OP2 [(TI "r,r,0,wt,v")
671 (V1TI "wa,v,r,r,0")])
673 ;; Mode attribute for boolean operation register constraints for operand1
674 ;; for one_cmpl. To simplify things, we repeat the constraint where 0
675 ;; is used for operand1 or operand2
676 (define_mode_attr BOOL_REGS_UNARY [(TI "r,0,0,wt,v")
684 (V1TI "wa,v,r,0,0")])
686 ;; Reload iterator for creating the function to allocate a base register to
687 ;; supplement addressing modes.
688 (define_mode_iterator RELOAD [V16QI V8HI V4SI V2DI V4SF V2DF V1TI
689 SF SD SI DF DD DI TI PTI KF IF TF])
691 ;; Iterate over smin, smax
692 (define_code_iterator fp_minmax [smin smax])
694 (define_code_attr minmax [(smin "min")
697 (define_code_attr SMINMAX [(smin "SMIN")
700 ;; Iterator to optimize the following cases:
701 ;; D-form load to FPR register & move to Altivec register
702 ;; Move Altivec register to FPR register and store
703 (define_mode_iterator ALTIVEC_DFORM [DF
704 (SF "TARGET_P8_VECTOR")
705 (DI "TARGET_POWERPC64")])
708 ;; Start with fixed-point load and store insns. Here we put only the more
709 ;; complex forms. Basic data transfer is done later.
711 (define_insn "zero_extendqi<mode>2"
712 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
713 (zero_extend:EXTQI (match_operand:QI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
720 [(set_attr "type" "load,shift,fpload,vecperm")])
722 (define_insn_and_split "*zero_extendqi<mode>2_dot"
723 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
724 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
726 (clobber (match_scratch:EXTQI 0 "=r,r"))]
731 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
733 (zero_extend:EXTQI (match_dup 1)))
735 (compare:CC (match_dup 0)
738 [(set_attr "type" "logical")
739 (set_attr "dot" "yes")
740 (set_attr "length" "4,8")])
742 (define_insn_and_split "*zero_extendqi<mode>2_dot2"
743 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
744 (compare:CC (zero_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
746 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
747 (zero_extend:EXTQI (match_dup 1)))]
752 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
754 (zero_extend:EXTQI (match_dup 1)))
756 (compare:CC (match_dup 0)
759 [(set_attr "type" "logical")
760 (set_attr "dot" "yes")
761 (set_attr "length" "4,8")])
764 (define_insn "zero_extendhi<mode>2"
765 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,^wJwK,^wK")
766 (zero_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
770 rlwinm %0,%1,0,0xffff
773 [(set_attr "type" "load,shift,fpload,vecperm")])
775 (define_insn_and_split "*zero_extendhi<mode>2_dot"
776 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
777 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
779 (clobber (match_scratch:EXTHI 0 "=r,r"))]
784 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
786 (zero_extend:EXTHI (match_dup 1)))
788 (compare:CC (match_dup 0)
791 [(set_attr "type" "logical")
792 (set_attr "dot" "yes")
793 (set_attr "length" "4,8")])
795 (define_insn_and_split "*zero_extendhi<mode>2_dot2"
796 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
797 (compare:CC (zero_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
799 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
800 (zero_extend:EXTHI (match_dup 1)))]
805 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
807 (zero_extend:EXTHI (match_dup 1)))
809 (compare:CC (match_dup 0)
812 [(set_attr "type" "logical")
813 (set_attr "dot" "yes")
814 (set_attr "length" "4,8")])
817 (define_insn "zero_extendsi<mode>2"
818 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r,wz,wu,wj,r,wJwK")
819 (zero_extend:EXTSI (match_operand:SI 1 "reg_or_mem_operand" "m,r,Z,Z,r,wIwH,wJwK")))]
828 xxextractuw %x0,%x1,4"
829 [(set_attr "type" "load,shift,fpload,fpload,mffgpr,mftgpr,vecexts")])
831 (define_insn_and_split "*zero_extendsi<mode>2_dot"
832 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
833 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
835 (clobber (match_scratch:EXTSI 0 "=r,r"))]
840 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
842 (zero_extend:DI (match_dup 1)))
844 (compare:CC (match_dup 0)
847 [(set_attr "type" "shift")
848 (set_attr "dot" "yes")
849 (set_attr "length" "4,8")])
851 (define_insn_and_split "*zero_extendsi<mode>2_dot2"
852 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
853 (compare:CC (zero_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
855 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
856 (zero_extend:EXTSI (match_dup 1)))]
861 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
863 (zero_extend:EXTSI (match_dup 1)))
865 (compare:CC (match_dup 0)
868 [(set_attr "type" "shift")
869 (set_attr "dot" "yes")
870 (set_attr "length" "4,8")])
873 (define_insn "extendqi<mode>2"
874 [(set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,?*wK")
875 (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,?*wK")))]
880 [(set_attr "type" "exts,vecperm")])
882 (define_insn_and_split "*extendqi<mode>2_dot"
883 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
884 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
886 (clobber (match_scratch:EXTQI 0 "=r,r"))]
891 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
893 (sign_extend:EXTQI (match_dup 1)))
895 (compare:CC (match_dup 0)
898 [(set_attr "type" "exts")
899 (set_attr "dot" "yes")
900 (set_attr "length" "4,8")])
902 (define_insn_and_split "*extendqi<mode>2_dot2"
903 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
904 (compare:CC (sign_extend:EXTQI (match_operand:QI 1 "gpc_reg_operand" "r,r"))
906 (set (match_operand:EXTQI 0 "gpc_reg_operand" "=r,r")
907 (sign_extend:EXTQI (match_dup 1)))]
912 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
914 (sign_extend:EXTQI (match_dup 1)))
916 (compare:CC (match_dup 0)
919 [(set_attr "type" "exts")
920 (set_attr "dot" "yes")
921 (set_attr "length" "4,8")])
924 (define_expand "extendhi<mode>2"
925 [(set (match_operand:EXTHI 0 "gpc_reg_operand")
926 (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand")))]
930 (define_insn "*extendhi<mode>2"
931 [(set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r,?*wK,?*wK")
932 (sign_extend:EXTHI (match_operand:HI 1 "reg_or_mem_operand" "m,r,Z,wK")))]
939 [(set_attr "type" "load,exts,fpload,vecperm")
940 (set_attr "sign_extend" "yes")
941 (set_attr "length" "4,4,8,4")])
944 [(set (match_operand:EXTHI 0 "altivec_register_operand")
946 (match_operand:HI 1 "indexed_or_indirect_operand")))]
947 "TARGET_P9_VECTOR && reload_completed"
951 (sign_extend:EXTHI (match_dup 2)))]
953 operands[2] = gen_rtx_REG (HImode, REGNO (operands[0]));
956 (define_insn_and_split "*extendhi<mode>2_dot"
957 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
958 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
960 (clobber (match_scratch:EXTHI 0 "=r,r"))]
965 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
967 (sign_extend:EXTHI (match_dup 1)))
969 (compare:CC (match_dup 0)
972 [(set_attr "type" "exts")
973 (set_attr "dot" "yes")
974 (set_attr "length" "4,8")])
976 (define_insn_and_split "*extendhi<mode>2_dot2"
977 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
978 (compare:CC (sign_extend:EXTHI (match_operand:HI 1 "gpc_reg_operand" "r,r"))
980 (set (match_operand:EXTHI 0 "gpc_reg_operand" "=r,r")
981 (sign_extend:EXTHI (match_dup 1)))]
986 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
988 (sign_extend:EXTHI (match_dup 1)))
990 (compare:CC (match_dup 0)
993 [(set_attr "type" "exts")
994 (set_attr "dot" "yes")
995 (set_attr "length" "4,8")])
998 (define_insn "extendsi<mode>2"
999 [(set (match_operand:EXTSI 0 "gpc_reg_operand"
1000 "=r, r, wl, wu, wj, wK, wH, wr")
1002 (sign_extend:EXTSI (match_operand:SI 1 "lwa_operand"
1003 "Y, r, Z, Z, r, wK, wH, ?wIwH")))]
1014 [(set_attr "type" "load,exts,fpload,fpload,mffgpr,vecexts,vecperm,mftgpr")
1015 (set_attr "sign_extend" "yes")
1016 (set_attr "length" "4,4,4,4,4,4,8,8")])
1019 [(set (match_operand:EXTSI 0 "int_reg_operand")
1020 (sign_extend:EXTSI (match_operand:SI 1 "vsx_register_operand")))]
1021 "TARGET_DIRECT_MOVE_64BIT && reload_completed"
1025 (sign_extend:DI (match_dup 2)))]
1027 operands[2] = gen_rtx_REG (SImode, reg_or_subregno (operands[0]));
1031 [(set (match_operand:DI 0 "altivec_register_operand")
1032 (sign_extend:DI (match_operand:SI 1 "altivec_register_operand")))]
1033 "TARGET_P8_VECTOR && !TARGET_P9_VECTOR && reload_completed"
1036 rtx dest = operands[0];
1037 rtx src = operands[1];
1038 int dest_regno = REGNO (dest);
1039 int src_regno = REGNO (src);
1040 rtx dest_v2di = gen_rtx_REG (V2DImode, dest_regno);
1041 rtx src_v4si = gen_rtx_REG (V4SImode, src_regno);
1043 if (VECTOR_ELT_ORDER_BIG)
1045 emit_insn (gen_altivec_vupkhsw (dest_v2di, src_v4si));
1046 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const1_rtx));
1050 emit_insn (gen_altivec_vupklsw (dest_v2di, src_v4si));
1051 emit_insn (gen_vsx_xxspltd_v2di (dest_v2di, dest_v2di, const0_rtx));
1056 (define_insn_and_split "*extendsi<mode>2_dot"
1057 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1058 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1060 (clobber (match_scratch:EXTSI 0 "=r,r"))]
1065 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1067 (sign_extend:EXTSI (match_dup 1)))
1069 (compare:CC (match_dup 0)
1072 [(set_attr "type" "exts")
1073 (set_attr "dot" "yes")
1074 (set_attr "length" "4,8")])
1076 (define_insn_and_split "*extendsi<mode>2_dot2"
1077 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1078 (compare:CC (sign_extend:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r,r"))
1080 (set (match_operand:EXTSI 0 "gpc_reg_operand" "=r,r")
1081 (sign_extend:EXTSI (match_dup 1)))]
1086 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1088 (sign_extend:EXTSI (match_dup 1)))
1090 (compare:CC (match_dup 0)
1093 [(set_attr "type" "exts")
1094 (set_attr "dot" "yes")
1095 (set_attr "length" "4,8")])
1097 ;; IBM 405, 440, 464 and 476 half-word multiplication operations.
1099 (define_insn "*macchwc"
1100 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1101 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1102 (match_operand:SI 2 "gpc_reg_operand" "r")
1105 (match_operand:HI 1 "gpc_reg_operand" "r")))
1106 (match_operand:SI 4 "gpc_reg_operand" "0"))
1108 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1109 (plus:SI (mult:SI (ashiftrt:SI
1117 [(set_attr "type" "halfmul")])
1119 (define_insn "*macchw"
1120 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1121 (plus:SI (mult:SI (ashiftrt:SI
1122 (match_operand:SI 2 "gpc_reg_operand" "r")
1125 (match_operand:HI 1 "gpc_reg_operand" "r")))
1126 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1129 [(set_attr "type" "halfmul")])
1131 (define_insn "*macchwuc"
1132 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1133 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1134 (match_operand:SI 2 "gpc_reg_operand" "r")
1137 (match_operand:HI 1 "gpc_reg_operand" "r")))
1138 (match_operand:SI 4 "gpc_reg_operand" "0"))
1140 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1141 (plus:SI (mult:SI (lshiftrt:SI
1149 [(set_attr "type" "halfmul")])
1151 (define_insn "*macchwu"
1152 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1153 (plus:SI (mult:SI (lshiftrt:SI
1154 (match_operand:SI 2 "gpc_reg_operand" "r")
1157 (match_operand:HI 1 "gpc_reg_operand" "r")))
1158 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1161 [(set_attr "type" "halfmul")])
1163 (define_insn "*machhwc"
1164 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1165 (compare:CC (plus:SI (mult:SI (ashiftrt:SI
1166 (match_operand:SI 1 "gpc_reg_operand" "%r")
1169 (match_operand:SI 2 "gpc_reg_operand" "r")
1171 (match_operand:SI 4 "gpc_reg_operand" "0"))
1173 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1174 (plus:SI (mult:SI (ashiftrt:SI
1183 [(set_attr "type" "halfmul")])
1185 (define_insn "*machhw"
1186 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1187 (plus:SI (mult:SI (ashiftrt:SI
1188 (match_operand:SI 1 "gpc_reg_operand" "%r")
1191 (match_operand:SI 2 "gpc_reg_operand" "r")
1193 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1196 [(set_attr "type" "halfmul")])
1198 (define_insn "*machhwuc"
1199 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1200 (compare:CC (plus:SI (mult:SI (lshiftrt:SI
1201 (match_operand:SI 1 "gpc_reg_operand" "%r")
1204 (match_operand:SI 2 "gpc_reg_operand" "r")
1206 (match_operand:SI 4 "gpc_reg_operand" "0"))
1208 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1209 (plus:SI (mult:SI (lshiftrt:SI
1218 [(set_attr "type" "halfmul")])
1220 (define_insn "*machhwu"
1221 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1222 (plus:SI (mult:SI (lshiftrt:SI
1223 (match_operand:SI 1 "gpc_reg_operand" "%r")
1226 (match_operand:SI 2 "gpc_reg_operand" "r")
1228 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1231 [(set_attr "type" "halfmul")])
1233 (define_insn "*maclhwc"
1234 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1235 (compare:CC (plus:SI (mult:SI (sign_extend:SI
1236 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1238 (match_operand:HI 2 "gpc_reg_operand" "r")))
1239 (match_operand:SI 4 "gpc_reg_operand" "0"))
1241 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1242 (plus:SI (mult:SI (sign_extend:SI
1249 [(set_attr "type" "halfmul")])
1251 (define_insn "*maclhw"
1252 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1253 (plus:SI (mult:SI (sign_extend:SI
1254 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1256 (match_operand:HI 2 "gpc_reg_operand" "r")))
1257 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1260 [(set_attr "type" "halfmul")])
1262 (define_insn "*maclhwuc"
1263 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1264 (compare:CC (plus:SI (mult:SI (zero_extend:SI
1265 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1267 (match_operand:HI 2 "gpc_reg_operand" "r")))
1268 (match_operand:SI 4 "gpc_reg_operand" "0"))
1270 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1271 (plus:SI (mult:SI (zero_extend:SI
1278 [(set_attr "type" "halfmul")])
1280 (define_insn "*maclhwu"
1281 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1282 (plus:SI (mult:SI (zero_extend:SI
1283 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1285 (match_operand:HI 2 "gpc_reg_operand" "r")))
1286 (match_operand:SI 3 "gpc_reg_operand" "0")))]
1289 [(set_attr "type" "halfmul")])
1291 (define_insn "*nmacchwc"
1292 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1293 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1294 (mult:SI (ashiftrt:SI
1295 (match_operand:SI 2 "gpc_reg_operand" "r")
1298 (match_operand:HI 1 "gpc_reg_operand" "r"))))
1300 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1301 (minus:SI (match_dup 4)
1302 (mult:SI (ashiftrt:SI
1309 [(set_attr "type" "halfmul")])
1311 (define_insn "*nmacchw"
1312 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1313 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1314 (mult:SI (ashiftrt:SI
1315 (match_operand:SI 2 "gpc_reg_operand" "r")
1318 (match_operand:HI 1 "gpc_reg_operand" "r")))))]
1321 [(set_attr "type" "halfmul")])
1323 (define_insn "*nmachhwc"
1324 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1325 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1326 (mult:SI (ashiftrt:SI
1327 (match_operand:SI 1 "gpc_reg_operand" "%r")
1330 (match_operand:SI 2 "gpc_reg_operand" "r")
1333 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1334 (minus:SI (match_dup 4)
1335 (mult:SI (ashiftrt:SI
1343 [(set_attr "type" "halfmul")])
1345 (define_insn "*nmachhw"
1346 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1347 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1348 (mult:SI (ashiftrt:SI
1349 (match_operand:SI 1 "gpc_reg_operand" "%r")
1352 (match_operand:SI 2 "gpc_reg_operand" "r")
1356 [(set_attr "type" "halfmul")])
1358 (define_insn "*nmaclhwc"
1359 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1360 (compare:CC (minus:SI (match_operand:SI 4 "gpc_reg_operand" "0")
1361 (mult:SI (sign_extend:SI
1362 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1364 (match_operand:HI 2 "gpc_reg_operand" "r"))))
1366 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1367 (minus:SI (match_dup 4)
1368 (mult:SI (sign_extend:SI
1374 [(set_attr "type" "halfmul")])
1376 (define_insn "*nmaclhw"
1377 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1378 (minus:SI (match_operand:SI 3 "gpc_reg_operand" "0")
1379 (mult:SI (sign_extend:SI
1380 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1382 (match_operand:HI 2 "gpc_reg_operand" "r")))))]
1385 [(set_attr "type" "halfmul")])
1387 (define_insn "*mulchwc"
1388 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1389 (compare:CC (mult:SI (ashiftrt:SI
1390 (match_operand:SI 2 "gpc_reg_operand" "r")
1393 (match_operand:HI 1 "gpc_reg_operand" "r")))
1395 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1396 (mult:SI (ashiftrt:SI
1403 [(set_attr "type" "halfmul")])
1405 (define_insn "*mulchw"
1406 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1407 (mult:SI (ashiftrt:SI
1408 (match_operand:SI 2 "gpc_reg_operand" "r")
1411 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1414 [(set_attr "type" "halfmul")])
1416 (define_insn "*mulchwuc"
1417 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1418 (compare:CC (mult:SI (lshiftrt:SI
1419 (match_operand:SI 2 "gpc_reg_operand" "r")
1422 (match_operand:HI 1 "gpc_reg_operand" "r")))
1424 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1425 (mult:SI (lshiftrt:SI
1432 [(set_attr "type" "halfmul")])
1434 (define_insn "*mulchwu"
1435 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1436 (mult:SI (lshiftrt:SI
1437 (match_operand:SI 2 "gpc_reg_operand" "r")
1440 (match_operand:HI 1 "gpc_reg_operand" "r"))))]
1443 [(set_attr "type" "halfmul")])
1445 (define_insn "*mulhhwc"
1446 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1447 (compare:CC (mult:SI (ashiftrt:SI
1448 (match_operand:SI 1 "gpc_reg_operand" "%r")
1451 (match_operand:SI 2 "gpc_reg_operand" "r")
1454 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1455 (mult:SI (ashiftrt:SI
1463 [(set_attr "type" "halfmul")])
1465 (define_insn "*mulhhw"
1466 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1467 (mult:SI (ashiftrt:SI
1468 (match_operand:SI 1 "gpc_reg_operand" "%r")
1471 (match_operand:SI 2 "gpc_reg_operand" "r")
1475 [(set_attr "type" "halfmul")])
1477 (define_insn "*mulhhwuc"
1478 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1479 (compare:CC (mult:SI (lshiftrt:SI
1480 (match_operand:SI 1 "gpc_reg_operand" "%r")
1483 (match_operand:SI 2 "gpc_reg_operand" "r")
1486 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1487 (mult:SI (lshiftrt:SI
1495 [(set_attr "type" "halfmul")])
1497 (define_insn "*mulhhwu"
1498 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1499 (mult:SI (lshiftrt:SI
1500 (match_operand:SI 1 "gpc_reg_operand" "%r")
1503 (match_operand:SI 2 "gpc_reg_operand" "r")
1507 [(set_attr "type" "halfmul")])
1509 (define_insn "*mullhwc"
1510 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1511 (compare:CC (mult:SI (sign_extend:SI
1512 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1514 (match_operand:HI 2 "gpc_reg_operand" "r")))
1516 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1517 (mult:SI (sign_extend:SI
1523 [(set_attr "type" "halfmul")])
1525 (define_insn "*mullhw"
1526 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1527 (mult:SI (sign_extend:SI
1528 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1530 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1533 [(set_attr "type" "halfmul")])
1535 (define_insn "*mullhwuc"
1536 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1537 (compare:CC (mult:SI (zero_extend:SI
1538 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1540 (match_operand:HI 2 "gpc_reg_operand" "r")))
1542 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1543 (mult:SI (zero_extend:SI
1549 [(set_attr "type" "halfmul")])
1551 (define_insn "*mullhwu"
1552 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
1553 (mult:SI (zero_extend:SI
1554 (match_operand:HI 1 "gpc_reg_operand" "%r"))
1556 (match_operand:HI 2 "gpc_reg_operand" "r"))))]
1559 [(set_attr "type" "halfmul")])
1561 ;; IBM 405, 440, 464 and 476 string-search dlmzb instruction support.
1562 (define_insn "dlmzb"
1563 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
1564 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
1565 (match_operand:SI 2 "gpc_reg_operand" "r")]
1567 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
1568 (unspec:SI [(match_dup 1)
1574 (define_expand "strlensi"
1575 [(set (match_operand:SI 0 "gpc_reg_operand" "")
1576 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
1577 (match_operand:QI 2 "const_int_operand" "")
1578 (match_operand 3 "const_int_operand" "")]
1579 UNSPEC_DLMZB_STRLEN))
1580 (clobber (match_scratch:CC 4 "=x"))]
1581 "TARGET_DLMZB && WORDS_BIG_ENDIAN && !optimize_size"
1583 rtx result = operands[0];
1584 rtx src = operands[1];
1585 rtx search_char = operands[2];
1586 rtx align = operands[3];
1587 rtx addr, scratch_string, word1, word2, scratch_dlmzb;
1588 rtx loop_label, end_label, mem, cr0, cond;
1589 if (search_char != const0_rtx
1590 || GET_CODE (align) != CONST_INT
1591 || INTVAL (align) < 8)
1593 word1 = gen_reg_rtx (SImode);
1594 word2 = gen_reg_rtx (SImode);
1595 scratch_dlmzb = gen_reg_rtx (SImode);
1596 scratch_string = gen_reg_rtx (Pmode);
1597 loop_label = gen_label_rtx ();
1598 end_label = gen_label_rtx ();
1599 addr = force_reg (Pmode, XEXP (src, 0));
1600 emit_move_insn (scratch_string, addr);
1601 emit_label (loop_label);
1602 mem = change_address (src, SImode, scratch_string);
1603 emit_move_insn (word1, mem);
1604 emit_move_insn (word2, adjust_address (mem, SImode, 4));
1605 cr0 = gen_rtx_REG (CCmode, CR0_REGNO);
1606 emit_insn (gen_dlmzb (scratch_dlmzb, word1, word2, cr0));
1607 cond = gen_rtx_NE (VOIDmode, cr0, const0_rtx);
1608 emit_jump_insn (gen_rtx_SET (pc_rtx,
1609 gen_rtx_IF_THEN_ELSE (VOIDmode,
1615 emit_insn (gen_addsi3 (scratch_string, scratch_string, GEN_INT (8)));
1616 emit_jump_insn (gen_rtx_SET (pc_rtx,
1617 gen_rtx_LABEL_REF (VOIDmode, loop_label)));
1619 emit_label (end_label);
1620 emit_insn (gen_addsi3 (scratch_string, scratch_string, scratch_dlmzb));
1621 emit_insn (gen_subsi3 (result, scratch_string, addr));
1622 emit_insn (gen_addsi3 (result, result, constm1_rtx));
1626 ;; Fixed-point arithmetic insns.
1628 (define_expand "add<mode>3"
1629 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1630 (plus:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
1631 (match_operand:SDI 2 "reg_or_add_cint_operand" "")))]
1634 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1636 rtx lo0 = gen_lowpart (SImode, operands[0]);
1637 rtx lo1 = gen_lowpart (SImode, operands[1]);
1638 rtx lo2 = gen_lowpart (SImode, operands[2]);
1639 rtx hi0 = gen_highpart (SImode, operands[0]);
1640 rtx hi1 = gen_highpart (SImode, operands[1]);
1641 rtx hi2 = gen_highpart_mode (SImode, DImode, operands[2]);
1643 if (!reg_or_short_operand (lo2, SImode))
1644 lo2 = force_reg (SImode, lo2);
1645 if (!adde_operand (hi2, SImode))
1646 hi2 = force_reg (SImode, hi2);
1648 emit_insn (gen_addsi3_carry (lo0, lo1, lo2));
1649 emit_insn (gen_addsi3_carry_in (hi0, hi1, hi2));
1653 if (CONST_INT_P (operands[2]) && !add_operand (operands[2], <MODE>mode))
1655 rtx tmp = ((!can_create_pseudo_p ()
1656 || rtx_equal_p (operands[0], operands[1]))
1657 ? operands[0] : gen_reg_rtx (<MODE>mode));
1659 /* Adding a constant to r0 is not a valid insn, so use a different
1660 strategy in that case. */
1661 if (reg_or_subregno (operands[1]) == 0 || reg_or_subregno (tmp) == 0)
1663 if (operands[0] == operands[1])
1665 rs6000_emit_move (operands[0], operands[2], <MODE>mode);
1666 emit_insn (gen_add<mode>3 (operands[0], operands[1], operands[0]));
1670 HOST_WIDE_INT val = INTVAL (operands[2]);
1671 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1672 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1674 if (<MODE>mode == DImode && !satisfies_constraint_L (GEN_INT (rest)))
1677 /* The ordering here is important for the prolog expander.
1678 When space is allocated from the stack, adding 'low' first may
1679 produce a temporary deallocation (which would be bad). */
1680 emit_insn (gen_add<mode>3 (tmp, operands[1], GEN_INT (rest)));
1681 emit_insn (gen_add<mode>3 (operands[0], tmp, GEN_INT (low)));
1686 (define_insn "*add<mode>3"
1687 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r,r")
1688 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b,b")
1689 (match_operand:GPR 2 "add_operand" "r,I,L")))]
1695 [(set_attr "type" "add")])
1697 (define_insn "addsi3_high"
1698 [(set (match_operand:SI 0 "gpc_reg_operand" "=b")
1699 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
1700 (high:SI (match_operand 2 "" ""))))]
1701 "TARGET_MACHO && !TARGET_64BIT"
1702 "addis %0,%1,ha16(%2)"
1703 [(set_attr "type" "add")])
1705 (define_insn_and_split "*add<mode>3_dot"
1706 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1707 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1708 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1710 (clobber (match_scratch:GPR 0 "=r,r"))]
1711 "<MODE>mode == Pmode"
1715 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1717 (plus:GPR (match_dup 1)
1720 (compare:CC (match_dup 0)
1723 [(set_attr "type" "add")
1724 (set_attr "dot" "yes")
1725 (set_attr "length" "4,8")])
1727 (define_insn_and_split "*add<mode>3_dot2"
1728 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1729 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
1730 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
1732 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1733 (plus:GPR (match_dup 1)
1735 "<MODE>mode == Pmode"
1739 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1741 (plus:GPR (match_dup 1)
1744 (compare:CC (match_dup 0)
1747 [(set_attr "type" "add")
1748 (set_attr "dot" "yes")
1749 (set_attr "length" "4,8")])
1751 (define_insn_and_split "*add<mode>3_imm_dot"
1752 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1753 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1754 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1756 (clobber (match_scratch:GPR 0 "=r,r"))
1757 (clobber (reg:GPR CA_REGNO))]
1758 "<MODE>mode == Pmode"
1762 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1764 (plus:GPR (match_dup 1)
1767 (compare:CC (match_dup 0)
1770 [(set_attr "type" "add")
1771 (set_attr "dot" "yes")
1772 (set_attr "length" "4,8")])
1774 (define_insn_and_split "*add<mode>3_imm_dot2"
1775 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
1776 (compare:CC (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,b")
1777 (match_operand:GPR 2 "short_cint_operand" "I,I"))
1779 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1780 (plus:GPR (match_dup 1)
1782 (clobber (reg:GPR CA_REGNO))]
1783 "<MODE>mode == Pmode"
1787 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
1789 (plus:GPR (match_dup 1)
1792 (compare:CC (match_dup 0)
1795 [(set_attr "type" "add")
1796 (set_attr "dot" "yes")
1797 (set_attr "length" "4,8")])
1799 ;; Split an add that we can't do in one insn into two insns, each of which
1800 ;; does one 16-bit part. This is used by combine. Note that the low-order
1801 ;; add should be last in case the result gets used in an address.
1804 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
1805 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
1806 (match_operand:GPR 2 "non_add_cint_operand" "")))]
1808 [(set (match_dup 0) (plus:GPR (match_dup 1) (match_dup 3)))
1809 (set (match_dup 0) (plus:GPR (match_dup 0) (match_dup 4)))]
1811 HOST_WIDE_INT val = INTVAL (operands[2]);
1812 HOST_WIDE_INT low = ((val & 0xffff) ^ 0x8000) - 0x8000;
1813 HOST_WIDE_INT rest = trunc_int_for_mode (val - low, <MODE>mode);
1815 operands[4] = GEN_INT (low);
1816 if (<MODE>mode == SImode || satisfies_constraint_L (GEN_INT (rest)))
1817 operands[3] = GEN_INT (rest);
1818 else if (can_create_pseudo_p ())
1820 operands[3] = gen_reg_rtx (DImode);
1821 emit_move_insn (operands[3], operands[2]);
1822 emit_insn (gen_adddi3 (operands[0], operands[1], operands[3]));
1830 (define_insn "add<mode>3_carry"
1831 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1832 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1833 (match_operand:P 2 "reg_or_short_operand" "rI")))
1834 (set (reg:P CA_REGNO)
1835 (ltu:P (plus:P (match_dup 1)
1840 [(set_attr "type" "add")])
1842 (define_insn "*add<mode>3_imm_carry_pos"
1843 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1844 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1845 (match_operand:P 2 "short_cint_operand" "n")))
1846 (set (reg:P CA_REGNO)
1847 (geu:P (match_dup 1)
1848 (match_operand:P 3 "const_int_operand" "n")))]
1849 "INTVAL (operands[2]) > 0
1850 && INTVAL (operands[2]) + INTVAL (operands[3]) == 0"
1852 [(set_attr "type" "add")])
1854 (define_insn "*add<mode>3_imm_carry_0"
1855 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1856 (match_operand:P 1 "gpc_reg_operand" "r"))
1857 (set (reg:P CA_REGNO)
1861 [(set_attr "type" "add")])
1863 (define_insn "*add<mode>3_imm_carry_m1"
1864 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1865 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1867 (set (reg:P CA_REGNO)
1872 [(set_attr "type" "add")])
1874 (define_insn "*add<mode>3_imm_carry_neg"
1875 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
1876 (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
1877 (match_operand:P 2 "short_cint_operand" "n")))
1878 (set (reg:P CA_REGNO)
1879 (gtu:P (match_dup 1)
1880 (match_operand:P 3 "const_int_operand" "n")))]
1881 "INTVAL (operands[2]) < 0
1882 && INTVAL (operands[2]) + INTVAL (operands[3]) == -1"
1884 [(set_attr "type" "add")])
1887 (define_expand "add<mode>3_carry_in"
1889 (set (match_operand:GPR 0 "gpc_reg_operand")
1890 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand")
1891 (match_operand:GPR 2 "adde_operand"))
1892 (reg:GPR CA_REGNO)))
1893 (clobber (reg:GPR CA_REGNO))])]
1896 if (operands[2] == const0_rtx)
1898 emit_insn (gen_add<mode>3_carry_in_0 (operands[0], operands[1]));
1901 if (operands[2] == constm1_rtx)
1903 emit_insn (gen_add<mode>3_carry_in_m1 (operands[0], operands[1]));
1908 (define_insn "*add<mode>3_carry_in_internal"
1909 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1910 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1911 (match_operand:GPR 2 "gpc_reg_operand" "r"))
1912 (reg:GPR CA_REGNO)))
1913 (clobber (reg:GPR CA_REGNO))]
1916 [(set_attr "type" "add")])
1918 (define_insn "*add<mode>3_carry_in_internal2"
1919 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1920 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1922 (match_operand:GPR 2 "gpc_reg_operand" "r")))
1923 (clobber (reg:GPR CA_REGNO))]
1926 [(set_attr "type" "add")])
1928 (define_insn "add<mode>3_carry_in_0"
1929 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1930 (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1931 (reg:GPR CA_REGNO)))
1932 (clobber (reg:GPR CA_REGNO))]
1935 [(set_attr "type" "add")])
1937 (define_insn "add<mode>3_carry_in_m1"
1938 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1939 (plus:GPR (plus:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
1942 (clobber (reg:GPR CA_REGNO))]
1945 [(set_attr "type" "add")])
1948 (define_expand "one_cmpl<mode>2"
1949 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
1950 (not:SDI (match_operand:SDI 1 "gpc_reg_operand" "")))]
1953 if (<MODE>mode == DImode && !TARGET_POWERPC64)
1955 rs6000_split_logical (operands, NOT, false, false, false);
1960 (define_insn "*one_cmpl<mode>2"
1961 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
1962 (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
1966 (define_insn_and_split "*one_cmpl<mode>2_dot"
1967 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1968 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1970 (clobber (match_scratch:GPR 0 "=r,r"))]
1971 "<MODE>mode == Pmode"
1975 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1977 (not:GPR (match_dup 1)))
1979 (compare:CC (match_dup 0)
1982 [(set_attr "type" "logical")
1983 (set_attr "dot" "yes")
1984 (set_attr "length" "4,8")])
1986 (define_insn_and_split "*one_cmpl<mode>2_dot2"
1987 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
1988 (compare:CC (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
1990 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
1991 (not:GPR (match_dup 1)))]
1992 "<MODE>mode == Pmode"
1996 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
1998 (not:GPR (match_dup 1)))
2000 (compare:CC (match_dup 0)
2003 [(set_attr "type" "logical")
2004 (set_attr "dot" "yes")
2005 (set_attr "length" "4,8")])
2008 (define_expand "sub<mode>3"
2009 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
2010 (minus:SDI (match_operand:SDI 1 "reg_or_short_operand" "")
2011 (match_operand:SDI 2 "gpc_reg_operand" "")))]
2014 if (<MODE>mode == DImode && !TARGET_POWERPC64)
2016 rtx lo0 = gen_lowpart (SImode, operands[0]);
2017 rtx lo1 = gen_lowpart (SImode, operands[1]);
2018 rtx lo2 = gen_lowpart (SImode, operands[2]);
2019 rtx hi0 = gen_highpart (SImode, operands[0]);
2020 rtx hi1 = gen_highpart_mode (SImode, DImode, operands[1]);
2021 rtx hi2 = gen_highpart (SImode, operands[2]);
2023 if (!reg_or_short_operand (lo1, SImode))
2024 lo1 = force_reg (SImode, lo1);
2025 if (!adde_operand (hi1, SImode))
2026 hi1 = force_reg (SImode, hi1);
2028 emit_insn (gen_subfsi3_carry (lo0, lo2, lo1));
2029 emit_insn (gen_subfsi3_carry_in (hi0, hi2, hi1));
2033 if (short_cint_operand (operands[1], <MODE>mode))
2035 emit_insn (gen_subf<mode>3_imm (operands[0], operands[2], operands[1]));
2040 (define_insn "*subf<mode>3"
2041 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2042 (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r")
2043 (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2046 [(set_attr "type" "add")])
2048 (define_insn_and_split "*subf<mode>3_dot"
2049 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2050 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2051 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2053 (clobber (match_scratch:GPR 0 "=r,r"))]
2054 "<MODE>mode == Pmode"
2058 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2060 (minus:GPR (match_dup 2)
2063 (compare:CC (match_dup 0)
2066 [(set_attr "type" "add")
2067 (set_attr "dot" "yes")
2068 (set_attr "length" "4,8")])
2070 (define_insn_and_split "*subf<mode>3_dot2"
2071 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2072 (compare:CC (minus:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r")
2073 (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2075 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2076 (minus:GPR (match_dup 2)
2078 "<MODE>mode == Pmode"
2082 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2084 (minus:GPR (match_dup 2)
2087 (compare:CC (match_dup 0)
2090 [(set_attr "type" "add")
2091 (set_attr "dot" "yes")
2092 (set_attr "length" "4,8")])
2094 (define_insn "subf<mode>3_imm"
2095 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2096 (minus:GPR (match_operand:GPR 2 "short_cint_operand" "I")
2097 (match_operand:GPR 1 "gpc_reg_operand" "r")))
2098 (clobber (reg:GPR CA_REGNO))]
2101 [(set_attr "type" "add")])
2103 (define_insn_and_split "subf<mode>3_carry_dot2"
2104 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2105 (compare:CC (minus:P (match_operand:P 2 "gpc_reg_operand" "r,r")
2106 (match_operand:P 1 "gpc_reg_operand" "r,r"))
2108 (set (match_operand:P 0 "gpc_reg_operand" "=r,r")
2109 (minus:P (match_dup 2)
2111 (set (reg:P CA_REGNO)
2112 (leu:P (match_dup 1)
2114 "<MODE>mode == Pmode"
2118 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2119 [(parallel [(set (match_dup 0)
2120 (minus:P (match_dup 2)
2122 (set (reg:P CA_REGNO)
2123 (leu:P (match_dup 1)
2126 (compare:CC (match_dup 0)
2129 [(set_attr "type" "add")
2130 (set_attr "dot" "yes")
2131 (set_attr "length" "4,8")])
2133 (define_insn "subf<mode>3_carry"
2134 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2135 (minus:P (match_operand:P 2 "reg_or_short_operand" "rI")
2136 (match_operand:P 1 "gpc_reg_operand" "r")))
2137 (set (reg:P CA_REGNO)
2138 (leu:P (match_dup 1)
2142 [(set_attr "type" "add")])
2144 (define_insn "*subf<mode>3_imm_carry_0"
2145 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2146 (neg:P (match_operand:P 1 "gpc_reg_operand" "r")))
2147 (set (reg:P CA_REGNO)
2152 [(set_attr "type" "add")])
2154 (define_insn "*subf<mode>3_imm_carry_m1"
2155 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
2156 (not:P (match_operand:P 1 "gpc_reg_operand" "r")))
2157 (set (reg:P CA_REGNO)
2161 [(set_attr "type" "add")])
2164 (define_expand "subf<mode>3_carry_in"
2166 (set (match_operand:GPR 0 "gpc_reg_operand")
2167 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand"))
2169 (match_operand:GPR 2 "adde_operand")))
2170 (clobber (reg:GPR CA_REGNO))])]
2173 if (operands[2] == const0_rtx)
2175 emit_insn (gen_subf<mode>3_carry_in_0 (operands[0], operands[1]));
2178 if (operands[2] == constm1_rtx)
2180 emit_insn (gen_subf<mode>3_carry_in_m1 (operands[0], operands[1]));
2185 (define_insn "*subf<mode>3_carry_in_internal"
2186 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2187 (plus:GPR (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2189 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2190 (clobber (reg:GPR CA_REGNO))]
2193 [(set_attr "type" "add")])
2195 (define_insn "subf<mode>3_carry_in_0"
2196 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2197 (plus:GPR (not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
2198 (reg:GPR CA_REGNO)))
2199 (clobber (reg:GPR CA_REGNO))]
2202 [(set_attr "type" "add")])
2204 (define_insn "subf<mode>3_carry_in_m1"
2205 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2206 (plus:GPR (minus:GPR (reg:GPR CA_REGNO)
2207 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2209 (clobber (reg:GPR CA_REGNO))]
2212 [(set_attr "type" "add")])
2214 (define_insn "subf<mode>3_carry_in_xx"
2215 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2216 (plus:GPR (reg:GPR CA_REGNO)
2218 (clobber (reg:GPR CA_REGNO))]
2221 [(set_attr "type" "add")])
2224 (define_insn "neg<mode>2"
2225 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2226 (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2229 [(set_attr "type" "add")])
2231 (define_insn_and_split "*neg<mode>2_dot"
2232 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2233 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2235 (clobber (match_scratch:GPR 0 "=r,r"))]
2236 "<MODE>mode == Pmode"
2240 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2242 (neg:GPR (match_dup 1)))
2244 (compare:CC (match_dup 0)
2247 [(set_attr "type" "add")
2248 (set_attr "dot" "yes")
2249 (set_attr "length" "4,8")])
2251 (define_insn_and_split "*neg<mode>2_dot2"
2252 [(set (match_operand:CC 2 "cc_reg_operand" "=x,?y")
2253 (compare:CC (neg:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
2255 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2256 (neg:GPR (match_dup 1)))]
2257 "<MODE>mode == Pmode"
2261 "&& reload_completed && cc_reg_not_cr0_operand (operands[2], CCmode)"
2263 (neg:GPR (match_dup 1)))
2265 (compare:CC (match_dup 0)
2268 [(set_attr "type" "add")
2269 (set_attr "dot" "yes")
2270 (set_attr "length" "4,8")])
2273 (define_insn "clz<mode>2"
2274 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2275 (clz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2278 [(set_attr "type" "cntlz")])
2280 (define_expand "ctz<mode>2"
2281 [(set (match_operand:GPR 0 "gpc_reg_operand")
2282 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2287 emit_insn (gen_ctz<mode>2_hw (operands[0], operands[1]));
2291 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2292 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2293 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2297 emit_insn (gen_add<mode>3 (tmp1, operands[1], constm1_rtx));
2298 emit_insn (gen_one_cmpl<mode>2 (tmp2, operands[1]));
2299 emit_insn (gen_and<mode>3 (tmp3, tmp1, tmp2));
2300 emit_insn (gen_popcntd<mode>2 (operands[0], tmp3));
2304 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2305 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2306 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2307 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits> - 1), tmp3));
2313 (define_insn "ctz<mode>2_hw"
2314 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2315 (ctz:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2318 [(set_attr "type" "cntlz")])
2320 (define_expand "ffs<mode>2"
2321 [(set (match_operand:GPR 0 "gpc_reg_operand")
2322 (ffs:GPR (match_operand:GPR 1 "gpc_reg_operand")))]
2325 rtx tmp1 = gen_reg_rtx (<MODE>mode);
2326 rtx tmp2 = gen_reg_rtx (<MODE>mode);
2327 rtx tmp3 = gen_reg_rtx (<MODE>mode);
2328 emit_insn (gen_neg<mode>2 (tmp1, operands[1]));
2329 emit_insn (gen_and<mode>3 (tmp2, operands[1], tmp1));
2330 emit_insn (gen_clz<mode>2 (tmp3, tmp2));
2331 emit_insn (gen_sub<mode>3 (operands[0], GEN_INT (<bits>), tmp3));
2336 (define_expand "popcount<mode>2"
2337 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2338 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2339 "TARGET_POPCNTB || TARGET_POPCNTD"
2341 rs6000_emit_popcount (operands[0], operands[1]);
2345 (define_insn "popcntb<mode>2"
2346 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2347 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")]
2351 [(set_attr "type" "popcnt")])
2353 (define_insn "popcntd<mode>2"
2354 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2355 (popcount:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")))]
2358 [(set_attr "type" "popcnt")])
2361 (define_expand "parity<mode>2"
2362 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
2363 (parity:GPR (match_operand:GPR 1 "gpc_reg_operand" "")))]
2366 rs6000_emit_parity (operands[0], operands[1]);
2370 (define_insn "parity<mode>2_cmpb"
2371 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2372 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")] UNSPEC_PARITY))]
2373 "TARGET_CMPB && TARGET_POPCNTB"
2375 [(set_attr "type" "popcnt")])
2377 (define_insn "cmpb<mode>3"
2378 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2379 (unspec:GPR [(match_operand:GPR 1 "gpc_reg_operand" "r")
2380 (match_operand:GPR 2 "gpc_reg_operand" "r")] UNSPEC_CMPB))]
2383 [(set_attr "type" "cmp")])
2385 ;; Since the hardware zeros the upper part of the register, save generating the
2386 ;; AND immediate if we are converting to unsigned
2387 (define_insn "*bswap<mode>2_extenddi"
2388 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2390 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z"))))]
2393 [(set_attr "length" "4")
2394 (set_attr "type" "load")])
2396 (define_insn "*bswaphi2_extendsi"
2397 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2399 (bswap:HI (match_operand:HI 1 "memory_operand" "Z"))))]
2402 [(set_attr "length" "4")
2403 (set_attr "type" "load")])
2405 ;; Separate the bswap patterns into load, store, and gpr<-gpr. This prevents
2406 ;; the register allocator from converting a gpr<-gpr swap into a store and then
2407 ;; load with byte swap, which can be slower than doing it in the registers. It
2408 ;; also prevents certain failures with the RELOAD register allocator.
2410 (define_expand "bswap<mode>2"
2411 [(use (match_operand:HSI 0 "reg_or_mem_operand"))
2412 (use (match_operand:HSI 1 "reg_or_mem_operand"))]
2415 rtx dest = operands[0];
2416 rtx src = operands[1];
2418 if (!REG_P (dest) && !REG_P (src))
2419 src = force_reg (<MODE>mode, src);
2422 emit_insn (gen_bswap<mode>2_load (dest, src));
2423 else if (MEM_P (dest))
2424 emit_insn (gen_bswap<mode>2_store (dest, src));
2426 emit_insn (gen_bswap<mode>2_reg (dest, src));
2430 (define_insn "bswap<mode>2_load"
2431 [(set (match_operand:HSI 0 "gpc_reg_operand" "=r")
2432 (bswap:HSI (match_operand:HSI 1 "memory_operand" "Z")))]
2435 [(set_attr "type" "load")])
2437 (define_insn "bswap<mode>2_store"
2438 [(set (match_operand:HSI 0 "memory_operand" "=Z")
2439 (bswap:HSI (match_operand:HSI 1 "gpc_reg_operand" "r")))]
2442 [(set_attr "type" "store")])
2444 (define_insn_and_split "bswaphi2_reg"
2445 [(set (match_operand:HI 0 "gpc_reg_operand" "=&r,wo")
2447 (match_operand:HI 1 "gpc_reg_operand" "r,wo")))
2448 (clobber (match_scratch:SI 2 "=&r,X"))]
2453 "reload_completed && int_reg_operand (operands[0], HImode)"
2455 (and:SI (lshiftrt:SI (match_dup 4)
2459 (and:SI (ashift:SI (match_dup 4)
2461 (const_int 65280))) ;; 0xff00
2463 (ior:SI (match_dup 3)
2466 operands[3] = simplify_gen_subreg (SImode, operands[0], HImode, 0);
2467 operands[4] = simplify_gen_subreg (SImode, operands[1], HImode, 0);
2469 [(set_attr "length" "12,4")
2470 (set_attr "type" "*,vecperm")])
2472 ;; We are always BITS_BIG_ENDIAN, so the bit positions below in
2473 ;; zero_extract insns do not change for -mlittle.
2474 (define_insn_and_split "bswapsi2_reg"
2475 [(set (match_operand:SI 0 "gpc_reg_operand" "=&r,wo")
2477 (match_operand:SI 1 "gpc_reg_operand" "r,wo")))]
2482 "reload_completed && int_reg_operand (operands[0], SImode)"
2483 [(set (match_dup 0) ; DABC
2484 (rotate:SI (match_dup 1)
2486 (set (match_dup 0) ; DCBC
2487 (ior:SI (and:SI (ashift:SI (match_dup 1)
2489 (const_int 16711680))
2490 (and:SI (match_dup 0)
2491 (const_int -16711681))))
2492 (set (match_dup 0) ; DCBA
2493 (ior:SI (and:SI (lshiftrt:SI (match_dup 1)
2496 (and:SI (match_dup 0)
2497 (const_int -256))))]
2499 [(set_attr "length" "12,4")
2500 (set_attr "type" "*,vecperm")])
2502 ;; On systems with LDBRX/STDBRX generate the loads/stores directly, just like
2503 ;; we do for L{H,W}BRX and ST{H,W}BRX above. If not, we have to generate more
2506 (define_expand "bswapdi2"
2507 [(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
2509 (match_operand:DI 1 "reg_or_mem_operand" "")))
2510 (clobber (match_scratch:DI 2 ""))
2511 (clobber (match_scratch:DI 3 ""))])]
2514 rtx dest = operands[0];
2515 rtx src = operands[1];
2517 if (!REG_P (dest) && !REG_P (src))
2518 operands[1] = src = force_reg (DImode, src);
2520 if (TARGET_POWERPC64 && TARGET_LDBRX)
2523 emit_insn (gen_bswapdi2_load (dest, src));
2524 else if (MEM_P (dest))
2525 emit_insn (gen_bswapdi2_store (dest, src));
2526 else if (TARGET_P9_VECTOR)
2527 emit_insn (gen_bswapdi2_xxbrd (dest, src));
2529 emit_insn (gen_bswapdi2_reg (dest, src));
2533 if (!TARGET_POWERPC64)
2535 /* 32-bit mode needs fewer scratch registers, but 32-bit addressing mode
2536 that uses 64-bit registers needs the same scratch registers as 64-bit
2538 emit_insn (gen_bswapdi2_32bit (dest, src));
2543 ;; Power7/cell has ldbrx/stdbrx, so use it directly
2544 (define_insn "bswapdi2_load"
2545 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2546 (bswap:DI (match_operand:DI 1 "memory_operand" "Z")))]
2547 "TARGET_POWERPC64 && TARGET_LDBRX"
2549 [(set_attr "type" "load")])
2551 (define_insn "bswapdi2_store"
2552 [(set (match_operand:DI 0 "memory_operand" "=Z")
2553 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))]
2554 "TARGET_POWERPC64 && TARGET_LDBRX"
2556 [(set_attr "type" "store")])
2558 (define_insn "bswapdi2_xxbrd"
2559 [(set (match_operand:DI 0 "gpc_reg_operand" "=wo")
2560 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "wo")))]
2563 [(set_attr "type" "vecperm")])
2565 (define_insn "bswapdi2_reg"
2566 [(set (match_operand:DI 0 "gpc_reg_operand" "=&r")
2567 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "r")))
2568 (clobber (match_scratch:DI 2 "=&r"))
2569 (clobber (match_scratch:DI 3 "=&r"))]
2570 "TARGET_POWERPC64 && TARGET_LDBRX && !TARGET_P9_VECTOR"
2572 [(set_attr "length" "36")])
2574 ;; Non-power7/cell, fall back to use lwbrx/stwbrx
2575 (define_insn "*bswapdi2_64bit"
2576 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,&r")
2577 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2578 (clobber (match_scratch:DI 2 "=&b,&b,&r"))
2579 (clobber (match_scratch:DI 3 "=&r,&r,&r"))]
2580 "TARGET_POWERPC64 && !TARGET_LDBRX
2581 && (REG_P (operands[0]) || REG_P (operands[1]))
2582 && !(MEM_P (operands[0]) && MEM_VOLATILE_P (operands[0]))
2583 && !(MEM_P (operands[1]) && MEM_VOLATILE_P (operands[1]))"
2585 [(set_attr "length" "16,12,36")])
2588 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2589 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2590 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2591 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2592 "TARGET_POWERPC64 && !TARGET_LDBRX && reload_completed"
2596 rtx dest = operands[0];
2597 rtx src = operands[1];
2598 rtx op2 = operands[2];
2599 rtx op3 = operands[3];
2600 rtx op3_32 = simplify_gen_subreg (SImode, op3, DImode,
2601 BYTES_BIG_ENDIAN ? 4 : 0);
2602 rtx dest_32 = simplify_gen_subreg (SImode, dest, DImode,
2603 BYTES_BIG_ENDIAN ? 4 : 0);
2609 addr1 = XEXP (src, 0);
2610 if (GET_CODE (addr1) == PLUS)
2612 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2613 if (TARGET_AVOID_XFORM)
2615 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2619 addr2 = gen_rtx_PLUS (Pmode, op2, XEXP (addr1, 1));
2621 else if (TARGET_AVOID_XFORM)
2623 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2628 emit_move_insn (op2, GEN_INT (4));
2629 addr2 = gen_rtx_PLUS (Pmode, op2, addr1);
2632 word1 = change_address (src, SImode, addr1);
2633 word2 = change_address (src, SImode, addr2);
2635 if (BYTES_BIG_ENDIAN)
2637 emit_insn (gen_bswapsi2 (op3_32, word2));
2638 emit_insn (gen_bswapsi2 (dest_32, word1));
2642 emit_insn (gen_bswapsi2 (op3_32, word1));
2643 emit_insn (gen_bswapsi2 (dest_32, word2));
2646 emit_insn (gen_ashldi3 (op3, op3, GEN_INT (32)));
2647 emit_insn (gen_iordi3 (dest, dest, op3));
2652 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2653 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2654 (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
2655 (clobber (match_operand:DI 3 "gpc_reg_operand" ""))]
2656 "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"
2723 rtx dest = operands[0];
2724 rtx src = operands[1];
2725 rtx op2 = operands[2];
2726 rtx op3 = operands[3];
2727 int lo_off = BYTES_BIG_ENDIAN ? 4 : 0;
2728 rtx dest_si = simplify_gen_subreg (SImode, dest, DImode, lo_off);
2729 rtx src_si = simplify_gen_subreg (SImode, src, DImode, lo_off);
2730 rtx op2_si = simplify_gen_subreg (SImode, op2, DImode, lo_off);
2731 rtx op3_si = simplify_gen_subreg (SImode, op3, DImode, lo_off);
2733 emit_insn (gen_lshrdi3 (op2, src, GEN_INT (32)));
2734 emit_insn (gen_bswapsi2 (dest_si, src_si));
2735 emit_insn (gen_bswapsi2 (op3_si, op2_si));
2736 emit_insn (gen_ashldi3 (dest, dest, GEN_INT (32)));
2737 emit_insn (gen_iordi3 (dest, dest, op3));
2741 (define_insn "bswapdi2_32bit"
2742 [(set (match_operand:DI 0 "reg_or_mem_operand" "=r,Z,?&r")
2743 (bswap:DI (match_operand:DI 1 "reg_or_mem_operand" "Z,r,r")))
2744 (clobber (match_scratch:SI 2 "=&b,&b,X"))]
2745 "!TARGET_POWERPC64 && (REG_P (operands[0]) || REG_P (operands[1]))"
2747 [(set_attr "length" "16,12,36")])
2750 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2751 (bswap:DI (match_operand:DI 1 "indexed_or_indirect_operand" "")))
2752 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2753 "!TARGET_POWERPC64 && reload_completed"
2757 rtx dest = operands[0];
2758 rtx src = operands[1];
2759 rtx op2 = operands[2];
2760 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2761 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2767 addr1 = XEXP (src, 0);
2768 if (GET_CODE (addr1) == PLUS)
2770 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2771 if (TARGET_AVOID_XFORM
2772 || REGNO (XEXP (addr1, 1)) == REGNO (dest2))
2774 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2778 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2780 else if (TARGET_AVOID_XFORM
2781 || REGNO (addr1) == REGNO (dest2))
2783 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2788 emit_move_insn (op2, GEN_INT (4));
2789 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2792 word1 = change_address (src, SImode, addr1);
2793 word2 = change_address (src, SImode, addr2);
2795 emit_insn (gen_bswapsi2 (dest2, word1));
2796 /* The REGNO (dest2) tests above ensure that addr2 has not been trashed,
2797 thus allowing us to omit an early clobber on the output. */
2798 emit_insn (gen_bswapsi2 (dest1, word2));
2803 [(set (match_operand:DI 0 "indexed_or_indirect_operand" "")
2804 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2805 (clobber (match_operand:SI 2 "gpc_reg_operand" ""))]
2806 "!TARGET_POWERPC64 && reload_completed"
2810 rtx dest = operands[0];
2811 rtx src = operands[1];
2812 rtx op2 = operands[2];
2813 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2814 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2820 addr1 = XEXP (dest, 0);
2821 if (GET_CODE (addr1) == PLUS)
2823 emit_insn (gen_add3_insn (op2, XEXP (addr1, 0), GEN_INT (4)));
2824 if (TARGET_AVOID_XFORM)
2826 emit_insn (gen_add3_insn (op2, XEXP (addr1, 1), op2));
2830 addr2 = gen_rtx_PLUS (SImode, op2, XEXP (addr1, 1));
2832 else if (TARGET_AVOID_XFORM)
2834 emit_insn (gen_add3_insn (op2, addr1, GEN_INT (4)));
2839 emit_move_insn (op2, GEN_INT (4));
2840 addr2 = gen_rtx_PLUS (SImode, op2, addr1);
2843 word1 = change_address (dest, SImode, addr1);
2844 word2 = change_address (dest, SImode, addr2);
2846 emit_insn (gen_bswapsi2 (word2, src1));
2847 emit_insn (gen_bswapsi2 (word1, src2));
2852 [(set (match_operand:DI 0 "gpc_reg_operand" "")
2853 (bswap:DI (match_operand:DI 1 "gpc_reg_operand" "")))
2854 (clobber (match_operand:SI 2 "" ""))]
2855 "!TARGET_POWERPC64 && reload_completed"
2859 rtx dest = operands[0];
2860 rtx src = operands[1];
2861 rtx src1 = simplify_gen_subreg (SImode, src, DImode, 0);
2862 rtx src2 = simplify_gen_subreg (SImode, src, DImode, 4);
2863 rtx dest1 = simplify_gen_subreg (SImode, dest, DImode, 0);
2864 rtx dest2 = simplify_gen_subreg (SImode, dest, DImode, 4);
2866 emit_insn (gen_bswapsi2 (dest1, src2));
2867 emit_insn (gen_bswapsi2 (dest2, src1));
2872 (define_insn "mul<mode>3"
2873 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2874 (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
2875 (match_operand:GPR 2 "reg_or_short_operand" "r,I")))]
2880 [(set_attr "type" "mul")
2882 (cond [(match_operand:GPR 2 "s8bit_cint_operand" "")
2884 (match_operand:GPR 2 "short_cint_operand" "")
2885 (const_string "16")]
2886 (const_string "<bits>")))])
2888 (define_insn_and_split "*mul<mode>3_dot"
2889 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2890 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2891 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2893 (clobber (match_scratch:GPR 0 "=r,r"))]
2894 "<MODE>mode == Pmode"
2898 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2900 (mult:GPR (match_dup 1)
2903 (compare:CC (match_dup 0)
2906 [(set_attr "type" "mul")
2907 (set_attr "size" "<bits>")
2908 (set_attr "dot" "yes")
2909 (set_attr "length" "4,8")])
2911 (define_insn_and_split "*mul<mode>3_dot2"
2912 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
2913 (compare:CC (mult:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
2914 (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
2916 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
2917 (mult:GPR (match_dup 1)
2919 "<MODE>mode == Pmode"
2923 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
2925 (mult:GPR (match_dup 1)
2928 (compare:CC (match_dup 0)
2931 [(set_attr "type" "mul")
2932 (set_attr "size" "<bits>")
2933 (set_attr "dot" "yes")
2934 (set_attr "length" "4,8")])
2937 (define_expand "<su>mul<mode>3_highpart"
2938 [(set (match_operand:GPR 0 "gpc_reg_operand")
2940 (mult:<DMODE> (any_extend:<DMODE>
2941 (match_operand:GPR 1 "gpc_reg_operand"))
2943 (match_operand:GPR 2 "gpc_reg_operand")))
2947 if (<MODE>mode == SImode && TARGET_POWERPC64)
2949 emit_insn (gen_<su>mulsi3_highpart_64 (operands[0], operands[1],
2954 if (!WORDS_BIG_ENDIAN)
2956 emit_insn (gen_<su>mul<mode>3_highpart_le (operands[0], operands[1],
2962 (define_insn "*<su>mul<mode>3_highpart"
2963 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
2965 (mult:<DMODE> (any_extend:<DMODE>
2966 (match_operand:GPR 1 "gpc_reg_operand" "r"))
2968 (match_operand:GPR 2 "gpc_reg_operand" "r")))
2970 "WORDS_BIG_ENDIAN && !(<MODE>mode == SImode && TARGET_POWERPC64)"
2971 "mulh<wd><u> %0,%1,%2"
2972 [(set_attr "type" "mul")
2973 (set_attr "size" "<bits>")])
2975 (define_insn "<su>mulsi3_highpart_le"
2976 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
2978 (mult:DI (any_extend:DI
2979 (match_operand:SI 1 "gpc_reg_operand" "r"))
2981 (match_operand:SI 2 "gpc_reg_operand" "r")))
2983 "!WORDS_BIG_ENDIAN && !TARGET_POWERPC64"
2985 [(set_attr "type" "mul")])
2987 (define_insn "<su>muldi3_highpart_le"
2988 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
2990 (mult:TI (any_extend:TI
2991 (match_operand:DI 1 "gpc_reg_operand" "r"))
2993 (match_operand:DI 2 "gpc_reg_operand" "r")))
2995 "!WORDS_BIG_ENDIAN && TARGET_POWERPC64"
2997 [(set_attr "type" "mul")
2998 (set_attr "size" "64")])
3000 (define_insn "<su>mulsi3_highpart_64"
3001 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
3004 (mult:DI (any_extend:DI
3005 (match_operand:SI 1 "gpc_reg_operand" "r"))
3007 (match_operand:SI 2 "gpc_reg_operand" "r")))
3011 [(set_attr "type" "mul")])
3013 (define_expand "<u>mul<mode><dmode>3"
3014 [(set (match_operand:<DMODE> 0 "gpc_reg_operand")
3015 (mult:<DMODE> (any_extend:<DMODE>
3016 (match_operand:GPR 1 "gpc_reg_operand"))
3018 (match_operand:GPR 2 "gpc_reg_operand"))))]
3019 "!(<MODE>mode == SImode && TARGET_POWERPC64)"
3021 rtx l = gen_reg_rtx (<MODE>mode);
3022 rtx h = gen_reg_rtx (<MODE>mode);
3023 emit_insn (gen_mul<mode>3 (l, operands[1], operands[2]));
3024 emit_insn (gen_<su>mul<mode>3_highpart (h, operands[1], operands[2]));
3025 emit_move_insn (gen_lowpart (<MODE>mode, operands[0]), l);
3026 emit_move_insn (gen_highpart (<MODE>mode, operands[0]), h);
3030 (define_insn "*maddld4"
3031 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3032 (plus:DI (mult:DI (match_operand:DI 1 "gpc_reg_operand" "r")
3033 (match_operand:DI 2 "gpc_reg_operand" "r"))
3034 (match_operand:DI 3 "gpc_reg_operand" "r")))]
3036 "maddld %0,%1,%2,%3"
3037 [(set_attr "type" "mul")])
3039 (define_insn "udiv<mode>3"
3040 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3041 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3042 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3045 [(set_attr "type" "div")
3046 (set_attr "size" "<bits>")])
3049 ;; For powers of two we can do sra[wd]i/addze for divide and then adjust for
3050 ;; modulus. If it isn't a power of two, force operands into register and do
3052 (define_expand "div<mode>3"
3053 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3054 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3055 (match_operand:GPR 2 "reg_or_cint_operand" "")))]
3058 if (CONST_INT_P (operands[2])
3059 && INTVAL (operands[2]) > 0
3060 && exact_log2 (INTVAL (operands[2])) >= 0)
3062 emit_insn (gen_div<mode>3_sra (operands[0], operands[1], operands[2]));
3066 operands[2] = force_reg (<MODE>mode, operands[2]);
3069 (define_insn "*div<mode>3"
3070 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3071 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3072 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3075 [(set_attr "type" "div")
3076 (set_attr "size" "<bits>")])
3078 (define_insn "div<mode>3_sra"
3079 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3080 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3081 (match_operand:GPR 2 "exact_log2_cint_operand" "N")))
3082 (clobber (reg:GPR CA_REGNO))]
3084 "sra<wd>i %0,%1,%p2\;addze %0,%0"
3085 [(set_attr "type" "two")
3086 (set_attr "length" "8")])
3088 (define_insn_and_split "*div<mode>3_sra_dot"
3089 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3090 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3091 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3093 (clobber (match_scratch:GPR 0 "=r,r"))
3094 (clobber (reg:GPR CA_REGNO))]
3095 "<MODE>mode == Pmode"
3097 sra<wd>i %0,%1,%p2\;addze. %0,%0
3099 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3100 [(parallel [(set (match_dup 0)
3101 (div:GPR (match_dup 1)
3103 (clobber (reg:GPR CA_REGNO))])
3105 (compare:CC (match_dup 0)
3108 [(set_attr "type" "two")
3109 (set_attr "length" "8,12")
3110 (set_attr "cell_micro" "not")])
3112 (define_insn_and_split "*div<mode>3_sra_dot2"
3113 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3114 (compare:CC (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
3115 (match_operand:GPR 2 "exact_log2_cint_operand" "N,N"))
3117 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3118 (div:GPR (match_dup 1)
3120 (clobber (reg:GPR CA_REGNO))]
3121 "<MODE>mode == Pmode"
3123 sra<wd>i %0,%1,%p2\;addze. %0,%0
3125 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3126 [(parallel [(set (match_dup 0)
3127 (div:GPR (match_dup 1)
3129 (clobber (reg:GPR CA_REGNO))])
3131 (compare:CC (match_dup 0)
3134 [(set_attr "type" "two")
3135 (set_attr "length" "8,12")
3136 (set_attr "cell_micro" "not")])
3138 (define_expand "mod<mode>3"
3139 [(set (match_operand:GPR 0 "gpc_reg_operand")
3140 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand")
3141 (match_operand:GPR 2 "reg_or_cint_operand")))]
3148 if (GET_CODE (operands[2]) != CONST_INT
3149 || INTVAL (operands[2]) <= 0
3150 || (i = exact_log2 (INTVAL (operands[2]))) < 0)
3155 operands[2] = force_reg (<MODE>mode, operands[2]);
3159 temp1 = gen_reg_rtx (<MODE>mode);
3160 temp2 = gen_reg_rtx (<MODE>mode);
3162 emit_insn (gen_div<mode>3 (temp1, operands[1], operands[2]));
3163 emit_insn (gen_ashl<mode>3 (temp2, temp1, GEN_INT (i)));
3164 emit_insn (gen_sub<mode>3 (operands[0], operands[1], temp2));
3169 ;; In order to enable using a peephole2 for combining div/mod to eliminate the
3170 ;; mod, prefer putting the result of mod into a different register
3171 (define_insn "*mod<mode>3"
3172 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3173 (mod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3174 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3177 [(set_attr "type" "div")
3178 (set_attr "size" "<bits>")])
3181 (define_insn "umod<mode>3"
3182 [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
3183 (umod:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3184 (match_operand:GPR 2 "gpc_reg_operand" "r")))]
3187 [(set_attr "type" "div")
3188 (set_attr "size" "<bits>")])
3190 ;; On machines with modulo support, do a combined div/mod the old fashioned
3191 ;; method, since the multiply/subtract is faster than doing the mod instruction
3195 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3196 (div:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3197 (match_operand:GPR 2 "gpc_reg_operand" "")))
3198 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3199 (mod:GPR (match_dup 1)
3202 && ! reg_mentioned_p (operands[0], operands[1])
3203 && ! reg_mentioned_p (operands[0], operands[2])
3204 && ! reg_mentioned_p (operands[3], operands[1])
3205 && ! reg_mentioned_p (operands[3], operands[2])"
3207 (div:GPR (match_dup 1)
3210 (mult:GPR (match_dup 0)
3213 (minus:GPR (match_dup 1)
3217 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3218 (udiv:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3219 (match_operand:GPR 2 "gpc_reg_operand" "")))
3220 (set (match_operand:GPR 3 "gpc_reg_operand" "")
3221 (umod:GPR (match_dup 1)
3224 && ! reg_mentioned_p (operands[0], operands[1])
3225 && ! reg_mentioned_p (operands[0], operands[2])
3226 && ! reg_mentioned_p (operands[3], operands[1])
3227 && ! reg_mentioned_p (operands[3], operands[2])"
3229 (udiv:GPR (match_dup 1)
3232 (mult:GPR (match_dup 0)
3235 (minus:GPR (match_dup 1)
3239 ;; Logical instructions
3240 ;; The logical instructions are mostly combined by using match_operator,
3241 ;; but the plain AND insns are somewhat different because there is no
3242 ;; plain 'andi' (only 'andi.'), no plain 'andis', and there are all
3243 ;; those rotate-and-mask operations. Thus, the AND insns come first.
3245 (define_expand "and<mode>3"
3246 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3247 (and:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3248 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3251 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3253 rs6000_split_logical (operands, AND, false, false, false);
3257 if (CONST_INT_P (operands[2]))
3259 if (rs6000_is_valid_and_mask (operands[2], <MODE>mode))
3261 emit_insn (gen_and<mode>3_mask (operands[0], operands[1], operands[2]));
3265 if (logical_const_operand (operands[2], <MODE>mode))
3267 emit_insn (gen_and<mode>3_imm (operands[0], operands[1], operands[2]));
3271 if (rs6000_is_valid_2insn_and (operands[2], <MODE>mode))
3273 rs6000_emit_2insn_and (<MODE>mode, operands, true, 0);
3277 operands[2] = force_reg (<MODE>mode, operands[2]);
3282 (define_insn "and<mode>3_imm"
3283 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3284 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3285 (match_operand:GPR 2 "logical_const_operand" "n")))
3286 (clobber (match_scratch:CC 3 "=x"))]
3287 "!rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3288 "andi%e2. %0,%1,%u2"
3289 [(set_attr "type" "logical")
3290 (set_attr "dot" "yes")])
3292 (define_insn_and_split "*and<mode>3_imm_dot"
3293 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3294 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3295 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3297 (clobber (match_scratch:GPR 0 "=r,r"))
3298 (clobber (match_scratch:CC 4 "=X,x"))]
3299 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3300 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3304 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3305 [(parallel [(set (match_dup 0)
3306 (and:GPR (match_dup 1)
3308 (clobber (match_dup 4))])
3310 (compare:CC (match_dup 0)
3313 [(set_attr "type" "logical")
3314 (set_attr "dot" "yes")
3315 (set_attr "length" "4,8")])
3317 (define_insn_and_split "*and<mode>3_imm_dot2"
3318 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3319 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3320 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3322 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3323 (and:GPR (match_dup 1)
3325 (clobber (match_scratch:CC 4 "=X,x"))]
3326 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3327 && !rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3331 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3332 [(parallel [(set (match_dup 0)
3333 (and:GPR (match_dup 1)
3335 (clobber (match_dup 4))])
3337 (compare:CC (match_dup 0)
3340 [(set_attr "type" "logical")
3341 (set_attr "dot" "yes")
3342 (set_attr "length" "4,8")])
3344 (define_insn_and_split "*and<mode>3_imm_mask_dot"
3345 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3346 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3347 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3349 (clobber (match_scratch:GPR 0 "=r,r"))]
3350 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3351 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3355 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3357 (and:GPR (match_dup 1)
3360 (compare:CC (match_dup 0)
3363 [(set_attr "type" "logical")
3364 (set_attr "dot" "yes")
3365 (set_attr "length" "4,8")])
3367 (define_insn_and_split "*and<mode>3_imm_mask_dot2"
3368 [(set (match_operand:CC 3 "cc_reg_operand" "=x,??y")
3369 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3370 (match_operand:GPR 2 "logical_const_operand" "n,n"))
3372 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3373 (and:GPR (match_dup 1)
3375 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3376 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3380 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3382 (and:GPR (match_dup 1)
3385 (compare:CC (match_dup 0)
3388 [(set_attr "type" "logical")
3389 (set_attr "dot" "yes")
3390 (set_attr "length" "4,8")])
3392 (define_insn "*and<mode>3_imm_dot_shifted"
3393 [(set (match_operand:CC 3 "cc_reg_operand" "=x")
3396 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3397 (match_operand:SI 4 "const_int_operand" "n"))
3398 (match_operand:GPR 2 "const_int_operand" "n"))
3400 (clobber (match_scratch:GPR 0 "=r"))]
3401 "logical_const_operand (GEN_INT (UINTVAL (operands[2])
3402 << INTVAL (operands[4])),
3404 && (<MODE>mode == Pmode
3405 || (UINTVAL (operands[2]) << INTVAL (operands[4])) <= 0x7fffffff)"
3407 operands[2] = GEN_INT (UINTVAL (operands[2]) << INTVAL (operands[4]));
3408 return "andi%e2. %0,%1,%u2";
3410 [(set_attr "type" "logical")
3411 (set_attr "dot" "yes")])
3414 (define_insn "and<mode>3_mask"
3415 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3416 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3417 (match_operand:GPR 2 "const_int_operand" "n")))]
3418 "rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3420 return rs6000_insn_for_and_mask (<MODE>mode, operands, false);
3422 [(set_attr "type" "shift")])
3424 (define_insn_and_split "*and<mode>3_mask_dot"
3425 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3426 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3427 (match_operand:GPR 2 "const_int_operand" "n,n"))
3429 (clobber (match_scratch:GPR 0 "=r,r"))]
3430 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3431 && !logical_const_operand (operands[2], <MODE>mode)
3432 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3434 if (which_alternative == 0)
3435 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3439 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3441 (and:GPR (match_dup 1)
3444 (compare:CC (match_dup 0)
3447 [(set_attr "type" "shift")
3448 (set_attr "dot" "yes")
3449 (set_attr "length" "4,8")])
3451 (define_insn_and_split "*and<mode>3_mask_dot2"
3452 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3453 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3454 (match_operand:GPR 2 "const_int_operand" "n,n"))
3456 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3457 (and:GPR (match_dup 1)
3459 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3460 && !logical_const_operand (operands[2], <MODE>mode)
3461 && rs6000_is_valid_and_mask (operands[2], <MODE>mode)"
3463 if (which_alternative == 0)
3464 return rs6000_insn_for_and_mask (<MODE>mode, operands, true);
3468 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
3470 (and:GPR (match_dup 1)
3473 (compare:CC (match_dup 0)
3476 [(set_attr "type" "shift")
3477 (set_attr "dot" "yes")
3478 (set_attr "length" "4,8")])
3481 (define_insn_and_split "*and<mode>3_2insn"
3482 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3483 (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r")
3484 (match_operand:GPR 2 "const_int_operand" "n")))]
3485 "rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3486 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3487 || logical_const_operand (operands[2], <MODE>mode))"
3492 rs6000_emit_2insn_and (<MODE>mode, operands, false, 0);
3495 [(set_attr "type" "shift")
3496 (set_attr "length" "8")])
3498 (define_insn_and_split "*and<mode>3_2insn_dot"
3499 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3500 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3501 (match_operand:GPR 2 "const_int_operand" "n,n"))
3503 (clobber (match_scratch:GPR 0 "=r,r"))]
3504 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3505 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3506 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3507 || logical_const_operand (operands[2], <MODE>mode))"
3509 "&& reload_completed"
3512 rs6000_emit_2insn_and (<MODE>mode, operands, false, 1);
3515 [(set_attr "type" "shift")
3516 (set_attr "dot" "yes")
3517 (set_attr "length" "8,12")])
3519 (define_insn_and_split "*and<mode>3_2insn_dot2"
3520 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
3521 (compare:CC (and:GPR (match_operand:GPR 1 "gpc_reg_operand" "%r,r")
3522 (match_operand:GPR 2 "const_int_operand" "n,n"))
3524 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3525 (and:GPR (match_dup 1)
3527 "(<MODE>mode == Pmode || UINTVAL (operands[2]) <= 0x7fffffff)
3528 && rs6000_is_valid_2insn_and (operands[2], <MODE>mode)
3529 && !(rs6000_is_valid_and_mask (operands[2], <MODE>mode)
3530 || logical_const_operand (operands[2], <MODE>mode))"
3532 "&& reload_completed"
3535 rs6000_emit_2insn_and (<MODE>mode, operands, false, 2);
3538 [(set_attr "type" "shift")
3539 (set_attr "dot" "yes")
3540 (set_attr "length" "8,12")])
3543 (define_expand "<code><mode>3"
3544 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
3545 (iorxor:SDI (match_operand:SDI 1 "gpc_reg_operand" "")
3546 (match_operand:SDI 2 "reg_or_cint_operand" "")))]
3549 if (<MODE>mode == DImode && !TARGET_POWERPC64)
3551 rs6000_split_logical (operands, <CODE>, false, false, false);
3555 if (non_logical_cint_operand (operands[2], <MODE>mode))
3557 rtx tmp = ((!can_create_pseudo_p ()
3558 || rtx_equal_p (operands[0], operands[1]))
3559 ? operands[0] : gen_reg_rtx (<MODE>mode));
3561 HOST_WIDE_INT value = INTVAL (operands[2]);
3562 HOST_WIDE_INT lo = value & 0xffff;
3563 HOST_WIDE_INT hi = value - lo;
3565 emit_insn (gen_<code><mode>3 (tmp, operands[1], GEN_INT (hi)));
3566 emit_insn (gen_<code><mode>3 (operands[0], tmp, GEN_INT (lo)));
3570 if (!reg_or_logical_cint_operand (operands[2], <MODE>mode))
3571 operands[2] = force_reg (<MODE>mode, operands[2]);
3575 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
3576 (iorxor:GPR (match_operand:GPR 1 "gpc_reg_operand" "")
3577 (match_operand:GPR 2 "non_logical_cint_operand" "")))]
3580 (iorxor:GPR (match_dup 1)
3583 (iorxor:GPR (match_dup 3)
3586 operands[3] = ((!can_create_pseudo_p ()
3587 || rtx_equal_p (operands[0], operands[1]))
3588 ? operands[0] : gen_reg_rtx (<MODE>mode));
3590 HOST_WIDE_INT value = INTVAL (operands[2]);
3591 HOST_WIDE_INT lo = value & 0xffff;
3592 HOST_WIDE_INT hi = value - lo;
3594 operands[4] = GEN_INT (hi);
3595 operands[5] = GEN_INT (lo);
3598 (define_insn "*bool<mode>3_imm"
3599 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3600 (match_operator:GPR 3 "boolean_or_operator"
3601 [(match_operand:GPR 1 "gpc_reg_operand" "%r")
3602 (match_operand:GPR 2 "logical_const_operand" "n")]))]
3605 [(set_attr "type" "logical")])
3607 (define_insn "*bool<mode>3"
3608 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3609 (match_operator:GPR 3 "boolean_operator"
3610 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3611 (match_operand:GPR 2 "gpc_reg_operand" "r")]))]
3614 [(set_attr "type" "logical")])
3616 (define_insn_and_split "*bool<mode>3_dot"
3617 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3618 (compare:CC (match_operator:GPR 3 "boolean_operator"
3619 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3620 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3622 (clobber (match_scratch:GPR 0 "=r,r"))]
3623 "<MODE>mode == Pmode"
3627 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3631 (compare:CC (match_dup 0)
3634 [(set_attr "type" "logical")
3635 (set_attr "dot" "yes")
3636 (set_attr "length" "4,8")])
3638 (define_insn_and_split "*bool<mode>3_dot2"
3639 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3640 (compare:CC (match_operator:GPR 3 "boolean_operator"
3641 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3642 (match_operand:GPR 2 "gpc_reg_operand" "r,r")])
3644 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3646 "<MODE>mode == Pmode"
3650 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3654 (compare:CC (match_dup 0)
3657 [(set_attr "type" "logical")
3658 (set_attr "dot" "yes")
3659 (set_attr "length" "4,8")])
3662 (define_insn "*boolc<mode>3"
3663 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3664 (match_operator:GPR 3 "boolean_operator"
3665 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))
3666 (match_operand:GPR 1 "gpc_reg_operand" "r")]))]
3669 [(set_attr "type" "logical")])
3671 (define_insn_and_split "*boolc<mode>3_dot"
3672 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3673 (compare:CC (match_operator:GPR 3 "boolean_operator"
3674 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3675 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3677 (clobber (match_scratch:GPR 0 "=r,r"))]
3678 "<MODE>mode == Pmode"
3682 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3686 (compare:CC (match_dup 0)
3689 [(set_attr "type" "logical")
3690 (set_attr "dot" "yes")
3691 (set_attr "length" "4,8")])
3693 (define_insn_and_split "*boolc<mode>3_dot2"
3694 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3695 (compare:CC (match_operator:GPR 3 "boolean_operator"
3696 [(not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))
3697 (match_operand:GPR 1 "gpc_reg_operand" "r,r")])
3699 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3701 "<MODE>mode == Pmode"
3705 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3709 (compare:CC (match_dup 0)
3712 [(set_attr "type" "logical")
3713 (set_attr "dot" "yes")
3714 (set_attr "length" "4,8")])
3717 (define_insn "*boolcc<mode>3"
3718 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3719 (match_operator:GPR 3 "boolean_operator"
3720 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
3721 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r"))]))]
3724 [(set_attr "type" "logical")])
3726 (define_insn_and_split "*boolcc<mode>3_dot"
3727 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3728 (compare:CC (match_operator:GPR 3 "boolean_operator"
3729 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3730 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3732 (clobber (match_scratch:GPR 0 "=r,r"))]
3733 "<MODE>mode == Pmode"
3737 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3741 (compare:CC (match_dup 0)
3744 [(set_attr "type" "logical")
3745 (set_attr "dot" "yes")
3746 (set_attr "length" "4,8")])
3748 (define_insn_and_split "*boolcc<mode>3_dot2"
3749 [(set (match_operand:CC 4 "cc_reg_operand" "=x,?y")
3750 (compare:CC (match_operator:GPR 3 "boolean_operator"
3751 [(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r"))
3752 (not:GPR (match_operand:GPR 2 "gpc_reg_operand" "r,r"))])
3754 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3756 "<MODE>mode == Pmode"
3760 "&& reload_completed && cc_reg_not_cr0_operand (operands[4], CCmode)"
3764 (compare:CC (match_dup 0)
3767 [(set_attr "type" "logical")
3768 (set_attr "dot" "yes")
3769 (set_attr "length" "4,8")])
3772 ;; TODO: Should have dots of this as well.
3773 (define_insn "*eqv<mode>3"
3774 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3775 (not:GPR (xor:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3776 (match_operand:GPR 2 "gpc_reg_operand" "r"))))]
3779 [(set_attr "type" "logical")])
3781 ;; Rotate-and-mask and insert.
3783 (define_insn "*rotl<mode>3_mask"
3784 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3785 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3786 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3787 (match_operand:SI 2 "reg_or_cint_operand" "rn")])
3788 (match_operand:GPR 3 "const_int_operand" "n")))]
3789 "rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3791 return rs6000_insn_for_shift_mask (<MODE>mode, operands, false);
3793 [(set_attr "type" "shift")
3794 (set_attr "maybe_var_shift" "yes")])
3796 (define_insn_and_split "*rotl<mode>3_mask_dot"
3797 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3799 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3800 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3801 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3802 (match_operand:GPR 3 "const_int_operand" "n,n"))
3804 (clobber (match_scratch:GPR 0 "=r,r"))]
3805 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3806 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3808 if (which_alternative == 0)
3809 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3813 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3815 (and:GPR (match_dup 4)
3818 (compare:CC (match_dup 0)
3821 [(set_attr "type" "shift")
3822 (set_attr "maybe_var_shift" "yes")
3823 (set_attr "dot" "yes")
3824 (set_attr "length" "4,8")])
3826 (define_insn_and_split "*rotl<mode>3_mask_dot2"
3827 [(set (match_operand:CC 5 "cc_reg_operand" "=x,?y")
3829 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3830 [(match_operand:GPR 1 "gpc_reg_operand" "r,r")
3831 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn")])
3832 (match_operand:GPR 3 "const_int_operand" "n,n"))
3834 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
3835 (and:GPR (match_dup 4)
3837 "(<MODE>mode == Pmode || UINTVAL (operands[3]) <= 0x7fffffff)
3838 && rs6000_is_valid_shift_mask (operands[3], operands[4], <MODE>mode)"
3840 if (which_alternative == 0)
3841 return rs6000_insn_for_shift_mask (<MODE>mode, operands, true);
3845 "&& reload_completed && cc_reg_not_cr0_operand (operands[5], CCmode)"
3847 (and:GPR (match_dup 4)
3850 (compare:CC (match_dup 0)
3853 [(set_attr "type" "shift")
3854 (set_attr "maybe_var_shift" "yes")
3855 (set_attr "dot" "yes")
3856 (set_attr "length" "4,8")])
3858 ; Special case for less-than-0. We can do it with just one machine
3859 ; instruction, but the generic optimizers do not realise it is cheap.
3860 (define_insn "*lt0_<mode>di"
3861 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3862 (lt:GPR (match_operand:DI 1 "gpc_reg_operand" "r")
3866 [(set_attr "type" "shift")])
3868 (define_insn "*lt0_<mode>si"
3869 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3870 (lt:GPR (match_operand:SI 1 "gpc_reg_operand" "r")
3873 "rlwinm %0,%1,1,31,31"
3874 [(set_attr "type" "shift")])
3878 ; Two forms for insert (the two arms of the IOR are not canonicalized,
3879 ; both are an AND so are the same precedence).
3880 (define_insn "*rotl<mode>3_insert"
3881 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3882 (ior:GPR (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3883 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3884 (match_operand:SI 2 "const_int_operand" "n")])
3885 (match_operand:GPR 3 "const_int_operand" "n"))
3886 (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3887 (match_operand:GPR 6 "const_int_operand" "n"))))]
3888 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3889 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3891 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3893 [(set_attr "type" "insert")])
3894 ; FIXME: this needs an attr "size", so that the scheduler can see the
3895 ; difference between rlwimi and rldimi. We also might want dot forms,
3896 ; but not for rlwimi on POWER4 and similar processors.
3898 (define_insn "*rotl<mode>3_insert_2"
3899 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3900 (ior:GPR (and:GPR (match_operand:GPR 5 "gpc_reg_operand" "0")
3901 (match_operand:GPR 6 "const_int_operand" "n"))
3902 (and:GPR (match_operator:GPR 4 "rotate_mask_operator"
3903 [(match_operand:GPR 1 "gpc_reg_operand" "r")
3904 (match_operand:SI 2 "const_int_operand" "n")])
3905 (match_operand:GPR 3 "const_int_operand" "n"))))]
3906 "rs6000_is_valid_insert_mask (operands[3], operands[4], <MODE>mode)
3907 && UINTVAL (operands[3]) + UINTVAL (operands[6]) + 1 == 0"
3909 return rs6000_insn_for_insert_mask (<MODE>mode, operands, false);
3911 [(set_attr "type" "insert")])
3913 ; There are also some forms without one of the ANDs.
3914 (define_insn "*rotl<mode>3_insert_3"
3915 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3916 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3917 (match_operand:GPR 4 "const_int_operand" "n"))
3918 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3919 (match_operand:SI 2 "const_int_operand" "n"))))]
3920 "INTVAL (operands[2]) == exact_log2 (UINTVAL (operands[4]) + 1)"
3922 if (<MODE>mode == SImode)
3923 return "rlwimi %0,%1,%h2,0,31-%h2";
3925 return "rldimi %0,%1,%H2,0";
3927 [(set_attr "type" "insert")])
3929 (define_insn "*rotl<mode>3_insert_4"
3930 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
3931 (ior:GPR (and:GPR (match_operand:GPR 3 "gpc_reg_operand" "0")
3932 (match_operand:GPR 4 "const_int_operand" "n"))
3933 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
3934 (match_operand:SI 2 "const_int_operand" "n"))))]
3935 "<MODE>mode == SImode &&
3936 GET_MODE_PRECISION (<MODE>mode)
3937 == INTVAL (operands[2]) + exact_log2 (-UINTVAL (operands[4]))"
3939 operands[2] = GEN_INT (GET_MODE_PRECISION (<MODE>mode)
3940 - INTVAL (operands[2]));
3941 if (<MODE>mode == SImode)
3942 return "rlwimi %0,%1,%h2,32-%h2,31";
3944 return "rldimi %0,%1,%H2,64-%H2";
3946 [(set_attr "type" "insert")])
3948 (define_insn "*rotlsi3_insert_5"
3949 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
3950 (ior:SI (and:SI (match_operand:SI 1 "gpc_reg_operand" "0,r")
3951 (match_operand:SI 2 "const_int_operand" "n,n"))
3952 (and:SI (match_operand:SI 3 "gpc_reg_operand" "r,0")
3953 (match_operand:SI 4 "const_int_operand" "n,n"))))]
3954 "rs6000_is_valid_mask (operands[2], NULL, NULL, SImode)
3955 && UINTVAL (operands[2]) != 0 && UINTVAL (operands[4]) != 0
3956 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3960 [(set_attr "type" "insert")])
3962 (define_insn "*rotldi3_insert_6"
3963 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3964 (ior:DI (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3965 (match_operand:DI 2 "const_int_operand" "n"))
3966 (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3967 (match_operand:DI 4 "const_int_operand" "n"))))]
3968 "exact_log2 (-UINTVAL (operands[2])) > 0
3969 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3971 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3972 return "rldimi %0,%3,0,%5";
3974 [(set_attr "type" "insert")
3975 (set_attr "size" "64")])
3977 (define_insn "*rotldi3_insert_7"
3978 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
3979 (ior:DI (and:DI (match_operand:DI 3 "gpc_reg_operand" "r")
3980 (match_operand:DI 4 "const_int_operand" "n"))
3981 (and:DI (match_operand:DI 1 "gpc_reg_operand" "0")
3982 (match_operand:DI 2 "const_int_operand" "n"))))]
3983 "exact_log2 (-UINTVAL (operands[2])) > 0
3984 && UINTVAL (operands[2]) + UINTVAL (operands[4]) + 1 == 0"
3986 operands[5] = GEN_INT (64 - exact_log2 (-UINTVAL (operands[2])));
3987 return "rldimi %0,%3,0,%5";
3989 [(set_attr "type" "insert")
3990 (set_attr "size" "64")])
3993 ; This handles the important case of multiple-precision shifts. There is
3994 ; no canonicalization rule for ASHIFT vs. LSHIFTRT, so two patterns.
3996 [(set (match_operand:GPR 0 "gpc_reg_operand")
3997 (ior:GPR (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
3998 (match_operand:SI 3 "const_int_operand"))
3999 (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4000 (match_operand:SI 4 "const_int_operand"))))]
4001 "can_create_pseudo_p ()
4002 && INTVAL (operands[3]) + INTVAL (operands[4])
4003 >= GET_MODE_PRECISION (<MODE>mode)"
4005 (lshiftrt:GPR (match_dup 2)
4008 (ior:GPR (and:GPR (match_dup 5)
4010 (ashift:GPR (match_dup 1)
4013 unsigned HOST_WIDE_INT mask = 1;
4014 mask = (mask << INTVAL (operands[3])) - 1;
4015 operands[5] = gen_reg_rtx (<MODE>mode);
4016 operands[6] = GEN_INT (mask);
4020 [(set (match_operand:GPR 0 "gpc_reg_operand")
4021 (ior:GPR (lshiftrt:GPR (match_operand:GPR 2 "gpc_reg_operand")
4022 (match_operand:SI 4 "const_int_operand"))
4023 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand")
4024 (match_operand:SI 3 "const_int_operand"))))]
4025 "can_create_pseudo_p ()
4026 && INTVAL (operands[3]) + INTVAL (operands[4])
4027 >= GET_MODE_PRECISION (<MODE>mode)"
4029 (lshiftrt:GPR (match_dup 2)
4032 (ior:GPR (and:GPR (match_dup 5)
4034 (ashift:GPR (match_dup 1)
4037 unsigned HOST_WIDE_INT mask = 1;
4038 mask = (mask << INTVAL (operands[3])) - 1;
4039 operands[5] = gen_reg_rtx (<MODE>mode);
4040 operands[6] = GEN_INT (mask);
4044 ; Another important case is setting some bits to 1; we can do that with
4045 ; an insert instruction, in many cases.
4046 (define_insn_and_split "*ior<mode>_mask"
4047 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4048 (ior:GPR (match_operand:GPR 1 "gpc_reg_operand" "0")
4049 (match_operand:GPR 2 "const_int_operand" "n")))
4050 (clobber (match_scratch:GPR 3 "=r"))]
4051 "!logical_const_operand (operands[2], <MODE>mode)
4052 && rs6000_is_valid_mask (operands[2], NULL, NULL, <MODE>mode)"
4058 (ior:GPR (and:GPR (rotate:GPR (match_dup 3)
4061 (and:GPR (match_dup 1)
4065 rs6000_is_valid_mask (operands[2], &nb, &ne, <MODE>mode);
4066 if (GET_CODE (operands[3]) == SCRATCH)
4067 operands[3] = gen_reg_rtx (<MODE>mode);
4068 operands[4] = GEN_INT (ne);
4069 operands[5] = GEN_INT (~UINTVAL (operands[2]));
4071 [(set_attr "type" "two")
4072 (set_attr "length" "8")])
4075 ;; Now the simple shifts.
4077 (define_insn "rotl<mode>3"
4078 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4079 (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4080 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4082 "rotl<wd>%I2 %0,%1,%<hH>2"
4083 [(set_attr "type" "shift")
4084 (set_attr "maybe_var_shift" "yes")])
4086 (define_insn "*rotlsi3_64"
4087 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4089 (rotate:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4090 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4092 "rotlw%I2 %0,%1,%h2"
4093 [(set_attr "type" "shift")
4094 (set_attr "maybe_var_shift" "yes")])
4096 (define_insn_and_split "*rotl<mode>3_dot"
4097 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4098 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4099 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4101 (clobber (match_scratch:GPR 0 "=r,r"))]
4102 "<MODE>mode == Pmode"
4104 rotl<wd>%I2. %0,%1,%<hH>2
4106 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4108 (rotate:GPR (match_dup 1)
4111 (compare:CC (match_dup 0)
4114 [(set_attr "type" "shift")
4115 (set_attr "maybe_var_shift" "yes")
4116 (set_attr "dot" "yes")
4117 (set_attr "length" "4,8")])
4119 (define_insn_and_split "*rotl<mode>3_dot2"
4120 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4121 (compare:CC (rotate:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4122 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4124 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4125 (rotate:GPR (match_dup 1)
4127 "<MODE>mode == Pmode"
4129 rotl<wd>%I2. %0,%1,%<hH>2
4131 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4133 (rotate:GPR (match_dup 1)
4136 (compare:CC (match_dup 0)
4139 [(set_attr "type" "shift")
4140 (set_attr "maybe_var_shift" "yes")
4141 (set_attr "dot" "yes")
4142 (set_attr "length" "4,8")])
4145 (define_insn "ashl<mode>3"
4146 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4147 (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4148 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4150 "sl<wd>%I2 %0,%1,%<hH>2"
4151 [(set_attr "type" "shift")
4152 (set_attr "maybe_var_shift" "yes")])
4154 (define_insn "*ashlsi3_64"
4155 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4157 (ashift:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4158 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4161 [(set_attr "type" "shift")
4162 (set_attr "maybe_var_shift" "yes")])
4164 (define_insn_and_split "*ashl<mode>3_dot"
4165 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4166 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4167 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4169 (clobber (match_scratch:GPR 0 "=r,r"))]
4170 "<MODE>mode == Pmode"
4172 sl<wd>%I2. %0,%1,%<hH>2
4174 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4176 (ashift:GPR (match_dup 1)
4179 (compare:CC (match_dup 0)
4182 [(set_attr "type" "shift")
4183 (set_attr "maybe_var_shift" "yes")
4184 (set_attr "dot" "yes")
4185 (set_attr "length" "4,8")])
4187 (define_insn_and_split "*ashl<mode>3_dot2"
4188 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4189 (compare:CC (ashift:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4190 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4192 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4193 (ashift:GPR (match_dup 1)
4195 "<MODE>mode == Pmode"
4197 sl<wd>%I2. %0,%1,%<hH>2
4199 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4201 (ashift:GPR (match_dup 1)
4204 (compare:CC (match_dup 0)
4207 [(set_attr "type" "shift")
4208 (set_attr "maybe_var_shift" "yes")
4209 (set_attr "dot" "yes")
4210 (set_attr "length" "4,8")])
4212 ;; Pretend we have a memory form of extswsli until register allocation is done
4213 ;; so that we use LWZ to load the value from memory, instead of LWA.
4214 (define_insn_and_split "ashdi3_extswsli"
4215 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r")
4217 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,m"))
4218 (match_operand:DI 2 "u6bit_cint_operand" "n,n")))]
4223 "&& reload_completed && MEM_P (operands[1])"
4227 (ashift:DI (sign_extend:DI (match_dup 3))
4230 operands[3] = gen_lowpart (SImode, operands[0]);
4232 [(set_attr "type" "shift")
4233 (set_attr "maybe_var_shift" "no")])
4236 (define_insn_and_split "ashdi3_extswsli_dot"
4237 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4240 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4241 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4243 (clobber (match_scratch:DI 0 "=r,r,r,r"))]
4250 "&& reload_completed
4251 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4252 || memory_operand (operands[1], SImode))"
4255 rtx dest = operands[0];
4256 rtx src = operands[1];
4257 rtx shift = operands[2];
4258 rtx cr = operands[3];
4265 src2 = gen_lowpart (SImode, dest);
4266 emit_move_insn (src2, src);
4269 if (REGNO (cr) == CR0_REGNO)
4271 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4275 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4276 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4279 [(set_attr "type" "shift")
4280 (set_attr "maybe_var_shift" "no")
4281 (set_attr "dot" "yes")
4282 (set_attr "length" "4,8,8,12")])
4284 (define_insn_and_split "ashdi3_extswsli_dot2"
4285 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y,?x,??y")
4288 (sign_extend:DI (match_operand:SI 1 "reg_or_mem_operand" "r,r,m,m"))
4289 (match_operand:DI 2 "u6bit_cint_operand" "n,n,n,n"))
4291 (set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r,r")
4292 (ashift:DI (sign_extend:DI (match_dup 1))
4300 "&& reload_completed
4301 && (cc_reg_not_cr0_operand (operands[3], CCmode)
4302 || memory_operand (operands[1], SImode))"
4305 rtx dest = operands[0];
4306 rtx src = operands[1];
4307 rtx shift = operands[2];
4308 rtx cr = operands[3];
4315 src2 = gen_lowpart (SImode, dest);
4316 emit_move_insn (src2, src);
4319 if (REGNO (cr) == CR0_REGNO)
4321 emit_insn (gen_ashdi3_extswsli_dot2 (dest, src2, shift, cr));
4325 emit_insn (gen_ashdi3_extswsli (dest, src2, shift));
4326 emit_insn (gen_rtx_SET (cr, gen_rtx_COMPARE (CCmode, dest, const0_rtx)));
4329 [(set_attr "type" "shift")
4330 (set_attr "maybe_var_shift" "no")
4331 (set_attr "dot" "yes")
4332 (set_attr "length" "4,8,8,12")])
4334 (define_insn "lshr<mode>3"
4335 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4336 (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4337 (match_operand:SI 2 "reg_or_cint_operand" "rn")))]
4339 "sr<wd>%I2 %0,%1,%<hH>2"
4340 [(set_attr "type" "shift")
4341 (set_attr "maybe_var_shift" "yes")])
4343 (define_insn "*lshrsi3_64"
4344 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4346 (lshiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4347 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))]
4350 [(set_attr "type" "shift")
4351 (set_attr "maybe_var_shift" "yes")])
4353 (define_insn_and_split "*lshr<mode>3_dot"
4354 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4355 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4356 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4358 (clobber (match_scratch:GPR 0 "=r,r"))]
4359 "<MODE>mode == Pmode"
4361 sr<wd>%I2. %0,%1,%<hH>2
4363 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4365 (lshiftrt:GPR (match_dup 1)
4368 (compare:CC (match_dup 0)
4371 [(set_attr "type" "shift")
4372 (set_attr "maybe_var_shift" "yes")
4373 (set_attr "dot" "yes")
4374 (set_attr "length" "4,8")])
4376 (define_insn_and_split "*lshr<mode>3_dot2"
4377 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4378 (compare:CC (lshiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4379 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4381 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4382 (lshiftrt:GPR (match_dup 1)
4384 "<MODE>mode == Pmode"
4386 sr<wd>%I2. %0,%1,%<hH>2
4388 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4390 (lshiftrt:GPR (match_dup 1)
4393 (compare:CC (match_dup 0)
4396 [(set_attr "type" "shift")
4397 (set_attr "maybe_var_shift" "yes")
4398 (set_attr "dot" "yes")
4399 (set_attr "length" "4,8")])
4402 (define_insn "ashr<mode>3"
4403 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
4404 (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
4405 (match_operand:SI 2 "reg_or_cint_operand" "rn")))
4406 (clobber (reg:GPR CA_REGNO))]
4408 "sra<wd>%I2 %0,%1,%<hH>2"
4409 [(set_attr "type" "shift")
4410 (set_attr "maybe_var_shift" "yes")])
4412 (define_insn "*ashrsi3_64"
4413 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4415 (ashiftrt:SI (match_operand:SI 1 "gpc_reg_operand" "r")
4416 (match_operand:SI 2 "reg_or_cint_operand" "rn"))))
4417 (clobber (reg:SI CA_REGNO))]
4420 [(set_attr "type" "shift")
4421 (set_attr "maybe_var_shift" "yes")])
4423 (define_insn_and_split "*ashr<mode>3_dot"
4424 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4425 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4426 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4428 (clobber (match_scratch:GPR 0 "=r,r"))
4429 (clobber (reg:GPR CA_REGNO))]
4430 "<MODE>mode == Pmode"
4432 sra<wd>%I2. %0,%1,%<hH>2
4434 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4435 [(parallel [(set (match_dup 0)
4436 (ashiftrt:GPR (match_dup 1)
4438 (clobber (reg:GPR CA_REGNO))])
4440 (compare:CC (match_dup 0)
4443 [(set_attr "type" "shift")
4444 (set_attr "maybe_var_shift" "yes")
4445 (set_attr "dot" "yes")
4446 (set_attr "length" "4,8")])
4448 (define_insn_and_split "*ashr<mode>3_dot2"
4449 [(set (match_operand:CC 3 "cc_reg_operand" "=x,?y")
4450 (compare:CC (ashiftrt:GPR (match_operand:GPR 1 "gpc_reg_operand" "r,r")
4451 (match_operand:SI 2 "reg_or_cint_operand" "rn,rn"))
4453 (set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4454 (ashiftrt:GPR (match_dup 1)
4456 (clobber (reg:GPR CA_REGNO))]
4457 "<MODE>mode == Pmode"
4459 sra<wd>%I2. %0,%1,%<hH>2
4461 "&& reload_completed && cc_reg_not_cr0_operand (operands[3], CCmode)"
4462 [(parallel [(set (match_dup 0)
4463 (ashiftrt:GPR (match_dup 1)
4465 (clobber (reg:GPR CA_REGNO))])
4467 (compare:CC (match_dup 0)
4470 [(set_attr "type" "shift")
4471 (set_attr "maybe_var_shift" "yes")
4472 (set_attr "dot" "yes")
4473 (set_attr "length" "4,8")])
4475 ;; Builtins to replace a division to generate FRE reciprocal estimate
4476 ;; instructions and the necessary fixup instructions
4477 (define_expand "recip<mode>3"
4478 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4479 (match_operand:RECIPF 1 "gpc_reg_operand" "")
4480 (match_operand:RECIPF 2 "gpc_reg_operand" "")]
4481 "RS6000_RECIP_HAVE_RE_P (<MODE>mode)"
4483 rs6000_emit_swdiv (operands[0], operands[1], operands[2], false);
4487 ;; Split to create division from FRE/FRES/etc. and fixup instead of the normal
4488 ;; hardware division. This is only done before register allocation and with
4489 ;; -ffast-math. This must appear before the divsf3/divdf3 insns.
4490 ;; We used to also check optimize_insn_for_speed_p () but problems with guessed
4491 ;; frequencies (pr68212/pr77536) yields that unreliable so it was removed.
4493 [(set (match_operand:RECIPF 0 "gpc_reg_operand" "")
4494 (div:RECIPF (match_operand 1 "gpc_reg_operand" "")
4495 (match_operand 2 "gpc_reg_operand" "")))]
4496 "RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4497 && can_create_pseudo_p () && flag_finite_math_only
4498 && !flag_trapping_math && flag_reciprocal_math"
4501 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4505 ;; Builtins to replace 1/sqrt(x) with instructions using RSQRTE and the
4506 ;; appropriate fixup.
4507 (define_expand "rsqrt<mode>2"
4508 [(match_operand:RECIPF 0 "gpc_reg_operand" "")
4509 (match_operand:RECIPF 1 "gpc_reg_operand" "")]
4510 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4512 rs6000_emit_swsqrt (operands[0], operands[1], 1);
4516 ;; Floating-point insns, excluding normal data motion. We combine the SF/DF
4517 ;; modes here, and also add in conditional vsx/power8-vector support to access
4518 ;; values in the traditional Altivec registers if the appropriate
4519 ;; -mupper-regs-{df,sf} option is enabled.
4521 (define_expand "abs<mode>2"
4522 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4523 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4524 "TARGET_<MODE>_INSN"
4527 (define_insn "*abs<mode>2_fpr"
4528 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4529 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4534 [(set_attr "type" "fpsimple")
4535 (set_attr "fp_type" "fp_addsub_<Fs>")])
4537 (define_insn "*nabs<mode>2_fpr"
4538 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4541 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))))]
4546 [(set_attr "type" "fpsimple")
4547 (set_attr "fp_type" "fp_addsub_<Fs>")])
4549 (define_expand "neg<mode>2"
4550 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4551 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4552 "TARGET_<MODE>_INSN"
4555 (define_insn "*neg<mode>2_fpr"
4556 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4557 (neg:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
4562 [(set_attr "type" "fpsimple")
4563 (set_attr "fp_type" "fp_addsub_<Fs>")])
4565 (define_expand "add<mode>3"
4566 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4567 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4568 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4569 "TARGET_<MODE>_INSN"
4572 (define_insn "*add<mode>3_fpr"
4573 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4574 (plus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4575 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4578 fadd<Ftrad> %0,%1,%2
4579 xsadd<Fvsx> %x0,%x1,%x2"
4580 [(set_attr "type" "fp")
4581 (set_attr "fp_type" "fp_addsub_<Fs>")])
4583 (define_expand "sub<mode>3"
4584 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4585 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4586 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4587 "TARGET_<MODE>_INSN"
4590 (define_insn "*sub<mode>3_fpr"
4591 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4592 (minus:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4593 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4596 fsub<Ftrad> %0,%1,%2
4597 xssub<Fvsx> %x0,%x1,%x2"
4598 [(set_attr "type" "fp")
4599 (set_attr "fp_type" "fp_addsub_<Fs>")])
4601 (define_expand "mul<mode>3"
4602 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4603 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4604 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4605 "TARGET_<MODE>_INSN"
4608 (define_insn "*mul<mode>3_fpr"
4609 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4610 (mult:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>")
4611 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4614 fmul<Ftrad> %0,%1,%2
4615 xsmul<Fvsx> %x0,%x1,%x2"
4616 [(set_attr "type" "dmul")
4617 (set_attr "fp_type" "fp_mul_<Fs>")])
4619 (define_expand "div<mode>3"
4620 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4621 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4622 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4623 "TARGET_<MODE>_INSN && !TARGET_SIMPLE_FPU"
4625 if (RS6000_RECIP_AUTO_RE_P (<MODE>mode)
4626 && can_create_pseudo_p () && flag_finite_math_only
4627 && !flag_trapping_math && flag_reciprocal_math)
4629 rs6000_emit_swdiv (operands[0], operands[1], operands[2], true);
4634 (define_insn "*div<mode>3_fpr"
4635 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4636 (div:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4637 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4638 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU"
4640 fdiv<Ftrad> %0,%1,%2
4641 xsdiv<Fvsx> %x0,%x1,%x2"
4642 [(set_attr "type" "<Fs>div")
4643 (set_attr "fp_type" "fp_div_<Fs>")])
4645 (define_insn "*sqrt<mode>2_internal"
4646 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4647 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4648 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4649 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4652 xssqrt<Fvsx> %x0,%x1"
4653 [(set_attr "type" "<Fs>sqrt")
4654 (set_attr "fp_type" "fp_sqrt_<Fs>")])
4656 (define_expand "sqrt<mode>2"
4657 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4658 (sqrt:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))]
4659 "TARGET_<MODE>_FPR && !TARGET_SIMPLE_FPU
4660 && (TARGET_PPC_GPOPT || (<MODE>mode == SFmode && TARGET_XILINX_FPU))"
4662 if (<MODE>mode == SFmode
4663 && TARGET_RECIP_PRECISION
4664 && RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)
4665 && !optimize_function_for_size_p (cfun)
4666 && flag_finite_math_only && !flag_trapping_math
4667 && flag_unsafe_math_optimizations)
4669 rs6000_emit_swsqrt (operands[0], operands[1], 0);
4674 ;; Floating point reciprocal approximation
4675 (define_insn "fre<Fs>"
4676 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4677 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4683 [(set_attr "type" "fp")])
4685 (define_insn "*rsqrt<mode>2"
4686 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>")
4687 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")]
4689 "RS6000_RECIP_HAVE_RSQRTE_P (<MODE>mode)"
4691 frsqrte<Ftrad> %0,%1
4692 xsrsqrte<Fvsx> %x0,%x1"
4693 [(set_attr "type" "fp")])
4695 ;; Floating point comparisons
4696 (define_insn "*cmp<mode>_fpr"
4697 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y,y")
4698 (compare:CCFP (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>")
4699 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>")))]
4703 xscmpudp %0,%x1,%x2"
4704 [(set_attr "type" "fpcompare")])
4706 ;; Floating point conversions
4707 (define_expand "extendsfdf2"
4708 [(set (match_operand:DF 0 "gpc_reg_operand")
4709 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand")))]
4710 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4712 if (HONOR_SNANS (SFmode))
4713 operands[1] = force_reg (SFmode, operands[1]);
4716 (define_insn_and_split "*extendsfdf2_fpr"
4717 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d,d,ws,?ws,wu,wb")
4718 (float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "0,f,m,0,wy,Z,wY")))]
4719 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !HONOR_SNANS (SFmode)"
4725 xscpsgndp %x0,%x1,%x1
4728 "&& reload_completed && REG_P (operands[1]) && REGNO (operands[0]) == REGNO (operands[1])"
4731 emit_note (NOTE_INSN_DELETED);
4734 [(set_attr "type" "fp,fpsimple,fpload,fp,fpsimple,fpload,fpload")])
4736 (define_insn "*extendsfdf2_snan"
4737 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
4738 (float_extend:DF (match_operand:SF 1 "gpc_reg_operand" "f,wy")))]
4739 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && HONOR_SNANS (SFmode)"
4743 [(set_attr "type" "fp")])
4745 (define_expand "truncdfsf2"
4746 [(set (match_operand:SF 0 "gpc_reg_operand" "")
4747 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "")))]
4748 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4751 (define_insn "*truncdfsf2_fpr"
4752 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
4753 (float_truncate:SF (match_operand:DF 1 "gpc_reg_operand" "d,ws")))]
4754 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
4758 [(set_attr "type" "fp")])
4760 ;; This expander is here to avoid FLOAT_WORDS_BIGENDIAN tests in
4761 ;; builtins.c and optabs.c that are not correct for IBM long double
4762 ;; when little-endian.
4763 (define_expand "signbit<mode>2"
4765 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))
4767 (subreg:DI (match_dup 2) 0))
4770 (set (match_operand:SI 0 "gpc_reg_operand" "")
4773 && (!FLOAT128_IEEE_P (<MODE>mode)
4774 || (TARGET_POWERPC64 && TARGET_DIRECT_MOVE))"
4776 if (FLOAT128_IEEE_P (<MODE>mode))
4778 if (<MODE>mode == KFmode)
4779 emit_insn (gen_signbitkf2_dm (operands[0], operands[1]));
4780 else if (<MODE>mode == TFmode)
4781 emit_insn (gen_signbittf2_dm (operands[0], operands[1]));
4786 operands[2] = gen_reg_rtx (DFmode);
4787 operands[3] = gen_reg_rtx (DImode);
4788 if (TARGET_POWERPC64)
4790 operands[4] = gen_reg_rtx (DImode);
4791 operands[5] = gen_rtx_LSHIFTRT (DImode, operands[3], GEN_INT (63));
4792 operands[6] = gen_rtx_SUBREG (SImode, operands[4],
4793 WORDS_BIG_ENDIAN ? 4 : 0);
4797 operands[4] = gen_reg_rtx (SImode);
4798 operands[5] = gen_rtx_SUBREG (SImode, operands[3],
4799 WORDS_BIG_ENDIAN ? 0 : 4);
4800 operands[6] = gen_rtx_LSHIFTRT (SImode, operands[4], GEN_INT (31));
4804 (define_expand "copysign<mode>3"
4806 (abs:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")))
4808 (neg:SFDF (abs:SFDF (match_dup 1))))
4809 (set (match_operand:SFDF 0 "gpc_reg_operand" "")
4810 (if_then_else:SFDF (ge (match_operand:SFDF 2 "gpc_reg_operand" "")
4814 "TARGET_HARD_FLOAT && <TARGET_FLOAT>
4815 && ((TARGET_PPC_GFXOPT
4816 && !HONOR_NANS (<MODE>mode)
4817 && !HONOR_SIGNED_ZEROS (<MODE>mode))
4819 || VECTOR_UNIT_VSX_P (<MODE>mode))"
4821 if (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))
4823 emit_insn (gen_copysign<mode>3_fcpsgn (operands[0], operands[1],
4828 operands[3] = gen_reg_rtx (<MODE>mode);
4829 operands[4] = gen_reg_rtx (<MODE>mode);
4830 operands[5] = CONST0_RTX (<MODE>mode);
4833 ;; Optimize signbit on 64-bit systems with direct move to avoid doing the store
4835 (define_insn_and_split "signbit<mode>2_dm"
4836 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r,r")
4838 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4840 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4842 "&& reload_completed"
4845 rs6000_split_signbit (operands[0], operands[1]);
4848 [(set_attr "length" "8,8,4")
4849 (set_attr "type" "mftgpr,load,integer")])
4851 (define_insn_and_split "*signbit<mode>2_dm_<su>ext"
4852 [(set (match_operand:DI 0 "gpc_reg_operand" "=r,r,r")
4855 [(match_operand:SIGNBIT 1 "input_operand" "wa,m,r")]
4857 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4859 "&& reload_completed"
4862 rs6000_split_signbit (operands[0], operands[1]);
4865 [(set_attr "length" "8,8,4")
4866 (set_attr "type" "mftgpr,load,integer")])
4868 ;; TARGET_MODES_TIEABLE_P doesn't allow DImode to be tied with the various
4869 ;; floating point types, which makes normal SUBREG's problematical. Instead
4870 ;; use a special pattern to avoid using a normal movdi.
4871 (define_insn "signbit<mode>2_dm2"
4872 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
4873 (unspec:DI [(match_operand:SIGNBIT 1 "gpc_reg_operand" "wa")
4876 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
4878 [(set_attr "type" "mftgpr")])
4881 ;; Use an unspec rather providing an if-then-else in RTL, to prevent the
4882 ;; compiler from optimizing -0.0
4883 (define_insn "copysign<mode>3_fcpsgn"
4884 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
4885 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")
4886 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv>")]
4888 "TARGET_<MODE>_FPR && (TARGET_CMPB || VECTOR_UNIT_VSX_P (<MODE>mode))"
4891 xscpsgndp %x0,%x2,%x1"
4892 [(set_attr "type" "fpsimple")])
4894 ;; For MIN, MAX, and conditional move, we use DEFINE_EXPAND's that involve a
4895 ;; fsel instruction and some auxiliary computations. Then we just have a
4896 ;; single DEFINE_INSN for fsel and the define_splits to make them if made by
4898 ;; For MIN, MAX on non-VSX machines, and conditional move all of the time, we
4899 ;; use DEFINE_EXPAND's that involve a fsel instruction and some auxiliary
4900 ;; computations. Then we just have a single DEFINE_INSN for fsel and the
4901 ;; define_splits to make them if made by combine. On VSX machines we have the
4902 ;; min/max instructions.
4904 ;; On VSX, we only check for TARGET_VSX instead of checking for a vsx/p8 vector
4905 ;; to allow either DF/SF to use only traditional registers.
4907 (define_expand "s<minmax><mode>3"
4908 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4909 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4910 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4911 "TARGET_MINMAX_<MODE>"
4913 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4917 (define_insn "*s<minmax><mode>3_vsx"
4918 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
4919 (fp_minmax:SFDF (match_operand:SFDF 1 "vsx_register_operand" "<Fv>")
4920 (match_operand:SFDF 2 "vsx_register_operand" "<Fv>")))]
4921 "TARGET_VSX && TARGET_<MODE>_FPR"
4923 return (TARGET_P9_MINMAX
4924 ? "xs<minmax>cdp %x0,%x1,%x2"
4925 : "xs<minmax>dp %x0,%x1,%x2");
4927 [(set_attr "type" "fp")])
4929 ;; The conditional move instructions allow us to perform max and min operations
4930 ;; even when we don't have the appropriate max/min instruction using the FSEL
4933 (define_insn_and_split "*s<minmax><mode>3_fpr"
4934 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
4935 (fp_minmax:SFDF (match_operand:SFDF 1 "gpc_reg_operand" "")
4936 (match_operand:SFDF 2 "gpc_reg_operand" "")))]
4937 "!TARGET_VSX && TARGET_MINMAX_<MODE>"
4942 rs6000_emit_minmax (operands[0], <SMINMAX>, operands[1], operands[2]);
4946 (define_expand "mov<mode>cc"
4947 [(set (match_operand:GPR 0 "gpc_reg_operand" "")
4948 (if_then_else:GPR (match_operand 1 "comparison_operator" "")
4949 (match_operand:GPR 2 "gpc_reg_operand" "")
4950 (match_operand:GPR 3 "gpc_reg_operand" "")))]
4954 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
4960 ;; We use the BASE_REGS for the isel input operands because, if rA is
4961 ;; 0, the value of 0 is placed in rD upon truth. Similarly for rB
4962 ;; because we may switch the operands and rB may end up being rA.
4964 ;; We need 2 patterns: an unsigned and a signed pattern. We could
4965 ;; leave out the mode in operand 4 and use one pattern, but reload can
4966 ;; change the mode underneath our feet and then gets confused trying
4967 ;; to reload the value.
4968 (define_insn "isel_signed_<mode>"
4969 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4971 (match_operator 1 "scc_comparison_operator"
4972 [(match_operand:CC 4 "cc_reg_operand" "y,y")
4974 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4975 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4978 [(set_attr "type" "isel")])
4980 (define_insn "isel_unsigned_<mode>"
4981 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4983 (match_operator 1 "scc_comparison_operator"
4984 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
4986 (match_operand:GPR 2 "reg_or_zero_operand" "O,b")
4987 (match_operand:GPR 3 "gpc_reg_operand" "r,r")))]
4990 [(set_attr "type" "isel")])
4992 ;; These patterns can be useful for combine; they let combine know that
4993 ;; isel can handle reversed comparisons so long as the operands are
4996 (define_insn "*isel_reversed_signed_<mode>"
4997 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
4999 (match_operator 1 "scc_rev_comparison_operator"
5000 [(match_operand:CC 4 "cc_reg_operand" "y,y")
5002 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5003 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5006 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5007 return "isel %0,%3,%2,%j1";
5009 [(set_attr "type" "isel")])
5011 (define_insn "*isel_reversed_unsigned_<mode>"
5012 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r,r")
5014 (match_operator 1 "scc_rev_comparison_operator"
5015 [(match_operand:CCUNS 4 "cc_reg_operand" "y,y")
5017 (match_operand:GPR 2 "gpc_reg_operand" "r,r")
5018 (match_operand:GPR 3 "reg_or_zero_operand" "O,b")))]
5021 PUT_CODE (operands[1], reverse_condition (GET_CODE (operands[1])));
5022 return "isel %0,%3,%2,%j1";
5024 [(set_attr "type" "isel")])
5026 ;; Floating point conditional move
5027 (define_expand "mov<mode>cc"
5028 [(set (match_operand:SFDF 0 "gpc_reg_operand" "")
5029 (if_then_else:SFDF (match_operand 1 "comparison_operator" "")
5030 (match_operand:SFDF 2 "gpc_reg_operand" "")
5031 (match_operand:SFDF 3 "gpc_reg_operand" "")))]
5032 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5035 if (rs6000_emit_cmove (operands[0], operands[1], operands[2], operands[3]))
5041 (define_insn "*fsel<SFDF:mode><SFDF2:mode>4"
5042 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=&<SFDF:rreg2>")
5044 (ge (match_operand:SFDF2 1 "gpc_reg_operand" "<SFDF2:rreg2>")
5045 (match_operand:SFDF2 4 "zero_fp_constant" "F"))
5046 (match_operand:SFDF 2 "gpc_reg_operand" "<SFDF:rreg2>")
5047 (match_operand:SFDF 3 "gpc_reg_operand" "<SFDF:rreg2>")))]
5048 "TARGET_<MODE>_FPR && TARGET_PPC_GFXOPT"
5050 [(set_attr "type" "fp")])
5052 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_p9"
5053 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5055 (match_operator:CCFP 1 "fpmask_comparison_operator"
5056 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5057 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5058 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5059 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5060 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5065 (if_then_else:V2DI (match_dup 1)
5069 (if_then_else:SFDF (ne (match_dup 6)
5074 if (GET_CODE (operands[6]) == SCRATCH)
5075 operands[6] = gen_reg_rtx (V2DImode);
5077 operands[7] = CONSTM1_RTX (V2DImode);
5078 operands[8] = CONST0_RTX (V2DImode);
5080 [(set_attr "length" "8")
5081 (set_attr "type" "vecperm")])
5083 ;; Handle inverting the fpmask comparisons.
5084 (define_insn_and_split "*mov<SFDF:mode><SFDF2:mode>cc_invert_p9"
5085 [(set (match_operand:SFDF 0 "vsx_register_operand" "=&<SFDF:Fv>,<SFDF:Fv>")
5087 (match_operator:CCFP 1 "invert_fpmask_comparison_operator"
5088 [(match_operand:SFDF2 2 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")
5089 (match_operand:SFDF2 3 "vsx_register_operand" "<SFDF2:Fv>,<SFDF2:Fv>")])
5090 (match_operand:SFDF 4 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")
5091 (match_operand:SFDF 5 "vsx_register_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5092 (clobber (match_scratch:V2DI 6 "=0,&wa"))]
5097 (if_then_else:V2DI (match_dup 9)
5101 (if_then_else:SFDF (ne (match_dup 6)
5106 rtx op1 = operands[1];
5107 enum rtx_code cond = reverse_condition_maybe_unordered (GET_CODE (op1));
5109 if (GET_CODE (operands[6]) == SCRATCH)
5110 operands[6] = gen_reg_rtx (V2DImode);
5112 operands[7] = CONSTM1_RTX (V2DImode);
5113 operands[8] = CONST0_RTX (V2DImode);
5115 operands[9] = gen_rtx_fmt_ee (cond, CCFPmode, operands[2], operands[3]);
5117 [(set_attr "length" "8")
5118 (set_attr "type" "vecperm")])
5120 (define_insn "*fpmask<mode>"
5121 [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa")
5123 (match_operator:CCFP 1 "fpmask_comparison_operator"
5124 [(match_operand:SFDF 2 "vsx_register_operand" "<Fv>")
5125 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")])
5126 (match_operand:V2DI 4 "all_ones_constant" "")
5127 (match_operand:V2DI 5 "zero_constant" "")))]
5129 "xscmp%V1dp %x0,%x2,%x3"
5130 [(set_attr "type" "fpcompare")])
5132 (define_insn "*xxsel<mode>"
5133 [(set (match_operand:SFDF 0 "vsx_register_operand" "=<Fv>")
5134 (if_then_else:SFDF (ne (match_operand:V2DI 1 "vsx_register_operand" "wa")
5135 (match_operand:V2DI 2 "zero_constant" ""))
5136 (match_operand:SFDF 3 "vsx_register_operand" "<Fv>")
5137 (match_operand:SFDF 4 "vsx_register_operand" "<Fv>")))]
5139 "xxsel %x0,%x4,%x3,%x1"
5140 [(set_attr "type" "vecmove")])
5143 ;; Conversions to and from floating-point.
5145 ; We don't define lfiwax/lfiwzx with the normal definition, because we
5146 ; don't want to support putting SImode in FPR registers.
5147 (define_insn "lfiwax"
5148 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wK")
5149 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wK")]
5151 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX"
5157 [(set_attr "type" "fpload,fpload,mffgpr,vecexts")])
5159 ; This split must be run before register allocation because it allocates the
5160 ; memory slot that is needed to move values to/from the FPR. We don't allocate
5161 ; it earlier to allow for the combiner to merge insns together where it might
5162 ; not be needed and also in case the insns are deleted as dead code.
5164 (define_insn_and_split "floatsi<mode>2_lfiwax"
5165 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5166 (float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5167 (clobber (match_scratch:DI 2 "=wi"))]
5168 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX
5169 && <SI_CONVERT_FP> && can_create_pseudo_p ()"
5175 rtx dest = operands[0];
5176 rtx src = operands[1];
5179 if (!MEM_P (src) && TARGET_POWERPC64
5180 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5181 tmp = convert_to_mode (DImode, src, false);
5185 if (GET_CODE (tmp) == SCRATCH)
5186 tmp = gen_reg_rtx (DImode);
5189 src = rs6000_address_for_fpconvert (src);
5190 emit_insn (gen_lfiwax (tmp, src));
5194 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5195 emit_move_insn (stack, src);
5196 emit_insn (gen_lfiwax (tmp, stack));
5199 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5202 [(set_attr "length" "12")
5203 (set_attr "type" "fpload")])
5205 (define_insn_and_split "floatsi<mode>2_lfiwax_mem"
5206 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5209 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5210 (clobber (match_scratch:DI 2 "=wi"))]
5211 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWAX && <SI_CONVERT_FP>"
5217 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5218 if (GET_CODE (operands[2]) == SCRATCH)
5219 operands[2] = gen_reg_rtx (DImode);
5220 if (TARGET_P8_VECTOR)
5221 emit_insn (gen_extendsidi2 (operands[2], operands[1]));
5223 emit_insn (gen_lfiwax (operands[2], operands[1]));
5224 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5227 [(set_attr "length" "8")
5228 (set_attr "type" "fpload")])
5230 (define_insn "lfiwzx"
5231 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wj,wj,wJwK")
5232 (unspec:DI [(match_operand:SI 1 "reg_or_indexed_operand" "Z,Z,r,wJwK")]
5234 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX"
5239 xxextractuw %x0,%x1,4"
5240 [(set_attr "type" "fpload,fpload,mftgpr,vecexts")])
5242 (define_insn_and_split "floatunssi<mode>2_lfiwzx"
5243 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5244 (unsigned_float:SFDF (match_operand:SI 1 "nonimmediate_operand" "r")))
5245 (clobber (match_scratch:DI 2 "=wi"))]
5246 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5252 rtx dest = operands[0];
5253 rtx src = operands[1];
5256 if (!MEM_P (src) && TARGET_POWERPC64
5257 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5258 tmp = convert_to_mode (DImode, src, true);
5262 if (GET_CODE (tmp) == SCRATCH)
5263 tmp = gen_reg_rtx (DImode);
5266 src = rs6000_address_for_fpconvert (src);
5267 emit_insn (gen_lfiwzx (tmp, src));
5271 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5272 emit_move_insn (stack, src);
5273 emit_insn (gen_lfiwzx (tmp, stack));
5276 emit_insn (gen_floatdi<mode>2 (dest, tmp));
5279 [(set_attr "length" "12")
5280 (set_attr "type" "fpload")])
5282 (define_insn_and_split "floatunssi<mode>2_lfiwzx_mem"
5283 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
5284 (unsigned_float:SFDF
5286 (match_operand:SI 1 "indexed_or_indirect_operand" "Z"))))
5287 (clobber (match_scratch:DI 2 "=wi"))]
5288 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LFIWZX && <SI_CONVERT_FP>"
5294 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5295 if (GET_CODE (operands[2]) == SCRATCH)
5296 operands[2] = gen_reg_rtx (DImode);
5297 if (TARGET_P8_VECTOR)
5298 emit_insn (gen_zero_extendsidi2 (operands[2], operands[1]));
5300 emit_insn (gen_lfiwzx (operands[2], operands[1]));
5301 emit_insn (gen_floatdi<mode>2 (operands[0], operands[2]));
5304 [(set_attr "length" "8")
5305 (set_attr "type" "fpload")])
5307 ; For each of these conversions, there is a define_expand, a define_insn
5308 ; with a '#' template, and a define_split (with C code). The idea is
5309 ; to allow constant folding with the template of the define_insn,
5310 ; then to have the insns split later (between sched1 and final).
5312 (define_expand "floatsidf2"
5313 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5314 (float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5317 (clobber (match_dup 4))
5318 (clobber (match_dup 5))
5319 (clobber (match_dup 6))])]
5320 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5323 if (TARGET_LFIWAX && TARGET_FCFID)
5325 emit_insn (gen_floatsidf2_lfiwax (operands[0], operands[1]));
5328 else if (TARGET_FCFID)
5330 rtx dreg = operands[1];
5332 dreg = force_reg (SImode, dreg);
5333 dreg = convert_to_mode (DImode, dreg, false);
5334 emit_insn (gen_floatdidf2 (operands[0], dreg));
5338 if (!REG_P (operands[1]))
5339 operands[1] = force_reg (SImode, operands[1]);
5340 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5341 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503601774854144\", DFmode));
5342 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5343 operands[5] = gen_reg_rtx (DFmode);
5344 operands[6] = gen_reg_rtx (SImode);
5347 (define_insn_and_split "*floatsidf2_internal"
5348 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5349 (float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5350 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5351 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5352 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5353 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))
5354 (clobber (match_operand:SI 6 "gpc_reg_operand" "=&r"))]
5355 "! TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5361 rtx lowword, highword;
5362 gcc_assert (MEM_P (operands[4]));
5363 highword = adjust_address (operands[4], SImode, 0);
5364 lowword = adjust_address (operands[4], SImode, 4);
5365 if (! WORDS_BIG_ENDIAN)
5366 std::swap (lowword, highword);
5368 emit_insn (gen_xorsi3 (operands[6], operands[1],
5369 GEN_INT (~ (HOST_WIDE_INT) 0x7fffffff)));
5370 emit_move_insn (lowword, operands[6]);
5371 emit_move_insn (highword, operands[2]);
5372 emit_move_insn (operands[5], operands[4]);
5373 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5376 [(set_attr "length" "24")
5377 (set_attr "type" "fp")])
5379 ;; If we don't have a direct conversion to single precision, don't enable this
5380 ;; conversion for 32-bit without fast math, because we don't have the insn to
5381 ;; generate the fixup swizzle to avoid double rounding problems.
5382 (define_expand "floatunssisf2"
5383 [(set (match_operand:SF 0 "gpc_reg_operand" "")
5384 (unsigned_float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
5385 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
5386 && ((TARGET_FCFIDUS && TARGET_LFIWZX)
5387 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
5388 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
5391 if (TARGET_LFIWZX && TARGET_FCFIDUS)
5393 emit_insn (gen_floatunssisf2_lfiwzx (operands[0], operands[1]));
5398 rtx dreg = operands[1];
5400 dreg = force_reg (SImode, dreg);
5401 dreg = convert_to_mode (DImode, dreg, true);
5402 emit_insn (gen_floatdisf2 (operands[0], dreg));
5407 (define_expand "floatunssidf2"
5408 [(parallel [(set (match_operand:DF 0 "gpc_reg_operand" "")
5409 (unsigned_float:DF (match_operand:SI 1 "nonimmediate_operand" "")))
5412 (clobber (match_dup 4))
5413 (clobber (match_dup 5))])]
5414 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5417 if (TARGET_LFIWZX && TARGET_FCFID)
5419 emit_insn (gen_floatunssidf2_lfiwzx (operands[0], operands[1]));
5422 else if (TARGET_FCFID)
5424 rtx dreg = operands[1];
5426 dreg = force_reg (SImode, dreg);
5427 dreg = convert_to_mode (DImode, dreg, true);
5428 emit_insn (gen_floatdidf2 (operands[0], dreg));
5432 if (!REG_P (operands[1]))
5433 operands[1] = force_reg (SImode, operands[1]);
5434 operands[2] = force_reg (SImode, GEN_INT (0x43300000));
5435 operands[3] = force_reg (DFmode, CONST_DOUBLE_ATOF (\"4503599627370496\", DFmode));
5436 operands[4] = rs6000_allocate_stack_temp (DFmode, true, false);
5437 operands[5] = gen_reg_rtx (DFmode);
5440 (define_insn_and_split "*floatunssidf2_internal"
5441 [(set (match_operand:DF 0 "gpc_reg_operand" "=&d")
5442 (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
5443 (use (match_operand:SI 2 "gpc_reg_operand" "r"))
5444 (use (match_operand:DF 3 "gpc_reg_operand" "d"))
5445 (clobber (match_operand:DF 4 "offsettable_mem_operand" "=o"))
5446 (clobber (match_operand:DF 5 "gpc_reg_operand" "=&d"))]
5447 "! TARGET_FCFIDU && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5448 && !(TARGET_FCFID && TARGET_POWERPC64)"
5454 rtx lowword, highword;
5455 gcc_assert (MEM_P (operands[4]));
5456 highword = adjust_address (operands[4], SImode, 0);
5457 lowword = adjust_address (operands[4], SImode, 4);
5458 if (! WORDS_BIG_ENDIAN)
5459 std::swap (lowword, highword);
5461 emit_move_insn (lowword, operands[1]);
5462 emit_move_insn (highword, operands[2]);
5463 emit_move_insn (operands[5], operands[4]);
5464 emit_insn (gen_subdf3 (operands[0], operands[5], operands[3]));
5467 [(set_attr "length" "20")
5468 (set_attr "type" "fp")])
5470 ;; ISA 3.0 adds instructions lxsi[bh]zx to directly load QImode and HImode to
5471 ;; vector registers. These insns favor doing the sign/zero extension in
5472 ;; the vector registers, rather then loading up a GPR, doing a sign/zero
5473 ;; extension and then a direct move.
5475 (define_expand "float<QHI:mode><FP_ISA3:mode>2"
5476 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5478 (match_operand:QHI 1 "input_operand")))
5479 (clobber (match_scratch:DI 2))
5480 (clobber (match_scratch:DI 3))
5481 (clobber (match_scratch:<QHI:MODE> 4))])]
5482 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5484 if (MEM_P (operands[1]))
5485 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5488 (define_insn_and_split "*float<QHI:mode><FP_ISA3:mode>2_internal"
5489 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5491 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5492 (clobber (match_scratch:DI 2 "=wK,wi,wK"))
5493 (clobber (match_scratch:DI 3 "=X,r,X"))
5494 (clobber (match_scratch:<QHI:MODE> 4 "=X,X,wK"))]
5495 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5497 "&& reload_completed"
5500 rtx result = operands[0];
5501 rtx input = operands[1];
5502 rtx di = operands[2];
5506 rtx tmp = operands[3];
5507 if (altivec_register_operand (input, <QHI:MODE>mode))
5508 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5509 else if (GET_CODE (tmp) == SCRATCH)
5510 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5513 emit_insn (gen_extend<QHI:mode>di2 (tmp, input));
5514 emit_move_insn (di, tmp);
5519 rtx tmp = operands[4];
5520 emit_move_insn (tmp, input);
5521 emit_insn (gen_extend<QHI:mode>di2 (di, tmp));
5524 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5528 (define_expand "floatuns<QHI:mode><FP_ISA3:mode>2"
5529 [(parallel [(set (match_operand:FP_ISA3 0 "vsx_register_operand")
5530 (unsigned_float:FP_ISA3
5531 (match_operand:QHI 1 "input_operand" "")))
5532 (clobber (match_scratch:DI 2 ""))
5533 (clobber (match_scratch:DI 3 ""))])]
5534 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5536 if (MEM_P (operands[1]))
5537 operands[1] = rs6000_address_for_fpconvert (operands[1]);
5540 (define_insn_and_split "*floatuns<QHI:mode><FP_ISA3:mode>2_internal"
5541 [(set (match_operand:FP_ISA3 0 "vsx_register_operand" "=<Fv>,<Fv>,<Fv>")
5542 (unsigned_float:FP_ISA3
5543 (match_operand:QHI 1 "reg_or_indexed_operand" "wK,r,Z")))
5544 (clobber (match_scratch:DI 2 "=wK,wi,wJwK"))
5545 (clobber (match_scratch:DI 3 "=X,r,X"))]
5546 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE && TARGET_POWERPC64"
5548 "&& reload_completed"
5551 rtx result = operands[0];
5552 rtx input = operands[1];
5553 rtx di = operands[2];
5555 if (MEM_P (input) || altivec_register_operand (input, <QHI:MODE>mode))
5556 emit_insn (gen_zero_extend<QHI:mode>di2 (di, input));
5559 rtx tmp = operands[3];
5560 if (GET_CODE (tmp) == SCRATCH)
5561 emit_insn (gen_extend<QHI:mode>di2 (di, input));
5564 emit_insn (gen_zero_extend<QHI:mode>di2 (tmp, input));
5565 emit_move_insn (di, tmp);
5569 emit_insn (gen_floatdi<FP_ISA3:mode>2 (result, di));
5573 (define_expand "fix_trunc<mode>si2"
5574 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5575 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5576 "TARGET_HARD_FLOAT && <TARGET_FLOAT>"
5579 if (!TARGET_P8_VECTOR)
5581 rtx src = force_reg (<MODE>mode, operands[1]);
5584 emit_insn (gen_fix_trunc<mode>si2_stfiwx (operands[0], src));
5587 rtx tmp = gen_reg_rtx (DImode);
5588 rtx stack = rs6000_allocate_stack_temp (DImode, true, false);
5589 emit_insn (gen_fix_trunc<mode>si2_internal (operands[0], src,
5596 ; Like the convert to float patterns, this insn must be split before
5597 ; register allocation so that it can allocate the memory slot if it
5599 (define_insn_and_split "fix_trunc<mode>si2_stfiwx"
5600 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5601 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5602 (clobber (match_scratch:DI 2 "=d"))]
5603 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5604 && (<MODE>mode != SFmode || TARGET_SINGLE_FLOAT)
5605 && TARGET_STFIWX && can_create_pseudo_p ()
5606 && !TARGET_P8_VECTOR"
5611 rtx dest = operands[0];
5612 rtx src = operands[1];
5613 rtx tmp = operands[2];
5615 if (GET_CODE (tmp) == SCRATCH)
5616 tmp = gen_reg_rtx (DImode);
5618 emit_insn (gen_fctiwz_<mode> (tmp, src));
5621 dest = rs6000_address_for_fpconvert (dest);
5622 emit_insn (gen_stfiwx (dest, tmp));
5625 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5627 dest = gen_lowpart (DImode, dest);
5628 emit_move_insn (dest, tmp);
5633 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5634 emit_insn (gen_stfiwx (stack, tmp));
5635 emit_move_insn (dest, stack);
5639 [(set_attr "length" "12")
5640 (set_attr "type" "fp")])
5642 (define_insn_and_split "fix_trunc<mode>si2_internal"
5643 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,?r")
5644 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d,<rreg>")))
5645 (clobber (match_operand:DI 2 "gpc_reg_operand" "=1,d"))
5646 (clobber (match_operand:DI 3 "offsettable_mem_operand" "=o,o"))]
5647 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && !TARGET_P8_VECTOR"
5654 gcc_assert (MEM_P (operands[3]));
5655 lowword = adjust_address (operands[3], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
5657 emit_insn (gen_fctiwz_<mode> (operands[2], operands[1]));
5658 emit_move_insn (operands[3], operands[2]);
5659 emit_move_insn (operands[0], lowword);
5662 [(set_attr "length" "16")
5663 (set_attr "type" "fp")])
5665 (define_expand "fix_trunc<mode>di2"
5666 [(set (match_operand:DI 0 "gpc_reg_operand" "")
5667 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5668 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5671 (define_insn "*fix_trunc<mode>di2_fctidz"
5672 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5673 (fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5674 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
5678 [(set_attr "type" "fp")])
5680 (define_expand "fix_trunc<SFDF:mode><QHI:mode>2"
5681 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5682 (fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5683 (clobber (match_scratch:DI 2))])]
5684 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5686 if (MEM_P (operands[0]))
5687 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5690 (define_insn_and_split "*fix_trunc<SFDF:mode><QHI:mode>2_internal"
5691 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5693 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5694 (clobber (match_scratch:DI 2 "=X,wi"))]
5695 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5697 "&& reload_completed"
5700 rtx dest = operands[0];
5701 rtx src = operands[1];
5703 if (vsx_register_operand (dest, <QHI:MODE>mode))
5705 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5706 emit_insn (gen_fix_trunc<SFDF:mode>di2 (di_dest, src));
5710 rtx tmp = operands[2];
5711 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5713 emit_insn (gen_fix_trunc<SFDF:mode>di2 (tmp, src));
5714 emit_move_insn (dest, tmp2);
5719 (define_expand "fixuns_trunc<mode>si2"
5720 [(set (match_operand:SI 0 "gpc_reg_operand" "")
5721 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "")))]
5722 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ && TARGET_STFIWX"
5725 if (!TARGET_P8_VECTOR)
5727 emit_insn (gen_fixuns_trunc<mode>si2_stfiwx (operands[0], operands[1]));
5732 (define_insn_and_split "fixuns_trunc<mode>si2_stfiwx"
5733 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
5734 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d")))
5735 (clobber (match_scratch:DI 2 "=d"))]
5736 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ
5737 && TARGET_STFIWX && can_create_pseudo_p ()
5738 && !TARGET_P8_VECTOR"
5743 rtx dest = operands[0];
5744 rtx src = operands[1];
5745 rtx tmp = operands[2];
5747 if (GET_CODE (tmp) == SCRATCH)
5748 tmp = gen_reg_rtx (DImode);
5750 emit_insn (gen_fctiwuz_<mode> (tmp, src));
5753 dest = rs6000_address_for_fpconvert (dest);
5754 emit_insn (gen_stfiwx (dest, tmp));
5757 else if (TARGET_POWERPC64 && (TARGET_MFPGPR || TARGET_DIRECT_MOVE))
5759 dest = gen_lowpart (DImode, dest);
5760 emit_move_insn (dest, tmp);
5765 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5766 emit_insn (gen_stfiwx (stack, tmp));
5767 emit_move_insn (dest, stack);
5771 [(set_attr "length" "12")
5772 (set_attr "type" "fp")])
5774 (define_insn "fixuns_trunc<mode>di2"
5775 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5776 (unsigned_fix:DI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5777 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCTIDUZ"
5781 [(set_attr "type" "fp")])
5783 (define_expand "fixuns_trunc<SFDF:mode><QHI:mode>2"
5784 [(parallel [(set (match_operand:<QHI:MODE> 0 "nonimmediate_operand")
5785 (unsigned_fix:QHI (match_operand:SFDF 1 "gpc_reg_operand")))
5786 (clobber (match_scratch:DI 2))])]
5787 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5789 if (MEM_P (operands[0]))
5790 operands[0] = rs6000_address_for_fpconvert (operands[0]);
5793 (define_insn_and_split "*fixuns_trunc<SFDF:mode><QHI:mode>2_internal"
5794 [(set (match_operand:<QHI:MODE> 0 "reg_or_indexed_operand" "=wIwJ,rZ")
5796 (match_operand:SFDF 1 "gpc_reg_operand" "<SFDF:Fv>,<SFDF:Fv>")))
5797 (clobber (match_scratch:DI 2 "=X,wi"))]
5798 "TARGET_P9_VECTOR && TARGET_DIRECT_MOVE_64BIT"
5800 "&& reload_completed"
5803 rtx dest = operands[0];
5804 rtx src = operands[1];
5806 if (vsx_register_operand (dest, <QHI:MODE>mode))
5808 rtx di_dest = gen_rtx_REG (DImode, REGNO (dest));
5809 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (di_dest, src));
5813 rtx tmp = operands[2];
5814 rtx tmp2 = gen_rtx_REG (<QHI:MODE>mode, REGNO (tmp));
5816 emit_insn (gen_fixuns_trunc<SFDF:mode>di2 (tmp, src));
5817 emit_move_insn (dest, tmp2);
5822 ;; If -mvsx-small-integer, we can represent the FIX operation directly. On
5823 ;; older machines, we have to use an UNSPEC to produce a SImode and move it
5824 ;; to another location, since SImode is not allowed in vector registers.
5825 (define_insn "*fctiw<u>z_<mode>_smallint"
5826 [(set (match_operand:SI 0 "vsx_register_operand" "=d,wi")
5827 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")))]
5828 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5831 xscvdp<su>xws %x0,%x1"
5832 [(set_attr "type" "fp")])
5834 ;; Combiner pattern to prevent moving the result of converting a floating point
5835 ;; value to 32-bit integer to GPR in order to save it.
5836 (define_insn_and_split "*fctiw<u>z_<mode>_mem"
5837 [(set (match_operand:SI 0 "memory_operand" "=Z")
5838 (any_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "wa")))
5839 (clobber (match_scratch:SI 2 "=wa"))]
5840 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_P8_VECTOR"
5842 "&& reload_completed"
5844 (any_fix:SI (match_dup 1)))
5848 ;; Here, we use (set (reg) (unspec:DI [(fix:SI ...)] UNSPEC_FCTIWZ))
5849 ;; rather than (set (subreg:SI (reg)) (fix:SI ...))
5850 ;; because the first makes it clear that operand 0 is not live
5851 ;; before the instruction.
5852 (define_insn "fctiwz_<mode>"
5853 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5855 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5857 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
5861 [(set_attr "type" "fp")])
5863 (define_insn "fctiwuz_<mode>"
5864 [(set (match_operand:DI 0 "gpc_reg_operand" "=d,wi")
5865 (unspec:DI [(unsigned_fix:SI
5866 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>"))]
5868 "TARGET_HARD_FLOAT && <TARGET_FLOAT> && TARGET_FCTIWUZ"
5872 [(set_attr "type" "fp")])
5874 ;; Only optimize (float (fix x)) -> frz if we are in fast-math mode, since
5875 ;; since the friz instruction does not truncate the value if the floating
5876 ;; point value is < LONG_MIN or > LONG_MAX.
5877 (define_insn "*friz"
5878 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
5879 (float:DF (fix:DI (match_operand:DF 1 "gpc_reg_operand" "d,ws"))))]
5880 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FPRND
5881 && flag_unsafe_math_optimizations && !flag_trapping_math && TARGET_FRIZ"
5885 [(set_attr "type" "fp")])
5887 ;; Opitmize converting SF/DFmode to signed SImode and back to SF/DFmode. This
5888 ;; optimization prevents on ISA 2.06 systems and earlier having to store the
5889 ;; value from the FPR/vector unit to the stack, load the value into a GPR, sign
5890 ;; extend it, store it back on the stack from the GPR, load it back into the
5891 ;; FP/vector unit to do the rounding. If we have direct move (ISA 2.07),
5892 ;; disable using store and load to sign/zero extend the value.
5893 (define_insn_and_split "*round32<mode>2_fprs"
5894 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5896 (fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5897 (clobber (match_scratch:DI 2 "=d"))
5898 (clobber (match_scratch:DI 3 "=d"))]
5899 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5900 && <SI_CONVERT_FP> && TARGET_LFIWAX && TARGET_STFIWX && TARGET_FCFID
5901 && !TARGET_DIRECT_MOVE && can_create_pseudo_p ()"
5906 rtx dest = operands[0];
5907 rtx src = operands[1];
5908 rtx tmp1 = operands[2];
5909 rtx tmp2 = operands[3];
5910 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5912 if (GET_CODE (tmp1) == SCRATCH)
5913 tmp1 = gen_reg_rtx (DImode);
5914 if (GET_CODE (tmp2) == SCRATCH)
5915 tmp2 = gen_reg_rtx (DImode);
5917 emit_insn (gen_fctiwz_<mode> (tmp1, src));
5918 emit_insn (gen_stfiwx (stack, tmp1));
5919 emit_insn (gen_lfiwax (tmp2, stack));
5920 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5923 [(set_attr "type" "fpload")
5924 (set_attr "length" "16")])
5926 (define_insn_and_split "*roundu32<mode>2_fprs"
5927 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=d")
5928 (unsigned_float:SFDF
5929 (unsigned_fix:SI (match_operand:SFDF 1 "gpc_reg_operand" "d"))))
5930 (clobber (match_scratch:DI 2 "=d"))
5931 (clobber (match_scratch:DI 3 "=d"))]
5932 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
5933 && TARGET_LFIWZX && TARGET_STFIWX && TARGET_FCFIDU && !TARGET_DIRECT_MOVE
5934 && can_create_pseudo_p ()"
5939 rtx dest = operands[0];
5940 rtx src = operands[1];
5941 rtx tmp1 = operands[2];
5942 rtx tmp2 = operands[3];
5943 rtx stack = rs6000_allocate_stack_temp (SImode, false, true);
5945 if (GET_CODE (tmp1) == SCRATCH)
5946 tmp1 = gen_reg_rtx (DImode);
5947 if (GET_CODE (tmp2) == SCRATCH)
5948 tmp2 = gen_reg_rtx (DImode);
5950 emit_insn (gen_fctiwuz_<mode> (tmp1, src));
5951 emit_insn (gen_stfiwx (stack, tmp1));
5952 emit_insn (gen_lfiwzx (tmp2, stack));
5953 emit_insn (gen_floatdi<mode>2 (dest, tmp2));
5956 [(set_attr "type" "fpload")
5957 (set_attr "length" "16")])
5959 (define_insn "lrintsfsi2"
5960 [(set (match_operand:SI 0 "gpc_reg_operand" "=d")
5961 (unspec:SI [(match_operand:DF 1 "gpc_reg_operand" "d")]
5963 "TARGET_SF_FPR && TARGET_FPRND"
5965 [(set_attr "type" "fp")])
5967 ;; No VSX equivalent to fctid
5968 (define_insn "lrint<mode>di2"
5969 [(set (match_operand:DI 0 "gpc_reg_operand" "=d")
5970 (unspec:DI [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
5972 "TARGET_<MODE>_FPR && TARGET_FPRND"
5974 [(set_attr "type" "fp")])
5976 (define_insn "btrunc<mode>2"
5977 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5978 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5980 "TARGET_<MODE>_FPR && TARGET_FPRND"
5984 [(set_attr "type" "fp")
5985 (set_attr "fp_type" "fp_addsub_<Fs>")])
5987 (define_insn "ceil<mode>2"
5988 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
5989 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
5991 "TARGET_<MODE>_FPR && TARGET_FPRND"
5995 [(set_attr "type" "fp")
5996 (set_attr "fp_type" "fp_addsub_<Fs>")])
5998 (define_insn "floor<mode>2"
5999 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv>")
6000 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv>")]
6002 "TARGET_<MODE>_FPR && TARGET_FPRND"
6006 [(set_attr "type" "fp")
6007 (set_attr "fp_type" "fp_addsub_<Fs>")])
6009 ;; No VSX equivalent to frin
6010 (define_insn "round<mode>2"
6011 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<rreg2>")
6012 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<rreg2>")]
6014 "TARGET_<MODE>_FPR && TARGET_FPRND"
6016 [(set_attr "type" "fp")
6017 (set_attr "fp_type" "fp_addsub_<Fs>")])
6019 (define_insn "*xsrdpi<mode>2"
6020 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Fv>")
6021 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "<Fv>")]
6023 "TARGET_<MODE>_FPR && TARGET_VSX"
6025 [(set_attr "type" "fp")
6026 (set_attr "fp_type" "fp_addsub_<Fs>")])
6028 (define_expand "lround<mode>di2"
6030 (unspec:SFDF [(match_operand:SFDF 1 "gpc_reg_operand" "")]
6032 (set (match_operand:DI 0 "gpc_reg_operand" "")
6033 (unspec:DI [(match_dup 2)]
6035 "TARGET_<MODE>_FPR && TARGET_VSX"
6037 operands[2] = gen_reg_rtx (<MODE>mode);
6040 ; An UNSPEC is used so we don't have to support SImode in FP registers.
6041 ; The 'wu' constraint is used for the 2nd alternative to ensure stxsiwx
6042 ; is only generated for Power8 or later.
6043 (define_insn "stfiwx"
6044 [(set (match_operand:SI 0 "memory_operand" "=Z,Z")
6045 (unspec:SI [(match_operand:DI 1 "gpc_reg_operand" "d,wu")]
6051 [(set_attr "type" "fpstore")])
6053 ;; If we don't have a direct conversion to single precision, don't enable this
6054 ;; conversion for 32-bit without fast math, because we don't have the insn to
6055 ;; generate the fixup swizzle to avoid double rounding problems.
6056 (define_expand "floatsisf2"
6057 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6058 (float:SF (match_operand:SI 1 "nonimmediate_operand" "")))]
6059 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6060 && ((TARGET_FCFIDS && TARGET_LFIWAX)
6061 || (TARGET_DOUBLE_FLOAT && TARGET_FCFID
6062 && (TARGET_POWERPC64 || flag_unsafe_math_optimizations)))"
6065 if (TARGET_FCFIDS && TARGET_LFIWAX)
6067 emit_insn (gen_floatsisf2_lfiwax (operands[0], operands[1]));
6070 else if (TARGET_FCFID && TARGET_LFIWAX)
6072 rtx dfreg = gen_reg_rtx (DFmode);
6073 emit_insn (gen_floatsidf2_lfiwax (dfreg, operands[1]));
6074 emit_insn (gen_truncdfsf2 (operands[0], dfreg));
6079 rtx dreg = operands[1];
6081 dreg = force_reg (SImode, dreg);
6082 dreg = convert_to_mode (DImode, dreg, false);
6083 emit_insn (gen_floatdisf2 (operands[0], dreg));
6088 (define_insn "floatdidf2"
6089 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6090 (float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6091 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT"
6095 [(set_attr "type" "fp")])
6097 ; Allow the combiner to merge source memory operands to the conversion so that
6098 ; the optimizer/register allocator doesn't try to load the value too early in a
6099 ; GPR and then use store/load to move it to a FPR and suffer from a store-load
6100 ; hit. We will split after reload to avoid the trip through the GPRs
6102 (define_insn_and_split "*floatdidf2_mem"
6103 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6104 (float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6105 (clobber (match_scratch:DI 2 "=d,wi"))]
6106 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_FCFID"
6108 "&& reload_completed"
6109 [(set (match_dup 2) (match_dup 1))
6110 (set (match_dup 0) (float:DF (match_dup 2)))]
6112 [(set_attr "length" "8")
6113 (set_attr "type" "fpload")])
6115 (define_expand "floatunsdidf2"
6116 [(set (match_operand:DF 0 "gpc_reg_operand" "")
6118 (match_operand:DI 1 "gpc_reg_operand" "")))]
6119 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6122 (define_insn "*floatunsdidf2_fcfidu"
6123 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6124 (unsigned_float:DF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6125 "TARGET_HARD_FLOAT && TARGET_FCFIDU"
6129 [(set_attr "type" "fp")
6130 (set_attr "length" "4")])
6132 (define_insn_and_split "*floatunsdidf2_mem"
6133 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,ws")
6134 (unsigned_float:DF (match_operand:DI 1 "memory_operand" "m,Z")))
6135 (clobber (match_scratch:DI 2 "=d,wi"))]
6136 "TARGET_HARD_FLOAT && (TARGET_FCFIDU || VECTOR_UNIT_VSX_P (DFmode))"
6138 "&& reload_completed"
6139 [(set (match_dup 2) (match_dup 1))
6140 (set (match_dup 0) (unsigned_float:DF (match_dup 2)))]
6142 [(set_attr "length" "8")
6143 (set_attr "type" "fpload")])
6145 (define_expand "floatdisf2"
6146 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6147 (float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6148 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6149 && (TARGET_FCFIDS || TARGET_POWERPC64 || flag_unsafe_math_optimizations)"
6154 rtx val = operands[1];
6155 if (!flag_unsafe_math_optimizations)
6157 rtx label = gen_label_rtx ();
6158 val = gen_reg_rtx (DImode);
6159 emit_insn (gen_floatdisf2_internal2 (val, operands[1], label));
6162 emit_insn (gen_floatdisf2_internal1 (operands[0], val));
6167 (define_insn "floatdisf2_fcfids"
6168 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy")
6169 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6170 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6171 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6175 [(set_attr "type" "fp")])
6177 (define_insn_and_split "*floatdisf2_mem"
6178 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6179 (float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6180 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6181 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6182 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDS"
6184 "&& reload_completed"
6188 emit_move_insn (operands[2], operands[1]);
6189 emit_insn (gen_floatdisf2_fcfids (operands[0], operands[2]));
6192 [(set_attr "length" "8")])
6194 ;; This is not IEEE compliant if rounding mode is "round to nearest".
6195 ;; If the DI->DF conversion is inexact, then it's possible to suffer
6196 ;; from double rounding.
6197 ;; Instead of creating a new cpu type for two FP operations, just use fp
6198 (define_insn_and_split "floatdisf2_internal1"
6199 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
6200 (float:SF (match_operand:DI 1 "gpc_reg_operand" "d")))
6201 (clobber (match_scratch:DF 2 "=d"))]
6202 "TARGET_FCFID && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && !TARGET_FCFIDS"
6204 "&& reload_completed"
6206 (float:DF (match_dup 1)))
6208 (float_truncate:SF (match_dup 2)))]
6210 [(set_attr "length" "8")
6211 (set_attr "type" "fp")])
6213 ;; Twiddles bits to avoid double rounding.
6214 ;; Bits that might be truncated when converting to DFmode are replaced
6215 ;; by a bit that won't be lost at that stage, but is below the SFmode
6216 ;; rounding position.
6217 (define_expand "floatdisf2_internal2"
6218 [(parallel [(set (match_dup 3) (ashiftrt:DI (match_operand:DI 1 "" "")
6220 (clobber (reg:DI CA_REGNO))])
6221 (set (match_operand:DI 0 "" "") (and:DI (match_dup 1)
6223 (set (match_dup 3) (plus:DI (match_dup 3)
6225 (set (match_dup 0) (plus:DI (match_dup 0)
6227 (set (match_dup 4) (compare:CCUNS (match_dup 3)
6229 (set (match_dup 0) (ior:DI (match_dup 0)
6231 (set (match_dup 0) (and:DI (match_dup 0)
6233 (set (pc) (if_then_else (geu (match_dup 4) (const_int 0))
6234 (label_ref (match_operand:DI 2 "" ""))
6236 (set (match_dup 0) (match_dup 1))]
6237 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6241 operands[3] = gen_reg_rtx (DImode);
6242 operands[4] = gen_reg_rtx (CCUNSmode);
6245 (define_expand "floatunsdisf2"
6246 [(set (match_operand:SF 0 "gpc_reg_operand" "")
6247 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "")))]
6248 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6249 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6252 (define_insn "floatunsdisf2_fcfidus"
6253 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wu")
6254 (unsigned_float:SF (match_operand:DI 1 "gpc_reg_operand" "d,wi")))]
6255 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6256 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6260 [(set_attr "type" "fp")])
6262 (define_insn_and_split "*floatunsdisf2_mem"
6263 [(set (match_operand:SF 0 "gpc_reg_operand" "=f,wy,wy")
6264 (unsigned_float:SF (match_operand:DI 1 "memory_operand" "m,m,Z")))
6265 (clobber (match_scratch:DI 2 "=d,d,wi"))]
6266 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
6267 && TARGET_DOUBLE_FLOAT && TARGET_FCFIDUS"
6269 "&& reload_completed"
6273 emit_move_insn (operands[2], operands[1]);
6274 emit_insn (gen_floatunsdisf2_fcfidus (operands[0], operands[2]));
6277 [(set_attr "length" "8")
6278 (set_attr "type" "fpload")])
6280 ;; Define the TImode operations that can be done in a small number
6281 ;; of instructions. The & constraints are to prevent the register
6282 ;; allocator from allocating registers that overlap with the inputs
6283 ;; (for example, having an input in 7,8 and an output in 6,7). We
6284 ;; also allow for the output being the same as one of the inputs.
6286 (define_expand "addti3"
6287 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6288 (plus:TI (match_operand:TI 1 "gpc_reg_operand" "")
6289 (match_operand:TI 2 "reg_or_short_operand" "")))]
6292 rtx lo0 = gen_lowpart (DImode, operands[0]);
6293 rtx lo1 = gen_lowpart (DImode, operands[1]);
6294 rtx lo2 = gen_lowpart (DImode, operands[2]);
6295 rtx hi0 = gen_highpart (DImode, operands[0]);
6296 rtx hi1 = gen_highpart (DImode, operands[1]);
6297 rtx hi2 = gen_highpart_mode (DImode, TImode, operands[2]);
6299 if (!reg_or_short_operand (lo2, DImode))
6300 lo2 = force_reg (DImode, lo2);
6301 if (!adde_operand (hi2, DImode))
6302 hi2 = force_reg (DImode, hi2);
6304 emit_insn (gen_adddi3_carry (lo0, lo1, lo2));
6305 emit_insn (gen_adddi3_carry_in (hi0, hi1, hi2));
6309 (define_expand "subti3"
6310 [(set (match_operand:TI 0 "gpc_reg_operand" "")
6311 (minus:TI (match_operand:TI 1 "reg_or_short_operand" "")
6312 (match_operand:TI 2 "gpc_reg_operand" "")))]
6315 rtx lo0 = gen_lowpart (DImode, operands[0]);
6316 rtx lo1 = gen_lowpart (DImode, operands[1]);
6317 rtx lo2 = gen_lowpart (DImode, operands[2]);
6318 rtx hi0 = gen_highpart (DImode, operands[0]);
6319 rtx hi1 = gen_highpart_mode (DImode, TImode, operands[1]);
6320 rtx hi2 = gen_highpart (DImode, operands[2]);
6322 if (!reg_or_short_operand (lo1, DImode))
6323 lo1 = force_reg (DImode, lo1);
6324 if (!adde_operand (hi1, DImode))
6325 hi1 = force_reg (DImode, hi1);
6327 emit_insn (gen_subfdi3_carry (lo0, lo2, lo1));
6328 emit_insn (gen_subfdi3_carry_in (hi0, hi2, hi1));
6332 ;; 128-bit logical operations expanders
6334 (define_expand "and<mode>3"
6335 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6336 (and:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6337 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6341 (define_expand "ior<mode>3"
6342 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6343 (ior:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6344 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6348 (define_expand "xor<mode>3"
6349 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6350 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6351 (match_operand:BOOL_128 2 "vlogical_operand" "")))]
6355 (define_expand "one_cmpl<mode>2"
6356 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6357 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6361 (define_expand "nor<mode>3"
6362 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6364 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6365 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6369 (define_expand "andc<mode>3"
6370 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6372 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6373 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6377 ;; Power8 vector logical instructions.
6378 (define_expand "eqv<mode>3"
6379 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6381 (xor:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" "")
6382 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6383 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6386 ;; Rewrite nand into canonical form
6387 (define_expand "nand<mode>3"
6388 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6390 (not:BOOL_128 (match_operand:BOOL_128 1 "vlogical_operand" ""))
6391 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))))]
6392 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6395 ;; The canonical form is to have the negated element first, so we need to
6396 ;; reverse arguments.
6397 (define_expand "orc<mode>3"
6398 [(set (match_operand:BOOL_128 0 "vlogical_operand" "")
6400 (not:BOOL_128 (match_operand:BOOL_128 2 "vlogical_operand" ""))
6401 (match_operand:BOOL_128 1 "vlogical_operand" "")))]
6402 "<MODE>mode == TImode || <MODE>mode == PTImode || TARGET_P8_VECTOR"
6405 ;; 128-bit logical operations insns and split operations
6406 (define_insn_and_split "*and<mode>3_internal"
6407 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6409 (match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6410 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")))]
6413 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6414 return "xxland %x0,%x1,%x2";
6416 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6417 return "vand %0,%1,%2";
6421 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6424 rs6000_split_logical (operands, AND, false, false, false);
6429 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6430 (const_string "veclogical")
6431 (const_string "integer")))
6432 (set (attr "length")
6434 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6437 (match_test "TARGET_POWERPC64")
6439 (const_string "16"))))])
6442 (define_insn_and_split "*bool<mode>3_internal"
6443 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6444 (match_operator:BOOL_128 3 "boolean_or_operator"
6445 [(match_operand:BOOL_128 1 "vlogical_operand" "%<BOOL_REGS_OP1>")
6446 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>")]))]
6449 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6450 return "xxl%q3 %x0,%x1,%x2";
6452 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6453 return "v%q3 %0,%1,%2";
6457 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6460 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, false);
6465 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6466 (const_string "veclogical")
6467 (const_string "integer")))
6468 (set (attr "length")
6470 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6473 (match_test "TARGET_POWERPC64")
6475 (const_string "16"))))])
6478 (define_insn_and_split "*boolc<mode>3_internal1"
6479 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6480 (match_operator:BOOL_128 3 "boolean_operator"
6482 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))
6483 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")]))]
6484 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6486 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6487 return "xxl%q3 %x0,%x1,%x2";
6489 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6490 return "v%q3 %0,%1,%2";
6494 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6495 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6498 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6503 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6504 (const_string "veclogical")
6505 (const_string "integer")))
6506 (set (attr "length")
6508 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6511 (match_test "TARGET_POWERPC64")
6513 (const_string "16"))))])
6515 (define_insn_and_split "*boolc<mode>3_internal2"
6516 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6517 (match_operator:TI2 3 "boolean_operator"
6519 (match_operand:TI2 2 "int_reg_operand" "r,0,r"))
6520 (match_operand:TI2 1 "int_reg_operand" "r,r,0")]))]
6521 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6523 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6526 rs6000_split_logical (operands, GET_CODE (operands[3]), false, false, true);
6529 [(set_attr "type" "integer")
6530 (set (attr "length")
6532 (match_test "TARGET_POWERPC64")
6534 (const_string "16")))])
6537 (define_insn_and_split "*boolcc<mode>3_internal1"
6538 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6539 (match_operator:BOOL_128 3 "boolean_operator"
6541 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>"))
6543 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))]))]
6544 "TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND)"
6546 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6547 return "xxl%q3 %x0,%x1,%x2";
6549 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6550 return "v%q3 %0,%1,%2";
6554 "(TARGET_P8_VECTOR || (GET_CODE (operands[3]) == AND))
6555 && reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6558 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6563 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6564 (const_string "veclogical")
6565 (const_string "integer")))
6566 (set (attr "length")
6568 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6571 (match_test "TARGET_POWERPC64")
6573 (const_string "16"))))])
6575 (define_insn_and_split "*boolcc<mode>3_internal2"
6576 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6577 (match_operator:TI2 3 "boolean_operator"
6579 (match_operand:TI2 1 "int_reg_operand" "r,0,r"))
6581 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))]))]
6582 "!TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6584 "reload_completed && !TARGET_P8_VECTOR && (GET_CODE (operands[3]) != AND)"
6587 rs6000_split_logical (operands, GET_CODE (operands[3]), false, true, true);
6590 [(set_attr "type" "integer")
6591 (set (attr "length")
6593 (match_test "TARGET_POWERPC64")
6595 (const_string "16")))])
6599 (define_insn_and_split "*eqv<mode>3_internal1"
6600 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6603 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_OP1>")
6604 (match_operand:BOOL_128 2 "vlogical_operand" "<BOOL_REGS_OP2>"))))]
6607 if (vsx_register_operand (operands[0], <MODE>mode))
6608 return "xxleqv %x0,%x1,%x2";
6612 "TARGET_P8_VECTOR && reload_completed
6613 && int_reg_operand (operands[0], <MODE>mode)"
6616 rs6000_split_logical (operands, XOR, true, false, false);
6621 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6622 (const_string "veclogical")
6623 (const_string "integer")))
6624 (set (attr "length")
6626 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6629 (match_test "TARGET_POWERPC64")
6631 (const_string "16"))))])
6633 (define_insn_and_split "*eqv<mode>3_internal2"
6634 [(set (match_operand:TI2 0 "int_reg_operand" "=&r,r,r")
6637 (match_operand:TI2 1 "int_reg_operand" "r,0,r")
6638 (match_operand:TI2 2 "int_reg_operand" "r,r,0"))))]
6641 "reload_completed && !TARGET_P8_VECTOR"
6644 rs6000_split_logical (operands, XOR, true, false, false);
6647 [(set_attr "type" "integer")
6648 (set (attr "length")
6650 (match_test "TARGET_POWERPC64")
6652 (const_string "16")))])
6654 ;; 128-bit one's complement
6655 (define_insn_and_split "*one_cmpl<mode>3_internal"
6656 [(set (match_operand:BOOL_128 0 "vlogical_operand" "=<BOOL_REGS_OUTPUT>")
6658 (match_operand:BOOL_128 1 "vlogical_operand" "<BOOL_REGS_UNARY>")))]
6661 if (TARGET_VSX && vsx_register_operand (operands[0], <MODE>mode))
6662 return "xxlnor %x0,%x1,%x1";
6664 if (TARGET_ALTIVEC && altivec_register_operand (operands[0], <MODE>mode))
6665 return "vnor %0,%1,%1";
6669 "reload_completed && int_reg_operand (operands[0], <MODE>mode)"
6672 rs6000_split_logical (operands, NOT, false, false, false);
6677 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6678 (const_string "veclogical")
6679 (const_string "integer")))
6680 (set (attr "length")
6682 (match_test "vsx_register_operand (operands[0], <MODE>mode)")
6685 (match_test "TARGET_POWERPC64")
6687 (const_string "16"))))])
6690 ;; Now define ways of moving data around.
6692 ;; Set up a register with a value from the GOT table
6694 (define_expand "movsi_got"
6695 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6696 (unspec:SI [(match_operand:SI 1 "got_operand" "")
6697 (match_dup 2)] UNSPEC_MOVSI_GOT))]
6698 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6701 if (GET_CODE (operands[1]) == CONST)
6703 rtx offset = const0_rtx;
6704 HOST_WIDE_INT value;
6706 operands[1] = eliminate_constant_term (XEXP (operands[1], 0), &offset);
6707 value = INTVAL (offset);
6710 rtx tmp = (!can_create_pseudo_p ()
6712 : gen_reg_rtx (Pmode));
6713 emit_insn (gen_movsi_got (tmp, operands[1]));
6714 emit_insn (gen_addsi3 (operands[0], tmp, offset));
6719 operands[2] = rs6000_got_register (operands[1]);
6722 (define_insn "*movsi_got_internal"
6723 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6724 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6725 (match_operand:SI 2 "gpc_reg_operand" "b")]
6727 "DEFAULT_ABI == ABI_V4 && flag_pic == 1"
6728 "lwz %0,%a1@got(%2)"
6729 [(set_attr "type" "load")])
6731 ;; Used by sched, shorten_branches and final when the GOT pseudo reg
6732 ;; didn't get allocated to a hard register.
6734 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6735 (unspec:SI [(match_operand:SI 1 "got_no_const_operand" "")
6736 (match_operand:SI 2 "memory_operand" "")]
6738 "DEFAULT_ABI == ABI_V4
6740 && reload_completed"
6741 [(set (match_dup 0) (match_dup 2))
6742 (set (match_dup 0) (unspec:SI [(match_dup 1)(match_dup 0)]
6746 ;; For SI, we special-case integers that can't be loaded in one insn. We
6747 ;; do the load 16-bits at a time. We could do this by loading from memory,
6748 ;; and this is even supposed to be faster, but it is simpler not to get
6749 ;; integers in the TOC.
6750 (define_insn "movsi_low"
6751 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
6752 (mem:SI (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
6753 (match_operand 2 "" ""))))]
6754 "TARGET_MACHO && ! TARGET_64BIT"
6755 "lwz %0,lo16(%2)(%1)"
6756 [(set_attr "type" "load")
6757 (set_attr "length" "4")])
6759 ;; MR LA LWZ LFIWZX LXSIWZX
6760 ;; STW STFIWX STXSIWX LI LIS
6761 ;; # XXLOR XXSPLTIB 0 XXSPLTIB -1 VSPLTISW
6762 ;; XXLXOR 0 XXLORC -1 P9 const MTVSRWZ MFVSRWZ
6763 ;; MF%1 MT%0 MT%0 NOP
6764 (define_insn "*movsi_internal1"
6765 [(set (match_operand:SI 0 "nonimmediate_operand"
6766 "=r, r, r, ?*wI, ?*wH,
6768 r, ?*wIwH, ?*wJwK, ?*wJwK, ?*wu,
6769 ?*wJwK, ?*wH, ?*wK, ?*wIwH, ?r,
6772 (match_operand:SI 1 "input_operand"
6779 "!TARGET_SINGLE_FPU &&
6780 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6807 "*, *, load, fpload, fpload,
6808 store, fpstore, fpstore, *, *,
6809 *, veclogical, vecsimple, vecsimple, vecsimple,
6810 veclogical, veclogical, vecsimple, mffgpr, mftgpr,
6820 (define_insn "*movsi_internal1_single"
6821 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,r,m,r,r,r,r,*c*l,*h,*h,m,*f")
6822 (match_operand:SI 1 "input_operand" "r,U,m,r,I,L,n,*h,r,r,0,f,m"))]
6823 "TARGET_SINGLE_FPU &&
6824 (gpc_reg_operand (operands[0], SImode) || gpc_reg_operand (operands[1], SImode))"
6839 [(set_attr "type" "*,*,load,store,*,*,*,mfjmpr,mtjmpr,*,*,fpstore,fpload")
6840 (set_attr "length" "4,4,4,4,4,4,8,4,4,4,4,4,4")])
6842 ;; Like movsi, but adjust a SF value to be used in a SI context, i.e.
6843 ;; (set (reg:SI ...) (subreg:SI (reg:SF ...) 0))
6845 ;; Because SF values are actually stored as DF values within the vector
6846 ;; registers, we need to convert the value to the vector SF format when
6847 ;; we need to use the bits in a union or similar cases. We only need
6848 ;; to do this transformation when the value is a vector register. Loads,
6849 ;; stores, and transfers within GPRs are assumed to be safe.
6851 ;; This is a more general case of reload_gpr_from_vsxsf. That insn must have
6852 ;; no alternatives, because the call is created as part of secondary_reload,
6853 ;; and operand #2's register class is used to allocate the temporary register.
6854 ;; This function is called before reload, and it creates the temporary as
6857 ;; MR LWZ LFIWZX LXSIWZX STW
6858 ;; STFS STXSSP STXSSPX VSX->GPR VSX->VSX
6861 (define_insn_and_split "movsi_from_sf"
6862 [(set (match_operand:SI 0 "nonimmediate_operand"
6863 "=r, r, ?*wI, ?*wH, m,
6864 m, wY, Z, r, ?*wIwH,
6867 (unspec:SI [(match_operand:SF 1 "input_operand"
6869 f, wb, wu, wIwH, wIwH,
6873 (clobber (match_scratch:V4SF 2
6878 "TARGET_NO_SF_SUBREG
6879 && (register_operand (operands[0], SImode)
6880 || register_operand (operands[1], SFmode))"
6893 "&& reload_completed
6894 && int_reg_operand (operands[0], SImode)
6895 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6898 rtx op0 = operands[0];
6899 rtx op1 = operands[1];
6900 rtx op2 = operands[2];
6901 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
6902 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6904 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6905 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
6909 "*, load, fpload, fpload, store,
6910 fpstore, fpstore, fpstore, mftgpr, fp,
6918 ;; movsi_from_sf with zero extension
6920 ;; RLDICL LWZ LFIWZX LXSIWZX VSX->GPR
6923 (define_insn_and_split "*movdi_from_sf_zero_ext"
6924 [(set (match_operand:DI 0 "gpc_reg_operand"
6925 "=r, r, ?*wI, ?*wH, r,
6929 (unspec:SI [(match_operand:SF 1 "input_operand"
6932 UNSPEC_SI_FROM_SF)))
6934 (clobber (match_scratch:V4SF 2
6938 "TARGET_DIRECT_MOVE_64BIT
6939 && (register_operand (operands[0], DImode)
6940 || register_operand (operands[1], SImode))"
6949 "&& reload_completed
6950 && register_operand (operands[0], DImode)
6951 && vsx_reg_sfsubreg_ok (operands[1], SFmode)"
6954 rtx op0 = operands[0];
6955 rtx op1 = operands[1];
6956 rtx op2 = operands[2];
6957 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
6959 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
6960 emit_insn (gen_zero_extendsidi2 (op0, op2_si));
6964 "*, load, fpload, fpload, two,
6971 ;; Like movsi_from_sf, but combine a convert from DFmode to SFmode before
6972 ;; moving it to SImode. We can do a SFmode store without having to do the
6973 ;; conversion explicitly. If we are doing a register->register conversion, use
6974 ;; XSCVDPSP instead of XSCVDPSPN, since the former handles cases where the
6975 ;; input will not fit in a SFmode, and the later assumes the value has already
6977 (define_insn "*movsi_from_df"
6978 [(set (match_operand:SI 0 "nonimmediate_operand" "=wa,m,wY,Z")
6979 (unspec:SI [(float_truncate:SF
6980 (match_operand:DF 1 "gpc_reg_operand" "wa, f,wb,wa"))]
6981 UNSPEC_SI_FROM_SF))]
6983 "TARGET_NO_SF_SUBREG"
6989 [(set_attr "type" "fp,fpstore,fpstore,fpstore")])
6991 ;; Split a load of a large constant into the appropriate two-insn
6995 [(set (match_operand:SI 0 "gpc_reg_operand" "")
6996 (match_operand:SI 1 "const_int_operand" ""))]
6997 "(unsigned HOST_WIDE_INT) (INTVAL (operands[1]) + 0x8000) >= 0x10000
6998 && (INTVAL (operands[1]) & 0xffff) != 0"
7002 (ior:SI (match_dup 0)
7006 if (rs6000_emit_set_const (operands[0], operands[1]))
7012 ;; Split loading -128..127 to use XXSPLITB and VEXTSW2D
7014 [(set (match_operand:DI 0 "altivec_register_operand")
7015 (match_operand:DI 1 "xxspltib_constant_split"))]
7016 "TARGET_P9_VECTOR && reload_completed"
7019 rtx op0 = operands[0];
7020 rtx op1 = operands[1];
7021 int r = REGNO (op0);
7022 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
7024 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
7025 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
7029 (define_insn "*mov<mode>_internal2"
7030 [(set (match_operand:CC 2 "cc_reg_operand" "=y,x,?y")
7031 (compare:CC (match_operand:P 1 "gpc_reg_operand" "0,r,r")
7033 (set (match_operand:P 0 "gpc_reg_operand" "=r,r,r") (match_dup 1))]
7039 [(set_attr "type" "cmp,logical,cmp")
7040 (set_attr "dot" "yes")
7041 (set_attr "length" "4,4,8")])
7044 [(set (match_operand:CC 2 "cc_reg_not_cr0_operand")
7045 (compare:CC (match_operand:P 1 "gpc_reg_operand")
7047 (set (match_operand:P 0 "gpc_reg_operand") (match_dup 1))]
7049 [(set (match_dup 0) (match_dup 1))
7051 (compare:CC (match_dup 0)
7055 (define_expand "mov<mode>"
7056 [(set (match_operand:INT 0 "general_operand" "")
7057 (match_operand:INT 1 "any_operand" ""))]
7059 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7061 ;; MR LHZ/LBZ LXSI*ZX STH/STB STXSI*X LI
7062 ;; XXLOR load 0 load -1 VSPLTI* # MFVSRWZ
7063 ;; MTVSRWZ MF%1 MT%1 NOP
7064 (define_insn "*mov<mode>_internal"
7065 [(set (match_operand:QHI 0 "nonimmediate_operand"
7066 "=r, r, ?*wJwK, m, Z, r,
7067 ?*wJwK, ?*wJwK, ?*wJwK, ?*wK, ?*wK, r,
7068 ?*wJwK, r, *c*l, *h")
7070 (match_operand:QHI 1 "input_operand"
7071 "r, m, Z, r, wJwK, i,
7072 wJwK, O, wM, wB, wS, ?*wJwK,
7075 "gpc_reg_operand (operands[0], <MODE>mode)
7076 || gpc_reg_operand (operands[1], <MODE>mode)"
7095 "*, load, fpload, store, fpstore, *,
7096 vecsimple, vecperm, vecperm, vecperm, vecperm, mftgpr,
7097 mffgpr, mfjmpr, mtjmpr, *")
7105 ;; Here is how to move condition codes around. When we store CC data in
7106 ;; an integer register or memory, we store just the high-order 4 bits.
7107 ;; This lets us not shift in the most common case of CR0.
7108 (define_expand "movcc"
7109 [(set (match_operand:CC 0 "nonimmediate_operand" "")
7110 (match_operand:CC 1 "nonimmediate_operand" ""))]
7114 (define_insn "*movcc_internal1"
7115 [(set (match_operand:CC 0 "nonimmediate_operand"
7116 "=y,x,?y,y,r,r,r,r,r,*c*l,r,m")
7117 (match_operand:CC 1 "general_operand"
7118 " y,r, r,O,x,y,r,I,h, r,m,r"))]
7119 "register_operand (operands[0], CCmode)
7120 || register_operand (operands[1], CCmode)"
7124 rlwinm %1,%1,%F0,0xffffffff\;mtcrf %R0,%1\;rlwinm %1,%1,%f0,0xffffffff
7127 mfcr %0%Q1\;rlwinm %0,%0,%f1,0xf0000000
7135 (cond [(eq_attr "alternative" "0,3")
7136 (const_string "cr_logical")
7137 (eq_attr "alternative" "1,2")
7138 (const_string "mtcr")
7139 (eq_attr "alternative" "6,7")
7140 (const_string "integer")
7141 (eq_attr "alternative" "8")
7142 (const_string "mfjmpr")
7143 (eq_attr "alternative" "9")
7144 (const_string "mtjmpr")
7145 (eq_attr "alternative" "10")
7146 (const_string "load")
7147 (eq_attr "alternative" "11")
7148 (const_string "store")
7149 (match_test "TARGET_MFCRF")
7150 (const_string "mfcrf")
7152 (const_string "mfcr")))
7153 (set_attr "length" "4,4,12,4,4,8,4,4,4,4,4,4")])
7155 ;; For floating-point, we normally deal with the floating-point registers
7156 ;; unless -msoft-float is used. The sole exception is that parameter passing
7157 ;; can produce floating-point values in fixed-point registers. Unless the
7158 ;; value is a simple constant or already in memory, we deal with this by
7159 ;; allocating memory and copying the value explicitly via that memory location.
7161 ;; Move 32-bit binary/decimal floating point
7162 (define_expand "mov<mode>"
7163 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "")
7164 (match_operand:FMOVE32 1 "any_operand" ""))]
7166 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7169 [(set (match_operand:FMOVE32 0 "gpc_reg_operand" "")
7170 (match_operand:FMOVE32 1 "const_double_operand" ""))]
7172 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7173 || (GET_CODE (operands[0]) == SUBREG
7174 && GET_CODE (SUBREG_REG (operands[0])) == REG
7175 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7176 [(set (match_dup 2) (match_dup 3))]
7181 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7183 if (! TARGET_POWERPC64)
7184 operands[2] = operand_subword (operands[0], 0, 0, <MODE>mode);
7186 operands[2] = gen_lowpart (SImode, operands[0]);
7188 operands[3] = gen_int_mode (l, SImode);
7191 ;; Originally, we tried to keep movsf and movsd common, but the differences
7192 ;; addressing was making it rather difficult to hide with mode attributes. In
7193 ;; particular for SFmode, on ISA 2.07 (power8) systems, having the GPR store
7194 ;; before the VSX stores meant that the register allocator would tend to do a
7195 ;; direct move to the GPR (which involves conversion from scalar to
7196 ;; vector/memory formats) to save values in the traditional Altivec registers,
7197 ;; while SDmode had problems on power6 if the GPR store was not first due to
7198 ;; the power6 not having an integer store operation.
7200 ;; LWZ LFS LXSSP LXSSPX STFS STXSSP
7201 ;; STXSSPX STW XXLXOR LI FMR XSCPSGNDP
7202 ;; MR MT<x> MF<x> NOP
7204 (define_insn "movsf_hardfloat"
7205 [(set (match_operand:SF 0 "nonimmediate_operand"
7206 "=!r, f, wb, wu, m, wY,
7207 Z, m, ww, !r, f, ww,
7209 (match_operand:SF 1 "input_operand"
7210 "m, m, wY, Z, f, wb,
7213 "(register_operand (operands[0], SFmode)
7214 || register_operand (operands[1], SFmode))
7215 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7216 && (TARGET_ALLOW_SF_SUBREG
7217 || valid_sf_si_move (operands[0], operands[1], SFmode))"
7230 xscpsgndp %x0,%x1,%x1
7236 "load, fpload, fpload, fpload, fpstore, fpstore,
7237 fpstore, store, veclogical, integer, fpsimple, fpsimple,
7238 *, mtjmpr, mfjmpr, *")])
7240 ;; LWZ LFIWZX STW STFIWX MTVSRWZ MFVSRWZ
7241 ;; FMR MR MT%0 MF%1 NOP
7242 (define_insn "movsd_hardfloat"
7243 [(set (match_operand:SD 0 "nonimmediate_operand"
7244 "=!r, wz, m, Z, ?wh, ?r,
7245 f, !r, *c*l, !r, *h")
7246 (match_operand:SD 1 "input_operand"
7247 "m, Z, r, wx, r, wh,
7249 "(register_operand (operands[0], SDmode)
7250 || register_operand (operands[1], SDmode))
7251 && TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT"
7265 "load, fpload, store, fpstore, mffgpr, mftgpr,
7266 fpsimple, *, mtjmpr, mfjmpr, *")])
7268 (define_insn "*mov<mode>_softfloat"
7269 [(set (match_operand:FMOVE32 0 "nonimmediate_operand" "=r,cl,r,r,m,r,r,r,r,*h")
7270 (match_operand:FMOVE32 1 "input_operand" "r,r,h,m,r,I,L,G,Fn,0"))]
7271 "(gpc_reg_operand (operands[0], <MODE>mode)
7272 || gpc_reg_operand (operands[1], <MODE>mode))
7273 && TARGET_SOFT_FLOAT"
7285 [(set_attr "type" "*,mtjmpr,mfjmpr,load,store,*,*,*,*,*")
7286 (set_attr "length" "4,4,4,4,4,4,4,4,8,4")])
7288 ;; Like movsf, but adjust a SI value to be used in a SF context, i.e.
7289 ;; (set (reg:SF ...) (subreg:SF (reg:SI ...) 0))
7291 ;; Because SF values are actually stored as DF values within the vector
7292 ;; registers, we need to convert the value to the vector SF format when
7293 ;; we need to use the bits in a union or similar cases. We only need
7294 ;; to do this transformation when the value is a vector register. Loads,
7295 ;; stores, and transfers within GPRs are assumed to be safe.
7297 ;; This is a more general case of reload_vsx_from_gprsf. That insn must have
7298 ;; no alternatives, because the call is created as part of secondary_reload,
7299 ;; and operand #2's register class is used to allocate the temporary register.
7300 ;; This function is called before reload, and it creates the temporary as
7303 ;; LWZ LFS LXSSP LXSSPX STW STFIWX
7304 ;; STXSIWX GPR->VSX VSX->GPR GPR->GPR
7305 (define_insn_and_split "movsf_from_si"
7306 [(set (match_operand:SF 0 "nonimmediate_operand"
7307 "=!r, f, wb, wu, m, Z,
7310 (unspec:SF [(match_operand:SI 1 "input_operand"
7315 (clobber (match_scratch:DI 2
7319 "TARGET_NO_SF_SUBREG
7320 && (register_operand (operands[0], SFmode)
7321 || register_operand (operands[1], SImode))"
7334 "&& reload_completed
7335 && vsx_reg_sfsubreg_ok (operands[0], SFmode)
7336 && int_reg_operand_not_pseudo (operands[1], SImode)"
7339 rtx op0 = operands[0];
7340 rtx op1 = operands[1];
7341 rtx op2 = operands[2];
7342 rtx op1_di = gen_rtx_REG (DImode, REGNO (op1));
7344 /* Move SF value to upper 32-bits for xscvspdpn. */
7345 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
7346 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
7347 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
7354 "load, fpload, fpload, fpload, store, fpstore,
7355 fpstore, vecfloat, mffgpr, *")])
7358 ;; Move 64-bit binary/decimal floating point
7359 (define_expand "mov<mode>"
7360 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "")
7361 (match_operand:FMOVE64 1 "any_operand" ""))]
7363 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7366 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7367 (match_operand:FMOVE64 1 "const_int_operand" ""))]
7368 "! TARGET_POWERPC64 && reload_completed
7369 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7370 || (GET_CODE (operands[0]) == SUBREG
7371 && GET_CODE (SUBREG_REG (operands[0])) == REG
7372 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7373 [(set (match_dup 2) (match_dup 4))
7374 (set (match_dup 3) (match_dup 1))]
7377 int endian = (WORDS_BIG_ENDIAN == 0);
7378 HOST_WIDE_INT value = INTVAL (operands[1]);
7380 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7381 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7382 operands[4] = GEN_INT (value >> 32);
7383 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
7387 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7388 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7389 "! TARGET_POWERPC64 && reload_completed
7390 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7391 || (GET_CODE (operands[0]) == SUBREG
7392 && GET_CODE (SUBREG_REG (operands[0])) == REG
7393 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7394 [(set (match_dup 2) (match_dup 4))
7395 (set (match_dup 3) (match_dup 5))]
7398 int endian = (WORDS_BIG_ENDIAN == 0);
7401 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7403 operands[2] = operand_subword (operands[0], endian, 0, <MODE>mode);
7404 operands[3] = operand_subword (operands[0], 1 - endian, 0, <MODE>mode);
7405 operands[4] = gen_int_mode (l[endian], SImode);
7406 operands[5] = gen_int_mode (l[1 - endian], SImode);
7410 [(set (match_operand:FMOVE64 0 "gpc_reg_operand" "")
7411 (match_operand:FMOVE64 1 "const_double_operand" ""))]
7412 "TARGET_POWERPC64 && reload_completed
7413 && ((GET_CODE (operands[0]) == REG && REGNO (operands[0]) <= 31)
7414 || (GET_CODE (operands[0]) == SUBREG
7415 && GET_CODE (SUBREG_REG (operands[0])) == REG
7416 && REGNO (SUBREG_REG (operands[0])) <= 31))"
7417 [(set (match_dup 2) (match_dup 3))]
7420 int endian = (WORDS_BIG_ENDIAN == 0);
7424 <real_value_to_target> (*CONST_DOUBLE_REAL_VALUE (operands[1]), l);
7426 operands[2] = gen_lowpart (DImode, operands[0]);
7427 /* HIGHPART is lower memory address when WORDS_BIG_ENDIAN. */
7428 val = ((HOST_WIDE_INT)(unsigned long)l[endian] << 32
7429 | ((HOST_WIDE_INT)(unsigned long)l[1 - endian]));
7431 operands[3] = gen_int_mode (val, DImode);
7434 ;; Don't have reload use general registers to load a constant. It is
7435 ;; less efficient than loading the constant into an FP register, since
7436 ;; it will probably be used there.
7438 ;; The move constraints are ordered to prefer floating point registers before
7439 ;; general purpose registers to avoid doing a store and a load to get the value
7440 ;; into a floating point register when it is needed for a floating point
7441 ;; operation. Prefer traditional floating point registers over VSX registers,
7442 ;; since the D-form version of the memory instructions does not need a GPR for
7443 ;; reloading. ISA 3.0 (power9) adds D-form addressing for scalars to Altivec
7446 ;; If we have FPR registers, rs6000_emit_move has moved all constants to memory,
7447 ;; except for 0.0 which can be created on VSX with an xor instruction.
7449 (define_insn "*mov<mode>_hardfloat32"
7450 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=m,d,d,<f64_p9>,wY,<f64_av>,Z,<f64_vsx>,<f64_vsx>,!r,Y,r,!r")
7451 (match_operand:FMOVE64 1 "input_operand" "d,m,d,wY,<f64_p9>,Z,<f64_av>,<f64_vsx>,<zero_fp>,<zero_fp>,r,Y,r"))]
7452 "! TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7453 && (gpc_reg_operand (operands[0], <MODE>mode)
7454 || gpc_reg_operand (operands[1], <MODE>mode))"
7469 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,two,store,load,two")
7470 (set_attr "size" "64")
7471 (set_attr "length" "4,4,4,4,4,4,4,4,4,8,8,8,8")])
7473 (define_insn "*mov<mode>_softfloat32"
7474 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,r,r,r")
7475 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,G,H,F"))]
7477 && (TARGET_SINGLE_FLOAT || TARGET_SOFT_FLOAT)
7478 && (gpc_reg_operand (operands[0], <MODE>mode)
7479 || gpc_reg_operand (operands[1], <MODE>mode))"
7481 [(set_attr "type" "store,load,two,*,*,*")
7482 (set_attr "length" "8,8,8,8,12,16")])
7484 ; ld/std require word-aligned displacements -> 'Y' constraint.
7485 ; List Y->r and r->Y before r->r for reload.
7486 (define_insn "*mov<mode>_hardfloat64"
7487 [(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>")
7488 (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"))]
7489 "TARGET_POWERPC64 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7490 && (gpc_reg_operand (operands[0], <MODE>mode)
7491 || gpc_reg_operand (operands[1], <MODE>mode))"
7513 [(set_attr "type" "fpstore,fpload,fpsimple,fpload,fpstore,fpload,fpstore,veclogical,veclogical,integer,store,load,*,mtjmpr,mfjmpr,*,mftgpr,mffgpr,mftgpr,mffgpr")
7514 (set_attr "size" "64")
7515 (set_attr "length" "4")])
7517 (define_insn "*mov<mode>_softfloat64"
7518 [(set (match_operand:FMOVE64 0 "nonimmediate_operand" "=Y,r,r,cl,r,r,r,r,*h")
7519 (match_operand:FMOVE64 1 "input_operand" "r,Y,r,r,h,G,H,F,0"))]
7520 "TARGET_POWERPC64 && TARGET_SOFT_FLOAT
7521 && (gpc_reg_operand (operands[0], <MODE>mode)
7522 || gpc_reg_operand (operands[1], <MODE>mode))"
7533 [(set_attr "type" "store,load,*,mtjmpr,mfjmpr,*,*,*,*")
7534 (set_attr "length" "4,4,4,4,4,8,12,16,4")])
7536 (define_expand "mov<mode>"
7537 [(set (match_operand:FMOVE128 0 "general_operand" "")
7538 (match_operand:FMOVE128 1 "any_operand" ""))]
7540 "{ rs6000_emit_move (operands[0], operands[1], <MODE>mode); DONE; }")
7542 ;; It's important to list Y->r and r->Y before r->r because otherwise
7543 ;; reload, given m->r, will try to pick r->r and reload it, which
7544 ;; doesn't make progress.
7546 ;; We can't split little endian direct moves of TDmode, because the words are
7547 ;; not swapped like they are for TImode or TFmode. Subregs therefore are
7548 ;; problematical. Don't allow direct move for this case.
7550 (define_insn_and_split "*mov<mode>_64bit_dm"
7551 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r,r,wh")
7552 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r,wh,r"))]
7553 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && FLOAT128_2REG_P (<MODE>mode)
7554 && (<MODE>mode != TDmode || WORDS_BIG_ENDIAN)
7555 && (gpc_reg_operand (operands[0], <MODE>mode)
7556 || gpc_reg_operand (operands[1], <MODE>mode))"
7558 "&& reload_completed"
7560 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7561 [(set_attr "length" "8,8,8,8,12,12,8,8,8")])
7563 (define_insn_and_split "*movtd_64bit_nodm"
7564 [(set (match_operand:TD 0 "nonimmediate_operand" "=m,d,d,Y,r,r")
7565 (match_operand:TD 1 "input_operand" "d,m,d,r,Y,r"))]
7566 "TARGET_HARD_FLOAT && TARGET_POWERPC64 && !WORDS_BIG_ENDIAN
7567 && (gpc_reg_operand (operands[0], TDmode)
7568 || gpc_reg_operand (operands[1], TDmode))"
7570 "&& reload_completed"
7572 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7573 [(set_attr "length" "8,8,8,12,12,8")])
7575 (define_insn_and_split "*mov<mode>_32bit"
7576 [(set (match_operand:FMOVE128_FPR 0 "nonimmediate_operand" "=m,d,d,d,Y,r,r")
7577 (match_operand:FMOVE128_FPR 1 "input_operand" "d,m,d,<zero_fp>,r,<zero_fp>Y,r"))]
7578 "TARGET_HARD_FLOAT && !TARGET_POWERPC64
7579 && (FLOAT128_2REG_P (<MODE>mode)
7580 || int_reg_operand_not_pseudo (operands[0], <MODE>mode)
7581 || int_reg_operand_not_pseudo (operands[1], <MODE>mode))
7582 && (gpc_reg_operand (operands[0], <MODE>mode)
7583 || gpc_reg_operand (operands[1], <MODE>mode))"
7585 "&& reload_completed"
7587 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7588 [(set_attr "length" "8,8,8,8,20,20,16")])
7590 (define_insn_and_split "*mov<mode>_softfloat"
7591 [(set (match_operand:FMOVE128 0 "nonimmediate_operand" "=Y,r,r")
7592 (match_operand:FMOVE128 1 "input_operand" "r,YGHF,r"))]
7594 && (gpc_reg_operand (operands[0], <MODE>mode)
7595 || gpc_reg_operand (operands[1], <MODE>mode))"
7597 "&& reload_completed"
7599 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; }
7600 [(set_attr "length" "20,20,16")])
7602 (define_expand "extenddf<mode>2"
7603 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7604 (float_extend:FLOAT128 (match_operand:DF 1 "gpc_reg_operand" "")))]
7605 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7607 if (FLOAT128_IEEE_P (<MODE>mode))
7608 rs6000_expand_float128_convert (operands[0], operands[1], false);
7609 else if (TARGET_VSX)
7611 if (<MODE>mode == TFmode)
7612 emit_insn (gen_extenddftf2_vsx (operands[0], operands[1]));
7613 else if (<MODE>mode == IFmode)
7614 emit_insn (gen_extenddfif2_vsx (operands[0], operands[1]));
7620 rtx zero = gen_reg_rtx (DFmode);
7621 rs6000_emit_move (zero, CONST0_RTX (DFmode), DFmode);
7623 if (<MODE>mode == TFmode)
7624 emit_insn (gen_extenddftf2_fprs (operands[0], operands[1], zero));
7625 else if (<MODE>mode == IFmode)
7626 emit_insn (gen_extenddfif2_fprs (operands[0], operands[1], zero));
7633 ;; Allow memory operands for the source to be created by the combiner.
7634 (define_insn_and_split "extenddf<mode>2_fprs"
7635 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d,&d")
7636 (float_extend:IBM128
7637 (match_operand:DF 1 "nonimmediate_operand" "d,m,d")))
7638 (use (match_operand:DF 2 "nonimmediate_operand" "m,m,d"))]
7639 "!TARGET_VSX && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT
7640 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7642 "&& reload_completed"
7643 [(set (match_dup 3) (match_dup 1))
7644 (set (match_dup 4) (match_dup 2))]
7646 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7647 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7649 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7650 operands[4] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7653 (define_insn_and_split "extenddf<mode>2_vsx"
7654 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d,d")
7655 (float_extend:IBM128
7656 (match_operand:DF 1 "nonimmediate_operand" "ws,m")))]
7657 "TARGET_LONG_DOUBLE_128 && TARGET_VSX && FLOAT128_IBM_P (<MODE>mode)"
7659 "&& reload_completed"
7660 [(set (match_dup 2) (match_dup 1))
7661 (set (match_dup 3) (match_dup 4))]
7663 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
7664 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
7666 operands[2] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
7667 operands[3] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
7668 operands[4] = CONST0_RTX (DFmode);
7671 (define_expand "extendsf<mode>2"
7672 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7673 (float_extend:FLOAT128 (match_operand:SF 1 "gpc_reg_operand" "")))]
7674 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7676 if (FLOAT128_IEEE_P (<MODE>mode))
7677 rs6000_expand_float128_convert (operands[0], operands[1], false);
7680 rtx tmp = gen_reg_rtx (DFmode);
7681 emit_insn (gen_extendsfdf2 (tmp, operands[1]));
7682 emit_insn (gen_extenddf<mode>2 (operands[0], tmp));
7687 (define_expand "trunc<mode>df2"
7688 [(set (match_operand:DF 0 "gpc_reg_operand" "")
7689 (float_truncate:DF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7690 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7692 if (FLOAT128_IEEE_P (<MODE>mode))
7694 rs6000_expand_float128_convert (operands[0], operands[1], false);
7699 (define_insn_and_split "trunc<mode>df2_internal1"
7700 [(set (match_operand:DF 0 "gpc_reg_operand" "=d,?d")
7702 (match_operand:IBM128 1 "gpc_reg_operand" "0,d")))]
7703 "FLOAT128_IBM_P (<MODE>mode) && !TARGET_XL_COMPAT
7704 && TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7708 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
7711 emit_note (NOTE_INSN_DELETED);
7714 [(set_attr "type" "fpsimple")])
7716 (define_insn "trunc<mode>df2_internal2"
7717 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7718 (float_truncate:DF (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7719 "FLOAT128_IBM_P (<MODE>mode) && TARGET_XL_COMPAT && TARGET_HARD_FLOAT
7720 && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
7722 [(set_attr "type" "fp")
7723 (set_attr "fp_type" "fp_addsub_d")])
7725 (define_expand "trunc<mode>sf2"
7726 [(set (match_operand:SF 0 "gpc_reg_operand" "")
7727 (float_truncate:SF (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7728 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7730 if (FLOAT128_IEEE_P (<MODE>mode))
7731 rs6000_expand_float128_convert (operands[0], operands[1], false);
7732 else if (<MODE>mode == TFmode)
7733 emit_insn (gen_trunctfsf2_fprs (operands[0], operands[1]));
7734 else if (<MODE>mode == IFmode)
7735 emit_insn (gen_truncifsf2_fprs (operands[0], operands[1]));
7741 (define_insn_and_split "trunc<mode>sf2_fprs"
7742 [(set (match_operand:SF 0 "gpc_reg_operand" "=f")
7743 (float_truncate:SF (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7744 (clobber (match_scratch:DF 2 "=d"))]
7745 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT
7746 && TARGET_LONG_DOUBLE_128 && FLOAT128_IBM_P (<MODE>mode)"
7748 "&& reload_completed"
7750 (float_truncate:DF (match_dup 1)))
7752 (float_truncate:SF (match_dup 2)))]
7755 (define_expand "floatsi<mode>2"
7756 [(parallel [(set (match_operand:FLOAT128 0 "gpc_reg_operand")
7757 (float:FLOAT128 (match_operand:SI 1 "gpc_reg_operand")))
7758 (clobber (match_scratch:DI 2))])]
7759 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7761 rtx op0 = operands[0];
7762 rtx op1 = operands[1];
7764 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7766 else if (FLOAT128_IEEE_P (<MODE>mode))
7768 rs6000_expand_float128_convert (op0, op1, false);
7773 rtx tmp = gen_reg_rtx (DFmode);
7774 expand_float (tmp, op1, false);
7775 if (<MODE>mode == TFmode)
7776 emit_insn (gen_extenddftf2 (op0, tmp));
7777 else if (<MODE>mode == IFmode)
7778 emit_insn (gen_extenddfif2 (op0, tmp));
7785 ; fadd, but rounding towards zero.
7786 ; This is probably not the optimal code sequence.
7787 (define_insn "fix_trunc_helper<mode>"
7788 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
7789 (unspec:DF [(match_operand:IBM128 1 "gpc_reg_operand" "d")]
7790 UNSPEC_FIX_TRUNC_TF))
7791 (clobber (match_operand:DF 2 "gpc_reg_operand" "=&d"))]
7792 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && FLOAT128_IBM_P (<MODE>mode)"
7793 "mffs %2\n\tmtfsb1 31\n\tmtfsb0 30\n\tfadd %0,%1,%L1\n\tmtfsf 1,%2"
7794 [(set_attr "type" "fp")
7795 (set_attr "length" "20")])
7797 (define_expand "fix_trunc<mode>si2"
7798 [(set (match_operand:SI 0 "gpc_reg_operand" "")
7799 (fix:SI (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7800 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7802 rtx op0 = operands[0];
7803 rtx op1 = operands[1];
7805 if (TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode))
7809 if (FLOAT128_IEEE_P (<MODE>mode))
7810 rs6000_expand_float128_convert (op0, op1, false);
7811 else if (<MODE>mode == TFmode)
7812 emit_insn (gen_fix_trunctfsi2_fprs (op0, op1));
7813 else if (<MODE>mode == IFmode)
7814 emit_insn (gen_fix_truncifsi2_fprs (op0, op1));
7821 (define_expand "fix_trunc<mode>si2_fprs"
7822 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
7823 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "")))
7824 (clobber (match_dup 2))
7825 (clobber (match_dup 3))
7826 (clobber (match_dup 4))
7827 (clobber (match_dup 5))])]
7828 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7830 operands[2] = gen_reg_rtx (DFmode);
7831 operands[3] = gen_reg_rtx (DFmode);
7832 operands[4] = gen_reg_rtx (DImode);
7833 operands[5] = assign_stack_temp (DImode, GET_MODE_SIZE (DImode));
7836 (define_insn_and_split "*fix_trunc<mode>si2_internal"
7837 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
7838 (fix:SI (match_operand:IBM128 1 "gpc_reg_operand" "d")))
7839 (clobber (match_operand:DF 2 "gpc_reg_operand" "=d"))
7840 (clobber (match_operand:DF 3 "gpc_reg_operand" "=&d"))
7841 (clobber (match_operand:DI 4 "gpc_reg_operand" "=d"))
7842 (clobber (match_operand:DI 5 "offsettable_mem_operand" "=o"))]
7843 "TARGET_HARD_FLOAT && TARGET_LONG_DOUBLE_128"
7849 emit_insn (gen_fix_trunc_helper<mode> (operands[2], operands[1],
7852 gcc_assert (MEM_P (operands[5]));
7853 lowword = adjust_address (operands[5], SImode, WORDS_BIG_ENDIAN ? 4 : 0);
7855 emit_insn (gen_fctiwz_df (operands[4], operands[2]));
7856 emit_move_insn (operands[5], operands[4]);
7857 emit_move_insn (operands[0], lowword);
7861 (define_expand "fix_trunc<mode>di2"
7862 [(set (match_operand:DI 0 "gpc_reg_operand" "")
7863 (fix:DI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7864 "TARGET_FLOAT128_TYPE"
7866 if (!TARGET_FLOAT128_HW)
7868 rs6000_expand_float128_convert (operands[0], operands[1], false);
7873 (define_expand "fixuns_trunc<IEEE128:mode><SDI:mode>2"
7874 [(set (match_operand:SDI 0 "gpc_reg_operand" "")
7875 (unsigned_fix:SDI (match_operand:IEEE128 1 "gpc_reg_operand" "")))]
7876 "TARGET_FLOAT128_TYPE"
7878 rs6000_expand_float128_convert (operands[0], operands[1], true);
7882 (define_expand "floatdi<mode>2"
7883 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7884 (float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7885 "TARGET_FLOAT128_TYPE"
7887 if (!TARGET_FLOAT128_HW)
7889 rs6000_expand_float128_convert (operands[0], operands[1], false);
7894 (define_expand "floatunsdi<IEEE128:mode>2"
7895 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7896 (unsigned_float:IEEE128 (match_operand:DI 1 "gpc_reg_operand" "")))]
7897 "TARGET_FLOAT128_TYPE"
7899 if (!TARGET_FLOAT128_HW)
7901 rs6000_expand_float128_convert (operands[0], operands[1], true);
7906 (define_expand "floatuns<IEEE128:mode>2"
7907 [(set (match_operand:IEEE128 0 "gpc_reg_operand" "")
7908 (unsigned_float:IEEE128 (match_operand:SI 1 "gpc_reg_operand" "")))]
7909 "TARGET_FLOAT128_TYPE"
7911 rtx op0 = operands[0];
7912 rtx op1 = operands[1];
7914 if (TARGET_FLOAT128_HW)
7915 emit_insn (gen_floatuns_<IEEE128:mode>si2_hw (op0, op1));
7917 rs6000_expand_float128_convert (op0, op1, true);
7921 (define_expand "neg<mode>2"
7922 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7923 (neg:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7924 "FLOAT128_IEEE_P (<MODE>mode)
7925 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7928 if (FLOAT128_IEEE_P (<MODE>mode))
7930 if (TARGET_FLOAT128_HW)
7932 if (<MODE>mode == TFmode)
7933 emit_insn (gen_negtf2_hw (operands[0], operands[1]));
7934 else if (<MODE>mode == KFmode)
7935 emit_insn (gen_negkf2_hw (operands[0], operands[1]));
7939 else if (TARGET_FLOAT128_TYPE)
7941 if (<MODE>mode == TFmode)
7942 emit_insn (gen_ieee_128bit_vsx_negtf2 (operands[0], operands[1]));
7943 else if (<MODE>mode == KFmode)
7944 emit_insn (gen_ieee_128bit_vsx_negkf2 (operands[0], operands[1]));
7950 rtx libfunc = optab_libfunc (neg_optab, <MODE>mode);
7951 rtx target = emit_library_call_value (libfunc, operands[0], LCT_CONST,
7953 operands[1], <MODE>mode);
7955 if (target && !rtx_equal_p (target, operands[0]))
7956 emit_move_insn (operands[0], target);
7962 (define_insn "neg<mode>2_internal"
7963 [(set (match_operand:IBM128 0 "gpc_reg_operand" "=d")
7964 (neg:IBM128 (match_operand:IBM128 1 "gpc_reg_operand" "d")))]
7965 "TARGET_HARD_FLOAT && FLOAT128_IBM_P (TFmode)"
7968 if (REGNO (operands[0]) == REGNO (operands[1]) + 1)
7969 return \"fneg %L0,%L1\;fneg %0,%1\";
7971 return \"fneg %0,%1\;fneg %L0,%L1\";
7973 [(set_attr "type" "fpsimple")
7974 (set_attr "length" "8")])
7976 (define_expand "abs<mode>2"
7977 [(set (match_operand:FLOAT128 0 "gpc_reg_operand" "")
7978 (abs:FLOAT128 (match_operand:FLOAT128 1 "gpc_reg_operand" "")))]
7979 "FLOAT128_IEEE_P (<MODE>mode)
7980 || (FLOAT128_IBM_P (<MODE>mode) && TARGET_HARD_FLOAT)"
7985 if (FLOAT128_IEEE_P (<MODE>mode))
7987 if (TARGET_FLOAT128_HW)
7989 if (<MODE>mode == TFmode)
7990 emit_insn (gen_abstf2_hw (operands[0], operands[1]));
7991 else if (<MODE>mode == KFmode)
7992 emit_insn (gen_abskf2_hw (operands[0], operands[1]));
7997 else if (TARGET_FLOAT128_TYPE)
7999 if (<MODE>mode == TFmode)
8000 emit_insn (gen_ieee_128bit_vsx_abstf2 (operands[0], operands[1]));
8001 else if (<MODE>mode == KFmode)
8002 emit_insn (gen_ieee_128bit_vsx_abskf2 (operands[0], operands[1]));
8011 label = gen_label_rtx ();
8012 if (<MODE>mode == TFmode)
8013 emit_insn (gen_abstf2_internal (operands[0], operands[1], label));
8014 else if (<MODE>mode == TFmode)
8015 emit_insn (gen_absif2_internal (operands[0], operands[1], label));
8022 (define_expand "abs<mode>2_internal"
8023 [(set (match_operand:IBM128 0 "gpc_reg_operand" "")
8024 (match_operand:IBM128 1 "gpc_reg_operand" ""))
8025 (set (match_dup 3) (match_dup 5))
8026 (set (match_dup 5) (abs:DF (match_dup 5)))
8027 (set (match_dup 4) (compare:CCFP (match_dup 3) (match_dup 5)))
8028 (set (pc) (if_then_else (eq (match_dup 4) (const_int 0))
8029 (label_ref (match_operand 2 "" ""))
8031 (set (match_dup 6) (neg:DF (match_dup 6)))]
8032 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
8035 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
8036 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
8037 operands[3] = gen_reg_rtx (DFmode);
8038 operands[4] = gen_reg_rtx (CCFPmode);
8039 operands[5] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, hi_word);
8040 operands[6] = simplify_gen_subreg (DFmode, operands[0], <MODE>mode, lo_word);
8044 ;; Generate IEEE 128-bit -0.0 (0x80000000000000000000000000000000) in a vector
8047 (define_expand "ieee_128bit_negative_zero"
8048 [(set (match_operand:V16QI 0 "register_operand" "") (match_dup 1))]
8049 "TARGET_FLOAT128_TYPE"
8051 rtvec v = rtvec_alloc (16);
8054 for (i = 0; i < 16; i++)
8055 RTVEC_ELT (v, i) = const0_rtx;
8057 high = (BYTES_BIG_ENDIAN) ? 0 : 15;
8058 RTVEC_ELT (v, high) = gen_int_mode (0x80, QImode);
8060 rs6000_expand_vector_init (operands[0], gen_rtx_PARALLEL (V16QImode, v));
8064 ;; IEEE 128-bit negate
8066 ;; We have 2 insns here for negate and absolute value. The first uses
8067 ;; match_scratch so that phases like combine can recognize neg/abs as generic
8068 ;; insns, and second insn after the first split pass loads up the bit to
8069 ;; twiddle the sign bit. Later GCSE passes can then combine multiple uses of
8070 ;; neg/abs to create the constant just once.
8072 (define_insn_and_split "ieee_128bit_vsx_neg<mode>2"
8073 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8074 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8075 (clobber (match_scratch:V16QI 2 "=v"))]
8076 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8079 [(parallel [(set (match_dup 0)
8080 (neg:IEEE128 (match_dup 1)))
8081 (use (match_dup 2))])]
8083 if (GET_CODE (operands[2]) == SCRATCH)
8084 operands[2] = gen_reg_rtx (V16QImode);
8086 operands[3] = gen_reg_rtx (V16QImode);
8087 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8089 [(set_attr "length" "8")
8090 (set_attr "type" "vecsimple")])
8092 (define_insn "*ieee_128bit_vsx_neg<mode>2_internal"
8093 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8094 (neg:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8095 (use (match_operand:V16QI 2 "register_operand" "v"))]
8096 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8097 "xxlxor %x0,%x1,%x2"
8098 [(set_attr "type" "veclogical")])
8100 ;; IEEE 128-bit absolute value
8101 (define_insn_and_split "ieee_128bit_vsx_abs<mode>2"
8102 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8103 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8104 (clobber (match_scratch:V16QI 2 "=v"))]
8105 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
8108 [(parallel [(set (match_dup 0)
8109 (abs:IEEE128 (match_dup 1)))
8110 (use (match_dup 2))])]
8112 if (GET_CODE (operands[2]) == SCRATCH)
8113 operands[2] = gen_reg_rtx (V16QImode);
8115 operands[3] = gen_reg_rtx (V16QImode);
8116 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8118 [(set_attr "length" "8")
8119 (set_attr "type" "vecsimple")])
8121 (define_insn "*ieee_128bit_vsx_abs<mode>2_internal"
8122 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8123 (abs:IEEE128 (match_operand:IEEE128 1 "register_operand" "wa")))
8124 (use (match_operand:V16QI 2 "register_operand" "v"))]
8125 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8126 "xxlandc %x0,%x1,%x2"
8127 [(set_attr "type" "veclogical")])
8129 ;; IEEE 128-bit negative absolute value
8130 (define_insn_and_split "*ieee_128bit_vsx_nabs<mode>2"
8131 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8134 (match_operand:IEEE128 1 "register_operand" "wa"))))
8135 (clobber (match_scratch:V16QI 2 "=v"))]
8136 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW
8137 && FLOAT128_IEEE_P (<MODE>mode)"
8140 [(parallel [(set (match_dup 0)
8141 (neg:IEEE128 (abs:IEEE128 (match_dup 1))))
8142 (use (match_dup 2))])]
8144 if (GET_CODE (operands[2]) == SCRATCH)
8145 operands[2] = gen_reg_rtx (V16QImode);
8147 operands[3] = gen_reg_rtx (V16QImode);
8148 emit_insn (gen_ieee_128bit_negative_zero (operands[2]));
8150 [(set_attr "length" "8")
8151 (set_attr "type" "vecsimple")])
8153 (define_insn "*ieee_128bit_vsx_nabs<mode>2_internal"
8154 [(set (match_operand:IEEE128 0 "register_operand" "=wa")
8157 (match_operand:IEEE128 1 "register_operand" "wa"))))
8158 (use (match_operand:V16QI 2 "register_operand" "v"))]
8159 "TARGET_FLOAT128_TYPE && !TARGET_FLOAT128_HW"
8161 [(set_attr "type" "veclogical")])
8163 ;; Float128 conversion functions. These expand to library function calls.
8164 ;; We use expand to convert from IBM double double to IEEE 128-bit
8165 ;; and trunc for the opposite.
8166 (define_expand "extendiftf2"
8167 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8168 (float_extend:TF (match_operand:IF 1 "gpc_reg_operand" "")))]
8169 "TARGET_FLOAT128_TYPE"
8171 rs6000_expand_float128_convert (operands[0], operands[1], false);
8175 (define_expand "extendifkf2"
8176 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8177 (float_extend:KF (match_operand:IF 1 "gpc_reg_operand" "")))]
8178 "TARGET_FLOAT128_TYPE"
8180 rs6000_expand_float128_convert (operands[0], operands[1], false);
8184 (define_expand "extendtfkf2"
8185 [(set (match_operand:KF 0 "gpc_reg_operand" "")
8186 (float_extend:KF (match_operand:TF 1 "gpc_reg_operand" "")))]
8187 "TARGET_FLOAT128_TYPE"
8189 rs6000_expand_float128_convert (operands[0], operands[1], false);
8193 (define_expand "trunciftf2"
8194 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8195 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8196 "TARGET_FLOAT128_TYPE"
8198 rs6000_expand_float128_convert (operands[0], operands[1], false);
8202 (define_expand "truncifkf2"
8203 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8204 (float_truncate:IF (match_operand:KF 1 "gpc_reg_operand" "")))]
8205 "TARGET_FLOAT128_TYPE"
8207 rs6000_expand_float128_convert (operands[0], operands[1], false);
8211 (define_expand "trunckftf2"
8212 [(set (match_operand:TF 0 "gpc_reg_operand" "")
8213 (float_truncate:TF (match_operand:KF 1 "gpc_reg_operand" "")))]
8214 "TARGET_FLOAT128_TYPE"
8216 rs6000_expand_float128_convert (operands[0], operands[1], false);
8220 (define_expand "trunctfif2"
8221 [(set (match_operand:IF 0 "gpc_reg_operand" "")
8222 (float_truncate:IF (match_operand:TF 1 "gpc_reg_operand" "")))]
8223 "TARGET_FLOAT128_TYPE"
8225 rs6000_expand_float128_convert (operands[0], operands[1], false);
8230 ;; Reload helper functions used by rs6000_secondary_reload. The patterns all
8231 ;; must have 3 arguments, and scratch register constraint must be a single
8234 ;; Reload patterns to support gpr load/store with misaligned mem.
8235 ;; and multiple gpr load/store at offset >= 0xfffc
8236 (define_expand "reload_<mode>_store"
8237 [(parallel [(match_operand 0 "memory_operand" "=m")
8238 (match_operand 1 "gpc_reg_operand" "r")
8239 (match_operand:GPR 2 "register_operand" "=&b")])]
8242 rs6000_secondary_reload_gpr (operands[1], operands[0], operands[2], true);
8246 (define_expand "reload_<mode>_load"
8247 [(parallel [(match_operand 0 "gpc_reg_operand" "=r")
8248 (match_operand 1 "memory_operand" "m")
8249 (match_operand:GPR 2 "register_operand" "=b")])]
8252 rs6000_secondary_reload_gpr (operands[0], operands[1], operands[2], false);
8257 ;; Reload patterns for various types using the vector registers. We may need
8258 ;; an additional base register to convert the reg+offset addressing to reg+reg
8259 ;; for vector registers and reg+reg or (reg+reg)&(-16) addressing to just an
8260 ;; index register for gpr registers.
8261 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_store"
8262 [(parallel [(match_operand:RELOAD 0 "memory_operand" "m")
8263 (match_operand:RELOAD 1 "gpc_reg_operand" "wa")
8264 (match_operand:P 2 "register_operand" "=b")])]
8267 rs6000_secondary_reload_inner (operands[1], operands[0], operands[2], true);
8271 (define_expand "reload_<RELOAD:mode>_<P:mptrsize>_load"
8272 [(parallel [(match_operand:RELOAD 0 "gpc_reg_operand" "wa")
8273 (match_operand:RELOAD 1 "memory_operand" "m")
8274 (match_operand:P 2 "register_operand" "=b")])]
8277 rs6000_secondary_reload_inner (operands[0], operands[1], operands[2], false);
8282 ;; Reload sometimes tries to move the address to a GPR, and can generate
8283 ;; invalid RTL for addresses involving AND -16. Allow addresses involving
8284 ;; reg+reg, reg+small constant, or just reg, all wrapped in an AND -16.
8286 (define_insn_and_split "*vec_reload_and_plus_<mptrsize>"
8287 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
8288 (and:P (plus:P (match_operand:P 1 "gpc_reg_operand" "r")
8289 (match_operand:P 2 "reg_or_cint_operand" "rI"))
8291 "TARGET_ALTIVEC && reload_completed"
8293 "&& reload_completed"
8295 (plus:P (match_dup 1)
8298 (and:P (match_dup 0)
8301 ;; Power8 merge instructions to allow direct move to/from floating point
8302 ;; registers in 32-bit mode. We use TF mode to get two registers to move the
8303 ;; individual 32-bit parts across. Subreg doesn't work too well on the TF
8304 ;; value, since it is allocated in reload and not all of the flow information
8305 ;; is setup for it. We have two patterns to do the two moves between gprs and
8306 ;; fprs. There isn't a dependancy between the two, but we could potentially
8307 ;; schedule other instructions between the two instructions.
8309 (define_insn "p8_fmrgow_<mode>"
8310 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8312 (match_operand:DF 1 "register_operand" "d")
8313 (match_operand:DF 2 "register_operand" "d")]
8314 UNSPEC_P8V_FMRGOW))]
8315 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8317 [(set_attr "type" "fpsimple")])
8319 (define_insn "p8_mtvsrwz"
8320 [(set (match_operand:DF 0 "register_operand" "=d")
8321 (unspec:DF [(match_operand:SI 1 "register_operand" "r")]
8322 UNSPEC_P8V_MTVSRWZ))]
8323 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8325 [(set_attr "type" "mftgpr")])
8327 (define_insn_and_split "reload_fpr_from_gpr<mode>"
8328 [(set (match_operand:FMOVE64X 0 "register_operand" "=d")
8329 (unspec:FMOVE64X [(match_operand:FMOVE64X 1 "register_operand" "r")]
8330 UNSPEC_P8V_RELOAD_FROM_GPR))
8331 (clobber (match_operand:IF 2 "register_operand" "=d"))]
8332 "!TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8334 "&& reload_completed"
8337 rtx dest = operands[0];
8338 rtx src = operands[1];
8339 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8340 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8341 rtx gpr_hi_reg = gen_highpart (SImode, src);
8342 rtx gpr_lo_reg = gen_lowpart (SImode, src);
8344 emit_insn (gen_p8_mtvsrwz (tmp_hi, gpr_hi_reg));
8345 emit_insn (gen_p8_mtvsrwz (tmp_lo, gpr_lo_reg));
8346 emit_insn (gen_p8_fmrgow_<mode> (dest, tmp_hi, tmp_lo));
8349 [(set_attr "length" "12")
8350 (set_attr "type" "three")])
8352 ;; Move 128 bit values from GPRs to VSX registers in 64-bit mode
8353 (define_insn "p8_mtvsrd_df"
8354 [(set (match_operand:DF 0 "register_operand" "=wa")
8355 (unspec:DF [(match_operand:DI 1 "register_operand" "r")]
8356 UNSPEC_P8V_MTVSRD))]
8357 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8359 [(set_attr "type" "mftgpr")])
8361 (define_insn "p8_xxpermdi_<mode>"
8362 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8363 (unspec:FMOVE128_GPR [
8364 (match_operand:DF 1 "register_operand" "wa")
8365 (match_operand:DF 2 "register_operand" "wa")]
8366 UNSPEC_P8V_XXPERMDI))]
8367 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8368 "xxpermdi %x0,%x1,%x2,0"
8369 [(set_attr "type" "vecperm")])
8371 (define_insn_and_split "reload_vsx_from_gpr<mode>"
8372 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=wa")
8373 (unspec:FMOVE128_GPR
8374 [(match_operand:FMOVE128_GPR 1 "register_operand" "r")]
8375 UNSPEC_P8V_RELOAD_FROM_GPR))
8376 (clobber (match_operand:IF 2 "register_operand" "=wa"))]
8377 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8379 "&& reload_completed"
8382 rtx dest = operands[0];
8383 rtx src = operands[1];
8384 /* You might think that we could use op0 as one temp and a DF clobber
8385 as op2, but you'd be wrong. Secondary reload move patterns don't
8386 check for overlap of the clobber and the destination. */
8387 rtx tmp_hi = simplify_gen_subreg (DFmode, operands[2], IFmode, 0);
8388 rtx tmp_lo = simplify_gen_subreg (DFmode, operands[2], IFmode, 8);
8389 rtx gpr_hi_reg = gen_highpart (DImode, src);
8390 rtx gpr_lo_reg = gen_lowpart (DImode, src);
8392 emit_insn (gen_p8_mtvsrd_df (tmp_hi, gpr_hi_reg));
8393 emit_insn (gen_p8_mtvsrd_df (tmp_lo, gpr_lo_reg));
8394 emit_insn (gen_p8_xxpermdi_<mode> (dest, tmp_hi, tmp_lo));
8397 [(set_attr "length" "12")
8398 (set_attr "type" "three")])
8401 [(set (match_operand:FMOVE128_GPR 0 "nonimmediate_operand" "")
8402 (match_operand:FMOVE128_GPR 1 "input_operand" ""))]
8404 && (int_reg_operand (operands[0], <MODE>mode)
8405 || int_reg_operand (operands[1], <MODE>mode))
8406 && (!TARGET_DIRECT_MOVE_128
8407 || (!vsx_register_operand (operands[0], <MODE>mode)
8408 && !vsx_register_operand (operands[1], <MODE>mode)))"
8410 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8412 ;; Move SFmode to a VSX from a GPR register. Because scalar floating point
8413 ;; type is stored internally as double precision in the VSX registers, we have
8414 ;; to convert it from the vector format.
8415 (define_insn "p8_mtvsrd_sf"
8416 [(set (match_operand:SF 0 "register_operand" "=wa")
8417 (unspec:SF [(match_operand:DI 1 "register_operand" "r")]
8418 UNSPEC_P8V_MTVSRD))]
8419 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8421 [(set_attr "type" "mftgpr")])
8423 (define_insn_and_split "reload_vsx_from_gprsf"
8424 [(set (match_operand:SF 0 "register_operand" "=wa")
8425 (unspec:SF [(match_operand:SF 1 "register_operand" "r")]
8426 UNSPEC_P8V_RELOAD_FROM_GPR))
8427 (clobber (match_operand:DI 2 "register_operand" "=r"))]
8428 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8430 "&& reload_completed"
8433 rtx op0 = operands[0];
8434 rtx op1 = operands[1];
8435 rtx op2 = operands[2];
8436 rtx op1_di = simplify_gen_subreg (DImode, op1, SFmode, 0);
8438 /* Move SF value to upper 32-bits for xscvspdpn. */
8439 emit_insn (gen_ashldi3 (op2, op1_di, GEN_INT (32)));
8440 emit_insn (gen_p8_mtvsrd_sf (op0, op2));
8441 emit_insn (gen_vsx_xscvspdpn_directmove (op0, op0));
8444 [(set_attr "length" "8")
8445 (set_attr "type" "two")])
8447 ;; Move 128 bit values from VSX registers to GPRs in 64-bit mode by doing a
8448 ;; normal 64-bit move, followed by an xxpermdi to get the bottom 64-bit value,
8449 ;; and then doing a move of that.
8450 (define_insn "p8_mfvsrd_3_<mode>"
8451 [(set (match_operand:DF 0 "register_operand" "=r")
8452 (unspec:DF [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8453 UNSPEC_P8V_RELOAD_FROM_VSX))]
8454 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8456 [(set_attr "type" "mftgpr")])
8458 (define_insn_and_split "reload_gpr_from_vsx<mode>"
8459 [(set (match_operand:FMOVE128_GPR 0 "register_operand" "=r")
8460 (unspec:FMOVE128_GPR
8461 [(match_operand:FMOVE128_GPR 1 "register_operand" "wa")]
8462 UNSPEC_P8V_RELOAD_FROM_VSX))
8463 (clobber (match_operand:FMOVE128_GPR 2 "register_operand" "=wa"))]
8464 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8466 "&& reload_completed"
8469 rtx dest = operands[0];
8470 rtx src = operands[1];
8471 rtx tmp = operands[2];
8472 rtx gpr_hi_reg = gen_highpart (DFmode, dest);
8473 rtx gpr_lo_reg = gen_lowpart (DFmode, dest);
8475 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_hi_reg, src));
8476 emit_insn (gen_vsx_xxpermdi_<mode>_be (tmp, src, src, GEN_INT (3)));
8477 emit_insn (gen_p8_mfvsrd_3_<mode> (gpr_lo_reg, tmp));
8480 [(set_attr "length" "12")
8481 (set_attr "type" "three")])
8483 ;; Move SFmode to a GPR from a VSX register. Because scalar floating point
8484 ;; type is stored internally as double precision, we have to convert it to the
8487 (define_insn_and_split "reload_gpr_from_vsxsf"
8488 [(set (match_operand:SF 0 "register_operand" "=r")
8489 (unspec:SF [(match_operand:SF 1 "register_operand" "ww")]
8490 UNSPEC_P8V_RELOAD_FROM_VSX))
8491 (clobber (match_operand:V4SF 2 "register_operand" "=wIwH"))]
8492 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE"
8494 "&& reload_completed"
8497 rtx op0 = operands[0];
8498 rtx op1 = operands[1];
8499 rtx op2 = operands[2];
8500 rtx op0_di = gen_rtx_REG (DImode, reg_or_subregno (op0));
8501 rtx op2_si = gen_rtx_REG (SImode, reg_or_subregno (op2));
8503 emit_insn (gen_vsx_xscvdpspn_scalar (op2, op1));
8504 emit_insn (gen_zero_extendsidi2 (op0_di, op2_si));
8507 [(set_attr "length" "8")
8508 (set_attr "type" "two")])
8511 ;; Next come the multi-word integer load and store and the load and store
8514 ;; List r->r after r->Y, otherwise reload will try to reload a
8515 ;; non-offsettable address by using r->r which won't make progress.
8516 ;; Use of fprs is disparaged slightly otherwise reload prefers to reload
8517 ;; a gpr into a fpr instead of reloading an invalid 'Y' address
8519 ;; GPR store GPR load GPR move FPR store FPR load FPR move
8520 ;; GPR const AVX store AVX store AVX load AVX load VSX move
8521 ;; P9 0 P9 -1 AVX 0/-1 VSX 0 VSX -1 P9 const
8524 (define_insn "*movdi_internal32"
8525 [(set (match_operand:DI 0 "nonimmediate_operand"
8526 "=Y, r, r, ^m, ^d, ^d,
8527 r, ^wY, $Z, ^wb, $wv, ^wi,
8528 *wo, *wo, *wv, *wi, *wi, *wv,
8531 (match_operand:DI 1 "input_operand"
8533 IJKnGHF, wb, wv, wY, Z, wi,
8534 Oj, wM, OjwM, Oj, wM, wS,
8538 && (gpc_reg_operand (operands[0], DImode)
8539 || gpc_reg_operand (operands[1], DImode))"
8561 "store, load, *, fpstore, fpload, fpsimple,
8562 *, fpstore, fpstore, fpload, fpload, veclogical,
8563 vecsimple, vecsimple, vecsimple, veclogical, veclogical, vecsimple,
8565 (set_attr "size" "64")])
8568 [(set (match_operand:DI 0 "gpc_reg_operand" "")
8569 (match_operand:DI 1 "const_int_operand" ""))]
8570 "! TARGET_POWERPC64 && reload_completed
8571 && gpr_or_gpr_p (operands[0], operands[1])
8572 && !direct_move_p (operands[0], operands[1])"
8573 [(set (match_dup 2) (match_dup 4))
8574 (set (match_dup 3) (match_dup 1))]
8577 HOST_WIDE_INT value = INTVAL (operands[1]);
8578 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8580 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8582 operands[4] = GEN_INT (value >> 32);
8583 operands[1] = GEN_INT (((value & 0xffffffff) ^ 0x80000000) - 0x80000000);
8587 [(set (match_operand:DIFD 0 "nonimmediate_operand" "")
8588 (match_operand:DIFD 1 "input_operand" ""))]
8589 "reload_completed && !TARGET_POWERPC64
8590 && gpr_or_gpr_p (operands[0], operands[1])
8591 && !direct_move_p (operands[0], operands[1])"
8593 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8595 ;; GPR store GPR load GPR move GPR li GPR lis GPR #
8596 ;; FPR store FPR load FPR move AVX store AVX store AVX load
8597 ;; AVX load VSX move P9 0 P9 -1 AVX 0/-1 VSX 0
8598 ;; VSX -1 P9 const AVX const From SPR To SPR SPR<->SPR
8599 ;; FPR->GPR GPR->FPR VSX->GPR GPR->VSX
8600 (define_insn "*movdi_internal64"
8601 [(set (match_operand:DI 0 "nonimmediate_operand"
8603 ^m, ^d, ^d, ^wY, $Z, $wb,
8604 $wv, ^wi, *wo, *wo, *wv, *wi,
8605 *wi, *wv, *wv, r, *h, *h,
8606 ?*r, ?*wg, ?*r, ?*wj")
8608 (match_operand:DI 1 "input_operand"
8610 d, m, d, wb, wv, wY,
8611 Z, wi, Oj, wM, OjwM, Oj,
8612 wM, wS, wB, *h, r, 0,
8616 && (gpc_reg_operand (operands[0], DImode)
8617 || gpc_reg_operand (operands[1], DImode))"
8648 "store, load, *, *, *, *,
8649 fpstore, fpload, fpsimple, fpstore, fpstore, fpload,
8650 fpload, veclogical, vecsimple, vecsimple, vecsimple, veclogical,
8651 veclogical, vecsimple, vecsimple, mfjmpr, mtjmpr, *,
8652 mftgpr, mffgpr, mftgpr, mffgpr")
8654 (set_attr "size" "64")
8662 ; Some DImode loads are best done as a load of -1 followed by a mask
8665 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo")
8666 (match_operand:DI 1 "const_int_operand"))]
8668 && num_insns_constant (operands[1], DImode) > 1
8669 && !IN_RANGE (INTVAL (operands[1]), -0x80000000, 0xffffffff)
8670 && rs6000_is_valid_and_mask (operands[1], DImode)"
8674 (and:DI (match_dup 0)
8678 ;; Split a load of a large constant into the appropriate five-instruction
8679 ;; sequence. Handle anything in a constant number of insns.
8680 ;; When non-easy constants can go in the TOC, this should use
8681 ;; easy_fp_constant predicate.
8683 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8684 (match_operand:DI 1 "const_int_operand" ""))]
8685 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8686 [(set (match_dup 0) (match_dup 2))
8687 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8690 if (rs6000_emit_set_const (operands[0], operands[1]))
8697 [(set (match_operand:DI 0 "int_reg_operand_not_pseudo" "")
8698 (match_operand:DI 1 "const_scalar_int_operand" ""))]
8699 "TARGET_POWERPC64 && num_insns_constant (operands[1], DImode) > 1"
8700 [(set (match_dup 0) (match_dup 2))
8701 (set (match_dup 0) (plus:DI (match_dup 0) (match_dup 3)))]
8704 if (rs6000_emit_set_const (operands[0], operands[1]))
8711 [(set (match_operand:DI 0 "altivec_register_operand" "")
8712 (match_operand:DI 1 "s5bit_cint_operand" ""))]
8713 "TARGET_VSX && reload_completed"
8716 rtx op0 = operands[0];
8717 rtx op1 = operands[1];
8718 int r = REGNO (op0);
8719 rtx op0_v4si = gen_rtx_REG (V4SImode, r);
8721 emit_insn (gen_altivec_vspltisw (op0_v4si, op1));
8722 if (op1 != const0_rtx && op1 != constm1_rtx)
8724 rtx op0_v2di = gen_rtx_REG (V2DImode, r);
8725 emit_insn (gen_altivec_vupkhsw (op0_v2di, op0_v4si));
8730 ;; Split integer constants that can be loaded with XXSPLTIB and a
8731 ;; sign extend operation.
8733 [(set (match_operand:INT_ISA3 0 "altivec_register_operand" "")
8734 (match_operand:INT_ISA3 1 "xxspltib_constant_split" ""))]
8735 "TARGET_P9_VECTOR && reload_completed"
8738 rtx op0 = operands[0];
8739 rtx op1 = operands[1];
8740 int r = REGNO (op0);
8741 rtx op0_v16qi = gen_rtx_REG (V16QImode, r);
8743 emit_insn (gen_xxspltib_v16qi (op0_v16qi, op1));
8744 if (<MODE>mode == DImode)
8745 emit_insn (gen_vsx_sign_extend_qi_di (operands[0], op0_v16qi));
8746 else if (<MODE>mode == SImode)
8747 emit_insn (gen_vsx_sign_extend_qi_si (operands[0], op0_v16qi));
8748 else if (<MODE>mode == HImode)
8750 rtx op0_v8hi = gen_rtx_REG (V8HImode, r);
8751 emit_insn (gen_altivec_vupkhsb (op0_v8hi, op0_v16qi));
8757 ;; TImode/PTImode is similar, except that we usually want to compute the
8758 ;; address into a register and use lsi/stsi (the exception is during reload).
8760 (define_insn "*mov<mode>_string"
8761 [(set (match_operand:TI2 0 "reg_or_mem_operand" "=Q,Y,????r,????r,????r,r")
8762 (match_operand:TI2 1 "input_operand" "r,r,Q,Y,r,n"))]
8764 && (<MODE>mode != TImode || VECTOR_MEM_NONE_P (TImode))
8765 && (gpc_reg_operand (operands[0], <MODE>mode)
8766 || gpc_reg_operand (operands[1], <MODE>mode))"
8769 switch (which_alternative)
8775 return \"stswi %1,%P0,16\";
8780 /* If the address is not used in the output, we can use lsi. Otherwise,
8781 fall through to generating four loads. */
8783 && ! reg_overlap_mentioned_p (operands[0], operands[1]))
8784 return \"lswi %0,%P1,16\";
8792 [(set_attr "type" "store,store,load,load,*,*")
8793 (set_attr "update" "yes")
8794 (set_attr "indexed" "yes")
8795 (set (attr "cell_micro") (if_then_else (match_test "TARGET_STRING")
8796 (const_string "always")
8797 (const_string "conditional")))])
8799 (define_insn "*mov<mode>_ppc64"
8800 [(set (match_operand:TI2 0 "nonimmediate_operand" "=wQ,Y,r,r,r,r")
8801 (match_operand:TI2 1 "input_operand" "r,r,wQ,Y,r,n"))]
8802 "(TARGET_POWERPC64 && VECTOR_MEM_NONE_P (<MODE>mode)
8803 && (gpc_reg_operand (operands[0], <MODE>mode)
8804 || gpc_reg_operand (operands[1], <MODE>mode)))"
8806 return rs6000_output_move_128bit (operands);
8808 [(set_attr "type" "store,store,load,load,*,*")
8809 (set_attr "length" "8")])
8812 [(set (match_operand:TI2 0 "int_reg_operand" "")
8813 (match_operand:TI2 1 "const_scalar_int_operand" ""))]
8815 && (VECTOR_MEM_NONE_P (<MODE>mode)
8816 || (reload_completed && INT_REGNO_P (REGNO (operands[0]))))"
8817 [(set (match_dup 2) (match_dup 4))
8818 (set (match_dup 3) (match_dup 5))]
8821 operands[2] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN == 0,
8823 operands[3] = operand_subword_force (operands[0], WORDS_BIG_ENDIAN != 0,
8825 if (CONST_WIDE_INT_P (operands[1]))
8827 operands[4] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 1));
8828 operands[5] = GEN_INT (CONST_WIDE_INT_ELT (operands[1], 0));
8830 else if (CONST_INT_P (operands[1]))
8832 operands[4] = GEN_INT (- (INTVAL (operands[1]) < 0));
8833 operands[5] = operands[1];
8840 [(set (match_operand:TI2 0 "nonimmediate_operand" "")
8841 (match_operand:TI2 1 "input_operand" ""))]
8843 && gpr_or_gpr_p (operands[0], operands[1])
8844 && !direct_move_p (operands[0], operands[1])
8845 && !quad_load_store_p (operands[0], operands[1])"
8847 { rs6000_split_multireg_move (operands[0], operands[1]); DONE; })
8849 (define_expand "load_multiple"
8850 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
8851 (match_operand:SI 1 "" ""))
8852 (use (match_operand:SI 2 "" ""))])]
8853 "TARGET_STRING && !TARGET_POWERPC64"
8861 /* Support only loading a constant number of fixed-point registers from
8862 memory and only bother with this if more than two; the machine
8863 doesn't support more than eight. */
8864 if (GET_CODE (operands[2]) != CONST_INT
8865 || INTVAL (operands[2]) <= 2
8866 || INTVAL (operands[2]) > 8
8867 || GET_CODE (operands[1]) != MEM
8868 || GET_CODE (operands[0]) != REG
8869 || REGNO (operands[0]) >= 32)
8872 count = INTVAL (operands[2]);
8873 regno = REGNO (operands[0]);
8875 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count));
8876 op1 = replace_equiv_address (operands[1],
8877 force_reg (SImode, XEXP (operands[1], 0)));
8879 for (i = 0; i < count; i++)
8880 XVECEXP (operands[3], 0, i)
8881 = gen_rtx_SET (gen_rtx_REG (SImode, regno + i),
8882 adjust_address_nv (op1, SImode, i * 4));
8885 (define_insn "*ldmsi8"
8886 [(match_parallel 0 "load_multiple_operation"
8887 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8888 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8889 (set (match_operand:SI 3 "gpc_reg_operand" "")
8890 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8891 (set (match_operand:SI 4 "gpc_reg_operand" "")
8892 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8893 (set (match_operand:SI 5 "gpc_reg_operand" "")
8894 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8895 (set (match_operand:SI 6 "gpc_reg_operand" "")
8896 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8897 (set (match_operand:SI 7 "gpc_reg_operand" "")
8898 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8899 (set (match_operand:SI 8 "gpc_reg_operand" "")
8900 (mem:SI (plus:SI (match_dup 1) (const_int 24))))
8901 (set (match_operand:SI 9 "gpc_reg_operand" "")
8902 (mem:SI (plus:SI (match_dup 1) (const_int 28))))])]
8903 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
8905 { return rs6000_output_load_multiple (operands); }"
8906 [(set_attr "type" "load")
8907 (set_attr "update" "yes")
8908 (set_attr "indexed" "yes")
8909 (set_attr "length" "32")])
8911 (define_insn "*ldmsi7"
8912 [(match_parallel 0 "load_multiple_operation"
8913 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8914 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8915 (set (match_operand:SI 3 "gpc_reg_operand" "")
8916 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8917 (set (match_operand:SI 4 "gpc_reg_operand" "")
8918 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8919 (set (match_operand:SI 5 "gpc_reg_operand" "")
8920 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8921 (set (match_operand:SI 6 "gpc_reg_operand" "")
8922 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8923 (set (match_operand:SI 7 "gpc_reg_operand" "")
8924 (mem:SI (plus:SI (match_dup 1) (const_int 20))))
8925 (set (match_operand:SI 8 "gpc_reg_operand" "")
8926 (mem:SI (plus:SI (match_dup 1) (const_int 24))))])]
8927 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
8929 { return rs6000_output_load_multiple (operands); }"
8930 [(set_attr "type" "load")
8931 (set_attr "update" "yes")
8932 (set_attr "indexed" "yes")
8933 (set_attr "length" "32")])
8935 (define_insn "*ldmsi6"
8936 [(match_parallel 0 "load_multiple_operation"
8937 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8938 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8939 (set (match_operand:SI 3 "gpc_reg_operand" "")
8940 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8941 (set (match_operand:SI 4 "gpc_reg_operand" "")
8942 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8943 (set (match_operand:SI 5 "gpc_reg_operand" "")
8944 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8945 (set (match_operand:SI 6 "gpc_reg_operand" "")
8946 (mem:SI (plus:SI (match_dup 1) (const_int 16))))
8947 (set (match_operand:SI 7 "gpc_reg_operand" "")
8948 (mem:SI (plus:SI (match_dup 1) (const_int 20))))])]
8949 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
8951 { return rs6000_output_load_multiple (operands); }"
8952 [(set_attr "type" "load")
8953 (set_attr "update" "yes")
8954 (set_attr "indexed" "yes")
8955 (set_attr "length" "32")])
8957 (define_insn "*ldmsi5"
8958 [(match_parallel 0 "load_multiple_operation"
8959 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8960 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8961 (set (match_operand:SI 3 "gpc_reg_operand" "")
8962 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8963 (set (match_operand:SI 4 "gpc_reg_operand" "")
8964 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8965 (set (match_operand:SI 5 "gpc_reg_operand" "")
8966 (mem:SI (plus:SI (match_dup 1) (const_int 12))))
8967 (set (match_operand:SI 6 "gpc_reg_operand" "")
8968 (mem:SI (plus:SI (match_dup 1) (const_int 16))))])]
8969 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
8971 { return rs6000_output_load_multiple (operands); }"
8972 [(set_attr "type" "load")
8973 (set_attr "update" "yes")
8974 (set_attr "indexed" "yes")
8975 (set_attr "length" "32")])
8977 (define_insn "*ldmsi4"
8978 [(match_parallel 0 "load_multiple_operation"
8979 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8980 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8981 (set (match_operand:SI 3 "gpc_reg_operand" "")
8982 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
8983 (set (match_operand:SI 4 "gpc_reg_operand" "")
8984 (mem:SI (plus:SI (match_dup 1) (const_int 8))))
8985 (set (match_operand:SI 5 "gpc_reg_operand" "")
8986 (mem:SI (plus:SI (match_dup 1) (const_int 12))))])]
8987 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
8989 { return rs6000_output_load_multiple (operands); }"
8990 [(set_attr "type" "load")
8991 (set_attr "update" "yes")
8992 (set_attr "indexed" "yes")
8993 (set_attr "length" "32")])
8995 (define_insn "*ldmsi3"
8996 [(match_parallel 0 "load_multiple_operation"
8997 [(set (match_operand:SI 2 "gpc_reg_operand" "")
8998 (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b")))
8999 (set (match_operand:SI 3 "gpc_reg_operand" "")
9000 (mem:SI (plus:SI (match_dup 1) (const_int 4))))
9001 (set (match_operand:SI 4 "gpc_reg_operand" "")
9002 (mem:SI (plus:SI (match_dup 1) (const_int 8))))])]
9003 "TARGET_STRING && XVECLEN (operands[0], 0) == 3"
9005 { return rs6000_output_load_multiple (operands); }"
9006 [(set_attr "type" "load")
9007 (set_attr "update" "yes")
9008 (set_attr "indexed" "yes")
9009 (set_attr "length" "32")])
9011 (define_expand "store_multiple"
9012 [(match_par_dup 3 [(set (match_operand:SI 0 "" "")
9013 (match_operand:SI 1 "" ""))
9014 (clobber (scratch:SI))
9015 (use (match_operand:SI 2 "" ""))])]
9016 "TARGET_STRING && !TARGET_POWERPC64"
9025 /* Support only storing a constant number of fixed-point registers to
9026 memory and only bother with this if more than two; the machine
9027 doesn't support more than eight. */
9028 if (GET_CODE (operands[2]) != CONST_INT
9029 || INTVAL (operands[2]) <= 2
9030 || INTVAL (operands[2]) > 8
9031 || GET_CODE (operands[0]) != MEM
9032 || GET_CODE (operands[1]) != REG
9033 || REGNO (operands[1]) >= 32)
9036 count = INTVAL (operands[2]);
9037 regno = REGNO (operands[1]);
9039 operands[3] = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (count + 1));
9040 to = force_reg (SImode, XEXP (operands[0], 0));
9041 op0 = replace_equiv_address (operands[0], to);
9043 XVECEXP (operands[3], 0, 0)
9044 = gen_rtx_SET (adjust_address_nv (op0, SImode, 0), operands[1]);
9045 XVECEXP (operands[3], 0, 1) = gen_rtx_CLOBBER (VOIDmode,
9046 gen_rtx_SCRATCH (SImode));
9048 for (i = 1; i < count; i++)
9049 XVECEXP (operands[3], 0, i + 1)
9050 = gen_rtx_SET (adjust_address_nv (op0, SImode, i * 4),
9051 gen_rtx_REG (SImode, regno + i));
9054 (define_insn "*stmsi8"
9055 [(match_parallel 0 "store_multiple_operation"
9056 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9057 (match_operand:SI 2 "gpc_reg_operand" "r"))
9058 (clobber (match_scratch:SI 3 "=X"))
9059 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9060 (match_operand:SI 4 "gpc_reg_operand" "r"))
9061 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9062 (match_operand:SI 5 "gpc_reg_operand" "r"))
9063 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9064 (match_operand:SI 6 "gpc_reg_operand" "r"))
9065 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9066 (match_operand:SI 7 "gpc_reg_operand" "r"))
9067 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9068 (match_operand:SI 8 "gpc_reg_operand" "r"))
9069 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9070 (match_operand:SI 9 "gpc_reg_operand" "r"))
9071 (set (mem:SI (plus:SI (match_dup 1) (const_int 28)))
9072 (match_operand:SI 10 "gpc_reg_operand" "r"))])]
9073 "TARGET_STRING && XVECLEN (operands[0], 0) == 9"
9075 [(set_attr "type" "store")
9076 (set_attr "update" "yes")
9077 (set_attr "indexed" "yes")
9078 (set_attr "cell_micro" "always")])
9080 (define_insn "*stmsi7"
9081 [(match_parallel 0 "store_multiple_operation"
9082 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9083 (match_operand:SI 2 "gpc_reg_operand" "r"))
9084 (clobber (match_scratch:SI 3 "=X"))
9085 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9086 (match_operand:SI 4 "gpc_reg_operand" "r"))
9087 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9088 (match_operand:SI 5 "gpc_reg_operand" "r"))
9089 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9090 (match_operand:SI 6 "gpc_reg_operand" "r"))
9091 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9092 (match_operand:SI 7 "gpc_reg_operand" "r"))
9093 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9094 (match_operand:SI 8 "gpc_reg_operand" "r"))
9095 (set (mem:SI (plus:SI (match_dup 1) (const_int 24)))
9096 (match_operand:SI 9 "gpc_reg_operand" "r"))])]
9097 "TARGET_STRING && XVECLEN (operands[0], 0) == 8"
9099 [(set_attr "type" "store")
9100 (set_attr "update" "yes")
9101 (set_attr "indexed" "yes")
9102 (set_attr "cell_micro" "always")])
9104 (define_insn "*stmsi6"
9105 [(match_parallel 0 "store_multiple_operation"
9106 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9107 (match_operand:SI 2 "gpc_reg_operand" "r"))
9108 (clobber (match_scratch:SI 3 "=X"))
9109 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9110 (match_operand:SI 4 "gpc_reg_operand" "r"))
9111 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9112 (match_operand:SI 5 "gpc_reg_operand" "r"))
9113 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9114 (match_operand:SI 6 "gpc_reg_operand" "r"))
9115 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9116 (match_operand:SI 7 "gpc_reg_operand" "r"))
9117 (set (mem:SI (plus:SI (match_dup 1) (const_int 20)))
9118 (match_operand:SI 8 "gpc_reg_operand" "r"))])]
9119 "TARGET_STRING && XVECLEN (operands[0], 0) == 7"
9121 [(set_attr "type" "store")
9122 (set_attr "update" "yes")
9123 (set_attr "indexed" "yes")
9124 (set_attr "cell_micro" "always")])
9126 (define_insn "*stmsi5"
9127 [(match_parallel 0 "store_multiple_operation"
9128 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9129 (match_operand:SI 2 "gpc_reg_operand" "r"))
9130 (clobber (match_scratch:SI 3 "=X"))
9131 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9132 (match_operand:SI 4 "gpc_reg_operand" "r"))
9133 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9134 (match_operand:SI 5 "gpc_reg_operand" "r"))
9135 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9136 (match_operand:SI 6 "gpc_reg_operand" "r"))
9137 (set (mem:SI (plus:SI (match_dup 1) (const_int 16)))
9138 (match_operand:SI 7 "gpc_reg_operand" "r"))])]
9139 "TARGET_STRING && XVECLEN (operands[0], 0) == 6"
9141 [(set_attr "type" "store")
9142 (set_attr "update" "yes")
9143 (set_attr "indexed" "yes")
9144 (set_attr "cell_micro" "always")])
9146 (define_insn "*stmsi4"
9147 [(match_parallel 0 "store_multiple_operation"
9148 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9149 (match_operand:SI 2 "gpc_reg_operand" "r"))
9150 (clobber (match_scratch:SI 3 "=X"))
9151 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9152 (match_operand:SI 4 "gpc_reg_operand" "r"))
9153 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9154 (match_operand:SI 5 "gpc_reg_operand" "r"))
9155 (set (mem:SI (plus:SI (match_dup 1) (const_int 12)))
9156 (match_operand:SI 6 "gpc_reg_operand" "r"))])]
9157 "TARGET_STRING && XVECLEN (operands[0], 0) == 5"
9159 [(set_attr "type" "store")
9160 (set_attr "update" "yes")
9161 (set_attr "indexed" "yes")
9162 (set_attr "cell_micro" "always")])
9164 (define_insn "*stmsi3"
9165 [(match_parallel 0 "store_multiple_operation"
9166 [(set (mem:SI (match_operand:SI 1 "gpc_reg_operand" "b"))
9167 (match_operand:SI 2 "gpc_reg_operand" "r"))
9168 (clobber (match_scratch:SI 3 "=X"))
9169 (set (mem:SI (plus:SI (match_dup 1) (const_int 4)))
9170 (match_operand:SI 4 "gpc_reg_operand" "r"))
9171 (set (mem:SI (plus:SI (match_dup 1) (const_int 8)))
9172 (match_operand:SI 5 "gpc_reg_operand" "r"))])]
9173 "TARGET_STRING && XVECLEN (operands[0], 0) == 4"
9175 [(set_attr "type" "store")
9176 (set_attr "update" "yes")
9177 (set_attr "indexed" "yes")
9178 (set_attr "cell_micro" "always")])
9180 (define_expand "setmemsi"
9181 [(parallel [(set (match_operand:BLK 0 "" "")
9182 (match_operand 2 "const_int_operand" ""))
9183 (use (match_operand:SI 1 "" ""))
9184 (use (match_operand:SI 3 "" ""))])]
9188 /* If value to set is not zero, use the library routine. */
9189 if (operands[2] != const0_rtx)
9192 if (expand_block_clear (operands))
9198 ;; String compare N insn.
9199 ;; Argument 0 is the target (result)
9200 ;; Argument 1 is the destination
9201 ;; Argument 2 is the source
9202 ;; Argument 3 is the length
9203 ;; Argument 4 is the alignment
9205 (define_expand "cmpstrnsi"
9206 [(parallel [(set (match_operand:SI 0)
9207 (compare:SI (match_operand:BLK 1)
9208 (match_operand:BLK 2)))
9209 (use (match_operand:SI 3))
9210 (use (match_operand:SI 4))])]
9211 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9213 if (optimize_insn_for_size_p ())
9216 if (expand_strn_compare (operands, 0))
9222 ;; String compare insn.
9223 ;; Argument 0 is the target (result)
9224 ;; Argument 1 is the destination
9225 ;; Argument 2 is the source
9226 ;; Argument 3 is the alignment
9228 (define_expand "cmpstrsi"
9229 [(parallel [(set (match_operand:SI 0)
9230 (compare:SI (match_operand:BLK 1)
9231 (match_operand:BLK 2)))
9232 (use (match_operand:SI 3))])]
9233 "TARGET_CMPB && (BYTES_BIG_ENDIAN || TARGET_LDBRX)"
9235 if (optimize_insn_for_size_p ())
9238 if (expand_strn_compare (operands, 1))
9244 ;; Block compare insn.
9245 ;; Argument 0 is the target (result)
9246 ;; Argument 1 is the destination
9247 ;; Argument 2 is the source
9248 ;; Argument 3 is the length
9249 ;; Argument 4 is the alignment
9251 (define_expand "cmpmemsi"
9252 [(parallel [(set (match_operand:SI 0)
9253 (compare:SI (match_operand:BLK 1)
9254 (match_operand:BLK 2)))
9255 (use (match_operand:SI 3))
9256 (use (match_operand:SI 4))])]
9259 if (expand_block_compare (operands))
9265 ;; String/block move insn.
9266 ;; Argument 0 is the destination
9267 ;; Argument 1 is the source
9268 ;; Argument 2 is the length
9269 ;; Argument 3 is the alignment
9271 (define_expand "movmemsi"
9272 [(parallel [(set (match_operand:BLK 0 "" "")
9273 (match_operand:BLK 1 "" ""))
9274 (use (match_operand:SI 2 "" ""))
9275 (use (match_operand:SI 3 "" ""))])]
9279 if (expand_block_move (operands))
9285 ;; Move up to 32 bytes at a time. The fixed registers are needed because the
9286 ;; register allocator doesn't have a clue about allocating 8 word registers.
9287 ;; rD/rS = r5 is preferred, efficient form.
9288 (define_expand "movmemsi_8reg"
9289 [(parallel [(set (match_operand 0 "" "")
9290 (match_operand 1 "" ""))
9291 (use (match_operand 2 "" ""))
9292 (use (match_operand 3 "" ""))
9293 (clobber (reg:SI 5))
9294 (clobber (reg:SI 6))
9295 (clobber (reg:SI 7))
9296 (clobber (reg:SI 8))
9297 (clobber (reg:SI 9))
9298 (clobber (reg:SI 10))
9299 (clobber (reg:SI 11))
9300 (clobber (reg:SI 12))
9301 (clobber (match_scratch:SI 4 ""))])]
9306 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9307 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9308 (use (match_operand:SI 2 "immediate_operand" "i"))
9309 (use (match_operand:SI 3 "immediate_operand" "i"))
9310 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9311 (clobber (reg:SI 6))
9312 (clobber (reg:SI 7))
9313 (clobber (reg:SI 8))
9314 (clobber (reg:SI 9))
9315 (clobber (reg:SI 10))
9316 (clobber (reg:SI 11))
9317 (clobber (reg:SI 12))
9318 (clobber (match_scratch:SI 5 "=X"))]
9320 && ((INTVAL (operands[2]) > 24 && INTVAL (operands[2]) < 32)
9321 || INTVAL (operands[2]) == 0)
9322 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 12)
9323 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 12)
9324 && REGNO (operands[4]) == 5"
9325 "lswi %4,%1,%2\;stswi %4,%0,%2"
9326 [(set_attr "type" "store")
9327 (set_attr "update" "yes")
9328 (set_attr "indexed" "yes")
9329 (set_attr "cell_micro" "always")
9330 (set_attr "length" "8")])
9332 ;; Move up to 24 bytes at a time. The fixed registers are needed because the
9333 ;; register allocator doesn't have a clue about allocating 6 word registers.
9334 ;; rD/rS = r5 is preferred, efficient form.
9335 (define_expand "movmemsi_6reg"
9336 [(parallel [(set (match_operand 0 "" "")
9337 (match_operand 1 "" ""))
9338 (use (match_operand 2 "" ""))
9339 (use (match_operand 3 "" ""))
9340 (clobber (reg:SI 5))
9341 (clobber (reg:SI 6))
9342 (clobber (reg:SI 7))
9343 (clobber (reg:SI 8))
9344 (clobber (reg:SI 9))
9345 (clobber (reg:SI 10))
9346 (clobber (match_scratch:SI 4 ""))])]
9351 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9352 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9353 (use (match_operand:SI 2 "immediate_operand" "i"))
9354 (use (match_operand:SI 3 "immediate_operand" "i"))
9355 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9356 (clobber (reg:SI 6))
9357 (clobber (reg:SI 7))
9358 (clobber (reg:SI 8))
9359 (clobber (reg:SI 9))
9360 (clobber (reg:SI 10))
9361 (clobber (match_scratch:SI 5 "=X"))]
9363 && INTVAL (operands[2]) > 16 && INTVAL (operands[2]) <= 32
9364 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 10)
9365 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 10)
9366 && REGNO (operands[4]) == 5"
9367 "lswi %4,%1,%2\;stswi %4,%0,%2"
9368 [(set_attr "type" "store")
9369 (set_attr "update" "yes")
9370 (set_attr "indexed" "yes")
9371 (set_attr "cell_micro" "always")
9372 (set_attr "length" "8")])
9374 ;; Move up to 16 bytes at a time, using 4 fixed registers to avoid spill
9375 ;; problems with TImode.
9376 ;; rD/rS = r5 is preferred, efficient form.
9377 (define_expand "movmemsi_4reg"
9378 [(parallel [(set (match_operand 0 "" "")
9379 (match_operand 1 "" ""))
9380 (use (match_operand 2 "" ""))
9381 (use (match_operand 3 "" ""))
9382 (clobber (reg:SI 5))
9383 (clobber (reg:SI 6))
9384 (clobber (reg:SI 7))
9385 (clobber (reg:SI 8))
9386 (clobber (match_scratch:SI 4 ""))])]
9391 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9392 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9393 (use (match_operand:SI 2 "immediate_operand" "i"))
9394 (use (match_operand:SI 3 "immediate_operand" "i"))
9395 (clobber (match_operand:SI 4 "gpc_reg_operand" "=&r"))
9396 (clobber (reg:SI 6))
9397 (clobber (reg:SI 7))
9398 (clobber (reg:SI 8))
9399 (clobber (match_scratch:SI 5 "=X"))]
9401 && INTVAL (operands[2]) > 8 && INTVAL (operands[2]) <= 16
9402 && (REGNO (operands[0]) < 5 || REGNO (operands[0]) > 8)
9403 && (REGNO (operands[1]) < 5 || REGNO (operands[1]) > 8)
9404 && REGNO (operands[4]) == 5"
9405 "lswi %4,%1,%2\;stswi %4,%0,%2"
9406 [(set_attr "type" "store")
9407 (set_attr "update" "yes")
9408 (set_attr "indexed" "yes")
9409 (set_attr "cell_micro" "always")
9410 (set_attr "length" "8")])
9412 ;; Move up to 8 bytes at a time.
9413 (define_expand "movmemsi_2reg"
9414 [(parallel [(set (match_operand 0 "" "")
9415 (match_operand 1 "" ""))
9416 (use (match_operand 2 "" ""))
9417 (use (match_operand 3 "" ""))
9418 (clobber (match_scratch:DI 4 ""))
9419 (clobber (match_scratch:SI 5 ""))])]
9420 "TARGET_STRING && ! TARGET_POWERPC64"
9424 [(set (mem:BLK (match_operand:SI 0 "gpc_reg_operand" "b"))
9425 (mem:BLK (match_operand:SI 1 "gpc_reg_operand" "b")))
9426 (use (match_operand:SI 2 "immediate_operand" "i"))
9427 (use (match_operand:SI 3 "immediate_operand" "i"))
9428 (clobber (match_scratch:DI 4 "=&r"))
9429 (clobber (match_scratch:SI 5 "=X"))]
9430 "TARGET_STRING && ! TARGET_POWERPC64
9431 && INTVAL (operands[2]) > 4 && INTVAL (operands[2]) <= 8"
9432 "lswi %4,%1,%2\;stswi %4,%0,%2"
9433 [(set_attr "type" "store")
9434 (set_attr "update" "yes")
9435 (set_attr "indexed" "yes")
9436 (set_attr "cell_micro" "always")
9437 (set_attr "length" "8")])
9439 ;; Move up to 4 bytes at a time.
9440 (define_expand "movmemsi_1reg"
9441 [(parallel [(set (match_operand 0 "" "")
9442 (match_operand 1 "" ""))
9443 (use (match_operand 2 "" ""))
9444 (use (match_operand 3 "" ""))
9445 (clobber (match_scratch:SI 4 ""))
9446 (clobber (match_scratch:SI 5 ""))])]
9451 [(set (mem:BLK (match_operand:P 0 "gpc_reg_operand" "b"))
9452 (mem:BLK (match_operand:P 1 "gpc_reg_operand" "b")))
9453 (use (match_operand:SI 2 "immediate_operand" "i"))
9454 (use (match_operand:SI 3 "immediate_operand" "i"))
9455 (clobber (match_scratch:SI 4 "=&r"))
9456 (clobber (match_scratch:SI 5 "=X"))]
9457 "TARGET_STRING && INTVAL (operands[2]) > 0 && INTVAL (operands[2]) <= 4"
9458 "lswi %4,%1,%2\;stswi %4,%0,%2"
9459 [(set_attr "type" "store")
9460 (set_attr "update" "yes")
9461 (set_attr "indexed" "yes")
9462 (set_attr "cell_micro" "always")
9463 (set_attr "length" "8")])
9465 ;; Define insns that do load or store with update. Some of these we can
9466 ;; get by using pre-decrement or pre-increment, but the hardware can also
9467 ;; do cases where the increment is not the size of the object.
9469 ;; In all these cases, we use operands 0 and 1 for the register being
9470 ;; incremented because those are the operands that local-alloc will
9471 ;; tie and these are the pair most likely to be tieable (and the ones
9472 ;; that will benefit the most).
9474 (define_insn "*movdi_update1"
9475 [(set (match_operand:DI 3 "gpc_reg_operand" "=r,r")
9476 (mem:DI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0,0")
9477 (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
9478 (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
9479 (plus:DI (match_dup 1) (match_dup 2)))]
9480 "TARGET_POWERPC64 && TARGET_UPDATE
9481 && (!avoiding_indexed_address_p (DImode)
9482 || !gpc_reg_operand (operands[2], DImode))"
9486 [(set_attr "type" "load")
9487 (set_attr "update" "yes")
9488 (set_attr "indexed" "yes,no")])
9490 (define_insn "movdi_<mode>_update"
9491 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9492 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9493 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9494 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9495 (plus:P (match_dup 1) (match_dup 2)))]
9496 "TARGET_POWERPC64 && TARGET_UPDATE
9497 && (!avoiding_indexed_address_p (Pmode)
9498 || !gpc_reg_operand (operands[2], Pmode)
9499 || (REG_P (operands[0])
9500 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9504 [(set_attr "type" "store")
9505 (set_attr "update" "yes")
9506 (set_attr "indexed" "yes,no")])
9508 ;; This pattern is only conditional on TARGET_POWERPC64, as it is
9509 ;; needed for stack allocation, even if the user passes -mno-update.
9510 (define_insn "movdi_<mode>_update_stack"
9511 [(set (mem:DI (plus:P (match_operand:P 1 "gpc_reg_operand" "0,0")
9512 (match_operand:P 2 "reg_or_aligned_short_operand" "r,I")))
9513 (match_operand:DI 3 "gpc_reg_operand" "r,r"))
9514 (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
9515 (plus:P (match_dup 1) (match_dup 2)))]
9520 [(set_attr "type" "store")
9521 (set_attr "update" "yes")
9522 (set_attr "indexed" "yes,no")])
9524 (define_insn "*movsi_update1"
9525 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9526 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9527 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9528 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9529 (plus:SI (match_dup 1) (match_dup 2)))]
9531 && (!avoiding_indexed_address_p (SImode)
9532 || !gpc_reg_operand (operands[2], SImode))"
9536 [(set_attr "type" "load")
9537 (set_attr "update" "yes")
9538 (set_attr "indexed" "yes,no")])
9540 (define_insn "*movsi_update2"
9541 [(set (match_operand:DI 3 "gpc_reg_operand" "=r")
9543 (mem:SI (plus:DI (match_operand:DI 1 "gpc_reg_operand" "0")
9544 (match_operand:DI 2 "gpc_reg_operand" "r")))))
9545 (set (match_operand:DI 0 "gpc_reg_operand" "=b")
9546 (plus:DI (match_dup 1) (match_dup 2)))]
9547 "TARGET_POWERPC64 && !avoiding_indexed_address_p (DImode)"
9549 [(set_attr "type" "load")
9550 (set_attr "sign_extend" "yes")
9551 (set_attr "update" "yes")
9552 (set_attr "indexed" "yes")])
9554 (define_insn "movsi_update"
9555 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9556 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9557 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9558 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9559 (plus:SI (match_dup 1) (match_dup 2)))]
9561 && (!avoiding_indexed_address_p (SImode)
9562 || !gpc_reg_operand (operands[2], SImode)
9563 || (REG_P (operands[0])
9564 && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
9568 [(set_attr "type" "store")
9569 (set_attr "update" "yes")
9570 (set_attr "indexed" "yes,no")])
9572 ;; This is an unconditional pattern; needed for stack allocation, even
9573 ;; if the user passes -mno-update.
9574 (define_insn "movsi_update_stack"
9575 [(set (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9576 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9577 (match_operand:SI 3 "gpc_reg_operand" "r,r"))
9578 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9579 (plus:SI (match_dup 1) (match_dup 2)))]
9584 [(set_attr "type" "store")
9585 (set_attr "update" "yes")
9586 (set_attr "indexed" "yes,no")])
9588 (define_insn "*movhi_update1"
9589 [(set (match_operand:HI 3 "gpc_reg_operand" "=r,r")
9590 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9591 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9592 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9593 (plus:SI (match_dup 1) (match_dup 2)))]
9595 && (!avoiding_indexed_address_p (SImode)
9596 || !gpc_reg_operand (operands[2], SImode))"
9600 [(set_attr "type" "load")
9601 (set_attr "update" "yes")
9602 (set_attr "indexed" "yes,no")])
9604 (define_insn "*movhi_update2"
9605 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9607 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9608 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9609 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9610 (plus:SI (match_dup 1) (match_dup 2)))]
9612 && (!avoiding_indexed_address_p (SImode)
9613 || !gpc_reg_operand (operands[2], SImode))"
9617 [(set_attr "type" "load")
9618 (set_attr "update" "yes")
9619 (set_attr "indexed" "yes,no")])
9621 (define_insn "*movhi_update3"
9622 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9624 (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9625 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9626 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9627 (plus:SI (match_dup 1) (match_dup 2)))]
9629 && !(avoiding_indexed_address_p (SImode)
9630 && gpc_reg_operand (operands[2], SImode))"
9634 [(set_attr "type" "load")
9635 (set_attr "sign_extend" "yes")
9636 (set_attr "update" "yes")
9637 (set_attr "indexed" "yes,no")])
9639 (define_insn "*movhi_update4"
9640 [(set (mem:HI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9641 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9642 (match_operand:HI 3 "gpc_reg_operand" "r,r"))
9643 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9644 (plus:SI (match_dup 1) (match_dup 2)))]
9646 && (!avoiding_indexed_address_p (SImode)
9647 || !gpc_reg_operand (operands[2], SImode))"
9651 [(set_attr "type" "store")
9652 (set_attr "update" "yes")
9653 (set_attr "indexed" "yes,no")])
9655 (define_insn "*movqi_update1"
9656 [(set (match_operand:QI 3 "gpc_reg_operand" "=r,r")
9657 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9658 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9659 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9660 (plus:SI (match_dup 1) (match_dup 2)))]
9662 && (!avoiding_indexed_address_p (SImode)
9663 || !gpc_reg_operand (operands[2], SImode))"
9667 [(set_attr "type" "load")
9668 (set_attr "update" "yes")
9669 (set_attr "indexed" "yes,no")])
9671 (define_insn "*movqi_update2"
9672 [(set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
9674 (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9675 (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
9676 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9677 (plus:SI (match_dup 1) (match_dup 2)))]
9679 && (!avoiding_indexed_address_p (SImode)
9680 || !gpc_reg_operand (operands[2], SImode))"
9684 [(set_attr "type" "load")
9685 (set_attr "update" "yes")
9686 (set_attr "indexed" "yes,no")])
9688 (define_insn "*movqi_update3"
9689 [(set (mem:QI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9690 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9691 (match_operand:QI 3 "gpc_reg_operand" "r,r"))
9692 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9693 (plus:SI (match_dup 1) (match_dup 2)))]
9695 && (!avoiding_indexed_address_p (SImode)
9696 || !gpc_reg_operand (operands[2], SImode))"
9700 [(set_attr "type" "store")
9701 (set_attr "update" "yes")
9702 (set_attr "indexed" "yes,no")])
9704 (define_insn "*movsf_update1"
9705 [(set (match_operand:SF 3 "gpc_reg_operand" "=f,f")
9706 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9707 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9708 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9709 (plus:SI (match_dup 1) (match_dup 2)))]
9710 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9711 && (!avoiding_indexed_address_p (SImode)
9712 || !gpc_reg_operand (operands[2], SImode))"
9716 [(set_attr "type" "fpload")
9717 (set_attr "update" "yes")
9718 (set_attr "indexed" "yes,no")])
9720 (define_insn "*movsf_update2"
9721 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9722 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9723 (match_operand:SF 3 "gpc_reg_operand" "f,f"))
9724 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9725 (plus:SI (match_dup 1) (match_dup 2)))]
9726 "TARGET_HARD_FLOAT && TARGET_SINGLE_FLOAT && TARGET_UPDATE
9727 && (!avoiding_indexed_address_p (SImode)
9728 || !gpc_reg_operand (operands[2], SImode))"
9732 [(set_attr "type" "fpstore")
9733 (set_attr "update" "yes")
9734 (set_attr "indexed" "yes,no")])
9736 (define_insn "*movsf_update3"
9737 [(set (match_operand:SF 3 "gpc_reg_operand" "=r,r")
9738 (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9739 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9740 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9741 (plus:SI (match_dup 1) (match_dup 2)))]
9742 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9743 && (!avoiding_indexed_address_p (SImode)
9744 || !gpc_reg_operand (operands[2], SImode))"
9748 [(set_attr "type" "load")
9749 (set_attr "update" "yes")
9750 (set_attr "indexed" "yes,no")])
9752 (define_insn "*movsf_update4"
9753 [(set (mem:SF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9754 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9755 (match_operand:SF 3 "gpc_reg_operand" "r,r"))
9756 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9757 (plus:SI (match_dup 1) (match_dup 2)))]
9758 "TARGET_SOFT_FLOAT && TARGET_UPDATE
9759 && (!avoiding_indexed_address_p (SImode)
9760 || !gpc_reg_operand (operands[2], SImode))"
9764 [(set_attr "type" "store")
9765 (set_attr "update" "yes")
9766 (set_attr "indexed" "yes,no")])
9768 (define_insn "*movdf_update1"
9769 [(set (match_operand:DF 3 "gpc_reg_operand" "=d,d")
9770 (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9771 (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
9772 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9773 (plus:SI (match_dup 1) (match_dup 2)))]
9774 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9775 && (!avoiding_indexed_address_p (SImode)
9776 || !gpc_reg_operand (operands[2], SImode))"
9780 [(set_attr "type" "fpload")
9781 (set_attr "update" "yes")
9782 (set_attr "indexed" "yes,no")
9783 (set_attr "size" "64")])
9785 (define_insn "*movdf_update2"
9786 [(set (mem:DF (plus:SI (match_operand:SI 1 "gpc_reg_operand" "0,0")
9787 (match_operand:SI 2 "reg_or_short_operand" "r,I")))
9788 (match_operand:DF 3 "gpc_reg_operand" "d,d"))
9789 (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
9790 (plus:SI (match_dup 1) (match_dup 2)))]
9791 "TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
9792 && (!avoiding_indexed_address_p (SImode)
9793 || !gpc_reg_operand (operands[2], SImode))"
9797 [(set_attr "type" "fpstore")
9798 (set_attr "update" "yes")
9799 (set_attr "indexed" "yes,no")])
9802 ;; After inserting conditional returns we can sometimes have
9803 ;; unnecessary register moves. Unfortunately we cannot have a
9804 ;; modeless peephole here, because some single SImode sets have early
9805 ;; clobber outputs. Although those sets expand to multi-ppc-insn
9806 ;; sequences, using get_attr_length here will smash the operands
9807 ;; array. Neither is there an early_cobbler_p predicate.
9808 ;; Also this optimization interferes with scalars going into
9809 ;; altivec registers (the code does reloading through the FPRs).
9811 [(set (match_operand:DF 0 "gpc_reg_operand" "")
9812 (match_operand:DF 1 "any_operand" ""))
9813 (set (match_operand:DF 2 "gpc_reg_operand" "")
9816 && peep2_reg_dead_p (2, operands[0])"
9817 [(set (match_dup 2) (match_dup 1))])
9820 [(set (match_operand:SF 0 "gpc_reg_operand" "")
9821 (match_operand:SF 1 "any_operand" ""))
9822 (set (match_operand:SF 2 "gpc_reg_operand" "")
9825 && peep2_reg_dead_p (2, operands[0])"
9826 [(set (match_dup 2) (match_dup 1))])
9831 ;; Mode attributes for different ABIs.
9832 (define_mode_iterator TLSmode [(SI "! TARGET_64BIT") (DI "TARGET_64BIT")])
9833 (define_mode_attr tls_abi_suffix [(SI "32") (DI "64")])
9834 (define_mode_attr tls_sysv_suffix [(SI "si") (DI "di")])
9835 (define_mode_attr tls_insn_suffix [(SI "wz") (DI "d")])
9837 (define_insn_and_split "tls_gd_aix<TLSmode:tls_abi_suffix>"
9838 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9839 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9840 (match_operand 4 "" "g")))
9841 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9842 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9844 (clobber (reg:SI LR_REGNO))]
9845 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9847 if (TARGET_CMODEL != CMODEL_SMALL)
9848 return "addis %0,%1,%2@got@tlsgd@ha\;addi %0,%0,%2@got@tlsgd@l\;"
9851 return "addi %0,%1,%2@got@tlsgd\;bl %z3\;nop";
9853 "&& TARGET_TLS_MARKERS"
9855 (unspec:TLSmode [(match_dup 1)
9858 (parallel [(set (match_dup 0)
9859 (call (mem:TLSmode (match_dup 3))
9861 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9862 (clobber (reg:SI LR_REGNO))])]
9864 [(set_attr "type" "two")
9865 (set (attr "length")
9866 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9870 (define_insn_and_split "tls_gd_sysv<TLSmode:tls_sysv_suffix>"
9871 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9872 (call (mem:TLSmode (match_operand:TLSmode 3 "symbol_ref_operand" "s"))
9873 (match_operand 4 "" "g")))
9874 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9875 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9877 (clobber (reg:SI LR_REGNO))]
9878 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
9882 if (TARGET_SECURE_PLT && flag_pic == 2)
9883 return "addi %0,%1,%2@got@tlsgd\;bl %z3+32768@plt";
9885 return "addi %0,%1,%2@got@tlsgd\;bl %z3@plt";
9888 return "addi %0,%1,%2@got@tlsgd\;bl %z3";
9890 "&& TARGET_TLS_MARKERS"
9892 (unspec:TLSmode [(match_dup 1)
9895 (parallel [(set (match_dup 0)
9896 (call (mem:TLSmode (match_dup 3))
9898 (unspec:TLSmode [(match_dup 2)] UNSPEC_TLSGD)
9899 (clobber (reg:SI LR_REGNO))])]
9901 [(set_attr "type" "two")
9902 (set_attr "length" "8")])
9904 (define_insn_and_split "*tls_gd<TLSmode:tls_abi_suffix>"
9905 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9906 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9907 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9909 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
9910 "addi %0,%1,%2@got@tlsgd"
9911 "&& TARGET_CMODEL != CMODEL_SMALL"
9914 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))
9916 (lo_sum:TLSmode (match_dup 3)
9917 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGD)))]
9920 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
9922 [(set (attr "length")
9923 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
9927 (define_insn "*tls_gd_high<TLSmode:tls_abi_suffix>"
9928 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9930 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
9931 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9933 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9934 "addis %0,%1,%2@got@tlsgd@ha"
9935 [(set_attr "length" "4")])
9937 (define_insn "*tls_gd_low<TLSmode:tls_abi_suffix>"
9938 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9939 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
9940 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
9941 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
9943 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
9944 "addi %0,%1,%2@got@tlsgd@l"
9945 [(set_attr "length" "4")])
9947 (define_insn "*tls_gd_call_aix<TLSmode:tls_abi_suffix>"
9948 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9949 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9950 (match_operand 2 "" "g")))
9951 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9953 (clobber (reg:SI LR_REGNO))]
9954 "HAVE_AS_TLS && TARGET_TLS_MARKERS
9955 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9956 "bl %z1(%3@tlsgd)\;nop"
9957 [(set_attr "type" "branch")
9958 (set_attr "length" "8")])
9960 (define_insn "*tls_gd_call_sysv<TLSmode:tls_abi_suffix>"
9961 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9962 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
9963 (match_operand 2 "" "g")))
9964 (unspec:TLSmode [(match_operand:TLSmode 3 "rs6000_tls_symbol_ref" "")]
9966 (clobber (reg:SI LR_REGNO))]
9967 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
9971 if (TARGET_SECURE_PLT && flag_pic == 2)
9972 return "bl %z1+32768(%3@tlsgd)@plt";
9973 return "bl %z1(%3@tlsgd)@plt";
9975 return "bl %z1(%3@tlsgd)";
9977 [(set_attr "type" "branch")
9978 (set_attr "length" "4")])
9980 (define_insn_and_split "tls_ld_aix<TLSmode:tls_abi_suffix>"
9981 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
9982 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
9983 (match_operand 3 "" "g")))
9984 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
9986 (clobber (reg:SI LR_REGNO))]
9987 "HAVE_AS_TLS && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
9989 if (TARGET_CMODEL != CMODEL_SMALL)
9990 return "addis %0,%1,%&@got@tlsld@ha\;addi %0,%0,%&@got@tlsld@l\;"
9993 return "addi %0,%1,%&@got@tlsld\;bl %z2\;nop";
9995 "&& TARGET_TLS_MARKERS"
9997 (unspec:TLSmode [(match_dup 1)]
9999 (parallel [(set (match_dup 0)
10000 (call (mem:TLSmode (match_dup 2))
10002 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10003 (clobber (reg:SI LR_REGNO))])]
10005 [(set_attr "type" "two")
10006 (set (attr "length")
10007 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10011 (define_insn_and_split "tls_ld_sysv<TLSmode:tls_sysv_suffix>"
10012 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10013 (call (mem:TLSmode (match_operand:TLSmode 2 "symbol_ref_operand" "s"))
10014 (match_operand 3 "" "g")))
10015 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10017 (clobber (reg:SI LR_REGNO))]
10018 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4"
10022 if (TARGET_SECURE_PLT && flag_pic == 2)
10023 return "addi %0,%1,%&@got@tlsld\;bl %z2+32768@plt";
10025 return "addi %0,%1,%&@got@tlsld\;bl %z2@plt";
10028 return "addi %0,%1,%&@got@tlsld\;bl %z2";
10030 "&& TARGET_TLS_MARKERS"
10031 [(set (match_dup 0)
10032 (unspec:TLSmode [(match_dup 1)]
10034 (parallel [(set (match_dup 0)
10035 (call (mem:TLSmode (match_dup 2))
10037 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10038 (clobber (reg:SI LR_REGNO))])]
10040 [(set_attr "length" "8")])
10042 (define_insn_and_split "*tls_ld<TLSmode:tls_abi_suffix>"
10043 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10044 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10046 "HAVE_AS_TLS && TARGET_TLS_MARKERS"
10047 "addi %0,%1,%&@got@tlsld"
10048 "&& TARGET_CMODEL != CMODEL_SMALL"
10049 [(set (match_dup 2)
10051 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))
10053 (lo_sum:TLSmode (match_dup 2)
10054 (unspec:TLSmode [(const_int 0) (match_dup 1)] UNSPEC_TLSLD)))]
10057 operands[2] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10059 [(set (attr "length")
10060 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10064 (define_insn "*tls_ld_high<TLSmode:tls_abi_suffix>"
10065 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10067 (unspec:TLSmode [(const_int 0)
10068 (match_operand:TLSmode 1 "gpc_reg_operand" "b")]
10070 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10071 "addis %0,%1,%&@got@tlsld@ha"
10072 [(set_attr "length" "4")])
10074 (define_insn "*tls_ld_low<TLSmode:tls_abi_suffix>"
10075 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10076 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10077 (unspec:TLSmode [(const_int 0)
10078 (match_operand:TLSmode 2 "gpc_reg_operand" "b")]
10080 "HAVE_AS_TLS && TARGET_TLS_MARKERS && TARGET_CMODEL != CMODEL_SMALL"
10081 "addi %0,%1,%&@got@tlsld@l"
10082 [(set_attr "length" "4")])
10084 (define_insn "*tls_ld_call_aix<TLSmode:tls_abi_suffix>"
10085 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10086 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10087 (match_operand 2 "" "g")))
10088 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10089 (clobber (reg:SI LR_REGNO))]
10090 "HAVE_AS_TLS && TARGET_TLS_MARKERS
10091 && (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)"
10092 "bl %z1(%&@tlsld)\;nop"
10093 [(set_attr "type" "branch")
10094 (set_attr "length" "8")])
10096 (define_insn "*tls_ld_call_sysv<TLSmode:tls_abi_suffix>"
10097 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10098 (call (mem:TLSmode (match_operand:TLSmode 1 "symbol_ref_operand" "s"))
10099 (match_operand 2 "" "g")))
10100 (unspec:TLSmode [(const_int 0)] UNSPEC_TLSLD)
10101 (clobber (reg:SI LR_REGNO))]
10102 "HAVE_AS_TLS && DEFAULT_ABI == ABI_V4 && TARGET_TLS_MARKERS"
10106 if (TARGET_SECURE_PLT && flag_pic == 2)
10107 return "bl %z1+32768(%&@tlsld)@plt";
10108 return "bl %z1(%&@tlsld)@plt";
10110 return "bl %z1(%&@tlsld)";
10112 [(set_attr "type" "branch")
10113 (set_attr "length" "4")])
10115 (define_insn "tls_dtprel_<TLSmode:tls_abi_suffix>"
10116 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10117 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10118 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10119 UNSPEC_TLSDTPREL))]
10121 "addi %0,%1,%2@dtprel")
10123 (define_insn "tls_dtprel_ha_<TLSmode:tls_abi_suffix>"
10124 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10125 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10126 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10127 UNSPEC_TLSDTPRELHA))]
10129 "addis %0,%1,%2@dtprel@ha")
10131 (define_insn "tls_dtprel_lo_<TLSmode:tls_abi_suffix>"
10132 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10133 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10134 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10135 UNSPEC_TLSDTPRELLO))]
10137 "addi %0,%1,%2@dtprel@l")
10139 (define_insn_and_split "tls_got_dtprel_<TLSmode:tls_abi_suffix>"
10140 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10141 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10142 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10143 UNSPEC_TLSGOTDTPREL))]
10145 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel(%1)"
10146 "&& TARGET_CMODEL != CMODEL_SMALL"
10147 [(set (match_dup 3)
10149 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))
10151 (lo_sum:TLSmode (match_dup 3)
10152 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTDTPREL)))]
10155 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10157 [(set (attr "length")
10158 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10162 (define_insn "*tls_got_dtprel_high<TLSmode:tls_abi_suffix>"
10163 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10165 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10166 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10167 UNSPEC_TLSGOTDTPREL)))]
10168 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10169 "addis %0,%1,%2@got@dtprel@ha"
10170 [(set_attr "length" "4")])
10172 (define_insn "*tls_got_dtprel_low<TLSmode:tls_abi_suffix>"
10173 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10174 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10175 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10176 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10177 UNSPEC_TLSGOTDTPREL)))]
10178 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10179 "l<TLSmode:tls_insn_suffix> %0,%2@got@dtprel@l(%1)"
10180 [(set_attr "length" "4")])
10182 (define_insn "tls_tprel_<TLSmode:tls_abi_suffix>"
10183 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10184 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10185 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10188 "addi %0,%1,%2@tprel")
10190 (define_insn "tls_tprel_ha_<TLSmode:tls_abi_suffix>"
10191 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10192 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10193 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10194 UNSPEC_TLSTPRELHA))]
10196 "addis %0,%1,%2@tprel@ha")
10198 (define_insn "tls_tprel_lo_<TLSmode:tls_abi_suffix>"
10199 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10200 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10201 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10202 UNSPEC_TLSTPRELLO))]
10204 "addi %0,%1,%2@tprel@l")
10206 ;; "b" output constraint here and on tls_tls input to support linker tls
10207 ;; optimization. The linker may edit the instructions emitted by a
10208 ;; tls_got_tprel/tls_tls pair to addis,addi.
10209 (define_insn_and_split "tls_got_tprel_<TLSmode:tls_abi_suffix>"
10210 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10211 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10212 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10213 UNSPEC_TLSGOTTPREL))]
10215 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel(%1)"
10216 "&& TARGET_CMODEL != CMODEL_SMALL"
10217 [(set (match_dup 3)
10219 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))
10221 (lo_sum:TLSmode (match_dup 3)
10222 (unspec:TLSmode [(match_dup 1) (match_dup 2)] UNSPEC_TLSGOTTPREL)))]
10225 operands[3] = gen_reg_rtx (TARGET_64BIT ? DImode : SImode);
10227 [(set (attr "length")
10228 (if_then_else (ne (symbol_ref "TARGET_CMODEL") (symbol_ref "CMODEL_SMALL"))
10232 (define_insn "*tls_got_tprel_high<TLSmode:tls_abi_suffix>"
10233 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=b")
10235 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10236 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10237 UNSPEC_TLSGOTTPREL)))]
10238 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10239 "addis %0,%1,%2@got@tprel@ha"
10240 [(set_attr "length" "4")])
10242 (define_insn "*tls_got_tprel_low<TLSmode:tls_abi_suffix>"
10243 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10244 (lo_sum:TLSmode (match_operand:TLSmode 1 "gpc_reg_operand" "b")
10245 (unspec:TLSmode [(match_operand:TLSmode 3 "gpc_reg_operand" "b")
10246 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10247 UNSPEC_TLSGOTTPREL)))]
10248 "HAVE_AS_TLS && TARGET_CMODEL != CMODEL_SMALL"
10249 "l<TLSmode:tls_insn_suffix> %0,%2@got@tprel@l(%1)"
10250 [(set_attr "length" "4")])
10252 (define_insn "tls_tls_<TLSmode:tls_abi_suffix>"
10253 [(set (match_operand:TLSmode 0 "gpc_reg_operand" "=r")
10254 (unspec:TLSmode [(match_operand:TLSmode 1 "gpc_reg_operand" "b")
10255 (match_operand:TLSmode 2 "rs6000_tls_symbol_ref" "")]
10257 "TARGET_ELF && HAVE_AS_TLS"
10258 "add %0,%1,%2@tls")
10260 (define_expand "tls_get_tpointer"
10261 [(set (match_operand:SI 0 "gpc_reg_operand" "")
10262 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))]
10263 "TARGET_XCOFF && HAVE_AS_TLS"
10266 emit_insn (gen_tls_get_tpointer_internal ());
10267 emit_move_insn (operands[0], gen_rtx_REG (SImode, 3));
10271 (define_insn "tls_get_tpointer_internal"
10273 (unspec:SI [(const_int 0)] UNSPEC_TLSTLS))
10274 (clobber (reg:SI LR_REGNO))]
10275 "TARGET_XCOFF && HAVE_AS_TLS"
10276 "bla __get_tpointer")
10278 (define_expand "tls_get_addr<mode>"
10279 [(set (match_operand:P 0 "gpc_reg_operand" "")
10280 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "")
10281 (match_operand:P 2 "gpc_reg_operand" "")] UNSPEC_TLSTLS))]
10282 "TARGET_XCOFF && HAVE_AS_TLS"
10285 emit_move_insn (gen_rtx_REG (Pmode, 3), operands[1]);
10286 emit_move_insn (gen_rtx_REG (Pmode, 4), operands[2]);
10287 emit_insn (gen_tls_get_addr_internal<mode> ());
10288 emit_move_insn (operands[0], gen_rtx_REG (Pmode, 3));
10292 (define_insn "tls_get_addr_internal<mode>"
10294 (unspec:P [(reg:P 3) (reg:P 4)] UNSPEC_TLSTLS))
10295 (clobber (reg:P 0))
10296 (clobber (reg:P 4))
10297 (clobber (reg:P 5))
10298 (clobber (reg:P 11))
10299 (clobber (reg:CC CR0_REGNO))
10300 (clobber (reg:P LR_REGNO))]
10301 "TARGET_XCOFF && HAVE_AS_TLS"
10302 "bla __tls_get_addr")
10304 ;; Next come insns related to the calling sequence.
10306 ;; First, an insn to allocate new stack space for dynamic use (e.g., alloca).
10307 ;; We move the back-chain and decrement the stack pointer.
10309 ;; Operand1 is more naturally reg_or_short_operand. However, for a large
10310 ;; constant alloca, using that predicate will force the generic code to put
10311 ;; the constant size into a register before calling the expander.
10313 ;; As a result the expander would not have the constant size information
10314 ;; in those cases and would have to generate less efficient code.
10316 ;; Thus we allow reg_or_cint_operand instead so that the expander can see
10317 ;; the constant size. The value is forced into a register if necessary.
10319 (define_expand "allocate_stack"
10320 [(set (match_operand 0 "gpc_reg_operand" "")
10321 (minus (reg 1) (match_operand 1 "reg_or_cint_operand" "")))
10323 (minus (reg 1) (match_dup 1)))]
10326 { rtx chain = gen_reg_rtx (Pmode);
10327 rtx stack_bot = gen_rtx_MEM (Pmode, stack_pointer_rtx);
10329 rtx insn, par, set, mem;
10331 /* By allowing reg_or_cint_operand as the predicate we can get
10332 better code for stack-clash-protection because we do not lose
10333 size information. But the rest of the code expects the operand
10334 to be reg_or_short_operand. If it isn't, then force it into
10336 rtx orig_op1 = operands[1];
10337 if (!reg_or_short_operand (operands[1], Pmode))
10338 operands[1] = force_reg (Pmode, operands[1]);
10340 emit_move_insn (chain, stack_bot);
10342 /* Check stack bounds if necessary. */
10343 if (crtl->limit_stack)
10346 available = expand_binop (Pmode, sub_optab,
10347 stack_pointer_rtx, stack_limit_rtx,
10348 NULL_RTX, 1, OPTAB_WIDEN);
10349 emit_insn (gen_cond_trap (LTU, available, operands[1], const0_rtx));
10352 /* Allocate and probe if requested.
10353 This may look similar to the loop we use for prologue allocations,
10354 but it is critically different. For the former we know the loop
10355 will iterate, but do not know that generally here. The former
10356 uses that knowledge to rotate the loop. Combining them would be
10357 possible with some performance cost. */
10358 if (flag_stack_clash_protection)
10360 rtx rounded_size, last_addr, residual;
10361 HOST_WIDE_INT probe_interval;
10362 compute_stack_clash_protection_loop_data (&rounded_size, &last_addr,
10363 &residual, &probe_interval,
10366 /* We do occasionally get in here with constant sizes, we might
10367 as well do a reasonable job when we obviously can. */
10368 if (rounded_size != const0_rtx)
10370 rtx loop_lab, end_loop;
10371 bool rotated = CONST_INT_P (rounded_size);
10372 rtx update = GEN_INT (-probe_interval);
10373 if (probe_interval > 32768)
10374 update = force_reg (Pmode, update);
10376 emit_stack_clash_protection_probe_loop_start (&loop_lab, &end_loop,
10377 last_addr, rotated);
10379 if (Pmode == SImode)
10380 emit_insn (gen_movsi_update_stack (stack_pointer_rtx,
10384 emit_insn (gen_movdi_di_update_stack (stack_pointer_rtx,
10387 emit_stack_clash_protection_probe_loop_end (loop_lab, end_loop,
10388 last_addr, rotated);
10391 /* Now handle residuals. We just have to set operands[1] correctly
10392 and let the rest of the expander run. */
10393 operands[1] = residual;
10394 if (!CONST_INT_P (residual))
10395 operands[1] = force_reg (Pmode, operands[1]);
10398 if (GET_CODE (operands[1]) != CONST_INT
10399 || INTVAL (operands[1]) < -32767
10400 || INTVAL (operands[1]) > 32768)
10402 neg_op0 = gen_reg_rtx (Pmode);
10404 emit_insn (gen_negsi2 (neg_op0, operands[1]));
10406 emit_insn (gen_negdi2 (neg_op0, operands[1]));
10409 neg_op0 = GEN_INT (- INTVAL (operands[1]));
10411 insn = emit_insn ((* ((TARGET_32BIT) ? gen_movsi_update_stack
10412 : gen_movdi_di_update_stack))
10413 (stack_pointer_rtx, stack_pointer_rtx, neg_op0,
10415 /* Since we didn't use gen_frame_mem to generate the MEM, grab
10416 it now and set the alias set/attributes. The above gen_*_update
10417 calls will generate a PARALLEL with the MEM set being the first
10419 par = PATTERN (insn);
10420 gcc_assert (GET_CODE (par) == PARALLEL);
10421 set = XVECEXP (par, 0, 0);
10422 gcc_assert (GET_CODE (set) == SET);
10423 mem = SET_DEST (set);
10424 gcc_assert (MEM_P (mem));
10425 MEM_NOTRAP_P (mem) = 1;
10426 set_mem_alias_set (mem, get_frame_alias_set ());
10428 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
10432 ;; These patterns say how to save and restore the stack pointer. We need not
10433 ;; save the stack pointer at function level since we are careful to
10434 ;; preserve the backchain. At block level, we have to restore the backchain
10435 ;; when we restore the stack pointer.
10437 ;; For nonlocal gotos, we must save both the stack pointer and its
10438 ;; backchain and restore both. Note that in the nonlocal case, the
10439 ;; save area is a memory location.
10441 (define_expand "save_stack_function"
10442 [(match_operand 0 "any_operand" "")
10443 (match_operand 1 "any_operand" "")]
10447 (define_expand "restore_stack_function"
10448 [(match_operand 0 "any_operand" "")
10449 (match_operand 1 "any_operand" "")]
10453 ;; Adjust stack pointer (op0) to a new value (op1).
10454 ;; First copy old stack backchain to new location, and ensure that the
10455 ;; scheduler won't reorder the sp assignment before the backchain write.
10456 (define_expand "restore_stack_block"
10457 [(set (match_dup 2) (match_dup 3))
10458 (set (match_dup 4) (match_dup 2))
10460 (set (match_operand 0 "register_operand" "")
10461 (match_operand 1 "register_operand" ""))]
10467 operands[1] = force_reg (Pmode, operands[1]);
10468 operands[2] = gen_reg_rtx (Pmode);
10469 operands[3] = gen_frame_mem (Pmode, operands[0]);
10470 operands[4] = gen_frame_mem (Pmode, operands[1]);
10471 p = rtvec_alloc (1);
10472 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10474 operands[5] = gen_rtx_PARALLEL (VOIDmode, p);
10477 (define_expand "save_stack_nonlocal"
10478 [(set (match_dup 3) (match_dup 4))
10479 (set (match_operand 0 "memory_operand" "") (match_dup 3))
10480 (set (match_dup 2) (match_operand 1 "register_operand" ""))]
10484 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10486 /* Copy the backchain to the first word, sp to the second. */
10487 operands[0] = adjust_address_nv (operands[0], Pmode, 0);
10488 operands[2] = adjust_address_nv (operands[0], Pmode, units_per_word);
10489 operands[3] = gen_reg_rtx (Pmode);
10490 operands[4] = gen_frame_mem (Pmode, operands[1]);
10493 (define_expand "restore_stack_nonlocal"
10494 [(set (match_dup 2) (match_operand 1 "memory_operand" ""))
10495 (set (match_dup 3) (match_dup 4))
10496 (set (match_dup 5) (match_dup 2))
10498 (set (match_operand 0 "register_operand" "") (match_dup 3))]
10502 int units_per_word = (TARGET_32BIT) ? 4 : 8;
10505 /* Restore the backchain from the first word, sp from the second. */
10506 operands[2] = gen_reg_rtx (Pmode);
10507 operands[3] = gen_reg_rtx (Pmode);
10508 operands[1] = adjust_address_nv (operands[1], Pmode, 0);
10509 operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word);
10510 operands[5] = gen_frame_mem (Pmode, operands[3]);
10511 p = rtvec_alloc (1);
10512 RTVEC_ELT (p, 0) = gen_rtx_SET (gen_frame_mem (BLKmode, operands[0]),
10514 operands[6] = gen_rtx_PARALLEL (VOIDmode, p);
10517 ;; TOC register handling.
10519 ;; Code to initialize the TOC register...
10521 (define_insn "load_toc_aix_si"
10522 [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10523 (unspec:SI [(const_int 0)] UNSPEC_TOC))
10524 (use (reg:SI 2))])]
10525 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_32BIT"
10529 extern int need_toc_init;
10531 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\", 1);
10532 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10533 operands[2] = gen_rtx_REG (Pmode, 2);
10534 return \"lwz %0,%1(%2)\";
10536 [(set_attr "type" "load")
10537 (set_attr "update" "no")
10538 (set_attr "indexed" "no")])
10540 (define_insn "load_toc_aix_di"
10541 [(parallel [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10542 (unspec:DI [(const_int 0)] UNSPEC_TOC))
10543 (use (reg:DI 2))])]
10544 "(DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2) && TARGET_64BIT"
10548 extern int need_toc_init;
10550 ASM_GENERATE_INTERNAL_LABEL (buf, \"LCTOC\",
10551 !TARGET_ELF || !TARGET_MINIMAL_TOC);
10553 strcat (buf, \"@toc\");
10554 operands[1] = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (buf));
10555 operands[2] = gen_rtx_REG (Pmode, 2);
10556 return \"ld %0,%1(%2)\";
10558 [(set_attr "type" "load")
10559 (set_attr "update" "no")
10560 (set_attr "indexed" "no")])
10562 (define_insn "load_toc_v4_pic_si"
10563 [(set (reg:SI LR_REGNO)
10564 (unspec:SI [(const_int 0)] UNSPEC_TOC))]
10565 "DEFAULT_ABI == ABI_V4 && flag_pic == 1 && TARGET_32BIT"
10566 "bl _GLOBAL_OFFSET_TABLE_@local-4"
10567 [(set_attr "type" "branch")
10568 (set_attr "length" "4")])
10570 (define_expand "load_toc_v4_PIC_1"
10571 [(parallel [(set (reg:SI LR_REGNO)
10572 (match_operand:SI 0 "immediate_operand" "s"))
10573 (use (unspec [(match_dup 0)] UNSPEC_TOC))])]
10574 "TARGET_ELF && DEFAULT_ABI == ABI_V4
10575 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10578 (define_insn "load_toc_v4_PIC_1_normal"
10579 [(set (reg:SI LR_REGNO)
10580 (match_operand:SI 0 "immediate_operand" "s"))
10581 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10582 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10583 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10584 "bcl 20,31,%0\\n%0:"
10585 [(set_attr "type" "branch")
10586 (set_attr "length" "4")
10587 (set_attr "cannot_copy" "yes")])
10589 (define_insn "load_toc_v4_PIC_1_476"
10590 [(set (reg:SI LR_REGNO)
10591 (match_operand:SI 0 "immediate_operand" "s"))
10592 (use (unspec [(match_dup 0)] UNSPEC_TOC))]
10593 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4
10594 && (flag_pic == 2 || (flag_pic && TARGET_SECURE_PLT))"
10598 static char templ[32];
10600 get_ppc476_thunk_name (name);
10601 sprintf (templ, \"bl %s\\n%%0:\", name);
10604 [(set_attr "type" "branch")
10605 (set_attr "length" "4")
10606 (set_attr "cannot_copy" "yes")])
10608 (define_expand "load_toc_v4_PIC_1b"
10609 [(parallel [(set (reg:SI LR_REGNO)
10610 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10611 (label_ref (match_operand 1 "" ""))]
10614 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10617 (define_insn "load_toc_v4_PIC_1b_normal"
10618 [(set (reg:SI LR_REGNO)
10619 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10620 (label_ref (match_operand 1 "" ""))]
10623 "!TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10624 "bcl 20,31,$+8\;.long %0-$"
10625 [(set_attr "type" "branch")
10626 (set_attr "length" "8")])
10628 (define_insn "load_toc_v4_PIC_1b_476"
10629 [(set (reg:SI LR_REGNO)
10630 (unspec:SI [(match_operand:SI 0 "immediate_operand" "s")
10631 (label_ref (match_operand 1 "" ""))]
10634 "TARGET_LINK_STACK && TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10638 static char templ[32];
10640 get_ppc476_thunk_name (name);
10641 sprintf (templ, \"bl %s\\n\\tb $+8\\n\\t.long %%0-$\", name);
10644 [(set_attr "type" "branch")
10645 (set_attr "length" "16")])
10647 (define_insn "load_toc_v4_PIC_2"
10648 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10649 (mem:SI (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10650 (minus:SI (match_operand:SI 2 "immediate_operand" "s")
10651 (match_operand:SI 3 "immediate_operand" "s")))))]
10652 "TARGET_ELF && DEFAULT_ABI == ABI_V4 && flag_pic == 2"
10654 [(set_attr "type" "load")])
10656 (define_insn "load_toc_v4_PIC_3b"
10657 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10658 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10660 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10661 (match_operand:SI 3 "symbol_ref_operand" "s")))))]
10662 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10663 "addis %0,%1,%2-%3@ha")
10665 (define_insn "load_toc_v4_PIC_3c"
10666 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10667 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10668 (minus:SI (match_operand:SI 2 "symbol_ref_operand" "s")
10669 (match_operand:SI 3 "symbol_ref_operand" "s"))))]
10670 "TARGET_ELF && TARGET_SECURE_PLT && DEFAULT_ABI == ABI_V4 && flag_pic"
10671 "addi %0,%1,%2-%3@l")
10673 ;; If the TOC is shared over a translation unit, as happens with all
10674 ;; the kinds of PIC that we support, we need to restore the TOC
10675 ;; pointer only when jumping over units of translation.
10676 ;; On Darwin, we need to reload the picbase.
10678 (define_expand "builtin_setjmp_receiver"
10679 [(use (label_ref (match_operand 0 "" "")))]
10680 "(DEFAULT_ABI == ABI_V4 && flag_pic == 1)
10681 || (TARGET_TOC && TARGET_MINIMAL_TOC)
10682 || (DEFAULT_ABI == ABI_DARWIN && flag_pic)"
10686 if (DEFAULT_ABI == ABI_DARWIN)
10688 rtx picrtx = gen_rtx_SYMBOL_REF (Pmode, MACHOPIC_FUNCTION_BASE_NAME);
10689 rtx picreg = gen_rtx_REG (Pmode, RS6000_PIC_OFFSET_TABLE_REGNUM);
10693 crtl->uses_pic_offset_table = 1;
10694 ASM_GENERATE_INTERNAL_LABEL(tmplab, \"LSJR\",
10695 CODE_LABEL_NUMBER (operands[0]));
10696 tmplabrtx = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (tmplab));
10698 emit_insn (gen_load_macho_picbase (tmplabrtx));
10699 emit_move_insn (picreg, gen_rtx_REG (Pmode, LR_REGNO));
10700 emit_insn (gen_macho_correct_pic (picreg, picreg, picrtx, tmplabrtx));
10704 rs6000_emit_load_toc_table (FALSE);
10708 ;; Largetoc support
10709 (define_insn "*largetoc_high"
10710 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10712 (unspec [(match_operand:DI 1 "" "")
10713 (match_operand:DI 2 "gpc_reg_operand" "b")]
10715 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10716 "addis %0,%2,%1@toc@ha")
10718 (define_insn "*largetoc_high_aix<mode>"
10719 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10721 (unspec [(match_operand:P 1 "" "")
10722 (match_operand:P 2 "gpc_reg_operand" "b")]
10724 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10725 "addis %0,%1@u(%2)")
10727 (define_insn "*largetoc_high_plus"
10728 [(set (match_operand:DI 0 "gpc_reg_operand" "=b*r")
10731 (unspec [(match_operand:DI 1 "" "")
10732 (match_operand:DI 2 "gpc_reg_operand" "b")]
10734 (match_operand:DI 3 "add_cint_operand" "n"))))]
10735 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10736 "addis %0,%2,%1+%3@toc@ha")
10738 (define_insn "*largetoc_high_plus_aix<mode>"
10739 [(set (match_operand:P 0 "gpc_reg_operand" "=b*r")
10742 (unspec [(match_operand:P 1 "" "")
10743 (match_operand:P 2 "gpc_reg_operand" "b")]
10745 (match_operand:P 3 "add_cint_operand" "n"))))]
10746 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10747 "addis %0,%1+%3@u(%2)")
10749 (define_insn "*largetoc_low"
10750 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
10751 (lo_sum:DI (match_operand:DI 1 "gpc_reg_operand" "b")
10752 (match_operand:DI 2 "" "")))]
10753 "TARGET_ELF && TARGET_CMODEL != CMODEL_SMALL"
10756 (define_insn "*largetoc_low_aix<mode>"
10757 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
10758 (lo_sum:P (match_operand:P 1 "gpc_reg_operand" "b")
10759 (match_operand:P 2 "" "")))]
10760 "TARGET_XCOFF && TARGET_CMODEL != CMODEL_SMALL"
10763 (define_insn_and_split "*tocref<mode>"
10764 [(set (match_operand:P 0 "gpc_reg_operand" "=b")
10765 (match_operand:P 1 "small_toc_ref" "R"))]
10768 "&& TARGET_CMODEL != CMODEL_SMALL && reload_completed"
10769 [(set (match_dup 0) (high:P (match_dup 1)))
10770 (set (match_dup 0) (lo_sum:P (match_dup 0) (match_dup 1)))])
10772 ;; Elf specific ways of loading addresses for non-PIC code.
10773 ;; The output of this could be r0, but we make a very strong
10774 ;; preference for a base register because it will usually
10775 ;; be needed there.
10776 (define_insn "elf_high"
10777 [(set (match_operand:SI 0 "gpc_reg_operand" "=b*r")
10778 (high:SI (match_operand 1 "" "")))]
10779 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10782 (define_insn "elf_low"
10783 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
10784 (lo_sum:SI (match_operand:SI 1 "gpc_reg_operand" "b")
10785 (match_operand 2 "" "")))]
10786 "TARGET_ELF && !TARGET_64BIT && !flag_pic"
10789 ;; Call and call_value insns
10790 (define_expand "call"
10791 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
10792 (match_operand 1 "" ""))
10793 (use (match_operand 2 "" ""))
10794 (clobber (reg:SI LR_REGNO))])]
10799 if (MACHOPIC_INDIRECT)
10800 operands[0] = machopic_indirect_call_target (operands[0]);
10803 gcc_assert (GET_CODE (operands[0]) == MEM);
10804 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
10806 operands[0] = XEXP (operands[0], 0);
10808 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10810 rs6000_call_aix (NULL_RTX, operands[0], operands[1], operands[2]);
10814 if (GET_CODE (operands[0]) != SYMBOL_REF
10815 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[2]) & CALL_LONG) != 0))
10817 if (INTVAL (operands[2]) & CALL_LONG)
10818 operands[0] = rs6000_longcall_ref (operands[0]);
10820 switch (DEFAULT_ABI)
10824 operands[0] = force_reg (Pmode, operands[0]);
10828 gcc_unreachable ();
10833 (define_expand "call_value"
10834 [(parallel [(set (match_operand 0 "" "")
10835 (call (mem:SI (match_operand 1 "address_operand" ""))
10836 (match_operand 2 "" "")))
10837 (use (match_operand 3 "" ""))
10838 (clobber (reg:SI LR_REGNO))])]
10843 if (MACHOPIC_INDIRECT)
10844 operands[1] = machopic_indirect_call_target (operands[1]);
10847 gcc_assert (GET_CODE (operands[1]) == MEM);
10848 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
10850 operands[1] = XEXP (operands[1], 0);
10852 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
10854 rs6000_call_aix (operands[0], operands[1], operands[2], operands[3]);
10858 if (GET_CODE (operands[1]) != SYMBOL_REF
10859 || (DEFAULT_ABI != ABI_DARWIN && (INTVAL (operands[3]) & CALL_LONG) != 0))
10861 if (INTVAL (operands[3]) & CALL_LONG)
10862 operands[1] = rs6000_longcall_ref (operands[1]);
10864 switch (DEFAULT_ABI)
10868 operands[1] = force_reg (Pmode, operands[1]);
10872 gcc_unreachable ();
10877 ;; Call to function in current module. No TOC pointer reload needed.
10878 ;; Operand2 is nonzero if we are using the V.4 calling sequence and
10879 ;; either the function was not prototyped, or it was prototyped as a
10880 ;; variable argument function. It is > 0 if FP registers were passed
10881 ;; and < 0 if they were not.
10883 (define_insn "*call_local32"
10884 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
10885 (match_operand 1 "" "g,g"))
10886 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10887 (clobber (reg:SI LR_REGNO))]
10888 "(INTVAL (operands[2]) & CALL_LONG) == 0"
10891 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10892 output_asm_insn (\"crxor 6,6,6\", operands);
10894 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10895 output_asm_insn (\"creqv 6,6,6\", operands);
10897 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10899 [(set_attr "type" "branch")
10900 (set_attr "length" "4,8")])
10902 (define_insn "*call_local64"
10903 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
10904 (match_operand 1 "" "g,g"))
10905 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10906 (clobber (reg:SI LR_REGNO))]
10907 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
10910 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10911 output_asm_insn (\"crxor 6,6,6\", operands);
10913 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10914 output_asm_insn (\"creqv 6,6,6\", operands);
10916 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z0@local\" : \"bl %z0\";
10918 [(set_attr "type" "branch")
10919 (set_attr "length" "4,8")])
10921 (define_insn "*call_value_local32"
10922 [(set (match_operand 0 "" "")
10923 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
10924 (match_operand 2 "" "g,g")))
10925 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10926 (clobber (reg:SI LR_REGNO))]
10927 "(INTVAL (operands[3]) & CALL_LONG) == 0"
10930 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10931 output_asm_insn (\"crxor 6,6,6\", operands);
10933 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10934 output_asm_insn (\"creqv 6,6,6\", operands);
10936 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10938 [(set_attr "type" "branch")
10939 (set_attr "length" "4,8")])
10942 (define_insn "*call_value_local64"
10943 [(set (match_operand 0 "" "")
10944 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
10945 (match_operand 2 "" "g,g")))
10946 (use (match_operand:SI 3 "immediate_operand" "O,n"))
10947 (clobber (reg:SI LR_REGNO))]
10948 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
10951 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
10952 output_asm_insn (\"crxor 6,6,6\", operands);
10954 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
10955 output_asm_insn (\"creqv 6,6,6\", operands);
10957 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"bl %z1@local\" : \"bl %z1\";
10959 [(set_attr "type" "branch")
10960 (set_attr "length" "4,8")])
10963 ;; A function pointer under System V is just a normal pointer
10964 ;; operands[0] is the function pointer
10965 ;; operands[1] is the stack size to clean up
10966 ;; operands[2] is the value FUNCTION_ARG returns for the VOID argument
10967 ;; which indicates how to set cr1
10969 (define_insn "*call_indirect_nonlocal_sysv<mode>"
10970 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l,c,*l"))
10971 (match_operand 1 "" "g,g,g,g"))
10972 (use (match_operand:SI 2 "immediate_operand" "O,O,n,n"))
10973 (clobber (reg:SI LR_REGNO))]
10974 "DEFAULT_ABI == ABI_V4
10975 || DEFAULT_ABI == ABI_DARWIN"
10977 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10978 output_asm_insn ("crxor 6,6,6", operands);
10980 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
10981 output_asm_insn ("creqv 6,6,6", operands);
10985 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
10986 (set_attr "length" "4,4,8,8")])
10988 (define_insn_and_split "*call_nonlocal_sysv<mode>"
10989 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
10990 (match_operand 1 "" "g,g"))
10991 (use (match_operand:SI 2 "immediate_operand" "O,n"))
10992 (clobber (reg:SI LR_REGNO))]
10993 "(DEFAULT_ABI == ABI_DARWIN
10994 || (DEFAULT_ABI == ABI_V4
10995 && (INTVAL (operands[2]) & CALL_LONG) == 0))"
10997 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
10998 output_asm_insn ("crxor 6,6,6", operands);
11000 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11001 output_asm_insn ("creqv 6,6,6", operands);
11004 return output_call(insn, operands, 0, 2);
11006 if (DEFAULT_ABI == ABI_V4 && flag_pic)
11008 gcc_assert (!TARGET_SECURE_PLT);
11009 return "bl %z0@plt";
11015 "DEFAULT_ABI == ABI_V4
11016 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11017 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11018 [(parallel [(call (mem:SI (match_dup 0))
11020 (use (match_dup 2))
11021 (use (match_dup 3))
11022 (clobber (reg:SI LR_REGNO))])]
11024 operands[3] = pic_offset_table_rtx;
11026 [(set_attr "type" "branch,branch")
11027 (set_attr "length" "4,8")])
11029 (define_insn "*call_nonlocal_sysv_secure<mode>"
11030 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
11031 (match_operand 1 "" "g,g"))
11032 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11033 (use (match_operand:SI 3 "register_operand" "r,r"))
11034 (clobber (reg:SI LR_REGNO))]
11035 "(DEFAULT_ABI == ABI_V4
11036 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[0])
11037 && (INTVAL (operands[2]) & CALL_LONG) == 0)"
11039 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11040 output_asm_insn ("crxor 6,6,6", operands);
11042 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11043 output_asm_insn ("creqv 6,6,6", operands);
11046 /* The magic 32768 offset here and in the other sysv call insns
11047 corresponds to the offset of r30 in .got2, as given by LCTOC1.
11048 See sysv4.h:toc_section. */
11049 return "bl %z0+32768@plt";
11051 return "bl %z0@plt";
11053 [(set_attr "type" "branch,branch")
11054 (set_attr "length" "4,8")])
11056 (define_insn "*call_value_indirect_nonlocal_sysv<mode>"
11057 [(set (match_operand 0 "" "")
11058 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l,c,*l"))
11059 (match_operand 2 "" "g,g,g,g")))
11060 (use (match_operand:SI 3 "immediate_operand" "O,O,n,n"))
11061 (clobber (reg:SI LR_REGNO))]
11062 "DEFAULT_ABI == ABI_V4
11063 || DEFAULT_ABI == ABI_DARWIN"
11065 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11066 output_asm_insn ("crxor 6,6,6", operands);
11068 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11069 output_asm_insn ("creqv 6,6,6", operands);
11073 [(set_attr "type" "jmpreg,jmpreg,jmpreg,jmpreg")
11074 (set_attr "length" "4,4,8,8")])
11076 (define_insn_and_split "*call_value_nonlocal_sysv<mode>"
11077 [(set (match_operand 0 "" "")
11078 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11079 (match_operand 2 "" "g,g")))
11080 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11081 (clobber (reg:SI LR_REGNO))]
11082 "(DEFAULT_ABI == ABI_DARWIN
11083 || (DEFAULT_ABI == ABI_V4
11084 && (INTVAL (operands[3]) & CALL_LONG) == 0))"
11086 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11087 output_asm_insn ("crxor 6,6,6", operands);
11089 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11090 output_asm_insn ("creqv 6,6,6", operands);
11093 return output_call(insn, operands, 1, 3);
11095 if (DEFAULT_ABI == ABI_V4 && flag_pic)
11097 gcc_assert (!TARGET_SECURE_PLT);
11098 return "bl %z1@plt";
11104 "DEFAULT_ABI == ABI_V4
11105 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11106 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11107 [(parallel [(set (match_dup 0)
11108 (call (mem:SI (match_dup 1))
11110 (use (match_dup 3))
11111 (use (match_dup 4))
11112 (clobber (reg:SI LR_REGNO))])]
11114 operands[4] = pic_offset_table_rtx;
11116 [(set_attr "type" "branch,branch")
11117 (set_attr "length" "4,8")])
11119 (define_insn "*call_value_nonlocal_sysv_secure<mode>"
11120 [(set (match_operand 0 "" "")
11121 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
11122 (match_operand 2 "" "g,g")))
11123 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11124 (use (match_operand:SI 4 "register_operand" "r,r"))
11125 (clobber (reg:SI LR_REGNO))]
11126 "(DEFAULT_ABI == ABI_V4
11127 && TARGET_SECURE_PLT && flag_pic && !SYMBOL_REF_LOCAL_P (operands[1])
11128 && (INTVAL (operands[3]) & CALL_LONG) == 0)"
11130 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11131 output_asm_insn ("crxor 6,6,6", operands);
11133 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11134 output_asm_insn ("creqv 6,6,6", operands);
11137 return "bl %z1+32768@plt";
11139 return "bl %z1@plt";
11141 [(set_attr "type" "branch,branch")
11142 (set_attr "length" "4,8")])
11145 ;; Call to AIX abi function in the same module.
11147 (define_insn "*call_local_aix<mode>"
11148 [(call (mem:SI (match_operand:P 0 "current_file_function_operand" "s"))
11149 (match_operand 1 "" "g"))
11150 (clobber (reg:P LR_REGNO))]
11151 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11153 [(set_attr "type" "branch")
11154 (set_attr "length" "4")])
11156 (define_insn "*call_value_local_aix<mode>"
11157 [(set (match_operand 0 "" "")
11158 (call (mem:SI (match_operand:P 1 "current_file_function_operand" "s"))
11159 (match_operand 2 "" "g")))
11160 (clobber (reg:P LR_REGNO))]
11161 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11163 [(set_attr "type" "branch")
11164 (set_attr "length" "4")])
11166 ;; Call to AIX abi function which may be in another module.
11167 ;; Restore the TOC pointer (r2) after the call.
11169 (define_insn "*call_nonlocal_aix<mode>"
11170 [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s"))
11171 (match_operand 1 "" "g"))
11172 (clobber (reg:P LR_REGNO))]
11173 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11175 [(set_attr "type" "branch")
11176 (set_attr "length" "8")])
11178 (define_insn "*call_value_nonlocal_aix<mode>"
11179 [(set (match_operand 0 "" "")
11180 (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s"))
11181 (match_operand 2 "" "g")))
11182 (clobber (reg:P LR_REGNO))]
11183 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11185 [(set_attr "type" "branch")
11186 (set_attr "length" "8")])
11188 ;; Call to indirect functions with the AIX abi using a 3 word descriptor.
11189 ;; Operand0 is the addresss of the function to call
11190 ;; Operand2 is the location in the function descriptor to load r2 from
11191 ;; Operand3 is the offset of the stack location holding the current TOC pointer
11193 (define_insn "*call_indirect_aix<mode>"
11194 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11195 (match_operand 1 "" "g,g"))
11196 (use (match_operand:P 2 "memory_operand" "<ptrm>,<ptrm>"))
11197 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11198 (clobber (reg:P LR_REGNO))]
11199 "DEFAULT_ABI == ABI_AIX"
11200 "<ptrload> 2,%2\;b%T0l\;<ptrload> 2,%3(1)"
11201 [(set_attr "type" "jmpreg")
11202 (set_attr "length" "12")])
11204 (define_insn "*call_value_indirect_aix<mode>"
11205 [(set (match_operand 0 "" "")
11206 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11207 (match_operand 2 "" "g,g")))
11208 (use (match_operand:P 3 "memory_operand" "<ptrm>,<ptrm>"))
11209 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 4 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11210 (clobber (reg:P LR_REGNO))]
11211 "DEFAULT_ABI == ABI_AIX"
11212 "<ptrload> 2,%3\;b%T1l\;<ptrload> 2,%4(1)"
11213 [(set_attr "type" "jmpreg")
11214 (set_attr "length" "12")])
11216 ;; Call to indirect functions with the ELFv2 ABI.
11217 ;; Operand0 is the addresss of the function to call
11218 ;; Operand2 is the offset of the stack location holding the current TOC pointer
11220 (define_insn "*call_indirect_elfv2<mode>"
11221 [(call (mem:SI (match_operand:P 0 "register_operand" "c,*l"))
11222 (match_operand 1 "" "g,g"))
11223 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 2 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11224 (clobber (reg:P LR_REGNO))]
11225 "DEFAULT_ABI == ABI_ELFv2"
11226 "b%T0l\;<ptrload> 2,%2(1)"
11227 [(set_attr "type" "jmpreg")
11228 (set_attr "length" "8")])
11230 (define_insn "*call_value_indirect_elfv2<mode>"
11231 [(set (match_operand 0 "" "")
11232 (call (mem:SI (match_operand:P 1 "register_operand" "c,*l"))
11233 (match_operand 2 "" "g,g")))
11234 (set (reg:P TOC_REGNUM) (unspec:P [(match_operand:P 3 "const_int_operand" "n,n")] UNSPEC_TOCSLOT))
11235 (clobber (reg:P LR_REGNO))]
11236 "DEFAULT_ABI == ABI_ELFv2"
11237 "b%T1l\;<ptrload> 2,%3(1)"
11238 [(set_attr "type" "jmpreg")
11239 (set_attr "length" "8")])
11242 ;; Call subroutine returning any type.
11243 (define_expand "untyped_call"
11244 [(parallel [(call (match_operand 0 "" "")
11246 (match_operand 1 "" "")
11247 (match_operand 2 "" "")])]
11253 emit_call_insn (gen_call (operands[0], const0_rtx, const0_rtx));
11255 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11257 rtx set = XVECEXP (operands[2], 0, i);
11258 emit_move_insn (SET_DEST (set), SET_SRC (set));
11261 /* The optimizer does not know that the call sets the function value
11262 registers we stored in the result block. We avoid problems by
11263 claiming that all hard registers are used and clobbered at this
11265 emit_insn (gen_blockage ());
11270 ;; sibling call patterns
11271 (define_expand "sibcall"
11272 [(parallel [(call (mem:SI (match_operand 0 "address_operand" ""))
11273 (match_operand 1 "" ""))
11274 (use (match_operand 2 "" ""))
11280 if (MACHOPIC_INDIRECT)
11281 operands[0] = machopic_indirect_call_target (operands[0]);
11284 gcc_assert (GET_CODE (operands[0]) == MEM);
11285 gcc_assert (GET_CODE (operands[1]) == CONST_INT);
11287 operands[0] = XEXP (operands[0], 0);
11289 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11291 rs6000_sibcall_aix (NULL_RTX, operands[0], operands[1], operands[2]);
11296 (define_expand "sibcall_value"
11297 [(parallel [(set (match_operand 0 "register_operand" "")
11298 (call (mem:SI (match_operand 1 "address_operand" ""))
11299 (match_operand 2 "" "")))
11300 (use (match_operand 3 "" ""))
11306 if (MACHOPIC_INDIRECT)
11307 operands[1] = machopic_indirect_call_target (operands[1]);
11310 gcc_assert (GET_CODE (operands[1]) == MEM);
11311 gcc_assert (GET_CODE (operands[2]) == CONST_INT);
11313 operands[1] = XEXP (operands[1], 0);
11315 if (DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2)
11317 rs6000_sibcall_aix (operands[0], operands[1], operands[2], operands[3]);
11322 (define_insn "*sibcall_local32"
11323 [(call (mem:SI (match_operand:SI 0 "current_file_function_operand" "s,s"))
11324 (match_operand 1 "" "g,g"))
11325 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11327 "(INTVAL (operands[2]) & CALL_LONG) == 0"
11330 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11331 output_asm_insn (\"crxor 6,6,6\", operands);
11333 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11334 output_asm_insn (\"creqv 6,6,6\", operands);
11336 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11338 [(set_attr "type" "branch")
11339 (set_attr "length" "4,8")])
11341 (define_insn "*sibcall_local64"
11342 [(call (mem:SI (match_operand:DI 0 "current_file_function_operand" "s,s"))
11343 (match_operand 1 "" "g,g"))
11344 (use (match_operand:SI 2 "immediate_operand" "O,n"))
11346 "TARGET_64BIT && (INTVAL (operands[2]) & CALL_LONG) == 0"
11349 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11350 output_asm_insn (\"crxor 6,6,6\", operands);
11352 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11353 output_asm_insn (\"creqv 6,6,6\", operands);
11355 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z0@local\" : \"b %z0\";
11357 [(set_attr "type" "branch")
11358 (set_attr "length" "4,8")])
11360 (define_insn "*sibcall_value_local32"
11361 [(set (match_operand 0 "" "")
11362 (call (mem:SI (match_operand:SI 1 "current_file_function_operand" "s,s"))
11363 (match_operand 2 "" "g,g")))
11364 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11366 "(INTVAL (operands[3]) & CALL_LONG) == 0"
11369 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11370 output_asm_insn (\"crxor 6,6,6\", operands);
11372 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11373 output_asm_insn (\"creqv 6,6,6\", operands);
11375 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11377 [(set_attr "type" "branch")
11378 (set_attr "length" "4,8")])
11380 (define_insn "*sibcall_value_local64"
11381 [(set (match_operand 0 "" "")
11382 (call (mem:SI (match_operand:DI 1 "current_file_function_operand" "s,s"))
11383 (match_operand 2 "" "g,g")))
11384 (use (match_operand:SI 3 "immediate_operand" "O,n"))
11386 "TARGET_64BIT && (INTVAL (operands[3]) & CALL_LONG) == 0"
11389 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11390 output_asm_insn (\"crxor 6,6,6\", operands);
11392 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11393 output_asm_insn (\"creqv 6,6,6\", operands);
11395 return (DEFAULT_ABI == ABI_V4 && flag_pic) ? \"b %z1@local\" : \"b %z1\";
11397 [(set_attr "type" "branch")
11398 (set_attr "length" "4,8")])
11400 (define_insn "*sibcall_nonlocal_sysv<mode>"
11401 [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
11402 (match_operand 1 "" ""))
11403 (use (match_operand 2 "immediate_operand" "O,n,O,n"))
11405 "(DEFAULT_ABI == ABI_DARWIN
11406 || DEFAULT_ABI == ABI_V4)
11407 && (INTVAL (operands[2]) & CALL_LONG) == 0"
11410 if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
11411 output_asm_insn (\"crxor 6,6,6\", operands);
11413 else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
11414 output_asm_insn (\"creqv 6,6,6\", operands);
11416 if (which_alternative >= 2)
11418 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11420 gcc_assert (!TARGET_SECURE_PLT);
11421 return \"b %z0@plt\";
11426 [(set_attr "type" "branch")
11427 (set_attr "length" "4,8,4,8")])
11429 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
11430 [(set (match_operand 0 "" "")
11431 (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
11432 (match_operand 2 "" "")))
11433 (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
11435 "(DEFAULT_ABI == ABI_DARWIN
11436 || DEFAULT_ABI == ABI_V4)
11437 && (INTVAL (operands[3]) & CALL_LONG) == 0"
11440 if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
11441 output_asm_insn (\"crxor 6,6,6\", operands);
11443 else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
11444 output_asm_insn (\"creqv 6,6,6\", operands);
11446 if (which_alternative >= 2)
11448 else if (DEFAULT_ABI == ABI_V4 && flag_pic)
11450 gcc_assert (!TARGET_SECURE_PLT);
11451 return \"b %z1@plt\";
11456 [(set_attr "type" "branch")
11457 (set_attr "length" "4,8,4,8")])
11459 ;; AIX ABI sibling call patterns.
11461 (define_insn "*sibcall_aix<mode>"
11462 [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
11463 (match_operand 1 "" "g,g"))
11465 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11469 [(set_attr "type" "branch")
11470 (set_attr "length" "4")])
11472 (define_insn "*sibcall_value_aix<mode>"
11473 [(set (match_operand 0 "" "")
11474 (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
11475 (match_operand 2 "" "g,g")))
11477 "DEFAULT_ABI == ABI_AIX || DEFAULT_ABI == ABI_ELFv2"
11481 [(set_attr "type" "branch")
11482 (set_attr "length" "4")])
11484 (define_expand "sibcall_epilogue"
11485 [(use (const_int 0))]
11488 if (!TARGET_SCHED_PROLOG)
11489 emit_insn (gen_blockage ());
11490 rs6000_emit_epilogue (TRUE);
11494 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11495 ;; all of memory. This blocks insns from being moved across this point.
11497 (define_insn "blockage"
11498 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)]
11502 (define_expand "probe_stack_address"
11503 [(use (match_operand 0 "address_operand"))]
11506 operands[0] = gen_rtx_MEM (Pmode, operands[0]);
11507 MEM_VOLATILE_P (operands[0]) = 1;
11510 emit_insn (gen_probe_stack_di (operands[0]));
11512 emit_insn (gen_probe_stack_si (operands[0]));
11516 (define_insn "probe_stack_<mode>"
11517 [(set (match_operand:P 0 "memory_operand" "=m")
11518 (unspec:P [(const_int 0)] UNSPEC_PROBE_STACK))]
11521 operands[1] = gen_rtx_REG (Pmode, 0);
11522 return "st<wd>%U0%X0 %1,%0";
11524 [(set_attr "type" "store")
11525 (set (attr "update")
11526 (if_then_else (match_operand 0 "update_address_mem")
11527 (const_string "yes")
11528 (const_string "no")))
11529 (set (attr "indexed")
11530 (if_then_else (match_operand 0 "indexed_address_mem")
11531 (const_string "yes")
11532 (const_string "no")))
11533 (set_attr "length" "4")])
11535 (define_insn "probe_stack_range<P:mode>"
11536 [(set (match_operand:P 0 "register_operand" "=&r")
11537 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
11538 (match_operand:P 2 "register_operand" "r")
11539 (match_operand:P 3 "register_operand" "r")]
11540 UNSPECV_PROBE_STACK_RANGE))]
11542 "* return output_probe_stack_range (operands[0], operands[2], operands[3]);"
11543 [(set_attr "type" "three")])
11545 ;; Compare insns are next. Note that the RS/6000 has two types of compares,
11546 ;; signed & unsigned, and one type of branch.
11548 ;; Start with the DEFINE_EXPANDs to generate the rtl for compares, scc
11549 ;; insns, and branches.
11551 (define_expand "cbranch<mode>4"
11552 [(use (match_operator 0 "comparison_operator"
11553 [(match_operand:GPR 1 "gpc_reg_operand" "")
11554 (match_operand:GPR 2 "reg_or_short_operand" "")]))
11555 (use (match_operand 3 ""))]
11559 /* Take care of the possibility that operands[2] might be negative but
11560 this might be a logical operation. That insn doesn't exist. */
11561 if (GET_CODE (operands[2]) == CONST_INT
11562 && INTVAL (operands[2]) < 0)
11564 operands[2] = force_reg (<MODE>mode, operands[2]);
11565 operands[0] = gen_rtx_fmt_ee (GET_CODE (operands[0]),
11566 GET_MODE (operands[0]),
11567 operands[1], operands[2]);
11570 rs6000_emit_cbranch (<MODE>mode, operands);
11574 (define_expand "cbranch<mode>4"
11575 [(use (match_operator 0 "comparison_operator"
11576 [(match_operand:FP 1 "gpc_reg_operand" "")
11577 (match_operand:FP 2 "gpc_reg_operand" "")]))
11578 (use (match_operand 3 ""))]
11582 rs6000_emit_cbranch (<MODE>mode, operands);
11586 (define_expand "cstore<mode>4_signed"
11587 [(use (match_operator 1 "signed_comparison_operator"
11588 [(match_operand:P 2 "gpc_reg_operand")
11589 (match_operand:P 3 "gpc_reg_operand")]))
11590 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11593 enum rtx_code cond_code = GET_CODE (operands[1]);
11595 rtx op0 = operands[0];
11596 rtx op1 = operands[2];
11597 rtx op2 = operands[3];
11599 if (cond_code == GE || cond_code == LT)
11601 cond_code = swap_condition (cond_code);
11602 std::swap (op1, op2);
11605 rtx tmp1 = gen_reg_rtx (<MODE>mode);
11606 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11607 rtx tmp3 = gen_reg_rtx (<MODE>mode);
11609 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11610 emit_insn (gen_lshr<mode>3 (tmp1, op1, GEN_INT (sh)));
11611 emit_insn (gen_ashr<mode>3 (tmp2, op2, GEN_INT (sh)));
11613 emit_insn (gen_subf<mode>3_carry (tmp3, op1, op2));
11615 if (cond_code == LE)
11616 emit_insn (gen_add<mode>3_carry_in (op0, tmp1, tmp2));
11619 rtx tmp4 = gen_reg_rtx (<MODE>mode);
11620 emit_insn (gen_add<mode>3_carry_in (tmp4, tmp1, tmp2));
11621 emit_insn (gen_xor<mode>3 (op0, tmp4, const1_rtx));
11627 (define_expand "cstore<mode>4_unsigned"
11628 [(use (match_operator 1 "unsigned_comparison_operator"
11629 [(match_operand:P 2 "gpc_reg_operand")
11630 (match_operand:P 3 "reg_or_short_operand")]))
11631 (clobber (match_operand:P 0 "gpc_reg_operand"))]
11634 enum rtx_code cond_code = GET_CODE (operands[1]);
11636 rtx op0 = operands[0];
11637 rtx op1 = operands[2];
11638 rtx op2 = operands[3];
11640 if (cond_code == GEU || cond_code == LTU)
11642 cond_code = swap_condition (cond_code);
11643 std::swap (op1, op2);
11646 if (!gpc_reg_operand (op1, <MODE>mode))
11647 op1 = force_reg (<MODE>mode, op1);
11648 if (!reg_or_short_operand (op2, <MODE>mode))
11649 op2 = force_reg (<MODE>mode, op2);
11651 rtx tmp = gen_reg_rtx (<MODE>mode);
11652 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11654 emit_insn (gen_subf<mode>3_carry (tmp, op1, op2));
11655 emit_insn (gen_subf<mode>3_carry_in_xx (tmp2));
11657 if (cond_code == LEU)
11658 emit_insn (gen_add<mode>3 (op0, tmp2, const1_rtx));
11660 emit_insn (gen_neg<mode>2 (op0, tmp2));
11665 (define_expand "cstore_si_as_di"
11666 [(use (match_operator 1 "unsigned_comparison_operator"
11667 [(match_operand:SI 2 "gpc_reg_operand")
11668 (match_operand:SI 3 "reg_or_short_operand")]))
11669 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11672 int uns_flag = unsigned_comparison_operator (operands[1], VOIDmode) ? 1 : 0;
11673 enum rtx_code cond_code = signed_condition (GET_CODE (operands[1]));
11675 operands[2] = force_reg (SImode, operands[2]);
11676 operands[3] = force_reg (SImode, operands[3]);
11677 rtx op1 = gen_reg_rtx (DImode);
11678 rtx op2 = gen_reg_rtx (DImode);
11679 convert_move (op1, operands[2], uns_flag);
11680 convert_move (op2, operands[3], uns_flag);
11682 if (cond_code == GT || cond_code == LE)
11684 cond_code = swap_condition (cond_code);
11685 std::swap (op1, op2);
11688 rtx tmp = gen_reg_rtx (DImode);
11689 rtx tmp2 = gen_reg_rtx (DImode);
11690 emit_insn (gen_subdi3 (tmp, op1, op2));
11691 emit_insn (gen_lshrdi3 (tmp2, tmp, GEN_INT (63)));
11697 gcc_unreachable ();
11702 tmp3 = gen_reg_rtx (DImode);
11703 emit_insn (gen_xordi3 (tmp3, tmp2, const1_rtx));
11707 convert_move (operands[0], tmp3, 1);
11712 (define_expand "cstore<mode>4_signed_imm"
11713 [(use (match_operator 1 "signed_comparison_operator"
11714 [(match_operand:GPR 2 "gpc_reg_operand")
11715 (match_operand:GPR 3 "immediate_operand")]))
11716 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11719 bool invert = false;
11721 enum rtx_code cond_code = GET_CODE (operands[1]);
11723 rtx op0 = operands[0];
11724 rtx op1 = operands[2];
11725 HOST_WIDE_INT val = INTVAL (operands[3]);
11727 if (cond_code == GE || cond_code == GT)
11729 cond_code = reverse_condition (cond_code);
11733 if (cond_code == LE)
11736 rtx tmp = gen_reg_rtx (<MODE>mode);
11737 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11738 rtx x = gen_reg_rtx (<MODE>mode);
11740 emit_insn (gen_and<mode>3 (x, op1, tmp));
11742 emit_insn (gen_ior<mode>3 (x, op1, tmp));
11746 rtx tmp = gen_reg_rtx (<MODE>mode);
11747 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11751 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11752 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11757 (define_expand "cstore<mode>4_unsigned_imm"
11758 [(use (match_operator 1 "unsigned_comparison_operator"
11759 [(match_operand:GPR 2 "gpc_reg_operand")
11760 (match_operand:GPR 3 "immediate_operand")]))
11761 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11764 bool invert = false;
11766 enum rtx_code cond_code = GET_CODE (operands[1]);
11768 rtx op0 = operands[0];
11769 rtx op1 = operands[2];
11770 HOST_WIDE_INT val = INTVAL (operands[3]);
11772 if (cond_code == GEU || cond_code == GTU)
11774 cond_code = reverse_condition (cond_code);
11778 if (cond_code == LEU)
11781 rtx tmp = gen_reg_rtx (<MODE>mode);
11782 rtx tmp2 = gen_reg_rtx (<MODE>mode);
11783 emit_insn (gen_add<mode>3 (tmp, op1, GEN_INT (-val)));
11784 emit_insn (gen_one_cmpl<mode>2 (tmp2, op1));
11785 rtx x = gen_reg_rtx (<MODE>mode);
11787 emit_insn (gen_ior<mode>3 (x, tmp, tmp2));
11789 emit_insn (gen_and<mode>3 (x, tmp, tmp2));
11793 rtx tmp = gen_reg_rtx (<MODE>mode);
11794 emit_insn (gen_one_cmpl<mode>2 (tmp, x));
11798 int sh = GET_MODE_BITSIZE (<MODE>mode) - 1;
11799 emit_insn (gen_lshr<mode>3 (op0, x, GEN_INT (sh)));
11804 (define_expand "cstore<mode>4"
11805 [(use (match_operator 1 "comparison_operator"
11806 [(match_operand:GPR 2 "gpc_reg_operand")
11807 (match_operand:GPR 3 "reg_or_short_operand")]))
11808 (clobber (match_operand:GPR 0 "gpc_reg_operand"))]
11811 /* Expanding EQ and NE directly to some machine instructions does not help
11812 but does hurt combine. So don't. */
11813 if (GET_CODE (operands[1]) == EQ)
11814 emit_insn (gen_eq<mode>3 (operands[0], operands[2], operands[3]));
11815 else if (<MODE>mode == Pmode
11816 && GET_CODE (operands[1]) == NE)
11817 emit_insn (gen_ne<mode>3 (operands[0], operands[2], operands[3]));
11818 else if (GET_CODE (operands[1]) == NE)
11820 rtx tmp = gen_reg_rtx (<MODE>mode);
11821 emit_insn (gen_eq<mode>3 (tmp, operands[2], operands[3]));
11822 emit_insn (gen_xor<mode>3 (operands[0], tmp, const1_rtx));
11825 /* If ISEL is fast, expand to it. */
11826 else if (TARGET_ISEL)
11827 rs6000_emit_int_cmove (operands[0], operands[1], const1_rtx, const0_rtx);
11829 /* Expanding the unsigned comparisons helps a lot: all the neg_ltu
11830 etc. combinations magically work out just right. */
11831 else if (<MODE>mode == Pmode
11832 && unsigned_comparison_operator (operands[1], VOIDmode))
11833 emit_insn (gen_cstore<mode>4_unsigned (operands[0], operands[1],
11834 operands[2], operands[3]));
11836 /* For comparisons smaller than Pmode we can cheaply do things in Pmode. */
11837 else if (<MODE>mode == SImode && Pmode == DImode)
11838 emit_insn (gen_cstore_si_as_di (operands[0], operands[1],
11839 operands[2], operands[3]));
11841 /* For signed comparisons against a constant, we can do some simple
11843 else if (signed_comparison_operator (operands[1], VOIDmode)
11844 && CONST_INT_P (operands[3]))
11845 emit_insn (gen_cstore<mode>4_signed_imm (operands[0], operands[1],
11846 operands[2], operands[3]));
11848 /* And similarly for unsigned comparisons. */
11849 else if (unsigned_comparison_operator (operands[1], VOIDmode)
11850 && CONST_INT_P (operands[3]))
11851 emit_insn (gen_cstore<mode>4_unsigned_imm (operands[0], operands[1],
11852 operands[2], operands[3]));
11854 /* We also do not want to use mfcr for signed comparisons. */
11855 else if (<MODE>mode == Pmode
11856 && signed_comparison_operator (operands[1], VOIDmode))
11857 emit_insn (gen_cstore<mode>4_signed (operands[0], operands[1],
11858 operands[2], operands[3]));
11860 /* Everything else, use the mfcr brute force. */
11862 rs6000_emit_sCOND (<MODE>mode, operands);
11867 (define_expand "cstore<mode>4"
11868 [(use (match_operator 1 "comparison_operator"
11869 [(match_operand:FP 2 "gpc_reg_operand")
11870 (match_operand:FP 3 "gpc_reg_operand")]))
11871 (clobber (match_operand:SI 0 "gpc_reg_operand"))]
11874 rs6000_emit_sCOND (<MODE>mode, operands);
11879 (define_expand "stack_protect_set"
11880 [(match_operand 0 "memory_operand")
11881 (match_operand 1 "memory_operand")]
11884 if (rs6000_stack_protector_guard == SSP_TLS)
11886 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11887 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11888 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11889 operands[1] = gen_rtx_MEM (Pmode, addr);
11893 emit_insn (gen_stack_protect_setdi (operands[0], operands[1]));
11895 emit_insn (gen_stack_protect_setsi (operands[0], operands[1]));
11900 (define_insn "stack_protect_setsi"
11901 [(set (match_operand:SI 0 "memory_operand" "=m")
11902 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
11903 (set (match_scratch:SI 2 "=&r") (const_int 0))]
11905 "lwz%U1%X1 %2,%1\;stw%U0%X0 %2,%0\;li %2,0"
11906 [(set_attr "type" "three")
11907 (set_attr "length" "12")])
11909 (define_insn "stack_protect_setdi"
11910 [(set (match_operand:DI 0 "memory_operand" "=Y")
11911 (unspec:DI [(match_operand:DI 1 "memory_operand" "Y")] UNSPEC_SP_SET))
11912 (set (match_scratch:DI 2 "=&r") (const_int 0))]
11914 "ld%U1%X1 %2,%1\;std%U0%X0 %2,%0\;li %2,0"
11915 [(set_attr "type" "three")
11916 (set_attr "length" "12")])
11918 (define_expand "stack_protect_test"
11919 [(match_operand 0 "memory_operand")
11920 (match_operand 1 "memory_operand")
11921 (match_operand 2 "")]
11924 rtx guard = operands[1];
11926 if (rs6000_stack_protector_guard == SSP_TLS)
11928 rtx reg = gen_rtx_REG (Pmode, rs6000_stack_protector_guard_reg);
11929 rtx offset = GEN_INT (rs6000_stack_protector_guard_offset);
11930 rtx addr = gen_rtx_PLUS (Pmode, reg, offset);
11931 guard = gen_rtx_MEM (Pmode, addr);
11934 operands[1] = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, guard), UNSPEC_SP_TEST);
11935 rtx test = gen_rtx_EQ (VOIDmode, operands[0], operands[1]);
11936 rtx jump = gen_cbranchsi4 (test, operands[0], operands[1], operands[2]);
11937 emit_jump_insn (jump);
11942 (define_insn "stack_protect_testsi"
11943 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11944 (unspec:CCEQ [(match_operand:SI 1 "memory_operand" "m,m")
11945 (match_operand:SI 2 "memory_operand" "m,m")]
11947 (set (match_scratch:SI 4 "=r,r") (const_int 0))
11948 (clobber (match_scratch:SI 3 "=&r,&r"))]
11951 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11952 lwz%U1%X1 %3,%1\;lwz%U2%X2 %4,%2\;cmplw %0,%3,%4\;li %3,0\;li %4,0"
11953 [(set_attr "length" "16,20")])
11955 (define_insn "stack_protect_testdi"
11956 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=x,?y")
11957 (unspec:CCEQ [(match_operand:DI 1 "memory_operand" "Y,Y")
11958 (match_operand:DI 2 "memory_operand" "Y,Y")]
11960 (set (match_scratch:DI 4 "=r,r") (const_int 0))
11961 (clobber (match_scratch:DI 3 "=&r,&r"))]
11964 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;xor. %3,%3,%4\;li %4,0
11965 ld%U1%X1 %3,%1\;ld%U2%X2 %4,%2\;cmpld %0,%3,%4\;li %3,0\;li %4,0"
11966 [(set_attr "length" "16,20")])
11969 ;; Here are the actual compare insns.
11970 (define_insn "*cmp<mode>_signed"
11971 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
11972 (compare:CC (match_operand:GPR 1 "gpc_reg_operand" "r")
11973 (match_operand:GPR 2 "reg_or_short_operand" "rI")))]
11975 "cmp<wd>%I2 %0,%1,%2"
11976 [(set_attr "type" "cmp")])
11978 (define_insn "*cmp<mode>_unsigned"
11979 [(set (match_operand:CCUNS 0 "cc_reg_operand" "=y")
11980 (compare:CCUNS (match_operand:GPR 1 "gpc_reg_operand" "r")
11981 (match_operand:GPR 2 "reg_or_u_short_operand" "rK")))]
11983 "cmpl<wd>%I2 %0,%1,%2"
11984 [(set_attr "type" "cmp")])
11986 ;; If we are comparing a register for equality with a large constant,
11987 ;; we can do this with an XOR followed by a compare. But this is profitable
11988 ;; only if the large constant is only used for the comparison (and in this
11989 ;; case we already have a register to reuse as scratch).
11991 ;; For 64-bit registers, we could only do so if the constant's bit 15 is clear:
11992 ;; otherwise we'd need to XOR with FFFFFFFF????0000 which is not available.
11995 [(set (match_operand:SI 0 "register_operand")
11996 (match_operand:SI 1 "logical_const_operand" ""))
11997 (set (match_dup 0) (match_operator:SI 3 "boolean_or_operator"
11999 (match_operand:SI 2 "logical_const_operand" "")]))
12000 (set (match_operand:CC 4 "cc_reg_operand" "")
12001 (compare:CC (match_operand:SI 5 "gpc_reg_operand" "")
12004 (if_then_else (match_operator 6 "equality_operator"
12005 [(match_dup 4) (const_int 0)])
12006 (match_operand 7 "" "")
12007 (match_operand 8 "" "")))]
12008 "peep2_reg_dead_p (3, operands[0])
12009 && peep2_reg_dead_p (4, operands[4])
12010 && REGNO (operands[0]) != REGNO (operands[5])"
12011 [(set (match_dup 0) (xor:SI (match_dup 5) (match_dup 9)))
12012 (set (match_dup 4) (compare:CC (match_dup 0) (match_dup 10)))
12013 (set (pc) (if_then_else (match_dup 6) (match_dup 7) (match_dup 8)))]
12016 /* Get the constant we are comparing against, and see what it looks like
12017 when sign-extended from 16 to 32 bits. Then see what constant we could
12018 XOR with SEXTC to get the sign-extended value. */
12019 rtx cnst = simplify_const_binary_operation (GET_CODE (operands[3]),
12021 operands[1], operands[2]);
12022 HOST_WIDE_INT c = INTVAL (cnst);
12023 HOST_WIDE_INT sextc = ((c & 0xffff) ^ 0x8000) - 0x8000;
12024 HOST_WIDE_INT xorv = c ^ sextc;
12026 operands[9] = GEN_INT (xorv);
12027 operands[10] = GEN_INT (sextc);
12030 ;; The following two insns don't exist as single insns, but if we provide
12031 ;; them, we can swap an add and compare, which will enable us to overlap more
12032 ;; of the required delay between a compare and branch. We generate code for
12033 ;; them by splitting.
12036 [(set (match_operand:CC 3 "cc_reg_operand" "=y")
12037 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "r")
12038 (match_operand:SI 2 "short_cint_operand" "i")))
12039 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12040 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12043 [(set_attr "length" "8")])
12046 [(set (match_operand:CCUNS 3 "cc_reg_operand" "=y")
12047 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "r")
12048 (match_operand:SI 2 "u_short_cint_operand" "i")))
12049 (set (match_operand:SI 0 "gpc_reg_operand" "=r")
12050 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "i")))]
12053 [(set_attr "length" "8")])
12056 [(set (match_operand:CC 3 "cc_reg_operand" "")
12057 (compare:CC (match_operand:SI 1 "gpc_reg_operand" "")
12058 (match_operand:SI 2 "short_cint_operand" "")))
12059 (set (match_operand:SI 0 "gpc_reg_operand" "")
12060 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12062 [(set (match_dup 3) (compare:CC (match_dup 1) (match_dup 2)))
12063 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12066 [(set (match_operand:CCUNS 3 "cc_reg_operand" "")
12067 (compare:CCUNS (match_operand:SI 1 "gpc_reg_operand" "")
12068 (match_operand:SI 2 "u_short_cint_operand" "")))
12069 (set (match_operand:SI 0 "gpc_reg_operand" "")
12070 (plus:SI (match_dup 1) (match_operand:SI 4 "short_cint_operand" "")))]
12072 [(set (match_dup 3) (compare:CCUNS (match_dup 1) (match_dup 2)))
12073 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 4)))])
12075 ;; Only need to compare second words if first words equal
12076 (define_insn "*cmp<mode>_internal1"
12077 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12078 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12079 (match_operand:IBM128 2 "gpc_reg_operand" "d")))]
12080 "!TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12081 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12082 "fcmpu %0,%1,%2\;bne %0,$+8\;fcmpu %0,%L1,%L2"
12083 [(set_attr "type" "fpcompare")
12084 (set_attr "length" "12")])
12086 (define_insn_and_split "*cmp<mode>_internal2"
12087 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
12088 (compare:CCFP (match_operand:IBM128 1 "gpc_reg_operand" "d")
12089 (match_operand:IBM128 2 "gpc_reg_operand" "d")))
12090 (clobber (match_scratch:DF 3 "=d"))
12091 (clobber (match_scratch:DF 4 "=d"))
12092 (clobber (match_scratch:DF 5 "=d"))
12093 (clobber (match_scratch:DF 6 "=d"))
12094 (clobber (match_scratch:DF 7 "=d"))
12095 (clobber (match_scratch:DF 8 "=d"))
12096 (clobber (match_scratch:DF 9 "=d"))
12097 (clobber (match_scratch:DF 10 "=d"))
12098 (clobber (match_scratch:GPR 11 "=b"))]
12099 "TARGET_XL_COMPAT && FLOAT128_IBM_P (<MODE>mode)
12100 && TARGET_HARD_FLOAT && TARGET_DOUBLE_FLOAT && TARGET_LONG_DOUBLE_128"
12102 "&& reload_completed"
12103 [(set (match_dup 3) (match_dup 14))
12104 (set (match_dup 4) (match_dup 15))
12105 (set (match_dup 9) (abs:DF (match_dup 5)))
12106 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 3)))
12107 (set (pc) (if_then_else (ne (match_dup 0) (const_int 0))
12108 (label_ref (match_dup 12))
12110 (set (match_dup 0) (compare:CCFP (match_dup 5) (match_dup 7)))
12111 (set (pc) (label_ref (match_dup 13)))
12113 (set (match_dup 10) (minus:DF (match_dup 5) (match_dup 7)))
12114 (set (match_dup 9) (minus:DF (match_dup 6) (match_dup 8)))
12115 (set (match_dup 9) (plus:DF (match_dup 10) (match_dup 9)))
12116 (set (match_dup 0) (compare:CCFP (match_dup 9) (match_dup 4)))
12119 REAL_VALUE_TYPE rv;
12120 const int lo_word = LONG_DOUBLE_LARGE_FIRST ? GET_MODE_SIZE (DFmode) : 0;
12121 const int hi_word = LONG_DOUBLE_LARGE_FIRST ? 0 : GET_MODE_SIZE (DFmode);
12123 operands[5] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, hi_word);
12124 operands[6] = simplify_gen_subreg (DFmode, operands[1], <MODE>mode, lo_word);
12125 operands[7] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, hi_word);
12126 operands[8] = simplify_gen_subreg (DFmode, operands[2], <MODE>mode, lo_word);
12127 operands[12] = gen_label_rtx ();
12128 operands[13] = gen_label_rtx ();
12130 operands[14] = force_const_mem (DFmode,
12131 const_double_from_real_value (rv, DFmode));
12132 operands[15] = force_const_mem (DFmode,
12133 const_double_from_real_value (dconst0,
12138 tocref = create_TOC_reference (XEXP (operands[14], 0), operands[11]);
12139 operands[14] = gen_const_mem (DFmode, tocref);
12140 tocref = create_TOC_reference (XEXP (operands[15], 0), operands[11]);
12141 operands[15] = gen_const_mem (DFmode, tocref);
12142 set_mem_alias_set (operands[14], get_TOC_alias_set ());
12143 set_mem_alias_set (operands[15], get_TOC_alias_set ());
12147 ;; Now we have the scc insns. We can do some combinations because of the
12148 ;; way the machine works.
12150 ;; Note that this is probably faster if we can put an insn between the
12151 ;; mfcr and rlinm, but this is tricky. Let's leave it for now. In most
12152 ;; cases the insns below which don't use an intermediate CR field will
12153 ;; be used instead.
12155 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12156 (match_operator:SI 1 "scc_comparison_operator"
12157 [(match_operand 2 "cc_reg_operand" "y")
12160 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12161 [(set (attr "type")
12162 (cond [(match_test "TARGET_MFCRF")
12163 (const_string "mfcrf")
12165 (const_string "mfcr")))
12166 (set_attr "length" "8")])
12168 ;; Same as above, but get the OV/ORDERED bit.
12169 (define_insn "move_from_CR_ov_bit"
12170 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12171 (unspec:SI [(match_operand:CC 1 "cc_reg_operand" "y")]
12173 "TARGET_PAIRED_FLOAT"
12174 "mfcr %0\;rlwinm %0,%0,%t1,1"
12175 [(set_attr "type" "mfcr")
12176 (set_attr "length" "8")])
12179 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
12180 (match_operator:DI 1 "scc_comparison_operator"
12181 [(match_operand 2 "cc_reg_operand" "y")
12184 "mfcr %0%Q2\;rlwinm %0,%0,%J1,1"
12185 [(set (attr "type")
12186 (cond [(match_test "TARGET_MFCRF")
12187 (const_string "mfcrf")
12189 (const_string "mfcr")))
12190 (set_attr "length" "8")])
12193 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12194 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12195 [(match_operand 2 "cc_reg_operand" "y,y")
12198 (set (match_operand:SI 3 "gpc_reg_operand" "=r,r")
12199 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12202 mfcr %3%Q2\;rlwinm. %3,%3,%J1,1
12204 [(set_attr "type" "shift")
12205 (set_attr "dot" "yes")
12206 (set_attr "length" "8,16")])
12209 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand" "")
12210 (compare:CC (match_operator:SI 1 "scc_comparison_operator"
12211 [(match_operand 2 "cc_reg_operand" "")
12214 (set (match_operand:SI 3 "gpc_reg_operand" "")
12215 (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
12216 "TARGET_32BIT && reload_completed"
12217 [(set (match_dup 3)
12218 (match_op_dup 1 [(match_dup 2) (const_int 0)]))
12220 (compare:CC (match_dup 3)
12225 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
12226 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12227 [(match_operand 2 "cc_reg_operand" "y")
12229 (match_operand:SI 3 "const_int_operand" "n")))]
12233 int is_bit = ccr_bit (operands[1], 1);
12234 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12237 if (is_bit >= put_bit)
12238 count = is_bit - put_bit;
12240 count = 32 - (put_bit - is_bit);
12242 operands[4] = GEN_INT (count);
12243 operands[5] = GEN_INT (put_bit);
12245 return \"mfcr %0%Q2\;rlwinm %0,%0,%4,%5,%5\";
12247 [(set (attr "type")
12248 (cond [(match_test "TARGET_MFCRF")
12249 (const_string "mfcrf")
12251 (const_string "mfcr")))
12252 (set_attr "length" "8")])
12255 [(set (match_operand:CC 0 "cc_reg_operand" "=x,?y")
12257 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12258 [(match_operand 2 "cc_reg_operand" "y,y")
12260 (match_operand:SI 3 "const_int_operand" "n,n"))
12262 (set (match_operand:SI 4 "gpc_reg_operand" "=r,r")
12263 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12268 int is_bit = ccr_bit (operands[1], 1);
12269 int put_bit = 31 - (INTVAL (operands[3]) & 31);
12272 /* Force split for non-cc0 compare. */
12273 if (which_alternative == 1)
12276 if (is_bit >= put_bit)
12277 count = is_bit - put_bit;
12279 count = 32 - (put_bit - is_bit);
12281 operands[5] = GEN_INT (count);
12282 operands[6] = GEN_INT (put_bit);
12284 return \"mfcr %4%Q2\;rlwinm. %4,%4,%5,%6,%6\";
12286 [(set_attr "type" "shift")
12287 (set_attr "dot" "yes")
12288 (set_attr "length" "8,16")])
12291 [(set (match_operand:CC 0 "cc_reg_not_cr0_operand")
12293 (ashift:SI (match_operator:SI 1 "scc_comparison_operator"
12294 [(match_operand 2 "cc_reg_operand")
12296 (match_operand:SI 3 "const_int_operand"))
12298 (set (match_operand:SI 4 "gpc_reg_operand")
12299 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12302 [(set (match_dup 4)
12303 (ashift:SI (match_op_dup 1 [(match_dup 2) (const_int 0)])
12306 (compare:CC (match_dup 4)
12311 (define_code_iterator cmp [eq ne lt ltu gt gtu le leu ge geu])
12312 (define_code_attr UNS [(eq "CC")
12314 (lt "CC") (ltu "CCUNS")
12315 (gt "CC") (gtu "CCUNS")
12316 (le "CC") (leu "CCUNS")
12317 (ge "CC") (geu "CCUNS")])
12318 (define_code_attr UNSu_ [(eq "")
12323 (ge "") (geu "u_")])
12324 (define_code_attr UNSIK [(eq "I")
12329 (ge "I") (geu "K")])
12331 (define_insn_and_split "<code><GPR:mode><GPR2:mode>2_isel"
12332 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12333 (cmp:GPR (match_operand:GPR2 1 "gpc_reg_operand" "r")
12334 (match_operand:GPR2 2 "reg_or_<cmp:UNSu_>short_operand" "r<cmp:UNSIK>")))
12335 (clobber (match_scratch:GPR 3 "=r"))
12336 (clobber (match_scratch:GPR 4 "=r"))
12337 (clobber (match_scratch:<UNS> 5 "=y"))]
12339 && !(<CODE> == EQ && operands[2] == const0_rtx)
12340 && !(<CODE> == NE && operands[2] == const0_rtx
12341 && <GPR:MODE>mode == Pmode && <GPR2:MODE>mode == Pmode)"
12346 rtx_code code = <CODE>;
12347 if (CONST_INT_P (operands[2]) && code != EQ && code != NE)
12349 HOST_WIDE_INT val = INTVAL (operands[2]);
12350 if (code == LT && val != -0x8000)
12355 if (code == GT && val != 0x7fff)
12360 if (code == LTU && val != 0)
12365 if (code == GTU && val != 0xffff)
12370 operands[2] = GEN_INT (val);
12373 if (code == NE || code == LE || code == GE || code == LEU || code == GEU)
12374 operands[3] = const0_rtx;
12377 if (GET_CODE (operands[3]) == SCRATCH)
12378 operands[3] = gen_reg_rtx (<GPR:MODE>mode);
12379 emit_move_insn (operands[3], const0_rtx);
12382 if (GET_CODE (operands[4]) == SCRATCH)
12383 operands[4] = gen_reg_rtx (<GPR:MODE>mode);
12384 emit_move_insn (operands[4], const1_rtx);
12386 if (GET_CODE (operands[5]) == SCRATCH)
12387 operands[5] = gen_reg_rtx (<UNS>mode);
12389 rtx c1 = gen_rtx_COMPARE (<UNS>mode, operands[1], operands[2]);
12390 emit_insn (gen_rtx_SET (operands[5], c1));
12392 rtx c2 = gen_rtx_fmt_ee (code, <GPR:MODE>mode, operands[5], const0_rtx);
12393 rtx x = gen_rtx_IF_THEN_ELSE (<GPR:MODE>mode, c2, operands[4], operands[3]);
12394 emit_move_insn (operands[0], x);
12398 [(set (attr "cost")
12399 (if_then_else (match_test "(CONST_INT_P (operands[2]) && <CODE> != EQ)
12401 || <CODE> == LE || <CODE> == GE
12402 || <CODE> == LEU || <CODE> == GEU")
12404 (const_string "10")))])
12406 (define_mode_attr scc_eq_op2 [(SI "rKLI")
12409 (define_expand "eq<mode>3"
12411 (set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12412 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12413 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12414 (clobber (match_scratch:GPR 3 "=r"))
12415 (clobber (match_scratch:GPR 4 "=r"))])]
12418 if (TARGET_ISEL && operands[2] != const0_rtx)
12420 emit_insn (gen_eq<mode><mode>2_isel (operands[0], operands[1],
12426 (define_insn_and_split "*eq<mode>3"
12427 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
12428 (eq:GPR (match_operand:GPR 1 "gpc_reg_operand" "r")
12429 (match_operand:GPR 2 "scc_eq_operand" "<scc_eq_op2>")))
12430 (clobber (match_scratch:GPR 3 "=r"))
12431 (clobber (match_scratch:GPR 4 "=r"))]
12432 "!(TARGET_ISEL && operands[2] != const0_rtx)"
12435 [(set (match_dup 4)
12436 (clz:GPR (match_dup 3)))
12438 (lshiftrt:GPR (match_dup 4)
12441 operands[3] = rs6000_emit_eqne (<MODE>mode,
12442 operands[1], operands[2], operands[3]);
12444 if (GET_CODE (operands[4]) == SCRATCH)
12445 operands[4] = gen_reg_rtx (<MODE>mode);
12447 operands[5] = GEN_INT (exact_log2 (GET_MODE_BITSIZE (<MODE>mode)));
12449 [(set (attr "length")
12450 (if_then_else (match_test "operands[2] == const0_rtx")
12452 (const_string "12")))])
12454 (define_expand "ne<mode>3"
12456 (set (match_operand:P 0 "gpc_reg_operand" "=r")
12457 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12458 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12459 (clobber (match_scratch:P 3 "=r"))
12460 (clobber (match_scratch:P 4 "=r"))
12461 (clobber (reg:P CA_REGNO))])]
12464 if (TARGET_ISEL && operands[2] != const0_rtx)
12466 emit_insn (gen_ne<mode><mode>2_isel (operands[0], operands[1],
12472 (define_insn_and_split "*ne<mode>3"
12473 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12474 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12475 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>")))
12476 (clobber (match_scratch:P 3 "=r"))
12477 (clobber (match_scratch:P 4 "=r"))
12478 (clobber (reg:P CA_REGNO))]
12479 "!(TARGET_ISEL && operands[2] != const0_rtx)"
12482 [(parallel [(set (match_dup 4)
12483 (plus:P (match_dup 3)
12485 (set (reg:P CA_REGNO)
12486 (ne:P (match_dup 3)
12488 (parallel [(set (match_dup 0)
12489 (plus:P (plus:P (not:P (match_dup 4))
12492 (clobber (reg:P CA_REGNO))])]
12494 operands[3] = rs6000_emit_eqne (<MODE>mode,
12495 operands[1], operands[2], operands[3]);
12497 if (GET_CODE (operands[4]) == SCRATCH)
12498 operands[4] = gen_reg_rtx (<MODE>mode);
12500 [(set (attr "length")
12501 (if_then_else (match_test "operands[2] == const0_rtx")
12503 (const_string "12")))])
12505 (define_insn_and_split "*neg_eq_<mode>"
12506 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12507 (neg:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12508 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12509 (clobber (match_scratch:P 3 "=r"))
12510 (clobber (match_scratch:P 4 "=r"))
12511 (clobber (reg:P CA_REGNO))]
12515 [(parallel [(set (match_dup 4)
12516 (plus:P (match_dup 3)
12518 (set (reg:P CA_REGNO)
12519 (ne:P (match_dup 3)
12521 (parallel [(set (match_dup 0)
12522 (plus:P (reg:P CA_REGNO)
12524 (clobber (reg:P CA_REGNO))])]
12526 operands[3] = rs6000_emit_eqne (<MODE>mode,
12527 operands[1], operands[2], operands[3]);
12529 if (GET_CODE (operands[4]) == SCRATCH)
12530 operands[4] = gen_reg_rtx (<MODE>mode);
12532 [(set (attr "length")
12533 (if_then_else (match_test "operands[2] == const0_rtx")
12535 (const_string "12")))])
12537 (define_insn_and_split "*neg_ne_<mode>"
12538 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12539 (neg:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12540 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12541 (clobber (match_scratch:P 3 "=r"))
12542 (clobber (match_scratch:P 4 "=r"))
12543 (clobber (reg:P CA_REGNO))]
12547 [(parallel [(set (match_dup 4)
12548 (neg:P (match_dup 3)))
12549 (set (reg:P CA_REGNO)
12550 (eq:P (match_dup 3)
12552 (parallel [(set (match_dup 0)
12553 (plus:P (reg:P CA_REGNO)
12555 (clobber (reg:P CA_REGNO))])]
12557 operands[3] = rs6000_emit_eqne (<MODE>mode,
12558 operands[1], operands[2], operands[3]);
12560 if (GET_CODE (operands[4]) == SCRATCH)
12561 operands[4] = gen_reg_rtx (<MODE>mode);
12563 [(set (attr "length")
12564 (if_then_else (match_test "operands[2] == const0_rtx")
12566 (const_string "12")))])
12568 (define_insn_and_split "*plus_eq_<mode>"
12569 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12570 (plus:P (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12571 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12572 (match_operand:P 3 "gpc_reg_operand" "r")))
12573 (clobber (match_scratch:P 4 "=r"))
12574 (clobber (match_scratch:P 5 "=r"))
12575 (clobber (reg:P CA_REGNO))]
12579 [(parallel [(set (match_dup 5)
12580 (neg:P (match_dup 4)))
12581 (set (reg:P CA_REGNO)
12582 (eq:P (match_dup 4)
12584 (parallel [(set (match_dup 0)
12585 (plus:P (match_dup 3)
12587 (clobber (reg:P CA_REGNO))])]
12589 operands[4] = rs6000_emit_eqne (<MODE>mode,
12590 operands[1], operands[2], operands[4]);
12592 if (GET_CODE (operands[5]) == SCRATCH)
12593 operands[5] = gen_reg_rtx (<MODE>mode);
12595 [(set (attr "length")
12596 (if_then_else (match_test "operands[2] == const0_rtx")
12598 (const_string "12")))])
12600 (define_insn_and_split "*plus_ne_<mode>"
12601 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12602 (plus:P (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12603 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))
12604 (match_operand:P 3 "gpc_reg_operand" "r")))
12605 (clobber (match_scratch:P 4 "=r"))
12606 (clobber (match_scratch:P 5 "=r"))
12607 (clobber (reg:P CA_REGNO))]
12611 [(parallel [(set (match_dup 5)
12612 (plus:P (match_dup 4)
12614 (set (reg:P CA_REGNO)
12615 (ne:P (match_dup 4)
12617 (parallel [(set (match_dup 0)
12618 (plus:P (match_dup 3)
12620 (clobber (reg:P CA_REGNO))])]
12622 operands[4] = rs6000_emit_eqne (<MODE>mode,
12623 operands[1], operands[2], operands[4]);
12625 if (GET_CODE (operands[5]) == SCRATCH)
12626 operands[5] = gen_reg_rtx (<MODE>mode);
12628 [(set (attr "length")
12629 (if_then_else (match_test "operands[2] == const0_rtx")
12631 (const_string "12")))])
12633 (define_insn_and_split "*minus_eq_<mode>"
12634 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12635 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12636 (eq:P (match_operand:P 1 "gpc_reg_operand" "r")
12637 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12638 (clobber (match_scratch:P 4 "=r"))
12639 (clobber (match_scratch:P 5 "=r"))
12640 (clobber (reg:P CA_REGNO))]
12644 [(parallel [(set (match_dup 5)
12645 (plus:P (match_dup 4)
12647 (set (reg:P CA_REGNO)
12648 (ne:P (match_dup 4)
12650 (parallel [(set (match_dup 0)
12651 (plus:P (plus:P (match_dup 3)
12654 (clobber (reg:P CA_REGNO))])]
12656 operands[4] = rs6000_emit_eqne (<MODE>mode,
12657 operands[1], operands[2], operands[4]);
12659 if (GET_CODE (operands[5]) == SCRATCH)
12660 operands[5] = gen_reg_rtx (<MODE>mode);
12662 [(set (attr "length")
12663 (if_then_else (match_test "operands[2] == const0_rtx")
12665 (const_string "12")))])
12667 (define_insn_and_split "*minus_ne_<mode>"
12668 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
12669 (minus:P (match_operand:P 3 "gpc_reg_operand" "r")
12670 (ne:P (match_operand:P 1 "gpc_reg_operand" "r")
12671 (match_operand:P 2 "scc_eq_operand" "<scc_eq_op2>"))))
12672 (clobber (match_scratch:P 4 "=r"))
12673 (clobber (match_scratch:P 5 "=r"))
12674 (clobber (reg:P CA_REGNO))]
12678 [(parallel [(set (match_dup 5)
12679 (neg:P (match_dup 4)))
12680 (set (reg:P CA_REGNO)
12681 (eq:P (match_dup 4)
12683 (parallel [(set (match_dup 0)
12684 (plus:P (plus:P (match_dup 3)
12687 (clobber (reg:P CA_REGNO))])]
12689 operands[4] = rs6000_emit_eqne (<MODE>mode,
12690 operands[1], operands[2], operands[4]);
12692 if (GET_CODE (operands[5]) == SCRATCH)
12693 operands[5] = gen_reg_rtx (<MODE>mode);
12695 [(set (attr "length")
12696 (if_then_else (match_test "operands[2] == const0_rtx")
12698 (const_string "12")))])
12700 (define_insn_and_split "*eqsi3_ext<mode>"
12701 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12702 (eq:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12703 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12704 (clobber (match_scratch:SI 3 "=r"))
12705 (clobber (match_scratch:SI 4 "=r"))]
12709 [(set (match_dup 4)
12710 (clz:SI (match_dup 3)))
12713 (lshiftrt:SI (match_dup 4)
12716 operands[3] = rs6000_emit_eqne (SImode,
12717 operands[1], operands[2], operands[3]);
12719 if (GET_CODE (operands[4]) == SCRATCH)
12720 operands[4] = gen_reg_rtx (SImode);
12722 [(set (attr "length")
12723 (if_then_else (match_test "operands[2] == const0_rtx")
12725 (const_string "12")))])
12727 (define_insn_and_split "*nesi3_ext<mode>"
12728 [(set (match_operand:EXTSI 0 "gpc_reg_operand" "=r")
12729 (ne:EXTSI (match_operand:SI 1 "gpc_reg_operand" "r")
12730 (match_operand:SI 2 "scc_eq_operand" "rKLI")))
12731 (clobber (match_scratch:SI 3 "=r"))
12732 (clobber (match_scratch:SI 4 "=r"))
12733 (clobber (match_scratch:EXTSI 5 "=r"))]
12737 [(set (match_dup 4)
12738 (clz:SI (match_dup 3)))
12741 (lshiftrt:SI (match_dup 4)
12744 (xor:EXTSI (match_dup 5)
12747 operands[3] = rs6000_emit_eqne (SImode,
12748 operands[1], operands[2], operands[3]);
12750 if (GET_CODE (operands[4]) == SCRATCH)
12751 operands[4] = gen_reg_rtx (SImode);
12752 if (GET_CODE (operands[5]) == SCRATCH)
12753 operands[5] = gen_reg_rtx (<MODE>mode);
12755 [(set (attr "length")
12756 (if_then_else (match_test "operands[2] == const0_rtx")
12757 (const_string "12")
12758 (const_string "16")))])
12760 ;; Define both directions of branch and return. If we need a reload
12761 ;; register, we'd rather use CR0 since it is much easier to copy a
12762 ;; register CC value to there.
12766 (if_then_else (match_operator 1 "branch_comparison_operator"
12767 [(match_operand 2 "cc_reg_operand" "y")
12769 (label_ref (match_operand 0))
12773 return output_cbranch (operands[1], "%l0", 0, insn);
12775 [(set_attr "type" "branch")])
12779 (if_then_else (match_operator 0 "branch_comparison_operator"
12780 [(match_operand 1 "cc_reg_operand" "y")
12786 return output_cbranch (operands[0], NULL, 0, insn);
12788 [(set_attr "type" "jmpreg")
12789 (set_attr "length" "4")])
12791 ;; Logic on condition register values.
12793 ; This pattern matches things like
12794 ; (set (reg:CCEQ 68) (compare:CCEQ (ior:SI (gt:SI (reg:CCFP 68) (const_int 0))
12795 ; (eq:SI (reg:CCFP 68) (const_int 0)))
12797 ; which are generated by the branch logic.
12798 ; Prefer destructive operations where BT = BB (for crXX BT,BA,BB)
12800 (define_insn "*cceq_ior_compare"
12801 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12802 (compare:CCEQ (match_operator:SI 1 "boolean_operator"
12803 [(match_operator:SI 2
12804 "branch_positive_comparison_operator"
12806 "cc_reg_operand" "y,y")
12808 (match_operator:SI 4
12809 "branch_positive_comparison_operator"
12811 "cc_reg_operand" "0,y")
12815 "cr%q1 %E0,%j2,%j4"
12816 [(set_attr "type" "cr_logical,delayed_cr")])
12818 ; Why is the constant -1 here, but 1 in the previous pattern?
12819 ; Because ~1 has all but the low bit set.
12821 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12822 (compare:CCEQ (match_operator:SI 1 "boolean_or_operator"
12823 [(not:SI (match_operator:SI 2
12824 "branch_positive_comparison_operator"
12826 "cc_reg_operand" "y,y")
12828 (match_operator:SI 4
12829 "branch_positive_comparison_operator"
12831 "cc_reg_operand" "0,y")
12835 "cr%q1 %E0,%j2,%j4"
12836 [(set_attr "type" "cr_logical,delayed_cr")])
12838 (define_insn "*cceq_rev_compare"
12839 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y,?y")
12840 (compare:CCEQ (match_operator:SI 1
12841 "branch_positive_comparison_operator"
12843 "cc_reg_operand" "0,y")
12848 [(set_attr "type" "cr_logical,delayed_cr")])
12850 ;; If we are comparing the result of two comparisons, this can be done
12851 ;; using creqv or crxor.
12853 (define_insn_and_split ""
12854 [(set (match_operand:CCEQ 0 "cc_reg_operand" "=y")
12855 (compare:CCEQ (match_operator 1 "branch_comparison_operator"
12856 [(match_operand 2 "cc_reg_operand" "y")
12858 (match_operator 3 "branch_comparison_operator"
12859 [(match_operand 4 "cc_reg_operand" "y")
12864 [(set (match_dup 0) (compare:CCEQ (xor:SI (match_dup 1) (match_dup 3))
12868 int positive_1, positive_2;
12870 positive_1 = branch_positive_comparison_operator (operands[1],
12871 GET_MODE (operands[1]));
12872 positive_2 = branch_positive_comparison_operator (operands[3],
12873 GET_MODE (operands[3]));
12876 operands[1] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[2]),
12877 GET_CODE (operands[1])),
12879 operands[2], const0_rtx);
12880 else if (GET_MODE (operands[1]) != SImode)
12881 operands[1] = gen_rtx_fmt_ee (GET_CODE (operands[1]), SImode,
12882 operands[2], const0_rtx);
12885 operands[3] = gen_rtx_fmt_ee (rs6000_reverse_condition (GET_MODE (operands[4]),
12886 GET_CODE (operands[3])),
12888 operands[4], const0_rtx);
12889 else if (GET_MODE (operands[3]) != SImode)
12890 operands[3] = gen_rtx_fmt_ee (GET_CODE (operands[3]), SImode,
12891 operands[4], const0_rtx);
12893 if (positive_1 == positive_2)
12895 operands[1] = gen_rtx_NOT (SImode, operands[1]);
12896 operands[5] = constm1_rtx;
12900 operands[5] = const1_rtx;
12904 ;; Unconditional branch and return.
12906 (define_insn "jump"
12908 (label_ref (match_operand 0)))]
12911 [(set_attr "type" "branch")])
12913 (define_insn "<return_str>return"
12917 [(set_attr "type" "jmpreg")])
12919 (define_expand "indirect_jump"
12920 [(set (pc) (match_operand 0 "register_operand"))])
12922 (define_insn "*indirect_jump<mode>"
12924 (match_operand:P 0 "register_operand" "c,*l"))]
12927 [(set_attr "type" "jmpreg")])
12929 ;; Table jump for switch statements:
12930 (define_expand "tablejump"
12931 [(use (match_operand 0))
12932 (use (label_ref (match_operand 1)))]
12936 emit_jump_insn (gen_tablejumpsi (operands[0], operands[1]));
12938 emit_jump_insn (gen_tablejumpdi (operands[0], operands[1]));
12942 (define_expand "tablejumpsi"
12943 [(set (match_dup 3)
12944 (plus:SI (match_operand:SI 0)
12946 (parallel [(set (pc)
12948 (use (label_ref (match_operand 1)))])]
12951 operands[0] = force_reg (SImode, operands[0]);
12952 operands[2] = force_reg (SImode, gen_rtx_LABEL_REF (SImode, operands[1]));
12953 operands[3] = gen_reg_rtx (SImode);
12956 (define_expand "tablejumpdi"
12957 [(set (match_dup 4)
12958 (sign_extend:DI (match_operand:SI 0 "lwa_operand")))
12960 (plus:DI (match_dup 4)
12962 (parallel [(set (pc)
12964 (use (label_ref (match_operand 1)))])]
12967 operands[2] = force_reg (DImode, gen_rtx_LABEL_REF (DImode, operands[1]));
12968 operands[3] = gen_reg_rtx (DImode);
12969 operands[4] = gen_reg_rtx (DImode);
12972 (define_insn "*tablejump<mode>_internal1"
12974 (match_operand:P 0 "register_operand" "c,*l"))
12975 (use (label_ref (match_operand 1)))]
12978 [(set_attr "type" "jmpreg")])
12981 [(unspec [(const_int 0)] UNSPEC_NOP)]
12985 (define_insn "group_ending_nop"
12986 [(unspec [(const_int 0)] UNSPEC_GRP_END_NOP)]
12989 if (rs6000_tune == PROCESSOR_POWER6)
12990 return "ori 1,1,0";
12991 return "ori 2,2,0";
12994 ;; Define the subtract-one-and-jump insns, starting with the template
12995 ;; so loop.c knows what to generate.
12997 (define_expand "doloop_end"
12998 [(use (match_operand 0)) ; loop pseudo
12999 (use (match_operand 1))] ; label
13004 if (GET_MODE (operands[0]) != DImode)
13006 emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
13010 if (GET_MODE (operands[0]) != SImode)
13012 emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
13017 (define_expand "ctr<mode>"
13018 [(parallel [(set (pc)
13019 (if_then_else (ne (match_operand:P 0 "register_operand")
13021 (label_ref (match_operand 1))
13024 (plus:P (match_dup 0)
13026 (clobber (match_scratch:CC 2))
13027 (clobber (match_scratch:P 3))])]
13031 ;; We need to be able to do this for any operand, including MEM, or we
13032 ;; will cause reload to blow up since we don't allow output reloads on
13034 ;; For the length attribute to be calculated correctly, the
13035 ;; label MUST be operand 0.
13036 ;; rs6000_legitimate_combined_insn prevents combine creating any of
13037 ;; the ctr<mode> insns.
13039 (define_insn "ctr<mode>_internal1"
13041 (if_then_else (ne (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13043 (label_ref (match_operand 0))
13045 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13046 (plus:P (match_dup 1)
13048 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13049 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13052 if (which_alternative != 0)
13054 else if (get_attr_length (insn) == 4)
13057 return "bdz $+8\;b %l0";
13059 [(set_attr "type" "branch")
13060 (set_attr "length" "*,16,20,20")])
13062 ;; Similar but use EQ
13064 (define_insn "ctr<mode>_internal2"
13066 (if_then_else (eq (match_operand:P 1 "register_operand" "c,*b,*b,*b")
13068 (label_ref (match_operand 0))
13070 (set (match_operand:P 2 "nonimmediate_operand" "=1,*r,m,*d*wi*c*l")
13071 (plus:P (match_dup 1)
13073 (clobber (match_scratch:CC 3 "=X,&x,&x,&x"))
13074 (clobber (match_scratch:P 4 "=X,X,&r,r"))]
13077 if (which_alternative != 0)
13079 else if (get_attr_length (insn) == 4)
13082 return "bdnz $+8\;b %l0";
13084 [(set_attr "type" "branch")
13085 (set_attr "length" "*,16,20,20")])
13087 ;; Now the splitters if we could not allocate the CTR register
13091 (if_then_else (match_operator 2 "comparison_operator"
13092 [(match_operand:P 1 "gpc_reg_operand")
13095 (match_operand 6)))
13096 (set (match_operand:P 0 "int_reg_operand")
13097 (plus:P (match_dup 1)
13099 (clobber (match_scratch:CC 3))
13100 (clobber (match_scratch:P 4))]
13102 [(set (match_dup 3)
13103 (compare:CC (match_dup 1)
13106 (plus:P (match_dup 1)
13109 (if_then_else (match_dup 7)
13113 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
13119 (if_then_else (match_operator 2 "comparison_operator"
13120 [(match_operand:P 1 "gpc_reg_operand")
13123 (match_operand 6)))
13124 (set (match_operand:P 0 "nonimmediate_operand")
13125 (plus:P (match_dup 1)
13127 (clobber (match_scratch:CC 3))
13128 (clobber (match_scratch:P 4))]
13129 "reload_completed && !gpc_reg_operand (operands[0], SImode)"
13130 [(set (match_dup 3)
13131 (compare:CC (match_dup 1)
13134 (plus:P (match_dup 1)
13139 (if_then_else (match_dup 7)
13143 operands[7] = gen_rtx_fmt_ee (GET_CODE (operands[2]), VOIDmode, operands[3],
13147 (define_insn "trap"
13148 [(trap_if (const_int 1) (const_int 0))]
13151 [(set_attr "type" "trap")])
13153 (define_expand "ctrap<mode>4"
13154 [(trap_if (match_operator 0 "ordered_comparison_operator"
13155 [(match_operand:GPR 1 "register_operand")
13156 (match_operand:GPR 2 "reg_or_short_operand")])
13157 (match_operand 3 "zero_constant" ""))]
13162 [(trap_if (match_operator 0 "ordered_comparison_operator"
13163 [(match_operand:GPR 1 "register_operand" "r")
13164 (match_operand:GPR 2 "reg_or_short_operand" "rI")])
13167 "t<wd>%V0%I2 %1,%2"
13168 [(set_attr "type" "trap")])
13170 ;; Insns related to generating the function prologue and epilogue.
13172 (define_expand "prologue"
13173 [(use (const_int 0))]
13176 rs6000_emit_prologue ();
13177 if (!TARGET_SCHED_PROLOG)
13178 emit_insn (gen_blockage ());
13182 (define_insn "*movesi_from_cr_one"
13183 [(match_parallel 0 "mfcr_operation"
13184 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13185 (unspec:SI [(match_operand:CC 2 "cc_reg_operand" "y")
13186 (match_operand 3 "immediate_operand" "n")]
13187 UNSPEC_MOVESI_FROM_CR))])]
13193 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13195 mask = INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13196 operands[4] = GEN_INT (mask);
13197 output_asm_insn (\"mfcr %1,%4\", operands);
13201 [(set_attr "type" "mfcrf")])
13203 ;; Don't include the volatile CRs since their values are not used wrt CR save
13204 ;; in the prologue and doing so prevents shrink-wrapping because we can't move the
13205 ;; prologue past an insn (early exit test) that defines a register used in the
13207 (define_insn "prologue_movesi_from_cr"
13208 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13209 (unspec:SI [(reg:CC CR2_REGNO) (reg:CC CR3_REGNO)
13210 (reg:CC CR4_REGNO)]
13211 UNSPEC_MOVESI_FROM_CR))]
13214 [(set_attr "type" "mfcr")])
13216 (define_insn "*crsave"
13217 [(match_parallel 0 "crsave_operation"
13218 [(set (match_operand:SI 1 "memory_operand" "=m")
13219 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13222 [(set_attr "type" "store")])
13224 (define_insn "*stmw"
13225 [(match_parallel 0 "stmw_operation"
13226 [(set (match_operand:SI 1 "memory_operand" "=m")
13227 (match_operand:SI 2 "gpc_reg_operand" "r"))])]
13230 [(set_attr "type" "store")
13231 (set_attr "update" "yes")
13232 (set_attr "indexed" "yes")])
13234 ; The following comment applies to:
13238 ; return_and_restore_gpregs*
13239 ; return_and_restore_fpregs*
13240 ; return_and_restore_fpregs_aix*
13242 ; The out-of-line save / restore functions expects one input argument.
13243 ; Since those are not standard call_insn's, we must avoid using
13244 ; MATCH_OPERAND for that argument. That way the register rename
13245 ; optimization will not try to rename this register.
13246 ; Each pattern is repeated for each possible register number used in
13247 ; various ABIs (r11, r1, and for some functions r12)
13249 (define_insn "*save_gpregs_<mode>_r11"
13250 [(match_parallel 0 "any_parallel_operand"
13251 [(clobber (reg:P LR_REGNO))
13252 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13254 (set (match_operand:P 2 "memory_operand" "=m")
13255 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13258 [(set_attr "type" "branch")
13259 (set_attr "length" "4")])
13261 (define_insn "*save_gpregs_<mode>_r12"
13262 [(match_parallel 0 "any_parallel_operand"
13263 [(clobber (reg:P LR_REGNO))
13264 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13266 (set (match_operand:P 2 "memory_operand" "=m")
13267 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13270 [(set_attr "type" "branch")
13271 (set_attr "length" "4")])
13273 (define_insn "*save_gpregs_<mode>_r1"
13274 [(match_parallel 0 "any_parallel_operand"
13275 [(clobber (reg:P LR_REGNO))
13276 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13278 (set (match_operand:P 2 "memory_operand" "=m")
13279 (match_operand:P 3 "gpc_reg_operand" "r"))])]
13282 [(set_attr "type" "branch")
13283 (set_attr "length" "4")])
13285 (define_insn "*save_fpregs_<mode>_r11"
13286 [(match_parallel 0 "any_parallel_operand"
13287 [(clobber (reg:P LR_REGNO))
13288 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13290 (set (match_operand:DF 2 "memory_operand" "=m")
13291 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13294 [(set_attr "type" "branch")
13295 (set_attr "length" "4")])
13297 (define_insn "*save_fpregs_<mode>_r12"
13298 [(match_parallel 0 "any_parallel_operand"
13299 [(clobber (reg:P LR_REGNO))
13300 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13302 (set (match_operand:DF 2 "memory_operand" "=m")
13303 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13306 [(set_attr "type" "branch")
13307 (set_attr "length" "4")])
13309 (define_insn "*save_fpregs_<mode>_r1"
13310 [(match_parallel 0 "any_parallel_operand"
13311 [(clobber (reg:P LR_REGNO))
13312 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13314 (set (match_operand:DF 2 "memory_operand" "=m")
13315 (match_operand:DF 3 "gpc_reg_operand" "d"))])]
13318 [(set_attr "type" "branch")
13319 (set_attr "length" "4")])
13321 ; This is to explain that changes to the stack pointer should
13322 ; not be moved over loads from or stores to stack memory.
13323 (define_insn "stack_tie"
13324 [(match_parallel 0 "tie_operand"
13325 [(set (mem:BLK (reg 1)) (const_int 0))])]
13328 [(set_attr "length" "0")])
13330 ; Some 32-bit ABIs do not have a red zone, so the stack deallocation has to
13331 ; stay behind all restores from the stack, it cannot be reordered to before
13332 ; one. See PR77687. This insn is an add or mr, and a memory clobber.
13333 (define_insn "stack_restore_tie"
13334 [(set (match_operand:SI 0 "gpc_reg_operand" "=r,r")
13335 (plus:SI (match_operand:SI 1 "gpc_reg_operand" "r,r")
13336 (match_operand:SI 2 "reg_or_cint_operand" "O,rI")))
13337 (set (mem:BLK (scratch)) (const_int 0))]
13342 [(set_attr "type" "*,add")])
13344 (define_expand "epilogue"
13345 [(use (const_int 0))]
13348 if (!TARGET_SCHED_PROLOG)
13349 emit_insn (gen_blockage ());
13350 rs6000_emit_epilogue (FALSE);
13354 ; On some processors, doing the mtcrf one CC register at a time is
13355 ; faster (like on the 604e). On others, doing them all at once is
13356 ; faster; for instance, on the 601 and 750.
13358 (define_expand "movsi_to_cr_one"
13359 [(set (match_operand:CC 0 "cc_reg_operand" "")
13360 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "")
13361 (match_dup 2)] UNSPEC_MOVESI_TO_CR))]
13363 "operands[2] = GEN_INT (1 << (75 - REGNO (operands[0])));")
13365 (define_insn "*movsi_to_cr"
13366 [(match_parallel 0 "mtcrf_operation"
13367 [(set (match_operand:CC 1 "cc_reg_operand" "=y")
13368 (unspec:CC [(match_operand:SI 2 "gpc_reg_operand" "r")
13369 (match_operand 3 "immediate_operand" "n")]
13370 UNSPEC_MOVESI_TO_CR))])]
13376 for (i = 0; i < XVECLEN (operands[0], 0); i++)
13377 mask |= INTVAL (XVECEXP (SET_SRC (XVECEXP (operands[0], 0, i)), 0, 1));
13378 operands[4] = GEN_INT (mask);
13379 return \"mtcrf %4,%2\";
13381 [(set_attr "type" "mtcr")])
13383 (define_insn "*mtcrfsi"
13384 [(set (match_operand:CC 0 "cc_reg_operand" "=y")
13385 (unspec:CC [(match_operand:SI 1 "gpc_reg_operand" "r")
13386 (match_operand 2 "immediate_operand" "n")]
13387 UNSPEC_MOVESI_TO_CR))]
13388 "GET_CODE (operands[0]) == REG
13389 && CR_REGNO_P (REGNO (operands[0]))
13390 && GET_CODE (operands[2]) == CONST_INT
13391 && INTVAL (operands[2]) == 1 << (75 - REGNO (operands[0]))"
13393 [(set_attr "type" "mtcr")])
13395 ; The load-multiple instructions have similar properties.
13396 ; Note that "load_multiple" is a name known to the machine-independent
13397 ; code that actually corresponds to the PowerPC load-string.
13399 (define_insn "*lmw"
13400 [(match_parallel 0 "lmw_operation"
13401 [(set (match_operand:SI 1 "gpc_reg_operand" "=r")
13402 (match_operand:SI 2 "memory_operand" "m"))])]
13405 [(set_attr "type" "load")
13406 (set_attr "update" "yes")
13407 (set_attr "indexed" "yes")
13408 (set_attr "cell_micro" "always")])
13410 ; FIXME: This would probably be somewhat simpler if the Cygnus sibcall
13411 ; stuff was in GCC. Oh, and "any_parallel_operand" is a bit flexible...
13413 ; The following comment applies to:
13417 ; return_and_restore_gpregs*
13418 ; return_and_restore_fpregs*
13419 ; return_and_restore_fpregs_aix*
13421 ; The out-of-line save / restore functions expects one input argument.
13422 ; Since those are not standard call_insn's, we must avoid using
13423 ; MATCH_OPERAND for that argument. That way the register rename
13424 ; optimization will not try to rename this register.
13425 ; Each pattern is repeated for each possible register number used in
13426 ; various ABIs (r11, r1, and for some functions r12)
13428 (define_insn "*restore_gpregs_<mode>_r11"
13429 [(match_parallel 0 "any_parallel_operand"
13430 [(clobber (reg:P LR_REGNO))
13431 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13433 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13434 (match_operand:P 3 "memory_operand" "m"))])]
13437 [(set_attr "type" "branch")
13438 (set_attr "length" "4")])
13440 (define_insn "*restore_gpregs_<mode>_r12"
13441 [(match_parallel 0 "any_parallel_operand"
13442 [(clobber (reg:P LR_REGNO))
13443 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13445 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13446 (match_operand:P 3 "memory_operand" "m"))])]
13449 [(set_attr "type" "branch")
13450 (set_attr "length" "4")])
13452 (define_insn "*restore_gpregs_<mode>_r1"
13453 [(match_parallel 0 "any_parallel_operand"
13454 [(clobber (reg:P LR_REGNO))
13455 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13457 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13458 (match_operand:P 3 "memory_operand" "m"))])]
13461 [(set_attr "type" "branch")
13462 (set_attr "length" "4")])
13464 (define_insn "*return_and_restore_gpregs_<mode>_r11"
13465 [(match_parallel 0 "any_parallel_operand"
13467 (clobber (reg:P LR_REGNO))
13468 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13470 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13471 (match_operand:P 3 "memory_operand" "m"))])]
13474 [(set_attr "type" "branch")
13475 (set_attr "length" "4")])
13477 (define_insn "*return_and_restore_gpregs_<mode>_r12"
13478 [(match_parallel 0 "any_parallel_operand"
13480 (clobber (reg:P LR_REGNO))
13481 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13483 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13484 (match_operand:P 3 "memory_operand" "m"))])]
13487 [(set_attr "type" "branch")
13488 (set_attr "length" "4")])
13490 (define_insn "*return_and_restore_gpregs_<mode>_r1"
13491 [(match_parallel 0 "any_parallel_operand"
13493 (clobber (reg:P LR_REGNO))
13494 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13496 (set (match_operand:P 2 "gpc_reg_operand" "=r")
13497 (match_operand:P 3 "memory_operand" "m"))])]
13500 [(set_attr "type" "branch")
13501 (set_attr "length" "4")])
13503 (define_insn "*return_and_restore_fpregs_<mode>_r11"
13504 [(match_parallel 0 "any_parallel_operand"
13506 (clobber (reg:P LR_REGNO))
13507 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13509 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13510 (match_operand:DF 3 "memory_operand" "m"))])]
13513 [(set_attr "type" "branch")
13514 (set_attr "length" "4")])
13516 (define_insn "*return_and_restore_fpregs_<mode>_r12"
13517 [(match_parallel 0 "any_parallel_operand"
13519 (clobber (reg:P LR_REGNO))
13520 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13522 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13523 (match_operand:DF 3 "memory_operand" "m"))])]
13526 [(set_attr "type" "branch")
13527 (set_attr "length" "4")])
13529 (define_insn "*return_and_restore_fpregs_<mode>_r1"
13530 [(match_parallel 0 "any_parallel_operand"
13532 (clobber (reg:P LR_REGNO))
13533 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13535 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13536 (match_operand:DF 3 "memory_operand" "m"))])]
13539 [(set_attr "type" "branch")
13540 (set_attr "length" "4")])
13542 (define_insn "*return_and_restore_fpregs_aix_<mode>_r11"
13543 [(match_parallel 0 "any_parallel_operand"
13545 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13547 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13548 (match_operand:DF 3 "memory_operand" "m"))])]
13551 [(set_attr "type" "branch")
13552 (set_attr "length" "4")])
13554 (define_insn "*return_and_restore_fpregs_aix_<mode>_r1"
13555 [(match_parallel 0 "any_parallel_operand"
13557 (use (match_operand:P 1 "symbol_ref_operand" "s"))
13559 (set (match_operand:DF 2 "gpc_reg_operand" "=d")
13560 (match_operand:DF 3 "memory_operand" "m"))])]
13563 [(set_attr "type" "branch")
13564 (set_attr "length" "4")])
13566 ; This is used in compiling the unwind routines.
13567 (define_expand "eh_return"
13568 [(use (match_operand 0 "general_operand" ""))]
13573 emit_insn (gen_eh_set_lr_si (operands[0]));
13575 emit_insn (gen_eh_set_lr_di (operands[0]));
13579 ; We can't expand this before we know where the link register is stored.
13580 (define_insn "eh_set_lr_<mode>"
13581 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
13583 (clobber (match_scratch:P 1 "=&b"))]
13588 [(unspec_volatile [(match_operand 0 "register_operand" "")] UNSPECV_EH_RR)
13589 (clobber (match_scratch 1 ""))]
13594 rs6000_emit_eh_reg_restore (operands[0], operands[1]);
13598 (define_insn "prefetch"
13599 [(prefetch (match_operand 0 "indexed_or_indirect_address" "a")
13600 (match_operand:SI 1 "const_int_operand" "n")
13601 (match_operand:SI 2 "const_int_operand" "n"))]
13605 if (GET_CODE (operands[0]) == REG)
13606 return INTVAL (operands[1]) ? \"dcbtst 0,%0\" : \"dcbt 0,%0\";
13607 return INTVAL (operands[1]) ? \"dcbtst %a0\" : \"dcbt %a0\";
13609 [(set_attr "type" "load")])
13611 ;; Handle -fsplit-stack.
13613 (define_expand "split_stack_prologue"
13617 rs6000_expand_split_stack_prologue ();
13621 (define_expand "load_split_stack_limit"
13622 [(set (match_operand 0)
13623 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))]
13626 emit_insn (gen_rtx_SET (operands[0],
13627 gen_rtx_UNSPEC (Pmode,
13628 gen_rtvec (1, const0_rtx),
13629 UNSPEC_STACK_CHECK)));
13633 (define_insn "load_split_stack_limit_di"
13634 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13635 (unspec:DI [(const_int 0)] UNSPEC_STACK_CHECK))]
13637 "ld %0,-0x7040(13)"
13638 [(set_attr "type" "load")
13639 (set_attr "update" "no")
13640 (set_attr "indexed" "no")])
13642 (define_insn "load_split_stack_limit_si"
13643 [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
13644 (unspec:SI [(const_int 0)] UNSPEC_STACK_CHECK))]
13646 "lwz %0,-0x7020(2)"
13647 [(set_attr "type" "load")
13648 (set_attr "update" "no")
13649 (set_attr "indexed" "no")])
13651 ;; A return instruction which the middle-end doesn't see.
13652 ;; Use r0 to stop regrename twiddling with lr restore insns emitted
13653 ;; after the call to __morestack.
13654 (define_insn "split_stack_return"
13655 [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)]
13658 [(set_attr "type" "jmpreg")])
13660 ;; If there are operand 0 bytes available on the stack, jump to
13662 (define_expand "split_stack_space_check"
13663 [(set (match_dup 2)
13664 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
13666 (minus (reg STACK_POINTER_REGNUM)
13667 (match_operand 0)))
13668 (set (match_dup 4) (compare:CCUNS (match_dup 3) (match_dup 2)))
13669 (set (pc) (if_then_else
13670 (geu (match_dup 4) (const_int 0))
13671 (label_ref (match_operand 1))
13675 rs6000_split_stack_space_check (operands[0], operands[1]);
13679 (define_insn "bpermd_<mode>"
13680 [(set (match_operand:P 0 "gpc_reg_operand" "=r")
13681 (unspec:P [(match_operand:P 1 "gpc_reg_operand" "r")
13682 (match_operand:P 2 "gpc_reg_operand" "r")] UNSPEC_BPERM))]
13685 [(set_attr "type" "popcnt")])
13688 ;; Builtin fma support. Handle
13689 ;; Note that the conditions for expansion are in the FMA_F iterator.
13691 (define_expand "fma<mode>4"
13692 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13694 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13695 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13696 (match_operand:FMA_F 3 "gpc_reg_operand" "")))]
13700 (define_insn "*fma<mode>4_fpr"
13701 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13703 (match_operand:SFDF 1 "gpc_reg_operand" "%<Ff>,<Fv2>,<Fv2>")
13704 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13705 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))]
13706 "TARGET_<MODE>_FPR"
13708 fmadd<Ftrad> %0,%1,%2,%3
13709 xsmadda<Fvsx> %x0,%x1,%x2
13710 xsmaddm<Fvsx> %x0,%x1,%x3"
13711 [(set_attr "type" "fp")
13712 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13714 ; Altivec only has fma and nfms.
13715 (define_expand "fms<mode>4"
13716 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13718 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13719 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13720 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13721 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13724 (define_insn "*fms<mode>4_fpr"
13725 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13727 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13728 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13729 (neg:SFDF (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13730 "TARGET_<MODE>_FPR"
13732 fmsub<Ftrad> %0,%1,%2,%3
13733 xsmsuba<Fvsx> %x0,%x1,%x2
13734 xsmsubm<Fvsx> %x0,%x1,%x3"
13735 [(set_attr "type" "fp")
13736 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13738 ;; If signed zeros are ignored, -(a * b - c) = -a * b + c.
13739 (define_expand "fnma<mode>4"
13740 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13743 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13744 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13745 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13746 "!HONOR_SIGNED_ZEROS (<MODE>mode)"
13749 ;; If signed zeros are ignored, -(a * b + c) = -a * b - c.
13750 (define_expand "fnms<mode>4"
13751 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13754 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13755 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13756 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13757 "!HONOR_SIGNED_ZEROS (<MODE>mode) && !VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13760 ; Not an official optab name, but used from builtins.
13761 (define_expand "nfma<mode>4"
13762 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13765 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13766 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13767 (match_operand:FMA_F 3 "gpc_reg_operand" ""))))]
13768 "!VECTOR_UNIT_ALTIVEC_P (<MODE>mode)"
13771 (define_insn "*nfma<mode>4_fpr"
13772 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13775 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13776 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13777 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>"))))]
13778 "TARGET_<MODE>_FPR"
13780 fnmadd<Ftrad> %0,%1,%2,%3
13781 xsnmadda<Fvsx> %x0,%x1,%x2
13782 xsnmaddm<Fvsx> %x0,%x1,%x3"
13783 [(set_attr "type" "fp")
13784 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13786 ; Not an official optab name, but used from builtins.
13787 (define_expand "nfms<mode>4"
13788 [(set (match_operand:FMA_F 0 "gpc_reg_operand" "")
13791 (match_operand:FMA_F 1 "gpc_reg_operand" "")
13792 (match_operand:FMA_F 2 "gpc_reg_operand" "")
13793 (neg:FMA_F (match_operand:FMA_F 3 "gpc_reg_operand" "")))))]
13797 (define_insn "*nfmssf4_fpr"
13798 [(set (match_operand:SFDF 0 "gpc_reg_operand" "=<Ff>,<Fv2>,<Fv2>")
13801 (match_operand:SFDF 1 "gpc_reg_operand" "<Ff>,<Fv2>,<Fv2>")
13802 (match_operand:SFDF 2 "gpc_reg_operand" "<Ff>,<Fv2>,0")
13804 (match_operand:SFDF 3 "gpc_reg_operand" "<Ff>,0,<Fv2>")))))]
13805 "TARGET_<MODE>_FPR"
13807 fnmsub<Ftrad> %0,%1,%2,%3
13808 xsnmsuba<Fvsx> %x0,%x1,%x2
13809 xsnmsubm<Fvsx> %x0,%x1,%x3"
13810 [(set_attr "type" "fp")
13811 (set_attr "fp_type" "fp_maddsub_<Fs>")])
13814 (define_expand "rs6000_get_timebase"
13815 [(use (match_operand:DI 0 "gpc_reg_operand" ""))]
13818 if (TARGET_POWERPC64)
13819 emit_insn (gen_rs6000_mftb_di (operands[0]));
13821 emit_insn (gen_rs6000_get_timebase_ppc32 (operands[0]));
13825 (define_insn "rs6000_get_timebase_ppc32"
13826 [(set (match_operand:DI 0 "gpc_reg_operand" "=r")
13827 (unspec_volatile:DI [(const_int 0)] UNSPECV_MFTB))
13828 (clobber (match_scratch:SI 1 "=r"))
13829 (clobber (match_scratch:CC 2 "=y"))]
13830 "!TARGET_POWERPC64"
13832 if (WORDS_BIG_ENDIAN)
13835 return "mfspr %0,269\;"
13843 return "mftbu %0\;"
13852 return "mfspr %L0,269\;"
13860 return "mftbu %L0\;"
13867 [(set_attr "length" "20")])
13869 (define_insn "rs6000_mftb_<mode>"
13870 [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
13871 (unspec_volatile:GPR [(const_int 0)] UNSPECV_MFTB))]
13875 return "mfspr %0,268";
13881 (define_insn "rs6000_mffs"
13882 [(set (match_operand:DF 0 "gpc_reg_operand" "=d")
13883 (unspec_volatile:DF [(const_int 0)] UNSPECV_MFFS))]
13884 "TARGET_HARD_FLOAT"
13887 (define_insn "rs6000_mtfsf"
13888 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "i")
13889 (match_operand:DF 1 "gpc_reg_operand" "d")]
13891 "TARGET_HARD_FLOAT"
13895 ;; Power8 fusion support for fusing an addis instruction with a D-form load of
13896 ;; a GPR. The addis instruction must be adjacent to the load, and use the same
13897 ;; register that is being loaded. The fused ops must be physically adjacent.
13899 ;; There are two parts to addis fusion. The support for fused TOCs occur
13900 ;; before register allocation, and is meant to reduce the lifetime for the
13901 ;; tempoary register that holds the ADDIS result. On Power8 GPR loads, we try
13902 ;; to use the register that is being load. The peephole2 then gathers any
13903 ;; other fused possibilities that it can find after register allocation. If
13904 ;; power9 fusion is selected, we also fuse floating point loads/stores.
13906 ;; Fused TOC support: Replace simple GPR loads with a fused form. This is done
13907 ;; before register allocation, so that we can avoid allocating a temporary base
13908 ;; register that won't be used, and that we try to load into base registers,
13909 ;; and not register 0. If we can't get a fused GPR load, generate a P9 fusion
13910 ;; (addis followed by load) even on power8.
13913 [(set (match_operand:INT1 0 "toc_fusion_or_p9_reg_operand" "")
13914 (match_operand:INT1 1 "toc_fusion_mem_raw" ""))]
13915 "TARGET_TOC_FUSION_INT && can_create_pseudo_p ()"
13916 [(parallel [(set (match_dup 0) (match_dup 2))
13917 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13918 (use (match_dup 3))
13919 (clobber (scratch:DI))])]
13921 operands[2] = fusion_wrap_memory_address (operands[1]);
13922 operands[3] = gen_rtx_REG (Pmode, TOC_REGISTER);
13925 (define_insn "*toc_fusionload_<mode>"
13926 [(set (match_operand:QHSI 0 "int_reg_operand" "=&b,??r")
13927 (match_operand:QHSI 1 "toc_fusion_mem_wrapped" "wG,wG"))
13928 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13929 (use (match_operand:DI 2 "base_reg_operand" "r,r"))
13930 (clobber (match_scratch:DI 3 "=X,&b"))]
13931 "TARGET_TOC_FUSION_INT"
13933 if (base_reg_operand (operands[0], <MODE>mode))
13934 return emit_fusion_gpr_load (operands[0], operands[1]);
13936 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13938 [(set_attr "type" "load")
13939 (set_attr "length" "8")])
13941 (define_insn "*toc_fusionload_di"
13942 [(set (match_operand:DI 0 "int_reg_operand" "=&b,??r,?d")
13943 (match_operand:DI 1 "toc_fusion_mem_wrapped" "wG,wG,wG"))
13944 (unspec [(const_int 0)] UNSPEC_FUSION_ADDIS)
13945 (use (match_operand:DI 2 "base_reg_operand" "r,r,r"))
13946 (clobber (match_scratch:DI 3 "=X,&b,&b"))]
13947 "TARGET_TOC_FUSION_INT && TARGET_POWERPC64
13948 && (MEM_P (operands[1]) || int_reg_operand (operands[0], DImode))"
13950 if (base_reg_operand (operands[0], DImode))
13951 return emit_fusion_gpr_load (operands[0], operands[1]);
13953 return emit_fusion_p9_load (operands[0], operands[1], operands[3]);
13955 [(set_attr "type" "load")
13956 (set_attr "length" "8")])
13959 ;; Find cases where the addis that feeds into a load instruction is either used
13960 ;; once or is the same as the target register, and replace it with the fusion
13964 [(set (match_operand:P 0 "base_reg_operand" "")
13965 (match_operand:P 1 "fusion_gpr_addis" ""))
13966 (set (match_operand:INT1 2 "base_reg_operand" "")
13967 (match_operand:INT1 3 "fusion_gpr_mem_load" ""))]
13969 && fusion_gpr_load_p (operands[0], operands[1], operands[2],
13973 expand_fusion_gpr_load (operands);
13977 ;; Fusion insn, created by the define_peephole2 above (and eventually by
13980 (define_insn "fusion_gpr_load_<mode>"
13981 [(set (match_operand:INT1 0 "base_reg_operand" "=b")
13982 (unspec:INT1 [(match_operand:INT1 1 "fusion_addis_mem_combo_load" "wF")]
13983 UNSPEC_FUSION_GPR))]
13986 return emit_fusion_gpr_load (operands[0], operands[1]);
13988 [(set_attr "type" "load")
13989 (set_attr "length" "8")])
13992 ;; ISA 3.0 (power9) fusion support
13993 ;; Merge addis with floating load/store to FPRs (or GPRs).
13995 [(set (match_operand:P 0 "base_reg_operand" "")
13996 (match_operand:P 1 "fusion_gpr_addis" ""))
13997 (set (match_operand:SFDF 2 "toc_fusion_or_p9_reg_operand" "")
13998 (match_operand:SFDF 3 "fusion_offsettable_mem_operand" ""))]
13999 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
14000 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])"
14003 expand_fusion_p9_load (operands);
14008 [(set (match_operand:P 0 "base_reg_operand" "")
14009 (match_operand:P 1 "fusion_gpr_addis" ""))
14010 (set (match_operand:SFDF 2 "offsettable_mem_operand" "")
14011 (match_operand:SFDF 3 "toc_fusion_or_p9_reg_operand" ""))]
14012 "TARGET_P9_FUSION && peep2_reg_dead_p (2, operands[0])
14013 && fusion_p9_p (operands[0], operands[1], operands[2], operands[3])
14014 && !rtx_equal_p (operands[0], operands[3])"
14017 expand_fusion_p9_store (operands);
14022 [(set (match_operand:SDI 0 "int_reg_operand" "")
14023 (match_operand:SDI 1 "upper16_cint_operand" ""))
14025 (ior:SDI (match_dup 0)
14026 (match_operand:SDI 2 "u_short_cint_operand" "")))]
14028 [(set (match_dup 0)
14029 (unspec:SDI [(match_dup 1)
14030 (match_dup 2)] UNSPEC_FUSION_P9))])
14033 [(set (match_operand:SDI 0 "int_reg_operand" "")
14034 (match_operand:SDI 1 "upper16_cint_operand" ""))
14035 (set (match_operand:SDI 2 "int_reg_operand" "")
14036 (ior:SDI (match_dup 0)
14037 (match_operand:SDI 3 "u_short_cint_operand" "")))]
14039 && !rtx_equal_p (operands[0], operands[2])
14040 && peep2_reg_dead_p (2, operands[0])"
14041 [(set (match_dup 2)
14042 (unspec:SDI [(match_dup 1)
14043 (match_dup 3)] UNSPEC_FUSION_P9))])
14045 ;; Fusion insns, created by the define_peephole2 above (and eventually by
14046 ;; reload). Because we want to eventually have secondary_reload generate
14047 ;; these, they have to have a single alternative that gives the register
14048 ;; classes. This means we need to have separate gpr/fpr/altivec versions.
14049 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_load"
14050 [(set (match_operand:GPR_FUSION 0 "int_reg_operand" "=r")
14052 [(match_operand:GPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14054 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14057 /* This insn is a secondary reload insn, which cannot have alternatives.
14058 If we are not loading up register 0, use the power8 fusion instead. */
14059 if (base_reg_operand (operands[0], <GPR_FUSION:MODE>mode))
14060 return emit_fusion_gpr_load (operands[0], operands[1]);
14062 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14064 [(set_attr "type" "load")
14065 (set_attr "length" "8")])
14067 (define_insn "fusion_gpr_<P:mode>_<GPR_FUSION:mode>_store"
14068 [(set (match_operand:GPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14070 [(match_operand:GPR_FUSION 1 "int_reg_operand" "r")]
14072 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14075 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14077 [(set_attr "type" "store")
14078 (set_attr "length" "8")])
14080 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_load"
14081 [(set (match_operand:FPR_FUSION 0 "vsx_register_operand" "=dwb")
14083 [(match_operand:FPR_FUSION 1 "fusion_addis_mem_combo_load" "wF")]
14085 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14088 return emit_fusion_p9_load (operands[0], operands[1], operands[2]);
14090 [(set_attr "type" "fpload")
14091 (set_attr "length" "8")])
14093 (define_insn "fusion_vsx_<P:mode>_<FPR_FUSION:mode>_store"
14094 [(set (match_operand:FPR_FUSION 0 "fusion_addis_mem_combo_store" "=wF")
14096 [(match_operand:FPR_FUSION 1 "vsx_register_operand" "dwb")]
14098 (clobber (match_operand:P 2 "base_reg_operand" "=b"))]
14101 return emit_fusion_p9_store (operands[0], operands[1], operands[2]);
14103 [(set_attr "type" "fpstore")
14104 (set_attr "length" "8")])
14106 (define_insn "*fusion_p9_<mode>_constant"
14107 [(set (match_operand:SDI 0 "int_reg_operand" "=r")
14108 (unspec:SDI [(match_operand:SDI 1 "upper16_cint_operand" "L")
14109 (match_operand:SDI 2 "u_short_cint_operand" "K")]
14110 UNSPEC_FUSION_P9))]
14113 emit_fusion_addis (operands[0], operands[1]);
14114 return "ori %0,%0,%2";
14116 [(set_attr "type" "two")
14117 (set_attr "length" "8")])
14120 ;; Optimize cases where we want to do a D-form load (register+offset) on
14121 ;; ISA 2.06/2.07 to an Altivec register, and the register allocator
14126 ;; and we change this to:
14131 [(match_scratch:P 0 "b")
14132 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14133 (match_operand:ALTIVEC_DFORM 2 "simple_offsettable_mem_operand"))
14134 (set (match_operand:ALTIVEC_DFORM 3 "altivec_register_operand")
14136 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14137 [(set (match_dup 0)
14142 rtx tmp_reg = operands[0];
14143 rtx mem = operands[2];
14144 rtx addr = XEXP (mem, 0);
14145 rtx add_op0, add_op1, new_addr;
14147 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14148 add_op0 = XEXP (addr, 0);
14149 add_op1 = XEXP (addr, 1);
14150 gcc_assert (REG_P (add_op0));
14151 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14153 operands[4] = add_op1;
14154 operands[5] = change_address (mem, <MODE>mode, new_addr);
14157 ;; Optimize cases were want to do a D-form store on ISA 2.06/2.07 from an
14158 ;; Altivec register, and the register allocator has generated:
14162 ;; and we change this to:
14167 [(match_scratch:P 0 "b")
14168 (set (match_operand:ALTIVEC_DFORM 1 "fpr_reg_operand")
14169 (match_operand:ALTIVEC_DFORM 2 "altivec_register_operand"))
14170 (set (match_operand:ALTIVEC_DFORM 3 "simple_offsettable_mem_operand")
14172 "TARGET_VSX && !TARGET_P9_VECTOR && peep2_reg_dead_p (2, operands[1])"
14173 [(set (match_dup 0)
14178 rtx tmp_reg = operands[0];
14179 rtx mem = operands[3];
14180 rtx addr = XEXP (mem, 0);
14181 rtx add_op0, add_op1, new_addr;
14183 gcc_assert (GET_CODE (addr) == PLUS || GET_CODE (addr) == LO_SUM);
14184 add_op0 = XEXP (addr, 0);
14185 add_op1 = XEXP (addr, 1);
14186 gcc_assert (REG_P (add_op0));
14187 new_addr = gen_rtx_PLUS (Pmode, add_op0, tmp_reg);
14189 operands[4] = add_op1;
14190 operands[5] = change_address (mem, <MODE>mode, new_addr);
14194 ;; Miscellaneous ISA 2.06 (power7) instructions
14195 (define_insn "addg6s"
14196 [(set (match_operand:SI 0 "register_operand" "=r")
14197 (unspec:SI [(match_operand:SI 1 "register_operand" "r")
14198 (match_operand:SI 2 "register_operand" "r")]
14202 [(set_attr "type" "integer")
14203 (set_attr "length" "4")])
14205 (define_insn "cdtbcd"
14206 [(set (match_operand:SI 0 "register_operand" "=r")
14207 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14211 [(set_attr "type" "integer")
14212 (set_attr "length" "4")])
14214 (define_insn "cbcdtd"
14215 [(set (match_operand:SI 0 "register_operand" "=r")
14216 (unspec:SI [(match_operand:SI 1 "register_operand" "r")]
14220 [(set_attr "type" "integer")
14221 (set_attr "length" "4")])
14223 (define_int_iterator UNSPEC_DIV_EXTEND [UNSPEC_DIVE
14228 (define_int_attr div_extend [(UNSPEC_DIVE "e")
14229 (UNSPEC_DIVEO "eo")
14230 (UNSPEC_DIVEU "eu")
14231 (UNSPEC_DIVEUO "euo")])
14233 (define_insn "div<div_extend>_<mode>"
14234 [(set (match_operand:GPR 0 "register_operand" "=r")
14235 (unspec:GPR [(match_operand:GPR 1 "register_operand" "r")
14236 (match_operand:GPR 2 "register_operand" "r")]
14237 UNSPEC_DIV_EXTEND))]
14239 "div<wd><div_extend> %0,%1,%2"
14240 [(set_attr "type" "div")
14241 (set_attr "size" "<bits>")])
14244 ;; Pack/unpack 128-bit floating point types that take 2 scalar registers
14246 ; Type of the 64-bit part when packing/unpacking 128-bit floating point types
14247 (define_mode_attr FP128_64 [(TF "DF")
14252 (define_expand "unpack<mode>"
14253 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "")
14255 [(match_operand:FMOVE128 1 "register_operand" "")
14256 (match_operand:QI 2 "const_0_to_1_operand" "")]
14257 UNSPEC_UNPACK_128BIT))]
14258 "FLOAT128_2REG_P (<MODE>mode)"
14261 (define_insn_and_split "unpack<mode>_dm"
14262 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m,d,r,m")
14264 [(match_operand:FMOVE128 1 "register_operand" "d,d,r,d,r")
14265 (match_operand:QI 2 "const_0_to_1_operand" "i,i,i,i,i")]
14266 UNSPEC_UNPACK_128BIT))]
14267 "TARGET_POWERPC64 && TARGET_DIRECT_MOVE && FLOAT128_2REG_P (<MODE>mode)"
14269 "&& reload_completed"
14270 [(set (match_dup 0) (match_dup 3))]
14272 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14274 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14276 emit_note (NOTE_INSN_DELETED);
14280 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14282 [(set_attr "type" "fp,fpstore,mffgpr,mftgpr,store")
14283 (set_attr "length" "4")])
14285 (define_insn_and_split "unpack<mode>_nodm"
14286 [(set (match_operand:<FP128_64> 0 "nonimmediate_operand" "=d,m")
14288 [(match_operand:FMOVE128 1 "register_operand" "d,d")
14289 (match_operand:QI 2 "const_0_to_1_operand" "i,i")]
14290 UNSPEC_UNPACK_128BIT))]
14291 "(!TARGET_POWERPC64 || !TARGET_DIRECT_MOVE) && FLOAT128_2REG_P (<MODE>mode)"
14293 "&& reload_completed"
14294 [(set (match_dup 0) (match_dup 3))]
14296 unsigned fp_regno = REGNO (operands[1]) + UINTVAL (operands[2]);
14298 if (REG_P (operands[0]) && REGNO (operands[0]) == fp_regno)
14300 emit_note (NOTE_INSN_DELETED);
14304 operands[3] = gen_rtx_REG (<FP128_64>mode, fp_regno);
14306 [(set_attr "type" "fp,fpstore")
14307 (set_attr "length" "4")])
14309 (define_insn_and_split "pack<mode>"
14310 [(set (match_operand:FMOVE128 0 "register_operand" "=d,&d")
14312 [(match_operand:<FP128_64> 1 "register_operand" "0,d")
14313 (match_operand:<FP128_64> 2 "register_operand" "d,d")]
14314 UNSPEC_PACK_128BIT))]
14315 "FLOAT128_2REG_P (<MODE>mode)"
14319 "&& reload_completed && REGNO (operands[0]) != REGNO (operands[1])"
14320 [(set (match_dup 3) (match_dup 1))
14321 (set (match_dup 4) (match_dup 2))]
14323 unsigned dest_hi = REGNO (operands[0]);
14324 unsigned dest_lo = dest_hi + 1;
14326 gcc_assert (!IN_RANGE (REGNO (operands[1]), dest_hi, dest_lo));
14327 gcc_assert (!IN_RANGE (REGNO (operands[2]), dest_hi, dest_lo));
14329 operands[3] = gen_rtx_REG (<FP128_64>mode, dest_hi);
14330 operands[4] = gen_rtx_REG (<FP128_64>mode, dest_lo);
14332 [(set_attr "type" "fpsimple,fp")
14333 (set_attr "length" "4,8")])
14335 (define_insn "unpack<mode>"
14336 [(set (match_operand:DI 0 "register_operand" "=wa,wa")
14337 (unspec:DI [(match_operand:FMOVE128_VSX 1 "register_operand" "0,wa")
14338 (match_operand:QI 2 "const_0_to_1_operand" "O,i")]
14339 UNSPEC_UNPACK_128BIT))]
14340 "VECTOR_MEM_ALTIVEC_OR_VSX_P (<MODE>mode)"
14342 if (REGNO (operands[0]) == REGNO (operands[1]) && INTVAL (operands[2]) == 0)
14343 return ASM_COMMENT_START " xxpermdi to same register";
14345 operands[3] = GEN_INT (INTVAL (operands[2]) == 0 ? 0 : 3);
14346 return "xxpermdi %x0,%x1,%x1,%3";
14348 [(set_attr "type" "vecperm")])
14350 (define_insn "pack<mode>"
14351 [(set (match_operand:FMOVE128_VSX 0 "register_operand" "=wa")
14352 (unspec:FMOVE128_VSX
14353 [(match_operand:DI 1 "register_operand" "wa")
14354 (match_operand:DI 2 "register_operand" "wa")]
14355 UNSPEC_PACK_128BIT))]
14357 "xxpermdi %x0,%x1,%x2,0"
14358 [(set_attr "type" "vecperm")])
14362 ;; ISA 2.08 IEEE 128-bit floating point support.
14364 (define_insn "add<mode>3"
14365 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14367 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14368 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14369 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14371 [(set_attr "type" "vecfloat")
14372 (set_attr "size" "128")])
14374 (define_insn "sub<mode>3"
14375 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14377 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14378 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14379 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14381 [(set_attr "type" "vecfloat")
14382 (set_attr "size" "128")])
14384 (define_insn "mul<mode>3"
14385 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14387 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14388 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14389 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14391 [(set_attr "type" "qmul")
14392 (set_attr "size" "128")])
14394 (define_insn "div<mode>3"
14395 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14397 (match_operand:IEEE128 1 "altivec_register_operand" "v")
14398 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14399 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14401 [(set_attr "type" "vecdiv")
14402 (set_attr "size" "128")])
14404 (define_insn "sqrt<mode>2"
14405 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14407 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14408 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14410 [(set_attr "type" "vecdiv")
14411 (set_attr "size" "128")])
14413 (define_expand "copysign<mode>3"
14414 [(use (match_operand:IEEE128 0 "altivec_register_operand"))
14415 (use (match_operand:IEEE128 1 "altivec_register_operand"))
14416 (use (match_operand:IEEE128 2 "altivec_register_operand"))]
14417 "FLOAT128_IEEE_P (<MODE>mode)"
14419 if (TARGET_FLOAT128_HW)
14420 emit_insn (gen_copysign<mode>3_hard (operands[0], operands[1],
14424 rtx tmp = gen_reg_rtx (<MODE>mode);
14425 emit_insn (gen_copysign<mode>3_soft (operands[0], operands[1],
14426 operands[2], tmp));
14431 (define_insn "copysign<mode>3_hard"
14432 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14434 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14435 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14437 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14438 "xscpsgnqp %0,%2,%1"
14439 [(set_attr "type" "vecmove")
14440 (set_attr "size" "128")])
14442 (define_insn "copysign<mode>3_soft"
14443 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14445 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14446 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14447 (match_operand:IEEE128 3 "altivec_register_operand" "+v")]
14449 "!TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14450 "xscpsgndp %x3,%x2,%x1\;xxpermdi %x0,%x3,%x1,1"
14451 [(set_attr "type" "veccomplex")
14452 (set_attr "length" "8")])
14454 (define_insn "neg<mode>2_hw"
14455 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14457 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14458 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14460 [(set_attr "type" "vecmove")
14461 (set_attr "size" "128")])
14464 (define_insn "abs<mode>2_hw"
14465 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14467 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14468 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14470 [(set_attr "type" "vecmove")
14471 (set_attr "size" "128")])
14474 (define_insn "*nabs<mode>2_hw"
14475 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14478 (match_operand:IEEE128 1 "altivec_register_operand" "v"))))]
14479 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14481 [(set_attr "type" "vecmove")
14482 (set_attr "size" "128")])
14484 ;; Initially don't worry about doing fusion
14485 (define_insn "fma<mode>4_hw"
14486 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14488 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14489 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14490 (match_operand:IEEE128 3 "altivec_register_operand" "0")))]
14491 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14492 "xsmaddqp %0,%1,%2"
14493 [(set_attr "type" "qmul")
14494 (set_attr "size" "128")])
14496 (define_insn "*fms<mode>4_hw"
14497 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14499 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14500 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14502 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14503 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14504 "xsmsubqp %0,%1,%2"
14505 [(set_attr "type" "qmul")
14506 (set_attr "size" "128")])
14508 (define_insn "*nfma<mode>4_hw"
14509 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14512 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14513 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14514 (match_operand:IEEE128 3 "altivec_register_operand" "0"))))]
14515 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14516 "xsnmaddqp %0,%1,%2"
14517 [(set_attr "type" "qmul")
14518 (set_attr "size" "128")])
14520 (define_insn "*nfms<mode>4_hw"
14521 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14524 (match_operand:IEEE128 1 "altivec_register_operand" "%v")
14525 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14527 (match_operand:IEEE128 3 "altivec_register_operand" "0")))))]
14528 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14529 "xsnmsubqp %0,%1,%2"
14530 [(set_attr "type" "qmul")
14531 (set_attr "size" "128")])
14533 (define_insn "extend<SFDF:mode><IEEE128:mode>2_hw"
14534 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14535 (float_extend:IEEE128
14536 (match_operand:SFDF 1 "altivec_register_operand" "v")))]
14537 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14539 [(set_attr "type" "vecfloat")
14540 (set_attr "size" "128")])
14542 ;; Conversion between KFmode and TFmode if TFmode is ieee 128-bit floating
14543 ;; point is a simple copy.
14544 (define_insn_and_split "extendkftf2"
14545 [(set (match_operand:TF 0 "vsx_register_operand" "=wa,?wa")
14546 (float_extend:TF (match_operand:KF 1 "vsx_register_operand" "0,wa")))]
14547 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14551 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14554 emit_note (NOTE_INSN_DELETED);
14557 [(set_attr "type" "*,veclogical")
14558 (set_attr "length" "0,4")])
14560 (define_insn_and_split "trunctfkf2"
14561 [(set (match_operand:KF 0 "vsx_register_operand" "=wa,?wa")
14562 (float_extend:KF (match_operand:TF 1 "vsx_register_operand" "0,wa")))]
14563 "TARGET_FLOAT128_TYPE && TARGET_IEEEQUAD"
14567 "&& reload_completed && REGNO (operands[0]) == REGNO (operands[1])"
14570 emit_note (NOTE_INSN_DELETED);
14573 [(set_attr "type" "*,veclogical")
14574 (set_attr "length" "0,4")])
14576 (define_insn "trunc<mode>df2_hw"
14577 [(set (match_operand:DF 0 "altivec_register_operand" "=v")
14579 (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14580 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14582 [(set_attr "type" "vecfloat")
14583 (set_attr "size" "128")])
14585 ;; There is no KFmode -> SFmode instruction. Preserve the accuracy by doing
14586 ;; the KFmode -> DFmode conversion using round to odd rather than the normal
14588 (define_insn_and_split "trunc<mode>sf2_hw"
14589 [(set (match_operand:SF 0 "vsx_register_operand" "=wy")
14591 (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14592 (clobber (match_scratch:DF 2 "=v"))]
14593 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14596 [(set (match_dup 2)
14597 (unspec:DF [(match_dup 1)]
14598 UNSPEC_TRUNC_ROUND_TO_ODD))
14600 (float_truncate:SF (match_dup 2)))]
14602 if (GET_CODE (operands[2]) == SCRATCH)
14603 operands[2] = gen_reg_rtx (DFmode);
14605 [(set_attr "type" "vecfloat")
14606 (set_attr "length" "8")])
14608 ;; Conversion between IEEE 128-bit and integer types
14609 (define_insn "fix_<mode>di2_hw"
14610 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14611 (fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14612 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14614 [(set_attr "type" "vecfloat")
14615 (set_attr "size" "128")])
14617 (define_insn "fixuns_<mode>di2_hw"
14618 [(set (match_operand:DI 0 "altivec_register_operand" "=v")
14619 (unsigned_fix:DI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14620 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14622 [(set_attr "type" "vecfloat")
14623 (set_attr "size" "128")])
14625 (define_insn "fix_<mode>si2_hw"
14626 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14627 (fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14628 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14630 [(set_attr "type" "vecfloat")
14631 (set_attr "size" "128")])
14633 (define_insn "fixuns_<mode>si2_hw"
14634 [(set (match_operand:SI 0 "altivec_register_operand" "=v")
14635 (unsigned_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))]
14636 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14638 [(set_attr "type" "vecfloat")
14639 (set_attr "size" "128")])
14641 ;; Combiner pattern to prevent moving the result of converting an IEEE 128-bit
14642 ;; floating point value to 32-bit integer to GPR in order to save it.
14643 (define_insn_and_split "*fix<uns>_<mode>_mem"
14644 [(set (match_operand:SI 0 "memory_operand" "=Z")
14645 (any_fix:SI (match_operand:IEEE128 1 "altivec_register_operand" "v")))
14646 (clobber (match_scratch:SI 2 "=v"))]
14647 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14649 "&& reload_completed"
14650 [(set (match_dup 2)
14651 (any_fix:SI (match_dup 1)))
14655 (define_insn "float_<mode>di2_hw"
14656 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14657 (float:IEEE128 (match_operand:DI 1 "altivec_register_operand" "v")))]
14658 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14660 [(set_attr "type" "vecfloat")
14661 (set_attr "size" "128")])
14663 (define_insn_and_split "float_<mode>si2_hw"
14664 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14665 (float:IEEE128 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14666 (clobber (match_scratch:DI 2 "=v"))]
14667 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14670 [(set (match_dup 2)
14671 (sign_extend:DI (match_dup 1)))
14673 (float:IEEE128 (match_dup 2)))]
14675 if (GET_CODE (operands[2]) == SCRATCH)
14676 operands[2] = gen_reg_rtx (DImode);
14678 if (MEM_P (operands[1]))
14679 operands[1] = rs6000_address_for_fpconvert (operands[1]);
14682 (define_insn_and_split "float<QHI:mode><IEEE128:mode>2"
14683 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14684 (float:IEEE128 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14685 (clobber (match_scratch:DI 2 "=X,r,X"))]
14686 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14688 "&& reload_completed"
14691 rtx dest = operands[0];
14692 rtx src = operands[1];
14693 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14695 if (altivec_register_operand (src, <QHI:MODE>mode))
14696 emit_insn (gen_extend<QHI:mode>di2 (dest_di, src));
14697 else if (int_reg_operand (src, <QHI:MODE>mode))
14699 rtx ext_di = operands[2];
14700 emit_insn (gen_extend<QHI:mode>di2 (ext_di, src));
14701 emit_move_insn (dest_di, ext_di);
14703 else if (MEM_P (src))
14705 rtx dest_qhi = gen_rtx_REG (<QHI:MODE>mode, REGNO (dest));
14706 emit_move_insn (dest_qhi, src);
14707 emit_insn (gen_extend<QHI:mode>di2 (dest_di, dest_qhi));
14710 gcc_unreachable ();
14712 emit_insn (gen_float_<IEEE128:mode>di2_hw (dest, dest_di));
14715 [(set_attr "length" "8,12,12")
14716 (set_attr "type" "vecfloat")
14717 (set_attr "size" "128")])
14719 (define_insn "floatuns_<mode>di2_hw"
14720 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14721 (unsigned_float:IEEE128
14722 (match_operand:DI 1 "altivec_register_operand" "v")))]
14723 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14725 [(set_attr "type" "vecfloat")
14726 (set_attr "size" "128")])
14728 (define_insn_and_split "floatuns_<mode>si2_hw"
14729 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14730 (unsigned_float:IEEE128
14731 (match_operand:SI 1 "nonimmediate_operand" "vrZ")))
14732 (clobber (match_scratch:DI 2 "=v"))]
14733 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14736 [(set (match_dup 2)
14737 (zero_extend:DI (match_dup 1)))
14739 (float:IEEE128 (match_dup 2)))]
14741 if (GET_CODE (operands[2]) == SCRATCH)
14742 operands[2] = gen_reg_rtx (DImode);
14744 if (MEM_P (operands[1]))
14745 operands[1] = rs6000_address_for_fpconvert (operands[1]);
14748 (define_insn_and_split "floatuns<QHI:mode><IEEE128:mode>2"
14749 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v,v,v")
14750 (unsigned_float:IEEE128
14751 (match_operand:QHI 1 "nonimmediate_operand" "v,r,Z")))
14752 (clobber (match_scratch:DI 2 "=X,r,X"))]
14753 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<IEEE128:MODE>mode)"
14755 "&& reload_completed"
14758 rtx dest = operands[0];
14759 rtx src = operands[1];
14760 rtx dest_di = gen_rtx_REG (DImode, REGNO (dest));
14762 if (altivec_register_operand (src, <QHI:MODE>mode) || MEM_P (src))
14763 emit_insn (gen_zero_extend<QHI:mode>di2 (dest_di, src));
14764 else if (int_reg_operand (src, <QHI:MODE>mode))
14766 rtx ext_di = operands[2];
14767 emit_insn (gen_zero_extend<QHI:mode>di2 (ext_di, src));
14768 emit_move_insn (dest_di, ext_di);
14771 gcc_unreachable ();
14773 emit_insn (gen_floatuns_<IEEE128:mode>di2_hw (dest, dest_di));
14776 [(set_attr "length" "8,12,8")
14777 (set_attr "type" "vecfloat")
14778 (set_attr "size" "128")])
14780 ;; IEEE 128-bit instructions with round to odd semantics
14781 (define_insn "add<mode>3_odd"
14782 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14784 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14785 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14786 UNSPEC_ADD_ROUND_TO_ODD))]
14787 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14788 "xsaddqpo %0,%1,%2"
14789 [(set_attr "type" "vecfloat")
14790 (set_attr "size" "128")])
14792 (define_insn "sub<mode>3_odd"
14793 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14795 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14796 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14797 UNSPEC_SUB_ROUND_TO_ODD))]
14798 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14799 "xssubqpo %0,%1,%2"
14800 [(set_attr "type" "vecfloat")
14801 (set_attr "size" "128")])
14803 (define_insn "mul<mode>3_odd"
14804 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14806 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14807 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14808 UNSPEC_MUL_ROUND_TO_ODD))]
14809 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14810 "xsmulqpo %0,%1,%2"
14811 [(set_attr "type" "qmul")
14812 (set_attr "size" "128")])
14814 (define_insn "div<mode>3_odd"
14815 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14817 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14818 (match_operand:IEEE128 2 "altivec_register_operand" "v")]
14819 UNSPEC_DIV_ROUND_TO_ODD))]
14820 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14821 "xsdivqpo %0,%1,%2"
14822 [(set_attr "type" "vecdiv")
14823 (set_attr "size" "128")])
14825 (define_insn "sqrt<mode>2_odd"
14826 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14828 [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14829 UNSPEC_SQRT_ROUND_TO_ODD))]
14830 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14832 [(set_attr "type" "vecdiv")
14833 (set_attr "size" "128")])
14835 (define_insn "fma<mode>4_odd"
14836 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14838 [(match_operand:IEEE128 1 "altivec_register_operand" "v")
14839 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14840 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14841 UNSPEC_FMA_ROUND_TO_ODD))]
14842 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14843 "xsmaddqpo %0,%1,%2"
14844 [(set_attr "type" "qmul")
14845 (set_attr "size" "128")])
14847 (define_insn "*fms<mode>4_odd"
14848 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14850 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14851 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14853 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14854 UNSPEC_FMA_ROUND_TO_ODD))]
14855 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14856 "xsmsubqpo %0,%1,%2"
14857 [(set_attr "type" "qmul")
14858 (set_attr "size" "128")])
14860 (define_insn "*nfma<mode>4_odd"
14861 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14864 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14865 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14866 (match_operand:IEEE128 3 "altivec_register_operand" "0")]
14867 UNSPEC_FMA_ROUND_TO_ODD)))]
14868 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14869 "xsnmaddqpo %0,%1,%2"
14870 [(set_attr "type" "qmul")
14871 (set_attr "size" "128")])
14873 (define_insn "*nfms<mode>4_odd"
14874 [(set (match_operand:IEEE128 0 "altivec_register_operand" "=v")
14877 [(match_operand:IEEE128 1 "altivec_register_operand" "%v")
14878 (match_operand:IEEE128 2 "altivec_register_operand" "v")
14880 (match_operand:IEEE128 3 "altivec_register_operand" "0"))]
14881 UNSPEC_FMA_ROUND_TO_ODD)))]
14882 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14883 "xsnmsubqpo %0,%1,%2"
14884 [(set_attr "type" "qmul")
14885 (set_attr "size" "128")])
14887 (define_insn "trunc<mode>df2_odd"
14888 [(set (match_operand:DF 0 "vsx_register_operand" "=v")
14889 (unspec:DF [(match_operand:IEEE128 1 "altivec_register_operand" "v")]
14890 UNSPEC_TRUNC_ROUND_TO_ODD))]
14891 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14893 [(set_attr "type" "vecfloat")
14894 (set_attr "size" "128")])
14896 ;; IEEE 128-bit comparisons
14897 (define_insn "*cmp<mode>_hw"
14898 [(set (match_operand:CCFP 0 "cc_reg_operand" "=y")
14899 (compare:CCFP (match_operand:IEEE128 1 "altivec_register_operand" "v")
14900 (match_operand:IEEE128 2 "altivec_register_operand" "v")))]
14901 "TARGET_FLOAT128_HW && FLOAT128_IEEE_P (<MODE>mode)"
14902 "xscmpuqp %0,%1,%2"
14903 [(set_attr "type" "veccmp")
14904 (set_attr "size" "128")])
14908 (include "sync.md")
14909 (include "vector.md")
14911 (include "altivec.md")
14913 (include "paired.md")
14914 (include "crypto.md")